OpenCores
URL https://opencores.org/ocsvn/qspiflash/qspiflash/trunk

Subversion Repositories qspiflash

[/] [qspiflash/] [trunk/] [rtl/] [wbqspiflash.v] - Diff between revs 9 and 14

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 9 Rev 14
Line 1... Line 1...
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    wbspiflash.v
// Filename:    wbspiflash.v
//
//
// Project:     Wishbone Controlled Quad SPI Flash Controller
// Project:     Wishbone Controlled Quad SPI Flash Controller
//
//
Line 22... Line 22...
//      2: Status register (R/w)
//      2: Status register (R/w)
//      3: Read ID (read only)
//      3: Read ID (read only)
//      (19 bits): Data (R/w, but expect writes to take a while)
//      (19 bits): Data (R/w, but expect writes to take a while)
//              
//              
//
//
// Creator:     Dan Gisselquist
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              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
// 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
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
Line 40... Line 40...
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// You should have received a copy of the GNU General Public License along
// 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
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
// <http://www.gnu.org/licenses/> for a copy.
//
//
// 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
//
//
//
//
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
`include "flash_config.v"
`include "flash_config.v"
 
`default_nettype        none
//
//
`define WBQSPI_RESET            0
`define WBQSPI_RESET            5'h0
`define WBQSPI_RESET_QUADMODE   1
`define WBQSPI_RESET_QUADMODE   5'h1
`define WBQSPI_IDLE             2
`define WBQSPI_IDLE             5'h2
`define WBQSPI_RDIDLE           3       // Idle, but in fast read mode
`define WBQSPI_RDIDLE           5'h3    // Idle, but in fast read mode
`define WBQSPI_WBDECODE         4
`define WBQSPI_WBDECODE         5'h4
`define WBQSPI_RD_DUMMY         5
`define WBQSPI_RD_DUMMY         5'h5
`define WBQSPI_QRD_ADDRESS      6
`define WBQSPI_QRD_ADDRESS      5'h6
`define WBQSPI_QRD_DUMMY        7
`define WBQSPI_QRD_DUMMY        5'h7
`define WBQSPI_READ_CMD         8
`define WBQSPI_READ_CMD         5'h8
`define WBQSPI_READ_DATA        9
`define WBQSPI_READ_DATA        5'h9
`define WBQSPI_WAIT_TIL_RDIDLE  10
`define WBQSPI_WAIT_TIL_RDIDLE  5'h10
`define WBQSPI_READ_ID_CMD      11
`define WBQSPI_READ_ID_CMD      5'h11
`define WBQSPI_READ_ID          12
`define WBQSPI_READ_ID          5'h12
`define WBQSPI_READ_STATUS      13
`define WBQSPI_READ_STATUS      5'h13
`define WBQSPI_READ_CONFIG      14
`define WBQSPI_READ_CONFIG      5'h14
`define WBQSPI_WAIT_TIL_IDLE    15
`define WBQSPI_WAIT_TIL_IDLE    5'h15
//
//
//
//
`ifndef READ_ONLY
`ifndef READ_ONLY
//
//
`define WBQSPI_WAIT_WIP_CLEAR   16
`define WBQSPI_WAIT_WIP_CLEAR   5'h16
`define WBQSPI_CHECK_WIP_CLEAR  17
`define WBQSPI_CHECK_WIP_CLEAR  5'h17
`define WBQSPI_CHECK_WIP_DONE   18
`define WBQSPI_CHECK_WIP_DONE   5'h18
`define WBQSPI_WEN              19
`define WBQSPI_WEN              5'h19
`define WBQSPI_PP               20      // Program page
`define WBQSPI_PP               5'h20   // Program page
`define WBQSPI_QPP              21      // Program page, 4 bit mode
`define WBQSPI_QPP              5'h21   // Program page, 4 bit mode
`define WBQSPI_WR_DATA          22
`define WBQSPI_WR_DATA          5'h22
`define WBQSPI_WR_BUS_CYCLE     23
`define WBQSPI_WR_BUS_CYCLE     5'h23
`define WBQSPI_WRITE_STATUS     24
`define WBQSPI_WRITE_STATUS     5'h24
`define WBQSPI_WRITE_CONFIG     25
`define WBQSPI_WRITE_CONFIG     5'h25
`define WBQSPI_ERASE_WEN        26
`define WBQSPI_ERASE_WEN        5'h26
`define WBQSPI_ERASE_CMD        27
`define WBQSPI_ERASE_CMD        5'h27
`define WBQSPI_ERASE_BLOCK      28
`define WBQSPI_ERASE_BLOCK      5'h28
`define WBQSPI_CLEAR_STATUS     29
`define WBQSPI_CLEAR_STATUS     5'h29
`define WBQSPI_IDLE_CHECK_WIP   30
`define WBQSPI_IDLE_CHECK_WIP   5'h30
//
//
`endif
`endif
 
 
module  wbqspiflash(i_clk_100mhz,
module  wbqspiflash(i_clk_100mhz,
                // Internal wishbone connections
                // Internal wishbone connections
Line 100... Line 101...
                o_wb_ack, o_wb_stall, o_wb_data,
                o_wb_ack, o_wb_stall, o_wb_data,
                // Quad Spi connections to the external device
                // Quad Spi connections to the external device
                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,
                o_interrupt);
                o_interrupt);
        parameter       ADDRESS_WIDTH=22;
        parameter       ADDRESS_WIDTH=22;
        input                   i_clk_100mhz;
        input   wire            i_clk_100mhz;
        // Wishbone, inputs first
        // Wishbone, inputs first
        input                   i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we;
        input   wire            i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we;
        input           [(ADDRESS_WIDTH-3):0]    i_wb_addr;
        input   wire    [(ADDRESS_WIDTH-3):0]    i_wb_addr;
        input           [31:0]   i_wb_data;
        input   wire    [31:0]   i_wb_data;
        // then outputs
        // then outputs
        output  reg             o_wb_ack;
        output  reg             o_wb_ack;
        output  reg             o_wb_stall;
        output  reg             o_wb_stall;
        output  reg     [31:0]   o_wb_data;
        output  reg     [31:0]   o_wb_data;
        // Quad SPI control wires
        // Quad SPI control wires
        output  wire            o_qspi_sck, o_qspi_cs_n;
        output  wire            o_qspi_sck, o_qspi_cs_n;
        output  wire    [1:0]    o_qspi_mod;
        output  wire    [1:0]    o_qspi_mod;
        output  wire    [3:0]    o_qspi_dat;
        output  wire    [3:0]    o_qspi_dat;
        input           [3:0]    i_qspi_dat;
        input   wire    [3:0]    i_qspi_dat;
        // Interrupt line
        // Interrupt line
        output  reg             o_interrupt;
        output  reg             o_interrupt;
        // output       wire    [31:0]  o_debug;
        // output       wire    [31:0]  o_debug;
 
 
        reg             spi_wr, spi_hold, spi_spd, spi_dir;
        reg             spi_wr, spi_hold, spi_spd, spi_dir;
Line 144... Line 145...
                erased_sector = 0;
                erased_sector = 0;
                dirty_sector  = 1'b1;
                dirty_sector  = 1'b1;
                write_protect = 1'b1;
                write_protect = 1'b1;
        end
        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     [7:0]    last_status;
        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     [31:0]   spif_data;
        reg     [31:0]   spif_data;
        reg     [5:0]    state;
        reg     [4:0]    state;
        reg             spif_ctrl, spif_req;
        reg             spif_ctrl, spif_req;
        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 191... Line 209...
                        // 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 ...
Line 222... Line 242...
                spi_wr <= 1'b0; // Keep the port idle, unless told otherwise
                spi_wr <= 1'b0; // Keep the port idle, unless told otherwise
                spi_hold <= 1'b0;
                spi_hold <= 1'b0;
                spi_spd  <= 1'b0;
                spi_spd  <= 1'b0;
                spi_dir <= 1'b0; // Write (for now, 'cause of cmd)
                spi_dir <= 1'b0; // Write (for now, 'cause of cmd)
                // Data register access
                // Data register access
                if ((i_wb_data_stb)&&(i_wb_cyc))
                if (i_wb_data_stb)
                begin
                begin
 
 
                        if (i_wb_we) // Request to write a page
                        if (i_wb_we) // Request to write a page
                        begin
                        begin
`ifdef  READ_ONLY
`ifdef  READ_ONLY
Line 263... Line 283...
                                o_wb_ack   <= 1'b0;
                                o_wb_ack   <= 1'b0;
                                o_wb_stall <= 1'b1;
                                o_wb_stall <= 1'b1;
                                spi_wr     <= 1'b1;     // Write cmd to device
                                spi_wr     <= 1'b1;     // Write cmd to device
                                if (quad_mode_enabled)
                                if (quad_mode_enabled)
                                begin
                                begin
                                        spi_in <= { 8'heb,
                                        spi_in <= { 8'heb, w_wb_addr };
                                                {(24-ADDRESS_WIDTH){1'b0}},
 
                                                i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
 
                                        state <= `WBQSPI_QRD_ADDRESS;
                                        state <= `WBQSPI_QRD_ADDRESS;
                                        spi_len    <= 2'b00; // single byte, cmd only
                                        spi_len    <= 2'b00; // single byte, cmd only
                                end else begin
                                end else begin
                                        spi_in <= { 8'h0b,
                                        spi_in <= { 8'h0b, w_wb_addr };
                                                {(24-ADDRESS_WIDTH){1'b0}},
 
                                                i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
 
                                        state <= `WBQSPI_RD_DUMMY;
                                        state <= `WBQSPI_RD_DUMMY;
                                        spi_len    <= 2'b11; // cmd+addr,32bits
                                        spi_len    <= 2'b11; // cmd+addr,32bits
                                end
                                end
`ifndef READ_ONLY
`ifndef READ_ONLY
                        end else begin
                        end else begin
Line 284... Line 300...
                                state <= `WBQSPI_WAIT_WIP_CLEAR;
                                state <= `WBQSPI_WAIT_WIP_CLEAR;
                                o_wb_ack   <= 1'b0;
                                o_wb_ack   <= 1'b0;
                                o_wb_stall <= 1'b1;
                                o_wb_stall <= 1'b1;
`endif
`endif
                        end
                        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
                begin
`ifdef  READ_ONLY
`ifdef  READ_ONLY
                        o_wb_ack   <= 1'b1;
                        o_wb_ack   <= 1'b1;
                        o_wb_stall <= 1'b0;
                        o_wb_stall <= 1'b0;
`else
`else
Line 350... Line 366...
                                o_wb_ack <= 1'b1;
                                o_wb_ack <= 1'b1;
                                o_wb_stall <= 1'b0;
                                o_wb_stall <= 1'b0;
                                end
                                end
                        endcase
                        endcase
`endif
`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
                begin
                        case(i_wb_addr[1:0])
                        case(i_wb_addr[1:0])
                        2'b00: begin // Read local register
                        2'b00: begin // Read local register
                                if (write_in_progress) // Read status
                                if (write_in_progress) // Read status
                                begin// register, is write still in progress?
                                begin// register, is write still in progress?
Line 426... Line 442...
                spif_ctrl  <= (i_wb_ctrl_stb)&&(~i_wb_data_stb);
                spif_ctrl  <= (i_wb_ctrl_stb)&&(~i_wb_data_stb);
                spif_req   <= (i_wb_ctrl_stb)||(i_wb_data_stb);
                spif_req   <= (i_wb_ctrl_stb)||(i_wb_data_stb);
                spi_hold <= 1'b0;
                spi_hold <= 1'b0;
                spi_spd<= 1'b1;
                spi_spd<= 1'b1;
                spi_dir <= 1'b0; // Write (for now)
                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
                begin // Continue our read ... send the new address / mode
                        o_wb_stall <= 1'b1;
                        o_wb_stall <= 1'b1;
                        spi_wr <= 1'b1;
                        spi_wr <= 1'b1;
                        spi_len <= 2'b10; // Write address, but not mode byte
                        spi_len <= 2'b10; // Write address, but not mode byte
                        spi_in <= { {(24-ADDRESS_WIDTH){1'b0}},
                        spi_in <= { w_wb_addr, 8'ha0 };
                                        i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 };
 
                        state <= `WBQSPI_QRD_DUMMY;
                        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
                begin
                        // A local read that doesn't touch the device, so leave
                        // A local read that doesn't touch the device, so leave
                        // the device in its current state
                        // the device in its current state
                        o_wb_stall <= 1'b0;
                        o_wb_stall <= 1'b0;
                        o_wb_ack <= 1'b1;
                        o_wb_ack <= 1'b1;
