diff options
-rw-r--r-- | src/rtl/trng.v | 682 | ||||
-rw-r--r-- | src/rtl/trng_csprng.v | 277 | ||||
-rw-r--r-- | src/rtl/trng_mixer.v | 128 |
3 files changed, 629 insertions, 458 deletions
diff --git a/src/rtl/trng.v b/src/rtl/trng.v index 29a4d11..f00aa79 100644 --- a/src/rtl/trng.v +++ b/src/rtl/trng.v @@ -1,4 +1,4 @@ -//====================================================================== + //====================================================================== // // trng.v // -------- @@ -45,7 +45,7 @@ module trng( input wire cs, input wire we, - input wire [7 : 0] address, + input wire [11 : 0] address, input wire [31 : 0] write_data, output wire [31 : 0] read_data, output wire error, @@ -60,141 +60,108 @@ module trng( //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - parameter ADDR_NAME0 = 8'h00; - parameter ADDR_NAME1 = 8'h01; - parameter ADDR_VERSION = 8'h02; - - parameter ADDR_TRNG_CTRL = 8'h10; - parameter TRNG_CTRL_ENABLE_BIT = 0; - parameter TRNG_CTRL_ENT0_ENABLE_BIT = 1; - parameter TRNG_CTRL_ENT1_ENABLE_BIT = 2; - parameter TRNG_CTRL_ENT2_ENABLE_BIT = 3; - parameter TRNG_CTRL_SEED_BIT = 8; - - parameter ADDR_TRNG_STATUS = 8'h11; - - parameter ADDR_TRNG_RND_DATA = 8'h20; - parameter ADDR_TRNG_RND_DATA_VALID = 8'h21; - parameter TRNG_RND_VALID_BIT = 0; - - parameter ADDR_CSPRNG_NUM_ROUNDS = 8'h30; - parameter ADDR_CSPRNG_NUM_BLOCKS_LOW = 8'h31; - parameter ADDR_CSPRNG_NUM_BLOCKS_HIGH = 8'h32; - - parameter ADDR_ENTROPY0_RAW = 8'h40; - parameter ADDR_ENTROPY0_STATS = 8'h41; - - parameter ADDR_ENTROPY1_RAW = 8'h50; - parameter ADDR_ENTROPY1_STATS = 8'h51; + parameter TRNG_PREFIX = 4'h0; + parameter ENTROPY1_PREFIX = 4'h5; + parameter ENTROPY2_PREFIX = 4'h6; + parameter MIXER_PREFIX = 4'ha; + parameter CSPRNG_PREFIX = 4'hb; - parameter ADDR_ENTROPY2_RAW = 8'h60; - parameter ADDR_ENTROPY2_STATS = 8'h61; - parameter ADDR_ENTROPY2_OP_A = 8'h68; - parameter ADDR_ENTROPY2_OP_B = 8'h69; + parameter DEBUG_ENTROPY0 = 3'h0; + parameter DEBUG_ENTROPY1 = 3'h1; + parameter DEBUG_ENTROPY2 = 3'h2; + parameter DEBUG_MIXER = 3'h3; + parameter DEBUG_CSPRNG = 3'h4; + parameter ADDR_NAME0 = 8'h00; + parameter ADDR_NAME1 = 8'h01; + parameter ADDR_VERSION = 8'h02; - parameter TRNG_NAME0 = 32'h74726e67; // "trng" - parameter TRNG_NAME1 = 32'h20202020; // " " - parameter TRNG_VERSION = 32'h302e3031; // "0.01" + parameter ADDR_TRNG_CTRL = 8'h10; + parameter TRNG_CTRL_DISCARD_BIT = 0; + parameter TRNG_CTRL_TEST_MODE_BIT = 1; + parameter ADDR_TRNG_STATUS = 8'h11; + parameter ADDR_DEBUG_CTRL = 8'h12; - parameter CSPRNG_DEFAULT_NUM_ROUNDS = 5'h18; - parameter CSPRNG_DEFAULT_NUM_BLOCKS = 64'h1000000000000000; + parameter TRNG_NAME0 = 32'h74726e67; // "trng" + parameter TRNG_NAME1 = 32'h20202020; // " " + parameter TRNG_VERSION = 32'h302e3031; // "0.01" //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- - reg [4 : 0] csprng_num_rounds_reg; - reg [4 : 0] csprng_num_rounds_new; - reg csprng_num_rounds_we; - - reg [31 : 0] csprng_num_blocks_low_reg; - reg [31 : 0] csprng_num_blocks_low_new; - reg csprng_num_blocks_low_we; - - reg [31 : 0] csprng_num_blocks_high_reg; - reg [31 : 0] csprng_num_blocks_high_new; - reg csprng_num_blocks_high_we; - - reg entropy0_enable_reg; - reg entropy0_enable_new; - reg entropy0_enable_we; - - reg entropy1_enable_reg; - reg entropy1_enable_new; - reg entropy1_enable_we; - - reg entropy2_enable_reg; - reg entropy2_enable_new; - reg entropy2_enable_we; - - reg [31 : 0] entropy2_op_a_reg; - reg [31 : 0] entropy2_op_a_new; - reg entropy2_op_a_we; - - reg [31 : 0] entropy2_op_b_reg; - reg [31 : 0] entropy2_op_b_new; - reg entropy2_op_b_we; + reg discard_reg; + reg discard_new; - reg enable_reg; - reg enable_new; - reg enable_we; - - reg csprng_seed_reg; - reg csprng_seed_new; - - reg csprng_rnd_ack_reg; - reg csprng_rnd_ack_new; + reg test_mode_reg; + reg test_mode_new; + reg test_mode_we; + reg [2 : 0] debug_mux_reg; + reg [2 : 0] debug_mux_new; + reg [2 : 0] debug_mux_we; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- - wire entropy0_enable; - wire [31 : 0] entropy0_raw; - wire [31 : 0] entropy0_stats; - wire entropy0_enabled; - wire entropy0_syn; - wire [31 : 0] entropy0_data; - wire entropy0_ack; - - wire entropy1_enable; - wire [31 : 0] entropy1_raw; - wire [31 : 0] entropy1_stats; - wire entropy1_enabled; - wire entropy1_syn; - wire [31 : 0] entropy1_data; - wire entropy1_ack; - - wire entropy2_enable; - wire [31 : 0] entropy2_raw; - wire [31 : 0] entropy2_stats; - wire entropy2_enabled; - wire entropy2_syn; - wire [31 : 0] entropy2_data; - wire entropy2_ack; - wire [7 : 0] entropy2_debug; + reg trng_api_cs; + reg trng_api_we; + reg [31 : 0] trng_api_read_data; + reg trng_api_error; - wire mixer_enable; + wire mixer_more_seed; wire [511 : 0] mixer_seed_data; wire mixer_seed_syn; + wire mixer_seed_ack; + reg mixer_api_cs; + reg mixer_api_we; + wire [31 : 0] mixer_api_read_data; + wire mixer_api_error; - wire csprng_enable; - wire csprng_debug_mode; - wire [4 : 0] csprng_num_rounds; - wire [63 : 0] csprng_num_blocks; - wire csprng_seed; wire csprng_more_seed; wire csprng_seed_ack; - wire csprng_ready; - wire csprng_error; - wire [31 : 0] csprng_rnd_data; - wire csprng_rnd_syn; + reg csprng_api_cs; + reg csprng_api_we; + wire [31 : 0] csprng_api_read_data; + wire csprng_api_error; + + wire entropy0_entropy_enabled; + wire [31 : 0] entropy0_entropy_data; + wire entropy0_entropy_syn; + wire entropy0_entropy_ack; + + reg entropy1_api_cs; + reg entropy1_api_we; + wire [31 : 0] entropy1_api_read_data; + wire entropy1_api_error; + wire entropy1_entropy_enabled; + wire [31 : 0] entropy1_entropy_data; + wire entropy1_entropy_syn; + wire entropy1_entropy_ack; + wire entropy1_test_mode; + wire [7 : 0] entropy1_debug; + reg entropy1_debug_update; + wire entropy1_security_error; + + reg entropy2_api_cs; + reg entropy2_api_we; + wire [31 : 0] entropy2_api_read_data; + wire entropy2_api_error; + wire entropy2_entropy_enabled; + wire [31 : 0] entropy2_entropy_data; + wire entropy2_entropy_syn; + wire entropy2_entropy_ack; + wire entropy2_test_mode; + wire [7 : 0] entropy2_debug; + reg entropy2_debug_update; + wire entropy2_security_error; + reg [7 : 0] api_address; reg [31 : 0] tmp_read_data; reg tmp_error; + reg [7 : 0] tmp_debug; //---------------------------------------------------------------- @@ -202,33 +169,13 @@ module trng( //---------------------------------------------------------------- assign read_data = tmp_read_data; assign error = tmp_error; - assign security_error = 0; - assign debug = entropy2_debug; - - assign csprng_num_blocks = {csprng_num_blocks_high_reg, - csprng_num_blocks_low_reg}; - - assign entropy0_enable = entropy0_enable_reg; - assign entropy1_enable = entropy1_enable_reg; - assign entropy2_enable = entropy2_enable_reg; - - assign mixer_enable = enable_reg; - - assign csprng_enable = enable_reg; - assign csprng_seed = csprng_seed_reg; - assign csprng_debug_mode = 0; + assign security_error = entropy1_security_error | entropy2_security_error; + assign debug = tmp_debug; // Patches to get our first version to work. - assign entropy0_enabled = 0; - assign entropy0_raw = 32'h00000000; - assign entropy0_stats = 32'h00000000; - assign entropy0_syn = 0; - assign entropy0_data = 32'h00000000; - - assign entropy1_enabled = 1; - - assign entropy2_enabled = 1; - assign entropy2_stats = 32'h00000000; + assign entropy0_entropy_enabled = 0; + assign entropy0_entropy_syn = 0; + assign entropy0_entropy_data = 32'h00000000; //---------------------------------------------------------------- @@ -238,23 +185,32 @@ module trng( .clk(clk), .reset_n(reset_n), - .enable(mixer_enable), + .cs(mixer_api_cs), + .we(mixer_api_we), + .address(api_address), + .write_data(write_data), + .read_data(mixer_api_read_data), + .error(mixer_api_error), + + .discard(discard_reg), + .test_mode(test_mode_reg), + .more_seed(csprng_more_seed), - .entropy0_enabled(entropy0_enabled), - .entropy0_syn(entropy0_syn), - .entropy0_data(entropy0_data), - .entropy0_ack(entropy0_ack), + .entropy0_enabled(entropy0_entropy_enabled), + .entropy0_syn(entropy0_entropy_syn), + .entropy0_data(entropy0_entropy_data), + .entropy0_ack(entropy0_entropy_ack), - .entropy1_enabled(entropy1_enabled), - .entropy1_syn(entropy1_syn), - .entropy1_data(entropy1_data), - .entropy1_ack(entropy1_ack), + .entropy1_enabled(entropy1_entropy_enabled), + .entropy1_syn(entropy1_entropy_syn), + .entropy1_data(entropy1_entropy_data), + .entropy1_ack(entropy1_entropy_ack), - .entropy2_enabled(entropy2_enabled), - .entropy2_syn(entropy2_syn), - .entropy2_data(entropy2_data), - .entropy2_ack(entropy2_ack), + .entropy2_enabled(entropy2_entropy_enabled), + .entropy2_syn(entropy2_entropy_syn), + .entropy2_data(entropy2_entropy_data), + .entropy2_ack(entropy2_entropy_ack), .seed_data(mixer_seed_data), .seed_syn(mixer_seed_syn), @@ -265,77 +221,72 @@ module trng( .clk(clk), .reset_n(reset_n), - .enable(csprng_enable), - .debug_mode(csprng_debug_mode), - .num_rounds(csprng_num_rounds_reg), - .num_blocks(csprng_num_blocks), - .seed(csprng_seed), + .cs(csprng_api_cs), + .we(csprng_api_we), + .address(api_address), + .write_data(write_data), + .read_data(csprng_api_read_data), + .error(csprng_api_error), + + .discard(discard_reg), + .test_mode(test_mode_reg), + .more_seed(csprng_more_seed), - .ready(csprng_ready), - .error(csprng_error), .seed_data(mixer_seed_data), .seed_syn(mixer_seed_syn), - .seed_ack(csprng_seed_ack), - - .rnd_data(csprng_rnd_data), - .rnd_syn(csprng_rnd_syn), - .rnd_ack(csprng_rnd_ack_reg) + .seed_ack(csprng_seed_ack) ); -// pseudo_entropy entropy0( -// .clk(clk), -// .reset_n(reset_n), -// -// .enable(entropy0_enable), -// -// .raw_entropy(entropy0_raw), -// .stats(entropy0_stats), -// -// .enabled(entropy0_enabled), -// .entropy_syn(entropy0_syn), -// .entropy_data(entropy0_data), -// .entropy_ack(entropy0_ack) -// ); - - avalanche_entropy_core entropy1( - .clk(clk), - .reset_n(reset_n), + avalanche_entropy entropy1( + .clk(clk), + .reset_n(reset_n), - .noise(avalanche_noise), - .sampled_noise(), - .entropy(), + .noise(avalanche_noise), - .entropy_syn(entropy1_syn), - .entropy_data(entropy1_data), - .entropy_ack(entropy1_ack), + .cs(entropy1_api_cs), + .we(entropy1_api_we), + .address(api_address), + .write_data(write_data), + .read_data(entropy1_api_read_data), + .error(entropy1_api_error), - .led(), - .debug_data(entropy1_raw), - .debug_clk(), + .discard(discard_reg), + .test_mode(test_mode_reg), + .security_error(entropy1_security_error), - .delta_data(entropy1_stats), - .delta_clk() - ); + .entropy_enabled(entropy1_entropy_enabled), + .entropy_data(entropy1_entropy_data), + .entropy_valid(entropy1_entropy_syn), + .entropy_ack(entropy1_entropy_ack), - rosc_entropy_core entropy2( - .clk(clk), - .reset_n(reset_n), + .debug(entropy1_debug), + .debug_update(entropy1_debug_update) + ); - .enable(entropy2_enable), + rosc_entropy entropy2( + .clk(clk), + .reset_n(reset_n), - .opa(entropy2_op_a_reg), - .opb(entropy2_op_b_reg), + .cs(entropy2_api_cs), + .we(entropy2_api_we), + .address(api_address), + .write_data(write_data), + .read_data(entropy2_api_read_data), + .error(entropy2_api_error), - .entropy(entropy2_raw), + .discard(discard_reg), + .test_mode(test_mode_reg), + .security_error(entropy2_security_error), - .rnd_data(entropy2_data), - .rnd_valid(entropy2_syn), - .rnd_ack(entropy2_ack), + .entropy_enabled(entropy2_entropy_enabled), + .entropy_data(entropy2_entropy_data), + .entropy_valid(entropy2_entropy_syn), + .entropy_ack(entropy2_entropy_ack), - .debug(entropy2_debug), - .debug_update(debug_update) - ); + .debug(entropy2_debug), + .debug_update(entropy2_debug_update) + ); //---------------------------------------------------------------- @@ -343,162 +294,181 @@ module trng( // // Update functionality for all registers in the core. // All registers are positive edge triggered with asynchronous - // active low reset. All registers have write enable. + // active low reset. //---------------------------------------------------------------- always @ (posedge clk or negedge reset_n) begin if (!reset_n) begin - entropy0_enable_reg <= 1; - entropy1_enable_reg <= 1; - entropy2_enable_reg <= 1; - entropy2_op_a_reg <= 32'h01010101; - entropy2_op_a_reg <= 32'h10101010; - enable_reg <= 1; - csprng_rnd_ack_reg <= 0; - csprng_seed_reg <= 0; - csprng_num_rounds_reg <= CSPRNG_DEFAULT_NUM_ROUNDS; - csprng_num_blocks_low_reg <= CSPRNG_DEFAULT_NUM_BLOCKS[31 : 0]; - csprng_num_blocks_high_reg <= CSPRNG_DEFAULT_NUM_BLOCKS[63 : 32]; + discard_reg <= 0; + test_mode_reg <= 0; + debug_mux_reg <= DEBUG_ENTROPY1; end else begin - csprng_rnd_ack_reg <= csprng_rnd_ack_new; - csprng_seed_reg <= csprng_seed_new; + discard_reg <= discard_new; - if (entropy0_enable_we) + if (test_mode_we) begin - entropy0_enable_reg <= entropy0_enable_new; + test_mode_reg <= test_mode_new; end - if (entropy1_enable_we) + if (debug_mux_we) begin - entropy1_enable_reg <= entropy1_enable_new; + debug_mux_reg <= debug_mux_new; end + end + end // reg_update - if (entropy2_enable_we) - begin - entropy2_enable_reg <= entropy2_enable_new; - end - if (entropy2_op_a_we) - begin - entropy2_op_a_reg <= entropy2_op_a_new; - end + //---------------------------------------------------------------- + // debug_mux + //---------------------------------------------------------------- + always @* + begin : debug_mux + entropy1_debug_update = 0; + entropy2_debug_update = 0; - if (entropy2_op_b_we) - begin - entropy2_op_b_reg <= entropy2_op_b_new; - end + tmp_debug = 8'h00; - if (enable_we) - begin - enable_reg <= enable_new; - end + case(debug_mux_reg) + DEBUG_ENTROPY1: + begin + entropy1_debug_update = debug_update; + tmp_debug = entropy1_debug; + end - if (csprng_num_rounds_we) - begin - csprng_num_rounds_reg <= csprng_num_rounds_new; - end + DEBUG_ENTROPY2: + begin + entropy2_debug_update = debug_update; + tmp_debug = entropy2_debug; + end - if (csprng_num_blocks_low_we) - begin - csprng_num_blocks_low_reg <= csprng_num_blocks_low_new; - end + default: + begin + + end + endcase // case (debug_mux_reg) + + end // debug_mux - if (csprng_num_blocks_high_we) - begin - csprng_num_blocks_high_reg <= csprng_num_blocks_high_new; - end - end - end // reg_update + + //---------------------------------------------------------------- + // api_mux + // + // This is a simple decoder that looks at the top 4 bits of + // the given api address and selects which of the sub modules + // or the top level mux that gets to handle any API + // operations. + //---------------------------------------------------------------- + always @* + begin : api_mux + trng_api_cs = 0; + trng_api_we = 0; + + entropy1_api_cs = 0; + entropy1_api_we = 0; + + entropy2_api_cs = 0; + entropy2_api_we = 0; + + mixer_api_cs = 0; + mixer_api_we = 0; + + csprng_api_cs = 0; + csprng_api_we = 0; + + api_address = address[7 : 0]; + tmp_read_data = 32'h00000000; + tmp_error = 0; + + case (address[11 : 8]) + TRNG_PREFIX: + begin + trng_api_cs = cs; + trng_api_we = we; + tmp_read_data = trng_api_read_data; + tmp_error = trng_api_error; + end + + ENTROPY1_PREFIX: + begin + entropy1_api_cs = cs; + entropy1_api_we = we; + tmp_read_data = entropy1_api_read_data; + tmp_error = entropy1_api_error; + end + + ENTROPY2_PREFIX: + begin + entropy2_api_cs = cs; + entropy2_api_we = we; + tmp_read_data = entropy2_api_read_data; + tmp_error = entropy2_api_error; + end + + MIXER_PREFIX: + begin + mixer_api_cs = cs; + mixer_api_we = we; + tmp_read_data = mixer_api_read_data; + tmp_error = mixer_api_error; + end + + CSPRNG_PREFIX: + begin + csprng_api_cs = cs; + csprng_api_we = we; + tmp_read_data = csprng_api_read_data; + tmp_error = csprng_api_error; + end + + default: + begin + + end + endcase // case (address[11 : 8]) + end // api_mux //---------------------------------------------------------------- - // api_logic + // trng_api_logic // - // Implementation of the api logic. If cs is enabled will either - // try to write to or read from the internal registers. + // Implementation of the top level api logic. //---------------------------------------------------------------- always @* - begin : api_logic - entropy0_enable_new = 0; - entropy0_enable_we = 0; - entropy1_enable_new = 0; - entropy1_enable_we = 0; - entropy2_enable_new = 0; - entropy2_enable_we = 0; - entropy2_op_a_new = 32'h00000000; - entropy2_op_a_we = 0; - entropy2_op_b_new = 32'h00000000; - entropy2_op_b_we = 0; - enable_new = 0; - enable_we = 0; - csprng_seed_new = 0; - csprng_rnd_ack_new = 0; - csprng_seed_new = 0; - csprng_num_rounds_new = 5'h00; - csprng_num_rounds_we = 0; - csprng_num_blocks_low_new = 32'h00000000; - csprng_num_blocks_low_we = 0; - csprng_num_blocks_high_new = 32'h00000000; - csprng_num_blocks_high_we = 0; - tmp_read_data = 32'h00000000; - tmp_error = 0; - - if (cs) + begin : trng_api_logic + discard_new = 0; + test_mode_new = 0; + test_mode_we = 0; + debug_mux_new = 3'h0; + debug_mux_we = 0; + trng_api_read_data = 32'h00000000; + trng_api_error = 0; + + if (trng_api_cs) begin - if (we) + if (trng_api_we) begin // Write operations. - case (address) + case (api_address) // Write operations. ADDR_TRNG_CTRL: begin - enable_new = write_data[TRNG_CTRL_ENABLE_BIT]; - enable_we = 1; - entropy0_enable_new = write_data[TRNG_CTRL_ENT0_ENABLE_BIT]; - entropy0_enable_we = 1; - entropy1_enable_new = write_data[TRNG_CTRL_ENT1_ENABLE_BIT]; - entropy1_enable_we = 1; - entropy2_enable_new = write_data[TRNG_CTRL_ENT2_ENABLE_BIT]; - entropy2_enable_we = 1; - csprng_seed_new = write_data[TRNG_CTRL_SEED_BIT]; + discard_new = write_data[TRNG_CTRL_DISCARD_BIT]; + test_mode_new = write_data[TRNG_CTRL_TEST_MODE_BIT]; + test_mode_we = 1; end - ADDR_CSPRNG_NUM_ROUNDS: + ADDR_DEBUG_CTRL: begin - csprng_num_rounds_new = write_data[4 : 0]; - csprng_num_rounds_we = 1; - end - - ADDR_CSPRNG_NUM_BLOCKS_LOW: - begin - csprng_num_blocks_low_new = write_data; - csprng_num_blocks_low_we = 1; - end - - ADDR_CSPRNG_NUM_BLOCKS_HIGH: - begin - csprng_num_blocks_high_new = write_data; - csprng_num_blocks_high_we = 1; - end - - ADDR_ENTROPY2_OP_A: - begin - entropy2_op_a_new = write_data; - entropy2_op_a_we = 1; - end - - ADDR_ENTROPY2_OP_B: - begin - entropy2_op_b_new = write_data; - entropy2_op_b_we = 1; + debug_mux_new = write_data[2 : 0]; + debug_mux_we = 1; end default: begin - tmp_error = 1; + trng_api_error = 1; end endcase // case (address) end // if (we) @@ -506,30 +476,25 @@ module trng( else begin // Read operations. - case (address) + case (api_address) // Read operations. ADDR_NAME0: begin - tmp_read_data = TRNG_NAME0; + trng_api_read_data = TRNG_NAME0; end ADDR_NAME1: begin - tmp_read_data = TRNG_NAME1; + trng_api_read_data = TRNG_NAME1; end ADDR_VERSION: begin - tmp_read_data = TRNG_VERSION; + trng_api_read_data = TRNG_VERSION; end ADDR_TRNG_CTRL: begin - tmp_read_data[TRNG_CTRL_ENABLE_BIT] = enable_reg; - tmp_read_data[TRNG_CTRL_ENT0_ENABLE_BIT] = entropy0_enable_reg; - tmp_read_data[TRNG_CTRL_ENT1_ENABLE_BIT] = entropy1_enable_reg; - tmp_read_data[TRNG_CTRL_ENT2_ENABLE_BIT] = entropy2_enable_reg; - tmp_read_data[TRNG_CTRL_SEED_BIT] = csprng_seed_reg; end ADDR_TRNG_STATUS: @@ -537,70 +502,19 @@ module trng( end - ADDR_TRNG_RND_DATA: - begin - csprng_rnd_ack_new = 1; - tmp_read_data = csprng_rnd_data; - end - - ADDR_TRNG_RND_DATA_VALID: - begin - tmp_read_data[TRNG_RND_VALID_BIT] = csprng_rnd_syn; - end - - ADDR_CSPRNG_NUM_ROUNDS: - begin - tmp_read_data[4 : 0] = csprng_num_rounds_reg; - end - - ADDR_CSPRNG_NUM_BLOCKS_LOW: - begin - tmp_read_data = csprng_num_blocks_low_reg; - end - - ADDR_CSPRNG_NUM_BLOCKS_HIGH: - begin - tmp_read_data = csprng_num_blocks_high_reg; - end - - ADDR_ENTROPY0_RAW: - begin - tmp_read_data = entropy0_raw; - end - - ADDR_ENTROPY0_STATS: - begin - tmp_read_data = entropy0_stats; - end - - ADDR_ENTROPY1_RAW: - begin - tmp_read_data = entropy1_raw; - end - - ADDR_ENTROPY1_STATS: - begin - tmp_read_data = entropy1_stats; - end - - ADDR_ENTROPY2_RAW: - begin - tmp_read_data = entropy2_raw; - end - - ADDR_ENTROPY2_STATS: + ADDR_DEBUG_CTRL: begin - tmp_read_data = entropy2_stats; + trng_api_read_data = debug_mux_new; end default: begin - tmp_error = 1; + trng_api_error = 1; end endcase // case (address) end end - end // addr_decoder + end // trng_api_logic endmodule // trng //====================================================================== diff --git a/src/rtl/trng_csprng.v b/src/rtl/trng_csprng.v index f9869db..a6dd247 100644 --- a/src/rtl/trng_csprng.v +++ b/src/rtl/trng_csprng.v @@ -41,25 +41,24 @@ module trng_csprng( input wire clk, input wire reset_n, - // Control, config and status. - input wire enable, - input debug_mode, - input wire [4 : 0] num_rounds, - input wire [63 : 0] num_blocks, - input wire seed, - output wire more_seed, - output wire ready, + input wire cs, + input wire we, + input wire [7 : 0] address, + input wire [31 : 0] write_data, + output wire [31 : 0] read_data, output wire error, - // Seed input + input wire discard, + input test_mode, + output wire more_seed, + output wire security_error, + input [511 : 0] seed_data, input wire seed_syn, output wire seed_ack, - // Random data output - output wire rnd_syn, - output wire [31 : 0] rnd_data, - input wire rnd_ack + output wire [7 : 0] debug, + input wire debug_update ); @@ -80,6 +79,22 @@ module trng_csprng( parameter CTRL_MORE = 4'h8; parameter CTRL_CANCEL = 4'hf; + parameter DEFAULT_NUM_ROUNDS = 5'h18; + parameter DEFAULT_NUM_BLOCKS = 64'h1000000000000000; + + parameter ADDR_CTRL = 8'h10; + parameter CTRL_ENABLE_BIT = 0; + parameter CTRL_SEED_BIT = 1; + + parameter ADDR_STATUS = 8'h11; + parameter STATUS_RND_VALID_BIT = 0; + + parameter ADDR_RND_DATA = 8'h20; + + parameter ADDR_NUM_ROUNDS = 8'h40; + parameter ADDR_NUM_BLOCK_LOW = 8'h41; + parameter ADDR_NUM_BLOCK_HIGH = 8'h42; + //---------------------------------------------------------------- // Registers including update variables and write enable. @@ -107,14 +122,6 @@ module trng_csprng( reg block_ctr_we; reg block_ctr_max; - reg error_reg; - reg error_new; - reg error_we; - - reg [3 : 0] csprng_ctrl_reg; - reg [3 : 0] csprng_ctrl_new; - reg csprng_ctrl_we; - reg ready_reg; reg ready_new; reg ready_we; @@ -125,10 +132,36 @@ module trng_csprng( reg seed_ack_reg; reg seed_ack_new; + reg enable_reg; + reg enable_new; + reg enable_we; + + reg seed_reg; + reg seed_new; + + reg [4 : 0] num_rounds_reg; + reg [4 : 0] num_rounds_new; + reg num_rounds_we; + + reg [31 : 0] num_blocks_low_reg; + reg [31 : 0] num_blocks_low_new; + reg num_blocks_low_we; + + reg [31 : 0] num_blocks_high_reg; + reg [31 : 0] num_blocks_high_new; + reg num_blocks_high_we; + + reg [3 : 0] csprng_ctrl_reg; + reg [3 : 0] csprng_ctrl_new; + reg csprng_ctrl_we; + //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- + reg [31 : 0] tmp_read_data; + reg tmp_error; + reg cipher_init; reg cipher_next; @@ -138,22 +171,25 @@ module trng_csprng( wire fifo_more_data; reg fifo_discard; - wire fifo_rnd_syn; - wire [31 : 0] fifo_rnd_data; + wire rnd_syn; + wire [31 : 0] rnd_data; + reg rnd_ack; reg fifo_cipher_data_valid; + wire [63 : 0] num_blocks; + //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- - assign seed_ack = seed_ack_reg; - assign more_seed = more_seed_reg; - - assign ready = ready_reg; - assign error = error_reg; + assign read_data = tmp_read_data; + assign error = tmp_error; + assign seed_ack = seed_ack_reg; + assign more_seed = more_seed_reg; + assign debug = 8'haa; + assign security_error = 0; - assign rnd_syn = fifo_rnd_syn; - assign rnd_data = fifo_rnd_data; + assign num_blocks = {num_blocks_high_reg, num_blocks_low_reg}; //---------------------------------------------------------------- @@ -170,7 +206,7 @@ module trng_csprng( .keylen(CIPHER_KEYLEN256), .iv(cipher_iv_reg), .ctr(cipher_ctr_reg), - .rounds(num_rounds), + .rounds(num_rounds_reg), .data_in(cipher_block_reg), .ready(cipher_ready), @@ -189,8 +225,8 @@ module trng_csprng( .discard(fifo_discard), .more_data(fifo_more_data), - .rnd_syn(fifo_rnd_syn), - .rnd_data(fifo_rnd_data), + .rnd_syn(rnd_syn), + .rnd_data(rnd_data), .rnd_ack(rnd_ack) ); @@ -206,21 +242,31 @@ module trng_csprng( begin if (!reset_n) begin - cipher_key_reg <= {8{32'h00000000}}; - cipher_iv_reg <= {2{32'h00000000}}; - cipher_ctr_reg <= {2{32'h00000000}}; - cipher_block_reg <= {16{32'h00000000}}; - block_ctr_reg <= {2{32'h00000000}}; - more_seed_reg <= 0; - seed_ack_reg <= 0; - ready_reg <= 0; - error_reg <= 0; - csprng_ctrl_reg <= CTRL_IDLE; + cipher_key_reg <= {8{32'h00000000}}; + cipher_iv_reg <= {2{32'h00000000}}; + cipher_ctr_reg <= {2{32'h00000000}}; + cipher_block_reg <= {16{32'h00000000}}; + block_ctr_reg <= {2{32'h00000000}}; + more_seed_reg <= 0; + seed_ack_reg <= 0; + ready_reg <= 0; + enable_reg <= 0; + seed_reg <= 0; + num_rounds_reg <= DEFAULT_NUM_ROUNDS; + num_blocks_low_reg <= DEFAULT_NUM_BLOCKS[31 : 0]; + num_blocks_high_reg <= DEFAULT_NUM_BLOCKS[63 : 32]; + csprng_ctrl_reg <= CTRL_IDLE; end else begin more_seed_reg <= more_seed_new; seed_ack_reg <= seed_ack_new; + seed_reg <= seed_new; + + if (enable_we) + begin + enable_reg <= enable_new; + end if (cipher_key_we) begin @@ -252,20 +298,137 @@ module trng_csprng( ready_reg <= ready_new; end - if (error_we) + if (csprng_ctrl_we) begin - error_reg <= error_new; + csprng_ctrl_reg <= csprng_ctrl_new; end - if (csprng_ctrl_we) + if (num_rounds_we) begin - csprng_ctrl_reg <= csprng_ctrl_new; + num_rounds_reg <= num_rounds_new; + end + + if (num_blocks_low_we) + begin + num_blocks_low_reg <= num_blocks_low_new; + end + + if (num_blocks_high_we) + begin + num_blocks_high_reg <= num_blocks_high_new; end end end // reg_update //---------------------------------------------------------------- + // csprng_api_logic + //---------------------------------------------------------------- + always @* + begin : csprng_api_logic + enable_new = 0; + enable_we = 0; + seed_new = 0; + + num_rounds_new = 5'h00; + num_rounds_we = 0; + + num_blocks_low_new = 32'h00000000; + num_blocks_low_we = 0; + num_blocks_high_new = 32'h00000000; + num_blocks_high_we = 0; + + rnd_ack = 0; + + tmp_read_data = 32'h00000000; + tmp_error = 0; + + if (cs) + begin + if (we) + begin + // Write operations. + case (address) + // Write operations. + ADDR_CTRL: + begin + enable_new = write_data[CTRL_ENABLE_BIT]; + enable_we = 1; + seed_new = write_data[CTRL_SEED_BIT]; + end + + ADDR_NUM_ROUNDS: + begin + num_rounds_new = write_data[4 : 0]; + num_rounds_we = 1; + end + + ADDR_NUM_BLOCK_LOW: + begin + num_blocks_low_new = write_data; + num_blocks_low_we = 1; + end + + ADDR_NUM_BLOCK_HIGH: + begin + num_blocks_high_new = write_data; + num_blocks_high_we = 1; + end + + default: + begin + tmp_error = 1; + end + endcase // case (address) + end // if (we) + + else + begin + // Read operations. + case (address) + // Read operations. + ADDR_CTRL: + begin + tmp_read_data = {30'h00000000, seed_reg, enable_reg}; + end + + ADDR_STATUS: + begin + tmp_read_data = {ready_reg, rnd_syn}; + end + + ADDR_RND_DATA: + begin + tmp_read_data = rnd_data; + rnd_ack = 1; + end + + ADDR_NUM_ROUNDS: + begin + tmp_read_data = {27'h0000000, num_rounds_reg}; + end + + ADDR_NUM_BLOCK_LOW: + begin + tmp_read_data = num_blocks_low_reg; + end + + ADDR_NUM_BLOCK_HIGH: + begin + tmp_read_data = num_blocks_high_reg; + end + + default: + begin + tmp_error = 1; + end + endcase // case (address) + end + end + end // cspng_api_logic + + + //---------------------------------------------------------------- // block_ctr // // Logic to implement the block counter. This includes the @@ -319,8 +482,6 @@ module trng_csprng( block_ctr_inc = 0; ready_new = 0; ready_we = 0; - error_new = 0; - error_we = 0; seed_ack_new = 0; more_seed_new = 0; fifo_discard = 0; @@ -331,7 +492,7 @@ module trng_csprng( case (csprng_ctrl_reg) CTRL_IDLE: begin - if (!enable) + if (!enable_reg) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -346,7 +507,7 @@ module trng_csprng( CTRL_SEED0: begin - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -363,7 +524,7 @@ module trng_csprng( CTRL_NSYN: begin - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -378,7 +539,7 @@ module trng_csprng( CTRL_SEED1: begin - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -403,7 +564,7 @@ module trng_csprng( CTRL_INIT0: begin - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -419,7 +580,7 @@ module trng_csprng( CTRL_INIT1: begin - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -433,7 +594,7 @@ module trng_csprng( CTRL_NEXT0: begin - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -447,7 +608,7 @@ module trng_csprng( end CTRL_NEXT1: - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; @@ -462,7 +623,7 @@ module trng_csprng( CTRL_MORE: begin - if ((!enable) || (seed)) + if ((!enable_reg) || (seed_reg)) begin csprng_ctrl_new = CTRL_CANCEL; csprng_ctrl_we = 1; diff --git a/src/rtl/trng_mixer.v b/src/rtl/trng_mixer.v index 37ea6d2..7d398f5 100644 --- a/src/rtl/trng_mixer.v +++ b/src/rtl/trng_mixer.v @@ -37,10 +37,19 @@ //====================================================================== module trng_mixer( - input wire clk, - input wire reset_n, + input wire clk, + input wire reset_n, + + input wire cs, + input wire we, + input wire [7 : 0] address, + input wire [31 : 0] write_data, + output wire [31 : 0] read_data, + output wire error, + + input wire discard, + input wire test_mode, - input wire enable, input wire more_seed, input wire entropy0_enabled, @@ -84,6 +93,12 @@ module trng_mixer( parameter ENTROPY_SRC2 = 4'h5; parameter ENTROPY_SRC2_ACK = 4'h6; + parameter ADDR_MIXER_CTRL = 8'h10; + parameter MIXER_CTRL_ENABLE_BIT = 0; + parameter MIXER_CTRL_RESTART_BIT = 1; + + parameter ADDR_MIXER_STATUS = 8'h11; + //---------------------------------------------------------------- // Registers including update variables and write enable. @@ -175,6 +190,13 @@ module trng_mixer( reg init_done_new; reg init_done_we; + reg enable_reg; + reg enable_new; + reg enable_we; + + reg restart_reg; + reg restart_new; + //---------------------------------------------------------------- // Wires. @@ -196,10 +218,16 @@ module trng_mixer( reg tmp_entropy1_ack; reg tmp_entropy2_ack; + reg [31 : 0] tmp_read_data; + reg tmp_error; + //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- + assign read_data = tmp_read_data; + assign error = tmp_error; + assign seed_syn = seed_syn_reg; assign seed_data = hash_digest; @@ -242,8 +270,8 @@ module trng_mixer( // reg_update // // Update functionality for all registers in the core. - // All registers are positive edge triggered with synchronous - // active low reset. All registers have write enable. + // All registers are positive edge triggered with asynchronous + // active low reset. //---------------------------------------------------------------- always @ (posedge clk or negedge reset_n) begin @@ -284,11 +312,15 @@ module trng_mixer( init_done_reg <= 0; word_ctr_reg <= 5'h00; seed_syn_reg <= 0; + enable_reg <= 0; + restart_reg <= 0; entropy_collect_ctrl_reg <= CTRL_IDLE; mixer_ctrl_reg <= CTRL_IDLE; end else begin + restart_reg <= restart_new; + if (block00_we) begin block00_reg <= muxed_entropy; @@ -469,6 +501,11 @@ module trng_mixer( entropy_collect_ctrl_reg <= entropy_collect_ctrl_new; end + if (enable_we) + begin + enable_reg <= enable_new; + end + if (mixer_ctrl_we) begin mixer_ctrl_reg <= mixer_ctrl_new; @@ -476,6 +513,65 @@ module trng_mixer( end end // reg_update + + //---------------------------------------------------------------- + // mixer_api_logic + //---------------------------------------------------------------- + always @* + begin : mixer_api_logic + enable_new = 0; + enable_we = 0; + restart_reg = 0; + restart_new = 0; + tmp_read_data = 32'h00000000; + tmp_error = 0; + + if (cs) + begin + if (we) + begin + // Write operations. + case (address) + // Write operations. + ADDR_MIXER_CTRL: + begin + enable_new = write_data[MIXER_CTRL_ENABLE_BIT]; + enable_we = 1; + restart_new = write_data[MIXER_CTRL_RESTART_BIT]; + end + + default: + begin + tmp_error = 1; + end + endcase // case (address) + end // if (we) + + else + begin + // Read operations. + case (address) + // Read operations. + ADDR_MIXER_CTRL: + begin + tmp_read_data = {30'h00000000, restart_reg, enable_reg}; + end + + ADDR_MIXER_STATUS: + begin + + end + + default: + begin + tmp_error = 1; + end + endcase // case (address) + end + end + end // mixer_api_logic + + //---------------------------------------------------------------- // entropy_collect_ctrl // @@ -509,7 +605,7 @@ module trng_mixer( ENTROPY_SRC0: begin - if (!enable) + if (!enable_reg) begin word_ctr_rst = 1; entropy_collect_ctrl_new = ENTROPY_IDLE; @@ -538,7 +634,7 @@ module trng_mixer( ENTROPY_SRC0_ACK: begin tmp_entropy0_ack = 1; - if (!enable) + if (!enable_reg) begin word_ctr_rst = 1; entropy_collect_ctrl_new = ENTROPY_IDLE; @@ -564,7 +660,7 @@ module trng_mixer( ENTROPY_SRC1: begin - if (!enable) + if (!enable_reg) begin word_ctr_rst = 1; entropy_collect_ctrl_new = ENTROPY_IDLE; @@ -593,7 +689,7 @@ module trng_mixer( ENTROPY_SRC1_ACK: begin tmp_entropy1_ack = 1; - if (!enable) + if (!enable_reg) begin word_ctr_rst = 1; entropy_collect_ctrl_new = ENTROPY_IDLE; @@ -618,7 +714,7 @@ module trng_mixer( ENTROPY_SRC2: begin - if (!enable) + if (!enable_reg) begin word_ctr_rst = 1; entropy_collect_ctrl_new = ENTROPY_IDLE; @@ -647,7 +743,7 @@ module trng_mixer( ENTROPY_SRC2_ACK: begin tmp_entropy2_ack = 1; - if (!enable) + if (!enable_reg) begin word_ctr_rst = 1; entropy_collect_ctrl_new = ENTROPY_IDLE; @@ -806,7 +902,7 @@ module trng_mixer( CTRL_COLLECT: begin - if ((!enable)) + if ((!discard)) begin mixer_ctrl_new = CTRL_IDLE; mixer_ctrl_we = 1; @@ -823,7 +919,7 @@ module trng_mixer( CTRL_MIX: begin - if ((!enable)) + if ((!discard)) begin mixer_ctrl_new = CTRL_IDLE; mixer_ctrl_we = 1; @@ -845,7 +941,7 @@ module trng_mixer( CTRL_SYN: begin - if ((!enable)) + if ((!discard)) begin mixer_ctrl_new = CTRL_IDLE; mixer_ctrl_we = 1; @@ -862,7 +958,7 @@ module trng_mixer( CTRL_ACK: begin - if ((!enable)) + if ((!discard)) begin mixer_ctrl_new = CTRL_IDLE; mixer_ctrl_we = 1; @@ -878,7 +974,7 @@ module trng_mixer( CTRL_NEXT: begin - if ((!enable)) + if ((!discard)) begin mixer_ctrl_new = CTRL_IDLE; mixer_ctrl_we = 1; |