aboutsummaryrefslogtreecommitdiff
path: root/src/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtl')
-rw-r--r--src/rtl/keywrap.v146
-rw-r--r--src/rtl/keywrap_core.v139
-rw-r--r--src/rtl/keywrap_mkmif.v449
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
+//======================================================================