Insert delay after release power-down command

This commit is contained in:
Joshua Tyler 2020-06-06 15:49:10 +01:00
parent f9b1beb4cf
commit 0af97a8a94
1 changed files with 37 additions and 22 deletions

View File

@ -204,6 +204,8 @@ module spimemio (
reg [3:0] state; reg [3:0] state;
reg [9:0] wakeup_ctr;
always @(posedge clk) begin always @(posedge clk) begin
xfer_resetn <= 1; xfer_resetn <= 1;
din_valid <= 0; din_valid <= 0;
@ -217,6 +219,7 @@ module spimemio (
din_qspi <= 0; din_qspi <= 0;
din_ddr <= 0; din_ddr <= 0;
din_rd <= 0; din_rd <= 0;
wakeup_ctr <= 0;
end else begin end else begin
if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data; if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data;
if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data; if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data;
@ -264,6 +267,18 @@ module spimemio (
end end
end end
4: begin 4: begin
// SPI flash chips that support power-down typically require
// some time to wake up before they can respond to commands
// (e.g. 3us For W25Q128JVSIM)
// This counter wastes 1024 clock cyles
// This is 102.4us at 10MHz, and 5.12us at 200MHz
// This range should cover all conceivable use cases
if(&wakeup_ctr) begin
state <= 5;
end
wakeup_ctr <= wakeup_ctr + 1;
end
5: begin
rd_inc <= 0; rd_inc <= 0;
din_valid <= 1; din_valid <= 1;
din_tag <= 0; din_tag <= 0;
@ -275,10 +290,10 @@ module spimemio (
endcase endcase
if (din_ready) begin if (din_ready) begin
din_valid <= 0; din_valid <= 0;
state <= 5; state <= 6;
end end
end end
5: begin 6: begin
if (valid && !ready) begin if (valid && !ready) begin
din_valid <= 1; din_valid <= 1;
din_tag <= 0; din_tag <= 0;
@ -287,52 +302,43 @@ module spimemio (
din_ddr <= config_ddr; din_ddr <= config_ddr;
if (din_ready) begin if (din_ready) begin
din_valid <= 0; din_valid <= 0;
state <= 6; state <= 7;
end end
end end
end end
6: begin 7: begin
din_valid <= 1; din_valid <= 1;
din_tag <= 0; 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;
state <= 7; state <= 8;
end end
end end
7: begin 8: begin
din_valid <= 1; din_valid <= 1;
din_tag <= 0; 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;
din_data <= 0; din_data <= 0;
state <= config_qspi || config_ddr ? 8 : 9; state <= config_qspi || config_ddr ? 9 : 10;
end end
end end
8: begin 9: begin
din_valid <= 1; din_valid <= 1;
din_tag <= 0; 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;
din_data <= config_dummy; din_data <= config_dummy;
din_valid <= 0;
state <= 9;
end
end
9: begin
din_valid <= 1;
din_tag <= 1;
if (din_ready) begin
din_valid <= 0; din_valid <= 0;
state <= 10; state <= 10;
end end
end end
10: begin 10: begin
din_valid <= 1; din_valid <= 1;
din_data <= 8'h 00; din_tag <= 1;
din_tag <= 2;
if (din_ready) begin if (din_ready) begin
din_valid <= 0; din_valid <= 0;
state <= 11; state <= 11;
@ -340,19 +346,28 @@ module spimemio (
end end
11: begin 11: begin
din_valid <= 1; din_valid <= 1;
din_tag <= 3; din_data <= 8'h 00;
din_tag <= 2;
if (din_ready) begin if (din_ready) begin
din_valid <= 0; din_valid <= 0;
state <= 12; state <= 12;
end end
end end
12: begin 12: begin
din_valid <= 1;
din_tag <= 3;
if (din_ready) begin
din_valid <= 0;
state <= 13;
end
end
13: begin
if (!rd_wait || valid) begin if (!rd_wait || valid) begin
din_valid <= 1; din_valid <= 1;
din_tag <= 4; din_tag <= 4;
if (din_ready) begin if (din_ready) begin
din_valid <= 0; din_valid <= 0;
state <= 9; state <= 10;
end end
end end
end end
@ -363,9 +378,9 @@ module spimemio (
rd_valid <= 0; rd_valid <= 0;
xfer_resetn <= 0; xfer_resetn <= 0;
if (config_cont) begin if (config_cont) begin
state <= 5; state <= 6;
end else begin end else begin
state <= 4; state <= 5;
din_qspi <= 0; din_qspi <= 0;
din_ddr <= 0; din_ddr <= 0;
end end