| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // Description: csrng ctr_drbg generate module |
| // |
| // This module will process the second half of the generate function. |
| // It takes in the key, v, and reseed counter values processed by the |
| // ctr_drbg cmd module. |
| |
| module csrng_ctr_drbg_gen import csrng_pkg::*; #( |
| parameter int NApps = 4, |
| parameter int Cmd = 3, |
| parameter int StateId = 4, |
| parameter int BlkLen = 128, |
| parameter int KeyLen = 256, |
| parameter int SeedLen = 384, |
| parameter int CtrLen = 32 |
| ) ( |
| input logic clk_i, |
| input logic rst_ni, |
| |
| // command interface |
| input logic ctr_drbg_gen_enable_i, |
| input logic ctr_drbg_gen_req_i, |
| output logic ctr_drbg_gen_rdy_o, // ready to process the req above |
| input logic [Cmd-1:0] ctr_drbg_gen_ccmd_i, // current command |
| input logic [StateId-1:0] ctr_drbg_gen_inst_id_i, // instantance id |
| input logic ctr_drbg_gen_glast_i, // gen cmd last beat |
| input logic ctr_drbg_gen_fips_i, // fips |
| input logic [SeedLen-1:0] ctr_drbg_gen_adata_i, // additional data |
| input logic [KeyLen-1:0] ctr_drbg_gen_key_i, |
| input logic [BlkLen-1:0] ctr_drbg_gen_v_i, |
| input logic [CtrLen-1:0] ctr_drbg_gen_rc_i, |
| |
| output logic ctr_drbg_gen_ack_o, // final ack when update process has been completed |
| output logic ctr_drbg_gen_sts_o, // final ack status |
| input logic ctr_drbg_gen_rdy_i, // ready to process the ack above |
| output logic [Cmd-1:0] ctr_drbg_gen_ccmd_o, |
| output logic [StateId-1:0] ctr_drbg_gen_inst_id_o, |
| output logic [KeyLen-1:0] ctr_drbg_gen_key_o, |
| output logic [BlkLen-1:0] ctr_drbg_gen_v_o, |
| output logic [CtrLen-1:0] ctr_drbg_gen_rc_o, |
| output logic [BlkLen-1:0] ctr_drbg_gen_bits_o, |
| output logic ctr_drbg_gen_fips_o, |
| |
| // es_req/ack |
| input logic ctr_drbg_gen_es_req_i, |
| output logic ctr_drbg_gen_es_ack_o, |
| |
| // update interface |
| output logic gen_upd_req_o, |
| input logic upd_gen_rdy_i, |
| output logic [Cmd-1:0] gen_upd_ccmd_o, |
| output logic [StateId-1:0] gen_upd_inst_id_o, |
| output logic [SeedLen-1:0] gen_upd_pdata_o, |
| output logic [KeyLen-1:0] gen_upd_key_o, |
| output logic [BlkLen-1:0] gen_upd_v_o, |
| |
| input logic upd_gen_ack_i, |
| output logic gen_upd_rdy_o, |
| input logic [Cmd-1:0] upd_gen_ccmd_i, |
| input logic [StateId-1:0] upd_gen_inst_id_i, |
| input logic [KeyLen-1:0] upd_gen_key_i, |
| input logic [BlkLen-1:0] upd_gen_v_i, |
| // block encrypt interface |
| output logic block_encrypt_req_o, |
| input logic block_encrypt_rdy_i, |
| output logic [Cmd-1:0] block_encrypt_ccmd_o, |
| output logic [StateId-1:0] block_encrypt_inst_id_o, |
| output logic [KeyLen-1:0] block_encrypt_key_o, |
| output logic [BlkLen-1:0] block_encrypt_v_o, |
| input logic block_encrypt_ack_i, |
| output logic block_encrypt_rdy_o, |
| input logic [Cmd-1:0] block_encrypt_ccmd_i, |
| input logic [StateId-1:0] block_encrypt_inst_id_i, |
| input logic [BlkLen-1:0] block_encrypt_v_i, |
| // misc |
| output logic ctr_drbg_gen_v_ctr_err_o, |
| output logic [2:0] ctr_drbg_gen_sfifo_gbencack_err_o, |
| output logic [2:0] ctr_drbg_gen_sfifo_grcstage_err_o, |
| output logic [2:0] ctr_drbg_gen_sfifo_ggenreq_err_o, |
| output logic [2:0] ctr_drbg_gen_sfifo_gadstage_err_o, |
| output logic [2:0] ctr_drbg_gen_sfifo_ggenbits_err_o, |
| output logic ctr_drbg_gen_sm_err_o |
| ); |
| |
| localparam int GenreqFifoDepth = 1; |
| localparam int GenreqFifoWidth = KeyLen+BlkLen+CtrLen+1+SeedLen+1+StateId+Cmd; |
| localparam int BlkEncAckFifoDepth = 1; |
| localparam int BlkEncAckFifoWidth = BlkLen+StateId+Cmd; |
| localparam int AdstageFifoDepth = 1; |
| localparam int AdstageFifoWidth = KeyLen+BlkLen+CtrLen+1+1; |
| localparam int RCStageFifoDepth = 1; |
| localparam int RCStageFifoWidth = KeyLen+BlkLen+BlkLen+CtrLen+1+1+StateId+Cmd; |
| localparam int GenbitsFifoDepth = 1; |
| localparam int GenbitsFifoWidth = 1+BlkLen+KeyLen+BlkLen+CtrLen+StateId+Cmd; |
| |
| // signals |
| logic [Cmd-1:0] genreq_ccmd; |
| logic [StateId-1:0] genreq_id; |
| logic genreq_glast; |
| logic [SeedLen-1:0] genreq_adata; |
| logic genreq_fips; |
| logic [KeyLen-1:0] genreq_key; |
| logic [BlkLen-1:0] genreq_v; |
| logic [CtrLen-1:0] genreq_rc; |
| |
| logic [KeyLen-1:0] adstage_key; |
| logic [BlkLen-1:0] adstage_v; |
| logic [CtrLen-1:0] adstage_rc; |
| logic adstage_fips; |
| logic adstage_glast; |
| logic [SeedLen-1:0] adstage_adata; |
| |
| logic [KeyLen-1:0] rcstage_key; |
| logic [BlkLen-1:0] rcstage_v; |
| logic [BlkLen-1:0] rcstage_bits; |
| logic [CtrLen-1:0] rcstage_rc; |
| logic rcstage_glast; |
| logic rcstage_fips; |
| logic [CtrLen-1:0] rcstage_rc_plus1; |
| logic [Cmd-1:0] rcstage_ccmd; |
| logic [StateId-1:0] rcstage_inst_id; |
| |
| logic [Cmd-1:0] genreq_ccmd_modified; |
| logic [Cmd-1:0] bencack_ccmd_modified; |
| |
| // cmdreq fifo |
| // logic [$clog2(CmdreqFifoDepth):0] sfifo_cmdreq_depth; |
| logic [GenreqFifoWidth-1:0] sfifo_genreq_rdata; |
| logic sfifo_genreq_push; |
| logic [GenreqFifoWidth-1:0] sfifo_genreq_wdata; |
| logic sfifo_genreq_pop; |
| logic sfifo_genreq_full; |
| logic sfifo_genreq_not_empty; |
| |
| // adstage fifo |
| logic [AdstageFifoWidth-1:0] sfifo_adstage_rdata; |
| logic sfifo_adstage_push; |
| logic [AdstageFifoWidth-1:0] sfifo_adstage_wdata; |
| logic sfifo_adstage_pop; |
| logic sfifo_adstage_full; |
| logic sfifo_adstage_not_empty; |
| // blk_encrypt_ack fifo |
| logic [BlkEncAckFifoWidth-1:0] sfifo_bencack_rdata; |
| logic sfifo_bencack_push; |
| logic [BlkEncAckFifoWidth-1:0] sfifo_bencack_wdata; |
| logic sfifo_bencack_pop; |
| logic sfifo_bencack_full; |
| logic sfifo_bencack_not_empty; |
| // breakout |
| logic [Cmd-1:0] sfifo_bencack_ccmd; |
| logic [StateId-1:0] sfifo_bencack_inst_id; |
| logic [BlkLen-1:0] sfifo_bencack_bits; |
| |
| // rcstage fifo |
| logic [RCStageFifoWidth-1:0] sfifo_rcstage_rdata; |
| logic sfifo_rcstage_push; |
| logic [RCStageFifoWidth-1:0] sfifo_rcstage_wdata; |
| logic sfifo_rcstage_pop; |
| logic sfifo_rcstage_full; |
| logic sfifo_rcstage_not_empty; |
| |
| // genbits fifo |
| logic [GenbitsFifoWidth-1:0] sfifo_genbits_rdata; |
| logic sfifo_genbits_push; |
| logic [GenbitsFifoWidth-1:0] sfifo_genbits_wdata; |
| logic sfifo_genbits_pop; |
| logic sfifo_genbits_full; |
| logic sfifo_genbits_not_empty; |
| |
| logic [CtrLen-1:0] v_inc; |
| logic [BlkLen-1:0] v_first; |
| logic [BlkLen-1:0] v_sized; |
| logic v_ctr_load; |
| logic v_ctr_inc; |
| logic interate_ctr_done; |
| logic interate_ctr_inc; |
| logic [NApps-1:0] capt_adata; |
| logic [SeedLen-1:0] update_adata[NApps]; |
| logic [CtrLen-1:0] v_ctr; |
| |
| // flops |
| logic [1:0] interate_ctr_q, interate_ctr_d; |
| logic [SeedLen-1:0] update_adata_q[NApps], update_adata_d[NApps]; |
| logic [NApps-1:0] update_adata_vld_q, update_adata_vld_d; |
| |
| // Encoding generated with: |
| // $ ./util/design/sparse-fsm-encode.py -d 3 -m 4 -n 5 \ |
| // -s 2651202796 --language=sv |
| // |
| // Hamming distance histogram: |
| // |
| // 0: -- |
| // 1: -- |
| // 2: -- |
| // 3: |||||||||||||||||||| (66.67%) |
| // 4: |||||||||| (33.33%) |
| // 5: -- |
| // |
| // Minimum Hamming distance: 3 |
| // Maximum Hamming distance: 4 |
| // Minimum Hamming weight: 2 |
| // Maximum Hamming weight: 3 |
| // |
| |
| localparam int StateWidth = 5; |
| typedef enum logic [StateWidth-1:0] { |
| ReqIdle = 5'b01101, |
| ReqSend = 5'b00011, |
| ESHalt = 5'b11000, |
| ReqError = 5'b10110 |
| } state_e; |
| |
| state_e state_d, state_q; |
| |
| // SEC_CM: UPDATE.FSM.SPARSE |
| `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ReqIdle) |
| |
| always_ff @(posedge clk_i or negedge rst_ni) |
| if (!rst_ni) begin |
| interate_ctr_q <= '0; |
| update_adata_q <= '{default:0}; |
| update_adata_vld_q <= '{default:0}; |
| end else begin |
| interate_ctr_q <= interate_ctr_d; |
| update_adata_q <= update_adata_d; |
| update_adata_vld_q <= update_adata_vld_d; |
| end |
| |
| |
| |
| //-------------------------------------------- |
| // input request fifo for staging gen request |
| //-------------------------------------------- |
| |
| prim_fifo_sync #( |
| .Width(GenreqFifoWidth), |
| .Pass(0), |
| .Depth(GenreqFifoDepth), |
| .OutputZeroIfEmpty(1'b0) |
| ) u_prim_fifo_sync_genreq ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (!ctr_drbg_gen_enable_i), |
| .wvalid_i (sfifo_genreq_push), |
| .wready_o (), |
| .wdata_i (sfifo_genreq_wdata), |
| .rvalid_o (sfifo_genreq_not_empty), |
| .rready_i (sfifo_genreq_pop), |
| .rdata_o (sfifo_genreq_rdata), |
| .full_o (sfifo_genreq_full), |
| .depth_o (), |
| .err_o () |
| ); |
| |
| assign genreq_ccmd_modified = (ctr_drbg_gen_ccmd_i == GEN) ? GENB : INV; |
| |
| assign sfifo_genreq_wdata = {ctr_drbg_gen_key_i,ctr_drbg_gen_v_i,ctr_drbg_gen_rc_i, |
| ctr_drbg_gen_fips_i,ctr_drbg_gen_adata_i,ctr_drbg_gen_glast_i, |
| ctr_drbg_gen_inst_id_i,genreq_ccmd_modified}; |
| |
| assign sfifo_genreq_push = ctr_drbg_gen_enable_i && ctr_drbg_gen_req_i; |
| |
| assign {genreq_key,genreq_v,genreq_rc, |
| genreq_fips,genreq_adata,genreq_glast, |
| genreq_id,genreq_ccmd} = sfifo_genreq_rdata; |
| |
| assign ctr_drbg_gen_rdy_o = !sfifo_genreq_full; |
| |
| assign ctr_drbg_gen_sfifo_ggenreq_err_o = |
| {(sfifo_genreq_push && sfifo_genreq_full), |
| (sfifo_genreq_pop && !sfifo_genreq_not_empty), |
| (sfifo_genreq_full && !sfifo_genreq_not_empty)}; |
| |
| |
| |
| //-------------------------------------------- |
| // prepare value for block_encrypt step |
| //-------------------------------------------- |
| |
| if (CtrLen < BlkLen) begin : gen_ctrlen_sm |
| // for ctr_len < blocklen |
| assign v_inc = genreq_v[CtrLen-1:0] + 1; |
| assign v_first = {genreq_v[BlkLen-1:CtrLen],v_inc}; |
| end else begin : g_ctrlen_lg |
| assign v_first = genreq_v + 1; |
| end |
| |
| // SEC_CM: DRBG_GEN.CTR.REDUN |
| prim_count #( |
| .Width(CtrLen) |
| ) u_prim_count_ctr_drbg ( |
| .clk_i, |
| .rst_ni, |
| .clr_i(!ctr_drbg_gen_enable_i), |
| .set_i(v_ctr_load), |
| .set_cnt_i(v_first[CtrLen-1:0]), |
| .incr_en_i(v_ctr_inc), // count up |
| .decr_en_i(1'b0), |
| .step_i(CtrLen'(1)), |
| .cnt_o(v_ctr), |
| .cnt_next_o(), |
| .err_o(ctr_drbg_gen_v_ctr_err_o) |
| ); |
| |
| assign v_sized = {v_first[BlkLen-1:CtrLen],v_ctr}; |
| |
| // interation counter |
| assign interate_ctr_d = |
| (!ctr_drbg_gen_enable_i) ? '0 : |
| interate_ctr_done ? '0 : |
| interate_ctr_inc ? (interate_ctr_q + 1) : |
| interate_ctr_q; |
| |
| // Supporting only 128b requests |
| assign interate_ctr_done = (interate_ctr_q >= 2'(BlkLen/BlkLen)); |
| |
| //-------------------------------------------- |
| // state machine to send values to block_encrypt |
| //-------------------------------------------- |
| |
| assign block_encrypt_ccmd_o = genreq_ccmd; |
| assign block_encrypt_inst_id_o = genreq_id; |
| assign block_encrypt_key_o = genreq_key; |
| assign block_encrypt_v_o = v_sized; |
| |
| always_comb begin |
| state_d = state_q; |
| v_ctr_load = 1'b0; |
| v_ctr_inc = 1'b0; |
| interate_ctr_inc = 1'b0; |
| sfifo_adstage_push = 1'b0; |
| block_encrypt_req_o = 1'b0; |
| sfifo_genreq_pop = 1'b0; |
| ctr_drbg_gen_sm_err_o = 1'b0; |
| ctr_drbg_gen_es_ack_o = 1'b0; |
| unique case (state_q) |
| // ReqIdle: increment v this cycle, push in next |
| ReqIdle: begin |
| // Prioritize halt requests from entropy_src over disable, as CSRNG would otherwise starve |
| // those requests while it is idle. |
| if (ctr_drbg_gen_es_req_i) begin |
| state_d = ESHalt; |
| end else if (!ctr_drbg_gen_enable_i) begin |
| state_d = ReqIdle; |
| end else if (sfifo_genreq_not_empty && !sfifo_adstage_full) begin |
| v_ctr_load = 1'b1; |
| state_d = ReqSend; |
| end |
| end |
| ReqSend: begin |
| if (!ctr_drbg_gen_enable_i) begin |
| state_d = ReqIdle; |
| end else if (!interate_ctr_done) begin |
| block_encrypt_req_o = 1'b1; |
| sfifo_adstage_push = 1'b1; |
| if (block_encrypt_rdy_i) begin |
| v_ctr_inc = 1'b1; |
| interate_ctr_inc = 1'b1; |
| end |
| end else begin |
| sfifo_genreq_pop = 1'b1; |
| state_d = ReqIdle; |
| end |
| end |
| ESHalt: begin |
| ctr_drbg_gen_es_ack_o = 1'b1; |
| if (!ctr_drbg_gen_es_req_i) begin |
| state_d = ReqIdle; |
| end |
| end |
| ReqError: begin |
| ctr_drbg_gen_sm_err_o = 1'b1; |
| end |
| default: begin |
| state_d = ReqError; |
| ctr_drbg_gen_sm_err_o = 1'b1; |
| end |
| endcase |
| end |
| |
| |
| //-------------------------------------------- |
| // fifo to stage key, v, rc, and adata, waiting for update block to ack |
| //-------------------------------------------- |
| |
| prim_fifo_sync #( |
| .Width(AdstageFifoWidth), |
| .Pass(0), |
| .Depth(AdstageFifoDepth), |
| .OutputZeroIfEmpty(1'b0) |
| ) u_prim_fifo_sync_adstage ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (!ctr_drbg_gen_enable_i), |
| .wvalid_i (sfifo_adstage_push), |
| .wready_o (), |
| .wdata_i (sfifo_adstage_wdata), |
| .rvalid_o (sfifo_adstage_not_empty), |
| .rready_i (sfifo_adstage_pop), |
| .rdata_o (sfifo_adstage_rdata), |
| .full_o (sfifo_adstage_full), |
| .depth_o (), |
| .err_o () |
| ); |
| |
| assign sfifo_adstage_wdata = {genreq_key,v_sized,genreq_rc,genreq_fips,genreq_glast}; |
| assign sfifo_adstage_pop = sfifo_adstage_not_empty && sfifo_bencack_pop; |
| assign {adstage_key,adstage_v,adstage_rc,adstage_fips,adstage_glast} = sfifo_adstage_rdata; |
| |
| assign ctr_drbg_gen_sfifo_gadstage_err_o = |
| {(sfifo_adstage_push && sfifo_adstage_full), |
| (sfifo_adstage_pop && !sfifo_adstage_not_empty), |
| (sfifo_adstage_full && !sfifo_adstage_not_empty)}; |
| |
| |
| // array to hold each channel's adata |
| for (genvar i = 0; i < NApps; i = i+1) begin : gen_adata |
| assign capt_adata[i] = (sfifo_adstage_push && (genreq_id == i)); |
| |
| assign update_adata_vld_d[i] = ~ctr_drbg_gen_enable_i ? 1'b0 : |
| capt_adata[i] && !update_adata_vld_q[i] ? 1'b1 : |
| (gen_upd_req_o && upd_gen_rdy_i && (sfifo_bencack_inst_id == i)) ? 1'b0 : |
| update_adata_vld_q[i]; |
| |
| assign update_adata_d[i] = ~ctr_drbg_gen_enable_i ? '0 : |
| (capt_adata[i] && !update_adata_vld_q[i]) ? genreq_adata : |
| update_adata_q[i]; |
| assign update_adata[i] = update_adata_q[i] & {SeedLen{update_adata_vld_q[i] && |
| (genreq_id == i)}}; |
| end |
| |
| always_comb begin |
| adstage_adata = '0; |
| for (int i = 0; i < NApps; i = i+1) begin |
| // since only one bus is active at a time based on the instant id, |
| // an "or" of all the buses can be done below |
| adstage_adata |= update_adata[i]; |
| end |
| end |
| |
| |
| //-------------------------------------------- |
| // block_encrypt response fifo from block encrypt |
| //-------------------------------------------- |
| |
| prim_fifo_sync #( |
| .Width(BlkEncAckFifoWidth), |
| .Pass(0), |
| .Depth(BlkEncAckFifoDepth), |
| .OutputZeroIfEmpty(1'b0) |
| ) u_prim_fifo_sync_bencack ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (!ctr_drbg_gen_enable_i), |
| .wvalid_i (sfifo_bencack_push), |
| .wready_o (), |
| .wdata_i (sfifo_bencack_wdata), |
| .rvalid_o (sfifo_bencack_not_empty), |
| .rready_i (sfifo_bencack_pop), |
| .rdata_o (sfifo_bencack_rdata), |
| .full_o (sfifo_bencack_full), |
| .depth_o (), |
| .err_o () |
| ); |
| |
| assign bencack_ccmd_modified = (block_encrypt_ccmd_i == GENB) ? GENU : INV; |
| |
| assign sfifo_bencack_push = !sfifo_bencack_full && block_encrypt_ack_i; |
| assign sfifo_bencack_wdata = {block_encrypt_v_i,block_encrypt_inst_id_i,bencack_ccmd_modified}; |
| assign block_encrypt_rdy_o = !sfifo_bencack_full; |
| |
| assign sfifo_bencack_pop = !sfifo_rcstage_full && sfifo_bencack_not_empty && |
| (upd_gen_rdy_i || !adstage_glast); |
| |
| assign {sfifo_bencack_bits,sfifo_bencack_inst_id,sfifo_bencack_ccmd} = sfifo_bencack_rdata; |
| |
| assign ctr_drbg_gen_sfifo_gbencack_err_o = |
| {(sfifo_bencack_push && sfifo_bencack_full), |
| (sfifo_bencack_pop && !sfifo_bencack_not_empty), |
| (sfifo_bencack_full && !sfifo_bencack_not_empty)}; |
| |
| |
| //-------------------------------------------- |
| // prepare values for update step |
| //-------------------------------------------- |
| |
| // send to the update block |
| assign gen_upd_req_o = sfifo_bencack_not_empty && adstage_glast; |
| assign gen_upd_ccmd_o = sfifo_bencack_ccmd; |
| assign gen_upd_inst_id_o = sfifo_bencack_inst_id; |
| assign gen_upd_pdata_o = adstage_adata; |
| assign gen_upd_key_o = adstage_key; |
| assign gen_upd_v_o = adstage_v; |
| |
| |
| |
| //-------------------------------------------- |
| // fifo to stage rc, waiting for update block to ack |
| //-------------------------------------------- |
| |
| prim_fifo_sync #( |
| .Width(RCStageFifoWidth), |
| .Pass(0), |
| .Depth(RCStageFifoDepth), |
| .OutputZeroIfEmpty(1'b0) |
| ) u_prim_fifo_sync_rcstage ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (!ctr_drbg_gen_enable_i), |
| .wvalid_i (sfifo_rcstage_push), |
| .wready_o (), |
| .wdata_i (sfifo_rcstage_wdata), |
| .rvalid_o (sfifo_rcstage_not_empty), |
| .rready_i (sfifo_rcstage_pop), |
| .rdata_o (sfifo_rcstage_rdata), |
| .full_o (sfifo_rcstage_full), |
| .depth_o (), |
| .err_o () |
| ); |
| |
| assign sfifo_rcstage_push = sfifo_adstage_pop; |
| assign sfifo_rcstage_wdata = {adstage_key,adstage_v,sfifo_bencack_bits, |
| adstage_rc,adstage_fips,adstage_glast, |
| sfifo_bencack_inst_id,sfifo_bencack_ccmd}; |
| |
| assign sfifo_rcstage_pop = sfifo_rcstage_not_empty && (upd_gen_ack_i || !rcstage_glast); |
| |
| assign {rcstage_key,rcstage_v,rcstage_bits,rcstage_rc,rcstage_fips,rcstage_glast, |
| rcstage_inst_id,rcstage_ccmd} = sfifo_rcstage_rdata; |
| |
| |
| assign ctr_drbg_gen_sfifo_grcstage_err_o = |
| {(sfifo_rcstage_push && sfifo_rcstage_full), |
| (sfifo_rcstage_pop && !sfifo_rcstage_not_empty), |
| (sfifo_rcstage_full && !sfifo_rcstage_not_empty)}; |
| |
| assign gen_upd_rdy_o = sfifo_rcstage_not_empty && !sfifo_genbits_full; |
| |
| |
| //-------------------------------------------- |
| // final cmd block processing |
| //-------------------------------------------- |
| |
| prim_fifo_sync #( |
| .Width(GenbitsFifoWidth), |
| .Pass(0), |
| .Depth(GenbitsFifoDepth), |
| .OutputZeroIfEmpty(1'b0) |
| ) u_prim_fifo_sync_genbits ( |
| .clk_i (clk_i), |
| .rst_ni (rst_ni), |
| .clr_i (!ctr_drbg_gen_enable_i), |
| .wvalid_i (sfifo_genbits_push), |
| .wready_o (), |
| .wdata_i (sfifo_genbits_wdata), |
| .rvalid_o (sfifo_genbits_not_empty), |
| .rready_i (sfifo_genbits_pop), |
| .rdata_o (sfifo_genbits_rdata), |
| .full_o (sfifo_genbits_full), |
| .depth_o (), |
| .err_o () |
| ); |
| |
| assign sfifo_genbits_push = sfifo_rcstage_pop; |
| |
| assign rcstage_rc_plus1 = (rcstage_rc+1); |
| |
| assign sfifo_genbits_wdata = rcstage_glast ? |
| {rcstage_fips,rcstage_bits,upd_gen_key_i,upd_gen_v_i, |
| rcstage_rc_plus1,upd_gen_inst_id_i,upd_gen_ccmd_i} : |
| {rcstage_fips,rcstage_bits,rcstage_key,rcstage_v, |
| rcstage_rc,rcstage_inst_id,rcstage_ccmd}; |
| |
| assign sfifo_genbits_pop = ctr_drbg_gen_rdy_i && sfifo_genbits_not_empty; |
| assign {ctr_drbg_gen_fips_o,ctr_drbg_gen_bits_o, |
| ctr_drbg_gen_key_o,ctr_drbg_gen_v_o,ctr_drbg_gen_rc_o, |
| ctr_drbg_gen_inst_id_o,ctr_drbg_gen_ccmd_o} = sfifo_genbits_rdata; |
| |
| assign ctr_drbg_gen_sfifo_ggenbits_err_o = |
| {(sfifo_genbits_push && sfifo_genbits_full), |
| (sfifo_genbits_pop && !sfifo_genbits_not_empty), |
| (sfifo_genbits_full && !sfifo_genbits_not_empty)}; |
| |
| // block ack |
| assign ctr_drbg_gen_ack_o = sfifo_genbits_pop; |
| |
| assign ctr_drbg_gen_sts_o = sfifo_genbits_pop && ( |
| (ctr_drbg_gen_ccmd_o == INV) || |
| (ctr_drbg_gen_ccmd_o == INS) || |
| (ctr_drbg_gen_ccmd_o == RES) || |
| (ctr_drbg_gen_ccmd_o == UPD) || |
| (ctr_drbg_gen_ccmd_o == UNI)); |
| |
| // Make sure that the state machine has a stable error state. This means that after the error |
| // state is entered it will not exit it unless a reset signal is received. |
| `ASSERT(CsrngDrbgGenErrorStStable_A, state_q == ReqError |=> $stable(state_q)) |
| // If in error state, the error output must be high. |
| `ASSERT(CsrngDrbgGenErrorOutput_A, |
| !(state_q inside {ReqIdle, ReqSend, ESHalt}) |-> ctr_drbg_gen_sm_err_o) |
| endmodule |