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 (
.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

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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;