URL
https://opencores.org/ocsvn/qspiflash/qspiflash/trunk
Subversion Repositories qspiflash
Compare Revisions
- This comparison shows the changes necessary to convert path
/qspiflash/trunk/rtl
- from Rev 11 to Rev 14
- ↔ Reverse comparison
Rev 11 → Rev 14
/eqspiflash.v
63,7 → 63,8
// Attempted reads before buffer is full will stall bus until |
// buffer is read. Writes act like the asynch-Read-ID command, |
// and will cause the controller to read the buffer. |
// 13.-14. Unused, mapped to Asynch-read-ID |
// 13. Reset Enable |
// 14. Reset Memory |
// 15. OTP control word |
// Write zero to permanently lock OTP |
// Read to determine if OTP is permanently locked |
178,7 → 179,7
bus_pipewr, bus_endwr, bus_ctreq, bus_idreq, |
bus_other_req, |
// Live parameters |
w_xip, w_quad, w_idloaded; |
w_xip, w_quad, w_idloaded, w_leave_xip; |
reg bus_wip; |
qspibus preproc(i_clk_200mhz, i_rst, |
i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, |
218,7 → 219,7
rd_spi_spd, rd_spi_dir, rd_spi_recycle, |
spi_out, spi_valid, |
spi_busy, spi_stopped, rd_data_ack, rd_data, |
w_quad, w_xip); |
w_quad, w_xip, w_leave_xip); |
|
// |
// Write/Erase flash module |
268,12 → 269,12
wire [1:0] ct_spi_len; |
// |
ctrlspi ctproc(i_clk_200mhz, |
bus_ctreq, bus_wr, bus_addr[2:0], bus_data, bus_sector, |
bus_ctreq, bus_wr, bus_addr[3:0], bus_data, bus_sector, |
ct_qspi_req, ct_grant, |
ct_spi_wr, ct_spi_hold, ct_spi_word, ct_spi_len, |
ct_spi_spd, ct_spi_dir, |
spi_out, spi_valid, spi_busy, spi_stopped, |
ct_ack, ct_data_ack, ct_data, w_xip, w_quad); |
ct_ack, ct_data_ack, ct_data, w_leave_xip, w_xip, w_quad); |
assign ct_spi_hold = 1'b0; |
assign ct_spi_spd = 1'b0; |
|
504,6 → 505,8
||(pending)&&(ctreg_stb)&&(~lcl_ack)&&(~i_ack); |
if (~o_wb_stall) |
begin // Bus command accepted! |
if (i_data_stb) |
next_addr <= i_addr + 22'h1; |
if ((i_data_stb)||(i_ctrl_stb)) |
begin |
pending <= 1'b1; |
510,7 → 513,6
o_addr <= i_addr; |
o_data <= i_data; |
o_wr <= i_we; |
next_addr <= i_addr + 22'h1; |
end |
|
if ((i_data_stb)&&(~i_we)) |
529,14 → 531,14
5'h5: lcl_ctreq <= 1'b1; |
5'h6: lcl_ctreq <= 1'b1; |
5'h7: lcl_ctreq <= 1'b1; |
5'h8: o_idreq <= 1'b1; // ID[0] |
5'h9: o_idreq <= 1'b1; // ID[1] |
5'ha: o_idreq <= 1'b1; // ID[2] |
5'hb: o_idreq <= 1'b1; // ID[3] |
5'hc: o_idreq <= 1'b1; // ID[4] |
5'hd: o_idreq <= 1'b1; // |
5'he: o_idreq <= 1'b1; |
5'hf: o_idreq <= 1'b1; // Program OTP register |
5'h8: o_idreq <= 1'b1; // ID[0] |
5'h9: o_idreq <= 1'b1; // ID[1] |
5'ha: o_idreq <= 1'b1; // ID[2] |
5'hb: o_idreq <= 1'b1; // ID[3] |
5'hc: o_idreq <= 1'b1; // ID[4] |
5'hd: lcl_ctreq <= 1'b1; // |
5'he: lcl_ctreq <= 1'b1; |
5'hf: o_idreq <= 1'b1; // Program OTP register |
default: begin o_idreq <= 1'b1; end |
endcase |
end else if (i_ctrl_stb) |
559,9 → 561,9
lcl_wrreq <= 1'b0; |
end |
|
if ((i_data_stb)&&(~o_wb_stall)) |
o_piperd <= ((~i_we)&&(~o_wb_stall)&&(pipeable)&&(i_addr == next_addr)); |
else if ((i_ack)||(((i_ctrl_stb)||(i_data_stb))&&(~o_wb_stall))) |
if ((i_data_stb)&&((~o_wb_stall)||(i_ack))) |
o_piperd <= ((~i_we)&&(pipeable)&&(i_addr == next_addr)); |
else if ((i_ack)&&(~i_data_stb)) |
o_piperd <= 1'b0; |
if ((i_data_stb)&&(~o_wb_stall)) |
pipeable <= (~i_we); |
581,6 → 583,7
wire new_req; |
assign new_req = (pending)&&(~last_pending); |
|
initial esector = 15'h00; |
initial o_wrreq = 1'b0; |
initial o_erreq = 1'b0; |
initial wp_err = 1'b0; |
612,9 → 615,9
begin |
esector[13:0] <= { o_data[23:14], 4'h0 }; |
wp <= (o_data[30])&&(new_req)||(wp)&&(~new_req); |
esector[14] <= o_data[28]; // Subsector |
if (o_data[28]) |
begin |
esector[14] <= o_data[28]; |
esector[3:0] <= o_data[13:10]; |
end |
end |
701,7 → 704,7
o_spi_wr, o_spi_hold, o_spi_word, o_spi_len, |
o_spi_spd, o_spi_dir, o_spi_recycle, |
i_spi_data, i_spi_valid, i_spi_busy, i_spi_stopped, |
o_data_ack, o_data, i_quad, i_xip); |
o_data_ack, o_data, i_quad, i_xip, o_leave_xip); |
input i_clk; |
input i_readreq, i_piperd, i_other_req; |
input [21:0] i_addr; |
717,6 → 720,7
output reg o_data_ack; |
output reg [31:0] o_data; |
input i_quad, i_xip; |
output wire o_leave_xip; |
|
reg accepted; |
initial accepted = 1'b0; |
786,13 → 790,13
rd_state <= `RD_GO_TO_IDLE; |
end |
`RD_QUAD_READ_DATA: begin |
o_qspi_req <= 1'b1; |
o_spi_dir <= 1'b1; |
o_spi_spd <= 1'b1; |
o_spi_len <= 2'b11; |
o_qspi_req <= 1'b1; // Insist that we keep the port |
o_spi_dir <= 1'b1; // Read |
o_spi_spd <= 1'b1; // Read at Quad rates |
o_spi_len <= 2'b11; // Read 4-bytes |
o_spi_recycle <= (r_leave_xip)? 1'b1: 1'b0; |
invalid_ack_pipe[0] <= (!r_requested); |
r_requested <= (r_requested)||(accepted); |
r_requested <= (r_requested)||(accepted); // Make sure at least one request goes through |
o_data_ack <= (!invalid_ack_pipe[3])&&(i_spi_valid)&&(r_requested)&&(~r_leave_xip); |
o_bus_ack <= (r_requested)&&(accepted)&&(i_piperd)&&(~r_leave_xip); |
o_spi_wr <= (~r_requested)||(i_piperd); |
868,6 → 872,7
end |
|
assign o_spi_hold = 1'b0; |
assign o_leave_xip = r_leave_xip; |
|
endmodule |
|
1119,12 → 1124,13
o_spi_spd, o_spi_dir, |
i_spi_data, i_spi_valid, i_spi_busy, |
i_spi_stopped, |
o_bus_ack, o_data_ack, o_data, o_xip, o_quad); |
o_bus_ack, o_data_ack, o_data, |
i_leave_xip, o_xip, o_quad); |
input i_clk; |
// From the WB bus controller |
input i_req; |
input i_wr; |
input [2:0] i_addr; |
input [3:0] i_addr; |
input [31:0] i_data; |
input [21:0] i_sector_address; |
// To/from the arbiter |
1144,6 → 1150,7
output reg o_bus_ack, o_data_ack; |
output reg [31:0] o_data; |
// Configuration items that we may have configured. |
input wire i_leave_xip; |
output reg o_xip; |
output wire o_quad; |
|
1181,13 → 1188,13
ctcmd_len <= 2'b00; // 8bit command (for all but Lock regs) |
r_ctdat_len <= 1'b0; // 8bit data (read or write) |
ctdat_wr <= i_wr; |
casez({ i_addr[2:0], i_wr, i_data[30] }) |
5'b00010: begin // Write Disable |
casez({ i_addr[3:0], i_wr, i_data[30] }) |
6'b000010: begin // Write Disable |
ctcmd_word[31:24] <= 8'h04; |
ctdat_skip <= 1'b1; |
ctbus_ack <= 1'b0; |
end |
5'b00011: begin // Write enable |
6'b000011: begin // Write enable |
ctcmd_word[31:24] <= 8'h06; |
ctdat_skip <= 1'b1; |
ctbus_ack <= 1'b0; |
1194,7 → 1201,7
end |
// 4'b0010?: begin // Read Status register |
// Moved to defaults section |
5'b0011?: begin // Write Status register (Requires WEL) |
6'b00011?: begin // Write Status register (Requires WEL) |
ctcmd_word[31:24] <= 8'h01; |
`ifdef CT_SAFE |
ctdat_word <= { 6'h00, i_data[1:0], 24'h00 }; |
1202,11 → 1209,11
ctdat_word <= { i_data[7:0], 24'h00 }; |
`endif |
end |
5'b0100?: begin // Read NV-Config register (two bytes) |
6'b00100?: begin // Read NV-Config register (two bytes) |
ctcmd_word[31:24] <= 8'hB5; |
r_ctdat_len <= 1'b1; // 16-bit data |
end |
5'b0101?: begin // Write NV-Config reg (2 bytes, Requires WEL) |
6'b00101?: begin // Write NV-Config reg (2 bytes, Requires WEL) |
ctcmd_word[31:24] <= 8'hB1; |
r_ctdat_len <= 1'b1; // 16-bit data |
`ifdef CT_SAFE |
1215,10 → 1222,10
ctdat_word <= { i_data[15:0], 16'h00 }; |
`endif |
end |
5'b0110?: begin // Read V-Config register |
6'b00110?: begin // Read V-Config register |
ctcmd_word[31:24] <= 8'h85; |
end |
5'b0111?: begin // Write V-Config register (Requires WEL) |
6'b00111?: begin // Write V-Config register (Requires WEL) |
ctcmd_word[31:24] <= 8'h81; |
r_ctdat_len <= 1'b0; // 8-bit data |
`ifdef CT_SAFE |
1226,12 → 1233,12
`else |
ctdat_word <= { i_data[7:0], 24'h00 }; |
`endif |
o_xip <= i_data[3]; |
o_xip <= ~i_data[3]; |
end |
5'b1000?: begin // Read EV-Config register |
6'b01000?: begin // Read EV-Config register |
ctcmd_word[31:24] <= 8'h65; |
end |
5'b1001?: begin // Write EV-Config register (Requires WEL) |
6'b01001?: begin // Write EV-Config register (Requires WEL) |
ctcmd_word[31:24] <= 8'h61; |
// o_quad <= (~i_data[7]); |
`ifdef CT_SAFE |
1240,24 → 1247,32
ctdat_word <= { i_data[7:0], 24'h00 }; |
`endif |
end |
5'b1010?: begin // Read Lock register |
6'b01010?: begin // Read Lock register |
ctcmd_word[31:0] <= { 8'he8, i_sector_address, 2'b00 }; |
ctcmd_len <= 2'b11; |
ctdat_wr <= 1'b0; // Read, not write |
end |
5'b1011?: begin // Write Lock register (Requires WEL) |
6'b01011?: begin // Write Lock register (Requires WEL) |
ctcmd_word[31:0] <= { 8'he5, i_sector_address, 2'b00 }; |
ctcmd_len <= 2'b11; |
ctdat_wr <= 1'b1; // Write |
end |
5'b1100?: begin // Read Flag Status register |
6'b01100?: begin // Read Flag Status register |
ctcmd_word[31:24] <= 8'h70; |
ctdat_wr <= 1'b0; // Read, not write |
end |
5'b1101?: begin // Write/Clear Flag Status register (No WEL required) |
6'b01101?: begin // Write/Clear Flag Status register (No WEL required) |
ctcmd_word[31:24] <= 8'h50; |
ctdat_skip <= 1'b1; |
end |
6'b11011?: begin // RESET_ENABLE (when written to) |
ctcmd_word[31:24] <= 8'h66; |
ctdat_skip <= 1'b1; |
end |
6'b11101?: begin // RESET_MEMORY (when written to) |
ctcmd_word[31:24] <= 8'h99; |
ctdat_skip <= 1'b1; |
end |
default: begin // Default to reading the status register |
ctcmd_word[31:24] <= 8'h05; |
ctdat_wr <= 1'b0; // Read, not write |
1264,7 → 1279,8
r_ctdat_len <= 1'b0; // 8-bit data |
end |
endcase |
end |
end else if (i_leave_xip) |
o_xip <= 1'b0; |
|
assign o_quad = 1'b1; |
|
/llqspi.v
37,6 → 37,10
// |
// |
/////////////////////////////////////////////////////////////////////////// |
// |
// |
`default_nettype none |
// |
`define QSPI_IDLE 3'h0 |
`define QSPI_START 3'h1 |
`define QSPI_BITS 3'h2 |
56,17 → 60,17
o_word, o_valid, o_busy, |
// QSPI interface |
o_sck, o_cs_n, o_mod, o_dat, i_dat); |
input i_clk; |
input wire i_clk; |
// Chip interface |
// Can send info |
// i_dir = 1, i_spd = 0, i_hold = 0, i_wr = 1, |
// i_word = { 1'b0, 32'info to send }, |
// i_len = # of bytes in word-1 |
input i_wr, i_hold; |
input [31:0] i_word; |
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_dir; // 0 -> read, 1 -> write to SPI |
input wire i_wr, i_hold; |
input wire [31:0] i_word; |
input wire [1:0] i_len; // 0=>8bits, 1=>16 bits, 2=>24 bits, 3=>32 bits |
input wire i_spd; // 0 -> normal QPI, 1 -> QSPI |
input wire i_dir; // 0 -> read, 1 -> write to SPI |
output reg [31:0] o_word; |
output reg o_valid, o_busy; |
// Interface with the QSPI lines |
/wbqspiflash.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbspiflash.v |
// |
24,12 → 24,12
// (19 bits): Data (R/w, but expect writes to take a while) |
// |
// |
// Creator: Dan Gisselquist |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015,2017, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
42,7 → 42,7
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// with this program. (It's in the $(ROOT)/doc directory. Run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
50,45 → 50,46
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
`include "flash_config.v" |
`default_nettype none |
// |
`define WBQSPI_RESET 0 |
`define WBQSPI_RESET_QUADMODE 1 |
`define WBQSPI_IDLE 2 |
`define WBQSPI_RDIDLE 3 // Idle, but in fast read mode |
`define WBQSPI_WBDECODE 4 |
`define WBQSPI_RD_DUMMY 5 |
`define WBQSPI_QRD_ADDRESS 6 |
`define WBQSPI_QRD_DUMMY 7 |
`define WBQSPI_READ_CMD 8 |
`define WBQSPI_READ_DATA 9 |
`define WBQSPI_WAIT_TIL_RDIDLE 10 |
`define WBQSPI_READ_ID_CMD 11 |
`define WBQSPI_READ_ID 12 |
`define WBQSPI_READ_STATUS 13 |
`define WBQSPI_READ_CONFIG 14 |
`define WBQSPI_WAIT_TIL_IDLE 15 |
`define WBQSPI_RESET 5'h0 |
`define WBQSPI_RESET_QUADMODE 5'h1 |
`define WBQSPI_IDLE 5'h2 |
`define WBQSPI_RDIDLE 5'h3 // Idle, but in fast read mode |
`define WBQSPI_WBDECODE 5'h4 |
`define WBQSPI_RD_DUMMY 5'h5 |
`define WBQSPI_QRD_ADDRESS 5'h6 |
`define WBQSPI_QRD_DUMMY 5'h7 |
`define WBQSPI_READ_CMD 5'h8 |
`define WBQSPI_READ_DATA 5'h9 |
`define WBQSPI_WAIT_TIL_RDIDLE 5'h10 |
`define WBQSPI_READ_ID_CMD 5'h11 |
`define WBQSPI_READ_ID 5'h12 |
`define WBQSPI_READ_STATUS 5'h13 |
`define WBQSPI_READ_CONFIG 5'h14 |
`define WBQSPI_WAIT_TIL_IDLE 5'h15 |
// |
// |
`ifndef READ_ONLY |
// |
`define WBQSPI_WAIT_WIP_CLEAR 16 |
`define WBQSPI_CHECK_WIP_CLEAR 17 |
`define WBQSPI_CHECK_WIP_DONE 18 |
`define WBQSPI_WEN 19 |
`define WBQSPI_PP 20 // Program page |
`define WBQSPI_QPP 21 // Program page, 4 bit mode |
`define WBQSPI_WR_DATA 22 |
`define WBQSPI_WR_BUS_CYCLE 23 |
`define WBQSPI_WRITE_STATUS 24 |
`define WBQSPI_WRITE_CONFIG 25 |
`define WBQSPI_ERASE_WEN 26 |
`define WBQSPI_ERASE_CMD 27 |
`define WBQSPI_ERASE_BLOCK 28 |
`define WBQSPI_CLEAR_STATUS 29 |
`define WBQSPI_IDLE_CHECK_WIP 30 |
`define WBQSPI_WAIT_WIP_CLEAR 5'h16 |
`define WBQSPI_CHECK_WIP_CLEAR 5'h17 |
`define WBQSPI_CHECK_WIP_DONE 5'h18 |
`define WBQSPI_WEN 5'h19 |
`define WBQSPI_PP 5'h20 // Program page |
`define WBQSPI_QPP 5'h21 // Program page, 4 bit mode |
`define WBQSPI_WR_DATA 5'h22 |
`define WBQSPI_WR_BUS_CYCLE 5'h23 |
`define WBQSPI_WRITE_STATUS 5'h24 |
`define WBQSPI_WRITE_CONFIG 5'h25 |
`define WBQSPI_ERASE_WEN 5'h26 |
`define WBQSPI_ERASE_CMD 5'h27 |
`define WBQSPI_ERASE_BLOCK 5'h28 |
`define WBQSPI_CLEAR_STATUS 5'h29 |
`define WBQSPI_IDLE_CHECK_WIP 5'h30 |
// |
`endif |
|
102,11 → 103,11
o_qspi_sck, o_qspi_cs_n, o_qspi_mod, o_qspi_dat, i_qspi_dat, |
o_interrupt); |
parameter ADDRESS_WIDTH=22; |
input i_clk_100mhz; |
input wire i_clk_100mhz; |
// Wishbone, inputs first |
input i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we; |
input [(ADDRESS_WIDTH-3):0] i_wb_addr; |
input [31:0] i_wb_data; |
input wire i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we; |
input wire [(ADDRESS_WIDTH-3):0] i_wb_addr; |
input wire [31:0] i_wb_data; |
// then outputs |
output reg o_wb_ack; |
output reg o_wb_stall; |
115,7 → 116,7
output wire o_qspi_sck, o_qspi_cs_n; |
output wire [1:0] o_qspi_mod; |
output wire [3:0] o_qspi_dat; |
input [3:0] i_qspi_dat; |
input wire [3:0] i_qspi_dat; |
// Interrupt line |
output reg o_interrupt; |
// output wire [31:0] o_debug; |
146,12 → 147,29
write_protect = 1'b1; |
end |
|
wire [23:0] w_wb_addr; |
generate |
if (ADDRESS_WIDTH>=24) |
assign w_wb_addr = { i_wb_addr[21:0], 2'b00 }; |
else |
assign w_wb_addr = { {(24-ADDRESS_WIDTH){1'b0}}, i_wb_addr, 2'b00 }; |
endgenerate |
|
// Repeat for spif_addr |
reg [(ADDRESS_WIDTH-3):0] spif_addr; |
wire [23:0] w_spif_addr; |
generate |
if (ADDRESS_WIDTH>=24) |
assign w_spif_addr = { spif_addr[21:0], 2'b00 }; |
else |
assign w_spif_addr = { {(24-ADDRESS_WIDTH){1'b0}}, spif_addr, 2'b00 }; |
endgenerate |
|
reg [7:0] last_status; |
reg quad_mode_enabled; |
reg spif_cmd, spif_override; |
reg [(ADDRESS_WIDTH-3):0] spif_addr; |
reg [31:0] spif_data; |
reg [5:0] state; |
reg [4:0] state; |
reg spif_ctrl, spif_req; |
wire [(ADDRESS_WIDTH-17):0] spif_sector; |
assign spif_sector = spif_addr[(ADDRESS_WIDTH-3):14]; |
193,7 → 211,9
begin |
// Okay, so here's the problem: we don't know whether or not |
// the Xilinx loader started us up in Quad Read I/O idle mode. |
// So, thus we need to |
// So, thus we need to toggle the clock and CS_n, with fewer |
// clocks than are necessary to transmit a word. |
// |
// Not ready to handle the bus yet, so stall any requests |
o_wb_ack <= 1'b0; |
o_wb_stall <= 1'b1; |
224,7 → 244,7
spi_spd <= 1'b0; |
spi_dir <= 1'b0; // Write (for now, 'cause of cmd) |
// Data register access |
if ((i_wb_data_stb)&&(i_wb_cyc)) |
if (i_wb_data_stb) |
begin |
|
if (i_wb_we) // Request to write a page |
265,15 → 285,11
spi_wr <= 1'b1; // Write cmd to device |
if (quad_mode_enabled) |
begin |
spi_in <= { 8'heb, |
{(24-ADDRESS_WIDTH){1'b0}}, |
i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 }; |
spi_in <= { 8'heb, w_wb_addr }; |
state <= `WBQSPI_QRD_ADDRESS; |
spi_len <= 2'b00; // single byte, cmd only |
end else begin |
spi_in <= { 8'h0b, |
{(24-ADDRESS_WIDTH){1'b0}}, |
i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 }; |
spi_in <= { 8'h0b, w_wb_addr }; |
state <= `WBQSPI_RD_DUMMY; |
spi_len <= 2'b11; // cmd+addr,32bits |
end |
286,7 → 302,7
o_wb_stall <= 1'b1; |
`endif |
end |
end else if ((i_wb_cyc)&&(i_wb_ctrl_stb)&&(i_wb_we)) |
end else if ((i_wb_ctrl_stb)&&(i_wb_we)) |
begin |
`ifdef READ_ONLY |
o_wb_ack <= 1'b1; |
352,7 → 368,7
end |
endcase |
`endif |
end else if ((i_wb_cyc)&&(i_wb_ctrl_stb)) // &&(~i_wb_we)) |
end else if (i_wb_ctrl_stb) // &&(~i_wb_we)) |
begin |
case(i_wb_addr[1:0]) |
2'b00: begin // Read local register |
428,15 → 444,14
spi_hold <= 1'b0; |
spi_spd<= 1'b1; |
spi_dir <= 1'b0; // Write (for now) |
if ((i_wb_cyc)&&(i_wb_data_stb)&&(~i_wb_we)) |
if ((i_wb_data_stb)&&(~i_wb_we)) |
begin // Continue our read ... send the new address / mode |
o_wb_stall <= 1'b1; |
spi_wr <= 1'b1; |
spi_len <= 2'b10; // Write address, but not mode byte |
spi_in <= { {(24-ADDRESS_WIDTH){1'b0}}, |
i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 }; |
spi_in <= { w_wb_addr, 8'ha0 }; |
state <= `WBQSPI_QRD_DUMMY; |
end else if((i_wb_cyc)&&(i_wb_ctrl_stb)&&(~i_wb_we)&&(i_wb_addr[1:0] == 2'b00)) |
end else if((i_wb_ctrl_stb)&&(~i_wb_we)&&(i_wb_addr[1:0] == 2'b00)) |
begin |
// A local read that doesn't touch the device, so leave |
// the device in its current state |
448,7 → 463,7
quad_mode_enabled, |
{(29-ADDRESS_WIDTH){1'b0}}, |
erased_sector, 14'h000 }; |
end else if((i_wb_cyc)&&((i_wb_ctrl_stb)||(i_wb_data_stb))) |
end else if(((i_wb_ctrl_stb)||(i_wb_data_stb))) |
begin // Need to release the device from quad mode for all else |
o_wb_ack <= 1'b0; |
o_wb_stall <= 1'b1; |
645,8 → 660,7
o_wb_stall <= 1'b1; |
|
spi_wr <= 1'b1; // Non-stop |
spi_in <= { {(24-ADDRESS_WIDTH){1'b0}}, |
spif_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 }; |
spi_in <= { w_spif_addr, 8'ha0 }; |
spi_len <= 2'b10; // Write address, not mode byte |
spi_spd <= 1'b1; |
spi_dir <= 1'b0; // Still writing |
688,7 → 702,7
end else if (state == `WBQSPI_READ_DATA) |
begin |
// Pipelined read support |
spi_wr <=((i_wb_cyc)&&(i_wb_data_stb)&&(~i_wb_we)&&(i_wb_addr== (spif_addr+1))); |
spi_wr <=((i_wb_data_stb)&&(~i_wb_we)&&(i_wb_addr== (spif_addr+1))); |
spi_in <= 32'h00; |
spi_len <= 2'b11; |
// Don't adjust the speed here, it was set in the setup |
712,8 → 726,7
o_wb_ack <= spif_req; |
o_wb_stall <= (~spi_wr); |
// adjust endian-ness to match the PC |
o_wb_data <= { spi_out[7:0], spi_out[15:8], |
spi_out[23:16], spi_out[31:24] }; |
o_wb_data <= spi_out; |
state <= (spi_wr)?`WBQSPI_READ_DATA |
: ((spi_spd) ? `WBQSPI_WAIT_TIL_RDIDLE : `WBQSPI_WAIT_TIL_IDLE); |
spif_req <= spi_wr; |
900,15 → 913,11
spi_wr <= 1'b1; // Write cmd to device |
if (quad_mode_enabled) |
begin |
spi_in <= { 8'heb, |
{(24-ADDRESS_WIDTH){1'b0}}, |
spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 }; |
spi_in <= { 8'heb, w_spif_addr }; |
state <= `WBQSPI_QRD_ADDRESS; |
// spi_len <= 2'b00; // single byte, cmd only |
end else begin |
spi_in <= { 8'h0b, |
{(24-ADDRESS_WIDTH){1'b0}}, |
spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 }; |
spi_in <= { 8'h0b, w_spif_addr }; |
state <= `WBQSPI_RD_DUMMY; |
spi_len <= 2'b11; // Send cmd and addr |
end end |
956,9 → 965,7
begin // We come here under a full stop / full port idle mode |
// Issue our command immediately |
spi_wr <= 1'b1; |
spi_in <= { 8'h02, |
{(24-ADDRESS_WIDTH){1'b0}}, |
spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 }; |
spi_in <= { 8'h02, w_spif_addr }; |
spi_len <= 2'b11; |
spi_hold <= 1'b1; |
spi_spd <= 1'b0; |
974,9 → 981,7
begin // We come here under a full stop / full port idle mode |
// Issue our command immediately |
spi_wr <= 1'b1; |
spi_in <= { 8'h32, |
{(24-ADDRESS_WIDTH){1'b0}}, |
spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 }; |
spi_in <= { 8'h32, w_spif_addr }; |
spi_len <= 2'b11; |
spi_hold <= 1'b1; |
spi_spd <= 1'b0; |
999,11 → 1004,7
o_wb_stall <= 1'b1; |
o_wb_ack <= 1'b0; |
spi_wr <= 1'b1; // write without waiting |
spi_in <= { |
spif_data[ 7: 0], |
spif_data[15: 8], |
spif_data[23:16], |
spif_data[31:24] }; |
spi_in <= spif_data; |
spi_len <= 2'b11; // Write 4 bytes |
spi_hold <= 1'b1; |
if (~spi_busy) |
.
Property changes :
Added: svn:ignore
## -0,0 +1 ##
+obj_dir