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