aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rtl/trng_mixer.v704
-rw-r--r--src/tb/tb_mixer.v223
2 files changed, 927 insertions, 0 deletions
diff --git a/src/rtl/trng_mixer.v b/src/rtl/trng_mixer.v
new file mode 100644
index 0000000..02588a1
--- /dev/null
+++ b/src/rtl/trng_mixer.v
@@ -0,0 +1,704 @@
+//======================================================================
+//
+// trng_mixer.v
+// ------------
+// Mixer for the TRNG.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2014, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module trng_mixer(
+ // Clock and reset.
+ input wire clk,
+ input wire reset_n,
+
+ // Controls.
+ input wire enable,
+ input wire more_seed,
+
+ input wire entropy0_enabled,
+ input wire entropy0_syn,
+ output wire entropy0_ack,
+
+ input wire entropy1_enabled,
+ input wire entropy1_syn,
+ output wire entropy1_ack,
+
+ input wire entropy2_enabled,
+ input wire entropy2_syn,
+ output wire entropy2_ack,
+
+ output wire [511 : 0] seed_data,
+ output wire seed_syn,
+ input wire seed_ack
+ );
+
+
+ //----------------------------------------------------------------
+ // Internal constant and parameter definitions.
+ //----------------------------------------------------------------
+ parameter MODE_SHA_512 = 2'h3;
+
+ 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;
+ parameter CTRL_CANCEL = 4'hf;
+
+
+ //----------------------------------------------------------------
+ // Registers including update variables and write enable.
+ //----------------------------------------------------------------
+ reg [31 : 0] block00_reg;
+ reg [31 : 0] block00_we;
+ reg [31 : 0] block01_reg;
+ reg [31 : 0] block01_we;
+ reg [31 : 0] block02_reg;
+ reg [31 : 0] block02_we;
+ reg [31 : 0] block03_reg;
+ reg [31 : 0] block03_we;
+ reg [31 : 0] block04_reg;
+ reg [31 : 0] block04_we;
+ reg [31 : 0] block05_reg;
+ reg [31 : 0] block05_we;
+ reg [31 : 0] block06_reg;
+ reg [31 : 0] block06_we;
+ reg [31 : 0] block07_reg;
+ reg [31 : 0] block07_we;
+ reg [31 : 0] block08_reg;
+ reg [31 : 0] block08_we;
+ reg [31 : 0] block09_reg;
+ reg [31 : 0] block09_we;
+ reg [31 : 0] block10_reg;
+ reg [31 : 0] block10_we;
+ reg [31 : 0] block11_reg;
+ reg [31 : 0] block11_we;
+ reg [31 : 0] block12_reg;
+ reg [31 : 0] block12_we;
+ reg [31 : 0] block13_reg;
+ reg [31 : 0] block13_we;
+ reg [31 : 0] block14_reg;
+ reg [31 : 0] block14_we;
+ reg [31 : 0] block15_reg;
+ reg [31 : 0] block15_we;
+ reg [31 : 0] block16_reg;
+ reg [31 : 0] block16_we;
+ reg [31 : 0] block17_reg;
+ reg [31 : 0] block17_we;
+ reg [31 : 0] block18_reg;
+ reg [31 : 0] block18_we;
+ reg [31 : 0] block19_reg;
+ reg [31 : 0] block19_we;
+ reg [31 : 0] block20_reg;
+ reg [31 : 0] block20_we;
+ reg [31 : 0] block21_reg;
+ reg [31 : 0] block21_we;
+ reg [31 : 0] block22_reg;
+ reg [31 : 0] block22_we;
+ reg [31 : 0] block23_reg;
+ reg [31 : 0] block23_we;
+ reg [31 : 0] block24_reg;
+ reg [31 : 0] block24_we;
+ reg [31 : 0] block25_reg;
+ reg [31 : 0] block25_we;
+ reg [31 : 0] block26_reg;
+ reg [31 : 0] block26_we;
+ reg [31 : 0] block27_reg;
+ reg [31 : 0] block27_we;
+ reg [31 : 0] block28_reg;
+ reg [31 : 0] block28_we;
+ reg [31 : 0] block29_reg;
+ reg [31 : 0] block29_we;
+ reg [31 : 0] block30_reg;
+ reg [31 : 0] block30_we;
+ reg [31 : 0] block31_reg;
+ reg [31 : 0] block31_we;
+
+ reg [4 : 0] word_ctr_reg;
+ reg [4 : 0] word_ctr_new;
+ reg word_ctr_inc;
+ reg word_ctr_rst;
+ reg word_ctr_we;
+
+ reg [3 : 0] mixer_ctrl_reg;
+ reg [3 : 0] mixer_ctrl_new;
+ reg mixer_ctrl_we;
+
+ reg seed_syn_reg;
+ reg seed_syn_new;
+ reg seed_syn_we;
+
+ reg init_done_reg;
+ reg init_done_new;
+ reg init_done_we;
+
+
+ //----------------------------------------------------------------
+ // Wires.
+ //----------------------------------------------------------------
+ reg [31 : 0] muxed_entropy;
+ reg muxed_entropy_syn;
+ reg update_block;
+ reg mux_entropy;
+
+ reg hash_init;
+ reg hash_next;
+
+ wire [1023 : 0] hash_block;
+ wire hash_ready;
+ wire [511 : 0] hash_digest;
+ wire hash_digest_valid;
+
+
+ //----------------------------------------------------------------
+ // Concurrent connectivity for ports etc.
+ //----------------------------------------------------------------
+ assign seed_data = hash_digest;
+
+ assign hash_block = {block00_reg, block01_reg, block02_reg, block03_reg,
+ block04_reg, block05_reg, block06_reg, block07_reg,
+ block08_reg, block09_reg,
+ block10_reg, block11_reg, block12_reg, block13_reg,
+ block14_reg, block15_reg, block16_reg, block17_reg,
+ block18_reg, block19_reg,
+ block20_reg, block21_reg, block22_reg, block23_reg,
+ block24_reg, block25_reg, block26_reg, block27_reg,
+ block28_reg, block29_reg,
+ block30_reg, block31_reg};
+
+
+ //----------------------------------------------------------------
+ // core instantiation.
+ //----------------------------------------------------------------
+ sha512_core hash(
+ .clk(clk),
+ .reset_n(reset_n),
+
+ .init(hash_init),
+ .next(hash_next),
+ .mode(MODE_SHA_512),
+
+ .block(hash_block),
+
+ .ready(hash_ready),
+ .digest(hash_digest),
+ .digest_valid(hash_digest_valid)
+ );
+
+
+ //----------------------------------------------------------------
+ // 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.
+ //----------------------------------------------------------------
+ always @ (posedge clk or negedge reset_n)
+ 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;
+ end
+ else
+ begin
+ if (block00_we)
+ begin
+ block00_reg <= muxed_entropy;
+ end
+
+ if (block01_we)
+ begin
+ block01_reg <= muxed_entropy;
+ end
+
+ if (block02_we)
+ begin
+ block02_reg <= muxed_entropy;
+ end
+
+ if (block03_we)
+ begin
+ block03_reg <= muxed_entropy;
+ end
+
+ if (block04_we)
+ begin
+ block04_reg <= muxed_entropy;
+ end
+
+ if (block05_we)
+ begin
+ block05_reg <= muxed_entropy;
+ end
+
+ if (block06_we)
+ begin
+ block06_reg <= muxed_entropy;
+ end
+
+ if (block07_we)
+ begin
+ block07_reg <= muxed_entropy;
+ end
+
+ if (block08_we)
+ begin
+ block08_reg <= muxed_entropy;
+ end
+
+ if (block09_we)
+ begin
+ block09_reg <= muxed_entropy;
+ end
+
+ if (block10_we)
+ begin
+ block10_reg <= muxed_entropy;
+ end
+
+ if (block11_we)
+ begin
+ block11_reg <= muxed_entropy;
+ end
+
+ if (block12_we)
+ begin
+ block12_reg <= muxed_entropy;
+ end
+
+ if (block13_we)
+ begin
+ block13_reg <= muxed_entropy;
+ end
+
+ if (block14_we)
+ begin
+ block14_reg <= muxed_entropy;
+ end
+
+ if (block15_we)
+ begin
+ block15_reg <= muxed_entropy;
+ end
+
+ if (block16_we)
+ begin
+ block16_reg <= muxed_entropy;
+ end
+
+ if (block17_we)
+ begin
+ block17_reg <= muxed_entropy;
+ end
+
+ if (block18_we)
+ begin
+ block18_reg <= muxed_entropy;
+ end
+
+ if (block19_we)
+ begin
+ block19_reg <= muxed_entropy;
+ end
+
+ if (block20_we)
+ begin
+ block20_reg <= muxed_entropy;
+ end
+
+ if (block21_we)
+ begin
+ block21_reg <= muxed_entropy;
+ end
+
+ if (block22_we)
+ begin
+ block22_reg <= muxed_entropy;
+ end
+
+ if (block23_we)
+ begin
+ block23_reg <= muxed_entropy;
+ end
+
+ if (block24_we)
+ begin
+ block24_reg <= muxed_entropy;
+ end
+
+ if (block25_we)
+ begin
+ block25_reg <= muxed_entropy;
+ end
+
+ if (block26_we)
+ begin
+ block26_reg <= muxed_entropy;
+ end
+
+ if (block27_we)
+ begin
+ block27_reg <= muxed_entropy;
+ end
+
+ if (block28_we)
+ begin
+ block28_reg <= muxed_entropy;
+ end
+
+ if (block29_we)
+ begin
+ block29_reg <= muxed_entropy;
+ end
+
+ if (block30_we)
+ begin
+ block30_reg <= muxed_entropy;
+ end
+
+ if (block31_we)
+ begin
+ block31_reg <= muxed_entropy;
+ end
+
+ if (mixer_ctrl_we)
+ begin
+ mixer_ctrl_reg <= mixer_ctrl_new;
+ end
+
+ if (seed_syn_we)
+ begin
+ seed_syn_reg <= seed_syn_we;
+ end
+
+ if (init_done_we)
+ begin
+ init_done_reg <= init_done_we;
+ end
+ end
+ end // reg_update
+
+ //----------------------------------------------------------------
+ // entropy_mux
+ //
+ // This is a round-robin mux that muxes the signals from
+ // the entropy sources that are enabled.
+ //----------------------------------------------------------------
+ always @*
+ begin : entropy_mux
+ end // entropy_mux
+
+
+ //----------------------------------------------------------------
+ // word_mux
+ //----------------------------------------------------------------
+ always @*
+ begin : word_mux
+ block00_we = 0;
+ block01_we = 0;
+ block02_we = 0;
+ block03_we = 0;
+ block04_we = 0;
+ block05_we = 0;
+ block06_we = 0;
+ block07_we = 0;
+ block08_we = 0;
+ block09_we = 0;
+ block10_we = 0;
+ block11_we = 0;
+ block12_we = 0;
+ block13_we = 0;
+ block14_we = 0;
+ block15_we = 0;
+ block16_we = 0;
+ block17_we = 0;
+ block18_we = 0;
+ block19_we = 0;
+ block20_we = 0;
+ block21_we = 0;
+ block22_we = 0;
+ block23_we = 0;
+ block24_we = 0;
+ block25_we = 0;
+ block26_we = 0;
+ block27_we = 0;
+ block28_we = 0;
+ block29_we = 0;
+ block30_we = 0;
+ block31_we = 0;
+
+ if (update_block)
+ begin
+ case (word_ctr_reg)
+ 00 : block00_we = 1;
+ 01 : block01_we = 1;
+ 02 : block02_we = 1;
+ 03 : block03_we = 1;
+ 04 : block04_we = 1;
+ 05 : block05_we = 1;
+ 06 : block06_we = 1;
+ 07 : block07_we = 1;
+ 08 : block08_we = 1;
+ 09 : block09_we = 1;
+ 10 : block10_we = 1;
+ 11 : block11_we = 1;
+ 12 : block12_we = 1;
+ 13 : block13_we = 1;
+ 14 : block14_we = 1;
+ 15 : block15_we = 1;
+ 16 : block16_we = 1;
+ 17 : block17_we = 1;
+ 18 : block18_we = 1;
+ 19 : block19_we = 1;
+ 20 : block20_we = 1;
+ 21 : block21_we = 1;
+ 22 : block22_we = 1;
+ 23 : block23_we = 1;
+ 24 : block24_we = 1;
+ 25 : block25_we = 1;
+ 26 : block26_we = 1;
+ 27 : block27_we = 1;
+ 28 : block28_we = 1;
+ 29 : block29_we = 1;
+ 30 : block30_we = 1;
+ 31 : block31_we = 1;
+ endcase // case (word_ctr_reg)
+ end
+ end // word_mux
+
+
+ //----------------------------------------------------------------
+ // word_ctr
+ //----------------------------------------------------------------
+ always @*
+ begin : word_ctr
+ word_ctr_new = 5'h00;
+ word_ctr_we = 0;
+
+ if (word_ctr_rst)
+ begin
+ word_ctr_new = 5'h00;
+ word_ctr_we = 1;
+ end
+
+ if (word_ctr_inc)
+ begin
+ word_ctr_new = word_ctr_reg + 1'b1;
+ word_ctr_we = 1;
+ end
+ end // word_ctr
+
+
+ //----------------------------------------------------------------
+ // mixer_ctrl_fsm
+ //
+ // Control FSM for the 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;
+ 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)
+ begin
+ word_ctr_rst = 1;
+ init_done_new = 0;
+ init_done_we = 1;
+ mixer_ctrl_new = CTRL_COLLECT;
+ mixer_ctrl_we = 1;
+ end
+ end
+
+ CTRL_COLLECT:
+ begin
+ if ((!enable))
+ begin
+ mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_we = 1;
+ end
+ else
+ begin
+ mux_entropy = 1;
+ if (word_ctr_reg == 5'h1f)
+ 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
+
+ CTRL_MIX:
+ begin
+ if ((!enable))
+ begin
+ mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_we = 1;
+ end
+ else
+ begin
+ if (init_done_reg)
+ begin
+ hash_next = 1;
+ end
+ else
+ begin
+ hash_init = 1;
+ end
+ mixer_ctrl_new = CTRL_SYN;
+ mixer_ctrl_we = 1;
+ end
+ end
+
+ CTRL_SYN:
+ begin
+ if ((!enable))
+ begin
+ mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_we = 1;
+ end
+ else if (hash_ready)
+ begin
+ seed_syn_new = 1;
+ seed_syn_we = 1;
+ mixer_ctrl_new = CTRL_ACK;
+ mixer_ctrl_we = 1;
+ end
+
+ end
+
+ CTRL_ACK:
+ begin
+ if ((!enable))
+ begin
+ mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_we = 1;
+ end
+ else if (seed_ack)
+ begin
+ seed_syn_new = 0;
+ seed_syn_we = 1;
+ mixer_ctrl_new = CTRL_NEXT;
+ mixer_ctrl_we = 1;
+ end
+ end
+
+ CTRL_NEXT:
+ begin
+ if ((!enable))
+ begin
+ mixer_ctrl_new = CTRL_CANCEL;
+ mixer_ctrl_we = 1;
+ end
+ else if (more_seed)
+ begin
+ word_ctr_rst = 1;
+ init_done_new = 1;
+ init_done_we = 1;
+ mixer_ctrl_new = CTRL_COLLECT;
+ mixer_ctrl_we = 1;
+ end
+ end
+
+ CTRL_CANCEL:
+ begin
+ mixer_ctrl_new = CTRL_IDLE;
+ mixer_ctrl_we = 1;
+ end
+
+ endcase // case (cspng_ctrl_reg)
+ end // mixer_ctrl_fsm
+
+endmodule // trng_mixer
+
+//======================================================================
+// EOF trng_mixer.v
+//======================================================================
diff --git a/src/tb/tb_mixer.v b/src/tb/tb_mixer.v
new file mode 100644
index 0000000..c135b61
--- /dev/null
+++ b/src/tb/tb_mixer.v
@@ -0,0 +1,223 @@
+//======================================================================
+//
+// tb_mixer.v
+// -----------
+// Testbench for the mixer module in the trng.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2014, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+//------------------------------------------------------------------
+// Simulator directives.
+//------------------------------------------------------------------
+`timescale 1ns/100ps
+
+
+//------------------------------------------------------------------
+// Test module.
+//------------------------------------------------------------------
+module tb_mixer();
+
+ //----------------------------------------------------------------
+ // Internal constant and parameter definitions.
+ //----------------------------------------------------------------
+ parameter DEBUG = 1;
+
+ parameter CLK_HALF_PERIOD = 1;
+ parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
+
+
+ //----------------------------------------------------------------
+ // Register and Wire declarations.
+ //----------------------------------------------------------------
+ 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;
+
+
+ //----------------------------------------------------------------
+ // Device Under Test.
+ //----------------------------------------------------------------
+ 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()
+ );
+
+
+ //----------------------------------------------------------------
+ // clk_gen
+ //
+ // Always running clock generator process.
+ //----------------------------------------------------------------
+ always
+ begin : clk_gen
+ #CLK_HALF_PERIOD;
+ tb_clk = !tb_clk;
+ end // clk_gen
+
+
+ //----------------------------------------------------------------
+ // sys_monitor()
+ //
+ // An always running process that creates a cycle counter and
+ // conditionally displays information about the DUT.
+ //----------------------------------------------------------------
+ always
+ begin : sys_monitor
+ cycle_ctr = cycle_ctr + 1;
+
+ #(CLK_PERIOD);
+
+ if (DEBUG)
+ begin
+ dump_dut_state();
+ end
+ end
+
+
+ //----------------------------------------------------------------
+ // dump_dut_state()
+ //
+ // Dump the state of the dump when needed.
+ //----------------------------------------------------------------
+ task dump_dut_state();
+ begin
+ $display("cycle: 0x%016x", cycle_ctr);
+ $display("State of DUT");
+ $display("------------");
+ $display("");
+ end
+ endtask // dump_dut_state
+
+
+ //----------------------------------------------------------------
+ // reset_dut()
+ //
+ // Toggle reset to put the DUT into a well known state.
+ //----------------------------------------------------------------
+ task reset_dut();
+ begin
+ $display("*** Toggle reset.");
+ tb_reset_n = 0;
+
+ #(2 * CLK_PERIOD);
+ tb_reset_n = 1;
+ $display("");
+ end
+ endtask // reset_dut
+
+
+ //----------------------------------------------------------------
+ // display_test_results()
+ //
+ // Display the accumulated test results.
+ //----------------------------------------------------------------
+ task display_test_results();
+ begin
+ if (error_ctr == 0)
+ begin
+ $display("*** All %02d test cases completed successfully", tc_ctr);
+ end
+ else
+ begin
+ $display("*** %02d tests completed - %02d test cases did not complete successfully.",
+ tc_ctr, error_ctr);
+ end
+ end
+ endtask // display_test_results
+
+
+ //----------------------------------------------------------------
+ // init_sim()
+ //
+ // Initialize all counters and testbed functionality as well
+ // as setting the DUT inputs to defined values.
+ //----------------------------------------------------------------
+ task init_sim();
+ begin
+ cycle_ctr = 0;
+ error_ctr = 0;
+ tc_ctr = 0;
+
+ tb_clk = 0;
+ tb_reset_n = 1;
+ tb_enable = 0;
+ end
+ endtask // init_sim
+
+
+ //----------------------------------------------------------------
+ // mixer_test
+ //
+ // The main test functionality.
+ //----------------------------------------------------------------
+ initial
+ begin : mixer_test
+
+ $display(" -= Testbench for mixer started =-");
+ $display(" ================================");
+ $display("");
+
+ init_sim();
+ dump_dut_state();
+ reset_dut();
+ dump_dut_state();
+
+ display_test_results();
+
+ $display("");
+ $display("*** Mixer simulation done. ***");
+ $finish;
+ end // mixer_test
+endmodule // tb_mixer
+
+//======================================================================
+// EOF tb_mixer.v
+//======================================================================