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_spi_slave.v | 234 +++++++++++++++++++++++-------------------- 1 file changed, 126 insertions(+), 108 deletions(-) (limited to 'src/rtl/fpga_mkm_spi_slave.v') 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 -- cgit v1.2.3