aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rtl/trng.v682
-rw-r--r--src/rtl/trng_csprng.v277
-rw-r--r--src/rtl/trng_mixer.v128
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;