@@ -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
15361531endmodule // csrng_core
0 commit comments