[csrng/rtl] internal state read timing improvements
Re-structed the read flow for the internal state array.
Added parameter to prim_fifo_sync to remove output mux.
Added simple flops to break up configuration paths.
Added fifo output mux back for genbits to prevent assertion.
Cleaned up format for hjson file.
Updated internal state rtl based on feedback.
Fixed hjson register wording.
Added comment for FIFO parameter use.
Signed-off-by: Mark Branstad <mark.branstad@wdc.com>
diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson
index fb476c0..940fd1e 100644
--- a/hw/ip/csrng/data/csrng.hjson
+++ b/hw/ip/csrng/data/csrng.hjson
@@ -212,6 +212,46 @@
}
]
},
+ { name: "HALT_MAIN_SM",
+ desc: "Halt the CSRNG main state machine register",
+ swaccess: "wo",
+ hwaccess: "hro",
+ regwen: "REGWEN",
+ fields: [
+ {
+ bits: "0",
+ name: "HALT_MAIN_SM",
+ desc: '''
+ Setting this bit halts the main state machine that processes
+ csrng application commands. The purpose of this register is to
+ allow reading the internal state registers in a controlled manner.
+ After this bit is set, the status bit should be polled to determine if the
+ state machine has halted. Once halted, the internal state can be read
+ out. To resume operation, this bit should be reset.
+ '''
+ },
+ ]
+ },
+ { name: "MAIN_SM_STS",
+ desc: "CSRNG main state machine status register",
+ swaccess: "ro",
+ hwaccess: "hwo",
+ fields: [
+ { bits: "0",
+ name: "MAIN_SM_STS",
+ desc: '''
+ This bit indicates when the CSRNG main state machine has been halted.
+ When the halt bit is set, this bit should be polled until this
+ status bit is set. When set, it is safe to read the internal state
+ registers. When the halt bit is cleared, this register can be
+ polled to make sure the main state machine is operational again.
+ '''
+ tags: [// Internal HW can modify status register
+ "excl:CsrAllTests:CsrExclCheck"]
+ resval: "0"
+ }
+ ]
+ },
{ name: "INT_STATE_NUM",
desc: "Internal state number register",
swaccess: "rw",
diff --git a/hw/ip/csrng/rtl/csrng.sv b/hw/ip/csrng/rtl/csrng.sv
index ffee8c6..582cfaf 100644
--- a/hw/ip/csrng/rtl/csrng.sv
+++ b/hw/ip/csrng/rtl/csrng.sv
@@ -10,7 +10,7 @@
import csrng_pkg::*;
import csrng_reg_pkg::*;
#(
- parameter aes_pkg::sbox_impl_e SBoxImpl = aes_pkg::SBoxImplLut,
+ parameter aes_pkg::sbox_impl_e SBoxImpl = aes_pkg::SBoxImplCanright,
parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}},
parameter int NHwApps = 2
) (
diff --git a/hw/ip/csrng/rtl/csrng_cmd_stage.sv b/hw/ip/csrng/rtl/csrng_cmd_stage.sv
index 85940da..1d074f0 100644
--- a/hw/ip/csrng/rtl/csrng_cmd_stage.sv
+++ b/hw/ip/csrng/rtl/csrng_cmd_stage.sv
@@ -114,7 +114,8 @@
prim_fifo_sync #(
.Width(CmdFifoWidth),
.Pass(0),
- .Depth(CmdFifoDepth)
+ .Depth(CmdFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_cmd (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -320,7 +321,8 @@
prim_fifo_sync #(
.Width(GenBitsFifoWidth),
.Pass(0),
- .Depth(GenBitsFifoDepth)
+ .Depth(GenBitsFifoDepth),
+ .OutputZeroIfEmpty(1'b1) // Set to 1 to prevent triggering the output assert check for x's
) u_prim_fifo_genbits (
.clk_i (clk_i),
.rst_ni (rst_ni),
diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv
index f70960d..2b46146 100644
--- a/hw/ip/csrng/rtl/csrng_core.sv
+++ b/hw/ip/csrng/rtl/csrng_core.sv
@@ -125,7 +125,6 @@
logic update_req;
logic uninstant_req;
logic [3:0] fifo_sel;
- logic state_db_rd_req;
logic ctr_drbg_cmd_req;
logic ctr_drbg_gen_req;
logic ctr_drbg_gen_req_rdy;
@@ -297,6 +296,8 @@
logic state_db_reg_rd_id_pulse;
logic [StateId-1:0] state_db_reg_rd_id;
logic [31:0] state_db_reg_rd_val;
+ logic halt_main_sm;
+ logic main_sm_sts;
logic [30:0] err_code_test_bit;
@@ -306,6 +307,9 @@
logic flag0_q, flag0_d;
logic statedb_wr_select_q, statedb_wr_select_d;
logic genbits_stage_fips_sw_q, genbits_stage_fips_sw_d;
+ logic lc_hw_debug_not_on_q, lc_hw_debug_not_on_d;
+ logic lc_hw_debug_on_q, lc_hw_debug_on_d;
+ logic cmd_req_dly_q, cmd_req_dly_d;
always_ff @(posedge clk_i or negedge rst_ni)
if (!rst_ni) begin
@@ -314,12 +318,18 @@
flag0_q <= '0;
statedb_wr_select_q <= '0;
genbits_stage_fips_sw_q <= '0;
+ lc_hw_debug_not_on_q <= '0;
+ lc_hw_debug_on_q <= '0;
+ cmd_req_dly_q <= '0;
end else begin
acmd_q <= acmd_d;
shid_q <= shid_d;
flag0_q <= flag0_d;
statedb_wr_select_q <= statedb_wr_select_d;
genbits_stage_fips_sw_q <= genbits_stage_fips_sw_d;
+ lc_hw_debug_not_on_q <= lc_hw_debug_not_on_d;
+ lc_hw_debug_on_q <= lc_hw_debug_on_d;
+ cmd_req_dly_q <= cmd_req_dly_d;
end
//--------------------------------------------
@@ -776,7 +786,9 @@
assign shid = acmd_bus[15:12];
assign acmd_d = acmd_sop ? acmd_bus[2:0] : acmd_q;
- assign shid_d = acmd_sop ? shid : shid_q;
+ assign shid_d = acmd_sop ? shid :
+ state_db_reg_rd_id_pulse ? state_db_reg_rd_id :
+ shid_q;
assign flag0_d = acmd_sop ? flag0 : flag0_q;
// sm to process all instantiation requests
@@ -796,10 +808,11 @@
.generate_req_o(generate_req),
.update_req_o(update_req),
.uninstant_req_o(uninstant_req),
+ .halt_main_sm_i(halt_main_sm),
+ .main_sm_halted_o(main_sm_sts),
.main_sm_err_o(main_sm_err)
);
-
// interrupt for sw app interface only
assign event_cs_cmd_req_done = cmd_stage_ack[NApps-1];
@@ -850,15 +863,19 @@
// of each csrng instance. The state
// is updated after each command.
- assign state_db_rd_req = reseed_req || generate_req || update_req;
-
assign cmd_result_wr_req = cmd_result_ack && (cmd_result_ccmd != GEN);
// register read access
assign state_db_reg_rd_sel = reg2hw.int_state_val.re;
assign state_db_reg_rd_id = reg2hw.int_state_num.q;
assign state_db_reg_rd_id_pulse = reg2hw.int_state_num.qe;
- assign hw2reg.int_state_val.d = cs_enable ? state_db_reg_rd_val : '0;
+ assign hw2reg.int_state_val.d = state_db_reg_rd_val;
+
+ // main sm control
+ assign halt_main_sm = reg2hw.halt_main_sm.q;
+ assign hw2reg.main_sm_sts.de = 1'b1;
+ assign hw2reg.main_sm_sts.d = main_sm_sts;
+
csrng_state_db #(
.NApps(NApps),
@@ -871,7 +888,6 @@
.clk_i(clk_i),
.rst_ni(rst_ni),
.state_db_enable_i(cs_enable),
- .state_db_rd_req_i(state_db_rd_req),
.state_db_rd_inst_id_i(shid_q),
.state_db_rd_key_o(state_db_rd_key),
.state_db_rd_v_o(state_db_rd_v),
@@ -889,9 +905,8 @@
.state_db_wr_res_ctr_i(state_db_wr_rc),
.state_db_wr_sts_i(state_db_wr_sts),
- .state_db_lc_en_i(lc_hw_debug_on),
+ .state_db_lc_en_i(lc_hw_debug_on_q),
.state_db_reg_rd_sel_i(state_db_reg_rd_sel),
- .state_db_reg_rd_id_i(state_db_reg_rd_id),
.state_db_reg_rd_id_pulse_i(state_db_reg_rd_id_pulse),
.state_db_reg_rd_val_o(state_db_reg_rd_val),
.state_db_sts_ack_o(state_db_sts_ack),
@@ -960,9 +975,10 @@
- assign ctr_drbg_cmd_req =
+ assign cmd_req_dly_d =
instant_req || reseed_req || generate_req || update_req || uninstant_req;
+ assign ctr_drbg_cmd_req = cmd_req_dly_q;
csrng_ctr_drbg_cmd #(
.Cmd(Cmd),
@@ -1131,6 +1147,9 @@
assign lc_hw_debug_not_on = (lc_hw_debug_en_out[0] != lc_ctrl_pkg::On);
assign lc_hw_debug_on = (lc_hw_debug_en_out[1] == lc_ctrl_pkg::On);
+ // flop for better timing
+ assign lc_hw_debug_not_on_d = lc_hw_debug_not_on;
+ assign lc_hw_debug_on_d = lc_hw_debug_on;
//-------------------------------------
// csrng_block_encrypt instantiation
@@ -1153,7 +1172,7 @@
.rst_ni(rst_ni),
.block_encrypt_bypass_i(!aes_cipher_enable),
.block_encrypt_enable_i(cs_enable),
- .block_encrypt_lc_hw_debug_not_on_i(lc_hw_debug_not_on),
+ .block_encrypt_lc_hw_debug_not_on_i(lc_hw_debug_not_on_q),
.block_encrypt_req_i(benblk_arb_vld),
.block_encrypt_rdy_o(benblk_arb_rdy),
.block_encrypt_key_i(benblk_arb_key),
diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv
index 37eab59..1ff269d 100644
--- a/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv
+++ b/hw/ip/csrng/rtl/csrng_ctr_drbg_cmd.sv
@@ -123,7 +123,8 @@
prim_fifo_sync #(
.Width(CmdreqFifoWidth),
.Pass(0),
- .Depth(CmdreqFifoDepth)
+ .Depth(CmdreqFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_cmdreq (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -211,7 +212,8 @@
prim_fifo_sync #(
.Width(RCStageFifoWidth),
.Pass(0),
- .Depth(RCStageFifoDepth)
+ .Depth(RCStageFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_rcstage (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -246,7 +248,8 @@
prim_fifo_sync #(
.Width(KeyVRCFifoWidth),
.Pass(0),
- .Depth(KeyVRCFifoDepth)
+ .Depth(KeyVRCFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_keyvrc (
.clk_i (clk_i),
.rst_ni (rst_ni),
diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_gen.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_gen.sv
index 87fba90..6405c10 100644
--- a/hw/ip/csrng/rtl/csrng_ctr_drbg_gen.sv
+++ b/hw/ip/csrng/rtl/csrng_ctr_drbg_gen.sv
@@ -229,7 +229,8 @@
prim_fifo_sync #(
.Width(GenreqFifoWidth),
.Pass(0),
- .Depth(GenreqFifoDepth)
+ .Depth(GenreqFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_genreq (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -346,7 +347,8 @@
prim_fifo_sync #(
.Width(AdstageFifoWidth),
.Pass(0),
- .Depth(AdstageFifoDepth)
+ .Depth(AdstageFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_adstage (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -379,7 +381,8 @@
prim_fifo_sync #(
.Width(BlkEncAckFifoWidth),
.Pass(0),
- .Depth(BlkEncAckFifoDepth)
+ .Depth(BlkEncAckFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_bencack (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -431,7 +434,8 @@
prim_fifo_sync #(
.Width(RCStageFifoWidth),
.Pass(0),
- .Depth(RCStageFifoDepth)
+ .Depth(RCStageFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_rcstage (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -467,7 +471,8 @@
prim_fifo_sync #(
.Width(GenbitsFifoWidth),
.Pass(0),
- .Depth(GenbitsFifoDepth)
+ .Depth(GenbitsFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_genbits (
.clk_i (clk_i),
.rst_ni (rst_ni),
diff --git a/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv b/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv
index 3e198bd..0d1855c 100644
--- a/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv
+++ b/hw/ip/csrng/rtl/csrng_ctr_drbg_upd.sv
@@ -263,7 +263,8 @@
prim_fifo_sync #(
.Width(UpdReqFifoWidth),
.Pass(0),
- .Depth(UpdReqFifoDepth)
+ .Depth(UpdReqFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_updreq (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -365,7 +366,8 @@
prim_fifo_sync #(
.Width(BlkEncReqFifoWidth),
.Pass(0),
- .Depth(BlkEncReqFifoDepth)
+ .Depth(BlkEncReqFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_bencreq (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -406,7 +408,8 @@
prim_fifo_sync #(
.Width(BlkEncAckFifoWidth),
.Pass(0),
- .Depth(BlkEncAckFifoDepth)
+ .Depth(BlkEncAckFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_bencack (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -439,7 +442,8 @@
prim_fifo_sync #(
.Width(PDataFifoWidth),
.Pass(0),
- .Depth(PDataFifoDepth)
+ .Depth(PDataFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_pdata (
.clk_i (clk_i),
.rst_ni (rst_ni),
@@ -539,7 +543,8 @@
prim_fifo_sync #(
.Width(FinalFifoWidth),
.Pass(0),
- .Depth(FinalFifoDepth)
+ .Depth(FinalFifoDepth),
+ .OutputZeroIfEmpty(1'b0)
) u_prim_fifo_sync_final (
.clk_i (clk_i),
.rst_ni (rst_ni),
diff --git a/hw/ip/csrng/rtl/csrng_main_sm.sv b/hw/ip/csrng/rtl/csrng_main_sm.sv
index 824bceb..a4af14a 100644
--- a/hw/ip/csrng/rtl/csrng_main_sm.sv
+++ b/hw/ip/csrng/rtl/csrng_main_sm.sv
@@ -24,43 +24,46 @@
output logic generate_req_o,
output logic update_req_o,
output logic uninstant_req_o,
+ input logic halt_main_sm_i,
+ output logic main_sm_halted_o,
output logic main_sm_err_o
);
// Encoding generated with:
-// $ ./util/design/sparse-fsm-encode.py -d 3 -m 10 -n 8 \
-// -s 845453599 --language=sv
+// $ ./util/design/sparse-fsm-encode.py -d 3 -m 11 -n 8 \
+// -s 2773294212 --language=sv
//
// Hamming distance histogram:
//
// 0: --
// 1: --
// 2: --
-// 3: ||||||||||||||| (26.67%)
-// 4: |||||||||||||||||||| (35.56%)
-// 5: ||||||||||||||| (26.67%)
-// 6: ||||| (8.89%)
-// 7: --
-// 8: | (2.22%)
+// 3: |||||||||||||||| (29.09%)
+// 4: |||||||||||||||||||| (34.55%)
+// 5: |||||||||| (18.18%)
+// 6: |||||||| (14.55%)
+// 7: || (3.64%)
+// 8: --
//
// Minimum Hamming distance: 3
-// Maximum Hamming distance: 8
-// Minimum Hamming weight: 2
+// Maximum Hamming distance: 7
+// Minimum Hamming weight: 1
// Maximum Hamming weight: 7
//
localparam int StateWidth = 8;
typedef enum logic [StateWidth-1:0] {
- Idle = 8'b10111111, // idle
- InstantPrep = 8'b11011101, // instantiate prep
- InstantReq = 8'b00010100, // instantiate request (takes adata or entropy)
- ReseedPrep = 8'b11000001, // reseed prep
- ReseedReq = 8'b01100100, // reseed request (takes adata and entropy and Key,V,RC)
- GenerateReq = 8'b10101100, // generate request (takes adata? and Key,V,RC)
- UpdatePrep = 8'b11010010, // update prep
- UpdateReq = 8'b11111000, // update request (takes adata and Key,V,RC)
- UninstantReq = 8'b11101011, // uninstantiate request (no input)
- Error = 8'b00001010 // error state, results in fatal alert
+ Idle = 8'b10100100, // idle
+ InstantPrep = 8'b10011100, // instantiate prep
+ InstantReq = 8'b00010010, // instantiate request (takes adata or entropy)
+ ReseedPrep = 8'b10101001, // reseed prep
+ ReseedReq = 8'b11010011, // reseed request (takes adata and entropy and Key,V,RC)
+ GenerateReq = 8'b11101010, // generate request (takes adata? and Key,V,RC)
+ UpdatePrep = 8'b00000001, // update prep
+ UpdateReq = 8'b01010101, // update request (takes adata and Key,V,RC)
+ UninstantReq = 8'b00001110, // uninstantiate request (no input)
+ SMHalted = 8'b01011000, // state machine halted
+ Error = 8'b11111101 // error state, results in fatal alert
} state_e;
state_e state_d, state_q;
@@ -90,28 +93,33 @@
generate_req_o = 1'b0;
update_req_o = 1'b0;
uninstant_req_o = 1'b0;
+ main_sm_halted_o = 1'b0;
main_sm_err_o = 1'b0;
unique case (state_q)
Idle: begin
- if (ctr_drbg_cmd_req_rdy_i) begin
- if (acmd_avail_i) begin
- acmd_accept_o = 1'b1;
- if (acmd_i == INS) begin
- if (acmd_eop_i) begin
- state_d = InstantPrep;
+ if (halt_main_sm_i) begin
+ state_d = SMHalted;
+ end else begin
+ if (ctr_drbg_cmd_req_rdy_i) begin
+ if (acmd_avail_i) begin
+ acmd_accept_o = 1'b1;
+ if (acmd_i == INS) begin
+ if (acmd_eop_i) begin
+ state_d = InstantPrep;
+ end
+ end else if (acmd_i == RES) begin
+ if (acmd_eop_i) begin
+ state_d = ReseedPrep;
+ end
+ end else if (acmd_i == GEN) begin
+ state_d = GenerateReq;
+ end else if (acmd_i == UPD) begin
+ if (acmd_eop_i) begin
+ state_d = UpdatePrep;
+ end
+ end else if (acmd_i == UNI) begin
+ state_d = UninstantReq;
end
- end else if (acmd_i == RES) begin
- if (acmd_eop_i) begin
- state_d = ReseedPrep;
- end
- end else if (acmd_i == GEN) begin
- state_d = GenerateReq;
- end else if (acmd_i == UPD) begin
- if (acmd_eop_i) begin
- state_d = UpdatePrep;
- end
- end else if (acmd_i == UNI) begin
- state_d = UninstantReq;
end
end
end
@@ -162,6 +170,12 @@
uninstant_req_o = 1'b1;
state_d = Idle;
end
+ SMHalted: begin
+ main_sm_halted_o = 1'b1;
+ if (!halt_main_sm_i) begin
+ state_d = Idle;
+ end
+ end
Error: begin
main_sm_err_o = 1'b1;
end
diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
index a2b5c44..9ac10e2 100644
--- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
@@ -11,7 +11,7 @@
parameter int NumAlerts = 1;
// Address width within the block
- parameter int BlockAw = 6;
+ parameter int BlockAw = 7;
////////////////////////////
// Typedefs for registers //
@@ -97,6 +97,10 @@
} csrng_reg2hw_genbits_reg_t;
typedef struct packed {
+ logic q;
+ } csrng_reg2hw_halt_main_sm_reg_t;
+
+ typedef struct packed {
logic [3:0] q;
logic qe;
} csrng_reg2hw_int_state_num_reg_t;
@@ -167,6 +171,11 @@
} csrng_hw2reg_genbits_reg_t;
typedef struct packed {
+ logic d;
+ logic de;
+ } csrng_hw2reg_main_sm_sts_reg_t;
+
+ typedef struct packed {
logic [31:0] d;
} csrng_hw2reg_int_state_val_reg_t;
@@ -283,14 +292,15 @@
// Register to internal design logic //
///////////////////////////////////////
typedef struct packed {
- csrng_reg2hw_intr_state_reg_t intr_state; // [134:131]
- csrng_reg2hw_intr_enable_reg_t intr_enable; // [130:127]
- csrng_reg2hw_intr_test_reg_t intr_test; // [126:119]
- csrng_reg2hw_alert_test_reg_t alert_test; // [118:117]
- csrng_reg2hw_regwen_reg_t regwen; // [116:116]
- csrng_reg2hw_ctrl_reg_t ctrl; // [115:110]
- csrng_reg2hw_cmd_req_reg_t cmd_req; // [109:77]
- csrng_reg2hw_genbits_reg_t genbits; // [76:44]
+ csrng_reg2hw_intr_state_reg_t intr_state; // [135:132]
+ csrng_reg2hw_intr_enable_reg_t intr_enable; // [131:128]
+ csrng_reg2hw_intr_test_reg_t intr_test; // [127:120]
+ csrng_reg2hw_alert_test_reg_t alert_test; // [119:118]
+ csrng_reg2hw_regwen_reg_t regwen; // [117:117]
+ csrng_reg2hw_ctrl_reg_t ctrl; // [116:111]
+ csrng_reg2hw_cmd_req_reg_t cmd_req; // [110:78]
+ csrng_reg2hw_genbits_reg_t genbits; // [77:45]
+ csrng_reg2hw_halt_main_sm_reg_t halt_main_sm; // [44:44]
csrng_reg2hw_int_state_num_reg_t int_state_num; // [43:39]
csrng_reg2hw_int_state_val_reg_t int_state_val; // [38:6]
csrng_reg2hw_err_code_test_reg_t err_code_test; // [5:0]
@@ -300,33 +310,36 @@
// Internal design logic to register //
///////////////////////////////////////
typedef struct packed {
- csrng_hw2reg_intr_state_reg_t intr_state; // [170:163]
- csrng_hw2reg_sum_sts_reg_t sum_sts; // [162:136]
- csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [135:132]
- csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [131:130]
- csrng_hw2reg_genbits_reg_t genbits; // [129:98]
+ csrng_hw2reg_intr_state_reg_t intr_state; // [172:165]
+ csrng_hw2reg_sum_sts_reg_t sum_sts; // [164:138]
+ csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [137:134]
+ csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [133:132]
+ csrng_hw2reg_genbits_reg_t genbits; // [131:100]
+ csrng_hw2reg_main_sm_sts_reg_t main_sm_sts; // [99:98]
csrng_hw2reg_int_state_val_reg_t int_state_val; // [97:66]
csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [65:50]
csrng_hw2reg_err_code_reg_t err_code; // [49:0]
} csrng_hw2reg_t;
// Register Address
- parameter logic [BlockAw-1:0] CSRNG_INTR_STATE_OFFSET = 6'h 0;
- parameter logic [BlockAw-1:0] CSRNG_INTR_ENABLE_OFFSET = 6'h 4;
- parameter logic [BlockAw-1:0] CSRNG_INTR_TEST_OFFSET = 6'h 8;
- parameter logic [BlockAw-1:0] CSRNG_ALERT_TEST_OFFSET = 6'h c;
- parameter logic [BlockAw-1:0] CSRNG_REGWEN_OFFSET = 6'h 10;
- parameter logic [BlockAw-1:0] CSRNG_CTRL_OFFSET = 6'h 14;
- parameter logic [BlockAw-1:0] CSRNG_SUM_STS_OFFSET = 6'h 18;
- parameter logic [BlockAw-1:0] CSRNG_CMD_REQ_OFFSET = 6'h 1c;
- parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 6'h 20;
- parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 6'h 24;
- parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 6'h 28;
- parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 6'h 2c;
- parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 6'h 30;
- parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 6'h 34;
- parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 6'h 38;
- parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 6'h 3c;
+ parameter logic [BlockAw-1:0] CSRNG_INTR_STATE_OFFSET = 7'h 0;
+ parameter logic [BlockAw-1:0] CSRNG_INTR_ENABLE_OFFSET = 7'h 4;
+ parameter logic [BlockAw-1:0] CSRNG_INTR_TEST_OFFSET = 7'h 8;
+ parameter logic [BlockAw-1:0] CSRNG_ALERT_TEST_OFFSET = 7'h c;
+ parameter logic [BlockAw-1:0] CSRNG_REGWEN_OFFSET = 7'h 10;
+ parameter logic [BlockAw-1:0] CSRNG_CTRL_OFFSET = 7'h 14;
+ parameter logic [BlockAw-1:0] CSRNG_SUM_STS_OFFSET = 7'h 18;
+ parameter logic [BlockAw-1:0] CSRNG_CMD_REQ_OFFSET = 7'h 1c;
+ parameter logic [BlockAw-1:0] CSRNG_SW_CMD_STS_OFFSET = 7'h 20;
+ parameter logic [BlockAw-1:0] CSRNG_GENBITS_VLD_OFFSET = 7'h 24;
+ parameter logic [BlockAw-1:0] CSRNG_GENBITS_OFFSET = 7'h 28;
+ parameter logic [BlockAw-1:0] CSRNG_HALT_MAIN_SM_OFFSET = 7'h 2c;
+ parameter logic [BlockAw-1:0] CSRNG_MAIN_SM_STS_OFFSET = 7'h 30;
+ parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 34;
+ parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 38;
+ parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 3c;
+ parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 40;
+ parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 44;
// Reset values for hwext registers and their fields
parameter logic [3:0] CSRNG_INTR_TEST_RESVAL = 4'h 0;
@@ -353,6 +366,8 @@
CSRNG_SW_CMD_STS,
CSRNG_GENBITS_VLD,
CSRNG_GENBITS,
+ CSRNG_HALT_MAIN_SM,
+ CSRNG_MAIN_SM_STS,
CSRNG_INT_STATE_NUM,
CSRNG_INT_STATE_VAL,
CSRNG_HW_EXC_STS,
@@ -361,7 +376,7 @@
} csrng_id_e;
// Register width information to check illegal writes
- parameter logic [3:0] CSRNG_PERMIT [16] = '{
+ parameter logic [3:0] CSRNG_PERMIT [18] = '{
4'b 0001, // index[ 0] CSRNG_INTR_STATE
4'b 0001, // index[ 1] CSRNG_INTR_ENABLE
4'b 0001, // index[ 2] CSRNG_INTR_TEST
@@ -373,11 +388,13 @@
4'b 0001, // index[ 8] CSRNG_SW_CMD_STS
4'b 0001, // index[ 9] CSRNG_GENBITS_VLD
4'b 1111, // index[10] CSRNG_GENBITS
- 4'b 0001, // index[11] CSRNG_INT_STATE_NUM
- 4'b 1111, // index[12] CSRNG_INT_STATE_VAL
- 4'b 0011, // index[13] CSRNG_HW_EXC_STS
- 4'b 1111, // index[14] CSRNG_ERR_CODE
- 4'b 0001 // index[15] CSRNG_ERR_CODE_TEST
+ 4'b 0001, // index[11] CSRNG_HALT_MAIN_SM
+ 4'b 0001, // index[12] CSRNG_MAIN_SM_STS
+ 4'b 0001, // index[13] CSRNG_INT_STATE_NUM
+ 4'b 1111, // index[14] CSRNG_INT_STATE_VAL
+ 4'b 0011, // index[15] CSRNG_HW_EXC_STS
+ 4'b 1111, // index[16] CSRNG_ERR_CODE
+ 4'b 0001 // index[17] CSRNG_ERR_CODE_TEST
};
endpackage
diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv
index 78e09e5..ee0bdc9 100644
--- a/hw/ip/csrng/rtl/csrng_reg_top.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_top.sv
@@ -23,7 +23,7 @@
import csrng_reg_pkg::* ;
- localparam int AW = 6;
+ localparam int AW = 7;
localparam int DW = 32;
localparam int DBW = DW/8; // Byte Width
@@ -143,6 +143,9 @@
logic genbits_vld_genbits_fips_re;
logic [31:0] genbits_qs;
logic genbits_re;
+ logic halt_main_sm_wd;
+ logic halt_main_sm_we;
+ logic main_sm_sts_qs;
logic [3:0] int_state_num_qs;
logic [3:0] int_state_num_wd;
logic int_state_num_we;
@@ -756,6 +759,58 @@
);
+ // R[halt_main_sm]: V(False)
+
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("WO"),
+ .RESVAL (1'h0)
+ ) u_halt_main_sm (
+ .clk_i (clk_i ),
+ .rst_ni (rst_ni ),
+
+ // from register interface (qualified with register enable)
+ .we (halt_main_sm_we & regwen_qs),
+ .wd (halt_main_sm_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0 ),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.halt_main_sm.q ),
+
+ .qs ()
+ );
+
+
+ // R[main_sm_sts]: V(False)
+
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("RO"),
+ .RESVAL (1'h0)
+ ) u_main_sm_sts (
+ .clk_i (clk_i ),
+ .rst_ni (rst_ni ),
+
+ .we (1'b0),
+ .wd ('0 ),
+
+ // from internal hardware
+ .de (hw2reg.main_sm_sts.de),
+ .d (hw2reg.main_sm_sts.d ),
+
+ // to internal hardware
+ .qe (),
+ .q (),
+
+ // to register interface (read)
+ .qs (main_sm_sts_qs)
+ );
+
+
// R[int_state_num]: V(False)
prim_subreg #(
@@ -1482,7 +1537,7 @@
- logic [15:0] addr_hit;
+ logic [17:0] addr_hit;
always_comb begin
addr_hit = '0;
addr_hit[ 0] = (reg_addr == CSRNG_INTR_STATE_OFFSET);
@@ -1496,11 +1551,13 @@
addr_hit[ 8] = (reg_addr == CSRNG_SW_CMD_STS_OFFSET);
addr_hit[ 9] = (reg_addr == CSRNG_GENBITS_VLD_OFFSET);
addr_hit[10] = (reg_addr == CSRNG_GENBITS_OFFSET);
- addr_hit[11] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET);
- addr_hit[12] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET);
- addr_hit[13] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET);
- addr_hit[14] = (reg_addr == CSRNG_ERR_CODE_OFFSET);
- addr_hit[15] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET);
+ addr_hit[11] = (reg_addr == CSRNG_HALT_MAIN_SM_OFFSET);
+ addr_hit[12] = (reg_addr == CSRNG_MAIN_SM_STS_OFFSET);
+ addr_hit[13] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET);
+ addr_hit[14] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET);
+ addr_hit[15] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET);
+ addr_hit[16] = (reg_addr == CSRNG_ERR_CODE_OFFSET);
+ addr_hit[17] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET);
end
assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
@@ -1524,6 +1581,8 @@
if (addr_hit[13] && reg_we && (CSRNG_PERMIT[13] != (CSRNG_PERMIT[13] & reg_be))) wr_err = 1'b1 ;
if (addr_hit[14] && reg_we && (CSRNG_PERMIT[14] != (CSRNG_PERMIT[14] & reg_be))) wr_err = 1'b1 ;
if (addr_hit[15] && reg_we && (CSRNG_PERMIT[15] != (CSRNG_PERMIT[15] & reg_be))) wr_err = 1'b1 ;
+ if (addr_hit[16] && reg_we && (CSRNG_PERMIT[16] != (CSRNG_PERMIT[16] & reg_be))) wr_err = 1'b1 ;
+ if (addr_hit[17] && reg_we && (CSRNG_PERMIT[17] != (CSRNG_PERMIT[17] & reg_be))) wr_err = 1'b1 ;
end
assign intr_state_cs_cmd_req_done_we = addr_hit[0] & reg_we & ~wr_err;
@@ -1590,12 +1649,16 @@
assign genbits_re = addr_hit[10] && reg_re;
- assign int_state_num_we = addr_hit[11] & reg_we & ~wr_err;
+ assign halt_main_sm_we = addr_hit[11] & reg_we & ~wr_err;
+ assign halt_main_sm_wd = reg_wdata[0];
+
+
+ assign int_state_num_we = addr_hit[13] & reg_we & ~wr_err;
assign int_state_num_wd = reg_wdata[3:0];
- assign int_state_val_re = addr_hit[12] && reg_re;
+ assign int_state_val_re = addr_hit[14] && reg_re;
- assign hw_exc_sts_we = addr_hit[13] & reg_we & ~wr_err;
+ assign hw_exc_sts_we = addr_hit[15] & reg_we & ~wr_err;
assign hw_exc_sts_wd = reg_wdata[14:0];
@@ -1623,7 +1686,7 @@
- assign err_code_test_we = addr_hit[15] & reg_we & ~wr_err;
+ assign err_code_test_we = addr_hit[17] & reg_we & ~wr_err;
assign err_code_test_wd = reg_wdata[4:0];
// Read data return
@@ -1689,18 +1752,26 @@
end
addr_hit[11]: begin
- reg_rdata_next[3:0] = int_state_num_qs;
+ reg_rdata_next[0] = '0;
end
addr_hit[12]: begin
- reg_rdata_next[31:0] = int_state_val_qs;
+ reg_rdata_next[0] = main_sm_sts_qs;
end
addr_hit[13]: begin
- reg_rdata_next[14:0] = hw_exc_sts_qs;
+ reg_rdata_next[3:0] = int_state_num_qs;
end
addr_hit[14]: begin
+ reg_rdata_next[31:0] = int_state_val_qs;
+ end
+
+ addr_hit[15]: begin
+ reg_rdata_next[14:0] = hw_exc_sts_qs;
+ end
+
+ addr_hit[16]: begin
reg_rdata_next[0] = err_code_sfifo_cmd_err_qs;
reg_rdata_next[1] = err_code_sfifo_genbits_err_qs;
reg_rdata_next[2] = err_code_sfifo_cmdreq_err_qs;
@@ -1728,7 +1799,7 @@
reg_rdata_next[30] = err_code_fifo_state_err_qs;
end
- addr_hit[15]: begin
+ addr_hit[17]: begin
reg_rdata_next[4:0] = err_code_test_qs;
end
diff --git a/hw/ip/csrng/rtl/csrng_state_db.sv b/hw/ip/csrng/rtl/csrng_state_db.sv
index f59bbc8..48ab160 100644
--- a/hw/ip/csrng/rtl/csrng_state_db.sv
+++ b/hw/ip/csrng/rtl/csrng_state_db.sv
@@ -22,7 +22,6 @@
// read interface
input logic state_db_enable_i,
- input logic state_db_rd_req_i,
input logic [StateId-1:0] state_db_rd_inst_id_i,
output logic [KeyLen-1:0] state_db_rd_key_o,
output logic [BlkLen-1:0] state_db_rd_v_o,
@@ -42,7 +41,6 @@
// status interface
input logic state_db_lc_en_i,
input logic state_db_reg_rd_sel_i,
- input logic [StateId-1:0] state_db_reg_rd_id_i,
input logic state_db_reg_rd_id_pulse_i,
output logic [31:0] state_db_reg_rd_val_o,
output logic state_db_sts_ack_o,
@@ -53,7 +51,6 @@
localparam int InternalStateWidth = 2+KeyLen+BlkLen+CtrLen;
localparam int RegInternalStateWidth = 30+InternalStateWidth;
localparam int RegW = 32;
- localparam int MaxNApps = 16;
logic [StateId-1:0] state_db_id;
logic [KeyLen-1:0] state_db_key;
@@ -64,11 +61,8 @@
logic state_db_sts;
logic state_db_write;
logic instance_status;
- logic [MaxNApps-1:0] int_st_out_sel;
- logic [MaxNApps-1:0] int_st_dmp_sel;
- logic [InternalStateWidth-1:0] internal_states_out[MaxNApps];
- logic [InternalStateWidth-1:0] internal_states_dmp[MaxNApps];
- logic [InternalStateWidth-1:0] internal_state_func;
+ logic [NApps-1:0] int_st_out_sel;
+ logic [InternalStateWidth-1:0] internal_states_out[NApps];
logic [RegInternalStateWidth-1:0] internal_state_diag;
logic reg_rd_ptr_inc;
@@ -93,12 +87,14 @@
// flops - no reset
logic [InternalStateWidth-1:0] internal_states_q[NApps], internal_states_d[NApps];
+ logic [InternalStateWidth-1:0] internal_state_pl_q, internal_state_pl_d;
// no reset on state
always_ff @(posedge clk_i)
begin
internal_states_q <= internal_states_d;
+ internal_state_pl_q <= internal_state_pl_d;
end
@@ -106,63 +102,26 @@
// internal state read logic
//--------------------------------------------
for (genvar rd = 0; rd < NApps; rd = rd+1) begin : gen_state_rd
- assign int_st_out_sel[rd] = (state_db_rd_req_i && (state_db_rd_inst_id_i == rd));
+ assign int_st_out_sel[rd] = (state_db_rd_inst_id_i == rd);
assign internal_states_out[rd] = int_st_out_sel[rd] ? internal_states_q[rd] : '0;
- // for dumping the internal state into register reads, the life cycle enable must be active
- assign int_st_dmp_sel[rd] = (state_db_reg_rd_sel_i && (state_db_reg_rd_id_i == rd)) &&
- state_db_lc_en_i;
- assign internal_states_dmp[rd] = int_st_dmp_sel[rd] ? internal_states_q[rd] : '0;
- end
-
- for (genvar rd = NApps; rd < 16; rd = rd+1) begin : gen_state_rd_zeros
- assign int_st_out_sel[rd] = 1'b0;
- assign int_st_dmp_sel[rd] = 1'b0;
- assign internal_states_out[rd] = {InternalStateWidth{int_st_out_sel[rd]}};
- assign internal_states_dmp[rd] = {InternalStateWidth{int_st_dmp_sel[rd]}};
end
// since only one of the internal states is active at a time, a
// logical "or" is made of all of the buses into one
- assign internal_state_func = internal_states_out[0] |
- internal_states_out[1] |
- internal_states_out[2] |
- internal_states_out[3] |
- internal_states_out[4] |
- internal_states_out[5] |
- internal_states_out[6] |
- internal_states_out[7] |
- internal_states_out[8] |
- internal_states_out[9] |
- internal_states_out[10] |
- internal_states_out[11] |
- internal_states_out[12] |
- internal_states_out[13] |
- internal_states_out[14] |
- internal_states_out[15];
+ always_comb begin
+ internal_state_pl_d = '0;
+ for (int i = 0; i < NApps; i = i+1) begin
+ internal_state_pl_d |= internal_states_out[i];
+ end
+ end
assign {state_db_rd_fips_o,state_db_rd_inst_st_o,
state_db_rd_key_o,state_db_rd_v_o,
- state_db_rd_res_ctr_o} = internal_state_func;
+ state_db_rd_res_ctr_o} = internal_state_pl_q;
- // to dump out the internal states, only one is active at a time, a
- // logical "or" is made of all of the buses into one
- assign internal_state_diag = {30'b0,internal_states_dmp[0]} |
- {30'b0,internal_states_dmp[1]} |
- {30'b0,internal_states_dmp[2]} |
- {30'b0,internal_states_dmp[3]} |
- {30'b0,internal_states_dmp[4]} |
- {30'b0,internal_states_dmp[5]} |
- {30'b0,internal_states_dmp[6]} |
- {30'b0,internal_states_dmp[7]} |
- {30'b0,internal_states_dmp[8]} |
- {30'b0,internal_states_dmp[9]} |
- {30'b0,internal_states_dmp[10]} |
- {30'b0,internal_states_dmp[11]} |
- {30'b0,internal_states_dmp[12]} |
- {30'b0,internal_states_dmp[13]} |
- {30'b0,internal_states_dmp[14]} |
- {30'b0,internal_states_dmp[15]};
+ // re-using the internal state pipeline version for better timing
+ assign internal_state_diag = {32'b0,internal_state_pl_q};
// Register access of internal state
@@ -187,7 +146,8 @@
assign reg_rd_ptr_inc = state_db_reg_rd_sel_i;
assign reg_rd_ptr_d =
- !state_db_enable_i ? '0 :
+ !state_db_enable_i ? 4'hf :
+ !state_db_lc_en_i ? 4'hf :
(reg_rd_ptr_q == 4'he) ? '0 :
state_db_reg_rd_id_pulse_i ? '0 :
reg_rd_ptr_inc ? (reg_rd_ptr_q+1) :
@@ -200,7 +160,8 @@
for (genvar wr = 0; wr < NApps; wr = wr+1) begin : gen_state_wr
- assign internal_states_d[wr] = (state_db_write && (state_db_id == wr)) ?
+ assign internal_states_d[wr] = !state_db_enable_i ? '0 : // better timing
+ (state_db_write && (state_db_id == wr)) ?
{state_db_fips,state_db_inst_st,state_db_key,
state_db_v,state_db_rc} : internal_states_q[wr];
end : gen_state_wr
@@ -235,6 +196,5 @@
// Assertions
`ASSERT_KNOWN(IntStOutSelOneHot_A, $onehot(int_st_out_sel))
- `ASSERT_KNOWN(IntStDmpSelOneHot_A, $onehot(int_st_dmp_sel))
endmodule