diff options
Diffstat (limited to 'src/rtl')
-rw-r--r-- | src/rtl/trng.v | 121 | ||||
-rw-r--r-- | src/rtl/trng_csprng.v | 61 | ||||
-rw-r--r-- | src/rtl/trng_csprng_fifo.v | 181 | ||||
-rw-r--r-- | src/rtl/trng_mixer.v | 46 |
4 files changed, 218 insertions, 191 deletions
diff --git a/src/rtl/trng.v b/src/rtl/trng.v index 9e8bf69..7a15e7e 100644 --- a/src/rtl/trng.v +++ b/src/rtl/trng.v @@ -76,17 +76,18 @@ module trng( localparam ADDR_NAME1 = 8'h01; localparam ADDR_VERSION = 8'h02; - localparam ADDR_TRNG_CTRL = 8'h10; + localparam ADDR_TRNG_CTRL = 8'h08; localparam TRNG_CTRL_DISCARD_BIT = 0; localparam TRNG_CTRL_TEST_MODE_BIT = 1; - localparam ADDR_TRNG_STATUS = 8'h11; + localparam ADDR_TRNG_STATUS = 8'h09; + localparam ADDR_DEBUG_CTRL = 8'h12; localparam ADDR_DEBUG_DELAY = 8'h13; localparam TRNG_NAME0 = 32'h74726e67; // "trng" localparam TRNG_NAME1 = 32'h20202020; // " " - localparam TRNG_VERSION = 32'h302e3530; // "0.50" + localparam TRNG_VERSION = 32'h302e3531; // "0.51" // 20x/s @ 50 MHz. localparam DEFAULT_DEBUG_DELAY = 32'h002625a0; @@ -329,6 +330,44 @@ module trng( //---------------------------------------------------------------- + // reg_update + // + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin + if (!reset_n) + begin + discard_reg <= 0; + test_mode_reg <= 0; + debug_mux_reg <= DEBUG_CSPRNG; + debug_delay_reg <= DEFAULT_DEBUG_DELAY; + debug_delay_ctr_reg <= 32'h00000000; + debug_out_reg <= 8'h00; + end + else + begin + discard_reg <= discard_new; + debug_delay_ctr_reg <= debug_delay_ctr_new; + + if (debug_out_we) + debug_out_reg <= tmp_debug; + + if (test_mode_we) + test_mode_reg <= test_mode_new; + + if (debug_mux_we) + debug_mux_reg <= debug_mux_new; + + if (debug_delay_we) + debug_delay_reg <= debug_delay_new; + end + end // reg_update + + + //---------------------------------------------------------------- // core_mux // // This is a simple decoder that looks at the top 4 bits of @@ -379,44 +418,6 @@ module trng( //---------------------------------------------------------------- - // reg_update - // - // Update functionality for all registers in the core. - // All registers are positive edge triggered with asynchronous - // active low reset. - //---------------------------------------------------------------- - always @ (posedge clk or negedge reset_n) - begin - if (!reset_n) - begin - discard_reg <= 0; - test_mode_reg <= 0; - debug_mux_reg <= DEBUG_CSPRNG; - debug_delay_reg <= DEFAULT_DEBUG_DELAY; - debug_delay_ctr_reg <= 32'h00000000; - debug_out_reg <= 8'h00; - end - else - begin - discard_reg <= discard_new; - debug_delay_ctr_reg <= debug_delay_ctr_new; - - if (debug_out_we) - debug_out_reg <= tmp_debug; - - if (test_mode_we) - test_mode_reg <= test_mode_new; - - if (debug_mux_we) - debug_mux_reg <= debug_mux_new; - - if (debug_delay_we) - debug_delay_reg <= debug_delay_new; - end - end // reg_update - - - //---------------------------------------------------------------- // debug_update_logic // // Debug update counter and update logic. @@ -505,9 +506,7 @@ module trng( begin if (trng_api_we) begin - // Write operations. case (api_address) - // Write operations. ADDR_TRNG_CTRL: begin discard_new = write_data[TRNG_CTRL_DISCARD_BIT]; @@ -528,60 +527,42 @@ module trng( end default: - begin - trng_api_error = 1; - end + trng_api_error = 1; endcase // case (address) end // if (we) else begin - // Read operations. case (api_address) - // Read operations. ADDR_NAME0: - begin - trng_api_read_data = TRNG_NAME0; - end + trng_api_read_data = TRNG_NAME0; ADDR_NAME1: - begin - trng_api_read_data = TRNG_NAME1; - end + trng_api_read_data = TRNG_NAME1; ADDR_VERSION: - begin - trng_api_read_data = TRNG_VERSION; - end + trng_api_read_data = TRNG_VERSION; ADDR_TRNG_CTRL: - begin - end + trng_api_read_data = {30'h0000000, test_mode_reg, discard_reg}; ADDR_TRNG_STATUS: begin - + // No error caused by reading status. end ADDR_DEBUG_CTRL: - begin - trng_api_read_data = {29'h0000000, debug_mux_new}; - end + trng_api_read_data = {29'h0000000, debug_mux_new}; ADDR_DEBUG_DELAY: - begin - trng_api_read_data = debug_delay_reg; - end + trng_api_read_data = debug_delay_reg; default: - begin - trng_api_error = 1; - end + trng_api_error = 1; endcase // case (address) end end end // trng_api_logic - endmodule // trng //====================================================================== diff --git a/src/rtl/trng_csprng.v b/src/rtl/trng_csprng.v index ce5c89c..d33e72a 100644 --- a/src/rtl/trng_csprng.v +++ b/src/rtl/trng_csprng.v @@ -49,7 +49,7 @@ module trng_csprng( output wire error, input wire discard, - input test_mode, + input wire test_mode, output wire more_seed, output wire security_error, @@ -78,6 +78,7 @@ module trng_csprng( localparam ADDR_STAT_BLOCKS_LOW = 8'h14; localparam ADDR_STAT_BLOCKS_HIGH = 8'h15; + localparam ADDR_STAT_RESEEDS = 8'h16; localparam ADDR_RND_DATA = 8'h20; @@ -103,7 +104,7 @@ module trng_csprng( localparam ADDR_TEST_SEED_W15 = 8'h8f; localparam CIPHER_KEYLEN256 = 1'b1; // 256 bit key. - localparam CIPHER_MAX_BLOCKS = 64'h1000000000000000; + localparam CIPHER_MAX_BLOCKS = 64'h0000000100000000; localparam CTRL_IDLE = 4'h0; localparam CTRL_SEED0 = 4'h1; @@ -117,7 +118,7 @@ module trng_csprng( localparam CTRL_CANCEL = 4'hf; localparam DEFAULT_NUM_ROUNDS = 5'h18; - localparam DEFAULT_NUM_BLOCKS = 64'h1000000000000000; + localparam DEFAULT_NUM_BLOCKS = 64'h0000000001000000; parameter CORE_NAME0 = 32'h63737072; // "cspr" parameter CORE_NAME1 = 32'h6e672020; // "ng " @@ -152,6 +153,12 @@ module trng_csprng( reg [63 : 0] block_stat_ctr_reg; reg [63 : 0] block_stat_ctr_new; + reg block_stat_ctr_we; + + reg [31 : 0] reseed_stat_ctr_reg; + reg [31 : 0] reseed_stat_ctr_new; + reg reseed_stat_ctr_inc; + reg reseed_stat_ctr_we; reg ready_reg; reg ready_new; @@ -279,6 +286,7 @@ module trng_csprng( cipher_block_reg <= {16{32'h00000000}}; block_ctr_reg <= {2{32'h00000000}}; block_stat_ctr_reg <= {2{32'h00000000}}; + reseed_stat_ctr_reg <= 32'h00000000; more_seed_reg <= 0; seed_ack_reg <= 0; ready_reg <= 0; @@ -313,9 +321,16 @@ module trng_csprng( if (block_ctr_we) begin block_ctr_reg <= block_ctr_new; + end + + if (block_stat_ctr_we) + begin block_stat_ctr_reg <= block_stat_ctr_new; end + if (reseed_stat_ctr_we) + reseed_stat_ctr_reg <= reseed_stat_ctr_new; + if (ready_we) ready_reg <= ready_new; @@ -421,6 +436,9 @@ module trng_csprng( ADDR_STAT_BLOCKS_HIGH: tmp_read_data = block_stat_ctr_reg[63 : 32]; + ADDR_STAT_RESEEDS: + tmp_read_data = reseed_stat_ctr_reg; + ADDR_RND_DATA: begin tmp_read_data = rnd_data; @@ -453,7 +471,7 @@ module trng_csprng( // ability to detect that maximum allowed number of blocks // has been reached. Either as defined by the application // or the hard coded CIPHER_MAX_BLOCKS value. - + // // The stat counter is a sepatate block counter updated in // sync with the block counter. It is only used to track the // number of blocks generated from the cipher as a metric @@ -465,6 +483,7 @@ module trng_csprng( block_ctr_we = 1'b0; block_ctr_max = 1'b0; block_stat_ctr_new = {2{32'h00000000}}; + block_stat_ctr_we = 1'b0; if (block_ctr_rst) begin @@ -475,8 +494,9 @@ module trng_csprng( if (block_ctr_inc) begin block_ctr_new = block_ctr_reg + 1'b1; - block_stat_ctr_new = block_stat_ctr_reg + 1'b1; block_ctr_we = 1; + block_stat_ctr_new = block_stat_ctr_reg + 1'b1; + block_stat_ctr_we = 1; end if ((block_ctr_reg == {num_blocks_high_reg, num_blocks_low_reg}) || @@ -488,6 +508,27 @@ module trng_csprng( //---------------------------------------------------------------- + // reseed_ctr + // + // A simple monotonically increasing counter that counts the + // number of times the CSPRNG has been reseeded. is reseeded. + // Note that the counter is 32-bit and it is up to SW to handle + // wrap around issues. + //---------------------------------------------------------------- + always @* + begin : reseed_ctr + reseed_stat_ctr_new = 32'h00000000; + reseed_stat_ctr_we = 0; + + if (reseed_stat_ctr_inc) + begin + reseed_stat_ctr_new = reseed_stat_ctr_reg + 1'b1; + reseed_stat_ctr_we = 1; + end + end // reseed_ctr + + + //---------------------------------------------------------------- // csprng_ctrl_fsm // // Control FSM for the CSPRNG. @@ -512,6 +553,7 @@ module trng_csprng( more_seed_new = 0; fifo_discard = 0; fifo_cipher_data_valid = 0; + reseed_stat_ctr_inc = 0; csprng_ctrl_new = CTRL_IDLE; csprng_ctrl_we = 0; @@ -597,10 +639,11 @@ module trng_csprng( end else begin - cipher_init = 1; - block_ctr_rst = 1; - csprng_ctrl_new = CTRL_INIT1; - csprng_ctrl_we = 1; + reseed_stat_ctr_inc = 1; + cipher_init = 1; + block_ctr_rst = 1; + csprng_ctrl_new = CTRL_INIT1; + csprng_ctrl_we = 1; end end diff --git a/src/rtl/trng_csprng_fifo.v b/src/rtl/trng_csprng_fifo.v index 1f91802..e3fe4fb 100644 --- a/src/rtl/trng_csprng_fifo.v +++ b/src/rtl/trng_csprng_fifo.v @@ -56,11 +56,12 @@ module trng_csprng_fifo( // Internal constant and parameter definitions. //---------------------------------------------------------------- localparam FIFO_ADDR_BITS = 2; - localparam FIFO_ADDR_MAX = FIFO_ADDR_BITS - 1; - localparam FIFO_MAX = (2 ** FIFO_ADDR_BITS) - 1; + localparam FIFO_ADDR_MAX = (2**FIFO_ADDR_BITS) - 1; + localparam FIFO_MAX = (2 ** FIFO_ADDR_BITS); localparam WR_IDLE = 0; - localparam WR_STORE = 1; + localparam WR_WAIT = 1; + localparam WR_NEXT = 2; localparam WR_DISCARD = 7; localparam RD_IDLE = 0; @@ -71,7 +72,7 @@ module trng_csprng_fifo( //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- - reg [511 : 0] fifo_mem [0 : FIFO_MAX]; + reg [511 : 0] fifo_mem [0 : FIFO_ADDR_MAX]; reg fifo_mem_we; reg [3 : 0] mux_data_ptr_reg; @@ -80,26 +81,26 @@ module trng_csprng_fifo( reg mux_data_ptr_rst; reg mux_data_ptr_we; - reg [FIFO_ADDR_MAX : 0] rd_ptr_reg; - reg [FIFO_ADDR_MAX : 0] rd_ptr_new; - reg rd_ptr_inc; - reg rd_ptr_rst; - reg rd_ptr_we; - - reg [FIFO_ADDR_MAX : 0] wr_ptr_reg; - reg [FIFO_ADDR_MAX : 0] wr_ptr_new; - reg wr_ptr_inc; - reg wr_ptr_rst; - reg wr_ptr_we; - - reg [FIFO_ADDR_MAX : 0] fifo_ctr_reg; - reg [FIFO_ADDR_MAX : 0] fifo_ctr_new; - reg fifo_ctr_inc; - reg fifo_ctr_dec; - reg fifo_ctr_rst; - reg fifo_ctr_we; - reg fifo_empty; - reg fifo_full; + reg [(FIFO_ADDR_BITS - 1) : 0] rd_ptr_reg; + reg [(FIFO_ADDR_BITS - 1) : 0] rd_ptr_new; + reg rd_ptr_inc; + reg rd_ptr_rst; + reg rd_ptr_we; + + reg [(FIFO_ADDR_BITS - 1) : 0] wr_ptr_reg; + reg [(FIFO_ADDR_BITS - 1) : 0] wr_ptr_new; + reg wr_ptr_inc; + reg wr_ptr_rst; + reg wr_ptr_we; + + reg [FIFO_ADDR_BITS : 0] fifo_ctr_reg; + reg [FIFO_ADDR_BITS : 0] fifo_ctr_new; + reg fifo_ctr_inc; + reg fifo_ctr_dec; + reg fifo_ctr_rst; + reg fifo_ctr_we; + reg fifo_empty; + reg fifo_full; reg [31 : 0] rnd_data_reg; @@ -117,6 +118,7 @@ module trng_csprng_fifo( reg more_data_reg; reg more_data_new; + reg more_data_we; //---------------------------------------------------------------- @@ -147,8 +149,8 @@ module trng_csprng_fifo( fifo_mem[02] <= {16{32'h00000000}}; fifo_mem[03] <= {16{32'h00000000}}; mux_data_ptr_reg <= 4'h0; - rd_ptr_reg <= {FIFO_ADDR_BITS{1'b0}}; - wr_ptr_reg <= {FIFO_ADDR_BITS{1'b0}}; + rd_ptr_reg <= {(FIFO_ADDR_BITS){1'b0}}; + wr_ptr_reg <= {(FIFO_ADDR_BITS){1'b0}}; fifo_ctr_reg <= {FIFO_ADDR_BITS{1'b0}}; rnd_data_reg <= 32'h00000000; rnd_syn_reg <= 0; @@ -158,48 +160,34 @@ module trng_csprng_fifo( end else begin - rnd_data_reg <= muxed_data; - more_data_reg <= more_data_new; + rnd_data_reg <= muxed_data; + + if (more_data_we) + more_data_reg <= more_data_new; if (rnd_syn_we) - begin - rnd_syn_reg <= rnd_syn_new; - end + rnd_syn_reg <= rnd_syn_new; if (fifo_mem_we) - begin - fifo_mem[wr_ptr_reg] <= csprng_data; - end + fifo_mem[wr_ptr_reg] <= csprng_data; if (mux_data_ptr_we) - begin - mux_data_ptr_reg <= mux_data_ptr_new; - end + mux_data_ptr_reg <= mux_data_ptr_new; if (rd_ptr_we) - begin - rd_ptr_reg <= rd_ptr_new; - end + rd_ptr_reg <= rd_ptr_new; if (wr_ptr_we) - begin - wr_ptr_reg <= wr_ptr_new; - end + wr_ptr_reg <= wr_ptr_new; if (fifo_ctr_we) - begin - fifo_ctr_reg <= fifo_ctr_new; - end + fifo_ctr_reg <= fifo_ctr_new; if (rd_ctrl_we) - begin - rd_ctrl_reg <= rd_ctrl_new; - end + rd_ctrl_reg <= rd_ctrl_new; if (wr_ctrl_we) - begin - wr_ctrl_reg <= wr_ctrl_new; - end + wr_ctrl_reg <= wr_ctrl_new; end end // reg_update @@ -257,18 +245,16 @@ module trng_csprng_fifo( fifo_ctr_dec = 0; if (rd_ptr_rst) - rd_ptr_we = 1; + begin + rd_ptr_new = {FIFO_ADDR_BITS{1'b0}}; + rd_ptr_we = 1; + end if (rd_ptr_inc) begin - fifo_ctr_dec = 1; - if (rd_ptr_reg == FIFO_MAX) - rd_ptr_we = 1; - else - begin - rd_ptr_new = rd_ptr_reg + 1'b1; - rd_ptr_we = 1; - end + fifo_ctr_dec = 1; + rd_ptr_new = rd_ptr_reg + 1'b1; + rd_ptr_we = 1; end end // fifo_rd_ptr @@ -280,21 +266,21 @@ module trng_csprng_fifo( //---------------------------------------------------------------- always @* begin : fifo_wr_ptr - wr_ptr_new = {FIFO_ADDR_BITS{1'b0}}; - wr_ptr_we = 0; + wr_ptr_new = {FIFO_ADDR_BITS{1'b0}}; + wr_ptr_we = 0; + fifo_ctr_inc = 0; if (wr_ptr_rst) - wr_ptr_we = 1; + begin + wr_ptr_new = {FIFO_ADDR_BITS{1'b0}}; + wr_ptr_we = 1; + end if (wr_ptr_inc) begin - if (wr_ptr_reg == FIFO_MAX) - wr_ptr_we = 1; - else - begin - wr_ptr_new = wr_ptr_reg + 1'b1; - wr_ptr_we = 1; - end + fifo_ctr_inc = 1; + wr_ptr_new = wr_ptr_reg + 1'b1; + wr_ptr_we = 1; end end // fifo_wr_ptr @@ -310,7 +296,7 @@ module trng_csprng_fifo( //---------------------------------------------------------------- always @* begin : fifo_ctr - fifo_ctr_new = {FIFO_ADDR_BITS{1'b0}}; + fifo_ctr_new = {(FIFO_ADDR_BITS + 1){1'b0}}; fifo_ctr_we = 0; fifo_empty = 0; fifo_full = 0; @@ -326,15 +312,18 @@ module trng_csprng_fifo( end if (fifo_ctr_rst) - fifo_ctr_we = 1; + begin + fifo_ctr_new = {(FIFO_ADDR_BITS + 1){1'b0}}; + fifo_ctr_we = 1; + end - if ((fifo_ctr_inc) && (fifo_ctr_reg < FIFO_MAX)) + if (fifo_ctr_inc) begin fifo_ctr_new = fifo_ctr_reg + 1'b1; fifo_ctr_we = 1; end - if ((fifo_ctr_dec) && (fifo_ctr_reg > 0)) + if (fifo_ctr_dec) begin fifo_ctr_new = fifo_ctr_reg - 1'b1; fifo_ctr_we = 1; @@ -429,9 +418,9 @@ module trng_csprng_fifo( wr_ptr_inc = 0; wr_ptr_rst = 0; fifo_mem_we = 0; - fifo_ctr_inc = 0; fifo_ctr_rst = 0; more_data_new = 0; + more_data_we = 0; wr_ctrl_new = WR_IDLE; wr_ctrl_we = 0; @@ -448,31 +437,43 @@ module trng_csprng_fifo( if (!fifo_full) begin more_data_new = 1'b1; + more_data_we = 1'b1; + wr_ctrl_new = WR_WAIT; + wr_ctrl_we = 1; end - - if (csprng_data_valid) + else begin - wr_ctrl_new = WR_STORE; - wr_ctrl_we = 1; + more_data_new = 1'b0; + more_data_we = 1'b1; end end end - WR_STORE: + WR_WAIT: begin - fifo_mem_we = 1; - wr_ptr_inc = 1; - fifo_ctr_inc = 1; - wr_ctrl_new = WR_IDLE; - wr_ctrl_we = 1; + if (csprng_data_valid) + begin + fifo_mem_we = 1; + wr_ptr_inc = 1; + wr_ctrl_new = WR_NEXT; + wr_ctrl_we = 1; + end + end + + WR_NEXT: + begin + more_data_new = 1'b0; + more_data_we = 1'b1; + wr_ctrl_new = WR_IDLE; + wr_ctrl_we = 1; end WR_DISCARD: begin - fifo_ctr_rst = 1; - wr_ptr_rst = 1; - wr_ctrl_new = WR_IDLE; - wr_ctrl_we = 1; + fifo_ctr_rst = 1; + wr_ptr_rst = 1; + wr_ctrl_new = WR_IDLE; + wr_ctrl_we = 1; end endcase // case (wr_ctrl_reg) end // wr_ctrl diff --git a/src/rtl/trng_mixer.v b/src/rtl/trng_mixer.v index 97777ac..d192090 100644 --- a/src/rtl/trng_mixer.v +++ b/src/rtl/trng_mixer.v @@ -80,34 +80,36 @@ module trng_mixer( //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - parameter MODE_SHA_512 = 2'h3; - - parameter ENTROPY_IDLE = 4'h0; - parameter ENTROPY_SRC0 = 4'h1; - parameter ENTROPY_SRC0_ACK = 4'h2; - parameter ENTROPY_SRC1 = 4'h3; - parameter ENTROPY_SRC1_ACK = 4'h4; - parameter ENTROPY_SRC2 = 4'h5; - parameter ENTROPY_SRC2_ACK = 4'h6; - - parameter CTRL_IDLE = 4'h0; - parameter CTRL_COLLECT = 4'h1; - parameter CTRL_MIX = 4'h2; - parameter CTRL_SYN = 4'h3; - parameter CTRL_ACK = 4'h4; - parameter CTRL_NEXT = 4'h5; + localparam MODE_SHA_512 = 2'h3; + + localparam ENTROPY_IDLE = 4'h0; + localparam ENTROPY_SRC0 = 4'h1; + localparam ENTROPY_SRC0_ACK = 4'h2; + localparam ENTROPY_SRC1 = 4'h3; + localparam ENTROPY_SRC1_ACK = 4'h4; + localparam ENTROPY_SRC2 = 4'h5; + localparam ENTROPY_SRC2_ACK = 4'h6; + localparam TEST_ENTROPY = 4'he; + localparam TEST_ENTROPY_ACK = 4'hf; + + localparam CTRL_IDLE = 4'h0; + localparam CTRL_COLLECT = 4'h1; + localparam CTRL_MIX = 4'h2; + localparam CTRL_SYN = 4'h3; + localparam CTRL_ACK = 4'h4; + localparam CTRL_NEXT = 4'h5; localparam ADDR_NAME0 = 8'h00; localparam ADDR_NAME1 = 8'h01; localparam ADDR_VERSION = 8'h02; - parameter ADDR_MIXER_CTRL = 8'h10; - parameter MIXER_CTRL_ENABLE_BIT = 0; - parameter MIXER_CTRL_RESTART_BIT = 1; - parameter ADDR_MIXER_STATUS = 8'h11; - parameter ADDR_MIXER_TIMEOUT = 8'h20; + localparam ADDR_MIXER_CTRL = 8'h10; + localparam MIXER_CTRL_ENABLE_BIT = 0; + localparam MIXER_CTRL_RESTART_BIT = 1; + localparam ADDR_MIXER_STATUS = 8'h11; + localparam ADDR_MIXER_TIMEOUT = 8'h20; - parameter DEFAULT_ENTROPY_TIMEOUT = 24'h100000; + localparam DEFAULT_ENTROPY_TIMEOUT = 24'h100000; parameter CORE_NAME0 = 32'h726e676d; // "rngm" parameter CORE_NAME1 = 32'h69786572; // "ixer" |