mirror of https://github.com/YosysHQ/picorv32.git
Add spimemio QSPI support
This commit is contained in:
parent
89ad9fc85a
commit
53b175d0fb
|
@ -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;
|
||||
next_fetch = 0;
|
||||
|
||||
case (mode)
|
||||
mode_spi: begin
|
||||
flash_io0_oe = 1;
|
||||
flash_io0_do = obuffer[7];
|
||||
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};
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
fetch_next = (next_count == 0);
|
||||
end
|
||||
endcase
|
||||
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
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue