Skip to content

Commit ac76d00

Browse files
committed
[csrng/csrng_core] Rework the state db arbitration
Replace the toggle-style state db arbitration by a simple valid-based scheme that leverages the fact that the ctr_drbg_gen and ctr_drbg_cmd units cannot deadlock or starve each other. Signed-off-by: Florian Glaser <[email protected]>
1 parent 0136fdb commit ac76d00

File tree

4 files changed

+27
-31
lines changed

4 files changed

+27
-31
lines changed

hw/ip/csrng/dv/env/seq_lib/csrng_err_vseq.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class csrng_err_vseq extends csrng_base_vseq;
6060
$assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A");
6161
$assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M");
6262
$assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M");
63+
$assertoff(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A");
6364
$assertoff(0, `HIER_PATH(`CMD_STAGE_0, u_state_regs_A));
6465
$assertoff(0, `HIER_PATH(`CMD_STAGE_1, u_state_regs_A));
6566
$assertoff(0, `HIER_PATH(`CMD_STAGE_2, u_state_regs_A));
@@ -361,6 +362,7 @@ class csrng_err_vseq extends csrng_base_vseq;
361362
$asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A");
362363
$asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M");
363364
$asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M");
365+
$asserton(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A");
364366
$asserton(0, `HIER_PATH(`CMD_STAGE_0, u_state_regs_A));
365367
$asserton(0, `HIER_PATH(`CMD_STAGE_1, u_state_regs_A));
366368
$asserton(0, `HIER_PATH(`CMD_STAGE_2, u_state_regs_A));

hw/ip/csrng/dv/env/seq_lib/csrng_intr_vseq.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ class csrng_intr_vseq extends csrng_base_vseq;
359359
$assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A");
360360
$assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M");
361361
$assertoff(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M");
362+
$assertoff(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A");
362363
$assertoff(0, `HIER_PATH(`CMD_STAGE_0, CsrngCmdStageGenbitsFifoPushExpected_A));
363364
$assertoff(0, `HIER_PATH(`CMD_STAGE_1, CsrngCmdStageGenbitsFifoPushExpected_A));
364365
$assertoff(0, `HIER_PATH(`CMD_STAGE_2, CsrngCmdStageGenbitsFifoPushExpected_A));
@@ -399,6 +400,7 @@ class csrng_intr_vseq extends csrng_base_vseq;
399400
$asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.LockArbDecision_A");
400401
$asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_benblk_arb.ReqStaysHighUntilGranted0_M");
401402
$asserton(0, "tb.dut.u_csrng_core.u_prim_arbiter_ppc_updblk_arb.ReqStaysHighUntilGranted0_M");
403+
$asserton(0, "tb.dut.u_csrng_core.CsrngNoConcurrentGenCmdRsp_A");
402404
$asserton(0, `HIER_PATH(`CMD_STAGE_0, CsrngCmdStageGenbitsFifoPushExpected_A));
403405
$asserton(0, `HIER_PATH(`CMD_STAGE_1, CsrngCmdStageGenbitsFifoPushExpected_A));
404406
$asserton(0, `HIER_PATH(`CMD_STAGE_2, CsrngCmdStageGenbitsFifoPushExpected_A));

hw/ip/csrng/rtl/csrng_core.sv

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,7 @@ module csrng_core import csrng_pkg::*; #(
8585
logic acmd_mop;
8686
logic acmd_eop;
8787

88-
logic cmd_blk_select;
89-
logic gen_blk_select;
90-
9188
logic state_db_wr_vld;
92-
logic state_db_wr_rdy;
9389
csrng_core_data_t state_db_wr_data;
9490
csrng_cmd_sts_e state_db_wr_sts;
9591
csrng_state_t state_db_rd_data;
@@ -112,7 +108,6 @@ module csrng_core import csrng_pkg::*; #(
112108
logic ctr_drbg_cmd_rsp_rdy;
113109
csrng_core_data_t ctr_drbg_cmd_rsp_data;
114110
logic ctr_drbg_cmd_rsp_glast;
115-
logic ctr_drbg_cmd_rsp_wr;
116111

