From ff7855900d4f4b8d3ccd840e54f5d9c940c4f7e4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 7 Aug 2017 16:27:57 +0200 Subject: [PATCH] Refactor picosoc flash_io interfaces --- picosoc/picosoc.v | 43 ++++++++++----------- picosoc/spiflash.v | 33 +++++++++------- picosoc/spiflash_tb.v | 87 ++++++++++++++++++++++--------------------- picosoc/spimemio.v | 56 ++++++++++++++++++++-------- picosoc/testbench.v | 5 +-- 5 files changed, 129 insertions(+), 95 deletions(-) diff --git a/picosoc/picosoc.v b/picosoc/picosoc.v index 6521152..23260c9 100644 --- a/picosoc/picosoc.v +++ b/picosoc/picosoc.v @@ -88,31 +88,32 @@ module picosoc ( ); spimemio spimemio ( - .clk(clk), - .resetn(resetn), - .valid (mem_valid && mem_addr[31:24] == 8'h 01), - .ready (spimem_ready), - .addr (mem_addr[23:0]), - .rdata (spimem_rdata), + .clk (clk), + .resetn (resetn), + .valid (mem_valid && mem_addr[31:24] == 8'h 01), + .ready (spimem_ready), + .addr (mem_addr[23:0]), + .rdata (spimem_rdata), - .flash_csb (flash_csb), - .flash_clk (flash_clk), + .flash_csb (flash_csb ), + .flash_clk (flash_clk ), - .flash_io0 (flash_io0_do), - .flash_io1 (flash_io1_di), - .flash_io2 (flash_io2_di), - .flash_io3 (flash_io3_di) + .flash_io0_oe (flash_io0_oe), + .flash_io1_oe (flash_io1_oe), + .flash_io2_oe (flash_io2_oe), + .flash_io3_oe (flash_io3_oe), + + .flash_io0_do (flash_io0_do), + .flash_io1_do (flash_io1_do), + .flash_io2_do (flash_io2_do), + .flash_io3_do (flash_io3_do), + + .flash_io0_di (flash_io0_di), + .flash_io1_di (flash_io1_di), + .flash_io2_di (flash_io2_di), + .flash_io3_di (flash_io3_di) ); - assign flash_io0_oe = 1; - assign flash_io1_oe = 0; - assign flash_io2_oe = 0; - assign flash_io3_oe = 0; - - assign flash_io1_do = 0; - assign flash_io2_do = 0; - assign flash_io3_do = 0; - reg [31:0] memory [0:MEM_WORDS-1]; always @(posedge clk) begin diff --git a/picosoc/spiflash.v b/picosoc/spiflash.v index c1e9615..6e6137f 100644 --- a/picosoc/spiflash.v +++ b/picosoc/spiflash.v @@ -15,15 +15,23 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * - * Supported commands: - * AB, B9, FF, 03, EB, ED - * - * Well written SPI flash data sheets: - * Cypress S25FL064L http://www.cypress.com/file/316661/download - * */ +`timescale 1 ns / 1 ps + +// +// Simple SPI flash simulation model +// +// This model samples io input signals 1ns before the SPI clock edge and +// updates output signals 1ns after the SPI clock edge. +// +// Supported commands: +// AB, B9, FF, 03, EB, ED +// +// Well written SPI flash data sheets: +// Cypress S25FL064L http://www.cypress.com/file/316661/download +// + module spiflash ( input csb, input clk, @@ -47,7 +55,6 @@ module spiflash ( reg [7:0] spi_out; reg spi_io_vld; - reg qspi_active = 0; reg powered_up = 0; localparam [3:0] mode_spi = 1; @@ -69,10 +76,10 @@ module spiflash ( reg io2_dout = 0; reg io3_dout = 0; - assign io0 = io0_oe ? io0_dout : 1'bz; - assign io1 = io1_oe ? io1_dout : 1'bz; - assign io2 = io2_oe ? io2_dout : 1'bz; - assign io3 = io3_oe ? io3_dout : 1'bz; + assign #1 io0 = io0_oe ? io0_dout : 1'bz; + assign #1 io1 = io1_oe ? io1_dout : 1'bz; + assign #1 io2 = io2_oe ? io2_dout : 1'bz; + assign #1 io3 = io3_oe ? io3_dout : 1'bz; wire io0_delayed; wire io1_delayed; @@ -105,7 +112,7 @@ module spiflash ( powered_up = 0; if (spi_cmd == 8'h ff) - qspi_active = 0; + xip_cmd = 0; end if (powered_up && spi_cmd == 'h 03) begin diff --git a/picosoc/spiflash_tb.v b/picosoc/spiflash_tb.v index 769a3a0..ce2e949 100644 --- a/picosoc/spiflash_tb.v +++ b/picosoc/spiflash_tb.v @@ -17,6 +17,8 @@ * */ +`timescale 1 ns / 1 ps + module testbench; reg flash_csb = 1; reg flash_clk = 0; @@ -69,10 +71,10 @@ module testbench; task xfer_begin; begin - #50; + #5; flash_csb = 0; $display("-- BEGIN"); - #50; + #5; end endtask @@ -83,17 +85,17 @@ module testbench; flash_io2_oe = 0; flash_io3_oe = 0; - #50; + #5; flash_clk = 1; - #50; + #5; flash_clk = 0; - #50; + #5; end endtask task xfer_end; begin - #50; + #5; flash_csb = 1; flash_io0_oe = 0; flash_io1_oe = 0; @@ -101,7 +103,7 @@ module testbench; flash_io3_oe = 0; $display("-- END"); $display(""); - #50; + #5; end endtask @@ -116,15 +118,15 @@ module testbench; for (i = 0; i < 8; i=i+1) begin flash_io0_dout = data[7-i]; - #50; + #5; + flash_clk = 1; rdata[7-i] = flash_io1; - flash_clk <= 1; - #50; + #5; flash_clk = 0; end $display("-- SPI SDR %02x %02x", data, rdata); - #50; + #5; end endtask @@ -142,23 +144,23 @@ module testbench; flash_io2_dout = data[6]; flash_io3_dout = data[7]; - #50; + #5; flash_clk = 1; - #50; - flash_clk = 0; + #5; + flash_clk = 0; flash_io0_dout = data[0]; flash_io1_dout = data[1]; flash_io2_dout = data[2]; flash_io3_dout = data[3]; - #50; + #5; flash_clk = 1; - #50; + #5; flash_clk = 0; $display("-- QSPI SDR %02x --", data); - #50; + #5; end endtask @@ -170,26 +172,28 @@ module testbench; flash_io2_oe = 0; flash_io3_oe = 0; - #50; + #5; + flash_clk = 1; rdata[4] = flash_io0; rdata[5] = flash_io1; rdata[6] = flash_io2; rdata[7] = flash_io3; - flash_clk <= 1; - #50; + + #5; flash_clk = 0; - #50; + #5; + flash_clk = 1; rdata[0] = flash_io0; rdata[1] = flash_io1; rdata[2] = flash_io2; rdata[3] = flash_io3; - flash_clk <= 1; - #50; + + #5; flash_clk = 0; $display("-- QSPI SDR -- %02x", rdata); - #50; + #5; end endtask @@ -202,24 +206,23 @@ module testbench; flash_io2_oe = 1; flash_io3_oe = 1; - flash_io0_dout <= data[4]; - flash_io1_dout <= data[5]; - flash_io2_dout <= data[6]; - flash_io3_dout <= data[7]; + flash_io0_dout = data[4]; + flash_io1_dout = data[5]; + flash_io2_dout = data[6]; + flash_io3_dout = data[7]; - #50; + #5; flash_clk = 1; + flash_io0_dout = data[0]; + flash_io1_dout = data[1]; + flash_io2_dout = data[2]; + flash_io3_dout = data[3]; - flash_io0_dout <= data[0]; - flash_io1_dout <= data[1]; - flash_io2_dout <= data[2]; - flash_io3_dout <= data[3]; - - #50; + #5; flash_clk = 0; $display("-- QSPI DDR %02x --", data); - #50; + #5; end endtask @@ -231,22 +234,22 @@ module testbench; flash_io2_oe = 0; flash_io3_oe = 0; - #50; + #5; + flash_clk = 1; rdata[4] = flash_io0; rdata[5] = flash_io1; rdata[6] = flash_io2; rdata[7] = flash_io3; - flash_clk <= 1; - #50; + #5; + flash_clk = 0; rdata[0] = flash_io0; rdata[1] = flash_io1; rdata[2] = flash_io2; rdata[3] = flash_io3; - flash_clk <= 0; $display("-- QSPI DDR -- %02x", rdata); - #50; + #5; end endtask @@ -351,7 +354,7 @@ module testbench; xfer_qspi_ddr_rd; expect(word1[31:24]); xfer_end; - #500; + #5; if (errcount) begin $display("FAIL"); diff --git a/picosoc/spimemio.v b/picosoc/spimemio.v index 6bb4ea6..57347cc 100644 --- a/picosoc/spimemio.v +++ b/picosoc/spimemio.v @@ -27,10 +27,21 @@ module spimemio ( output reg flash_csb, output reg flash_clk, - output flash_io0, - input flash_io1, - input flash_io2, - input flash_io3 + + output reg flash_io0_oe, + output reg flash_io1_oe, + output reg flash_io2_oe, + output reg flash_io3_oe, + + output reg flash_io0_do, + output reg flash_io1_do, + output reg flash_io2_do, + output reg flash_io3_do, + + input flash_io0_di, + input flash_io1_di, + input flash_io2_di, + input flash_io3_di ); parameter ENABLE_PREFETCH = 1; @@ -39,36 +50,49 @@ module spimemio ( reg [31:0] buffer; reg [6:0] xfer_cnt; + reg pulse_csb_8; reg xfer_wait; reg prefetch; - reg spi_mosi; - wire spi_miso; - - assign flash_io0 = spi_mosi; - assign spi_miso = flash_io1; - always @(posedge clk) begin ready <= 0; if (!resetn) begin - flash_csb <= 1; - flash_clk <= 1; - xfer_cnt <= 8; - buffer <= 8'hAB << 24; addr_q_vld <= 0; xfer_wait <= 0; prefetch <= 0; + + xfer_cnt <= 16; + pulse_csb_8 <= 1; + buffer <= {8'h FF, 8'h AB, 16'h 0000}; + + flash_csb <= 1; + flash_clk <= 1; + + flash_io0_oe <= 0; + flash_io1_oe <= 0; + flash_io2_oe <= 0; + flash_io3_oe <= 0; + + flash_io0_do <= 0; + flash_io1_do <= 0; + flash_io2_do <= 0; + flash_io3_do <= 0; end else if (xfer_cnt) begin + if (xfer_cnt == 8 && pulse_csb_8) begin + pulse_csb_8 <= 0; + flash_csb <= 1; + end else if (flash_csb) begin flash_csb <= 0; end else if (flash_clk) begin flash_clk <= 0; - spi_mosi <= buffer[31]; + flash_io0_oe <= 1; + flash_io0_do <= buffer[31]; end else begin flash_clk <= 1; - buffer <= {buffer, spi_miso}; + buffer <= {buffer, flash_io1_di}; xfer_cnt <= xfer_cnt - 1; end end else diff --git a/picosoc/testbench.v b/picosoc/testbench.v index 8d968e0..6b1cae2 100644 --- a/picosoc/testbench.v +++ b/picosoc/testbench.v @@ -17,6 +17,8 @@ * */ +`timescale 1 ns / 1 ps + module testbench; reg clk; always #5 clk = (clk === 1'b0); @@ -37,9 +39,6 @@ module testbench; $stop; end - wire [31:0] gpio_i = 0; - wire [31:0] gpio_o; - wire flash_csb; wire flash_clk;