Skip to content

Commit

Permalink
[entropy_src] Add FIFO to deal with backpressure from the conditioner
Browse files Browse the repository at this point in the history
This commit adds a 32-bit wide distribution FIFO of configurable depth.
The FIFO is added between the postht FIFO, the observe FIFO, the bypass
FIFO and the precon FIFO. Its main purpose is to buffer entropy bits
while the conditioner is busy such that we don't have to drop entropy
bits from the hardware pipeline.

Dropping entropy bits is not a big issue per se as it's allowed by the
spec (when done after the health tests and in a way such that number
of samples going into the conditioner is fixed). Also, under normal
operating conditions, noise source samples arrive at very low rate and
dropping bits should not be needed.

However, verifying that the `correct` entropy bits are dropped is hard
and seems impossible for our current DV environment as it requires to
very accurately model the hardware pipeline which is undesirable. Thus,
the safest approach is to add this new distribution FIFO and tune its
depth parameter to handle potential backpressure from the conditioner
such that dropping bits is not necessary.

Signed-off-by: Pirmin Vogel <[email protected]>
  • Loading branch information
vogelpi committed Mar 6, 2024
1 parent c2c27db commit 74a6e9b
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 115 deletions.
17 changes: 16 additions & 1 deletion hw/ip/entropy_src/data/entropy_src.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@
local: "false",
expose: "true"
},
{ name: "DistrFifoDepth",
type: "int unsigned",
default: "2",
desc: "Number of 32-bit entries in the distr FIFO",
local: "false",
expose: "true"
},
{ name: "Stub",
type: "bit",
default: "0",
Expand Down Expand Up @@ -1631,6 +1638,14 @@
'''
}
{ bits: "1",
name: "SFIFO_DISTR_ERR",
desc: '''
This bit will be set to one when an error has been detected for the distribution FIFO.
The type of error is reflected in the type status bits (bits 28 through 30 of this register).
This bit will stay set until the next reset.
'''
}
{ bits: "2",
name: "SFIFO_OBSERVE_ERR",
desc: '''
This bit will be set to one when an error has been detected for the
Expand All @@ -1639,7 +1654,7 @@
This bit will stay set until the next reset.
'''
}
{ bits: "2",
{ bits: "3",
name: "SFIFO_ESFINAL_ERR",
desc: '''
This bit will be set to one when an error has been detected for the
Expand Down
16 changes: 11 additions & 5 deletions hw/ip/entropy_src/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -1482,12 +1482,12 @@ Writing a zero resets this status bit.
Hardware detection of error conditions status register
- Offset: `0xd8`
- Reset default: `0x0`
- Reset mask: `0x71f00007`
- Reset mask: `0x71f0000f`

### Fields

```wavejson
{"reg": [{"name": "SFIFO_ESRNG_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_OBSERVE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_ESFINAL_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 17}, {"name": "ES_ACK_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ES_MAIN_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ES_CNTR_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SHA3_STATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SHA3_RST_STORAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 3}, {"name": "FIFO_WRITE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_READ_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_STATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}], "config": {"lanes": 1, "fontsize": 10, "vspace": 220}}
{"reg": [{"name": "SFIFO_ESRNG_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_DISTR_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_OBSERVE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SFIFO_ESFINAL_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 16}, {"name": "ES_ACK_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ES_MAIN_SM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ES_CNTR_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SHA3_STATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SHA3_RST_STORAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 3}, {"name": "FIFO_WRITE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_READ_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FIFO_STATE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 1}], "config": {"lanes": 1, "fontsize": 10, "vspace": 220}}
```

| Bits | Type | Reset | Name |
Expand All @@ -1502,9 +1502,10 @@ Hardware detection of error conditions status register
| 22 | ro | 0x0 | [ES_CNTR_ERR](#err_code--es_cntr_err) |
| 21 | ro | 0x0 | [ES_MAIN_SM_ERR](#err_code--es_main_sm_err) |
| 20 | ro | 0x0 | [ES_ACK_SM_ERR](#err_code--es_ack_sm_err) |
| 19:3 | | | Reserved |
| 2 | ro | 0x0 | [SFIFO_ESFINAL_ERR](#err_code--sfifo_esfinal_err) |
| 1 | ro | 0x0 | [SFIFO_OBSERVE_ERR](#err_code--sfifo_observe_err) |
| 19:4 | | | Reserved |
| 3 | ro | 0x0 | [SFIFO_ESFINAL_ERR](#err_code--sfifo_esfinal_err) |
| 2 | ro | 0x0 | [SFIFO_OBSERVE_ERR](#err_code--sfifo_observe_err) |
| 1 | ro | 0x0 | [SFIFO_DISTR_ERR](#err_code--sfifo_distr_err) |
| 0 | ro | 0x0 | [SFIFO_ESRNG_ERR](#err_code--sfifo_esrng_err) |

### ERR_CODE . FIFO_STATE_ERR
Expand Down Expand Up @@ -1560,6 +1561,11 @@ observe FIFO. The type of error is reflected in the type status
bits (bits 28 through 30 of this register).
This bit will stay set until the next reset.

### ERR_CODE . SFIFO_DISTR_ERR
This bit will be set to one when an error has been detected for the distribution FIFO.
The type of error is reflected in the type status bits (bits 28 through 30 of this register).
This bit will stay set until the next reset.

### ERR_CODE . SFIFO_ESRNG_ERR
This bit will be set to one when an error has been detected for the
esrng FIFO. The type of error is reflected in the type status
Expand Down
13 changes: 11 additions & 2 deletions hw/ip/entropy_src/dv/cov/entropy_src_cov_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ interface entropy_src_cov_if
bit esrng_fifo_not_empty_i,
bit esbit_fifo_not_empty_i,
bit postht_fifo_not_empty_i,
bit distr_fifo_not_empty_i,
bit cs_aes_halt_req_i,
bit sha3_done_i,
bit bypass_mode_i,
Expand Down Expand Up @@ -556,7 +557,13 @@ interface entropy_src_cov_if
bins not_empty = {1'b1};
}

cr_enable_i_fifo_state: cross cp_enable, cp_esrng_fifo, cp_esbit_fifo, cp_postht_fifo {
cp_distr_fifo: coverpoint distr_fifo_not_empty_i {
bins empty = {1'b0};
bins not_empty = {1'b1};
}

cr_enable_i_fifo_state: cross cp_enable,
cp_esrng_fifo, cp_esbit_fifo, cp_postht_fifo, cp_distr_fifo {
// When re-enabling, all those FIFOs are empty.
//
// This is a property of the current implementation and it may be legal to change the
Expand All @@ -566,7 +573,8 @@ interface entropy_src_cov_if
illegal_bins enabling_and_any_fifo_not_empty =
binsof(cp_enable.enabling) && (binsof(cp_esrng_fifo.not_empty) ||
binsof(cp_esbit_fifo.not_empty) ||
binsof(cp_postht_fifo.not_empty));
binsof(cp_postht_fifo.not_empty) ||
binsof(cp_distr_fifo.not_empty));
}

cp_sha3_state: coverpoint {cs_aes_halt_req_i, sha3_done_i} {
Expand Down Expand Up @@ -1117,6 +1125,7 @@ interface entropy_src_cov_if
tb.dut.u_entropy_src_core.u_enable_delay.esrng_fifo_not_empty_i,
tb.dut.u_entropy_src_core.u_enable_delay.esbit_fifo_not_empty_i,
tb.dut.u_entropy_src_core.u_enable_delay.postht_fifo_not_empty_i,
tb.dut.u_entropy_src_core.u_enable_delay.distr_fifo_not_empty_i,
tb.dut.u_entropy_src_core.u_enable_delay.cs_aes_halt_req_i,
tb.dut.u_entropy_src_core.u_enable_delay.sha3_done_i == MuBi4True,
tb.dut.u_entropy_src_core.u_enable_delay.bypass_mode_i,
Expand Down
8 changes: 5 additions & 3 deletions hw/ip/entropy_src/dv/env/entropy_src_env_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,14 @@ class entropy_src_env_cfg extends cip_base_env_cfg #(.RAL_T(entropy_src_reg_bloc
constraint which_err_code_c {
which_err_code dist {
sfifo_esrng_err :/ 2,
sfifo_distr_err :/ 2,
sfifo_observe_err :/ 2,
sfifo_esfinal_err :/ 2,
es_ack_sm_err :/ 2,
es_main_sm_err :/ 2,
es_cntr_err :/ 60,
fifo_read_err :/ 3,
fifo_state_err :/ 3};}
fifo_read_err :/ 4,
fifo_state_err :/ 4};}

constraint which_cntr_replicate_c {which_cntr_replicate inside {[0:RNG_BUS_WIDTH-1]};}
int num_bins = 2**RNG_BUS_WIDTH;
Expand All @@ -206,7 +207,7 @@ class entropy_src_env_cfg extends cip_base_env_cfg #(.RAL_T(entropy_src_reg_bloc
// Write errors no longer apply to the esfinal or esrng fifos
// so exclude those combinations when targetting a specific fifo or error condition
constraint which_fifo_err_c {
which_err_code inside {sfifo_esrng_err, sfifo_esfinal_err} ->
which_err_code inside {sfifo_esrng_err, sfifo_distr_err, sfifo_esfinal_err} ->
which_fifo_err inside {read, state};
which_err_code == fifo_read_err -> which_fifo_err == read;
which_err_code == fifo_state_err -> which_fifo_err == state;
Expand All @@ -215,6 +216,7 @@ class entropy_src_env_cfg extends cip_base_env_cfg #(.RAL_T(entropy_src_reg_bloc
constraint which_fifo_c {
which_err_code == sfifo_observe_err -> which_fifo == sfifo_observe;
which_err_code == sfifo_esrng_err -> which_fifo == sfifo_esrng;
which_err_code == sfifo_distr_err -> which_fifo == sfifo_distr;
which_err_code == sfifo_esfinal_err -> which_fifo == sfifo_esfinal;
}

Expand Down
51 changes: 28 additions & 23 deletions hw/ip/entropy_src/dv/env/entropy_src_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,33 @@ package entropy_src_env_pkg;

typedef enum int {
sfifo_esrng_err = 0,
sfifo_observe_err = 1,
sfifo_esfinal_err = 2,
es_ack_sm_err = 3,
es_main_sm_err = 4,
es_cntr_err = 5,
fifo_read_err = 6,
fifo_state_err = 7,
sfifo_esrng_err_test = 8,
sfifo_observe_err_test = 9,
sfifo_esfinal_err_test = 10,
es_ack_sm_err_test = 11,
es_main_sm_err_test = 12,
es_cntr_err_test = 13,
fifo_read_err_test = 14,
fifo_state_err_test = 15
sfifo_distr_err = 1,
sfifo_observe_err = 2,
sfifo_esfinal_err = 3,
es_ack_sm_err = 4,
es_main_sm_err = 5,
es_cntr_err = 6,
fifo_read_err = 7,
fifo_state_err = 8,
sfifo_esrng_err_test = 9,
sfifo_distr_err_test = 10,
sfifo_observe_err_test = 11,
sfifo_esfinal_err_test = 12,
es_ack_sm_err_test = 13,
es_main_sm_err_test = 14,
es_cntr_err_test = 15,
fifo_read_err_test = 16,
fifo_state_err_test = 17
} err_code_e;

typedef enum int {
sfifo_observe_error = 0,
sfifo_esrng_error = 1,
sfifo_esfinal_error = 2,
es_ack_sm_error = 3,
es_main_sm_error = 4,
es_cntr_error = 5
sfifo_distr_error = 2,
sfifo_esfinal_error = 3,
es_ack_sm_error = 4,
es_main_sm_error = 5,
es_cntr_error = 6
} fatal_err_e;

typedef enum int {
Expand Down Expand Up @@ -119,8 +122,9 @@ package entropy_src_env_pkg;

typedef enum int {
sfifo_esrng = 0,
sfifo_observe = 1,
sfifo_esfinal = 2
sfifo_distr = 1,
sfifo_observe = 2,
sfifo_esfinal = 3
} which_fifo_e;

typedef enum int {
Expand All @@ -130,8 +134,9 @@ package entropy_src_env_pkg;

typedef enum bit [4:0] {
sfifo_esrng_err_code = 0,
sfifo_observe_err_code = 1,
sfifo_esfinal_err_code = 2,
sfifo_distr_err_code = 1,
sfifo_observe_err_code = 2,
sfifo_esfinal_err_code = 3,
es_ack_sm_err_code = 20,
es_main_sm_err_code = 21,
es_cntr_err_code = 22,
Expand Down
4 changes: 2 additions & 2 deletions hw/ip/entropy_src/dv/env/seq_lib/entropy_src_err_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class entropy_src_err_vseq extends entropy_src_base_vseq;
cfg.entropy_src_assert_vif.assert_off_err();

case (cfg.which_err_code) inside
sfifo_esrng_err, sfifo_observe_err, sfifo_esfinal_err: begin
sfifo_esrng_err, sfifo_distr_err, sfifo_observe_err, sfifo_esfinal_err: begin
path_name = cfg.which_fifo_err.name();

path1 = cfg.entropy_src_path_vif.fifo_err_path(fifo_base_path,
Expand Down Expand Up @@ -144,7 +144,7 @@ class entropy_src_err_vseq extends entropy_src_base_vseq;
force_fifo_err(path1, path2, value1, value2, fld, 1'b1);
cov_vif.cg_fifo_err_sample(cfg.which_fifo_err, cfg.which_fifo);
end
sfifo_esrng_err_test, sfifo_observe_err_test, sfifo_esfinal_err_test,
sfifo_esrng_err_test, sfifo_distr_err_test, sfifo_observe_err_test, sfifo_esfinal_err_test,
es_ack_sm_err_test, es_main_sm_err_test, es_cntr_err_test,
fifo_read_err_test, fifo_state_err_test: begin
// First turn off module_enable to write registers
Expand Down
6 changes: 4 additions & 2 deletions hw/ip/entropy_src/dv/sva/entropy_src_assert_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ interface entropy_src_assert_if ();
$assertoff(0, `CORE.Final_EsbitFifoPushedIntoPosthtFifo_A);
$assertoff(0, `CORE.AtReset_PosthtFifoPushedFromEsbitOrEsrngFifos_A);
$assertoff(0, `CORE.Final_PosthtFifoPushedFromEsbitOrEsrngFifos_A);
$assertoff(0, `CORE.AtReset_PosthtFifoPushedIntoPreconFifo_A);
$assertoff(0, `CORE.Final_PosthtFifoPushedIntoPreconFifo_A);
$assertoff(0, `CORE.AtReset_PosthtFifoPushedIntoDistrFifo_A);
$assertoff(0, `CORE.Final_PosthtFifoPushedIntoDistrFifo_A);
$assertoff(0, `CORE.AtReset_DistrFifoPushedIntoPreconFifo_A);
$assertoff(0, `CORE.Final_DistrFifoPushedIntoPreconFifo_A);
$assertoff(0, `CORE.AtReset_EsfinalFifoPushed_A);
$assertoff(0, `CORE.Final_EsfinalFifoPushed_A);
$assertoff(0, `CORE.AtReset_EsfinalFifoPushedPostStartup_A);
Expand Down
13 changes: 11 additions & 2 deletions hw/ip/entropy_src/rtl/entropy_src.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ module entropy_src
#(
parameter bit Stub = 1'b0,
parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}},
parameter int EsFifoDepth = 4
parameter int EsFifoDepth = 4,
parameter int DistrFifoDepth = 2
) (
input logic clk_i,
input logic rst_ni,
Expand Down Expand Up @@ -130,7 +131,8 @@ module entropy_src
);

entropy_src_core #(
.EsFifoDepth(EsFifoDepth)
.EsFifoDepth(EsFifoDepth),
.DistrFifoDepth(DistrFifoDepth)
) u_entropy_src_core (
.clk_i,
.rst_ni(core_rst_n),
Expand Down Expand Up @@ -410,6 +412,13 @@ module entropy_src
u_entropy_src_core.u_prim_fifo_sync_esrng.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_rptr,
alert_tx_o[1])

`ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(DistrFifoWptrCheck_A,
u_entropy_src_core.u_prim_fifo_sync_distr.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_wptr,
alert_tx_o[1])
`ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(DistrFifoRptrCheck_A,
u_entropy_src_core.u_prim_fifo_sync_distr.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_rptr,
alert_tx_o[1])

`ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(ObserveFifoWptrCheck_A,
u_entropy_src_core.u_prim_fifo_sync_observe.gen_normal_fifo.u_fifo_cnt.gen_secure_ptrs.u_wptr,
alert_tx_o[1])
Expand Down
Loading

0 comments on commit 74a6e9b

Please sign in to comment.