117112
logic ctr_drbg_cmd_req_vld;
118113
logic ctr_drbg_cmd_req_rdy;
@@ -296,7 +291,6 @@ module csrng_core import csrng_pkg::*; #(
296291
logic gen_last_q, gen_last_d;
297292
mubi4_t flag0_q, flag0_d;
298293
logic [NumAppsLg-1:0] cmd_arb_idx_q, cmd_arb_idx_d;
299-
logic statedb_wr_select_q, statedb_wr_select_d;
300294
logic genbits_stage_fips_sw_q, genbits_stage_fips_sw_d;
301295
logic [CmdWidth-1:0] cmd_req_ccmd_dly_q, cmd_req_ccmd_dly_d;
302296
logic cs_aes_halt_q, cs_aes_halt_d;
@@ -315,7 +309,6 @@ module csrng_core import csrng_pkg::*; #(
315309
gen_last_q <= '0;
316310
flag0_q <= prim_mubi_pkg::MuBi4False;
317311
cmd_arb_idx_q <= '0;
318-
statedb_wr_select_q <= '0;
319312
genbits_stage_fips_sw_q <= '0;
320313
cmd_req_ccmd_dly_q <= '0;
321314
cs_aes_halt_q <= '0;
@@ -332,7 +325,6 @@ module csrng_core import csrng_pkg::*; #(
332325
gen_last_q <= gen_last_d;
333326
flag0_q <= flag0_d;
334327
cmd_arb_idx_q <= cmd_arb_idx_d;
335-
statedb_wr_select_q <= statedb_wr_select_d;
336328
genbits_stage_fips_sw_q <= genbits_stage_fips_sw_d;
337329
cmd_req_ccmd_dly_q <= cmd_req_ccmd_dly_d;
338330
cs_aes_halt_q <= cs_aes_halt_d;
@@ -786,10 +778,9 @@ module csrng_core import csrng_pkg::*; #(
786778

787779
// Set reseed_cnt_reached_d to true if the max number of generate requests between reseeds
788780
// has been reached for the respective counter.
789-
assign reseed_cnt_reached_d[ai] =
790-
state_db_wr_vld && state_db_wr_rdy && (state_db_wr_data.inst_id == ai) ?
791-
(state_db_wr_data.rs_ctr >= reg2hw.reseed_interval.q) :
792-
reseed_cnt_reached_q[ai];
781+
assign reseed_cnt_reached_d[ai] = (state_db_wr_vld && (state_db_wr_data.inst_id == ai)) ?
782+
(state_db_wr_data.rs_ctr >= reg2hw.reseed_interval.q) :
783+
reseed_cnt_reached_q[ai];
793784

794785
end : gen_cmd_stage
795786

@@ -1092,7 +1083,6 @@ module csrng_core import csrng_pkg::*; #(
10921083
// of each csrng instance. The state
10931084
// is updated after each command.
10941085

1095-
assign ctr_drbg_cmd_rsp_wr = ctr_drbg_cmd_rsp_vld && (ctr_drbg_cmd_rsp_data.cmd != GEN);
10961086
assign state_db_reg_read_en = cs_enable_fo[40] && read_int_state && otp_sw_app_read_en[1];
10971087

10981088
csrng_state_db u_csrng_state_db (
@@ -1104,7 +1094,6 @@ module csrng_core import csrng_pkg::*; #(
11041094
.rd_state_o (state_db_rd_data),
11051095

11061096
.wr_vld_i (state_db_wr_vld),
1107-
.wr_rdy_o (state_db_wr_rdy),
11081097
.wr_data_i (state_db_wr_data),
11091098
.wr_status_i(state_db_wr_sts),
11101099

@@ -1123,19 +1112,22 @@ module csrng_core import csrng_pkg::*; #(
11231112
.reseed_counter_o(reseed_counter)
11241113
);
11251114

1126-
assign statedb_wr_select_d = (!cs_enable_fo[42]) ? 1'b0 : !statedb_wr_select_q;
1115+
logic cmd_rsp_to_state_db;
11271116

