aboutsummaryrefslogblamecommitdiff
path: root/src/tb/tb_keywrap_mkmif.v
blob: b275499effa1fab8741e29c9d339381eb302a1c7 (plain) (tree)






































                                                                           



                                                                
















                                                                    
                   
                         
                         
                         
 



                                 
                               









                               
 

                         







                                                                    














                                                   



                                                                    


                                                                    





                                     


                                                                    



















                                                                    



                                         
                                         


                                                                                               
                     
           







                                                                                       

                         







                                                                                                                 

           

                   
                                           


                                                                                       

                     




                                                                    



















                                                                           










                                                                    
                         
                         

                         
 

                           





                             






                                                                    





                                                                    
                                   

                 


                        
 
                                     
                 




                                                                    





                                                                    

                        



                                      
                 





                                                                    
                                                                    
                     


                          

                                                                         
                 
 
                   



                     
                   
 
                                    

                   
                          

 






                                                                    
                                          
                                                           

                                                                              
                   

                         

                                                                

                           



                           
                   

                   









                                                                           
                                        



                              

                                                                    


































                                                                              
































                                                                                               



                                                                    

                                                                           


                   
                  
                 
                      
                          

                           
                 

                   
                                                                    


               
                             

                                                                        
                         
                                                                        
//======================================================================
//
// 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
//======================================================================