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

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [rtl/] [wbqspiflash.v] - Diff between revs 11 and 46

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

Rev 11 Rev 46
Line 1... Line 1...
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    wbspiflash.v
// Filename:    wbspiflash.v
//
//
// Project:     Wishbone Controlled Quad SPI Flash Controller
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
//
//
// Purpose:     Access a Quad SPI flash via a WISHBONE interface.  This
// Purpose:     Access a Quad SPI flash via a WISHBONE interface.  This
//              includes both read and write (and erase) commands to the SPI
//              includes both read and write (and erase) commands to the SPI
//              flash.  All read/write commands are accomplished using the
//              flash.  All read/write commands are accomplished using the
//              high speed (4-bit) interface.  Further, the device will be
//              high speed (4-bit) interface.  Further, the device will be
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 "flashconfig.v"
`include "flashconfig.v"
//
//
`define WBQSPI_RESET            0
`define WBQSPI_RESET            0
`define WBQSPI_RESET_QUADMODE   1
`define WBQSPI_RESET_QUADMODE   1
Line 63... Line 64...
`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 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;
 
        localparam      AW = ADDRESS_WIDTH-2;
        input                   i_clk_100mhz;
        input                   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                   i_wb_cyc, i_wb_data_stb, i_wb_ctrl_stb, i_wb_we;
        input           [(ADDRESS_WIDTH-3):0]    i_wb_addr;
        input           [(AW-1):0]       i_wb_addr;
        input           [31:0]   i_wb_data;
        input           [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;
Line 148... Line 150...
 
 
        reg     [7:0]    last_status;
        reg     [7:0]    last_status;
        reg     [9:0]    reset_counter;
        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     [(AW-1):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;
        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[(AW-1):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 };
 
 
        initial state = `WBQSPI_RESET;
        initial state = `WBQSPI_RESET;
        initial o_wb_ack   = 1'b0;
        initial o_wb_ack   = 1'b0;
Line 166... Line 168...
        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;
        initial spif_override = 1'b1;
 
        initial spif_ctrl     = 1'b0;
        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_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
        alt_ctrl <= (reset_counter[9:8]==2'b10)?reset_counter[0]:1'b1; // Toggle clock too
Line 235... Line 238...
                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 278... Line 281...
                                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,
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
                                                i_wb_addr[(AW-1):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,
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
                                                i_wb_addr[(AW-1):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 297... 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 363... 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 439... 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 <= { {(24-ADDRESS_WIDTH){1'b0}},
                                        i_wb_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 };
                                        i_wb_addr[(AW-1):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 459... Line 462...
                                        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 657... Line 660...
                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 <= { {(24-ADDRESS_WIDTH){1'b0}},
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00, 8'ha0 };
                                spif_addr[(AW-1):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 699... Line 702...
                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 723... Line 726...
                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 913... Line 915...
                                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,
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
                                                spif_addr[(AW-1):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,
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                {(24-ADDRESS_WIDTH){1'b0}},
                                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
                                                spif_addr[(AW-1):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 969... Line 971...
        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,
                                {(24-ADDRESS_WIDTH){1'b0}},
                                {(24-ADDRESS_WIDTH){1'b0}},
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
                                spif_addr[(AW-1):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 987... Line 989...
        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,
                                {(24-ADDRESS_WIDTH){1'b0}},
                                {(24-ADDRESS_WIDTH){1'b0}},
                                spif_addr[(ADDRESS_WIDTH-3):0], 2'b00 };
                                spif_addr[(AW-1):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 1010... Line 1012...
        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
Line 1040... Line 1038...
                end else if (spi_wr)
                end else if (spi_wr)
                begin // Give the SPI a chance to get busy on the last write
                begin // Give the SPI a chance to get busy on the last write
                        // Do nothing here.
                        // Do nothing here.
                end else if ((i_wb_data_stb)&&(i_wb_we)
                end else if ((i_wb_data_stb)&&(i_wb_we)
                                &&(i_wb_addr == (spif_addr+1))
                                &&(i_wb_addr == (spif_addr+1))
                                &&(i_wb_addr[(ADDRESS_WIDTH-3):6]==spif_addr[(ADDRESS_WIDTH-3):6]))
                                &&(i_wb_addr[(AW-1):6]==spif_addr[(AW-1):6]))
                begin
                begin
                        spif_cmd  <= 1'b1;
                        spif_cmd  <= 1'b1;
                        spif_data <= i_wb_data;
                        spif_data <= i_wb_data;
                        spif_addr <= i_wb_addr;
                        spif_addr <= i_wb_addr;
                        spif_ctrl  <= 1'b0;
                        spif_ctrl  <= 1'b0;
Line 1113... Line 1111...
                spi_in <= { 8'hd8, 2'h0, spif_data[19:14], 14'h000, 2'b00 };
                spi_in <= { 8'hd8, 2'h0, spif_data[19:14], 14'h000, 2'b00 };
                spi_len <= 2'b11; // 32 bit write
                spi_len <= 2'b11; // 32 bit write
                // together with setting our copy of the WIP bit
                // together with setting our copy of the WIP bit
                write_in_progress <= 1'b1;
                write_in_progress <= 1'b1;
                // keeping track of which sector we just erased
                // keeping track of which sector we just erased
                erased_sector <= spif_data[(ADDRESS_WIDTH-3):14];
                erased_sector <= spif_data[(AW-1):14];
                // and marking this erase sector as no longer dirty
                // and marking this erase sector as no longer dirty
                dirty_sector <= 1'b0;
                dirty_sector <= 1'b0;
 
 
                // Wait for a full stop before issuing this command
                // Wait for a full stop before issuing this command
                if ((~spi_busy)&&(~spi_wr)&&(o_qspi_cs_n))
                if ((~spi_busy)&&(~spi_wr)&&(o_qspi_cs_n))
Line 1131... Line 1129...
                spi_hold   <= 1'b0;
                spi_hold   <= 1'b0;
                o_wb_stall <= 1'b1;
                o_wb_stall <= 1'b1;
                o_wb_ack   <= 1'b0;
                o_wb_ack   <= 1'b0;
                spif_req <= (spif_req) && (i_wb_cyc);
                spif_req <= (spif_req) && (i_wb_cyc);
                // When the port clears, we can head back to idle
                // When the port clears, we can head back to idle
 
                //      No ack necessary, we ackd before getting
 
                //      here.
                if ((~spi_busy)&&(~spi_wr))
                if ((~spi_busy)&&(~spi_wr))
                begin
 
                        o_wb_ack <= spif_req;
 
                        state <= `WBQSPI_IDLE;
                        state <= `WBQSPI_IDLE;
                end
 
        end else if (state == `WBQSPI_CLEAR_STATUS)
        end else if (state == `WBQSPI_CLEAR_STATUS)
        begin // Issue a clear status command
        begin // Issue a clear status command
                spi_wr <= 1'b1;
                spi_wr <= 1'b1;
                spi_hold <= 1'b0;
                spi_hold <= 1'b0;
                spi_len <= 2'b00; // 8 bit command
                spi_len <= 2'b00; // 8 bit command

powered by: WebSVN 2.1.0

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