Line 446... Line 461...
                                        dirty_sector, spi_busy,
                                        dirty_sector, spi_busy,
                                        ~write_protect,
                                        ~write_protect,
                                        quad_mode_enabled,
                                        quad_mode_enabled,
                                        {(29-ADDRESS_WIDTH){1'b0}},
                                        {(29-ADDRESS_WIDTH){1'b0}},
                                        erased_sector, 14'h000 };
                                        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
                begin // Need to release the device from quad mode for all else
                        o_wb_ack   <= 1'b0;
                        o_wb_ack   <= 1'b0;
                        o_wb_stall <= 1'b1;
                        o_wb_stall <= 1'b1;
                        spi_wr <= 1'b1;
                        spi_wr <= 1'b1;
                        spi_len <= 2'b11;
                        spi_len <= 2'b11;
Line 643... Line 658...
                // address (24-bits) and mode (8-bits) in quad speed.
                // address (24-bits) and mode (8-bits) in quad speed.
                o_wb_ack   <= 1'b0;
                o_wb_ack   <= 1'b0;
                o_wb_stall <= 1'b1;
                o_wb_stall <= 1'b1;
 
 
                spi_wr <= 1'b1; // Non-stop
                spi_wr <= 1'b1; // Non-stop
                spi_in <= { {(24-ADDRESS_WIDTH){1'b0}},
                spi_in <= { w_spif_addr, 8'ha0 };
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 };
 
                spi_len <= 2'b10; // Write address, not mode byte
                spi_len <= 2'b10; // Write address, not mode byte
                spi_spd <= 1'b1;
                spi_spd <= 1'b1;
                spi_dir <= 1'b0; // Still writing
                spi_dir <= 1'b0; // Still writing
                spi_hold <= 1'b0;
                spi_hold <= 1'b0;
                spif_req<= (spif_req) && (i_wb_cyc);
                spif_req<= (spif_req) && (i_wb_cyc);
Line 686... Line 700...
                if ((spi_valid)&&(spi_len == 2'b11))
                if ((spi_valid)&&(spi_len == 2'b11))
                        state <= `WBQSPI_READ_DATA;
                        state <= `WBQSPI_READ_DATA;
        end else if (state == `WBQSPI_READ_DATA)
        end else if (state == `WBQSPI_READ_DATA)
        begin
        begin
                // Pipelined read support
                // 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_in <= 32'h00;
                spi_len <= 2'b11;
                spi_len <= 2'b11;
                // Don't adjust the speed here, it was set in the setup
                // Don't adjust the speed here, it was set in the setup
                spi_dir <= 1'b1;        // Now we get to read
                spi_dir <= 1'b1;        // Now we get to read
                // Don't let the device go to idle until the bus cycle ends.
                // Don't let the device go to idle until the bus cycle ends.
Line 710... Line 724...
                if ((spi_valid)&&(~spi_in[31]))
                if ((spi_valid)&&(~spi_in[31]))
                begin // Single pulse acknowledge and write data out
                begin // Single pulse acknowledge and write data out
                        o_wb_ack <= spif_req;
                        o_wb_ack <= spif_req;
                        o_wb_stall <= (~spi_wr);
                        o_wb_stall <= (~spi_wr);
                        // adjust endian-ness to match the PC
                        // adjust endian-ness to match the PC
                        o_wb_data <= { spi_out[7:0], spi_out[15:8],
                        o_wb_data <= spi_out;
                                spi_out[23:16], spi_out[31:24] };
 
                        state <= (spi_wr)?`WBQSPI_READ_DATA
                        state <= (spi_wr)?`WBQSPI_READ_DATA
                                : ((spi_spd) ? `WBQSPI_WAIT_TIL_RDIDLE : `WBQSPI_WAIT_TIL_IDLE);
                                : ((spi_spd) ? `WBQSPI_WAIT_TIL_RDIDLE : `WBQSPI_WAIT_TIL_IDLE);
                        spif_req <= spi_wr;
                        spif_req <= spi_wr;
                        spi_hold <= (~spi_wr);
                        spi_hold <= (~spi_wr);
                        if (spi_wr)
                        if (spi_wr)
Line 898... Line 911...
                        casez({ spif_cmd, spif_ctrl, spif_addr[1:0] })
                        casez({ spif_cmd, spif_ctrl, spif_addr[1:0] })
                        4'b00??: begin // Read data from ... somewhere
                        4'b00??: begin // Read data from ... somewhere
                                spi_wr     <= 1'b1;     // Write cmd to device
                                spi_wr     <= 1'b1;     // Write cmd to device
                                if (quad_mode_enabled)
                                if (quad_mode_enabled)
                                begin
                                begin
                                        spi_in <= { 8'heb,
                                        spi_in <= { 8'heb, w_spif_addr };
                                                {(24-ADDRESS_WIDTH){1'b0}},
 
                                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
 
                                        state <= `WBQSPI_QRD_ADDRESS;
                                        state <= `WBQSPI_QRD_ADDRESS;
                                        // spi_len    <= 2'b00; // single byte, cmd only
                                        // spi_len    <= 2'b00; // single byte, cmd only
                                end else begin
                                end else begin
                                        spi_in <= { 8'h0b,
                                        spi_in <= { 8'h0b, w_spif_addr };
                                                {(24-ADDRESS_WIDTH){1'b0}},
 
                                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
 
                                        state <= `WBQSPI_RD_DUMMY;
                                        state <= `WBQSPI_RD_DUMMY;
                                        spi_len    <= 2'b11; // Send cmd and addr
                                        spi_len    <= 2'b11; // Send cmd and addr
                                end end
                                end end
                        4'b10??: begin // Write data to ... anywhere
                        4'b10??: begin // Write data to ... anywhere
                                spi_wr <= 1'b1;
                                spi_wr <= 1'b1;
Line 954... Line 963...
                        // state <= `WBQSPI_PP;
                        // state <= `WBQSPI_PP;
        end else if (state == `WBQSPI_PP)
        end else if (state == `WBQSPI_PP)
        begin // We come here under a full stop / full port idle mode
        begin // We come here under a full stop / full port idle mode
                // Issue our command immediately
                // Issue our command immediately
                spi_wr <= 1'b1;
                spi_wr <= 1'b1;
                spi_in <= { 8'h02,
                spi_in <= { 8'h02, w_spif_addr };
                                {(24-ADDRESS_WIDTH){1'b0}},
 
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
 
                spi_len <= 2'b11;
                spi_len <= 2'b11;
                spi_hold <= 1'b1;
                spi_hold <= 1'b1;
                spi_spd  <= 1'b0;
                spi_spd  <= 1'b0;
                spi_dir  <= 1'b0; // Writing
                spi_dir  <= 1'b0; // Writing
                spif_req<= (spif_req) && (i_wb_cyc);
                spif_req<= (spif_req) && (i_wb_cyc);
Line 972... Line 979...
                        dirty_sector <= 1'b1;
                        dirty_sector <= 1'b1;
        end else if (state == `WBQSPI_QPP)
        end else if (state == `WBQSPI_QPP)
        begin // We come here under a full stop / full port idle mode
        begin // We come here under a full stop / full port idle mode
                // Issue our command immediately
                // Issue our command immediately
                spi_wr <= 1'b1;
                spi_wr <= 1'b1;
                spi_in <= { 8'h32,
                spi_in <= { 8'h32, w_spif_addr };
                                {(24-ADDRESS_WIDTH){1'b0}},
 
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
 
                spi_len <= 2'b11;
                spi_len <= 2'b11;
                spi_hold <= 1'b1;
                spi_hold <= 1'b1;
                spi_spd  <= 1'b0;
                spi_spd  <= 1'b0;
                spi_dir  <= 1'b0; // Writing
                spi_dir  <= 1'b0; // Writing
                spif_req<= (spif_req) && (i_wb_cyc);
                spif_req<= (spif_req) && (i_wb_cyc);
Line 997... Line 1002...
        end else if (state == `WBQSPI_WR_DATA)
        end else if (state == `WBQSPI_WR_DATA)
        begin
        begin
                o_wb_stall <= 1'b1;
                o_wb_stall <= 1'b1;
                o_wb_ack   <= 1'b0;
                o_wb_ack   <= 1'b0;
                spi_wr   <= 1'b1; // write without waiting
                spi_wr   <= 1'b1; // write without waiting
                spi_in   <= {
                spi_in   <= spif_data;
                        spif_data[ 7: 0],
 
                        spif_data[15: 8],
 
                        spif_data[23:16],
 
                        spif_data[31:24] };
 
                spi_len  <= 2'b11; // Write 4 bytes
                spi_len  <= 2'b11; // Write 4 bytes
                spi_hold <= 1'b1;
                spi_hold <= 1'b1;
                if (~spi_busy)
                if (~spi_busy)
                begin
                begin
                        o_wb_ack <= spif_req; // Ack when command given
                        o_wb_ack <= spif_req; // Ack when command given

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.