Line 1... |
Line 1... |
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Filename: llqspi.v
|
// Filename: lleqspi.v
|
//
|
//
|
// Project: Wishbone Controlled Quad SPI Flash Controller
|
// Project: Wishbone Controlled Quad SPI Flash Controller
|
//
|
//
|
// Purpose: Reads/writes a word (user selectable number of bytes) of data
|
// Purpose: Reads/writes a word (user selectable number of bytes) of data
|
// to/from a Quad SPI port. The port is understood to be
|
// to/from a Quad SPI port. The port is understood to be
|
Line 68... |
Line 68... |
input [1:0] i_len; // 0=>8bits, 1=>16 bits, 2=>24 bits, 3=>32 bits
|
input [1:0] i_len; // 0=>8bits, 1=>16 bits, 2=>24 bits, 3=>32 bits
|
input i_spd; // 0 -> normal QPI, 1 -> QSPI
|
input i_spd; // 0 -> normal QPI, 1 -> QSPI
|
input i_dir; // 0 -> read, 1 -> write to SPI
|
input i_dir; // 0 -> read, 1 -> write to SPI
|
input i_recycle; // 0 = 20ns, 1 = 50ns
|
input i_recycle; // 0 = 20ns, 1 = 50ns
|
output reg [31:0] o_word;
|
output reg [31:0] o_word;
|
output wire o_valid;
|
output reg o_valid;
|
output reg o_busy;
|
output reg o_busy;
|
// Interface with the QSPI lines
|
// Interface with the QSPI lines
|
output reg o_sck;
|
output reg o_sck;
|
output reg o_cs_n;
|
output reg o_cs_n;
|
output reg [1:0] o_mod;
|
output reg [1:0] o_mod;
|
Line 81... |
Line 81... |
|
|
// output wire [22:0] o_dbg;
|
// output wire [22:0] o_dbg;
|
// assign o_dbg = { state, spi_len,
|
// assign o_dbg = { state, spi_len,
|
// o_busy, o_valid, o_cs_n, o_sck, o_mod, o_dat, i_dat };
|
// o_busy, o_valid, o_cs_n, o_sck, o_mod, o_dat, i_dat };
|
|
|
// Timing:
|
|
//
|
|
// Tick Clk BSY/WR CS_n BIT/MO STATE
|
|
// 0 1 0/0 1 -
|
|
// 1 1 0/1 1 -
|
|
// 2 1 1/0 0 - QSPI_START
|
|
// 3 0 1/0 0 - QSPI_START
|
|
// 4 0 1/0 0 0 QSPI_BITS
|
|
// 5 1 1/0 0 0 QSPI_BITS
|
|
// 6 0 1/0 0 1 QSPI_BITS
|
|
// 7 1 1/0 0 1 QSPI_BITS
|
|
// 8 0 1/0 0 2 QSPI_BITS
|
|
// 9 1 1/0 0 2 QSPI_BITS
|
|
// 10 0 1/0 0 3 QSPI_BITS
|
|
// 11 1 1/0 0 3 QSPI_BITS
|
|
// 12 0 1/0 0 4 QSPI_BITS
|
|
// 13 1 1/0 0 4 QSPI_BITS
|
|
// 14 0 1/0 0 5 QSPI_BITS
|
|
// 15 1 1/0 0 5 QSPI_BITS
|
|
// 16 0 1/0 0 6 QSPI_BITS
|
|
// 17 1 1/1 0 6 QSPI_BITS
|
|
// 18 0 1/1 0 7 QSPI_READY
|
|
// 19 1 0/1 0 7 QSPI_READY
|
|
// 20 0 1/0/V 0 8 QSPI_BITS
|
|
// 21 1 1/0 0 8 QSPI_BITS
|
|
// 22 0 1/0 0 9 QSPI_BITS
|
|
// 23 1 1/0 0 9 QSPI_BITS
|
|
// 24 0 1/0 0 10 QSPI_BITS
|
|
// 25 1 1/0 0 10 QSPI_BITS
|
|
// 26 0 1/0 0 11 QSPI_BITS
|
|
// 27 1 1/0 0 11 QSPI_BITS
|
|
// 28 0 1/0 0 12 QSPI_BITS
|
|
// 29 1 1/0 0 12 QSPI_BITS
|
|
// 30 0 1/0 0 13 QSPI_BITS
|
|
// 31 1 1/0 0 13 QSPI_BITS
|
|
// 32 0 1/0 0 14 QSPI_BITS
|
|
// 33 1 1/0 0 14 QSPI_BITS
|
|
// 34 0 1/0 0 15 QSPI_READY
|
|
// 35 1 1/0 0 15 QSPI_READY
|
|
// 36 1 1/0/V 0 - QSPI_STOP
|
|
// 37 1 1/0 0 - QSPI_STOPB
|
|
// 38 1 1/0 1 - QSPI_IDLE
|
|
// 39 1 0/0 1 -
|
|
// Now, let's switch from single bit to quad mode
|
|
// 40 1 0/0 1 - QSPI_IDLE
|
|
// 41 1 0/1 1 - QSPI_IDLE
|
|
// 42 1 1/0 0 - QSPI_START
|
|
// 43 0 1/0 0 - QSPI_START
|
|
// 44 0 1/0 0 0 QSPI_BITS
|
|
// 45 1 1/0 0 0 QSPI_BITS
|
|
// 46 0 1/0 0 1 QSPI_BITS
|
|
// 47 1 1/0 0 1 QSPI_BITS
|
|
// 48 0 1/0 0 2 QSPI_BITS
|
|
// 49 1 1/0 0 2 QSPI_BITS
|
|
// 50 0 1/0 0 3 QSPI_BITS
|
|
// 51 1 1/0 0 3 QSPI_BITS
|
|
// 52 0 1/0 0 4 QSPI_BITS
|
|
// 53 1 1/0 0 4 QSPI_BITS
|
|
// 54 0 1/0 0 5 QSPI_BITS
|
|
// 55 1 1/0 0 5 QSPI_BITS
|
|
// 56 0 1/0 0 6 QSPI_BITS
|
|
// 57 1 1/1/QR 0 6 QSPI_BITS
|
|
// 58 0 1/1/QR 0 7 QSPI_READY
|
|
// 59 1 0/1/QR 0 7 QSPI_READY
|
|
// 60 0 1/0/?/V 0 8-11 QSPI_BITS
|
|
// 61 1 1/0/? 0 8-11 QSPI_BITS
|
|
// 62 0 1/0/? 0 12-15 QSPI_BITS
|
|
// 63 1 1/0/? 0 12-15 QSPI_BITS
|
|
// 64 1 1/0/?/V 0 - QSPI_STOP
|
|
// 65 1 1/0/? 0 - QSPI_STOPB
|
|
// 66 1 1/0/? 1 - QSPI_IDLE
|
|
// 67 1 0/0 1 - QSPI_IDLE
|
|
// Now let's try something entirely in Quad read mode, from the
|
|
// beginning
|
|
// 68 1 0/1/QR 1 - QSPI_IDLE
|
|
// 69 1 1/0 0 - QSPI_START
|
|
// 70 0 1/0 0 - QSPI_START
|
|
// 71 0 1/0 0 0-3 QSPI_BITS
|
|
// 72 1 1/0 0 0-3 QSPI_BITS
|
|
// 73 0 1/1/QR 0 4-7 QSPI_BITS
|
|
// 74 1 0/1/QR 0 4-7 QSPI_BITS
|
|
// 75 0 1/?/?/V 0 8-11 QSPI_BITS
|
|
// 76 1 1/?/? 0 8-11 QSPI_BITS
|
|
// 77 0 1/1/QR 0 12-15 QSPI_BITS
|
|
// 78 1 0/1/QR 0 12-15 QSPI_BITS
|
|
// 79 0 1/?/?/V 0 16-19 QSPI_BITS
|
|
// 80 1 1/0 0 16-19 QSPI_BITS
|
|
// 81 0 1/0 0 20-23 QSPI_BITS
|
|
// 82 1 1/0 0 20-23 QSPI_BITS
|
|
// 83 1 1/0/V 0 - QSPI_STOP
|
|
// 84 1 1/0 0 - QSPI_STOPB
|
|
// 85 1 1/0 1 - QSPI_IDLE
|
|
// 86 1 0/0 1 - QSPI_IDLE
|
|
|
|
wire i_miso;
|
wire i_miso;
|
assign i_miso = i_dat[1];
|
assign i_miso = i_dat[1];
|
|
|
// These are used in creating a delayed input.
|
// These are used in creating a delayed input.
|
reg rd_input, rd_spd, rd_valid;
|
reg rd_input, rd_spd, rd_valid;
|
Line 389... |
Line 295... |
o_dat <= 4'hd;
|
o_dat <= 4'hd;
|
end
|
end
|
*/
|
*/
|
end
|
end
|
|
|
|
`define EXTRA_DELAY
|
|
wire rd_input_N, rd_valid_N, r_spd_N;
|
|
`ifdef EXTRA_DELAY
|
|
reg [2:0] rd_input_p, rd_valid_p, r_spd_p;
|
|
always @(posedge i_clk)
|
|
rd_input_p <= { rd_input_p[1:0], rd_input };
|
|
always @(posedge i_clk)
|
|
rd_valid_p <= { rd_valid_p[1:0], rd_valid };
|
|
always @(posedge i_clk)
|
|
r_spd_p <= { r_spd_p[1:0], r_spd };
|
|
|
|
assign rd_input_N = rd_input_p[2];
|
|
assign rd_valid_N = rd_valid_p[2];
|
|
assign r_spd_N = r_spd_p[2];
|
|
`else
|
|
assign rd_input_N = rd_input;
|
|
assign rd_valid_N = rd_valid;
|
|
assign r_spd_N = rd_spd;
|
|
`endif
|
|
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
if ((state == `EQSPI_IDLE)||(rd_valid))
|
// if ((state == `EQSPI_IDLE)||(rd_valid_N))
|
|
if (o_valid)
|
r_input <= 31'h00;
|
r_input <= 31'h00;
|
else if ((rd_input)&&(r_spd))
|
if ((rd_input_N)&&(r_spd_N))
|
r_input <= { r_input[26:0], i_dat };
|
r_input <= { r_input[26:0], i_dat };
|
else if (rd_input)
|
else if (rd_input_N)
|
r_input <= { r_input[29:0], i_miso };
|
r_input <= { r_input[29:0], i_miso };
|
|
|
if ((rd_valid)&&(r_spd))
|
if ((rd_valid_N)&&(r_spd_N))
|
o_word <= { r_input[27:0], i_dat };
|
o_word <= { r_input[27:0], i_dat };
|
else if (rd_valid)
|
else if (rd_valid_N)
|
o_word <= { r_input[30:0], i_miso };
|
o_word <= { r_input[30:0], i_miso };
|
|
o_valid <= rd_valid_N;
|
end
|
end
|
|
|
assign o_valid = rd_valid;
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|