mirror of https://github.com/YosysHQ/picorv32.git
Add support for QSPI DDR mode, Add SPI MEMIO config reg
This commit is contained in:
parent
53b175d0fb
commit
78f2f5efd2
|
@ -27,3 +27,32 @@ and upload them to a connected iCE40-HX8K Breakout Board.
|
||||||
| [hx8kdemo.v](hx8kdemo.v) | FPGA-based example implementation on iCE40-HX8K Breakout Board |
|
| [hx8kdemo.v](hx8kdemo.v) | FPGA-based example implementation on iCE40-HX8K Breakout Board |
|
||||||
| [hx8kdemo.pcf](hx8kdemo.pcf) | Pin constraints for implementation on iCE40-HX8K Breakout Board |
|
| [hx8kdemo.pcf](hx8kdemo.pcf) | Pin constraints for implementation on iCE40-HX8K Breakout Board |
|
||||||
|
|
||||||
|
### Memory map:
|
||||||
|
|
||||||
|
| Address Range | Description |
|
||||||
|
| ------------------------ | --------------------------------------- |
|
||||||
|
| 0x00000000 .. 0x00FFFFFF | Internal SRAM |
|
||||||
|
| 0x01000000 .. 0x01FFFFFF | External Serial Flash |
|
||||||
|
| 0x02000000 .. 0x02000003 | SPI Flash Controller Config Register |
|
||||||
|
| 0x03000000 .. 0x00FFFFFF | Memory mapped user peripherals |
|
||||||
|
|
||||||
|
The example design (hx8kdemo.v) and generic test bench (testbench.v) have 32
|
||||||
|
GPIO pins mapped to the 32 bit word at address 0x03000000.
|
||||||
|
|
||||||
|
### SPI Flash Controller Config Register:
|
||||||
|
|
||||||
|
| Bit(s) | Description |
|
||||||
|
| -----: | --------------------------------------------------------- |
|
||||||
|
| 31 | MEMIO Enable (reset=1, set to 0 to bit bang SPI commands) |
|
||||||
|
| 30:20 | Reserved (read 0) |
|
||||||
|
| 19:16 | IO Output enable bits in bit bang mode |
|
||||||
|
| 15:14 | Reserved (read 0) |
|
||||||
|
| 13 | Chip select (CS) line in bit bang mode |
|
||||||
|
| 12 | Serial clock line in bit bang mode |
|
||||||
|
| 11:8 | IO data bits in bit bang mode |
|
||||||
|
| 7 | Reserved (read 0) |
|
||||||
|
| 6 | DDR Enable bit (reset=0) |
|
||||||
|
| 5 | QSPI Enable bit (reset=0) |
|
||||||
|
| 4 | Continous Read Enable bit (reset=0) |
|
||||||
|
| 3:0 | Number of QSPI dummy cycles (reset=0) |
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ li x5,0x00008067 # ret
|
||||||
sw x5,196(x0)
|
sw x5,196(x0)
|
||||||
|
|
||||||
# setup gpio address in x5
|
# setup gpio address in x5
|
||||||
li x5,0x02000000
|
li x5,0x03000000
|
||||||
sw x0,0(x5)
|
sw x0,0(x5)
|
||||||
|
|
||||||
# initial entry point into RAM code
|
# initial entry point into RAM code
|
||||||
|
|
|
@ -72,7 +72,7 @@ module hx8kdemo (
|
||||||
gpio_shr <= 0;
|
gpio_shr <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
iomem_ready <= 0;
|
iomem_ready <= 0;
|
||||||
if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 02) begin
|
if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 03) begin
|
||||||
iomem_ready <= 1;
|
iomem_ready <= 1;
|
||||||
iomem_rdata <= gpio;
|
iomem_rdata <= gpio;
|
||||||
if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
|
if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
|
||||||
|
|
|
@ -69,8 +69,12 @@ module picosoc (
|
||||||
assign iomem_addr = mem_addr;
|
assign iomem_addr = mem_addr;
|
||||||
assign iomem_wdata = mem_wdata;
|
assign iomem_wdata = mem_wdata;
|
||||||
|
|
||||||
assign mem_ready = (iomem_valid && iomem_ready) || spimem_ready || ram_ready;
|
wire spimemio_cfgreg_sel = (mem_addr == 32'h 0200_0000);
|
||||||
assign mem_rdata = (iomem_valid && iomem_ready) ? iomem_rdata : spimem_ready ? spimem_rdata : ram_ready ? ram_rdata : 32'h xxxx_xxxx;
|
wire [31:0] spimemio_cfgreg_do;
|
||||||
|
|
||||||
|
assign mem_ready = (iomem_valid && iomem_ready) || spimem_ready || ram_ready || spimemio_cfgreg_sel;
|
||||||
|
assign mem_rdata = (iomem_valid && iomem_ready) ? iomem_rdata : spimem_ready ? spimem_rdata : ram_ready ? ram_rdata :
|
||||||
|
spimemio_cfgreg_sel ? spimemio_cfgreg_do : 32'h xxxx_xxxx;
|
||||||
|
|
||||||
picorv32 #(
|
picorv32 #(
|
||||||
.STACKADDR(STACKADDR),
|
.STACKADDR(STACKADDR),
|
||||||
|
@ -111,7 +115,11 @@ module picosoc (
|
||||||
.flash_io0_di (flash_io0_di),
|
.flash_io0_di (flash_io0_di),
|
||||||
.flash_io1_di (flash_io1_di),
|
.flash_io1_di (flash_io1_di),
|
||||||
.flash_io2_di (flash_io2_di),
|
.flash_io2_di (flash_io2_di),
|
||||||
.flash_io3_di (flash_io3_di)
|
.flash_io3_di (flash_io3_di),
|
||||||
|
|
||||||
|
.cfgreg_we(spimemio_cfgreg_sel ? mem_wstrb : 4'b 0000),
|
||||||
|
.cfgreg_di(mem_wdata),
|
||||||
|
.cfgreg_do(spimemio_cfgreg_do)
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [31:0] memory [0:MEM_WORDS-1];
|
reg [31:0] memory [0:MEM_WORDS-1];
|
||||||
|
|
|
@ -41,12 +41,17 @@ module spimemio (
|
||||||
input flash_io0_di,
|
input flash_io0_di,
|
||||||
input flash_io1_di,
|
input flash_io1_di,
|
||||||
input flash_io2_di,
|
input flash_io2_di,
|
||||||
input flash_io3_di
|
input flash_io3_di,
|
||||||
|
|
||||||
|
input [3:0] cfgreg_we,
|
||||||
|
input [31:0] cfgreg_di,
|
||||||
|
output [31:0] cfgreg_do
|
||||||
);
|
);
|
||||||
reg xfer_resetn;
|
reg xfer_resetn;
|
||||||
reg din_valid;
|
reg din_valid;
|
||||||
wire din_ready;
|
wire din_ready;
|
||||||
reg [7:0] din_data;
|
reg [7:0] din_data;
|
||||||
|
reg [3:0] din_tag;
|
||||||
reg din_cont;
|
reg din_cont;
|
||||||
reg din_qspi;
|
reg din_qspi;
|
||||||
reg din_ddr;
|
reg din_ddr;
|
||||||
|
@ -54,9 +59,9 @@ module spimemio (
|
||||||
|
|
||||||
wire dout_valid;
|
wire dout_valid;
|
||||||
wire [7:0] dout_data;
|
wire [7:0] dout_data;
|
||||||
|
wire [3:0] dout_tag;
|
||||||
|
|
||||||
reg [23:0] buffer;
|
reg [23:0] buffer;
|
||||||
reg [3:0] buffer_wen;
|
|
||||||
|
|
||||||
reg [23:0] rd_addr;
|
reg [23:0] rd_addr;
|
||||||
reg rd_valid;
|
reg rd_valid;
|
||||||
|
@ -66,10 +71,84 @@ module spimemio (
|
||||||
assign ready = valid && (addr == rd_addr) && rd_valid;
|
assign ready = valid && (addr == rd_addr) && rd_valid;
|
||||||
wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
|
wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
|
||||||
|
|
||||||
reg config_ddr = 0;
|
reg softreset;
|
||||||
reg config_qspi = 0;
|
|
||||||
reg config_cont = 0;
|
reg config_en; // cfgreg[31]
|
||||||
reg [3:0] config_dummy = 1;
|
reg [3:0] config_oe; // cfgreg[19:16]
|
||||||
|
reg config_csb; // cfgreg[13]
|
||||||
|
reg config_clk; // cfgref[12]
|
||||||
|
reg [3:0] config_do; // cfgreg[11:8]
|
||||||
|
reg config_ddr; // cfgreg[6]
|
||||||
|
reg config_qspi; // cfgreg[5]
|
||||||
|
reg config_cont; // cfgreg[4]
|
||||||
|
reg [3:0] config_dummy; // cfgreg[3:0]
|
||||||
|
|
||||||
|
assign cfgreg_do[31] = config_en;
|
||||||
|
assign cfgreg_do[30:20] = 0;
|
||||||
|
assign cfgreg_do[19:16] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
|
||||||
|
assign cfgreg_do[15:14] = 0;
|
||||||
|
assign cfgreg_do[13] = flash_csb;
|
||||||
|
assign cfgreg_do[12] = flash_clk;
|
||||||
|
assign cfgreg_do[11:8] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
|
||||||
|
assign cfgreg_do[7] = 0;
|
||||||
|
assign cfgreg_do[6] = config_ddr;
|
||||||
|
assign cfgreg_do[5] = config_qspi;
|
||||||
|
assign cfgreg_do[4] = config_cont;
|
||||||
|
assign cfgreg_do[3:0] = config_dummy;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
softreset <= !config_en || cfgreg_we;
|
||||||
|
if (!resetn) begin
|
||||||
|
softreset <= 1;
|
||||||
|
config_en <= 1;
|
||||||
|
config_csb <= 0;
|
||||||
|
config_clk <= 0;
|
||||||
|
config_oe <= 0;
|
||||||
|
config_do <= 0;
|
||||||
|
config_ddr <= 0;
|
||||||
|
config_qspi <= 0;
|
||||||
|
config_cont <= 0;
|
||||||
|
config_dummy <= 0;
|
||||||
|
end else begin
|
||||||
|
if (cfgreg_we[0]) begin
|
||||||
|
config_ddr <= cfgreg_di[6];
|
||||||
|
config_qspi <= cfgreg_di[5];
|
||||||
|
config_cont <= cfgreg_di[4];
|
||||||
|
config_dummy <= cfgreg_di[3:0];
|
||||||
|
end
|
||||||
|
if (cfgreg_we[1]) begin
|
||||||
|
config_csb <= cfgreg_di[13];
|
||||||
|
config_clk <= cfgreg_di[12];
|
||||||
|
config_do <= cfgreg_di[11:8];
|
||||||
|
end
|
||||||
|
if (cfgreg_we[2]) begin
|
||||||
|
config_oe <= cfgreg_di[19:16];
|
||||||
|
end
|
||||||
|
if (cfgreg_we[3]) begin
|
||||||
|
config_en <= cfgreg_di[31];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire xfer_io0_oe;
|
||||||
|
wire xfer_io1_oe;
|
||||||
|
wire xfer_io2_oe;
|
||||||
|
wire xfer_io3_oe;
|
||||||
|
|
||||||
|
wire xfer_io0_do;
|
||||||
|
wire xfer_io1_do;
|
||||||
|
wire xfer_io2_do;
|
||||||
|
wire xfer_io3_do;
|
||||||
|
|
||||||
|
assign flash_io0_oe = config_en ? xfer_io0_oe : config_oe[0];
|
||||||
|
assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
|
||||||
|
assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
|
||||||
|
assign flash_io3_oe = config_en ? xfer_io3_oe : config_oe[3];
|
||||||
|
|
||||||
|
assign flash_io0_do = config_en ? xfer_io0_do : config_do[0];
|
||||||
|
assign flash_io1_do = config_en ? xfer_io1_do : config_do[1];
|
||||||
|
assign flash_io2_do = config_en ? xfer_io2_do : config_do[2];
|
||||||
|
assign flash_io3_do = config_en ? xfer_io3_do : config_do[3];
|
||||||
|
|
||||||
spimemio_xfer xfer (
|
spimemio_xfer xfer (
|
||||||
.clk (clk ),
|
.clk (clk ),
|
||||||
|
@ -77,22 +156,24 @@ module spimemio (
|
||||||
.din_valid (din_valid ),
|
.din_valid (din_valid ),
|
||||||
.din_ready (din_ready ),
|
.din_ready (din_ready ),
|
||||||
.din_data (din_data ),
|
.din_data (din_data ),
|
||||||
|
.din_tag (din_tag ),
|
||||||
.din_cont (din_cont ),
|
.din_cont (din_cont ),
|
||||||
.din_qspi (din_qspi ),
|
.din_qspi (din_qspi ),
|
||||||
.din_ddr (din_ddr ),
|
.din_ddr (din_ddr ),
|
||||||
.din_rd (din_rd ),
|
.din_rd (din_rd ),
|
||||||
.dout_valid (dout_valid ),
|
.dout_valid (dout_valid ),
|
||||||
.dout_data (dout_data ),
|
.dout_data (dout_data ),
|
||||||
|
.dout_tag (dout_tag ),
|
||||||
.flash_csb (flash_csb ),
|
.flash_csb (flash_csb ),
|
||||||
.flash_clk (flash_clk ),
|
.flash_clk (flash_clk ),
|
||||||
.flash_io0_oe (flash_io0_oe),
|
.flash_io0_oe (xfer_io0_oe),
|
||||||
.flash_io1_oe (flash_io1_oe),
|
.flash_io1_oe (xfer_io1_oe),
|
||||||
.flash_io2_oe (flash_io2_oe),
|
.flash_io2_oe (xfer_io2_oe),
|
||||||
.flash_io3_oe (flash_io3_oe),
|
.flash_io3_oe (xfer_io3_oe),
|
||||||
.flash_io0_do (flash_io0_do),
|
.flash_io0_do (xfer_io0_do),
|
||||||
.flash_io1_do (flash_io1_do),
|
.flash_io1_do (xfer_io1_do),
|
||||||
.flash_io2_do (flash_io2_do),
|
.flash_io2_do (xfer_io2_do),
|
||||||
.flash_io3_do (flash_io3_do),
|
.flash_io3_do (xfer_io3_do),
|
||||||
.flash_io0_di (flash_io0_di),
|
.flash_io0_di (flash_io0_di),
|
||||||
.flash_io1_di (flash_io1_di),
|
.flash_io1_di (flash_io1_di),
|
||||||
.flash_io2_di (flash_io2_di),
|
.flash_io2_di (flash_io2_di),
|
||||||
|
@ -105,20 +186,20 @@ module spimemio (
|
||||||
xfer_resetn <= 1;
|
xfer_resetn <= 1;
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
|
|
||||||
if (!resetn) begin
|
if (!resetn || softreset) begin
|
||||||
state <= 0;
|
state <= 0;
|
||||||
xfer_resetn <= 0;
|
xfer_resetn <= 0;
|
||||||
rd_valid <= 0;
|
rd_valid <= 0;
|
||||||
buffer_wen <= 0;
|
din_tag <= 0;
|
||||||
din_cont <= 0;
|
din_cont <= 0;
|
||||||
din_qspi <= 0;
|
din_qspi <= 0;
|
||||||
din_ddr <= 0;
|
din_ddr <= 0;
|
||||||
din_rd <= 0;
|
din_rd <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (dout_valid && buffer_wen[0]) buffer[ 7: 0] <= dout_data;
|
if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data;
|
||||||
if (dout_valid && buffer_wen[1]) buffer[15: 8] <= dout_data;
|
if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data;
|
||||||
if (dout_valid && buffer_wen[2]) buffer[23:16] <= dout_data;
|
if (dout_valid && dout_tag == 3) buffer[23:16] <= dout_data;
|
||||||
if (dout_valid && buffer_wen[3]) begin
|
if (dout_valid && dout_tag == 4) begin
|
||||||
rdata <= {dout_data, buffer};
|
rdata <= {dout_data, buffer};
|
||||||
rd_addr <= rd_inc ? rd_addr + 4 : addr;
|
rd_addr <= rd_inc ? rd_addr + 4 : addr;
|
||||||
rd_valid <= 1;
|
rd_valid <= 1;
|
||||||
|
@ -126,10 +207,6 @@ module spimemio (
|
||||||
rd_inc <= 1;
|
rd_inc <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dout_valid && buffer_wen) begin
|
|
||||||
buffer_wen <= 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (valid)
|
if (valid)
|
||||||
rd_wait <= 0;
|
rd_wait <= 0;
|
||||||
|
|
||||||
|
@ -137,6 +214,7 @@ module spimemio (
|
||||||
0: begin
|
0: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
din_data <= 8'h ff;
|
din_data <= 8'h ff;
|
||||||
|
din_tag <= 0;
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
state <= 1;
|
state <= 1;
|
||||||
|
@ -151,6 +229,7 @@ module spimemio (
|
||||||
2: begin
|
2: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
din_data <= 8'h ab;
|
din_data <= 8'h ab;
|
||||||
|
din_tag <= 0;
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
state <= 3;
|
state <= 3;
|
||||||
|
@ -165,6 +244,7 @@ module spimemio (
|
||||||
4: begin
|
4: begin
|
||||||
rd_inc <= 0;
|
rd_inc <= 0;
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 0;
|
||||||
case ({config_ddr, config_qspi})
|
case ({config_ddr, config_qspi})
|
||||||
2'b11: din_data <= 8'h ED;
|
2'b11: din_data <= 8'h ED;
|
||||||
2'b01: din_data <= 8'h EB;
|
2'b01: din_data <= 8'h EB;
|
||||||
|
@ -178,6 +258,7 @@ module spimemio (
|
||||||
5: begin
|
5: begin
|
||||||
if (valid && !ready) begin
|
if (valid && !ready) begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 0;
|
||||||
din_data <= addr[23:16];
|
din_data <= addr[23:16];
|
||||||
din_qspi <= config_qspi;
|
din_qspi <= config_qspi;
|
||||||
din_ddr <= config_ddr;
|
din_ddr <= config_ddr;
|
||||||
|
@ -189,6 +270,7 @@ module spimemio (
|
||||||
end
|
end
|
||||||
6: begin
|
6: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 0;
|
||||||
din_data <= addr[15:8];
|
din_data <= addr[15:8];
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
|
@ -197,6 +279,7 @@ module spimemio (
|
||||||
end
|
end
|
||||||
7: begin
|
7: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 0;
|
||||||
din_data <= addr[7:0];
|
din_data <= addr[7:0];
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
|
@ -206,6 +289,7 @@ module spimemio (
|
||||||
end
|
end
|
||||||
8: begin
|
8: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 0;
|
||||||
din_data <= config_cont ? 8'h A5 : 8'h FF;
|
din_data <= config_cont ? 8'h A5 : 8'h FF;
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
din_rd <= 1;
|
din_rd <= 1;
|
||||||
|
@ -216,8 +300,8 @@ module spimemio (
|
||||||
end
|
end
|
||||||
9: begin
|
9: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 1;
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
buffer_wen <= 4'b 0001;
|
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
state <= 10;
|
state <= 10;
|
||||||
end
|
end
|
||||||
|
@ -225,16 +309,16 @@ module spimemio (
|
||||||
10: begin
|
10: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
din_data <= 8'h 00;
|
din_data <= 8'h 00;
|
||||||
|
din_tag <= 2;
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
buffer_wen <= 4'b 0010;
|
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
state <= 11;
|
state <= 11;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
11: begin
|
11: begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 3;
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
buffer_wen <= 4'b 0100;
|
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
state <= 12;
|
state <= 12;
|
||||||
end
|
end
|
||||||
|
@ -242,8 +326,8 @@ module spimemio (
|
||||||
12: begin
|
12: begin
|
||||||
if (!rd_wait || valid) begin
|
if (!rd_wait || valid) begin
|
||||||
din_valid <= 1;
|
din_valid <= 1;
|
||||||
|
din_tag <= 4;
|
||||||
if (din_ready) begin
|
if (din_ready) begin
|
||||||
buffer_wen <= 4'b 1000;
|
|
||||||
din_valid <= 0;
|
din_valid <= 0;
|
||||||
state <= 9;
|
state <= 9;
|
||||||
end
|
end
|
||||||
|
@ -255,7 +339,6 @@ module spimemio (
|
||||||
rd_inc <= 0;
|
rd_inc <= 0;
|
||||||
rd_valid <= 0;
|
rd_valid <= 0;
|
||||||
xfer_resetn <= 0;
|
xfer_resetn <= 0;
|
||||||
buffer_wen <= 0;
|
|
||||||
if (config_cont) begin
|
if (config_cont) begin
|
||||||
state <= 5;
|
state <= 5;
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -275,6 +358,7 @@ module spimemio_xfer (
|
||||||
input din_valid,
|
input din_valid,
|
||||||
output din_ready,
|
output din_ready,
|
||||||
input [7:0] din_data,
|
input [7:0] din_data,
|
||||||
|
input [3:0] din_tag,
|
||||||
input din_cont,
|
input din_cont,
|
||||||
input din_qspi,
|
input din_qspi,
|
||||||
input din_ddr,
|
input din_ddr,
|
||||||
|
@ -282,6 +366,7 @@ module spimemio_xfer (
|
||||||
|
|
||||||
output dout_valid,
|
output dout_valid,
|
||||||
output [7:0] dout_data,
|
output [7:0] dout_data,
|
||||||
|
output [3:0] dout_tag,
|
||||||
|
|
||||||
output reg flash_csb,
|
output reg flash_csb,
|
||||||
output reg flash_clk,
|
output reg flash_clk,
|
||||||
|
@ -310,7 +395,10 @@ module spimemio_xfer (
|
||||||
reg xfer_cont;
|
reg xfer_cont;
|
||||||
reg xfer_qspi;
|
reg xfer_qspi;
|
||||||
reg xfer_ddr;
|
reg xfer_ddr;
|
||||||
|
reg xfer_ddr_q;
|
||||||
reg xfer_rd;
|
reg xfer_rd;
|
||||||
|
reg [3:0] xfer_tag;
|
||||||
|
reg [3:0] xfer_tag_q;
|
||||||
|
|
||||||
reg [7:0] next_obuffer;
|
reg [7:0] next_obuffer;
|
||||||
reg [7:0] next_ibuffer;
|
reg [7:0] next_ibuffer;
|
||||||
|
@ -320,10 +408,16 @@ module spimemio_xfer (
|
||||||
reg next_fetch;
|
reg next_fetch;
|
||||||
reg last_fetch;
|
reg last_fetch;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
xfer_ddr_q <= xfer_ddr;
|
||||||
|
xfer_tag_q <= xfer_tag;
|
||||||
|
end
|
||||||
|
|
||||||
assign din_ready = din_valid && resetn && next_fetch;
|
assign din_ready = din_valid && resetn && next_fetch;
|
||||||
|
|
||||||
assign dout_valid = xfer_ddr ? fetch && !last_fetch : next_fetch && !fetch;
|
assign dout_valid = xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch;
|
||||||
assign dout_data = ibuffer;
|
assign dout_data = ibuffer;
|
||||||
|
assign dout_tag = xfer_tag_q;
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
flash_io0_oe = 0;
|
flash_io0_oe = 0;
|
||||||
|
@ -405,6 +499,7 @@ module spimemio_xfer (
|
||||||
flash_clk <= 0;
|
flash_clk <= 0;
|
||||||
count <= 0;
|
count <= 0;
|
||||||
dummy_count <= 0;
|
dummy_count <= 0;
|
||||||
|
xfer_tag <= 0;
|
||||||
xfer_cont <= 0;
|
xfer_cont <= 0;
|
||||||
xfer_qspi <= 0;
|
xfer_qspi <= 0;
|
||||||
xfer_ddr <= 0;
|
xfer_ddr <= 0;
|
||||||
|
@ -426,12 +521,11 @@ module spimemio_xfer (
|
||||||
flash_csb <= 0;
|
flash_csb <= 0;
|
||||||
flash_clk <= 0;
|
flash_clk <= 0;
|
||||||
|
|
||||||
obuffer <= din_data;
|
|
||||||
// ibuffer <= 8'h 00;
|
|
||||||
|
|
||||||
count <= 8;
|
count <= 8;
|
||||||
dummy_count <= din_rd ? din_data : 0;
|
dummy_count <= din_rd ? din_data : 0;
|
||||||
|
obuffer <= din_data;
|
||||||
|
|
||||||
|
xfer_tag <= din_tag;
|
||||||
xfer_cont <= din_cont;
|
xfer_cont <= din_cont;
|
||||||
xfer_qspi <= din_qspi;
|
xfer_qspi <= din_qspi;
|
||||||
xfer_ddr <= din_ddr;
|
xfer_ddr <= din_ddr;
|
||||||
|
|
|
@ -78,7 +78,7 @@ module testbench;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
iomem_ready <= 0;
|
iomem_ready <= 0;
|
||||||
if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 02) begin
|
if (iomem_valid && !iomem_ready && iomem_addr[31:24] == 8'h 03) begin
|
||||||
iomem_ready <= 1;
|
iomem_ready <= 1;
|
||||||
iomem_rdata <= gpio;
|
iomem_rdata <= gpio;
|
||||||
if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
|
if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
|
||||||
|
|
Loading…
Reference in New Issue