[flash_ctrl] propagate write integrity - propagate write integrity past adapter_sram into flash_phy - simplify the various integerity errors into local escalation Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl.sv.tpl b/hw/ip/flash_ctrl/data/flash_ctrl.sv.tpl index f71d0c3..1c62a2d 100644 --- a/hw/ip/flash_ctrl/data/flash_ctrl.sv.tpl +++ b/hw/ip/flash_ctrl/data/flash_ctrl.sv.tpl
@@ -153,22 +153,22 @@ ); // FIFO Connections - logic prog_fifo_wvalid; - logic prog_fifo_wready; - logic prog_fifo_rvalid; - logic prog_fifo_ren; - logic [BusWidth-1:0] prog_fifo_wdata; - logic [BusWidth-1:0] prog_fifo_rdata; - logic [FifoDepthW-1:0] prog_fifo_depth; - logic rd_fifo_wready; - logic rd_fifo_rvalid; - logic rd_fifo_rready; - logic rd_fifo_wen; - logic rd_fifo_ren; - logic [BusWidth-1:0] rd_fifo_wdata; - logic [BusWidth-1:0] rd_fifo_rdata; - logic [FifoDepthW-1:0] rd_fifo_depth; - logic rd_fifo_full; + logic prog_fifo_wvalid; + logic prog_fifo_wready; + logic prog_fifo_rvalid; + logic prog_fifo_ren; + logic [BusFullWidth-1:0] prog_fifo_wdata; + logic [BusFullWidth-1:0] prog_fifo_rdata; + logic [FifoDepthW-1:0] prog_fifo_depth; + logic rd_fifo_wready; + logic rd_fifo_rvalid; + logic rd_fifo_rready; + logic rd_fifo_wen; + logic rd_fifo_ren; + logic [BusWidth-1:0] rd_fifo_wdata; + logic [BusWidth-1:0] rd_fifo_rdata; + logic [FifoDepthW-1:0] rd_fifo_depth; + logic rd_fifo_full; // Program Control Connections logic prog_flash_req; @@ -198,7 +198,7 @@ logic flash_req; logic flash_rd_done, flash_prog_done, flash_erase_done; logic flash_mp_err; - logic [BusWidth-1:0] flash_prog_data; + logic [BusFullWidth-1:0] flash_prog_data; logic flash_prog_last; flash_prog_e flash_prog_type; logic [BusWidth-1:0] flash_rd_data; @@ -255,7 +255,7 @@ logic sw_rvalid; logic adapter_rvalid; logic sw_wvalid; - logic [BusWidth-1:0] sw_wdata; + logic [BusFullWidth-1:0] sw_wdata; logic sw_wready; // lfsr for local entropy usage @@ -339,7 +339,7 @@ .hw_rvalid_o(hw_rvalid), .hw_rready_i(hw_rready), .hw_wvalid_i(hw_wvalid), - .hw_wdata_i(hw_wdata), + .hw_wdata_i(BusFullWidth'(hw_wdata)), // TODO: enhance for hw side later .hw_wready_o(hw_wready), // hardware interface does not talk to prog_fifo @@ -468,10 +468,11 @@ assign prog_op_valid = op_start & prog_op; tlul_adapter_sram #( - .SramAw(1), //address unused + .SramAw(1), //address unused .SramDw(BusWidth), - .ByteAccess(0), //flash may not support byte access - .ErrOnRead(1) //reads not supported + .ByteAccess(0), //flash may not support byte access + .ErrOnRead(1), //reads not supported + .EnableDataIntgPt(1) //passthrough data integrity ) u_to_prog_fifo ( .clk_i, .rst_ni, @@ -486,13 +487,13 @@ .wmask_o (), .intg_error_o(), .wdata_o (sw_wdata), - .rdata_i (BusWidth'(0)), + .rdata_i ('0), .rvalid_i (1'b0), .rerror_i (2'b0) ); prim_fifo_sync #( - .Width(BusWidth), + .Width(BusFullWidth), .Depth(FifoDepth) ) u_prog_fifo ( .clk_i, @@ -813,7 +814,6 @@ assign flash_phy_req.jtag_req.tms = cio_tms_i; assign flash_phy_req.jtag_req.tdi = cio_tdi_i; assign flash_phy_req.jtag_req.trst_n = '0; - assign flash_phy_req.intg_err = intg_err; assign cio_tdo_o = flash_phy_rsp.jtag_rsp.tdo; assign cio_tdo_en_o = flash_phy_rsp.jtag_rsp.tdo_oe; assign flash_rd_err = flash_phy_rsp.rd_err; @@ -1162,7 +1162,6 @@ logic flash_host_rderr; logic [flash_ctrl_pkg::BusWidth-1:0] flash_host_rdata; logic [flash_ctrl_pkg::BusAddrW-1:0] flash_host_addr; - logic flash_host_intg_err; import prim_mubi_pkg::mubi4_test_true_loose; logic host_disable; @@ -1188,7 +1187,7 @@ .ByteAccess(0), .ErrOnWrite(1), .CmdIntgCheck(1), - .EnableRspIntgGen(1), + .EnableRspIntgGen(1), // keep until read path generate .EnableDataIntgGen(1) ) u_tl_adapter_eflash ( .clk_i, @@ -1203,7 +1202,7 @@ .addr_o (flash_host_addr), .wdata_o (), .wmask_o (), - .intg_error_o(flash_host_intg_err), + .intg_error_o(), .rdata_i (flash_host_rdata), .rvalid_i (flash_host_req_done | disabled_rvalid), .rerror_i ({flash_host_rderr,1'b0} | disabled_err) @@ -1215,7 +1214,6 @@ .clk_i, .rst_ni, .host_req_i (flash_host_req), - .host_intg_err_i (flash_host_intg_err), .host_addr_i (flash_host_addr), .host_req_rdy_o (flash_host_req_rdy), .host_req_done_o (flash_host_req_done),
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl_pkg.sv.tpl b/hw/ip/flash_ctrl/data/flash_ctrl_pkg.sv.tpl index 4600469..5e4e0b9 100644 --- a/hw/ip/flash_ctrl/data/flash_ctrl_pkg.sv.tpl +++ b/hw/ip/flash_ctrl/data/flash_ctrl_pkg.sv.tpl
@@ -33,6 +33,8 @@ }); parameter int WordsPerPage = ${cfg.words_per_page}; // Number of flash words per page parameter int BusWidth = top_pkg::TL_DW; + parameter int BusIntgWidth = tlul_pkg::DataIntgWidth; + parameter int BusFullWidth = BusWidth + BusIntgWidth; parameter int MpRegions = 8; // flash controller protection regions parameter int FifoDepth = 16; // rd / prog fifos parameter int InfoTypesWidth = prim_util_pkg::vbits(InfoTypes); @@ -381,7 +383,7 @@ flash_part_e part; logic [InfoTypesWidth-1:0] info_sel; logic [BusAddrW-1:0] addr; - logic [BusWidth-1:0] prog_data; + logic [BusFullWidth-1:0] prog_data; logic prog_last; flash_prog_e prog_type; mp_region_cfg_t [MpRegions:0] region_cfgs; @@ -392,7 +394,6 @@ logic alert_trig; logic alert_ack; jtag_pkg::jtag_req_t jtag_req; - logic intg_err; prim_mubi_pkg::mubi4_t flash_disable; } flash_req_t; @@ -422,7 +423,6 @@ alert_trig: 1'b0, alert_ack: 1'b0, jtag_req: '0, - intg_err: '0, flash_disable: prim_mubi_pkg::MuBi4False };
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv index b6807de..4ddd3c0 100644 --- a/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv +++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_arb.sv
@@ -32,7 +32,7 @@ // software interface to prog_fifo input sw_wvalid_i, output logic sw_wready_o, - input [BusWidth-1:0] sw_wdata_i, + input [BusFullWidth-1:0] sw_wdata_i, // hardware interface to rd_ctrl / erase_ctrl input hw_req_i, @@ -48,7 +48,7 @@ // hardware interface to prog_fifo input hw_wvalid_i, - input [BusWidth-1:0] hw_wdata_i, + input [BusFullWidth-1:0] hw_wdata_i, output logic hw_wready_o, // muxed interface to rd_ctrl / erase_ctrl @@ -70,7 +70,7 @@ // muxed interface to prog_fifo output logic prog_fifo_wvalid_o, - output logic [BusWidth-1:0] prog_fifo_wdata_o, + output logic [BusFullWidth-1:0] prog_fifo_wdata_o, input logic prog_fifo_wready_i, // flash phy initialization ongoing
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_prog.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_prog.sv index 9bc468a..e164bd7 100644 --- a/hw/ip/flash_ctrl/rtl/flash_ctrl_prog.sv +++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_prog.sv
@@ -23,14 +23,14 @@ // FIFO Interface input data_rdy_i, - input [BusWidth-1:0] data_i, + input [BusFullWidth-1:0] data_i, output logic data_rd_o, // Flash Macro Interface output logic flash_req_o, output logic [BusAddrW-1:0] flash_addr_o, output logic flash_ovfl_o, - output logic [BusWidth-1:0] flash_data_o, + output logic [BusFullWidth-1:0] flash_data_o, output logic flash_last_o, // last beat of prog data output flash_prog_e flash_type_o, input flash_done_i,
diff --git a/hw/ip/flash_ctrl/rtl/flash_phy.sv b/hw/ip/flash_ctrl/rtl/flash_phy.sv index 6100800..fd1dfae 100644 --- a/hw/ip/flash_ctrl/rtl/flash_phy.sv +++ b/hw/ip/flash_ctrl/rtl/flash_phy.sv
@@ -20,7 +20,6 @@ input clk_i, input rst_ni, input host_req_i, - input host_intg_err_i, input [BusAddrW-1:0] host_addr_i, output logic host_req_rdy_o, output logic host_req_done_o, @@ -91,9 +90,12 @@ logic [BusWidth-1:0] rd_data [NumBanks]; logic [NumBanks-1:0] rd_err; - // fsm error per block + // fsm error per bank logic [NumBanks-1:0] fsm_err; + // integrity error per bank + logic [NumBanks-1:0] intg_err; + // select which bank each is operating on assign host_bank_sel = host_req_i ? host_addr_i[BusAddrW-1 -: BankW] : '0; assign ctrl_bank_sel = flash_ctrl_i.addr[BusAddrW-1 -: BankW]; @@ -114,8 +116,7 @@ assign flash_ctrl_o.rd_data = rd_data[ctrl_bank_sel]; assign flash_ctrl_o.rd_err = rd_err[ctrl_bank_sel]; assign flash_ctrl_o.init_busy = init_busy; - // feed through host integrity error directly - assign flash_ctrl_o.intg_err = host_intg_err_i; + assign flash_ctrl_o.intg_err = |intg_err; assign flash_ctrl_o.fsm_err = |fsm_err; @@ -224,7 +225,6 @@ .clk_i, .rst_ni, // integrity error is either from host or from controller - .intg_err_i(host_intg_err_i | flash_ctrl_i.intg_err), .req_i(ctrl_req), .scramble_en_i(flash_ctrl_i.scramble_en), .ecc_en_i(flash_ctrl_i.ecc_en), @@ -263,7 +263,8 @@ .prim_flash_rsp_i(prim_flash_rsp[bank]), .ecc_single_err_o(ecc_single_err[bank]), .ecc_addr_o(ecc_addr[bank][BusBankAddrW-1:0]), - .fsm_err_o(fsm_err[bank]) + .fsm_err_o(fsm_err[bank]), + .intg_err_o(intg_err[bank]) ); end // block: gen_flash_banks
diff --git a/hw/ip/flash_ctrl/rtl/flash_phy_core.sv b/hw/ip/flash_ctrl/rtl/flash_phy_core.sv index 977f0d2..0482767 100644 --- a/hw/ip/flash_ctrl/rtl/flash_phy_core.sv +++ b/hw/ip/flash_ctrl/rtl/flash_phy_core.sv
@@ -17,7 +17,6 @@ ) ( input clk_i, input rst_ni, - input intg_err_i, input host_req_i, // host request - read only input host_scramble_en_i, input host_ecc_en_i, @@ -34,7 +33,7 @@ input flash_ctrl_pkg::flash_part_e part_i, input [InfoTypesWidth-1:0] info_sel_i, input [BusBankAddrW-1:0] addr_i, - input [BusWidth-1:0] prog_data_i, + 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, @@ -54,7 +53,8 @@ output logic rd_err_o, output logic ecc_single_err_o, output logic [BusBankAddrW-1:0] ecc_addr_o, - output logic fsm_err_o + output logic fsm_err_o, + output logic intg_err_o ); @@ -351,7 +351,7 @@ if (WidthMultiple == 1) begin : gen_single_prog_data assign flash_prog_req = reqs[PhyProg]; - assign prog_data = prog_data_i; + assign prog_data = prog_data_i[BusWidth-1:0]; assign prog_fsm_err = '0; end else begin : gen_prog_data @@ -378,7 +378,8 @@ .ack_o(prog_ack), .block_data_o(prog_data), .data_o(prog_full_data), - .fsm_err_o(prog_fsm_err) + .fsm_err_o(prog_fsm_err), + .intg_err_o ); end @@ -418,7 +419,7 @@ .clk_i, .rst_ni, // both escalation and and integrity error cause the scramble keys to change - .intg_err_i(intg_err_i | mubi4_test_true_loose(flash_disable[ScrDisableIdx])), + .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),
diff --git a/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv b/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv index 8a1cb2d..8749cf4 100644 --- a/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv +++ b/hw/ip/flash_ctrl/rtl/flash_phy_pkg.sv
@@ -32,6 +32,7 @@ // flash ctrl / bus parameters parameter int unsigned BusWidth = flash_ctrl_pkg::BusWidth; + parameter int unsigned BusFullWidth = flash_ctrl_pkg::BusFullWidth; parameter int unsigned BusBankAddrW = flash_ctrl_pkg::BusBankAddrW; parameter int unsigned BusWordW = flash_ctrl_pkg::BusWordW; parameter int unsigned ProgTypes = flash_ctrl_pkg::ProgTypes;
diff --git a/hw/ip/flash_ctrl/rtl/flash_phy_prog.sv b/hw/ip/flash_ctrl/rtl/flash_phy_prog.sv index 2306941..f7f670e 100644 --- a/hw/ip/flash_ctrl/rtl/flash_phy_prog.sv +++ b/hw/ip/flash_ctrl/rtl/flash_phy_prog.sv
@@ -28,7 +28,7 @@ input scramble_i, input ecc_i, input [WordSelW-1:0] sel_i, - input [BusWidth-1:0] data_i, + input [BusFullWidth-1:0] data_i, input last_i, input ack_i, // ack means request has been accepted by flash input done_i, // done means requested transaction has completed @@ -44,7 +44,8 @@ // block data does not contain ecc / metadata portion output logic [DataWidth-1:0] block_data_o, output logic [FullDataWidth-1:0] data_o, - output logic fsm_err_o + output logic fsm_err_o, + output logic intg_err_o ); // Encoding generated with: @@ -106,7 +107,42 @@ logic plain_ecc_en; // selects empty data or real data - assign pack_data = (data_sel == Actual) ? data_i : {BusWidth{1'b1}}; + assign pack_data = (data_sel == Actual) ? data_i[BusWidth-1:0] : {BusWidth{1'b1}}; + + logic data_intg_ok; + logic [1:0] data_err; + + // TODO: for clarity purposes, tlul should have an integrity wrapper module that is + // instantiated here. That way the module does not need to know exactly what is used. + prim_secded_inv_39_32_dec u_data_intg_chk ( + .data_i(data_i), + .data_o(), + .syndrome_o(), + .err_o(data_err) + ); + assign data_intg_ok = (data_err == '0); + + logic data_invalid_q, data_invalid_d; + // hold on integrity failure indication until reset + assign data_invalid_d = data_invalid_q | + (pack_valid & ~data_intg_ok); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + data_invalid_q <= '0; + end else begin + data_invalid_q <= data_invalid_d; + end + end + + // indication to upper layer prescence of error + assign intg_err_o = data_invalid_q; + + // if integrity failure is seen, fake communication with flash + // and simply terminate + logic ack, done; + assign ack = ack_i | data_invalid_q; + assign done = done_i | data_invalid_q; // next idx will be aligned assign idx_sub_one = idx - 1'b1; @@ -230,7 +266,8 @@ end StReqFlash: begin - req_o = 1'b1; + // only request flash if data integrity was valid + req_o = ~data_invalid_q; last_o = last_i; // if this is the last beat of the program burst @@ -238,16 +275,15 @@ // if this is NOT the last beat // - ack the upstream request and accept more beats if (last_i) begin - state_d = ack_i ? StWaitFlash : StReqFlash; + state_d = ack ? StWaitFlash : StReqFlash; end else begin - ack_o = ack_i; - state_d = ack_i ? StIdle : StReqFlash; + ack_o = ack; + state_d = ack ? StIdle : StReqFlash; end end StWaitFlash: begin - - if (done_i) begin + if (done) begin ack_o = 1'b1; state_d = StIdle; end @@ -270,7 +306,7 @@ if (!rst_ni) begin packed_data <= '0; mask_q <= '0; - end else if (req_o && ack_i) begin + end else if (req_o && ack) begin packed_data <= '0; end else if (calc_req_o && calc_ack_i) begin packed_data <= packed_data ^ mask_i; @@ -335,7 +371,7 @@ done_cnt <= '0; end else if (txn_done) begin done_cnt <= '0; - end else if (done_i) begin + end else if (done) begin done_cnt <= done_cnt + 1'b1; end end
diff --git a/hw/ip/flash_ctrl/rtl/flash_phy_scramble.sv b/hw/ip/flash_ctrl/rtl/flash_phy_scramble.sv index 062e06e..ddf5b4e 100644 --- a/hw/ip/flash_ctrl/rtl/flash_phy_scramble.sv +++ b/hw/ip/flash_ctrl/rtl/flash_phy_scramble.sv
@@ -14,7 +14,7 @@ ) ( input clk_i, input rst_ni, - input intg_err_i, + input disable_i, input calc_req_i, // calculate galois multiplier mask input op_req_i, // request primitive operation input cipher_ops_e op_type_i, // sramble or de-scramble @@ -43,7 +43,7 @@ if (!rst_ni) begin addr_key_sel <= '0; end else if (!calc_req_i || calc_req_i && calc_ack_o) begin - addr_key_sel <= intg_err_i; + addr_key_sel <= disable_i; end end @@ -94,7 +94,7 @@ if (!rst_ni) begin data_key_sel <= '0; end else if (!op_req_i || op_req_i && op_ack_o) begin - data_key_sel <= intg_err_i; + data_key_sel <= disable_i; end end