Line 35... |
Line 35... |
// License: GPL, v3, as defined and found on www.gnu.org,
|
// License: GPL, v3, as defined and found on www.gnu.org,
|
// http://www.gnu.org/licenses/gpl.html
|
// http://www.gnu.org/licenses/gpl.html
|
//
|
//
|
//
|
//
|
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
`define QSPI_IDLE 0
|
`define QSPI_IDLE 3'h0
|
`define QSPI_START 1
|
`define QSPI_START 3'h1
|
`define QSPI_BITS 2
|
`define QSPI_BITS 3'h2
|
`define QSPI_READY 3
|
`define QSPI_READY 3'h3
|
`define QSPI_STOP 4
|
`define QSPI_HOLDING 3'h4
|
`define QSPI_STOP_B 5
|
`define QSPI_STOP 3'h5
|
|
`define QSPI_STOP_B 3'h6
|
|
|
// Modes
|
// Modes
|
`define QSPI_MOD_SPI 2'b00
|
`define QSPI_MOD_SPI 2'b00
|
`define QSPI_MOD_QOUT 2'b10
|
`define QSPI_MOD_QOUT 2'b10
|
`define QSPI_MOD_QIN 2'b11
|
`define QSPI_MOD_QIN 2'b11
|
Line 264... |
Line 265... |
o_busy <= 1'b1;
|
o_busy <= 1'b1;
|
// This is the state on the last clock (both low and
|
// This is the state on the last clock (both low and
|
// high clocks) of the data. Data is valid during
|
// high clocks) of the data. Data is valid during
|
// this state. Here we chose to either STOP or
|
// this state. Here we chose to either STOP or
|
// continue and transmit more.
|
// continue and transmit more.
|
o_sck <= (i_hold); // Stay here on hold, no clocks
|
o_sck <= (i_hold); // No clocks while holding
|
if((~o_busy)&&(i_wr))// Acknowledge a new request
|
if((~o_busy)&&(i_wr))// Acknowledge a new request
|
begin
|
begin
|
state <= `QSPI_BITS;
|
state <= `QSPI_BITS;
|
o_busy <= 1'b1;
|
o_busy <= 1'b1;
|
o_sck <= 1'b0;
|
o_sck <= 1'b0;
|
Line 301... |
Line 302... |
end else if (o_mod[1])
|
end else if (o_mod[1])
|
begin
|
begin
|
r_input <= { r_input[26:0], i_dat };
|
r_input <= { r_input[26:0], i_dat };
|
o_word <= { r_input[27:0], i_dat };
|
o_word <= { r_input[27:0], i_dat };
|
end
|
end
|
end else if (i_hold)
|
|
begin // Stay here, holding the clock high, if the user
|
|
// has more data, but it isn't ready yet.
|
|
o_busy <= 1'b0;
|
|
end else begin
|
end else begin
|
o_sck <= 1'b1;
|
o_sck <= 1'b1;
|
state <= `QSPI_STOP;
|
state <= (i_hold)?`QSPI_HOLDING : `QSPI_STOP;
|
|
o_busy <= (~i_hold);
|
|
|
// Read a bit upon any transition
|
// Read a bit upon any transition
|
o_valid <= 1'b1;
|
o_valid <= 1'b1;
|
if (~o_mod[1])
|
if (~o_mod[1])
|
begin
|
begin
|
Line 321... |
Line 319... |
begin
|
begin
|
r_input <= { r_input[26:0], i_dat };
|
r_input <= { r_input[26:0], i_dat };
|
o_word <= { r_input[27:0], i_dat };
|
o_word <= { r_input[27:0], i_dat };
|
end
|
end
|
end
|
end
|
|
end else if (state == `QSPI_HOLDING)
|
|
begin
|
|
// We need this state so that the o_valid signal
|
|
// can get strobed with our last result. Otherwise
|
|
// we could just sit in READY waiting for a new command.
|
|
//
|
|
// Incidentally, the change producing this state was
|
|
// the result of a nasty race condition. See the
|
|
// commends in wbqspiflash for more details.
|
|
//
|
|
o_valid <= 1'b0;
|
|
o_cs_n <= 1'b0;
|
|
o_busy <= 1'b0;
|
|
if((~o_busy)&&(i_wr))// Acknowledge a new request
|
|
begin
|
|
state <= `QSPI_BITS;
|
|
o_busy <= 1'b1;
|
|
o_sck <= 1'b0;
|
|
|
|
// Read the new request off the bus
|
|
r_spd <= i_spd;
|
|
r_dir <= i_dir;
|
|
// Set up the first bits on the bus
|
|
o_mod<=(i_spd)?{ 1'b1, i_dir } : `QSPI_MOD_SPI;
|
|
if (i_spd)
|
|
begin
|
|
o_dat <= i_word[31:28];
|
|
r_word <= { i_word[27:0], 4'h0 };
|
|
spi_len<= { 1'b0, i_len, 3'b100 };
|
|
end else begin
|
|
o_dat <= { 3'b110, i_word[31] };
|
|
r_word <= { i_word[30:0], 1'b0 };
|
|
spi_len<= { 1'b0, i_len, 3'b111 };
|
|
end
|
|
end else begin
|
|
o_sck <= 1'b1;
|
|
state <= (i_hold)?`QSPI_HOLDING : `QSPI_STOP;
|
|
o_busy <= (~i_hold);
|
|
end
|
end else if (state == `QSPI_STOP)
|
end else if (state == `QSPI_STOP)
|
begin
|
begin
|
o_sck <= 1'b1; // Stop the clock
|
o_sck <= 1'b1; // Stop the clock
|
o_valid <= 1'b0; // Output may have just been valid, but no more
|
o_valid <= 1'b0; // Output may have just been valid, but no more
|
o_busy <= 1'b1; // Still busy till port is clear
|
o_busy <= 1'b1; // Still busy till port is clear
|