Skip to content

Commit

Permalink
[otp_ctrl] Fix UNKNOWN error due to array indexing
Browse files Browse the repository at this point in the history
Under error conditions, the ECC register array may be indexed
with an invalid index, thus producing Xes in RTL.

This patch ensures that we always output defined data from the
ECC register, no matter the index value.

Signed-off-by: Michael Schaffner <[email protected]>
  • Loading branch information
msfschaffner committed Jan 23, 2024
1 parent 2ba74d6 commit 914dee7
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 17 deletions.
26 changes: 18 additions & 8 deletions hw/ip/otp_ctrl/rtl/otp_ctrl_ecc_reg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module otp_ctrl_ecc_reg #(
input logic wren_i,
input logic [Aw-1:0] addr_i,
input logic [Width-1:0] wdata_i,
output logic [Width-1:0] rdata_o,

// Concurrent output of the register state.
output logic [Depth-1:0][Width-1:0] data_o,
Expand Down Expand Up @@ -46,8 +47,12 @@ module otp_ctrl_ecc_reg #(
data_d = data_q;
ecc_d = ecc_q;

if (wren_i && 32'(addr_i) < Depth) begin
{ecc_d[0], data_d[0]} = ecc_enc;
rdata_o = '0;
if (32'(addr_i) < Depth) begin
rdata_o = data_q[0];
if (wren_i) begin
{ecc_d[0], data_d[0]} = ecc_enc;
end
end
end
end else begin : gen_multiple_words
Expand All @@ -56,8 +61,12 @@ module otp_ctrl_ecc_reg #(
data_d = data_q;
ecc_d = ecc_q;

if (wren_i && 32'(addr_i) < Depth) begin
{ecc_d[addr_i], data_d[addr_i]} = ecc_enc;
rdata_o = '0;
if (32'(addr_i) < Depth) begin
rdata_o = data_q[addr_i];
if (wren_i) begin
{ecc_d[addr_i], data_d[addr_i]} = ecc_enc;
end
end
end
end
Expand Down Expand Up @@ -87,9 +96,10 @@ module otp_ctrl_ecc_reg #(
end
end

`ASSERT_KNOWN(EccKnown_A, ecc_q)
`ASSERT_KNOWN(DataKnown_A, data_q)
`ASSERT_KNOWN(DataOutKnown_A, data_o)
`ASSERT_KNOWN(EccErrKnown_A, ecc_err_o)
`ASSERT_KNOWN(EccKnown_A, ecc_q)
`ASSERT_KNOWN(DataKnown_A, data_q)
`ASSERT_KNOWN(RDataOutKnown_A, rdata_o)
`ASSERT_KNOWN(DataOutKnown_A, data_o)
`ASSERT_KNOWN(EccErrKnown_A, ecc_err_o)

endmodule : otp_ctrl_ecc_reg
7 changes: 3 additions & 4 deletions hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv
Original file line number Diff line number Diff line change
Expand Up @@ -637,25 +637,24 @@ module otp_ctrl_part_buf
// Always transfer 64bit blocks.
assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1);

logic [Info.size*8-1:0] data;
assign scrmbl_data_o = data[{cnt, {$clog2(ScrmblBlockWidth){1'b0}}} +: ScrmblBlockWidth];

assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;

/////////////////
// Buffer Regs //
/////////////////

// SEC_CM: PART.DATA_REG.INTEGRITY
logic [Info.size*8-1:0] data;
otp_ctrl_ecc_reg #(
.Width ( ScrmblBlockWidth ),
.Depth ( NumScrmblBlocks )
) u_otp_ctrl_ecc_reg (
.clk_i,
.rst_ni,
.wren_i ( buffer_reg_en ),
.addr_i ( cnt ),
.addr_i ( cnt ),
.wdata_i ( data_mux ),
.rdata_o ( scrmbl_data_o ),
.data_o ( data ),
.ecc_err_o ( ecc_err )
);
Expand Down
11 changes: 6 additions & 5 deletions hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,12 @@ module otp_ctrl_part_unbuf
) u_otp_ctrl_ecc_reg (
.clk_i,
.rst_ni,
.wren_i ( digest_reg_en ),
.addr_i ( '0 ),
.wdata_i ( otp_rdata_i ),
.data_o ( digest_o ),
.ecc_err_o ( ecc_err )
.wren_i ( digest_reg_en ),
.addr_i ( '0 ),
.wdata_i ( otp_rdata_i ),
.rdata_o ( ),
.data_o ( digest_o ),
.ecc_err_o ( ecc_err )
);
end else begin : gen_no_ecc_reg
logic unused_digest_reg_en;
Expand Down

0 comments on commit 914dee7

Please sign in to comment.