aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rtl/trng_mixer.v379
-rw-r--r--src/tb/tb_mixer.v127
2 files changed, 389 insertions, 117 deletions
diff --git a/src/rtl/trng_mixer.v b/src/rtl/trng_mixer.v
index 02588a1..37ea6d2 100644
--- a/src/rtl/trng_mixer.v
+++ b/src/rtl/trng_mixer.v
@@ -37,25 +37,26 @@
//======================================================================
module trng_mixer(
- // Clock and reset.
input wire clk,
input wire reset_n,
- // Controls.
- input wire enable,
- input wire more_seed,
+ input wire enable,
+ input wire more_seed,
- input wire entropy0_enabled,
- input wire entropy0_syn,
- output wire entropy0_ack,
+ input wire entropy0_enabled,
+ input wire entropy0_syn,
+ input wire [31 : 0] entropy0_data,
+ output wire entropy0_ack,
- input wire entropy1_enabled,
- input wire entropy1_syn,
- output wire entropy1_ack,
+ input wire entropy1_enabled,
+ input wire entropy1_syn,
+ input wire [31 : 0] entropy1_data,
+ output wire entropy1_ack,
- input wire entropy2_enabled,
- input wire entropy2_syn,
- output wire entropy2_ack,
+ input wire entropy2_enabled,
+ input wire entropy2_syn,
+ input wire [31 : 0] entropy2_data,
+ output wire entropy2_ack,
output wire [511 : 0] seed_data,
output wire seed_syn,
@@ -74,7 +75,14 @@ module trng_mixer(
parameter CTRL_SYN = 4'h3;
parameter CTRL_ACK = 4'h4;
parameter CTRL_NEXT = 4'h5;
- parameter CTRL_CANCEL = 4'hf;
+
+ 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;
//----------------------------------------------------------------
@@ -151,6 +159,10 @@ module trng_mixer(
reg word_ctr_rst;
reg word_ctr_we;
+ reg [3 : 0] entropy_collect_ctrl_reg;
+ reg [3 : 0] entropy_collect_ctrl_new;
+ reg entropy_collect_ctrl_we;
+
reg [3 : 0] mixer_ctrl_reg;
reg [3 : 0] mixer_ctrl_new;
reg mixer_ctrl_we;
@@ -168,9 +180,9 @@ module trng_mixer(
// Wires.
//----------------------------------------------------------------
reg [31 : 0] muxed_entropy;
- reg muxed_entropy_syn;
+ reg collect_block;
reg update_block;
- reg mux_entropy;
+ reg block_done;
reg hash_init;
reg hash_next;
@@ -180,10 +192,15 @@ module trng_mixer(
wire [511 : 0] hash_digest;
wire hash_digest_valid;
+ reg tmp_entropy0_ack;
+ reg tmp_entropy1_ack;
+ reg tmp_entropy2_ack;
+
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
+ assign seed_syn = seed_syn_reg;
assign seed_data = hash_digest;
assign hash_block = {block00_reg, block01_reg, block02_reg, block03_reg,
@@ -197,6 +214,10 @@ module trng_mixer(
block28_reg, block29_reg,
block30_reg, block31_reg};
+ assign entropy0_ack = tmp_entropy0_ack;
+ assign entropy1_ack = tmp_entropy1_ack;
+ assign entropy2_ack = tmp_entropy2_ack;
+
//----------------------------------------------------------------
// core instantiation.
@@ -228,40 +249,43 @@ module trng_mixer(
begin
if (!reset_n)
begin
- block00_reg <= 32'h00000000;
- block01_reg <= 32'h00000000;
- block02_reg <= 32'h00000000;
- block03_reg <= 32'h00000000;
- block04_reg <= 32'h00000000;
- block05_reg <= 32'h00000000;
- block06_reg <= 32'h00000000;
- block07_reg <= 32'h00000000;
- block08_reg <= 32'h00000000;
- block09_reg <= 32'h00000000;
- block10_reg <= 32'h00000000;
- block11_reg <= 32'h00000000;
- block12_reg <= 32'h00000000;
- block13_reg <= 32'h00000000;
- block14_reg <= 32'h00000000;
- block15_reg <= 32'h00000000;
- block16_reg <= 32'h00000000;
- block17_reg <= 32'h00000000;
- block18_reg <= 32'h00000000;
- block19_reg <= 32'h00000000;
- block20_reg <= 32'h00000000;
- block21_reg <= 32'h00000000;
- block22_reg <= 32'h00000000;
- block23_reg <= 32'h00000000;
- block24_reg <= 32'h00000000;
- block25_reg <= 32'h00000000;
- block26_reg <= 32'h00000000;
- block27_reg <= 32'h00000000;
- block28_reg <= 32'h00000000;
- block29_reg <= 32'h00000000;
- block30_reg <= 32'h00000000;
- block31_reg <= 32'h00000000;
- seed_syn_reg <= 0;
- mixer_ctrl_reg <= CTRL_IDLE;
+ block00_reg <= 32'h00000000;
+ block01_reg <= 32'h00000000;
+ block02_reg <= 32'h00000000;
+ block03_reg <= 32'h00000000;
+ block04_reg <= 32'h00000000;
+ block05_reg <= 32'h00000000;
+ block06_reg <= 32'h00000000;
+ block07_reg <= 32'h00000000;
+ block08_reg <= 32'h00000000;
+ block09_reg <= 32'h00000000;
+ block10_reg <= 32'h00000000;
+ block11_reg <= 32'h00000000;
+ block12_reg <= 32'h00000000;
+ block13_reg <= 32'h00000000;
+ block14_reg <= 32'h00000000;
+ block15_reg <= 32'h00000000;
+ block16_reg <= 32'h00000000;
+ block17_reg <= 32'h00000000;
+ block18_reg <= 32'h00000000;
+ block19_reg <= 32'h00000000;
+ block20_reg <= 32'h00000000;
+ block21_reg <= 32'h00000000;
+ block22_reg <= 32'h00000000;
+ block23_reg <= 32'h00000000;
+ block24_reg <= 32'h00000000;
+ block25_reg <= 32'h00000000;
+ block26_reg <= 32'h00000000;
+ block27_reg <= 32'h00000000;
+ block28_reg <= 32'h00000000;
+ block29_reg <= 32'h00000000;
+ block30_reg <= 32'h00000000;
+ block31_reg <= 32'h00000000;
+ init_done_reg <= 0;
+ word_ctr_reg <= 5'h00;
+ seed_syn_reg <= 0;
+ entropy_collect_ctrl_reg <= CTRL_IDLE;
+ mixer_ctrl_reg <= CTRL_IDLE;
end
else
begin
@@ -425,31 +449,228 @@ module trng_mixer(
block31_reg <= muxed_entropy;
end
- if (mixer_ctrl_we)
+ if (init_done_we)
begin
- mixer_ctrl_reg <= mixer_ctrl_new;
+ init_done_reg <= init_done_new;
+ end
+
+ if (word_ctr_we)
+ begin
+ word_ctr_reg <= word_ctr_new;
end
if (seed_syn_we)
begin
- seed_syn_reg <= seed_syn_we;
+ seed_syn_reg <= seed_syn_new;
end
- if (init_done_we)
+ if (entropy_collect_ctrl_we)
+ begin
+ entropy_collect_ctrl_reg <= entropy_collect_ctrl_new;
+ end
+
+ if (mixer_ctrl_we)
begin
- init_done_reg <= init_done_we;
+ mixer_ctrl_reg <= mixer_ctrl_new;
end
end
end // reg_update
//----------------------------------------------------------------
- // entropy_mux
+ // entropy_collect_ctrl
//
- // This is a round-robin mux that muxes the signals from
- // the entropy sources that are enabled.
+ // This FSM implements a round-robin mux for signals from the
+ // entropy sources and updates the block until a block has
+ // been filled.
//----------------------------------------------------------------
always @*
begin : entropy_mux
+ tmp_entropy0_ack = 0;
+ tmp_entropy1_ack = 0;
+ tmp_entropy2_ack = 0;
+ word_ctr_inc = 0;
+ word_ctr_rst = 0;
+ update_block = 0;
+ block_done = 0;
+ muxed_entropy = 32'h00000000;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 0;
+
+ case (entropy_collect_ctrl_reg)
+ ENTROPY_IDLE:
+ begin
+ if (collect_block)
+ begin
+ word_ctr_rst = 1;
+ entropy_collect_ctrl_new = ENTROPY_SRC0;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+
+ ENTROPY_SRC0:
+ begin
+ if (!enable)
+ begin
+ word_ctr_rst = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ if (entropy0_enabled)
+ begin
+ if (entropy0_syn)
+ begin
+ muxed_entropy = entropy0_data;
+ update_block = 1;
+ entropy_collect_ctrl_new = ENTROPY_SRC0_ACK;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ else
+ begin
+ entropy_collect_ctrl_new = ENTROPY_SRC1;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ end
+
+ ENTROPY_SRC0_ACK:
+ begin
+ tmp_entropy0_ack = 1;
+ if (!enable)
+ begin
+ word_ctr_rst = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ if (word_ctr_reg == 5'h1f)
+ begin
+ block_done = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ word_ctr_inc = 1;
+ entropy_collect_ctrl_new = ENTROPY_SRC1;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ end
+
+
+ ENTROPY_SRC1:
+ begin
+ if (!enable)
+ begin
+ word_ctr_rst = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ if (entropy1_enabled)
+ begin
+ if (entropy1_syn)
+ begin
+ muxed_entropy = entropy1_data;
+ update_block = 1;
+ entropy_collect_ctrl_new = ENTROPY_SRC1_ACK;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ else
+ begin
+ entropy_collect_ctrl_new = ENTROPY_SRC2;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ end
+
+ ENTROPY_SRC1_ACK:
+ begin
+ tmp_entropy1_ack = 1;
+ if (!enable)
+ begin
+ word_ctr_rst = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ if (word_ctr_reg == 5'h1f)
+ begin
+ block_done = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ word_ctr_inc = 1;
+ entropy_collect_ctrl_new = ENTROPY_SRC2;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ end
+
+ ENTROPY_SRC2:
+ begin
+ if (!enable)
+ begin
+ word_ctr_rst = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ if (entropy2_enabled)
+ begin
+ if (entropy2_syn)
+ begin
+ muxed_entropy = entropy2_data;
+ update_block = 1;
+ entropy_collect_ctrl_new = ENTROPY_SRC2_ACK;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ else
+ begin
+ entropy_collect_ctrl_new = ENTROPY_SRC0;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ end
+
+ ENTROPY_SRC2_ACK:
+ begin
+ tmp_entropy2_ack = 1;
+ if (!enable)
+ begin
+ word_ctr_rst = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ if (word_ctr_reg == 5'h1f)
+ begin
+ block_done = 1;
+ entropy_collect_ctrl_new = ENTROPY_IDLE;
+ entropy_collect_ctrl_we = 1;
+ end
+ else
+ begin
+ word_ctr_inc = 1;
+ entropy_collect_ctrl_new = ENTROPY_SRC0;
+ entropy_collect_ctrl_we = 1;
+ end
+ end
+ end
+
+ endcase // case (entropy_collect_ctrl_reg)
end // entropy_mux
@@ -560,30 +781,22 @@ module trng_mixer(
//----------------------------------------------------------------
always @*
begin : mixer_ctrl_fsm
- word_ctr_inc = 0;
- word_ctr_rst = 0;
seed_syn_new = 0;
seed_syn_we = 0;
init_done_new = 0;
init_done_we = 0;
hash_init = 0;
hash_next = 0;
- mux_entropy = 0;
- update_block = 0;
+ collect_block = 0;
mixer_ctrl_new = CTRL_IDLE;
mixer_ctrl_we = 0;
case (mixer_ctrl_reg)
CTRL_IDLE:
begin
- if (!enable)
- begin
- mixer_ctrl_new = CTRL_CANCEL;
- mixer_ctrl_we = 1;
- end
- else if (more_seed)
+ if (more_seed)
begin
- word_ctr_rst = 1;
+ collect_block = 1;
init_done_new = 0;
init_done_we = 1;
mixer_ctrl_new = CTRL_COLLECT;
@@ -595,24 +808,16 @@ module trng_mixer(
begin
if ((!enable))
begin
- mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_new = CTRL_IDLE;
mixer_ctrl_we = 1;
end
else
begin
- mux_entropy = 1;
- if (word_ctr_reg == 5'h1f)
+ if (block_done)
begin
mixer_ctrl_new = CTRL_MIX;
mixer_ctrl_we = 1;
end
- else
- begin
- if (muxed_entropy_syn)
- begin
- word_ctr_inc = 1;
- end
- end
end
end
@@ -620,7 +825,7 @@ module trng_mixer(
begin
if ((!enable))
begin
- mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_new = CTRL_IDLE;
mixer_ctrl_we = 1;
end
else
@@ -642,7 +847,7 @@ module trng_mixer(
begin
if ((!enable))
begin
- mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_new = CTRL_IDLE;
mixer_ctrl_we = 1;
end
else if (hash_ready)
@@ -659,7 +864,7 @@ module trng_mixer(
begin
if ((!enable))
begin
- mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_new = CTRL_IDLE;
mixer_ctrl_we = 1;
end
else if (seed_ack)
@@ -675,12 +880,12 @@ module trng_mixer(
begin
if ((!enable))
begin
- mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_new = CTRL_IDLE;
mixer_ctrl_we = 1;
end
else if (more_seed)
begin
- word_ctr_rst = 1;
+ collect_block = 1;
init_done_new = 1;
init_done_we = 1;
mixer_ctrl_new = CTRL_COLLECT;
@@ -688,12 +893,6 @@ module trng_mixer(
end
end
- CTRL_CANCEL:
- begin
- mixer_ctrl_new = CTRL_IDLE;
- mixer_ctrl_we = 1;
- end
-
endcase // case (cspng_ctrl_reg)
end // mixer_ctrl_fsm
diff --git a/src/tb/tb_mixer.v b/src/tb/tb_mixer.v
index c135b61..b08533a 100644
--- a/src/tb/tb_mixer.v
+++ b/src/tb/tb_mixer.v
@@ -59,14 +59,34 @@ module tb_mixer();
//----------------------------------------------------------------
// Register and Wire declarations.
//----------------------------------------------------------------
- reg [31 : 0] cycle_ctr;
- reg [31 : 0] error_ctr;
- reg [31 : 0] tc_ctr;
+ reg [31 : 0] cycle_ctr;
+ reg [31 : 0] error_ctr;
+ reg [31 : 0] tc_ctr;
+
+ reg tb_clk;
+ reg tb_reset_n;
+ reg tb_enable;
+ reg tb_more_seed;
+
+ reg tb_entropy0_enabled;
+ reg tb_entropy0_syn;
+ reg [31 : 0] tb_entropy0_data;
+ wire tb_entropy0_ack;
+
+ reg tb_entropy1_enabled;
+ reg tb_entropy1_syn;
+ reg [31 : 0] tb_entropy1_data;
+ wire tb_entropy1_ack;
+
+ reg tb_entropy2_enabled;
+ reg tb_entropy2_syn;
+ reg [31 : 0] tb_entropy2_data;
+ wire tb_entropy2_ack;
+
+ wire [511 : 0] tb_seed_data;
+ wire tb_syn;
+ reg tb_ack;
- reg tb_clk;
- reg tb_reset_n;
- reg tb_enable;
-
//----------------------------------------------------------------
// Device Under Test.
@@ -74,20 +94,28 @@ module tb_mixer();
trng_mixer dut(
.clk(tb_clk),
.reset_n(tb_reset_n),
- .enable(),
- .more_seed(),
- .entropy0_enabled(),
- .entropy0_syn(),
- .entropy0_ack(),
- .entropy1_enabled(),
- .entropy1_syn(),
- .entropy1_ack(),
- .entropy2_enabled(),
- .entropy2_syn(),
- .entropy2_ack(),
- .seed_data(),
- .seed_syn(),
- .seed_ack()
+
+ .enable(tb_enable),
+ .more_seed(tb_more_seed),
+
+ .entropy0_enabled(tb_entropy0_enabled),
+ .entropy0_syn(tb_entropy0_syn),
+ .entropy0_data(tb_entropy0_data),
+ .entropy0_ack(tb_entropy0_ack),
+
+ .entropy1_enabled(tb_entropy1_enabled),
+ .entropy1_syn(tb_entropy1_syn),
+ .entropy1_data(tb_entropy1_data),
+ .entropy1_ack(tb_entropy1_ack),
+
+ .entropy2_enabled(tb_entropy2_enabled),
+ .entropy2_syn(tb_entropy2_syn),
+ .entropy2_data(tb_entropy2_data),
+ .entropy2_ack(tb_entropy2_ack),
+
+ .seed_data(tb_seed_data),
+ .seed_syn(tb_syn),
+ .seed_ack(tb_ack)
);
@@ -182,18 +210,61 @@ module tb_mixer();
//----------------------------------------------------------------
task init_sim();
begin
- cycle_ctr = 0;
- error_ctr = 0;
- tc_ctr = 0;
+ cycle_ctr = 0;
+ error_ctr = 0;
+ tc_ctr = 0;
+
+ tb_clk = 0;
+ tb_reset_n = 1;
+
+ tb_enable = 0;
+ tb_more_seed = 0;
+
+ tb_entropy0_enabled = 0;
+ tb_entropy0_syn = 0;
+ tb_entropy0_data = 32'h00000000;
- tb_clk = 0;
- tb_reset_n = 1;
- tb_enable = 0;
+ tb_entropy1_enabled = 0;
+ tb_entropy1_syn = 0;
+ tb_entropy1_data = 32'h00000000;
+
+ tb_entropy2_enabled = 0;
+ tb_entropy2_syn = 0;
+ tb_entropy2_data = 32'h00000000;
+
+ tb_ack = 0;
end
endtask // init_sim
//----------------------------------------------------------------
+ // tc1_gen_seeds()
+ //
+ // A simple first testcase that tries to make the DUT generate
+ // a number of seeds based on entropy from source 0 and 2.
+ //----------------------------------------------------------------
+ task tc1_gen_seeds();
+ begin
+ $display("*** Starting TC1: Setting continious seed generation.");
+ tb_entropy0_enabled = 1;
+ tb_entropy0_syn = 1;
+ tb_entropy0_data = 32'h01010202;
+
+ tb_entropy2_enabled = 1;
+ tb_entropy2_syn = 1;
+ tb_entropy2_data = 32'haa55aa55;
+
+ tb_enable = 1;
+ tb_more_seed = 1;
+ tb_ack = 1;
+
+ #(50000 * CLK_PERIOD);
+ $display("*** TC1 done.");
+ end
+ endtask // tc1_gen_seeds
+
+
+ //----------------------------------------------------------------
// mixer_test
//
// The main test functionality.
@@ -210,6 +281,8 @@ module tb_mixer();
reset_dut();
dump_dut_state();
+ tc1_gen_seeds();
+
display_test_results();
$display("");