Skip to content

Commit

Permalink
[otp_ctrl] Fix OOB error in DAI
Browse files Browse the repository at this point in the history
We did not hit this corner case before since the OTP array
was fully populated. The new parameterization is not yet
fully complete and may not be fully populated, hence we
should add an OOB check.

Signed-off-by: Michael Schaffner <[email protected]>
  • Loading branch information
msfschaffner committed Jan 23, 2024
1 parent be3312f commit 2ba74d6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 14 deletions.
4 changes: 2 additions & 2 deletions hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_lock_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ class otp_ctrl_dai_lock_vseq extends otp_ctrl_smoke_vseq;
if (part_idx == Secret0Idx) dai_addr inside `PART_ADDR_RANGE(Secret0Idx);
if (part_idx == Secret1Idx) dai_addr inside `PART_ADDR_RANGE(Secret1Idx);
if (part_idx == Secret2Idx) dai_addr inside `PART_ADDR_RANGE(Secret2Idx);
if (part_idx == LifeCycleIdx && write_unused_addr) {
if (part_idx == LifeCycleIdx) {
if (write_unused_addr) {
// Dai address input is only 11 bits wide.
dai_addr inside {[PartInfo[LifeCycleIdx].offset : {11{1'b1}}]};
} else {
dai_addr inside {[PartInfo[LifeCycleIdx].offset : '1]};
dai_addr inside `PART_ADDR_RANGE(LifeCycleIdx);
}
}
solve part_idx before dai_addr;
Expand Down
28 changes: 16 additions & 12 deletions hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ module otp_ctrl_dai
logic [ScrmblBlockWidth-1:0] data_q;
logic [NumPartWidth-1:0] part_idx;
logic [NumPart-1:0][OtpAddrWidth-1:0] digest_addr_lut;
logic part_sel_valid;

// Output partition error state.
assign error_o = error_q;
Expand Down Expand Up @@ -297,9 +298,10 @@ module otp_ctrl_dai
// that is the case, we immediately bail out. Otherwise, we
// request a block of data from OTP.
ReadSt: begin
if (mubi8_test_false_strict(part_access_i[part_idx].read_lock) ||
// HW digests always remain readable.
PartInfo[part_idx].hw_digest && otp_addr_o == digest_addr_lut[part_idx]) begin
if (part_sel_valid && (mubi8_test_false_strict(part_access_i[part_idx].read_lock) ||
// HW digests always remain readable.
PartInfo[part_idx].hw_digest && otp_addr_o ==
digest_addr_lut[part_idx])) begin
otp_req_o = 1'b1;
// Depending on the partition configuration,
// the wrapper is instructed to ignore integrity errors.
Expand All @@ -324,9 +326,10 @@ module otp_ctrl_dai
// terminal error state.
ReadWaitSt: begin
// Continuously check read access and bail out if this is not consistent.
if (mubi8_test_false_strict(part_access_i[part_idx].read_lock) ||
// HW digests always remain readable.
PartInfo[part_idx].hw_digest && otp_addr_o == digest_addr_lut[part_idx]) begin
if (part_sel_valid && (mubi8_test_false_strict(part_access_i[part_idx].read_lock) ||
// HW digests always remain readable.
PartInfo[part_idx].hw_digest && otp_addr_o ==
digest_addr_lut[part_idx])) begin
if (otp_rvalid_i) begin
// Check OTP return code.
if (otp_err_e'(otp_err_i) inside {NoError, MacroEccCorrError}) begin
Expand Down Expand Up @@ -393,7 +396,7 @@ module otp_ctrl_dai
// permanently write locked and can hence not be written via the DAI.
WriteSt: begin
dai_prog_idle_o = 1'b0;
if (mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
// If this is a HW digest write to a buffered partition.
((PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].hw_digest &&
base_sel_q == PartOffset && otp_addr_o == digest_addr_lut[part_idx]) ||
Expand Down Expand Up @@ -428,7 +431,7 @@ module otp_ctrl_dai
WriteWaitSt: begin
dai_prog_idle_o = 1'b0;
// Continuously check write access and bail out if this is not consistent.
if (mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
// If this is a HW digest write to a buffered partition.
((PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].hw_digest &&
base_sel_q == PartOffset && otp_addr_o == digest_addr_lut[part_idx]) ||
Expand Down Expand Up @@ -471,7 +474,7 @@ module otp_ctrl_dai
ScrSt: begin
scrmbl_mtx_req_o = 1'b1;
// Check write access and bail out if this is not consistent.
if (mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
// If this is a non HW digest write to a buffered partition.
(PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].secret &&
PartInfo[part_idx].hw_digest && base_sel_q == DaiOffset &&
Expand All @@ -496,7 +499,7 @@ module otp_ctrl_dai
ScrWaitSt: begin
scrmbl_mtx_req_o = 1'b1;
// Continously check write access and bail out if this is not consistent.
if (mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) &&
// If this is a non HW digest write to a buffered partition.
(PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].secret &&
PartInfo[part_idx].hw_digest && base_sel_q == DaiOffset &&
Expand Down Expand Up @@ -532,7 +535,8 @@ module otp_ctrl_dai
// SEC_CM: PART.MEM.DIGEST
DigReadSt: begin
scrmbl_mtx_req_o = 1'b1;
if (mubi8_test_false_strict(part_access_i[part_idx].read_lock) &&
if (part_sel_valid &&
mubi8_test_false_strict(part_access_i[part_idx].read_lock) &&
mubi8_test_false_strict(part_access_i[part_idx].write_lock)) begin
otp_req_o = 1'b1;
// Depending on the partition configuration,
Expand Down Expand Up @@ -716,7 +720,7 @@ module otp_ctrl_dai
.data_i ( '{default: '0} ),
.gnt_o ( ), // unused
.idx_o ( part_idx ),
.valid_o ( ), // unused
.valid_o ( part_sel_valid ), // used for detecting OOB addresses
.data_o ( ), // unused
.ready_i ( 1'b0 )
);
Expand Down

0 comments on commit 2ba74d6

Please sign in to comment.