aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--picosoc/spimemio.v176
1 files changed, 134 insertions, 42 deletions
diff --git a/picosoc/spimemio.v b/picosoc/spimemio.v
index 1535aea..91bbb2f 100644
--- a/picosoc/spimemio.v
+++ b/picosoc/spimemio.v
@@ -66,6 +66,11 @@ module spimemio (
assign ready = valid && (addr == rd_addr) && rd_valid;
wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
+ reg config_ddr = 0;
+ reg config_qspi = 0;
+ reg config_cont = 0;
+ reg [3:0] config_dummy = 1;
+
spimemio_xfer xfer (
.clk (clk ),
.resetn (xfer_resetn ),
@@ -99,7 +104,6 @@ module spimemio (
always @(posedge clk) begin
xfer_resetn <= 1;
din_valid <= 0;
- din_data <= 8'h 00;
if (!resetn) begin
state <= 0;
@@ -133,8 +137,10 @@ module spimemio (
0: begin
din_valid <= 1;
din_data <= 8'h ff;
- if (din_ready)
+ if (din_ready) begin
+ din_valid <= 0;
state <= 1;
+ end
end
1: begin
if (dout_valid) begin
@@ -145,8 +151,10 @@ module spimemio (
2: begin
din_valid <= 1;
din_data <= 8'h ab;
- if (din_ready)
+ if (din_ready) begin
+ din_valid <= 0;
state <= 3;
+ end
end
3: begin
if (dout_valid) begin
@@ -157,43 +165,60 @@ module spimemio (
4: begin
rd_inc <= 0;
din_valid <= 1;
- din_data <= 8'h 03;
- if (din_ready)
+ case ({config_ddr, config_qspi})
+ 2'b11: din_data <= 8'h ED;
+ 2'b01: din_data <= 8'h EB;
+ 2'b00: din_data <= 8'h 03;
+ endcase
+ if (din_ready) begin
+ din_valid <= 0;
state <= 5;
+ end
end
5: begin
if (valid && !ready) begin
din_valid <= 1;
din_data <= addr[23:16];
- if (din_ready)
+ din_qspi <= config_qspi;
+ din_ddr <= config_ddr;
+ if (din_ready) begin
+ din_valid <= 0;
state <= 6;
+ end
end
end
6: begin
din_valid <= 1;
din_data <= addr[15:8];
- if (din_ready)
+ if (din_ready) begin
+ din_valid <= 0;
state <= 7;
+ end
end
7: begin
din_valid <= 1;
din_data <= addr[7:0];
- if (din_ready)
- state <= 8;
+ if (din_ready) begin
+ din_valid <= 0;
+ din_data <= 0;
+ state <= config_qspi ? 8 : 9;
+ end
end
8: begin
din_valid <= 1;
- din_data <= 8'h 00;
+ din_data <= config_cont ? 8'h A5 : 8'h FF;
if (din_ready) begin
- buffer_wen <= 4'b 0001;
+ din_rd <= 1;
+ din_data <= config_dummy;
+ din_valid <= 0;
state <= 9;
end
end
9: begin
din_valid <= 1;
- din_data <= 8'h 00;
if (din_ready) begin
- buffer_wen <= 4'b 0010;
+ buffer_wen <= 4'b 0001;
+ din_valid <= 0;
state <= 10;
end
end
@@ -201,17 +226,26 @@ module spimemio (
din_valid <= 1;
din_data <= 8'h 00;
if (din_ready) begin
- buffer_wen <= 4'b 0100;
+ buffer_wen <= 4'b 0010;
+ din_valid <= 0;
state <= 11;
end
end
11: begin
+ din_valid <= 1;
+ if (din_ready) begin
+ buffer_wen <= 4'b 0100;
+ din_valid <= 0;
+ state <= 12;
+ end
+ end
+ 12: begin
if (!rd_wait || valid) begin
din_valid <= 1;
- din_data <= 8'h 00;
if (din_ready) begin
buffer_wen <= 4'b 1000;
- state <= 8;
+ din_valid <= 0;
+ state <= 9;
end
end
end
@@ -222,7 +256,14 @@ module spimemio (
rd_valid <= 0;
xfer_resetn <= 0;
buffer_wen <= 0;
- state <= 4;
+ if (config_cont) begin
+ state <= 5;
+ end else begin
+ state <= 4;
+ din_qspi <= 0;
+ din_ddr <= 0;
+ end
+ din_rd <= 0;
end
end
end
@@ -260,13 +301,12 @@ module spimemio_xfer (
input flash_io2_di,
input flash_io3_di
);
- localparam [3:0] mode_spi = 0;
- reg [3:0] mode;
-
reg [7:0] obuffer;
reg [7:0] ibuffer;
reg [3:0] count;
+ reg [3:0] dummy_count;
+
reg xfer_cont;
reg xfer_qspi;
reg xfer_ddr;
@@ -276,12 +316,13 @@ module spimemio_xfer (
reg [7:0] next_ibuffer;
reg [3:0] next_count;
- reg fetch_next;
- reg last_fetch_next;
+ reg fetch;
+ reg next_fetch;
+ reg last_fetch;
- assign din_ready = din_valid && resetn && fetch_next;
+ assign din_ready = din_valid && resetn && next_fetch;
- assign dout_valid = fetch_next && !last_fetch_next;
+ assign dout_valid = xfer_ddr ? fetch && !last_fetch : next_fetch && !fetch;
assign dout_data = ibuffer;
always @* begin
@@ -298,34 +339,83 @@ module spimemio_xfer (
next_obuffer = obuffer;
next_ibuffer = ibuffer;
next_count = count;
- fetch_next = 0;
-
- case (mode)
- mode_spi: begin
- flash_io0_oe = 1;
- flash_io0_do = obuffer[7];
+ next_fetch = 0;
+
+ if (dummy_count == 0) begin
+ case ({xfer_ddr, xfer_qspi})
+ 2'b 00: begin
+ flash_io0_oe = 1;
+ flash_io0_do = obuffer[7];
+
+ if (flash_clk) begin
+ next_obuffer = {obuffer[6:0], 1'b 0};
+ next_count = count - |count;
+ end else begin
+ next_ibuffer = {ibuffer[6:0], flash_io1_di};
+ end
- if (flash_clk) begin
- next_obuffer = {obuffer[6:0], 1'b 0};
- next_count = count - |count;
- end else begin
- next_ibuffer = {ibuffer[6:0], flash_io1_di};
+ next_fetch = (next_count == 0);
end
+ 2'b 01: begin
+ flash_io0_oe = !xfer_rd;
+ flash_io1_oe = !xfer_rd;
+ flash_io2_oe = !xfer_rd;
+ flash_io3_oe = !xfer_rd;
+
+ flash_io0_do = obuffer[4];
+ flash_io1_do = obuffer[5];
+ flash_io2_do = obuffer[6];
+ flash_io3_do = obuffer[7];
+
+ if (flash_clk) begin
+ next_obuffer = {obuffer[3:0], 4'b 0000};
+ next_count = count - {|count, 2'b00};
+ end else begin
+ next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
+ end
- fetch_next = (next_count == 0);
- end
- endcase
+ next_fetch = (next_count == 0);
+ end
+ 2'b 11: begin
+ flash_io0_oe = !xfer_rd;
+ flash_io1_oe = !xfer_rd;
+ flash_io2_oe = !xfer_rd;
+ flash_io3_oe = !xfer_rd;
+
+ flash_io0_do = obuffer[4];
+ flash_io1_do = obuffer[5];
+ flash_io2_do = obuffer[6];
+ flash_io3_do = obuffer[7];
+
+ next_obuffer = {obuffer[3:0], 4'b 0000};
+ next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
+ next_count = count - {|count, 2'b00};
+
+ next_fetch = (next_count == 0);
+ end
+ endcase
+ end
end
always @(posedge clk) begin
if (!resetn) begin
- mode <= mode_spi;
- last_fetch_next <= 1;
+ fetch <= 1;
+ last_fetch <= 1;
flash_csb <= 1;
flash_clk <= 0;
count <= 0;
+ dummy_count <= 0;
+ xfer_cont <= 0;
+ xfer_qspi <= 0;
+ xfer_ddr <= 0;
+ xfer_rd <= 0;
end else begin
- last_fetch_next <= fetch_next;
+ fetch <= next_fetch;
+ last_fetch <= xfer_ddr ? fetch : 1;
+ if (dummy_count) begin
+ flash_clk <= !flash_clk && !flash_csb;
+ dummy_count <= dummy_count - flash_clk;
+ end else
if (count) begin
flash_clk <= !flash_clk && !flash_csb;
obuffer <= next_obuffer;
@@ -337,8 +427,10 @@ module spimemio_xfer (
flash_clk <= 0;
obuffer <= din_data;
- ibuffer <= 8'h 00;
+ // ibuffer <= 8'h 00;
+
count <= 8;
+ dummy_count <= din_rd ? din_data : 0;
xfer_cont <= din_cont;
xfer_qspi <= din_qspi;