aboutsummaryrefslogtreecommitdiff
path: root/src/tb/tb_keywrap_mkmif.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/tb/tb_keywrap_mkmif.v')
-rw-r--r--src/tb/tb_keywrap_mkmif.v434
1 files changed, 434 insertions, 0 deletions
diff --git a/src/tb/tb_keywrap_mkmif.v b/src/tb/tb_keywrap_mkmif.v
new file mode 100644
index 0000000..b275499
--- /dev/null
+++ b/src/tb/tb_keywrap_mkmif.v
@@ -0,0 +1,434 @@
+//======================================================================
+//
+// tb_keywrap_mkm.v
+// ----------------
+// Testbench for the mkmif wrapper in keywrap.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2018, 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.
+//
+//======================================================================
+
+// We need this since the specific memory module sets timescale.
+`timescale 1ns/10ps
+
+module tb_keywrap_mkmif();
+
+ //----------------------------------------------------------------
+ // Parameters.
+ //----------------------------------------------------------------
+ parameter DEBUG = 1;
+
+ parameter CLK_HALF_PERIOD = 1;
+ parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
+
+
+ //----------------------------------------------------------------
+ // Variables, regs and wires.
+ //----------------------------------------------------------------
+ integer cycle_ctr;
+ integer error_ctr;
+ integer tc_ctr;
+
+ integer show_spi;
+ integer show_dut_state;
+ integer show_mem_state;
+ integer show_mkm_state;
+
+ reg tb_clk;
+ reg tb_reset_n;
+ wire tb_mkm_spi_sclk;
+ wire tb_mkm_spi_cs_n;
+ wire tb_mkm_spi_do;
+ wire tb_mkm_spi_di;
+ reg tb_init;
+ reg tb_read;
+ reg tb_write;
+ reg tb_key_status;
+ wire tb_ready;
+ reg [31 : 0] tb_wr_status;
+ wire [31 : 0] tb_rd_status;
+ reg [255 : 0] tb_wr_key;
+ wire [255 : 0] tb_rd_key;
+
+ wire mem_hold_n = 1'b1;
+
+
+ //----------------------------------------------------------------
+ // Device Under Test.
+ //----------------------------------------------------------------
+ keywrap_mkmif dut(
+ .clk(tb_clk),
+ .reset_n(tb_reset_n),
+
+ .mkm_spi_sclk(tb_mkm_spi_sclk),
+ .mkm_spi_cs_n(tb_mkm_spi_cs_n),
+ .mkm_spi_do(tb_mkm_spi_do),
+ .mkm_spi_di(tb_mkm_spi_di),
+
+ .init(tb_init),
+ .read(tb_read),
+ .write(tb_write),
+ .key_status(tb_key_status),
+ .ready(tb_ready),
+
+ .wr_status(tb_wr_status),
+ .rd_status(tb_rd_status),
+ .wr_key(tb_wr_key),
+ .rd_key(tb_rd_key)
+ );
+
+
+ //----------------------------------------------------------------
+ // Memory model. See README.md in src/tech for info on how
+ // to get the vendor specific model needed here.
+ //----------------------------------------------------------------
+ M23K640 mem(.SI(tb_mkm_spi_di),
+ .SO(tb_mkm_spi_do),
+ .SCK(tb_mkm_spi_sclk),
+ .CS_N(tb_mkm_spi_cs_n),
+ .HOLD_N(mem_hold_n),
+ .RESET(tb_reset_n));
+
+
+ //----------------------------------------------------------------
+ // 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;
+ $display("cycle: %08d", cycle_ctr);
+
+ if (show_dut_state)
+ begin
+ $display("DUT control state:");
+ $display("init: 0x%01x read: 0x%01x write: 0x%01x key_status: 0x%01x",
+ dut.init, dut.read, dut.write, dut.key_status);
+ $display("ready: 0x%01x ctrl_state: 0x%02x", dut.ready, dut.keywrap_mkmif_ctrl_reg);
+ $display();
+ end
+
+ if (show_mkm_state)
+ begin
+ $display("MKM control state:");
+ $display("ready: 0x%1x ctrl: 0x%1x", dut.mkm_ready, dut.mkm.mkmif_ctrl_reg);
+ $display();
+ end
+
+ if (show_mem_state)
+ begin
+ $display("Memory control state:");
+ $display("Hold: 0x%1x BitCounter: 0x%04x", mem.Hold, mem.BitCounter);
+ $display("DataShifterI: 0x%02x DataShifterO: 0x%1x", mem.DataShifterI, mem.DataShifterO);
+ $display("InstRegister: 0x%1x AddrRegister: 0x%02x", mem.InstRegister, mem.AddrRegister);
+ $display("OpMode0: 0x%1x OpMode1: 0x%1x", mem.OpMode0, mem.OpMode1);
+ $display("InstructionREAD: 0x%1x InstructionRDSR: 0x%1x", mem.InstructionREAD, mem.InstructionRDSR);
+ $display("InstructionWRSR: 0x%1x InstructionWRITE: 0x%1x", mem.InstructionWRSR, mem.InstructionWRITE);
+ $display();
+ end
+
+ if (show_spi)
+ begin
+ $display("SPI interface state:");
+ $display("spi_clk: 0x%01x, spi_cs_n: 0x%01x, spi_do: 0x%01x, spi_di: 0x%01x",
+ tb_mkm_spi_sclk, tb_mkm_spi_cs_n, tb_mkm_spi_do, tb_mkm_spi_di);
+ end
+
+ $display("\n");
+ #(CLK_PERIOD);
+ end
+
+
+ //----------------------------------------------------------------
+ // dump_mem
+ //
+ // Dump the contents of the memory model.
+ //----------------------------------------------------------------
+ task dump_mem;
+ begin : dump_mem
+ integer i;
+
+ $display("Contents of the first 256 bytes in the serial memory:");
+ for (i = 0 ; i < 256 ; i = i + 8)
+ $display("0x%01x 0x%01x 0x%01x 0x%01x 0x%01x 0x%01x 0x%01x 0x%01x",
+ mem.MemoryBlock[i], mem.MemoryBlock[i + 1],
+ mem.MemoryBlock[i + 2], mem.MemoryBlock[i + 3],
+ mem.MemoryBlock[i + 4], mem.MemoryBlock[i + 5],
+ mem.MemoryBlock[i + 6], mem.MemoryBlock[i + 7]);
+ end
+ endtask // dump_mem
+
+
+ //----------------------------------------------------------------
+ // 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;
+
+ show_spi = 0;
+ show_dut_state = 0;
+ show_mem_state = 0;
+ show_mkm_state = 0;
+
+ tb_clk = 1'h0;
+ tb_reset_n = 1'h1;
+ tb_init = 1'h0;
+ tb_read = 1'h0;
+ tb_write = 1'h0;
+ tb_key_status = 1'h0;
+ tb_wr_status = 32'h0;
+ tb_wr_key = 256'h0;
+
+ #(CLK_PERIOD);
+ end
+ endtask // init_sim
+
+
+ //----------------------------------------------------------------
+ // reset_dut()
+ //
+ // Toggle reset to put the DUT into a well known state.
+ //----------------------------------------------------------------
+ task reset_dut;
+ begin
+ $display("Asserting reset.");
+ $display();
+
+ tb_reset_n = 0;
+ #(2 * CLK_PERIOD);
+ tb_reset_n = 1;
+
+ $display("Deasserting reset.");
+ $display();
+ end
+ endtask // reset_dut
+
+
+ //----------------------------------------------------------------
+ // wait_ready()
+ //
+ // Wait for ready to be asserted.
+ //----------------------------------------------------------------
+ task wait_ready;
+ begin
+ #(2 * CLK_PERIOD);
+
+ while (!tb_ready)
+ #(CLK_PERIOD);
+
+ $display("Ready has been set.");
+ $display();
+ end
+ endtask // wait_ready
+
+
+ //----------------------------------------------------------------
+ // test_init_mem
+ //----------------------------------------------------------------
+ task test_init_mem;
+ begin
+ tc_ctr = tc_ctr + 1;
+
+ $display("TEST INIT-MEM START");
+ $display("Check that the memory is configured when pulling init.");
+ $display();
+
+ show_spi = 0;
+ tb_init = 1'h1;
+ #(CLK_PERIOD);
+ tb_init = 1'h0;
+ wait_ready();
+ show_spi = 0;
+
+ $display("TEST INIT-MEM END");
+ $display("");
+ end
+ endtask // test_init_mem
+
+
+ //----------------------------------------------------------------
+ // test_write_status
+ //----------------------------------------------------------------
+ task test_write_status;
+ begin
+ tc_ctr = tc_ctr + 1;
+
+ $display("TEST WRITE-STATUS START");
+ $display("Check that we can write the status word.");
+
+ // Observe SPI for a number of cycles. Reset the DUT during observation.
+ show_spi = 0;
+ #(10 * CLK_PERIOD);
+
+ $display("Trying to write 0xdeadbeef to status address.");
+ tb_wr_status = 32'hdeadbeef;
+ tb_key_status = 1'h0;
+ tb_write = 1'h1;
+
+ #(CLK_PERIOD);
+ tb_write = 1'h0;
+
+ wait_ready();
+ show_spi = 0;
+
+ // Check content in memory.
+ if ((mem.MemoryBlock[0] == 8'hde) && (mem.MemoryBlock[1] == 8'had) &&
+ (mem.MemoryBlock[2] == 8'hbe) && (mem.MemoryBlock[3] == 8'hef))
+ $display("Correct status word was written into the memory.");
+ else
+ begin
+ $display("Correct status word was NOT written into the memory.");
+ error_ctr = error_ctr + 1;
+ end
+
+ $display("TEST WRITE-STATUS END");
+ $display("");
+ end
+ endtask // test_write_status
+
+
+ //----------------------------------------------------------------
+ // test_read_status
+ // Note: This test should be called after test_write_status.
+ // If not the contents of the memort will be undefined.
+ //----------------------------------------------------------------
+ task test_read_status;
+ begin
+ tc_ctr = tc_ctr + 1;
+
+ $display("TEST READ-STATUS START");
+ $display("Check that we can read the status word.");
+
+ // Observe SPI for a number of cycles. Reset the DUT during observation.
+ show_spi = 0;
+ show_dut_state = 1;
+ #(10 * CLK_PERIOD);
+
+ $display("Trying to read 0xdeadbeef from the status address.");
+ tb_key_status = 1'h0;
+ tb_read = 1'h1;
+
+ #(CLK_PERIOD);
+ tb_read = 1'h0;
+
+ wait_ready();
+ show_spi = 0;
+
+ $display("The word read: 0x%04x", tb_rd_status);
+
+ $display("TEST READ-STATUS END");
+ $display("");
+ end
+ endtask // test_read_status
+
+
+ //----------------------------------------------------------------
+ // test_write_key
+ //----------------------------------------------------------------
+ task test_write_key;
+ begin
+ tc_ctr = tc_ctr + 1;
+
+ $display("TEST WRITE-KEY START");
+ $display("Check that we can write the key words.");
+
+ // Observe SPI for a number of cycles. Reset the DUT during observation.
+ show_spi = 0;
+ #(10 * CLK_PERIOD);
+
+ $display("Trying to write test key to key address.");
+ $display("test key: 0x01020304 0xaa55aa55 0x00ff00ff 0x0f0e0d0c");
+ $display(" 0x11121314 0x55aa55aa 0x11ee11ee 0x1f1e1d1c");
+
+ tb_wr_key = 256'h01020304_aa55aa55_00ff00ff_0f0e0d0c_11121314_55aa55aa_11ee11ee_1f1e1d1c;
+ tb_key_status = 1'h1;
+ tb_write = 1'h1;
+
+ #(CLK_PERIOD);
+ tb_write = 1'h0;
+
+ wait_ready();
+ show_spi = 0;
+
+ $display("TEST WRITE-KEY END");
+ $display("");
+ end
+ endtask // test_write_key
+
+ //----------------------------------------------------------------
+ // main
+ //----------------------------------------------------------------
+ initial
+ begin : main
+ $display(" -= Testbench for Keywrap mkmif integration started =-");
+ $display(" ====================================================");
+ $display("");
+
+ init_sim();
+ reset_dut();
+ dump_mem();
+ test_init_mem();
+ test_write_status();
+// test_read_status();
+// test_write_key();
+ dump_mem();
+
+ $display("");
+ $display("*** Keywrap mkmif integration testbench done. ***");
+ $finish;
+ end // main
+
+endmodule // tb_keywrap_mkmif
+
+//======================================================================
+// EOF tb_keywrap_mkmif.v
+//======================================================================