diff options
Diffstat (limited to 'src/rtl')
-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 |
3 files changed, 677 insertions, 57 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 +//====================================================================== |