Line 63... |
Line 63... |
`define WBQSPI_QRD_ADDRESS 6
|
`define WBQSPI_QRD_ADDRESS 6
|
`define WBQSPI_QRD_DUMMY 7
|
`define WBQSPI_QRD_DUMMY 7
|
`define WBQSPI_READ_CMD 8
|
`define WBQSPI_READ_CMD 8
|
`define WBQSPI_READ_DATA 9
|
`define WBQSPI_READ_DATA 9
|
`define WBQSPI_WAIT_TIL_RDIDLE 10
|
`define WBQSPI_WAIT_TIL_RDIDLE 10
|
`define WBQSPI_READ_ID_CMD 11
|
`define WBQSPI_READ_ID_CMD 11 //
|
`define WBQSPI_READ_ID 12
|
`define WBQSPI_READ_ID 12 //
|
`define WBQSPI_READ_STATUS 13
|
`define WBQSPI_READ_STATUS 13 //
|
`define WBQSPI_READ_CONFIG 14
|
`define WBQSPI_READ_CONFIG 14 //
|
`define WBQSPI_WAIT_TIL_IDLE 15
|
`define WBQSPI_WAIT_TIL_IDLE 15
|
//
|
//
|
//
|
//
|
`ifndef READ_ONLY
|
`ifndef READ_ONLY
|
//
|
//
|
Line 145... |
Line 145... |
dirty_sector = 1'b1;
|
dirty_sector = 1'b1;
|
write_protect = 1'b1;
|
write_protect = 1'b1;
|
end
|
end
|
|
|
reg [7:0] last_status;
|
reg [7:0] last_status;
|
|
reg [9:0] reset_counter;
|
reg quad_mode_enabled;
|
reg quad_mode_enabled;
|
reg spif_cmd, spif_override;
|
reg spif_cmd, spif_override;
|
reg [(ADDRESS_WIDTH-3):0] spif_addr;
|
reg [(ADDRESS_WIDTH-3):0] spif_addr;
|
reg [31:0] spif_data;
|
reg [31:0] spif_data;
|
reg [5:0] state;
|
reg [5:0] state;
|
reg spif_ctrl, spif_req;
|
reg spif_ctrl, spif_req;
|
|
reg alt_cmd, alt_ctrl;
|
wire [(ADDRESS_WIDTH-17):0] spif_sector;
|
wire [(ADDRESS_WIDTH-17):0] spif_sector;
|
assign spif_sector = spif_addr[(ADDRESS_WIDTH-3):14];
|
assign spif_sector = spif_addr[(ADDRESS_WIDTH-3):14];
|
|
|
// assign o_debug = { spi_wr, spi_spd, spi_hold, state, spi_dbg };
|
// assign o_debug = { spi_wr, spi_spd, spi_hold, state, spi_dbg };
|
|
|
Line 163... |
Line 165... |
initial o_wb_stall = 1'b1;
|
initial o_wb_stall = 1'b1;
|
initial spi_wr = 1'b0;
|
initial spi_wr = 1'b0;
|
initial spi_len = 2'b00;
|
initial spi_len = 2'b00;
|
initial quad_mode_enabled = 1'b0;
|
initial quad_mode_enabled = 1'b0;
|
initial o_interrupt = 1'b0;
|
initial o_interrupt = 1'b0;
|
|
initial spif_override = 1'b1;
|
always @(posedge i_clk_100mhz)
|
always @(posedge i_clk_100mhz)
|
begin
|
begin
|
spif_override <= 1'b0;
|
spif_override <= 1'b0;
|
|
alt_cmd <= (reset_counter[9:8]==2'b10)?reset_counter[3]:1'b1; // Toggle CS_n
|
|
alt_ctrl <= (reset_counter[9:8]==2'b10)?reset_counter[0]:1'b1; // Toggle clock too
|
if (state == `WBQSPI_RESET)
|
if (state == `WBQSPI_RESET)
|
begin
|
begin
|
// From a reset, we should
|
// From a reset, we should
|
// Enable the Quad I/O mode
|
// Enable the Quad I/O mode
|
// Disable the Write protection bits in the status register
|
// Disable the Write protection bits in the status register
|
Line 183... |
Line 188... |
spi_dir <= 1'b0;
|
spi_dir <= 1'b0;
|
last_status <= 8'h00;
|
last_status <= 8'h00;
|
state <= `WBQSPI_RESET_QUADMODE;
|
state <= `WBQSPI_RESET_QUADMODE;
|
spif_req <= 1'b0;
|
spif_req <= 1'b0;
|
spif_override <= 1'b1;
|
spif_override <= 1'b1;
|
last_status <= 8'hfc; //
|
last_status <= 8'h00; //
|
|
reset_counter <= 10'h3fc; //
|
// This guarantees that we aren't starting in quad
|
// This guarantees that we aren't starting in quad
|
// I/O mode, where the FPGA configuration scripts may
|
// I/O mode, where the FPGA configuration scripts may
|
// have left us.
|
// have left us.
|
end else if (state == `WBQSPI_RESET_QUADMODE)
|
end else if (state == `WBQSPI_RESET_QUADMODE)
|
begin
|
begin
|
// Okay, so here's the problem: we don't know whether or not
|
// 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.
|
// 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
|
// Not ready to handle the bus yet, so stall any requests
|
o_wb_ack <= 1'b0;
|
o_wb_ack <= 1'b0;
|
o_wb_stall <= 1'b1;
|
o_wb_stall <= 1'b1;
|
|
|
// Do something ...
|
// Do something ...
|
if (last_status == 8'h00)
|
if (reset_counter == 10'h00)
|
begin
|
begin
|
spif_override <= 1'b0;
|
spif_override <= 1'b0;
|
state <= `WBQSPI_IDLE;
|
state <= `WBQSPI_IDLE;
|
|
|
|
// Find out if we can use Quad I/O mode ...
|
|
state <= `WBQSPI_READ_CONFIG;
|
|
spi_wr <= 1'b1;
|
|
spi_len <= 2'b01;
|
|
spi_in <= { 8'h35, 24'h00};
|
|
|
end else begin
|
end else begin
|
last_status <= last_status - 8'h1;
|
reset_counter <= reset_counter - 10'h1;
|
spif_override <= 1'b1;
|
spif_override <= 1'b1;
|
spif_cmd <= last_status[3]; // Toggle CS_n
|
|
spif_ctrl <= last_status[0]; // Toggle clock too
|
|
end
|
end
|
end else if (state == `WBQSPI_IDLE)
|
end else if (state == `WBQSPI_IDLE)
|
begin
|
begin
|
o_interrupt <= 1'b0;
|
o_interrupt <= 1'b0;
|
o_wb_stall <= 1'b0;
|
o_wb_stall <= 1'b0;
|
Line 1182... |
Line 1195... |
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// Command and control during the reset sequence
|
// Command and control during the reset sequence
|
assign o_qspi_cs_n = (spif_override)?spif_cmd :w_qspi_cs_n;
|
assign o_qspi_cs_n = (spif_override)?alt_cmd :w_qspi_cs_n;
|
assign o_qspi_sck = (spif_override)?spif_ctrl:w_qspi_sck;
|
assign o_qspi_sck = (spif_override)?alt_ctrl:w_qspi_sck;
|
assign o_qspi_mod = (spif_override)? 2'b01 :w_qspi_mod;
|
assign o_qspi_mod = (spif_override)? 2'b01 :w_qspi_mod;
|
assign o_qspi_dat = (spif_override)? 4'b00 :w_qspi_dat;
|
assign o_qspi_dat = (spif_override)? 4'b00 :w_qspi_dat;
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|