Skip to content

Commit

Permalink
[flash_ctrl] Share flash_scrambling module among banks
Browse files Browse the repository at this point in the history
Each bank had its own scrambling module, and since this is not needed
from a throughput perspective (we typically only access one bank at a
time), the module can be shared to save area.

This fixes lowRISC#3353

Signed-off-by: Michael Schaffner <[email protected]>
  • Loading branch information
msfschaffner committed Mar 18, 2024
1 parent 7446215 commit c95dc32
Show file tree
Hide file tree
Showing 15 changed files with 531 additions and 309 deletions.
38 changes: 15 additions & 23 deletions hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_sec_otp_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,10 @@ class flash_ctrl_hw_sec_otp_vseq extends flash_ctrl_base_vseq;
// Tests the connections between the Flash OTP and the Scramble Block in the Flash Ctrl
virtual task otp_scramble_key_test_connect();

logic [KeyWidth-1:0] prb_otp_addr_key [flash_ctrl_pkg::NumBanks];
logic [KeyWidth-1:0] prb_otp_data_key [flash_ctrl_pkg::NumBanks];
logic [KeyWidth-1:0] prb_otp_addr_rand_key[flash_ctrl_pkg::NumBanks];
logic [KeyWidth-1:0] prb_otp_data_rand_key[flash_ctrl_pkg::NumBanks];
logic [KeyWidth-1:0] prb_otp_addr_key;
logic [KeyWidth-1:0] prb_otp_data_key;
logic [KeyWidth-1:0] prb_otp_addr_rand_key;
logic [KeyWidth-1:0] prb_otp_data_rand_key;

// OTP SCRAMBLE KEY TESTS - CONNECTIVITY TEST ONLY

Expand All @@ -270,24 +270,16 @@ class flash_ctrl_hw_sec_otp_vseq extends flash_ctrl_base_vseq;
`uvm_info(`gfn, "FLASH OTP KEY - Scramble Connectivity Check", UVM_LOW)

// Probe Internal Scramble Signals
for (int i = 0; i < flash_ctrl_pkg::NumBanks; i++) begin
prb_otp_addr_key[i] = read_key_probe(
$sformatf("tb.dut.u_eflash.gen_flash_cores[%0d].u_core.u_scramble.addr_key_i", i));
prb_otp_addr_rand_key[i] = read_key_probe(
$sformatf("tb.dut.u_eflash.gen_flash_cores[%0d].u_core.u_scramble.rand_addr_key_i", i));
prb_otp_data_key[i] = read_key_probe(
$sformatf("tb.dut.u_eflash.gen_flash_cores[%0d].u_core.u_scramble.data_key_i", i));
prb_otp_data_rand_key[i] = read_key_probe(
$sformatf("tb.dut.u_eflash.gen_flash_cores[%0d].u_core.u_scramble.rand_data_key_i", i));
end
prb_otp_addr_key = read_key_probe("tb.dut.u_eflash.u_scramble.addr_key_i");
prb_otp_addr_rand_key = read_key_probe("tb.dut.u_eflash.u_scramble.rand_addr_key_i");
prb_otp_data_key = read_key_probe("tb.dut.u_eflash.u_scramble.data_key_i");
prb_otp_data_rand_key = read_key_probe("tb.dut.u_eflash.u_scramble.rand_data_key_i");

// Compare OTP Keys - Probed vs Expected (For This Test Scenario)
for (int i = 0; i < flash_ctrl_pkg::NumBanks; i++) begin
compare_key_probe(i, "otp_addr_key", prb_otp_addr_key[i], otp_addr_key);
compare_key_probe(i, "otp_addr_rand_key", prb_otp_addr_rand_key[i], otp_addr_rand_key);
compare_key_probe(i, "otp_data_key", prb_otp_data_key[i], otp_data_key);
compare_key_probe(i, "otp_data_rand_key", prb_otp_data_rand_key[i], otp_data_rand_key);
end
compare_key_probe("otp_addr_key", prb_otp_addr_key, otp_addr_key);
compare_key_probe("otp_addr_rand_key", prb_otp_addr_rand_key, otp_addr_rand_key);
compare_key_probe("otp_data_key", prb_otp_data_key, otp_data_key);
compare_key_probe("otp_data_rand_key", prb_otp_data_rand_key, otp_data_rand_key);

endtask : otp_scramble_key_test_connect

Expand All @@ -298,17 +290,17 @@ class flash_ctrl_hw_sec_otp_vseq extends flash_ctrl_base_vseq;
endfunction : read_key_probe

// Task that compares an expected Key with a given key
virtual task compare_key_probe(input uint i, input string dut_prb,
virtual task compare_key_probe(input string dut_prb,
input logic [KeyWidth-1:0] key,
input logic [KeyWidth-1:0] expected_key);

`uvm_info(`gfn, $sformatf("Compare OTP Key, Read : 0x%0x, Expected : 0x%0x", key, expected_key),
UVM_MEDIUM)

