diff options
author | Paul Selkirk <paul@psgd.org> | 2020-03-31 09:27:02 -0400 |
---|---|---|
committer | Paul Selkirk <paul@psgd.org> | 2020-03-31 09:27:28 -0400 |
commit | 2aee357d677e720215f5a03cf071ee94980cf05d (patch) | |
tree | 0fbf83ad000d9b98ba556629f894d2a5a2b62d67 /src | |
parent | 4333178c6a8f467ddacc13ddae0bed588b6bdcf3 (diff) | |
parent | 0d2aa16a71c1f0ca183a71c3d5460c6ff1a2f245 (diff) |
Merge branch 'integrate_mkmif' to master
Diffstat (limited to 'src')
-rw-r--r-- | src/rtl/keywrap.v | 146 | ||||
-rw-r--r-- | src/rtl/keywrap_core.v | 139 | ||||
-rw-r--r-- | src/rtl/keywrap_mkmif.v | 449 | ||||
-rw-r--r-- | src/tb/tb_keywrap.v | 24 | ||||
-rw-r--r-- | src/tb/tb_keywrap_core.v | 52 | ||||
-rw-r--r-- | src/tb/tb_keywrap_mkmif.v | 434 | ||||
-rw-r--r-- | src/tech/README.md | 14 |
7 files changed, 1181 insertions, 77 deletions
diff --git a/src/rtl/keywrap.v b/src/rtl/keywrap.v index 2033b23..2e9a7f6 100644 --- a/src/rtl/keywrap.v +++ b/src/rtl/keywrap.v @@ -53,6 +53,11 @@ module keywrap #(parameter ADDR_BITS = 12) input wire clk, input wire reset_n, + output wire mkm_spi_sclk, + output wire mkm_spi_cs_n, + input wire mkm_spi_do, + output wire mkm_spi_di, + input wire cs, input wire we, @@ -65,42 +70,52 @@ module keywrap #(parameter ADDR_BITS = 12) //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - localparam ADDR_NAME0 = 8'h00; - localparam ADDR_NAME1 = 8'h01; - localparam ADDR_VERSION = 8'h02; + localparam ADDR_NAME0 = 8'h00; + localparam ADDR_NAME1 = 8'h01; + localparam ADDR_VERSION = 8'h02; - localparam ADDR_CTRL = 8'h08; - localparam CTRL_INIT_BIT = 0; - localparam CTRL_NEXT_BIT = 1; + localparam ADDR_CTRL = 8'h08; + localparam CTRL_INIT_BIT = 0; + localparam CTRL_NEXT_BIT = 1; + localparam CTRL_READ_BIT = 2; + localparam CTRL_WRITE_BIT = 3; localparam ADDR_STATUS = 8'h09; localparam STATUS_READY_BIT = 0; localparam STATUS_VALID_BIT = 1; - localparam ADDR_CONFIG = 8'h0a; - localparam CTRL_ENCDEC_BIT = 0; - localparam CTRL_KEYLEN_BIT = 1; + localparam ADDR_CONFIG = 8'h0a; + localparam CONFIG_ENCDEC_BIT = 0; + localparam CONFIG_KEYLEN_BIT = 1; + localparam CONFIG_MKS_BIT = 2; + + localparam ADDR_RLEN = 8'h0c; + localparam ADDR_A0 = 8'h0e; + localparam ADDR_A1 = 8'h0f; + + localparam ADDR_KEY0 = 8'h10; + localparam ADDR_KEY1 = 8'h11; + localparam ADDR_KEY2 = 8'h12; + localparam ADDR_KEY3 = 8'h13; + localparam ADDR_KEY4 = 8'h14; + localparam ADDR_KEY5 = 8'h15; + localparam ADDR_KEY6 = 8'h16; + localparam ADDR_KEY7 = 8'h17; - localparam ADDR_RLEN = 8'h0c; - localparam ADDR_A0 = 8'h0e; - localparam ADDR_A1 = 8'h0f; + localparam ADDR_MSTATUS = 8'h20; - localparam ADDR_KEY0 = 8'h10; - localparam ADDR_KEY1 = 8'h11; - localparam ADDR_KEY2 = 8'h12; - localparam ADDR_KEY3 = 8'h13; - localparam ADDR_KEY4 = 8'h14; - localparam ADDR_KEY5 = 8'h15; - localparam ADDR_KEY6 = 8'h16; - localparam ADDR_KEY7 = 8'h17; + localparam CORE_NAME0 = 32'h6b657920; // "key " + localparam CORE_NAME1 = 32'h77726170; // "wrap" + localparam CORE_VERSION = 32'h302e3830; // "0.80" - localparam CORE_NAME0 = 32'h6b657920; // "key " - localparam CORE_NAME1 = 32'h77726170; // "wrap" - localparam CORE_VERSION = 32'h302e3830; // "0.80" + localparam MEM_BITS = ADDR_BITS - 1; + localparam RLEN_BITS = ADDR_BITS - 2; + localparam PAD = ADDR_BITS - 8; - localparam MEM_BITS = ADDR_BITS - 1; - localparam RLEN_BITS = ADDR_BITS - 2; - localparam PAD = ADDR_BITS - 8; + + // If set to one, will allow read access to key memory. + // Should be set to zero in all production FPGA bitstreams. + localparam DEBUG_MKM_READ = 1'h1; //---------------------------------------------------------------- @@ -112,6 +127,15 @@ module keywrap #(parameter ADDR_BITS = 12) reg next_reg; reg next_new; + reg read_reg; + reg read_new; + + reg write_reg; + reg write_new; + + reg mkey_mstatus_reg; + reg mkey_mstatus_new; + reg encdec_reg; reg keylen_reg; reg config_we; @@ -128,6 +152,9 @@ module keywrap #(parameter ADDR_BITS = 12) reg [31 : 0] key_reg [0 : 7]; reg key_we; + reg [31 : 0] mstatus_reg; + reg mstatus_we; + reg [31 : 0] api_rd_delay_reg; reg [31 : 0] api_rd_delay_new; @@ -146,6 +173,8 @@ module keywrap #(parameter ADDR_BITS = 12) wire core_ready; wire core_valid; wire [255 : 0] core_key; + wire [255 : 0] core_mkey; + wire [31 : 0] core_mstatus; wire [63 : 0] core_a_init; wire [63 : 0] core_a_result; wire [31 : 0] core_api_rd_data; @@ -166,15 +195,23 @@ module keywrap #(parameter ADDR_BITS = 12) //---------------------------------------------------------------- - // core instantiation. + // keywrap core instantiation. //---------------------------------------------------------------- keywrap_core #(.MEM_BITS(MEM_BITS)) core( .clk(clk), .reset_n(reset_n), + .mkm_spi_sclk(mkm_spi_sclk), + .mkm_spi_cs_n(mkm_spi_cs_n), + .mkm_spi_do(mkm_spi_do), + .mkm_spi_di(mkm_spi_di), + .init(init_reg), .next(next_reg), + .read(read_reg), + .write(write_reg), + .mkey_mstatus(mkey_mstatus_reg), .encdec(encdec_reg), .ready(core_ready), @@ -184,6 +221,9 @@ module keywrap #(parameter ADDR_BITS = 12) .key(core_key), .keylen(keylen_reg), + .status(mstatus_reg), + .mkey(core_mkey), + .mstatus(core_mstatus), .a_init(core_a_init), .a_result(core_a_result), @@ -209,8 +249,12 @@ module keywrap #(parameter ADDR_BITS = 12) init_reg <= 1'h0; next_reg <= 1'h0; + read_reg <= 1'h0; + write_reg <= 1'h0; + mkey_mstatus_reg <= 1'h0; encdec_reg <= 1'h0; keylen_reg <= 1'h0; + mstatus_reg <= 32'h0; rlen_reg <= {RLEN_BITS{1'h0}}; valid_reg <= 1'h0; ready_reg <= 1'h0; @@ -224,12 +268,16 @@ module keywrap #(parameter ADDR_BITS = 12) valid_reg <= core_valid; init_reg <= init_new; next_reg <= next_new; + read_reg <= read_new; + write_reg <= write_new; + mkey_mstatus_reg <= mkey_mstatus_new; api_rd_delay_reg <= api_rd_delay_new; if (config_we) begin - encdec_reg <= write_data[CTRL_ENCDEC_BIT]; - keylen_reg <= write_data[CTRL_KEYLEN_BIT]; + mkey_mstatus_reg <= write_data[CONFIG_MKS_BIT]; + encdec_reg <= write_data[CONFIG_ENCDEC_BIT]; + keylen_reg <= write_data[CONFIG_KEYLEN_BIT]; end if (rlen_we) @@ -241,6 +289,9 @@ module keywrap #(parameter ADDR_BITS = 12) if (a1_we) a1_reg <= write_data; + if (mstatus_we) + mstatus_reg <= write_data; + if (key_we) key_reg[address[2 : 0]] <= write_data; end @@ -256,21 +307,25 @@ module keywrap #(parameter ADDR_BITS = 12) begin : api init_new = 1'h0; next_new = 1'h0; + read_new = 1'h0; + write_new = 1'h0; config_we = 1'h0; rlen_we = 1'h0; key_we = 1'h0; core_api_we = 1'h0; a0_we = 1'h0; a1_we = 1'h0; + mstatus_we = 1'h0; tmp_read_data = 32'h0; tmp_error = 1'h0; api_rd_delay_new = 32'h0; // api_mux - if (address[(ADDR_BITS - 1)]) - tmp_read_data = core_api_rd_data; - else - tmp_read_data = api_rd_delay_reg; + if (core_ready) + if (address[(ADDR_BITS - 1)]) + tmp_read_data = core_api_rd_data; + else + tmp_read_data = api_rd_delay_reg; if (cs) begin @@ -280,8 +335,10 @@ module keywrap #(parameter ADDR_BITS = 12) begin if (address == {{PAD{1'h0}}, ADDR_CTRL}) begin - init_new = write_data[CTRL_INIT_BIT]; - next_new = write_data[CTRL_NEXT_BIT]; + init_new = write_data[CTRL_INIT_BIT]; + next_new = write_data[CTRL_NEXT_BIT]; + read_new = write_data[CTRL_READ_BIT]; + write_new = write_data[CTRL_WRITE_BIT]; end if (address == {{PAD{1'h0}}, ADDR_CONFIG}) @@ -296,6 +353,9 @@ module keywrap #(parameter ADDR_BITS = 12) if (address == {{PAD{1'h0}}, ADDR_A1}) a1_we = 1'h1; + if (address == {{PAD{1'h0}}, ADDR_MSTATUS}) + mstatus_we = 1'h1; + if ((address >= {{PAD{1'h0}}, ADDR_KEY0}) && (address <= {{PAD{1'h0}}, ADDR_KEY7})) key_we = 1'h1; @@ -317,12 +377,10 @@ module keywrap #(parameter ADDR_BITS = 12) api_rd_delay_new = CORE_VERSION; if (address == {{PAD{1'h0}}, ADDR_CTRL}) - api_rd_delay_new = {28'h0, keylen_reg, encdec_reg, next_reg, init_reg}; + api_rd_delay_new = {26'h0, keylen_reg, encdec_reg, write_reg, read_reg, next_reg, init_reg}; if (address == {{PAD{1'h0}}, ADDR_STATUS}) - begin - api_rd_delay_new = {30'h0, valid_reg, ready_reg}; - end + api_rd_delay_new = {30'h0, valid_reg, ready_reg}; if (address == {{PAD{1'h0}}, ADDR_RLEN}) api_rd_delay_new = {{(32 - RLEN_BITS){1'h0}}, rlen_reg}; @@ -332,6 +390,16 @@ module keywrap #(parameter ADDR_BITS = 12) if (address == {{PAD{1'h0}}, ADDR_A1}) api_rd_delay_new = core_a_result[31 : 0]; + + if (address == {{PAD{1'h0}}, ADDR_MSTATUS}) + api_rd_delay_new = core_mstatus; + + // Warning: Should be disabled after mkmif + // integration has been completed. + if (DEBUG_MKM_READ) + if ((address >= {{PAD{1'h0}},ADDR_KEY0}) && (address <= {{PAD{1'h0}}, ADDR_KEY7})) + api_rd_delay_new = core_mkey[(7 - (address - {{PAD{1'h0}}, ADDR_KEY7})) * 32 +: 32]; + end // else: !if(we) end // if (cs) end // block: api diff --git a/src/rtl/keywrap_core.v b/src/rtl/keywrap_core.v index b3e17f6..3abe93c 100644 --- a/src/rtl/keywrap_core.v +++ b/src/rtl/keywrap_core.v @@ -44,17 +44,28 @@ module keywrap_core #(parameter MEM_BITS = 11) input wire clk, input wire reset_n, + output wire mkm_spi_sclk, + output wire mkm_spi_cs_n, + input wire mkm_spi_do, + output wire mkm_spi_di, + input wire init, input wire next, + input wire read, + input wire write, + input wire mkey_mstatus, + input wire mkey_key, input wire encdec, output wire ready, output wire valid, input wire [(MEM_BITS - 2) : 0] rlen, - input wire [255 : 0] key, input wire keylen, + input wire [31 : 0] status, + output wire [255 : 0] mkey, + output wire [31 : 0] mstatus, input wire [63 : 0] a_init, output wire [63 : 0] a_result, @@ -71,17 +82,19 @@ module keywrap_core #(parameter MEM_BITS = 11) //---------------------------------------------------------------- localparam MAX_ITERATIONS = 6 - 1; - localparam CTRL_IDLE = 4'h0; - localparam CTRL_INIT_WAIT = 4'h1; - localparam CTRL_NEXT_WSTART = 4'h2; - localparam CTRL_NEXT_USTART = 4'h3; - localparam CTRL_NEXT_LOOP0 = 4'h4; - localparam CTRL_NEXT_LOOP = 4'h5; - localparam CTRL_NEXT_WAIT = 4'h6; - localparam CTRL_NEXT_UPDATE = 4'h7; - localparam CTRL_NEXT_WCHECK = 4'h8; - localparam CTRL_NEXT_UCHECK = 4'h9; - localparam CTRL_NEXT_FINALIZE = 4'ha; + localparam CTRL_RESET = 4'h0; + localparam CTRL_IDLE = 4'h1; + localparam CTRL_INIT_WAIT = 4'h2; + localparam CTRL_NEXT_WSTART = 4'h3; + localparam CTRL_NEXT_USTART = 4'h4; + localparam CTRL_NEXT_LOOP0 = 4'h5; + localparam CTRL_NEXT_LOOP = 4'h6; + localparam CTRL_NEXT_WAIT = 4'h7; + localparam CTRL_NEXT_UPDATE = 4'h8; + localparam CTRL_NEXT_WCHECK = 4'h9; + localparam CTRL_NEXT_UCHECK = 4'ha; + localparam CTRL_NEXT_FINALIZE = 4'hb; + localparam CTRL_MKM_WAIT = 4'hc; //---------------------------------------------------------------- @@ -130,6 +143,7 @@ module keywrap_core #(parameter MEM_BITS = 11) wire aes_valid; reg [127 : 0] aes_block; wire [127 : 0] aes_result; + reg [255 : 0] aes_key; reg update_state; @@ -138,6 +152,15 @@ module keywrap_core #(parameter MEM_BITS = 11) reg [63 : 0] core_wr_data; wire [63 : 0] core_rd_data; + reg mkm_init; + reg mkm_read; + reg mkm_write; + reg mkm_key_status; + wire mkm_ready; + wire [255 : 0] mkm_rd_key; + wire [31 : 0] mkm_rd_status; + wire [31 : 0] mkm_wr_status; + //---------------------------------------------------------------- // Instantiations. @@ -166,7 +189,7 @@ module keywrap_core #(parameter MEM_BITS = 11) .init(aes_init), .next(aes_next), - .key(key), + .key(aes_key), .keylen(keylen), .block(aes_block), @@ -177,12 +200,36 @@ module keywrap_core #(parameter MEM_BITS = 11) ); + keywrap_mkmif mkmif( + .clk(clk), + .reset_n(reset_n), + + .mkm_spi_sclk(mkm_spi_sclk), + .mkm_spi_cs_n(mkm_spi_cs_n), + .mkm_spi_do(mkm_spi_do), + .mkm_spi_di(mkm_spi_di), + + .init(mkm_init), + .read(mkm_read), + .write(mkm_write), + .key_status(mkey_mstatus), + .ready(mkm_ready), + + .wr_status(mkm_wr_status), + .rd_status(mkm_rd_status), + .wr_key(key), + .rd_key(mkm_rd_key) + ); + + //---------------------------------------------------------------- // Assignments for ports. //---------------------------------------------------------------- - assign a_result = a_reg; - assign ready = ready_reg; - assign valid = valid_reg; + assign a_result = a_reg; + assign ready = ready_reg; + assign valid = valid_reg; + assign mkey = mkm_rd_key; + assign mstatus = mkm_rd_status; //---------------------------------------------------------------- @@ -190,6 +237,8 @@ module keywrap_core #(parameter MEM_BITS = 11) //---------------------------------------------------------------- always @ (posedge clk or negedge reset_n) begin: reg_update + integer i; + if (!reset_n) begin a_reg <= 64'h0; @@ -197,7 +246,7 @@ module keywrap_core #(parameter MEM_BITS = 11) valid_reg <= 1'h0; block_ctr_reg <= {(MEM_BITS - 1){1'h0}}; iteration_ctr_reg <= 3'h0; - keywrap_core_ctrl_reg <= CTRL_IDLE; + keywrap_core_ctrl_reg <= CTRL_RESET; end else @@ -333,6 +382,17 @@ module keywrap_core #(parameter MEM_BITS = 11) end + //---------------------------------------------------------------- + // aes_key_mux + //---------------------------------------------------------------- + always @* + begin + if (mkey_key) + aes_key = mkm_rd_key; + else + aes_key = key; + end + //---------------------------------------------------------------- // keywrap_core_ctrl @@ -347,6 +407,9 @@ module keywrap_core #(parameter MEM_BITS = 11) update_state = 1'h0; aes_init = 1'h0; aes_next = 1'h0; + mkm_init = 1'h0; + mkm_read = 1'h0; + mkm_write = 1'h0; block_ctr_dec = 1'h0; block_ctr_inc = 1'h0; block_ctr_rst = 1'h0; @@ -355,11 +418,22 @@ module keywrap_core #(parameter MEM_BITS = 11) iteration_ctr_dec = 1'h0; iteration_ctr_set = 1'h0; iteration_ctr_rst = 1'h0; + keywrap_core_ctrl_new = CTRL_IDLE; keywrap_core_ctrl_we = 1'h0; case (keywrap_core_ctrl_reg) + CTRL_RESET: + begin + mkm_init = 1'h1; + ready_new = 1'h0; + ready_we = 1'h1; + keywrap_core_ctrl_new = CTRL_MKM_WAIT; + keywrap_core_ctrl_we = 1'h0; + end + + CTRL_IDLE: begin if (init) @@ -386,6 +460,25 @@ module keywrap_core #(parameter MEM_BITS = 11) keywrap_core_ctrl_new = CTRL_NEXT_USTART; keywrap_core_ctrl_we = 1'h1; end + + if (read) + begin + mkm_read = 1'h1; + ready_new = 1'h0; + ready_we = 1'h1; + mkm_read = 1'h1; + keywrap_core_ctrl_new = CTRL_MKM_WAIT; + keywrap_core_ctrl_we = 1'h1; + end + + if (write) + begin + mkm_write = 1'h1; + ready_new = 1'h0; + ready_we = 1'h1; + keywrap_core_ctrl_new = CTRL_MKM_WAIT; + keywrap_core_ctrl_we = 1'h1; + end end @@ -517,9 +610,19 @@ module keywrap_core #(parameter MEM_BITS = 11) end - default: + CTRL_MKM_WAIT: begin + if (mkm_ready) + begin + ready_new = 1'h1; + ready_we = 1'h1; + keywrap_core_ctrl_new = CTRL_IDLE; + keywrap_core_ctrl_we = 1'h1; + end + end + default: + begin end endcase // case (keywrap_core_ctrl_reg) end // keywrap_core_ctrl diff --git a/src/rtl/keywrap_mkmif.v b/src/rtl/keywrap_mkmif.v new file mode 100644 index 0000000..d73c5bd --- /dev/null +++ b/src/rtl/keywrap_mkmif.v @@ -0,0 +1,449 @@ +//====================================================================== +// +// keywrap_mkmif.v +// --------------- +// Wrapper for the mkmif_core. This allow us to simplify the +// integration of the mkmif in keywrap_core. +// +// +// 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. +// +//====================================================================== + +module keywrap_mkmif ( + input wire clk, + input wire reset_n, + + output wire mkm_spi_sclk, + output wire mkm_spi_cs_n, + input wire mkm_spi_do, + output wire mkm_spi_di, + + input wire init, + input wire read, + input wire write, + input wire key_status, + output wire ready, + + input wire [31 : 0] wr_status, + output wire [31 : 0] rd_status, + input wire [255 : 0] wr_key, + output wire [255 : 0] rd_key + ); + + + //---------------------------------------------------------------- + // Paramenters and local defines. + //---------------------------------------------------------------- + localparam CTRL_IDLE = 4'h0; + localparam CTRL_WAIT = 4'h1; + localparam CTRL_INIT = 4'h2; + localparam CTRL_READ = 4'h3; + localparam CTRL_READ_STATUS_WAIT = 4'h4; + localparam CTRL_READ_KEY = 4'h5; + localparam CTRL_READ_KEY_WAIT = 4'h6; + localparam CTRL_WRITE = 4'h8; + localparam CTRL_WRITE_KEY = 4'h9; + localparam CTRL_WRITE_KEY_WAIT = 4'ha; + + // Addresses for storage in the mkm + localparam MKM_STATUS_WORD = 16'h00; + localparam MKM_KEY_BASE_WORD = 16'h04; + + localparam DEFAULT_SCLK_DIV = 16'h0020; + + + //---------------------------------------------------------------- + // Registers and memories including control signals. + //---------------------------------------------------------------- + reg [31 : 0] key_reg [0 : 7]; + reg key_we; + + reg [2 : 0] key_word_ctr_reg; + reg [2 : 0] key_word_ctr_new; + reg key_word_ctr_we; + reg key_word_ctr_rst; + reg key_word_ctr_inc; + + reg [15 : 0] mkm_addr_reg; + reg [15 : 0] mkm_addr_new; + reg mkm_addr_we; + + reg [31 : 0] mkm_write_data_reg; + reg [31 : 0] mkm_write_data_new; + reg mkm_write_data_we; + + reg [31 : 0] status_reg; + reg [31 : 0] status_new; + reg status_we; + + reg ready_reg; + reg ready_new; + reg ready_we; + + reg [3 : 0] keywrap_mkmif_ctrl_reg; + reg [3 : 0] keywrap_mkmif_ctrl_new; + reg keywrap_mkmif_ctrl_we; + + reg init_op_reg; + reg read_op_reg; + reg write_op_reg; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg mkm_init_op; + reg mkm_read_op; + reg mkm_write_op; + wire mkm_ready; + wire mkm_valid; + reg [15 : 0] mkm_addr; + reg [31 : 0] mkm_write_data; + wire [31 : 0] mkm_read_data; + + + //---------------------------------------------------------------- + // Instantiations. + //---------------------------------------------------------------- + mkmif_core mkm( + .clk(clk), + .reset_n(reset_n), + + .spi_sclk(mkm_spi_sclk), + .spi_cs_n(mkm_spi_cs_n), + .spi_do(mkm_spi_do), + .spi_di(mkm_spi_di), + + .init_op(init_op_reg), + .read_op(read_op_reh), + .write_op(write_op_reg), + + .ready(mkm_ready), + .valid(mkm_valid), + + .sclk_div(DEFAULT_SCLK_DIV), + .addr(mkm_addr_reg), + .write_data(mkm_write_data_reg), + .read_data(mkm_read_data) + ); + + + //---------------------------------------------------------------- + // Assignments for ports. + //---------------------------------------------------------------- + assign ready = ready_reg; + + assign rd_status = status_reg; + + assign rd_key = {key_reg[7], key_reg[6], key_reg[5], key_reg[4], + key_reg[3], key_reg[2], key_reg[1], key_reg[0]}; + + + //---------------------------------------------------------------- + // reg_update + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin: reg_update + integer i; + + if (!reset_n) + begin + for (i = 0 ; i < 8 ; i = i + 1) + key_reg[i] <= 32'h0; + + ready_reg <= 1'h1; + status_reg <= 32'h0; + mkm_addr_reg <= 16'h0; + mkm_write_data_reg <= 32'h0; + key_word_ctr_reg <= 3'h0; + init_op_reg <= 1'h0; + read_op_reg <= 1'h0; + write_op_reg <= 1'h0; + keywrap_mkmif_ctrl_reg <= CTRL_IDLE; + end + + else + begin + init_op_reg <= mkm_init_op; + read_op_reg <= mkm_read_op; + write_op_reg <= mkm_write_op; + + if (ready_we) + ready_reg <= ready_new; + + if (mkm_addr_we) + mkm_addr_reg <= mkm_addr_new; + + if (mkm_write_data_we) + mkm_write_data_reg <= mkm_write_data_new; + + if (key_we) + key_reg[key_word_ctr_reg] <= mkm_read_data; + + if (status_we) + status_reg <= mkm_read_data; + + if (key_word_ctr_we) + key_word_ctr_reg <= key_word_ctr_new; + + if (keywrap_mkmif_ctrl_we) + keywrap_mkmif_ctrl_reg <= keywrap_mkmif_ctrl_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // key_word_ctr + //---------------------------------------------------------------- + always @* + begin : key_word_ctr + key_word_ctr_new = 3'h0; + key_word_ctr_we = 1'h0; + + if (key_word_ctr_rst) + begin + key_word_ctr_new = 3'h0; + key_word_ctr_we = 1'h1; + end + + if (key_word_ctr_inc) + begin + key_word_ctr_new = key_word_ctr_reg + 1'h1; + key_word_ctr_we = 1'h1; + end + + end + + + //---------------------------------------------------------------- + // keywrap_mkmif_ctrl + //---------------------------------------------------------------- + always @* + begin : keywrap_mkmif_ctrl + ready_new = 1'h0; + ready_we = 1'h0; + key_we = 1'h0; + key_word_ctr_rst = 1'h0; + key_word_ctr_inc = 1'h0; + status_we = 1'h0; + mkm_init_op = 1'h0; + mkm_read_op = 1'h0; + mkm_write_op = 1'h0; + mkm_addr_new = 16'h0; + mkm_addr_we = 1'h0; + mkm_write_data_new = 32'h0; + mkm_write_data_we = 1'h0; + keywrap_mkmif_ctrl_new = CTRL_IDLE; + keywrap_mkmif_ctrl_we = 1'h0; + + case (keywrap_mkmif_ctrl_reg) + CTRL_IDLE: + begin + if (init) + begin + mkm_init_op = 1'h1; + ready_new = 1'h0; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_INIT; + keywrap_mkmif_ctrl_we = 1'h1; + end + + if (read) + begin + ready_new = 1'h0; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_READ; + keywrap_mkmif_ctrl_we = 1'h1; + end + + if (write) + begin + ready_new = 1'h0; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_WRITE; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_INIT: + begin + keywrap_mkmif_ctrl_new = CTRL_WAIT; + keywrap_mkmif_ctrl_we = 1'h1; + end + + + CTRL_READ: + begin + if (key_status) + begin + key_word_ctr_rst = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_READ_KEY; + keywrap_mkmif_ctrl_we = 1'h1; + end + else + begin + mkm_read_op = 1'h1; + mkm_addr_new = MKM_STATUS_WORD; + mkm_addr_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_READ_STATUS_WAIT; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_WAIT: + begin + if (mkm_ready) + begin + ready_new = 1'h1; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_IDLE; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_READ_STATUS_WAIT: + begin + ready_new = 1'h1; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_IDLE; + keywrap_mkmif_ctrl_we = 1'h1; + if (mkm_ready) + begin + status_we = 1'h1; + ready_new = 1'h1; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_IDLE; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_READ_KEY: + begin + if (key_word_ctr_reg < 8) + begin + mkm_read_op = 1'h1; + mkm_addr_new = MKM_KEY_BASE_WORD + {key_word_ctr_reg, 2'h0}; + mkm_addr_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_READ_KEY_WAIT; + keywrap_mkmif_ctrl_we = 1'h1; + end + else + begin + ready_new = 1'h1; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_IDLE; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_READ_KEY_WAIT: + begin + if (mkm_ready) + begin + key_we = 1'h1; + key_word_ctr_inc = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_READ_KEY; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_WRITE: + begin + if (key_status) + begin + key_word_ctr_rst = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_WRITE_KEY; + keywrap_mkmif_ctrl_we = 1'h1; + end + else + begin + mkm_write_op = 1'h1; + mkm_addr_new = MKM_STATUS_WORD; + mkm_addr_we = 1'h1; + mkm_write_data_new = wr_status; + mkm_write_data_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_WAIT; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_WRITE_KEY: + begin + if (key_word_ctr_reg < 8) + begin + mkm_write_op = 1'h1; + mkm_addr_new = MKM_KEY_BASE_WORD + {key_word_ctr_reg, 2'h0}; + mkm_addr_we = 1'h1; + mkm_write_data_new = wr_key[key_word_ctr_reg * 32 +: 32]; + mkm_write_data_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_WRITE_KEY_WAIT; + keywrap_mkmif_ctrl_we = 1'h1; + end + else + begin + ready_new = 1'h1; + ready_we = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_IDLE; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + CTRL_WRITE_KEY_WAIT: + begin + if (mkm_ready) + begin + key_word_ctr_inc = 1'h1; + keywrap_mkmif_ctrl_new = CTRL_WRITE_KEY; + keywrap_mkmif_ctrl_we = 1'h1; + end + end + + + default: + begin + end + endcase // case (keywrap_mkmif_ctrl_reg) + end // keywrap_mkmif_ctrl + +endmodule // keywrap_mkmif + +//====================================================================== +// EOF keywrap_mkmif.v +//====================================================================== diff --git a/src/tb/tb_keywrap.v b/src/tb/tb_keywrap.v index b232ab3..fb02792 100644 --- a/src/tb/tb_keywrap.v +++ b/src/tb/tb_keywrap.v @@ -102,6 +102,10 @@ module tb_keywrap(); reg tb_clk; reg tb_reset_n; + wire tb_mkm_spi_sclk; + wire tb_mkm_spi_cs_n; + reg tb_mkm_spi_do; + wire tb_mkm_spi_di; reg tb_cs; reg tb_we; reg [(ADDR_BITS -1 ) : 0] tb_address; @@ -116,6 +120,10 @@ module tb_keywrap(); keywrap 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), .cs(tb_cs), .we(tb_we), .address(tb_address), @@ -348,15 +356,17 @@ module tb_keywrap(); //---------------------------------------------------------------- task init_sim; begin - cycle_ctr = 0; - error_ctr = 0; - tc_ctr = 0; + cycle_ctr = 1'h0; + error_ctr = 1'h0; + tc_ctr = 1'h0; - tb_clk = 0; - tb_reset_n = 1; + tb_clk = 1'h0; + tb_reset_n = 1'h1; - tb_cs = 0; - tb_we = 0; + tb_mkm_spi_do = 1'h1; + + tb_cs = 1'h0; + tb_we = 1'h0; tb_address = 8'h0; tb_write_data = 32'h0; end diff --git a/src/tb/tb_keywrap_core.v b/src/tb/tb_keywrap_core.v index 6ec76be..b8857ea 100644 --- a/src/tb/tb_keywrap_core.v +++ b/src/tb/tb_keywrap_core.v @@ -64,7 +64,11 @@ module tb_keywrap_core(); reg tb_reset_n; reg tb_init; reg tb_next; + reg tb_read; + reg tb_write; reg tb_encdec; + reg tb_mkey_mstatus; + reg tb_mkey_key; wire tb_ready; wire tb_valid; wire tb_loaded; @@ -74,7 +78,10 @@ module tb_keywrap_core(); wire tb_dut_timeout; reg [(RLEN_BITS - 1) : 0] tb_rlen; reg [255 : 0] tb_key; + reg [31 : 0] tb_status; reg tb_keylen; + wire [255 : 0] tb_mkey; + wire [31 : 0] tb_mstatus; reg [63 : 0] tb_a_init; wire [63 : 0] tb_a_result; reg tb_api_we; @@ -82,6 +89,11 @@ module tb_keywrap_core(); reg [31 : 0] tb_api_wr_data; wire [31 : 0] tb_api_rd_data; + wire tb_mkm_spi_sclk; + wire tb_mkm_spi_cs_n; + reg tb_mkm_spi_do; + wire tb_mkm_spi_di; + //---------------------------------------------------------------- // Device Under Test. @@ -91,8 +103,17 @@ module tb_keywrap_core(); .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), .next(tb_next), + .read(tb_read), + .write(tb_write), + .mkey_mstatus(tb_mkey_mstatus), + .mkey_key(tb_mkey_key), .encdec(tb_encdec), .ready(tb_ready), @@ -107,6 +128,9 @@ module tb_keywrap_core(); .rlen(tb_rlen), .key(tb_key), .keylen(tb_keylen), + .status(tb_status), + .mkey(tb_mkey), + .mstatus(tb_mstatus), .a_init(tb_a_init), .a_result(tb_a_result), @@ -158,19 +182,21 @@ module tb_keywrap_core(); tb_clk = 0; tb_reset_n = 0; - tb_init = 1'h0; - tb_next = 1'h0; - tb_encdec = 1'h0; - tb_rlen = 13'h0; - tb_key = 256'h0; - tb_keylen = 1'h0; - tb_timeout = 32'hdeadbeef; - tb_ping = 1'h0; - tb_zeroise = 1'h0; - tb_a_init = 64'h0; - tb_api_we = 1'h0; - tb_api_addr = 14'h0; - tb_api_wr_data = 32'h0; + tb_init = 0; + tb_next = 0; + tb_read = 0; + tb_write = 0; + tb_encdec = 0; + tb_mkey_mstatus = 0; + tb_mkey_key = 0; + tb_rlen = 13'h0; + tb_key = 256'h0; + tb_status = 32'h0; + tb_keylen = 0; + tb_a_init = 64'h0; + tb_api_we = 0; + tb_api_addr = 14'h0; + tb_api_wr_data = 32'h0; #(CLK_PERIOD * 10); 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 +//====================================================================== diff --git a/src/tech/README.md b/src/tech/README.md new file mode 100644 index 0000000..0e04542 --- /dev/null +++ b/src/tech/README.md @@ -0,0 +1,14 @@ +README.md +========= +This dir is where the vendor specific Verilog memory model should be +stored. + +The memory used is the [Microchip +23K640](https://www.microchip.com/wwwproducts/en/23A640) a 64kbit, +SPI-connected serial SRAM. + +The Verilog memory model can be downloaded from that webpage or [by +clicking on this link](http://ww1.microchip.com/downloads/en/DeviceDoc/23x640_Verilog_Model.zip). + +Download and unzip the file in this directory. This should produce two +files, 23A640.v and 23K640.v. The one needed for simulation is 23K640.v |