Refactor picosoc flash_io interfaces

This commit is contained in:
Clifford Wolf 2017-08-07 16:27:57 +02:00
parent db2222ec02
commit ff7855900d
5 changed files with 129 additions and 95 deletions

View File

@ -88,31 +88,32 @@ module picosoc (
); );
spimemio spimemio ( spimemio spimemio (
.clk(clk), .clk (clk),
.resetn(resetn), .resetn (resetn),
.valid (mem_valid && mem_addr[31:24] == 8'h 01), .valid (mem_valid && mem_addr[31:24] == 8'h 01),
.ready (spimem_ready), .ready (spimem_ready),
.addr (mem_addr[23:0]), .addr (mem_addr[23:0]),
.rdata (spimem_rdata), .rdata (spimem_rdata),
.flash_csb (flash_csb), .flash_csb (flash_csb ),
.flash_clk (flash_clk), .flash_clk (flash_clk ),
.flash_io0 (flash_io0_do), .flash_io0_oe (flash_io0_oe),
.flash_io1 (flash_io1_di), .flash_io1_oe (flash_io1_oe),
.flash_io2 (flash_io2_di), .flash_io2_oe (flash_io2_oe),
.flash_io3 (flash_io3_di) .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]; reg [31:0] memory [0:MEM_WORDS-1];
always @(posedge clk) begin always @(posedge clk) begin

View File

@ -15,15 +15,23 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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 ( module spiflash (
input csb, input csb,
input clk, input clk,
@ -47,7 +55,6 @@ module spiflash (
reg [7:0] spi_out; reg [7:0] spi_out;
reg spi_io_vld; reg spi_io_vld;
reg qspi_active = 0;
reg powered_up = 0; reg powered_up = 0;
localparam [3:0] mode_spi = 1; localparam [3:0] mode_spi = 1;
@ -69,10 +76,10 @@ module spiflash (
reg io2_dout = 0; reg io2_dout = 0;
reg io3_dout = 0; reg io3_dout = 0;
assign io0 = io0_oe ? io0_dout : 1'bz; assign #1 io0 = io0_oe ? io0_dout : 1'bz;
assign io1 = io1_oe ? io1_dout : 1'bz; assign #1 io1 = io1_oe ? io1_dout : 1'bz;
assign io2 = io2_oe ? io2_dout : 1'bz; assign #1 io2 = io2_oe ? io2_dout : 1'bz;
assign io3 = io3_oe ? io3_dout : 1'bz; assign #1 io3 = io3_oe ? io3_dout : 1'bz;
wire io0_delayed; wire io0_delayed;
wire io1_delayed; wire io1_delayed;
@ -105,7 +112,7 @@ module spiflash (
powered_up = 0; powered_up = 0;
if (spi_cmd == 8'h ff) if (spi_cmd == 8'h ff)
qspi_active = 0; xip_cmd = 0;
end end
if (powered_up && spi_cmd == 'h 03) begin if (powered_up && spi_cmd == 'h 03) begin

View File

@ -17,6 +17,8 @@
* *
*/ */
`timescale 1 ns / 1 ps
module testbench; module testbench;
reg flash_csb = 1; reg flash_csb = 1;
reg flash_clk = 0; reg flash_clk = 0;
@ -69,10 +71,10 @@ module testbench;
task xfer_begin; task xfer_begin;
begin begin
#50; #5;
flash_csb = 0; flash_csb = 0;
$display("-- BEGIN"); $display("-- BEGIN");
#50; #5;
end end
endtask endtask
@ -83,17 +85,17 @@ module testbench;
flash_io2_oe = 0; flash_io2_oe = 0;
flash_io3_oe = 0; flash_io3_oe = 0;
#50; #5;
flash_clk = 1; flash_clk = 1;
#50; #5;
flash_clk = 0; flash_clk = 0;
#50; #5;
end end
endtask endtask
task xfer_end; task xfer_end;
begin begin
#50; #5;
flash_csb = 1; flash_csb = 1;
flash_io0_oe = 0; flash_io0_oe = 0;
flash_io1_oe = 0; flash_io1_oe = 0;
@ -101,7 +103,7 @@ module testbench;
flash_io3_oe = 0; flash_io3_oe = 0;
$display("-- END"); $display("-- END");
$display(""); $display("");
#50; #5;
end end
endtask endtask
@ -116,15 +118,15 @@ module testbench;
for (i = 0; i < 8; i=i+1) begin for (i = 0; i < 8; i=i+1) begin
flash_io0_dout = data[7-i]; flash_io0_dout = data[7-i];
#50; #5;
flash_clk = 1;
rdata[7-i] = flash_io1; rdata[7-i] = flash_io1;
flash_clk <= 1; #5;
#50;
flash_clk = 0; flash_clk = 0;
end end
$display("-- SPI SDR %02x %02x", data, rdata); $display("-- SPI SDR %02x %02x", data, rdata);
#50; #5;
end end
endtask endtask
@ -142,23 +144,23 @@ module testbench;
flash_io2_dout = data[6]; flash_io2_dout = data[6];
flash_io3_dout = data[7]; flash_io3_dout = data[7];
#50; #5;
flash_clk = 1; flash_clk = 1;
#50;
flash_clk = 0;
#5;
flash_clk = 0;
flash_io0_dout = data[0]; flash_io0_dout = data[0];
flash_io1_dout = data[1]; flash_io1_dout = data[1];
flash_io2_dout = data[2]; flash_io2_dout = data[2];
flash_io3_dout = data[3]; flash_io3_dout = data[3];
#50; #5;
flash_clk = 1; flash_clk = 1;
#50; #5;
flash_clk = 0; flash_clk = 0;
$display("-- QSPI SDR %02x --", data); $display("-- QSPI SDR %02x --", data);
#50; #5;
end end
endtask endtask
@ -170,26 +172,28 @@ module testbench;
flash_io2_oe = 0; flash_io2_oe = 0;
flash_io3_oe = 0; flash_io3_oe = 0;
#50; #5;
flash_clk = 1;
rdata[4] = flash_io0; rdata[4] = flash_io0;
rdata[5] = flash_io1; rdata[5] = flash_io1;
rdata[6] = flash_io2; rdata[6] = flash_io2;
rdata[7] = flash_io3; rdata[7] = flash_io3;
flash_clk <= 1;
#50; #5;
flash_clk = 0; flash_clk = 0;
#50; #5;
flash_clk = 1;
rdata[0] = flash_io0; rdata[0] = flash_io0;
rdata[1] = flash_io1; rdata[1] = flash_io1;
rdata[2] = flash_io2; rdata[2] = flash_io2;
rdata[3] = flash_io3; rdata[3] = flash_io3;
flash_clk <= 1;
#50; #5;
flash_clk = 0; flash_clk = 0;
$display("-- QSPI SDR -- %02x", rdata); $display("-- QSPI SDR -- %02x", rdata);
#50; #5;
end end
endtask endtask
@ -202,24 +206,23 @@ module testbench;
flash_io2_oe = 1; flash_io2_oe = 1;
flash_io3_oe = 1; flash_io3_oe = 1;
flash_io0_dout <= data[4]; flash_io0_dout = data[4];
flash_io1_dout <= data[5]; flash_io1_dout = data[5];
flash_io2_dout <= data[6]; flash_io2_dout = data[6];
flash_io3_dout <= data[7]; flash_io3_dout = data[7];
#50; #5;
flash_clk = 1; 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]; #5;
flash_io1_dout <= data[1];
flash_io2_dout <= data[2];
flash_io3_dout <= data[3];
#50;
flash_clk = 0; flash_clk = 0;
$display("-- QSPI DDR %02x --", data); $display("-- QSPI DDR %02x --", data);
#50; #5;
end end
endtask endtask
@ -231,22 +234,22 @@ module testbench;
flash_io2_oe = 0; flash_io2_oe = 0;
flash_io3_oe = 0; flash_io3_oe = 0;
#50; #5;
flash_clk = 1;
rdata[4] = flash_io0; rdata[4] = flash_io0;
rdata[5] = flash_io1; rdata[5] = flash_io1;
rdata[6] = flash_io2; rdata[6] = flash_io2;
rdata[7] = flash_io3; rdata[7] = flash_io3;
flash_clk <= 1;
#50; #5;
flash_clk = 0;
rdata[0] = flash_io0; rdata[0] = flash_io0;
rdata[1] = flash_io1; rdata[1] = flash_io1;
rdata[2] = flash_io2; rdata[2] = flash_io2;
rdata[3] = flash_io3; rdata[3] = flash_io3;
flash_clk <= 0;
$display("-- QSPI DDR -- %02x", rdata); $display("-- QSPI DDR -- %02x", rdata);
#50; #5;
end end
endtask endtask
@ -351,7 +354,7 @@ module testbench;
xfer_qspi_ddr_rd; expect(word1[31:24]); xfer_qspi_ddr_rd; expect(word1[31:24]);
xfer_end; xfer_end;
#500; #5;
if (errcount) begin if (errcount) begin
$display("FAIL"); $display("FAIL");

View File

@ -27,10 +27,21 @@ module spimemio (
output reg flash_csb, output reg flash_csb,
output reg flash_clk, output reg flash_clk,
output flash_io0,
input flash_io1, output reg flash_io0_oe,
input flash_io2, output reg flash_io1_oe,
input flash_io3 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; parameter ENABLE_PREFETCH = 1;
@ -39,36 +50,49 @@ module spimemio (
reg [31:0] buffer; reg [31:0] buffer;
reg [6:0] xfer_cnt; reg [6:0] xfer_cnt;
reg pulse_csb_8;
reg xfer_wait; reg xfer_wait;
reg prefetch; reg prefetch;
reg spi_mosi;
wire spi_miso;
assign flash_io0 = spi_mosi;
assign spi_miso = flash_io1;
always @(posedge clk) begin always @(posedge clk) begin
ready <= 0; ready <= 0;
if (!resetn) begin if (!resetn) begin
flash_csb <= 1;
flash_clk <= 1;
xfer_cnt <= 8;
buffer <= 8'hAB << 24;
addr_q_vld <= 0; addr_q_vld <= 0;
xfer_wait <= 0; xfer_wait <= 0;
prefetch <= 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 end else
if (xfer_cnt) begin 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 if (flash_csb) begin
flash_csb <= 0; flash_csb <= 0;
end else end else
if (flash_clk) begin if (flash_clk) begin
flash_clk <= 0; flash_clk <= 0;
spi_mosi <= buffer[31]; flash_io0_oe <= 1;
flash_io0_do <= buffer[31];
end else begin end else begin
flash_clk <= 1; flash_clk <= 1;
buffer <= {buffer, spi_miso}; buffer <= {buffer, flash_io1_di};
xfer_cnt <= xfer_cnt - 1; xfer_cnt <= xfer_cnt - 1;
end end
end else end else

View File

@ -17,6 +17,8 @@
* *
*/ */
`timescale 1 ns / 1 ps
module testbench; module testbench;
reg clk; reg clk;
always #5 clk = (clk === 1'b0); always #5 clk = (clk === 1'b0);
@ -37,9 +39,6 @@ module testbench;
$stop; $stop;
end end
wire [31:0] gpio_i = 0;
wire [31:0] gpio_o;
wire flash_csb; wire flash_csb;
wire flash_clk; wire flash_clk;