Line 100... |
Line 100... |
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
//
|
//
|
// `define QSPI_READ_ONLY
|
// `define QSPI_READ_ONLY
|
module eqspiflash(i_clk_200mhz, i_rst,
|
module eqspiflash(i_clk_82mhz, i_rst,
|
// Incoming wishbone connection(s)
|
// Incoming wishbone connection(s)
|
// The two strobe lines allow the data to live on a
|
// The two strobe lines allow the data to live on a
|
// separate part of the master bus from the control
|
// separate part of the master bus from the control
|
// registers. Only one strobe will ever be active at any
|
// registers. Only one strobe will ever be active at any
|
// time, no strobes will ever be active unless i_wb_cyc
|
// time, no strobes will ever be active unless i_wb_cyc
|
Line 118... |
Line 118... |
// Interrupt the CPU
|
// Interrupt the CPU
|
o_interrupt, o_cmd_accepted,
|
o_interrupt, o_cmd_accepted,
|
// Debug the interface
|
// Debug the interface
|
o_dbg);
|
o_dbg);
|
|
|
input i_clk_200mhz, i_rst;
|
input i_clk_82mhz, i_rst;
|
// Wishbone bus inputs
|
// Wishbone bus inputs
|
input i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we;
|
input i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we;
|
input [21:0] i_wb_addr; // 24 bits of addr space
|
input [21:0] i_wb_addr; // 24 bits of addr space
|
input [31:0] i_wb_data;
|
input [31:0] i_wb_data;
|
// Wishbone bus outputs
|
// Wishbone bus outputs
|
Line 140... |
Line 140... |
output reg o_cmd_accepted;
|
output reg o_cmd_accepted;
|
//
|
//
|
output wire [31:0] o_dbg;
|
output wire [31:0] o_dbg;
|
|
|
initial o_cmd_accepted = 1'b0;
|
initial o_cmd_accepted = 1'b0;
|
always @(posedge i_clk_200mhz)
|
always @(posedge i_clk_82mhz)
|
o_cmd_accepted=((i_wb_data_stb)||(i_wb_ctrl_stb))&&(~o_wb_stall);
|
o_cmd_accepted=((i_wb_data_stb)||(i_wb_ctrl_stb))&&(~o_wb_stall);
|
//
|
//
|
// lleqspi
|
// lleqspi
|
//
|
//
|
// Providing the low-level SPI interface
|
// Providing the low-level SPI interface
|
Line 152... |
Line 152... |
reg spi_wr, spi_hold, spi_spd, spi_dir, spi_recycle;
|
reg spi_wr, spi_hold, spi_spd, spi_dir, spi_recycle;
|
reg [31:0] spi_word;
|
reg [31:0] spi_word;
|
reg [1:0] spi_len;
|
reg [1:0] spi_len;
|
wire [31:0] spi_out;
|
wire [31:0] spi_out;
|
wire spi_valid, spi_busy, spi_stopped;
|
wire spi_valid, spi_busy, spi_stopped;
|
lleqspi lowlvl(i_clk_200mhz, spi_wr, spi_hold, spi_word, spi_len,
|
lleqspi lowlvl(i_clk_82mhz, spi_wr, spi_hold, spi_word, spi_len,
|
spi_spd, spi_dir, spi_recycle, spi_out, spi_valid, spi_busy,
|
spi_spd, spi_dir, spi_recycle, spi_out, spi_valid, spi_busy,
|
o_qspi_sck, o_qspi_cs_n, o_qspi_mod, o_qspi_dat, i_qspi_dat);
|
o_qspi_sck, o_qspi_cs_n, o_qspi_mod, o_qspi_dat, i_qspi_dat);
|
assign spi_stopped = (o_qspi_cs_n)&&(~spi_busy)&&(~spi_wr);
|
assign spi_stopped = (o_qspi_cs_n)&&(~spi_busy)&&(~spi_wr);
|
|
|
|
|
Line 179... |
Line 179... |
bus_pipewr, bus_endwr, bus_ctreq, bus_idreq,
|
bus_pipewr, bus_endwr, bus_ctreq, bus_idreq,
|
bus_other_req,
|
bus_other_req,
|
// Live parameters
|
// Live parameters
|
w_xip, w_quad, w_idloaded, w_leave_xip;
|
w_xip, w_quad, w_idloaded, w_leave_xip;
|
reg bus_wip;
|
reg bus_wip;
|
qspibus preproc(i_clk_200mhz, i_rst,
|
qspibus preproc(i_clk_82mhz, i_rst,
|
i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb,
|
i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb,
|
i_wb_we, i_wb_addr, i_wb_data,
|
i_wb_we, i_wb_addr, i_wb_data,
|
bus_wb_ack, bus_wb_stall, bus_wb_data,
|
bus_wb_ack, bus_wb_stall, bus_wb_data,
|
bus_wr, bus_addr, bus_data, bus_sector,
|
bus_wr, bus_addr, bus_data, bus_sector,
|
bus_readreq, bus_piperd,
|
bus_readreq, bus_piperd,
|
Line 209... |
Line 209... |
wire rd_spi_wr, rd_spi_hold, rd_spi_spd, rd_spi_dir,
|
wire rd_spi_wr, rd_spi_hold, rd_spi_spd, rd_spi_dir,
|
rd_spi_recycle;
|
rd_spi_recycle;
|
wire [31:0] rd_spi_word;
|
wire [31:0] rd_spi_word;
|
wire [1:0] rd_spi_len;
|
wire [1:0] rd_spi_len;
|
//
|
//
|
readqspi rdproc(i_clk_200mhz, bus_readreq, bus_piperd,
|
readqspi rdproc(i_clk_82mhz, bus_readreq, bus_piperd,
|
bus_other_req,
|
bus_other_req,
|
bus_addr, rd_bus_ack,
|
bus_addr, rd_bus_ack,
|
rd_qspi_req, rd_qspi_grant,
|
rd_qspi_req, rd_qspi_grant,
|
rd_spi_wr, rd_spi_hold, rd_spi_word, rd_spi_len,
|
rd_spi_wr, rd_spi_hold, rd_spi_word, rd_spi_len,
|
rd_spi_spd, rd_spi_dir, rd_spi_recycle,
|
rd_spi_spd, rd_spi_dir, rd_spi_recycle,
|
Line 239... |
Line 239... |
wire [31:0] ew_spi_word;
|
wire [31:0] ew_spi_word;
|
wire [1:0] ew_spi_len;
|
wire [1:0] ew_spi_len;
|
//
|
//
|
wire w_ew_wip;
|
wire w_ew_wip;
|
//
|
//
|
writeqspi ewproc(i_clk_200mhz, bus_wreq,bus_ereq,
|
writeqspi ewproc(i_clk_82mhz, bus_wreq,bus_ereq,
|
bus_pipewr, bus_endwr,
|
bus_pipewr, bus_endwr,
|
bus_addr, bus_data,
|
bus_addr, bus_data,
|
ew_bus_ack, ew_qspi_req, ew_qspi_grant,
|
ew_bus_ack, ew_qspi_req, ew_qspi_grant,
|
ew_spi_wr, ew_spi_hold, ew_spi_word, ew_spi_len,
|
ew_spi_wr, ew_spi_hold, ew_spi_word, ew_spi_len,
|
ew_spi_spd, ew_spi_dir,
|
ew_spi_spd, ew_spi_dir,
|
Line 266... |
Line 266... |
// SPI control wires
|
// SPI control wires
|
wire ct_spi_wr, ct_spi_hold, ct_spi_spd, ct_spi_dir;
|
wire ct_spi_wr, ct_spi_hold, ct_spi_spd, ct_spi_dir;
|
wire [31:0] ct_spi_word;
|
wire [31:0] ct_spi_word;
|
wire [1:0] ct_spi_len;
|
wire [1:0] ct_spi_len;
|
//
|
//
|
ctrlspi ctproc(i_clk_200mhz,
|
ctrlspi ctproc(i_clk_82mhz,
|
bus_ctreq, bus_wr, bus_addr[3:0], bus_data, bus_sector,
|
bus_ctreq, bus_wr, bus_addr[3:0], bus_data, bus_sector,
|
ct_qspi_req, ct_grant,
|
ct_qspi_req, ct_grant,
|
ct_spi_wr, ct_spi_hold, ct_spi_word, ct_spi_len,
|
ct_spi_wr, ct_spi_hold, ct_spi_word, ct_spi_len,
|
ct_spi_spd, ct_spi_dir,
|
ct_spi_spd, ct_spi_dir,
|
spi_out, spi_valid, spi_busy, spi_stopped,
|
spi_out, spi_valid, spi_busy, spi_stopped,
|
Line 297... |
Line 297... |
wire [31:0] id_spi_word;
|
wire [31:0] id_spi_word;
|
wire [1:0] id_spi_len;
|
wire [1:0] id_spi_len;
|
//
|
//
|
wire w_id_wip;
|
wire w_id_wip;
|
//
|
//
|
idotpqspi idotp(i_clk_200mhz, bus_idreq,
|
idotpqspi idotp(i_clk_82mhz, bus_idreq,
|
bus_wr, bus_pipewr, bus_addr[4:0], bus_data, id_bus_ack,
|
bus_wr, bus_pipewr, bus_addr[4:0], bus_data, id_bus_ack,
|
id_qspi_req, id_qspi_grant,
|
id_qspi_req, id_qspi_grant,
|
id_spi_wr, id_spi_hold, id_spi_word, id_spi_len,
|
id_spi_wr, id_spi_hold, id_spi_word, id_spi_len,
|
id_spi_spd, id_spi_dir,
|
id_spi_spd, id_spi_dir,
|
spi_out, spi_valid, spi_busy, spi_stopped,
|
spi_out, spi_valid, spi_busy, spi_stopped,
|
Line 309... |
Line 309... |
|
|
// Arbitrator
|
// Arbitrator
|
reg owned;
|
reg owned;
|
reg [1:0] owner;
|
reg [1:0] owner;
|
initial owned = 1'b0;
|
initial owned = 1'b0;
|
always @(posedge i_clk_200mhz) // 7 inputs (spi_stopped is the CE)
|
always @(posedge i_clk_82mhz) // 7 inputs (spi_stopped is the CE)
|
if ((~owned)&&(spi_stopped))
|
if ((~owned)&&(spi_stopped))
|
begin
|
begin
|
casez({rd_qspi_req,ew_qspi_req,id_qspi_req,ct_qspi_req})
|
casez({rd_qspi_req,ew_qspi_req,id_qspi_req,ct_qspi_req})
|
4'b1???: begin owned<= 1'b1; owner <= 2'b00; end
|
4'b1???: begin owned<= 1'b1; owner <= 2'b00; end
|
4'b01??: begin owned<= 1'b1; owner <= 2'b01; end
|
4'b01??: begin owned<= 1'b1; owner <= 2'b01; end
|
Line 336... |
Line 336... |
assign ew_qspi_grant = (owned)&&(owner == 2'b01);
|
assign ew_qspi_grant = (owned)&&(owner == 2'b01);
|
assign id_qspi_grant = (owned)&&(owner == 2'b10);
|
assign id_qspi_grant = (owned)&&(owner == 2'b10);
|
assign ct_grant = (owned)&&(owner == 2'b11);
|
assign ct_grant = (owned)&&(owner == 2'b11);
|
|
|
// Module controller
|
// Module controller
|
always @(posedge i_clk_200mhz)
|
always @(posedge i_clk_82mhz)
|
case(owner)
|
case(owner)
|
2'b00: begin
|
2'b00: begin
|
spi_wr <= (owned)&&(rd_spi_wr);
|
spi_wr <= (owned)&&(rd_spi_wr);
|
spi_hold <= rd_spi_hold;
|
spi_hold <= rd_spi_hold;
|
spi_word <= rd_spi_word;
|
spi_word <= rd_spi_word;
|
Line 380... |
Line 380... |
|
|
reg last_wip;
|
reg last_wip;
|
initial bus_wip = 1'b0;
|
initial bus_wip = 1'b0;
|
initial last_wip = 1'b0;
|
initial last_wip = 1'b0;
|
initial o_interrupt = 1'b0;
|
initial o_interrupt = 1'b0;
|
always @(posedge i_clk_200mhz)
|
always @(posedge i_clk_82mhz)
|
begin
|
begin
|
bus_wip <= w_ew_wip || w_id_wip;
|
bus_wip <= w_ew_wip || w_id_wip;
|
last_wip <= bus_wip;
|
last_wip <= bus_wip;
|
o_interrupt <= ((~bus_wip)&&(last_wip));
|
o_interrupt <= ((~bus_wip)&&(last_wip));
|
end
|
end
|
|
|
|
|
// Now, let's return values onto the wb bus
|
// Now, let's return values onto the wb bus
|
always @(posedge i_clk_200mhz)
|
always @(posedge i_clk_82mhz)
|
begin
|
begin
|
// Ack our internal bus controller. This means the command was
|
// Ack our internal bus controller. This means the command was
|
// accepted, and the bus can go on to looking for the next
|
// accepted, and the bus can go on to looking for the next
|
// command. It controls the i_wb_stall line, just not the
|
// command. It controls the i_wb_stall line, just not the
|
// i_wb_ack line.
|
// i_wb_ack line.
|
Line 449... |
Line 449... |
|
|
|
|
//
|
//
|
reg pending, lcl_wrreq, lcl_ctreq, lcl_ack, ack, wp_err, wp;
|
reg pending, lcl_wrreq, lcl_ctreq, lcl_ack, ack, wp_err, wp;
|
reg lcl_reg;
|
reg lcl_reg;
|
reg [14:0] esector;
|
reg [12:0] esector;
|
reg [21:0] next_addr;
|
reg [21:0] next_addr;
|
|
|
|
|
reg pipeable;
|
reg pipeable;
|
reg same_page;
|
reg same_page;
|
Line 503... |
Line 503... |
|
|
ctreg_stb <= (i_ctrl_stb)&&(~o_wb_stall)&&(i_addr[4:0]==5'h00)&&(~pending)
|
ctreg_stb <= (i_ctrl_stb)&&(~o_wb_stall)&&(i_addr[4:0]==5'h00)&&(~pending)
|
||(pending)&&(ctreg_stb)&&(~lcl_ack)&&(~i_ack);
|
||(pending)&&(ctreg_stb)&&(~lcl_ack)&&(~i_ack);
|
if (~o_wb_stall)
|
if (~o_wb_stall)
|
begin // Bus command accepted!
|
begin // Bus command accepted!
|
|
if (i_data_stb)
|
|
next_addr <= i_addr + 22'h1;
|
if ((i_data_stb)||(i_ctrl_stb))
|
if ((i_data_stb)||(i_ctrl_stb))
|
begin
|
begin
|
pending <= 1'b1;
|
pending <= 1'b1;
|
o_addr <= i_addr;
|
o_addr <= i_addr;
|
o_data <= i_data;
|
o_data <= i_data;
|
o_wr <= i_we;
|
o_wr <= i_we;
|
next_addr <= i_addr + 22'h1;
|
|
end
|
end
|
|
|
if ((i_data_stb)&&(~i_we))
|
if ((i_data_stb)&&(~i_we))
|
o_readreq <= 1'b1;
|
o_readreq <= 1'b1;
|
|
|
Line 558... |
Line 559... |
o_idreq <= 1'b0;
|
o_idreq <= 1'b0;
|
lcl_ctreq <= 1'b0;
|
lcl_ctreq <= 1'b0;
|
lcl_wrreq <= 1'b0;
|
lcl_wrreq <= 1'b0;
|
end
|
end
|
|
|
if ((i_data_stb)&&(~o_wb_stall))
|
if ((i_data_stb)&&((~o_wb_stall)||(i_ack)))
|
o_piperd <= ((~i_we)&&(~o_wb_stall)&&(pipeable)&&(i_addr == next_addr));
|
o_piperd <= ((~i_we)&&(pipeable)&&(i_addr == next_addr));
|
else if ((i_ack)||(((i_ctrl_stb)||(i_data_stb))&&(~o_wb_stall)))
|
else if ((i_ack)&&(~i_data_stb))
|
o_piperd <= 1'b0;
|
o_piperd <= 1'b0;
|
if ((i_data_stb)&&(~o_wb_stall))
|
if ((i_data_stb)&&(~o_wb_stall))
|
pipeable <= (~i_we);
|
pipeable <= (~i_we);
|
else if ((i_ctrl_stb)&&(~o_wb_stall))
|
else if ((i_ctrl_stb)&&(~o_wb_stall))
|
pipeable <= 1'b0;
|
pipeable <= 1'b0;
|
Line 580... |
Line 581... |
always @(posedge i_clk)
|
always @(posedge i_clk)
|
last_wip <= i_wip;
|
last_wip <= i_wip;
|
wire new_req;
|
wire new_req;
|
assign new_req = (pending)&&(~last_pending);
|
assign new_req = (pending)&&(~last_pending);
|
|
|
initial esector = 15'h00;
|
initial esector = 13'h00;
|
initial o_wrreq = 1'b0;
|
initial o_wrreq = 1'b0;
|
initial o_erreq = 1'b0;
|
initial o_erreq = 1'b0;
|
initial wp_err = 1'b0;
|
initial wp_err = 1'b0;
|
initial lcl_ack = 1'b0;
|
initial lcl_ack = 1'b0;
|
initial r_other = 1'b0;
|
initial r_other = 1'b0;
|
Line 610... |
Line 611... |
// Default ACK is always set to zero, unless the following ...
|
// Default ACK is always set to zero, unless the following ...
|
o_wb_ack <= 1'b0;
|
o_wb_ack <= 1'b0;
|
|
|
if (set_sector)
|
if (set_sector)
|
begin
|
begin
|
esector[13:0] <= { o_data[23:14], 4'h0 };
|
esector[11:0] <= { o_data[21:14], 4'h0 };
|
wp <= (o_data[30])&&(new_req)||(wp)&&(~new_req);
|
wp <= (o_data[30])&&(new_req)||(wp)&&(~new_req);
|
esector[14] <= o_data[28]; // Subsector
|
esector[12] <= o_data[28]; // Subsector
|
if (o_data[28])
|
if (o_data[28])
|
begin
|
begin
|
esector[3:0] <= o_data[13:10];
|
esector[3:0] <= o_data[13:10];
|
end
|
end
|
end
|
end
|
Line 676... |
Line 677... |
end
|
end
|
|
|
end
|
end
|
|
|
|
|
assign o_wb_data[31:0] = { i_wip, ~wp, i_quad, esector[14],
|
assign o_wb_data[31:0] = { i_wip, ~wp, i_quad, esector[12],
|
i_idloaded, wp_err, i_xip, i_spi_stopped,
|
i_idloaded, wp_err, i_xip, i_spi_stopped,
|
esector[13:0], 10'h00 };
|
2'b00, esector[11:0], 10'h00 };
|
assign o_sector = { esector[13:0], 8'h00 }; // 22 bits
|
assign o_sector = { 2'b00, esector[11:0], 8'h00 }; // 22 bits
|
assign o_other = (r_other)||(o_idreq);
|
assign o_other = (r_other)||(o_idreq);
|
|
|
endmodule
|
endmodule
|
|
|
|
|
Line 695... |
Line 696... |
`define RD_QUAD_DUMMY 4'h5
|
`define RD_QUAD_DUMMY 4'h5
|
`define RD_QUAD_ADDRESS 4'h6
|
`define RD_QUAD_ADDRESS 4'h6
|
`define RD_XIP 4'h7
|
`define RD_XIP 4'h7
|
`define RD_GO_TO_IDLE 4'h8
|
`define RD_GO_TO_IDLE 4'h8
|
`define RD_GO_TO_XIP 4'h9
|
`define RD_GO_TO_XIP 4'h9
|
|
`define RD_IDLE_QUAD_PORT 4'ha
|
|
|
module readqspi(i_clk, i_readreq, i_piperd, i_other_req, i_addr, o_bus_ack,
|
module readqspi(i_clk, i_readreq, i_piperd, i_other_req, i_addr, o_bus_ack,
|
o_qspi_req, i_grant,
|
o_qspi_req, i_grant,
|
o_spi_wr, o_spi_hold, o_spi_word, o_spi_len,
|
o_spi_wr, o_spi_hold, o_spi_word, o_spi_len,
|
o_spi_spd, o_spi_dir, o_spi_recycle,
|
o_spi_spd, o_spi_dir, o_spi_recycle,
|
Line 743... |
Line 745... |
invalid_ack_pipe <= { invalid_ack_pipe[2:0], accepted };
|
invalid_ack_pipe <= { invalid_ack_pipe[2:0], accepted };
|
case(rd_state)
|
case(rd_state)
|
`RD_IDLE: begin
|
`RD_IDLE: begin
|
r_requested <= 1'b0;
|
r_requested <= 1'b0;
|
o_qspi_req <= 1'b0;
|
o_qspi_req <= 1'b0;
|
o_spi_word <= { ((i_quad)? 8'h6B: 8'h0b), i_addr, 2'b00 };
|
// 0x0b is a fast read, uses all SPI protocol
|
|
// 0x6b is a Quad output fast read, uses SPI cmd,
|
|
// SPI address, QSPI data
|
|
// 0xeb is a Quad I/O fast read, using SPI cmd,
|
|
// QSPI address and data
|
|
o_spi_word <= { ((i_quad)? 8'hEB: 8'h0b), i_addr, 2'b00 };
|
o_spi_wr <= 1'b0;
|
o_spi_wr <= 1'b0;
|
o_spi_dir <= 1'b0;
|
o_spi_dir <= 1'b0;
|
o_spi_spd <= 1'b0;
|
o_spi_spd <= 1'b0;
|
o_spi_len <= 2'b11;
|
o_spi_len <= (i_quad)? 2'b00 : 2'b11;
|
r_xip <= (i_xip)&&(i_quad);
|
r_xip <= (i_xip)&&(i_quad);
|
r_leave_xip <= 1'b0; // Not in it, so can't leave it
|
r_leave_xip <= 1'b0; // Not in it, so can't leave it
|
r_quad <= i_quad;
|
r_quad <= i_quad;
|
if (i_readreq)
|
if (i_readreq)
|
begin
|
begin
|
Line 760... |
Line 767... |
end end
|
end end
|
`RD_IDLE_GET_PORT: begin
|
`RD_IDLE_GET_PORT: begin
|
o_spi_wr <= 1'b1; // Write the address
|
o_spi_wr <= 1'b1; // Write the address
|
o_qspi_req <= 1'b1;
|
o_qspi_req <= 1'b1;
|
if (accepted)
|
if (accepted)
|
|
begin
|
|
rd_state <= (r_quad) ? `RD_IDLE_QUAD_PORT : `RD_SLOW_DUMMY;
|
|
o_spi_word[31:8] <= o_spi_word[23:0];
|
|
end end
|
|
`RD_IDLE_QUAD_PORT: begin
|
|
o_spi_wr <= 1'b1; // Write the command
|
|
o_qspi_req <= 1'b1;
|
|
o_spi_spd <= 1'b1;
|
|
o_spi_dir <= 1'b0;
|
|
o_spi_len <= 2'b10;
|
|
|
|
// We haven't saved our address any where but in the
|
|
// SPI word we just sent. Hence, let's just
|
|
// grab it from there.
|
|
if (accepted)
|
rd_state <= `RD_SLOW_DUMMY;
|
rd_state <= `RD_SLOW_DUMMY;
|
end
|
end
|
`RD_SLOW_DUMMY: begin
|
`RD_SLOW_DUMMY: begin
|
o_spi_wr <= 1'b1; // Write 8 dummy clocks
|
o_spi_wr <= 1'b1; // Write 8 dummy clocks--this is the same for
|
o_qspi_req <= 1'b1;
|
o_qspi_req <= 1'b1; // both Quad I/O, Quad O, and fast-read commands
|
o_spi_dir <= 1'b0;
|
o_spi_dir <= 1'b0;
|
o_spi_spd <= 1'b0;
|
o_spi_spd <= r_quad;
|
o_spi_word[31:24] <= (r_xip) ? 8'h00 : 8'hff;
|
o_spi_word[31:0] <= (r_xip) ? 32'h00 : 32'hffffffff;
|
o_spi_len <= 2'b00; // 8 clocks = 8-bits
|
o_spi_len <= (r_quad)? 2'b11:2'b00; // 8 clocks
|
if (accepted)
|
if (accepted)
|
rd_state <= (r_quad)?`RD_QUAD_READ_DATA
|
rd_state <= (r_quad)?`RD_QUAD_READ_DATA
|
: `RD_SLOW_READ_DATA;
|
: `RD_SLOW_READ_DATA;
|
end
|
end
|
`RD_SLOW_READ_DATA: begin
|
`RD_SLOW_READ_DATA: begin
|
Line 787... |
Line 809... |
r_requested <= (r_requested)||(accepted);
|
r_requested <= (r_requested)||(accepted);
|
if ((i_spi_valid)&&(~o_spi_wr))
|
if ((i_spi_valid)&&(~o_spi_wr))
|
rd_state <= `RD_GO_TO_IDLE;
|
rd_state <= `RD_GO_TO_IDLE;
|
end
|
end
|
`RD_QUAD_READ_DATA: begin
|
`RD_QUAD_READ_DATA: begin
|
o_qspi_req <= 1'b1;
|
o_qspi_req <= 1'b1; // Insist that we keep the port
|
o_spi_dir <= 1'b1;
|
o_spi_dir <= 1'b1; // Read
|
o_spi_spd <= 1'b1;
|
o_spi_spd <= 1'b1; // Read at Quad rates
|
o_spi_len <= 2'b11;
|
o_spi_len <= 2'b11; // Read 4-bytes
|
o_spi_recycle <= (r_leave_xip)? 1'b1: 1'b0;
|
o_spi_recycle <= (r_leave_xip)? 1'b1: 1'b0;
|
invalid_ack_pipe[0] <= (!r_requested);
|
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_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_bus_ack <= (r_requested)&&(accepted)&&(i_piperd)&&(~r_leave_xip);
|
o_spi_wr <= (~r_requested)||(i_piperd);
|
o_spi_wr <= (~r_requested)||(i_piperd);
|
// if (accepted)
|
// if (accepted)
|
// o_spi_wr <= (i_piperd);
|
// o_spi_wr <= (i_piperd);
|
Line 808... |
Line 830... |
end
|
end
|
`RD_QUAD_ADDRESS: begin
|
`RD_QUAD_ADDRESS: begin
|
o_qspi_req <= 1'b1;
|
o_qspi_req <= 1'b1;
|
o_spi_wr <= 1'b1;
|
o_spi_wr <= 1'b1;
|
o_spi_dir <= 1'b0; // Write the address
|
o_spi_dir <= 1'b0; // Write the address
|
o_spi_spd <= 1'b0;
|
o_spi_spd <= 1'b1; // High speed
|
o_spi_word[31:0] <= { i_addr, 2'b00, 8'h00 };
|
o_spi_word[31:0] <= { i_addr, 2'b00, 8'h00 };
|
o_spi_len <= 2'b10; // 24 bits, High speed, 6 clocks
|
o_spi_len <= 2'b10; // 24 bits, High speed, 6 clocks
|
if (accepted)
|
if (accepted)
|
rd_state <= `RD_QUAD_DUMMY;
|
rd_state <= `RD_QUAD_DUMMY;
|
end
|
end
|
Line 831... |
Line 853... |
r_requested <= 1'b0;
|
r_requested <= 1'b0;
|
o_qspi_req <= 1'b1;
|
o_qspi_req <= 1'b1;
|
o_spi_word <= { i_addr, 2'b00, 8'h00 };
|
o_spi_word <= { i_addr, 2'b00, 8'h00 };
|
o_spi_wr <= 1'b0;
|
o_spi_wr <= 1'b0;
|
o_spi_dir <= 1'b0; // Write to SPI
|
o_spi_dir <= 1'b0; // Write to SPI
|
o_spi_spd <= 1'b0;
|
o_spi_spd <= 1'b1; // High speed
|
o_spi_len <= 2'b11;
|
o_spi_len <= 2'b11;
|
r_leave_xip <= i_other_req;
|
r_leave_xip <= i_other_req;
|
r_xip <= (~i_other_req);
|
r_xip <= (~i_other_req);
|
o_bus_ack <= 1'b0;
|
o_bus_ack <= 1'b0;
|
if ((i_readreq)||(i_other_req))
|
if ((i_readreq)||(i_other_req))
|