1128-
assign cmd_blk_select = !statedb_wr_select_q;
1129-
assign gen_blk_select = statedb_wr_select_q;
1117+
// Keep forwarding gen unit responses to the state db unless the cmd unit has a valid response.
1118+
assign cmd_rsp_to_state_db = (ctr_drbg_cmd_rsp_data.cmd != GEN) && (ctr_drbg_cmd_rsp_vld == 1'b1);
11301119

1131-
// return to requesting block
1132-
assign ctr_drbg_cmd_rsp_rdy = (cmd_blk_select && state_db_wr_rdy) && ctr_drbg_gen_req_rdy;
1133-
assign ctr_drbg_gen_rsp_rdy = gen_blk_select && state_db_wr_rdy;
1120+
assign state_db_wr_vld = cmd_rsp_to_state_db ? ctr_drbg_cmd_rsp_vld : ctr_drbg_gen_rsp_vld;
1121+
assign state_db_wr_data = cmd_rsp_to_state_db ? ctr_drbg_cmd_rsp_data : ctr_drbg_gen_rsp_data;
1122+
assign state_db_wr_sts = cmd_rsp_to_state_db ? CMD_STS_SUCCESS : ctr_drbg_gen_rsp_sts;
11341123

1135-
// Mux either generate or command stage result to state db
1136-
assign state_db_wr_vld = gen_blk_select ? ctr_drbg_gen_rsp_vld : ctr_drbg_cmd_rsp_wr;
1137-
assign state_db_wr_data = gen_blk_select ? ctr_drbg_gen_rsp_data : ctr_drbg_cmd_rsp_data;
1138-
assign state_db_wr_sts = gen_blk_select ? ctr_drbg_gen_rsp_sts : CMD_STS_SUCCESS;
1124+
// Tie gen unit request to zero if cmd unit writes to state db
1125+
assign ctr_drbg_gen_req_vld = cmd_rsp_to_state_db ? 1'b0 : ctr_drbg_cmd_rsp_vld;
1126+
// State db is always ready to write; the respective response ready signal can be tied high
1127+
assign ctr_drbg_gen_rsp_rdy = cmd_rsp_to_state_db ? 1'b0 : 1'b1;
1128+
// Response ready for cmd unit cannot depend on its response valid to avoid combinational loop,
1129+
// hence cmd_rsp_to_state_db cannot be used here.
1130+
assign ctr_drbg_cmd_rsp_rdy = (ctr_drbg_cmd_rsp_data.cmd == GEN) ? ctr_drbg_gen_req_rdy : 1'b1;
11391131

11401132
// Forward the reseed counter values to the register interface.
11411133
always_comb begin : reseed_counter_assign
@@ -1407,8 +1399,6 @@ module csrng_core import csrng_pkg::*; #(
14071399
// of the sequence is done by the
14081400
// csrng_ctr_drbg_cmd block.
14091401

1410-
assign ctr_drbg_gen_req_vld = ctr_drbg_cmd_rsp_vld && (ctr_drbg_cmd_rsp_data.cmd == GEN);
1411-
14121402
csrng_ctr_drbg_gen u_csrng_ctr_drbg_gen (
14131403
.clk_i (clk_i),
14141404
.rst_ni (rst_ni),
@@ -1486,10 +1476,11 @@ module csrng_core import csrng_pkg::*; #(
14861476
logic [SeedLen-1:0] unused_gen_rsp_pdata;
14871477
logic unused_state_db_inst_state;
14881478

1489-
assign unused_err_code_test_bit = (|err_code_test_bit[19:16]) || (|err_code_test_bit[27:26]) ||
1479+
assign unused_err_code_test_bit = err_code_test_bit[27] || (|err_code_test_bit[19:16]) ||
14901480
err_code_test_bit[8] || (|err_code_test_bit[6:5]) ||
14911481
err_code_test_bit[2];
1492-
assign unused_enable_fo = cs_enable_fo[10] || (|cs_enable_fo[8:7]) || cs_enable_fo[4];
1482+
assign unused_enable_fo = cs_enable_fo[42] || cs_enable_fo[10] || (|cs_enable_fo[8:7]) ||
1483+
cs_enable_fo[4];
14931484
assign unused_reg2hw_genbits = (|reg2hw.genbits.q);
14941485
assign unused_int_state_val = (|reg2hw.int_state_val.q);
14951486
assign unused_reseed_interval = reg2hw.reseed_interval.qe;
@@ -1531,6 +1522,10 @@ module csrng_core import csrng_pkg::*; #(
15311522
`ASSERT(CsrngUniZeroizeV_A, state_db_zeroize -> (state_db_wr_data.v == '0))
15321523
`ASSERT(CsrngUniZeroizeRc_A, state_db_zeroize -> (state_db_wr_data.rs_ctr == '0))
15331524
`ASSERT(CsrngUniZeroizeSts_A, state_db_zeroize -> (state_db_wr_sts == '0))
1525+
1526+
// Ensure that the ctr_drbg_generate and ctr_drbg_command units never try to write to the
1527+
// state db at the same time.
1528+
`ASSERT(CsrngNoConcurrentGenCmdRsp_A, !(ctr_drbg_cmd_rsp_vld && ctr_drbg_gen_rsp_vld))
15341529
`endif
15351530

15361531
endmodule // csrng_core

hw/ip/csrng/rtl/csrng_state_db.sv

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ module csrng_state_db
2727

2828
// Write interface
2929
input logic wr_vld_i,
30-
output logic wr_rdy_o,
3130
input csrng_core_data_t wr_data_i,
3231
input csrng_cmd_sts_e wr_status_i,
3332

@@ -167,8 +166,6 @@ module csrng_state_db
167166
assign status_val_o = status_val_q;
168167
assign status_inst_id_o = status_inst_id_q;
169168

170-
assign wr_rdy_o = 1'b1;
171-
172169
// Unused signals
173170
logic [SeedLen-1:0] unused_wdata_pdata;
174171
logic [InstIdWidth-NumAppsLg-1:0] unused_reg_rd_id, unused_rd_inst_id;

0 commit comments

Comments
 (0)