From c03aa37d4f237f2eb90d9a958428011ca2bd455c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Wed, 11 May 2016 17:13:04 +0200 Subject: Adding all source files and testbenches for the mkmif core. Adding Makefile for building simulation and linting. Adding top level license file. --- src/rtl/mkmif_core.v | 292 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 src/rtl/mkmif_core.v (limited to 'src/rtl/mkmif_core.v') diff --git a/src/rtl/mkmif_core.v b/src/rtl/mkmif_core.v new file mode 100644 index 0000000..0f90bf0 --- /dev/null +++ b/src/rtl/mkmif_core.v @@ -0,0 +1,292 @@ +//====================================================================== +// +// mkmif_core.v +// ------------ +// The actual core module for the Master Key Memory (MKM) interface. +// The interface is implemented to use the Microchip 23K640 serial +// sram as external storage. The core acts as a SPI Master for the +// external memory including SPI clock generation. +// +// The current version of the core does not provide any functionality +// to protect against remanence. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2011, 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 mkmif_core( + input wire clk, + input wire reset_n, + + output wire spi_sclk, + output wire spi_cs_n, + input wire spi_do, + output wire spi_di, + + input wire read_op, + input wire write_op, + input wire init_op, + output wire ready, + output wire valid, + input wire [15 : 0] sclk_div, + input wire [15 : 0] addr, + input wire [31 : 0] write_data, + output wire [31 : 0] read_data + ); + + + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam SPI_READ_DATA_CMD = 8'h03; + localparam SPI_WRITE_DATA_CMD = 8'h02; + localparam SPI_READ_STATUS_CMD = 8'h05; + localparam SPI_WRITE_STATUS_CMD = 8'h01; + + localparam SEQ_MODE_NO_HOLD = 8'b01000001; + + localparam CTRL_IDLE = 0; + localparam CTRL_READY = 1; + localparam CTRL_READ = 2; + localparam CTRL_WRITE = 3; + localparam CTRL_INIT = 4; + localparam CTRL_OP_START = 5; + localparam CTRL_OP_WAIT = 6; + + + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg ready_reg; + reg ready_new; + reg ready_we; + reg valid_reg; + reg valid_new; + reg valid_we; + + reg [31 : 0] read_data_reg; + reg read_data_we; + + reg [3 : 0] mkmif_ctrl_reg; + reg [3 : 0] mkmif_ctrl_new; + reg mkmif_ctrl_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + wire [31 : 0] spi_read_data; + reg [55 : 0] spi_write_data; + reg spi_set; + reg spi_start; + wire spi_ready; + reg [2 : 0] spi_length; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign ready = ready_reg; + assign valid = valid_reg; + assign read_data = read_data_reg; + + + //---------------------------------------------------------------- + // spi + // The actual spi interfacce + //---------------------------------------------------------------- + mkmif_spi spi( + .clk(clk), + .reset_n(reset_n), + + .spi_sclk(spi_sclk), + .spi_cs_n(spi_cs_n), + .spi_do(spi_do), + .spi_di(spi_di), + + .set(spi_set), + .start(spi_start), + .length(spi_length), + .divisor(sclk_div), + .ready(spi_ready), + .wr_data(spi_write_data), + .rd_data(spi_read_data) + ); + + + //---------------------------------------------------------------- + // reg_update + // Update functionality for all registers in the core. + // All registers are positive edge triggered with asynchronous + // active low reset. + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin + if (!reset_n) + begin + ready_reg <= 0; + valid_reg <= 0; + read_data_reg <= 32'h0; + mkmif_ctrl_reg <= CTRL_IDLE; + end + else + begin + if (ready_we) + ready_reg <= ready_new; + + if (valid_we) + valid_reg <= valid_new; + + if (read_data_we) + read_data_reg <= spi_read_data; + + if (mkmif_ctrl_we) + mkmif_ctrl_reg <= mkmif_ctrl_new; + end + end // reg_update + + + //---------------------------------------------------------------- + // mkmif_ctrl + // Main control FSM. + //---------------------------------------------------------------- + always @* + begin : mkmif_ctrl + spi_set = 0; + spi_start = 0; + spi_length = 3'h0; + spi_write_data = 56'h0; + read_data_we = 0; + ready_new = 0; + ready_we = 0; + valid_new = 0; + valid_we = 0; + mkmif_ctrl_new = CTRL_IDLE; + mkmif_ctrl_we = 0; + + case (mkmif_ctrl_reg) + CTRL_IDLE: + begin + mkmif_ctrl_new = CTRL_INIT; + mkmif_ctrl_we = 1; + end + + CTRL_READY: + begin + ready_new = 1; + ready_we = 1; + + if (read_op) + begin + ready_new = 0; + ready_we = 1; + valid_new = 0; + valid_we = 1; + mkmif_ctrl_new = CTRL_READ; + mkmif_ctrl_we = 1; + end + + if (write_op) + begin + ready_new = 0; + ready_we = 1; + mkmif_ctrl_new = CTRL_WRITE; + mkmif_ctrl_we = 1; + end + + if (init_op) + begin + ready_new = 0; + ready_we = 1; + mkmif_ctrl_new = CTRL_INIT; + mkmif_ctrl_we = 1; + end + end + + CTRL_READ: + begin + spi_set = 1; + spi_write_data = {SPI_READ_DATA_CMD, addr, 32'h0}; + spi_length = 3'h7; + mkmif_ctrl_new = CTRL_OP_START; + mkmif_ctrl_we = 1; + end + + CTRL_WRITE: + begin + spi_set = 1; + spi_write_data = {SPI_WRITE_DATA_CMD, addr, write_data}; + spi_length = 3'h7; + mkmif_ctrl_new = CTRL_OP_START; + mkmif_ctrl_we = 1; + end + + CTRL_INIT: + begin + if (spi_ready) + begin + spi_set = 1; + spi_write_data = {SPI_WRITE_STATUS_CMD, SEQ_MODE_NO_HOLD, 40'h0}; + spi_length = 3'h2; + mkmif_ctrl_new = CTRL_OP_START; + mkmif_ctrl_we = 1; + end + end + + CTRL_OP_START: + begin + spi_start = 1; + mkmif_ctrl_new = CTRL_OP_WAIT; + mkmif_ctrl_we = 1; + end + + CTRL_OP_WAIT: + begin + if (spi_ready) + begin + read_data_we = 1; + valid_new = 1; + valid_we = 1; + mkmif_ctrl_new = CTRL_READY; + mkmif_ctrl_we = 1; + end + end + + default: + begin + end + endcase // case (mkmif_ctrl_reg) + end // mkmif_ctrl +endmodule // mkmif + +//====================================================================== +// EOF mkmif.v +//====================================================================== -- cgit v1.2.3