`DV_CHECK_EQ(key, expected_key, $sformatf(
{"Flash OTP Scramble Key Mismatch, Key : %s[%0d], Read : ",
{"Flash OTP Scramble Key Mismatch, Key : %s, Read : ",
"0x%0x, Expected : 0x%0x, FAIL"},
dut_prb, i, key, expected_key))
dut_prb, key, expected_key))

endtask : compare_key_probe

Expand Down
34 changes: 25 additions & 9 deletions hw/ip/flash_ctrl/rtl/flash_phy.sv
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ module flash_phy
assign host_ecc_en = mubi4_test_true_strict(mubi4_and_hi(region_cfg.ecc_en, region_cfg.en));

// Prim flash to flash_phy_core connections
flash_phy_pkg::scramble_req_t [NumBanks-1:0] scramble_req;
flash_phy_pkg::scramble_rsp_t [NumBanks-1:0] scramble_rsp;
flash_phy_pkg::flash_phy_prim_flash_req_t [NumBanks-1:0] prim_flash_req;
flash_phy_pkg::flash_phy_prim_flash_rsp_t [NumBanks-1:0] prim_flash_rsp;
logic [NumBanks-1:0] ecc_single_err;
Expand All @@ -205,9 +207,10 @@ module flash_phy
assign flash_ctrl_o.ecc_single_err = ecc_single_err;
assign flash_ctrl_o.ecc_addr = ecc_addr;

mubi4_t [NumBanks-1:0] flash_disable;
// One extra copy for the flash scrambling module.
mubi4_t [NumBanks:0] flash_disable;
prim_mubi4_sync #(
.NumCopies(NumBanks),
.NumCopies(NumBanks+1),
.AsyncOn(0)
) u_disable_buf (
.clk_i,
Expand Down Expand Up @@ -248,9 +251,7 @@ module flash_phy
assign ctrl_req = flash_ctrl_i.req & (ctrl_bank_sel == bank);
assign ecc_addr[bank][BusBankAddrW +: BankW] = bank;

flash_phy_core #(
.SecScrambleEn(SecScrambleEn)
) u_core (
flash_phy_core u_core (
.clk_i,
.rst_ni,
// integrity error is either from host or from controller
Expand All @@ -275,10 +276,6 @@ module flash_phy
.prog_data_i(flash_ctrl_i.prog_data),
.prog_last_i(flash_ctrl_i.prog_last),
.prog_type_i(flash_ctrl_i.prog_type),
.addr_key_i(flash_ctrl_i.addr_key),
.data_key_i(flash_ctrl_i.data_key),
.rand_addr_key_i(flash_ctrl_i.rand_addr_key),
.rand_data_key_i(flash_ctrl_i.rand_data_key),
.rd_buf_en_i(flash_ctrl_i.rd_buf_en),
.host_req_rdy_o(host_req_rdy[bank]),
.host_req_done_o(host_req_done[bank]),
Expand All @@ -288,6 +285,8 @@ module flash_phy
.rd_data_o(rd_data[bank]),
.rd_err_o(rd_err[bank]),
.flash_disable_i(flash_disable[bank]),
.scramble_req_o(scramble_req[bank]),
.scramble_rsp_i(scramble_rsp[bank]),
.prim_flash_req_o(prim_flash_req[bank]),
.prim_flash_rsp_i(prim_flash_rsp[bank]),
.ecc_single_err_o(ecc_single_err[bank]),
Expand All @@ -304,6 +303,23 @@ module flash_phy
);
end // block: gen_flash_banks

// shared scrambling module
// SEC_CM: MEM.SCRAMBLE
flash_phy_scramble #(
.SecScrambleEn(SecScrambleEn)
) u_scramble (
.clk_i,
.rst_ni,
// both escalation and integrity error cause the scramble keys to change
.disable_i(prim_mubi_pkg::mubi4_test_true_loose(flash_disable[NumBanks])),
.addr_key_i(flash_ctrl_i.addr_key),
.data_key_i(flash_ctrl_i.data_key),
.rand_addr_key_i(flash_ctrl_i.rand_addr_key),
.rand_data_key_i(flash_ctrl_i.rand_data_key),
.scramble_req_i(scramble_req),
.scramble_rsp_o(scramble_rsp)
);

// life cycle handling
logic tdo;
lc_ctrl_pkg::lc_tx_t [FlashLcDftLast-1:0] lc_nvm_debug_en;
Expand Down
56 changes: 18 additions & 38 deletions hw/ip/flash_ctrl/rtl/flash_phy_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ module flash_phy_core
import flash_phy_pkg::*;
import prim_mubi_pkg::mubi4_t;
#(
parameter int unsigned ArbCnt = 5,
parameter bit SecScrambleEn = 1'b1
parameter int unsigned ArbCnt = 5
) (
input clk_i,
input rst_ni,
Expand All @@ -36,12 +35,10 @@ module flash_phy_core
input [BusFullWidth-1:0] prog_data_i,
input prog_last_i,
input flash_ctrl_pkg::flash_prog_e prog_type_i,
input [KeySize-1:0] addr_key_i,
input [KeySize-1:0] data_key_i,
input [KeySize-1:0] rand_addr_key_i,
input [KeySize-1:0] rand_data_key_i,
input rd_buf_en_i,
input prim_mubi_pkg::mubi4_t flash_disable_i,
output scramble_req_t scramble_req_o,
input scramble_rsp_t scramble_rsp_i,
input flash_phy_prim_flash_rsp_t prim_flash_rsp_i,
output flash_phy_prim_flash_req_t prim_flash_req_o,
output logic host_req_rdy_o,
Expand Down Expand Up @@ -170,7 +167,6 @@ module flash_phy_core
HostDisableIdx,
CtrlDisableIdx,
FsmDisableIdx,
ScrDisableIdx,
ProgFsmDisableIdx,
LastDisableIdx
} phy_core_disable_e;
Expand Down Expand Up @@ -522,6 +518,8 @@ module flash_phy_core
);
end

assign fsm_err_o = fsm_err | prog_fsm_err;

////////////////////////
// erase pipeline
////////////////////////
Expand All @@ -544,39 +542,21 @@ module flash_phy_core
);

////////////////////////
// scrambling / de-scrambling primitive
// bundle data to send to shared scrambling module
////////////////////////

logic [BankAddrW-1:0] scramble_muxed_addr;
assign scramble_muxed_addr = prog_calc_req ? muxed_addr[BusBankAddrW-1:LsbAddrBit] :
rd_calc_addr;

// SEC_CM: MEM.SCRAMBLE
flash_phy_scramble #(
.SecScrambleEn(SecScrambleEn)
) u_scramble (
.clk_i,
.rst_ni,
// both escalation and integrity error cause the scramble keys to change
.disable_i(mubi4_test_true_loose(flash_disable[ScrDisableIdx])),
.calc_req_i(prog_calc_req | rd_calc_req),
.op_req_i(prog_op_req | rd_op_req),
.op_type_i(prog_op_req ? ScrambleOp : DeScrambleOp),
.addr_i(scramble_muxed_addr),
.plain_data_i(prog_data),
.scrambled_data_i(rd_scrambled_data),
.addr_key_i,
.data_key_i,
.rand_addr_key_i,
.rand_data_key_i,
.calc_ack_o(calc_ack),
.op_ack_o(op_ack),
.mask_o(scramble_mask),
.plain_data_o(rd_descrambled_data),
.scrambled_data_o(prog_scrambled_data)
);

assign fsm_err_o = fsm_err | prog_fsm_err;
assign scramble_req_o.calc_req = prog_calc_req | rd_calc_req;
assign scramble_req_o.op_req = prog_op_req | rd_op_req;
assign scramble_req_o.op_type = prog_op_req ? ScrambleOp : DeScrambleOp;
assign scramble_req_o.addr = prog_calc_req ? muxed_addr[BusBankAddrW-1:LsbAddrBit] :
rd_calc_addr;
assign scramble_req_o.plain_data = prog_data;
assign scramble_req_o.scrambled_data = rd_scrambled_data;
assign calc_ack = scramble_rsp_i.calc_ack;
assign op_ack = scramble_rsp_i.op_ack;
assign scramble_mask = scramble_rsp_i.mask;
assign rd_descrambled_data = scramble_rsp_i.plain_data;
assign prog_scrambled_data = scramble_rsp_i.scrambled_data;

////////////////////////
// Actual connection to flash phy
Expand Down
17 changes: 17 additions & 0 deletions hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,21 @@ package flash_phy_pkg;
logic [FullDataWidth-1:0] rdata;
} flash_phy_prim_flash_rsp_t;

typedef struct packed {
logic calc_req;
logic op_req;
cipher_ops_e op_type;
logic [BankAddrW-1:0] addr;
logic [DataWidth-1:0] plain_data;
logic [DataWidth-1:0] scrambled_data;
} scramble_req_t;

typedef struct packed {
logic calc_ack;
logic op_ack;
logic [DataWidth-1:0] mask;
logic [DataWidth-1:0] plain_data;
logic [DataWidth-1:0] scrambled_data;
} scramble_rsp_t;

endpackage // flash_phy_pkg
Loading

0 comments on commit c95dc32

Please sign in to comment.