From 6f167e358cd681722eea2b482e2e8d429ea673ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Tue, 26 Mar 2019 14:49:45 +0100 Subject: Completed first RTL for the SPI slave. Simplified the design to simply be two shift registers and a somple FSM that detects clock flanks and SS. --- src/rtl/fpga_mkm.v | 32 +++++- src/rtl/fpga_mkm_spi_slave.v | 234 +++++++++++++++++++++++-------------------- toolruns/Makefile | 13 ++- 3 files changed, 162 insertions(+), 117 deletions(-) diff --git a/src/rtl/fpga_mkm.v b/src/rtl/fpga_mkm.v index eb6172d..e0dc14a 100644 --- a/src/rtl/fpga_mkm.v +++ b/src/rtl/fpga_mkm.v @@ -40,6 +40,8 @@ module fpga_mkm( input wire clk, + // SPI slave interface ports. + input wire ss, input wire sclk, input wire mosi, output wire miso, @@ -66,9 +68,14 @@ module fpga_mkm( localparam CTRL_DONE = 3; + localparam MEM_WORDS = 16; + + //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- + reg [31 : 0] key_mem [0 : (MEM_WORDS - 1)]; + reg [21 : 0] alarm_counter_reg = 22'h0; reg alarm_reg = 1'h0; @@ -95,8 +102,23 @@ module fpga_mkm( assign rled4 = alarm_counter_reg[21]; assign gled5 = key_loaded_reg; - assign miso = miso_reg; - assign alarm = alarm_reg; + + + //---------------------------------------------------------------- + // Module instantiations. + //---------------------------------------------------------------- + fpga_mkm_spi_slave spi_slave( + .clk(clk), + .ss(ss), + .sclk(sclk), + .mosi(mosi), + .miso(miso), + .spi_active(), + .rx_byte_available(), + .rx_byte(), + .tx_byte_load(), + .tx_byte() + ); //---------------------------------------------------------------- @@ -104,10 +126,12 @@ module fpga_mkm( //---------------------------------------------------------------- always @ (posedge clk or negedge tamper) begin : reg_update + integer i; + if (!tamper) begin - // Zeroise the key material! - + for (i = 0 ; i < MEM_WORDS ; i = i + 1) + key_mem[i] <= 32'h0; end else begin diff --git a/src/rtl/fpga_mkm_spi_slave.v b/src/rtl/fpga_mkm_spi_slave.v index 473d37d..1449af2 100644 --- a/src/rtl/fpga_mkm_spi_slave.v +++ b/src/rtl/fpga_mkm_spi_slave.v @@ -48,91 +48,78 @@ //====================================================================== module fpga_mkm_spi_slave( - input wire clk, + input wire clk, - input wire ss, - input wire sclk, - input wire mosi, - output wire miso, + input wire ss, + input wire sclk, + input wire mosi, + output wire miso, - output wire rx_byte_available, - output wire rx_byte_ack, + output wire spi_active, + output wire rx_byte_available, output wire [7 : 0] rx_byte, - input wire tx_byte_available, - output wire tx_byte_ack, - output wire tx_byte_error, - input wire [7 : 0] tx_byte + input wire tx_byte_load, + input wire [7 : 0] tx_byte ); //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - localparam CTRL_IDLE = 3'h0; + localparam CTRL_IDLE = 3'h0; + localparam CTRL_SELECTED = 3'h1; + localparam CTRL_POS_EDGE = 3'h2; + localparam CTRL_NEG_EDGE = 3'h3; //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- - reg ss_sample0_reg; - reg ss_sample1_reg; - reg ss_reg; + reg ss_sample0_reg; + reg ss_sample1_reg; + reg ss_reg; - reg sclk_sample0_reg; - reg sclk_sample1_reg; - reg sclk_reg; + reg sclk_sample0_reg; + reg sclk_sample1_reg; + reg sclk_reg; - reg mosi_sample0_reg; - reg mosi_sample1_reg; - reg mosi_reg; + reg mosi_sample0_reg; + reg mosi_sample1_reg; + reg mosi_reg; reg [7 : 0] rx_byte_reg = 8'h0; reg [7 : 0] rx_byte_new; - reg rx_byte_we; - - reg [2 : 0] rx_bit_ctr_reg = 3'h0; - reg [2 : 0] rx_bit_ctr_new; - reg rx_bit_ctr_we; - reg rx_bit_ctr_rst; - reg rx_bit_ctr_inc; - - reg rx_byte_available_reg = 1'h0; - reg rx_byte_available_new; - reg rx_byte_available_we; + reg rx_byte_next; reg [7 : 0] tx_byte_reg = 8'h0; reg [7 : 0] tx_byte_new; reg tx_byte_we; - reg tx_byte_load; - reg tx_byte_loadz; reg tx_byte_next; + reg tx_byte_loadz; - reg [2 : 0] tx_bit_ctr_reg = 3'h0; - reg [2 : 0] tx_bit_ctr_new; - reg tx_bit_ctr_we; - reg tx_bit_ctr_rst; - reg tx_bit_ctr_inc; - - reg tx_byte_ack_reg = 1'h0; - reg tx_byte_ack_new; + reg [2 : 0] bit_ctr_reg = 3'h0; + reg [2 : 0] bit_ctr_new; + reg bit_ctr_we; + reg bit_ctr_rst; + reg bit_ctr_inc; - reg tx_byte_error_reg = 1'h0; - reg tx_byte_error_new; + reg spi_active_reg = 1'h0; + reg spi_active_new; + reg spi_active_we; - reg [2 : 0] spi_slave_ctrl_reg = CTRL_IDLE; - reg [2 : 0] spi_slave_ctrl_new; - reg spi_slave_ctrl_we; + reg [2 : 0] spi_slave_ctrl_reg = CTRL_IDLE; + reg [2 : 0] spi_slave_ctrl_new; + reg spi_slave_ctrl_we; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- assign miso = tx_byte_reg[7]; - assign rx_byte_available = rx_byte_available_reg; + assign rx_byte_available = (bit_ctr_reg == 3'h7); assign rx_byte = rx_byte_reg; - assign tx_byte_ack = tx_byte_ack_reg; - assign tx_byte_error = tx_byte_error_reg; + assign spi_active = spi_active_reg; //---------------------------------------------------------------- @@ -152,23 +139,17 @@ module fpga_mkm_spi_slave( mosi_sample1_reg <= mosi_sample0_reg; mosi_reg <= mosi_sample1_reg; - tx_byte_ack_reg <= tx_byte_ack_new; - tx_byte_error_reg <= tx_byte_error_new; - - if (rx_byte_we) + if (rx_byte_next) rx_byte_reg <= {rx_byte_reg[6 : 0], mosi_reg}; - if (rx_bit_ctr_we) - rx_bit_ctr_reg <= rx_bit_ctr_new; - - if (rx_byte_available_we) - rx_byte_available_reg <= rx_byte_available_new; + if (bit_ctr_we) + bit_ctr_reg <= bit_ctr_new; if (tx_byte_we) tx_byte_reg <= tx_byte_new; - if (tx_bit_ctr_we) - tx_bit_ctr_reg <= tx_bit_ctr_new; + if (spi_active_we) + spi_active_reg <= spi_active_new; if (spi_slave_ctrl_we) spi_slave_ctrl_reg <= spi_slave_ctrl_new; @@ -181,7 +162,7 @@ module fpga_mkm_spi_slave( // set the next bit to transmit. //---------------------------------------------------------------- always @* - begin : tx_byt_logic + begin : tx_byte_logic tx_byte_new = 8'h0; tx_byte_we = 1'h0; @@ -199,52 +180,30 @@ module fpga_mkm_spi_slave( if (tx_byte_next) begin - tx_byte_new = {tx_byte_reg[6 : 0], 1'h0]}; + tx_byte_new = {tx_byte_reg[6 : 0], 1'h0}; tx_byte_we = 1'h1; end end //---------------------------------------------------------------- - // rx_bit_ctr - //---------------------------------------------------------------- - always @* - begin : rx_bit_ctr - rx_bit_ctr_new = 3'h0; - rx_bit_ctr_we = 1'h0; - - if (rx_bit_ctr_rst) - begin - rx_bit_ctr_new = 3'h0; - rx_bit_ctr_we = 1'h1; - end - - if (rx_bit_ctr_inc) - begin - rx_bit_ctr_new = rx_bit_ctr_reg + 1'h1; - rx_bit_ctr_we = 1'h0; - end - end - - - //---------------------------------------------------------------- - // tx_bit_ctr + // bit_ctr //---------------------------------------------------------------- always @* - begin : tx_bit_ctr - tx_bit_ctr_new = 3'h0; - tx_bit_ctr_we = 1'h0; + begin : bit_ctr + bit_ctr_new = 3'h0; + bit_ctr_we = 1'h0; - if (tx_bit_ctr_rst) + if (bit_ctr_rst) begin - tx_bit_ctr_new = 3'h0; - tx_bit_ctr_we = 1'h1; + bit_ctr_new = 3'h0; + bit_ctr_we = 1'h1; end - if (tx_bit_ctr_inc) + if (bit_ctr_inc) begin - tx_bit_ctr_new = tx_bit_ctr_reg + 1'h1; - tx_bit_ctr_we = 1'h0; + bit_ctr_new = bit_ctr_reg + 1'h1; + bit_ctr_we = 1'h1; end end @@ -254,22 +213,81 @@ module fpga_mkm_spi_slave( //---------------------------------------------------------------- always @* begin : spi_slave_ctrl_fsm - rx_bit_ctr_rst = 1'h0; - rx_bit_ctr_inc = 1'h0; - tx_bit_ctr_rst = 1'h0; - tx_bit_ctr_inc = 1'h0; - tx_byte_load = 1'h0; - tx_byte_loadz = 1'h0; - tx_byte_next = 1'h0; - tx_byte_ack_new = 1'h0; - tx_byte_error_new = 1'h0; - rx_byte_we = 1'h0; - + bit_ctr_rst = 1'h0; + bit_ctr_inc = 1'h0; + rx_byte_next = 1'h0; + tx_byte_loadz = 1'h0; + tx_byte_next = 1'h0; + spi_active_new = 1'h0; + spi_active_we = 1'h0; + spi_slave_ctrl_new = CTRL_IDLE; + spi_slave_ctrl_we = 1'h0; case (spi_slave_ctrl_reg) - + CTRL_IDLE: + begin + if (ss_reg == 0) + begin + spi_slave_ctrl_new = CTRL_SELECTED; + spi_slave_ctrl_we = 1'h1; + end + end + + + CTRL_SELECTED: + begin + bit_ctr_rst = 1'h1; + tx_byte_loadz = 1'h1; + spi_active_new = 1'h1; + spi_active_we = 1'h1; + spi_slave_ctrl_new = CTRL_POS_EDGE; + spi_slave_ctrl_we = 1'h1; + end + + + CTRL_POS_EDGE: + begin + if (ss_reg == 0) + begin + if ((sclk_sample1_reg == 1'h1) && (sclk_reg == 1'h0)) + begin + rx_byte_next = 1'h1; + tx_byte_next = 1'h1; + bit_ctr_inc = 1'h1; + spi_slave_ctrl_new = CTRL_NEG_EDGE; + spi_slave_ctrl_we = 1'h1; + end + end + else + begin + spi_active_new = 1'h0; + spi_active_we = 1'h1; + spi_slave_ctrl_new = CTRL_IDLE; + spi_slave_ctrl_we = 1'h1; + end + end + + + CTRL_NEG_EDGE: + begin + if (ss_reg == 0) + begin + if ((sclk_sample1_reg == 1'h0) && (sclk_reg == 1'h1)) + begin + spi_slave_ctrl_new = CTRL_POS_EDGE; + spi_slave_ctrl_we = 1'h1; + end + end + else + begin + spi_active_new = 1'h0; + spi_active_we = 1'h1; + spi_slave_ctrl_new = CTRL_IDLE; + spi_slave_ctrl_we = 1'h1; + end + end endcase // case (spi_slave_ctrl_reg) - end + end // block: spi_slave_ctrl_fsm endmodule // fpga_mkm_spi_slave diff --git a/toolruns/Makefile b/toolruns/Makefile index bb1f4bf..82f2de3 100755 --- a/toolruns/Makefile +++ b/toolruns/Makefile @@ -55,6 +55,9 @@ FOOTPRINT = tq144 TOP_NAME = fpga_mkm TOP_SRC = ../src/rtl/fpga_mkm.v TB_TOP_SRC = ../src/tb/tb_fpga_mkm.v +SPI_SRC = ../src/rtl/fpga_mkm_spi_slave.v +TB_SPI_SRC = ../src/tb/tb_fpga_mkm_spi_slave.v + CONFIG_SRC = ../src/config/pinmap_icestick.pcf CC = iverilog @@ -70,19 +73,19 @@ LINT_FLAGS = +1364-2001ext+ --lint-only -Wall -Wno-fatal -Wno-DECLFILENAME all: top.sim -top.sim: $(TB_TOP_SRC) $(TOP_SRC) - $(CC) $(CC_FLAGS) -o top.sim $(TB_TOP_SRC) $(TOP_SRC) +top.sim: $(TB_TOP_SRC) $(TOP_SRC) $(SPI_SRC) + $(CC) $(CC_FLAGS) -o top.sim $(TB_TOP_SRC) $(TOP_SRC) $(SPI_SRC) sim-top: top.sim ./top.sim -lint: $(TOP_SRC) - $(LINT) $(LINT_FLAGS) $(TOP_SRC) +lint: $(TOP_SRC) $(SPI_SRC) + $(LINT) $(LINT_FLAGS) $(TOP_SRC) $(SPI_SRC) -bitstream: $(TOP_SRC) +bitstream: $(TOP_SRC) $(SPI_SRC) mkdir -p $(BUILD) yosys -p "synth_ice40 -top $(TOP_NAME) -blif $(BUILD)/$(PROJ).blif" $(TOP_SRC) arachne-pnr -d $(DEVICE) -P $(FOOTPRINT) -o $(BUILD)/$(PROJ).asc -p $(CONFIG_SRC) $(BUILD)/$(PROJ).blif -- cgit v1.2.3