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

Subversion Repositories qspiflash

[/] [qspiflash/] [trunk/] [bench/] [cpp/] [eqspiflash_tb.cpp] - Diff between revs 12 and 16

Only display areas with differences | Details | Blame | View Log

Rev 12 Rev 16
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    eqspiflash_tb.cpp
// Filename:    eqspiflash_tb.cpp
//
//
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
// Project:     Wishbone Controlled Quad SPI Flash Controller
//
//
// Purpose:     To determine whether or not the eqspiflash module works.  Run
// Purpose:     To determine whether or not the eqspiflash module works.  Run
//              this with no arguments, and check whether or not the last line
//              this with no arguments, and check whether or not the last line
//      contains "SUCCESS" or not.  If it does contain "SUCCESS", then the
//      contains "SUCCESS" or not.  If it does contain "SUCCESS", then the
//      module passes all tests found within here.
//      module passes all tests found within here.
//
//
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
// Copyright (C) 2015-2016, 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.
//
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// 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 "verilated.h"
#include "verilated.h"
 
#include "verilated_vcd_c.h"
#include "Veqspiflash.h"
#include "Veqspiflash.h"
#include "eqspiflashsim.h"
#include "eqspiflashsim.h"
 
 
#define QSPIFLASH       0x0400000
#define QSPIFLASH       0x0400000
const int       BOMBCOUNT = 2048;
const int       BOMBCOUNT = 2048;
 
 
class   EQSPIFLASH_TB {
class   EQSPIFLASH_TB {
        long            m_tickcount;
        unsigned long           m_tickcount;
        Veqspiflash     *m_core;
        Veqspiflash     *m_core;
        EQSPIFLASHSIM   *m_flash;
        EQSPIFLASHSIM   *m_flash;
        bool            m_bomb;
        bool            m_bomb;
 
        VerilatedVcdC*  m_trace;
 
 
public:
public:
 
 
        EQSPIFLASH_TB(void) {
        EQSPIFLASH_TB(void) {
 
                Verilated::traceEverOn(true);
                m_core = new Veqspiflash;
                m_core = new Veqspiflash;
                m_flash= new EQSPIFLASHSIM;
                m_flash= new EQSPIFLASHSIM(24,true);
 
                m_trace= NULL;
        }
        }
 
 
        unsigned operator[](const int index) { return (*m_flash)[index]; }
        unsigned operator[](const int index) { return (*m_flash)[index]; }
        void    setflash(unsigned addr, unsigned v) {
        void    setflash(unsigned addr, unsigned v) {
                m_flash->set(addr, v);
                m_flash->set(addr, v);
        }
        }
        void    load(const char *fname) {
        void    load(const char *fname) {
                m_flash->load(0,fname);
                m_flash->load(0,fname);
        }
        }
 
 
        void    tick(void) {
        void    trace(const char *fname) {
                m_core->i_clk_200mhz = 1;
                if (!m_trace) {
 
                        m_trace = new VerilatedVcdC;
 
                        m_core->trace(m_trace, 99);
 
                        m_trace->open(fname);
 
                }
 
        }
 
 
 
        void    tick(void) {
 
                // m_core->i_clk_82mhz = 0;
 
                // m_core->eval();
                m_core->i_qspi_dat = (*m_flash)(m_core->o_qspi_cs_n,
                m_core->i_qspi_dat = (*m_flash)(m_core->o_qspi_cs_n,
                        m_core->o_qspi_sck, m_core->o_qspi_dat);
                        m_core->o_qspi_sck, m_core->o_qspi_dat);
 
 
 
                m_core->i_clk_82mhz = 1;
 
                m_core->eval();
 
// #define      DEBUGGING_OUTPUT
 
#ifdef  DEBUGGING_OUTPUT
                printf("%08lx-WB: %s %s/%s %s %s[%s%s%s%s%s] %s %s@0x%08x[%08x/%08x] -- SPI %s%s[%x/%x](%d,%d)",
                printf("%08lx-WB: %s %s/%s %s %s[%s%s%s%s%s] %s %s@0x%08x[%08x/%08x] -- SPI %s%s[%x/%x](%d,%d)",
                        m_tickcount,
                        m_tickcount,
                        (m_core->i_wb_cyc)?"CYC":"   ",
                        (m_core->i_wb_cyc)?"CYC":"   ",
                        (m_core->i_wb_data_stb)?"DSTB":"    ",
                        (m_core->i_wb_data_stb)?"DSTB":"    ",
                        (m_core->i_wb_ctrl_stb)?"CSTB":"    ",
                        (m_core->i_wb_ctrl_stb)?"CSTB":"    ",
                        (m_core->o_wb_stall)?"STALL":"     ",
                        (m_core->o_wb_stall)?"STALL":"     ",
                        (m_core->o_wb_ack)?"ACK":"   ",
                        (m_core->o_wb_ack)?"ACK":"   ",
                        (m_core->v__DOT__bus_wb_ack)?"BS":"  ",
                        (m_core->v__DOT__bus_wb_ack)?"BS":"  ",
                        (m_core->v__DOT__rd_data_ack)?"RD":"  ",
                        (m_core->v__DOT__rd_data_ack)?"RD":"  ",
                        (m_core->v__DOT__ew_data_ack)?"EW":"  ",
                        (m_core->v__DOT__ew_data_ack)?"EW":"  ",
                        (m_core->v__DOT__id_data_ack)?"ID":"  ",
                        (m_core->v__DOT__id_data_ack)?"ID":"  ",
                        (m_core->v__DOT__ct_data_ack)?"CT":"  ",
                        (m_core->v__DOT__ct_data_ack)?"CT":"  ",
                        (m_core->o_cmd_accepted)?"BUS":"   ",
                        (m_core->o_cmd_accepted)?"BUS":"   ",
                        (m_core->i_wb_we)?"W":"R",
                        (m_core->i_wb_we)?"W":"R",
                        (m_core->i_wb_addr), (m_core->i_wb_data),
                        (m_core->i_wb_addr), (m_core->i_wb_data),
                        (m_core->o_wb_data),
                        (m_core->o_wb_data),
                        (!m_core->o_qspi_cs_n)?"CS":"  ",
                        (!m_core->o_qspi_cs_n)?"CS":"  ",
                        (m_core->o_qspi_sck)?"CK":"  ",
                        (m_core->o_qspi_sck)?"CK":"  ",
                        (m_core->o_qspi_dat), (m_core->i_qspi_dat),
                        (m_core->o_qspi_dat), (m_core->i_qspi_dat),
                        (m_core->o_qspi_dat)&1, ((m_core->i_qspi_dat)&2)?1:0);
                        (m_core->o_qspi_dat)&1, ((m_core->i_qspi_dat)&2)?1:0);
 
 
                /// printf("%08lx-EQ: ", m_tickcount);
                /// printf("%08lx-EQ: ", m_tickcount);
                printf("EQ: ");
                printf("EQ: ");
                if (m_core->v__DOT__owned) {
                if (m_core->v__DOT__owned) {
                        switch(m_core->v__DOT__owner&3) {
                        switch(m_core->v__DOT__owner&3) {
                        case 0: printf("RD"); break;
                        case 0: printf("RD"); break;
                        case 1: printf("EW"); break;
                        case 1: printf("EW"); break;
                        case 2: printf("ID"); break;
                        case 2: printf("ID"); break;
                        case 3: printf("CT"); break;
                        case 3: printf("CT"); break;
                        }
                        }
                } else printf("  ");
                } else printf("  ");
 
 
                printf(" REQ[%s%s%s%s]",
                printf(" REQ[%s%s%s%s]",
                        (m_core->v__DOT__rd_qspi_req)?"RD":"  ",
                        (m_core->v__DOT__rd_qspi_req)?"RD":"  ",
                        (m_core->v__DOT__ew_qspi_req)?"EW":"  ",
                        (m_core->v__DOT__ew_qspi_req)?"EW":"  ",
                        (m_core->v__DOT__id_qspi_req)?"ID":"  ",
                        (m_core->v__DOT__id_qspi_req)?"ID":"  ",
                        (m_core->v__DOT__ct_qspi_req)?"CT":"  ");
                        (m_core->v__DOT__ct_qspi_req)?"CT":"  ");
 
 
                printf(" %s[%s%2d%s%s0x%08x]",
                printf(" %s[%s%2d%s%s0x%08x]",
                        (m_core->v__DOT__spi_wr)?"CMD":"   ",
                        (m_core->v__DOT__spi_wr)?"CMD":"   ",
                        (m_core->v__DOT__spi_hold)?"HLD":"   ",
                        (m_core->v__DOT__spi_hold)?"HLD":"   ",
                        (m_core->v__DOT__spi_len+1)*8,
                        (m_core->v__DOT__spi_len+1)*8,
                        (m_core->v__DOT__spi_dir)?"RD":"WR",
                        (m_core->v__DOT__spi_dir)?"RD":"WR",
                        (m_core->v__DOT__spi_spd)?"Q":" ",
                        (m_core->v__DOT__spi_spd)?"Q":" ",
                        (m_core->v__DOT__spi_word));
                        (m_core->v__DOT__spi_word));
 
 
                printf(" STATE[%2x%s,%2x%s,%2x%s,%2x%s]",
                printf(" STATE[%2x%s,%2x%s,%2x%s,%2x%s]",
                        m_core->v__DOT__rdproc__DOT__rd_state,
                        m_core->v__DOT__rdproc__DOT__rd_state,
                                (m_core->v__DOT__rd_spi_wr)?"W":" ",
                                (m_core->v__DOT__rd_spi_wr)?"W":" ",
                        m_core->v__DOT__ewproc__DOT__wr_state,
                        m_core->v__DOT__ewproc__DOT__wr_state,
                                (m_core->v__DOT__ew_spi_wr)?"W":" ",
                                (m_core->v__DOT__ew_spi_wr)?"W":" ",
                        m_core->v__DOT__idotp__DOT__id_state,
                        m_core->v__DOT__idotp__DOT__id_state,
                                (m_core->v__DOT__id_spi_wr)?"W":" ",
                                (m_core->v__DOT__id_spi_wr)?"W":" ",
                        m_core->v__DOT__ctproc__DOT__ctstate,
                        m_core->v__DOT__ctproc__DOT__ctstate,
                                (m_core->v__DOT__ct_spi_wr)?"W":" ");
                                (m_core->v__DOT__ct_spi_wr)?"W":" ");
 
 
                printf(" LL:[%s%s%d(%08x)->%08x]",
                printf(" LL:[%s%s%d(%08x)->%08x]",
                        (m_core->v__DOT__spi_busy)?"BSY":"   ",
                        (m_core->v__DOT__spi_busy)?"BSY":"   ",
                        (m_core->v__DOT__spi_valid)?"VAL":"   ",
                        (m_core->v__DOT__spi_valid)?"VAL":"   ",
                        (m_core->v__DOT__lowlvl__DOT__state),
                        (m_core->v__DOT__lowlvl__DOT__state),
                        (m_core->v__DOT__lowlvl__DOT__r_input),
                        (m_core->v__DOT__lowlvl__DOT__r_input),
                        (m_core->v__DOT__spi_out));
                        (m_core->v__DOT__spi_out));
 
 
                // printf(" 0x%08x,%02x ", m_core->v__DOT__id_data, 
                // printf(" 0x%08x,%02x ", m_core->v__DOT__id_data, 
                        // m_core->v__DOT__bus_addr);
                        // m_core->v__DOT__bus_addr);
                printf(" %s%08x@%08x",
                printf(" %s%08x@%08x",
                        (m_core->v__DOT__bus_wr)?"W":"R",
                        (m_core->v__DOT__bus_wr)?"W":"R",
                        m_core->v__DOT__bus_data, m_core->v__DOT__bus_addr);
                        m_core->v__DOT__bus_data, m_core->v__DOT__bus_addr);
 
 
                if (m_core->v__DOT__idotp__DOT__id_state == 5)
                if (m_core->v__DOT__idotp__DOT__id_state == 5)
                        printf(" %s[%2x]%s",
                        printf(" %s[%2x]%s",
                                (m_core->v__DOT__idotp__DOT__last_addr)?"LST":"   ",
                                (m_core->v__DOT__idotp__DOT__last_addr)?"LST":"   ",
                                (m_core->v__DOT__idotp__DOT__lcl_id_addr),
                                (m_core->v__DOT__idotp__DOT__lcl_id_addr),
                                (m_core->v__DOT__idotp__DOT__id_loaded)?"LOD":"   ");
                                (m_core->v__DOT__idotp__DOT__id_loaded)?"LOD":"   ");
 
 
 
 
                printf(" %s[%08x]",
                printf(" %s[%08x]",
                        (m_core->v__DOT__idotp__DOT__nxt_data_ack)
                        (m_core->v__DOT__idotp__DOT__nxt_data_ack)
                        ?"NXT":"   ", m_core->v__DOT__idotp__DOT__nxt_data);
                        ?"NXT":"   ", m_core->v__DOT__idotp__DOT__nxt_data);
                printf(" %s[%x]",
                printf(" %s[%x]",
                        (m_core->v__DOT__idotp__DOT__set_val)?"SET":"   ",
                        (m_core->v__DOT__idotp__DOT__set_val)?"SET":"   ",
                        (m_core->v__DOT__idotp__DOT__set_addr));
                        (m_core->v__DOT__idotp__DOT__set_addr));
 
 
                printf(" RD:IACK[%x]",
                printf(" RD:IACK[%x]",
                        (m_core->v__DOT__rdproc__DOT__invalid_ack_pipe));
                        (m_core->v__DOT__rdproc__DOT__invalid_ack_pipe));
                printf(" CT:IACK[%x]",
                printf(" CT:IACK[%x]",
                        (m_core->v__DOT__ctproc__DOT__invalid_ack_pipe));
                        (m_core->v__DOT__ctproc__DOT__invalid_ack_pipe));
 
 
                {
                {
                        unsigned counts = m_flash->counts_till_idle();
                        unsigned counts = m_flash->counts_till_idle();
                        if (counts)
                        if (counts)
                                printf(" %8dI ", counts);
                                printf(" %8dI ", counts);
                }
                }
                printf("%s%s%s%s",
                printf("%s%s%s%s",
                        (m_core->v__DOT__rdproc__DOT__accepted)?"RD-ACC":"",
                        (m_core->v__DOT__rdproc__DOT__accepted)?"RD-ACC":"",
                        (m_core->v__DOT__ewproc__DOT__accepted)?"EW-ACC":"",
                        (m_core->v__DOT__ewproc__DOT__accepted)?"EW-ACC":"",
                        (m_core->v__DOT__idotp__DOT__accepted)?"ID-ACC":"",
                        (m_core->v__DOT__idotp__DOT__accepted)?"ID-ACC":"",
                        (m_core->v__DOT__ctproc__DOT__accepted)?"CT-ACC":"");
                        (m_core->v__DOT__ctproc__DOT__accepted)?"CT-ACC":"");
 
 
 
 
                printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                        (m_core->v__DOT__preproc__DOT__pending)?" PENDING":"",
                        (m_core->v__DOT__preproc__DOT__pending)?" PENDING":"",
                        (m_core->v__DOT__preproc__DOT__lcl_key)?" KEY":"",
                        (m_core->v__DOT__preproc__DOT__lcl_key)?" KEY":"",
                        (m_core->v__DOT__preproc__DOT__ctreg_stb)?" CTSTB":"",
                        (m_core->v__DOT__preproc__DOT__ctreg_stb)?" CTSTB":"",
                        (m_core->v__DOT__bus_ctreq)?" BUSCTRL":"",
                        (m_core->v__DOT__bus_ctreq)?" BUSCTRL":"",
                        (m_core->v__DOT__bus_other_req)?" BUSOTHER":"",
                        (m_core->v__DOT__bus_other_req)?" BUSOTHER":"",
                        (m_core->v__DOT__preproc__DOT__wp)?" WP":"",
                        (m_core->v__DOT__preproc__DOT__wp)?" WP":"",
                        (m_core->v__DOT__bus_wip)?" WIP":"",
                        (m_core->v__DOT__bus_wip)?" WIP":"",
                        // (m_core->v__DOT__preproc__DOT__lcl_reg)?" LCLREG":"",
                        // (m_core->v__DOT__preproc__DOT__lcl_reg)?" LCLREG":"",
                        // (m_core->v__DOT__w_xip)?" XIP":"",
                        // (m_core->v__DOT__w_xip)?" XIP":"",
                        // (m_core->v__DOT__w_quad)?" QUAD":"",
                        // (m_core->v__DOT__w_quad)?" QUAD":"",
                        // (m_core->v__DOT__bus_piperd)?" RDPIPE":"",
                        (m_core->v__DOT__bus_piperd)?" RDPIPE":"",
                        (m_core->v__DOT__preproc__DOT__wp)?" WRWP":"",
                        (m_core->v__DOT__preproc__DOT__wp)?" WRWP":"",
                        (m_core->v__DOT__ewproc__DOT__cyc)?" WRCYC":"",
                        (m_core->v__DOT__ewproc__DOT__cyc)?" WRCYC":"",
                        (m_core->v__DOT__bus_pipewr)?" WRPIPE":"",
                        (m_core->v__DOT__bus_pipewr)?" WRPIPE":"",
                        (m_core->v__DOT__bus_endwr)?" ENDWR":"",
                        (m_core->v__DOT__bus_endwr)?" ENDWR":"",
                        (m_core->v__DOT__ct_ack)?" CTACK":"",
                        (m_core->v__DOT__ct_ack)?" CTACK":"",
                        (m_core->v__DOT__rd_bus_ack)?" RDACK":"",
                        (m_core->v__DOT__rd_bus_ack)?" RDACK":"",
                        (m_core->v__DOT__id_bus_ack)?" IDACK":"",
                        (m_core->v__DOT__id_bus_ack)?" IDACK":"",
                        (m_core->v__DOT__ew_bus_ack)?" EWACK":"",
                        (m_core->v__DOT__ew_bus_ack)?" EWACK":"",
                        (m_core->v__DOT__preproc__DOT__lcl_ack)?" LCLACK":"",
                        (m_core->v__DOT__preproc__DOT__lcl_ack)?" LCLACK":"",
                        (m_core->v__DOT__rdproc__DOT__r_leave_xip)?" LVXIP":"",
                        (m_core->v__DOT__rdproc__DOT__r_leave_xip)?" LVXIP":"",
                        (m_core->v__DOT__preproc__DOT__new_req)?" NREQ":"");
                        (m_core->v__DOT__preproc__DOT__new_req)?" NREQ":"");
 
 
                printf("%s%s%s",
                printf("%s%s%s",
                        (m_core->v__DOT__bus_idreq)?" BUSID":"",
                        (m_core->v__DOT__bus_idreq)?" BUSID":"",
                        (m_core->v__DOT__id_bus_ack)?" BUSAK":"",
                        (m_core->v__DOT__id_bus_ack)?" BUSAK":"",
                        (m_core->v__DOT__idotp__DOT__id_read_request)?" IDRD":"");
                        (m_core->v__DOT__idotp__DOT__id_read_request)?" IDRD":"");
 
 
                if (m_core->v__DOT__rdproc__DOT__r_requested)
                if (m_core->v__DOT__rdproc__DOT__r_requested)
                        fputs(" RD:R_REQUESTED", stdout);
                        fputs(" RD:R_REQUESTED", stdout);
                if (m_core->v__DOT__rdproc__DOT__r_leave_xip)
                if (m_core->v__DOT__rdproc__DOT__r_leave_xip)
                        fputs(" RD:R_LVXIP", stdout);
                        fputs(" RD:R_LVXIP", stdout);
 
 
 
 
                printf("\n");
                printf("\n");
 
#endif
 
 
 
                if ((m_trace)&&(m_tickcount>0))  m_trace->dump(10*m_tickcount-2);
 
                m_core->i_clk_82mhz = 1;
                m_core->eval();
                m_core->eval();
                m_core->i_clk_200mhz = 0;
                if (m_trace)    m_trace->dump(10*m_tickcount);
 
                m_core->i_clk_82mhz = 0;
                m_core->eval();
                m_core->eval();
 
                if (m_trace)    m_trace->dump(10*m_tickcount+5);
 
 
                m_tickcount++;
                m_tickcount++;
 
 
                /*
                /*
                if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
                if ((m_core->o_wb_ack)&&(!m_core->i_wb_cyc)) {
                        printf("SETTING ERR TO TRUE!!!!!  ACK w/ no CYC\n");
                        printf("SETTING ERR TO TRUE!!!!!  ACK w/ no CYC\n");
                        // m_bomb = true;
                        // m_bomb = true;
                }
                }
                */
                */
        }
        }
 
 
        void wb_tick(void) {
        void wb_tick(void) {
                printf("WB-TICK()\n");
                printf("WB-TICK()\n");
                m_core->i_wb_cyc   = 0;
                m_core->i_wb_cyc   = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                tick();
                tick();
        }
        }
 
 
        unsigned wb_read(unsigned a) {
        unsigned wb_read(unsigned a) {
                int             errcount = 0;
                int             errcount = 0;
                unsigned        result;
                unsigned        result;
 
 
                printf("WB-READ(%08x)\n", a);
                printf("WB-READ(%08x)\n", a);
 
 
                m_core->i_wb_cyc = 1;
                m_core->i_wb_cyc = 1;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_we  = 0;
                m_core->i_wb_we  = 0;
                m_core->i_wb_addr= a & 0x03fffff;
                m_core->i_wb_addr= a & 0x03fffff;
 
 
                if (m_core->o_wb_stall)
                if (m_core->o_wb_stall) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
                                tick();
                                tick();
                else
                } tick();
                        tick();
 
 
 
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
                        tick();
                        tick();
 
 
 
 
                result = m_core->o_wb_data;
                result = m_core->o_wb_data;
 
 
                // Release the bus?
                // Release the bus?
                m_core->i_wb_cyc = 0;
                m_core->i_wb_cyc = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                if(errcount >= BOMBCOUNT) {
                if(errcount >= BOMBCOUNT) {
                        printf("SETTING ERR TO TRUE!!!!!\n");
                        printf("RD-SETTING ERR TO TRUE!!!!!\n");
                        m_bomb = true;
                        m_bomb = true;
                } else if (!m_core->o_wb_ack) {
                } else if (!m_core->o_wb_ack) {
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
                        m_bomb = true;
                        m_bomb = true;
                }
                }
                tick();
                tick();
 
 
                return result;
                return result;
        }
        }
 
 
        void    wb_read(unsigned a, int len, unsigned *buf) {
        void    wb_read(unsigned a, int len, unsigned *buf) {
                int             errcount = 0;
                int             errcount = 0;
                int             THISBOMBCOUNT = BOMBCOUNT * len;
                int             THISBOMBCOUNT = BOMBCOUNT * len;
                int             cnt, rdidx, inc;
                int             cnt, rdidx, inc;
 
 
                printf("WB-READ(%08x, %d)\n", a, len);
                printf("WB-READ(%08x, %d)\n", a, len);
 
 
                while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
                while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
                        wb_tick();
                        wb_tick();
 
 
                if (errcount >= BOMBCOUNT) {
                if (errcount >= BOMBCOUNT) {
                        m_bomb = true;
                        m_bomb = true;
                        return;
                        return;
                }
                }
 
 
                errcount = 0;
                errcount = 0;
 
 
                m_core->i_wb_cyc = 1;
                m_core->i_wb_cyc = 1;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_we  = 0;
                m_core->i_wb_we  = 0;
                m_core->i_wb_addr= a & 0x03fffff;
                m_core->i_wb_addr= a & 0x03fffff;
 
 
                rdidx =0; cnt = 0;
                rdidx =0; cnt = 0;
                inc = (m_core->i_wb_data_stb);
                inc = (m_core->i_wb_data_stb);
 
 
                do {
                do {
                        int     s;
                        int     s;
                        s = (m_core->o_wb_stall==0)?0:1;
                        s = (m_core->o_wb_stall==0)?0:1;
                        tick();
                        tick();
                        if (!s)
                        if (!s)
                                m_core->i_wb_addr += inc;
                                m_core->i_wb_addr += inc;
                        cnt += (s==0)?1:0;
                        cnt += (s==0)?1:0;
                        if (m_core->o_wb_ack)
                        if (m_core->o_wb_ack)
                                buf[rdidx++] = m_core->o_wb_data;
                                buf[rdidx++] = m_core->o_wb_data;
                } while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
                } while((cnt < len)&&(errcount++ < THISBOMBCOUNT));
 
 
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
                while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) {
                        tick();
                        tick();
                        if (m_core->o_wb_ack)
                        if (m_core->o_wb_ack)
                                buf[rdidx++] = m_core->o_wb_data;
                                buf[rdidx++] = m_core->o_wb_data;
                }
                }
 
 
                // Release the bus?
                // Release the bus?
                m_core->i_wb_cyc = 0;
                m_core->i_wb_cyc = 0;
 
 
                if(errcount >= THISBOMBCOUNT) {
                if(errcount >= THISBOMBCOUNT) {
                        printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
                        printf("RDI-SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT);
                        m_bomb = true;
                        m_bomb = true;
                } else if (!m_core->o_wb_ack) {
                } else if (!m_core->o_wb_ack) {
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
                        printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n");
                        m_bomb = true;
                        m_bomb = true;
                }
                }
                tick();
                tick();
        }
        }
 
 
        void    wb_write(unsigned a, unsigned int v) {
        void    wb_write(unsigned a, unsigned int v) {
                int errcount = 0;
                int errcount = 0;
 
 
                printf("WB-WRITE(%08x) = %08x\n", a, v);
                printf("WB-WRITE(%08x) = %08x\n", a, v);
                m_core->i_wb_cyc = 1;
                m_core->i_wb_cyc = 1;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_we  = 1;
                m_core->i_wb_we  = 1;
                m_core->i_wb_addr= a & 0x03fffff;
                m_core->i_wb_addr= a & 0x03fffff;
                m_core->i_wb_data= v;
                m_core->i_wb_data= v;
 
 
                if (m_core->o_wb_stall)
                if (m_core->o_wb_stall)
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall))
                                tick();
                                tick();
                tick();
                tick();
 
 
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
                while((errcount++ <  BOMBCOUNT)&&(!m_core->o_wb_ack))
                        tick();
                        tick();
 
 
                // Release the bus?
                // Release the bus?
                m_core->i_wb_cyc = 0;
                m_core->i_wb_cyc = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                if(errcount >= BOMBCOUNT) {
                if(errcount >= BOMBCOUNT) {
                        printf("SETTING ERR TO TRUE!!!!!\n");
                        printf("WB-SETTING ERR TO TRUE!!!!!\n");
                        m_bomb = true;
                        m_bomb = true;
                } tick();
                } tick();
        }
        }
 
 
        void    wb_write(unsigned a, unsigned int ln, unsigned int *buf) {
        void    wb_write(unsigned a, unsigned int ln, unsigned int *buf) {
                unsigned errcount = 0, nacks = 0;
                unsigned errcount = 0, nacks = 0;
 
 
                m_core->i_wb_cyc = 1;
                m_core->i_wb_cyc = 1;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
                        m_core->i_wb_we  = 1;
                        m_core->i_wb_we  = 1;
                        m_core->i_wb_addr= (a+stbcnt) & 0x03fffff;
                        m_core->i_wb_addr= (a+stbcnt) & 0x03fffff;
                        m_core->i_wb_data= buf[stbcnt];
                        m_core->i_wb_data= buf[stbcnt];
                        errcount = 0;
                        errcount = 0;
 
 
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
                                tick(); if (m_core->o_wb_ack) nacks++;
                                tick(); if (m_core->o_wb_ack) nacks++;
                        }
                        }
                        // Tick, now that we're not stalled.  This is the tick
                        // Tick, now that we're not stalled.  This is the tick
                        // that gets accepted.
                        // that gets accepted.
                        tick(); if (m_core->o_wb_ack) nacks++;
                        tick(); if (m_core->o_wb_ack) nacks++;
                }
                }
 
 
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                errcount = 0;
                errcount = 0;
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
                        tick();
                        tick();
                        if (m_core->o_wb_ack) {
                        if (m_core->o_wb_ack) {
                                nacks++;
                                nacks++;
                                errcount = 0;
                                errcount = 0;
                        }
                        }
                }
                }
 
 
                // Release the bus
                // Release the bus
                m_core->i_wb_cyc = 0;
                m_core->i_wb_cyc = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                if(errcount >= BOMBCOUNT) {
                if(errcount >= BOMBCOUNT) {
                        printf("SETTING ERR TO TRUE!!!!!\n");
                        printf("WBI-SETTING ERR TO TRUE!!!!!\n");
                        m_bomb = true;
                        m_bomb = true;
                } tick();
                } tick();
        }
        }
 
 
        void    wb_write_slow(unsigned a, unsigned int ln, unsigned int *buf,
        void    wb_write_slow(unsigned a, unsigned int ln, unsigned int *buf,
                        int slowcounts) {
                        int slowcounts) {
                unsigned errcount = 0, nacks = 0;
                unsigned errcount = 0, nacks = 0;
 
 
                m_core->i_wb_cyc = 1;
                m_core->i_wb_cyc = 1;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
                        m_core->i_wb_we  = 1;
                        m_core->i_wb_we  = 1;
                        m_core->i_wb_addr= (a+stbcnt) & 0x03fffff;
                        m_core->i_wb_addr= (a+stbcnt) & 0x03fffff;
                        m_core->i_wb_data= buf[stbcnt];
                        m_core->i_wb_data= buf[stbcnt];
                        errcount = 0;
                        errcount = 0;
 
 
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_wb_stall)) {
                                tick(); if (m_core->o_wb_ack) nacks++;
                                tick(); if (m_core->o_wb_ack) nacks++;
                        }
                        }
 
 
                        // Tick, now that we're not stalled.  This is the tick
                        // Tick, now that we're not stalled.  This is the tick
                        // that gets accepted.
                        // that gets accepted.
                        tick(); if (m_core->o_wb_ack) nacks++;
                        tick(); if (m_core->o_wb_ack) nacks++;
 
 
 
 
                        m_core->i_wb_data_stb = 0;
                        m_core->i_wb_data_stb = 0;
                        m_core->i_wb_ctrl_stb = 0;
                        m_core->i_wb_ctrl_stb = 0;
                        for(int j=0; j<slowcounts; j++) {
                        for(int j=0; j<slowcounts; j++) {
                                tick(); if (m_core->o_wb_ack) nacks++;
                                tick(); if (m_core->o_wb_ack) nacks++;
                        }
                        }
 
 
                        // Turn our strobe signal back on again, after we just
                        // Turn our strobe signal back on again, after we just
                        // turned it off.
                        // turned it off.
                        m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                        m_core->i_wb_data_stb = (a & QSPIFLASH)?1:0;
                        m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                        m_core->i_wb_ctrl_stb = !(m_core->i_wb_data_stb);
                }
                }
 
 
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                errcount = 0;
                errcount = 0;
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
                while((nacks < ln)&&(errcount++ < BOMBCOUNT)) {
                        tick();
                        tick();
                        if (m_core->o_wb_ack) {
                        if (m_core->o_wb_ack) {
                                nacks++;
                                nacks++;
                                errcount = 0;
                                errcount = 0;
                        }
                        }
                }
                }
 
 
                // Release the bus
                // Release the bus
                m_core->i_wb_cyc = 0;
                m_core->i_wb_cyc = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_data_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
                m_core->i_wb_ctrl_stb = 0;
 
 
                if(errcount >= BOMBCOUNT) {
                if(errcount >= BOMBCOUNT) {
                        printf("SETTING ERR TO TRUE!!!!!\n");
                        printf("WBS-SETTING ERR TO TRUE!!!!!\n");
                        m_bomb = true;
                        m_bomb = true;
                } tick();
                } tick();
        }
        }
 
 
        bool    bombed(void) const { return m_bomb; }
        bool    bombed(void) const { return m_bomb; }
 
 
};
};
 
 
int main(int  argc, char **argv) {
int main(int  argc, char **argv) {
        Verilated::commandArgs(argc, argv);
        Verilated::commandArgs(argc, argv);
        EQSPIFLASH_TB   *tb = new EQSPIFLASH_TB;
        EQSPIFLASH_TB   *tb = new EQSPIFLASH_TB;
        const char      *fname = "/dev/urandom";
        const char      *fname = "/dev/urandom";
        unsigned        rdv;
        unsigned        rdv;
        unsigned        *rdbuf;
        unsigned        *rdbuf;
        int              idx = 4;
        int              idx = 4;
 
 
        tb->load(fname);
        tb->load(fname);
        rdbuf = new unsigned[4096];
        rdbuf = new unsigned[4096];
        tb->setflash(0,0);
        tb->setflash(0,0);
 
 
 
        tb->trace("eqspi.vcd");
 
 
        tb->wb_tick();
        tb->wb_tick();
        rdv = tb->wb_read(QSPIFLASH);
        rdv = tb->wb_read(QSPIFLASH);
        printf("READ[0] = %04x\n", rdv);
        printf("READ[0] = %04x\n", rdv);
        if (rdv != 0)
        if (rdv != 0)
                goto test_failure;
                goto test_failure;
 
 
        tb->wb_tick();
        tb->wb_tick();
        if (tb->bombed())
        if (tb->bombed())
                goto test_failure;
                goto test_failure;
 
 
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
                unsigned        tblv;
                unsigned        tblv;
                tblv = (*tb)[i];
                tblv = (*tb)[i];
                rdv = tb->wb_read(QSPIFLASH+i);
                rdv = tb->wb_read(QSPIFLASH+i);
 
 
                if(tblv != rdv) {
                if(tblv != rdv) {
                        printf("BOMB: READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+i, rdv, tblv);
                        printf("BOMB: READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+i, rdv, tblv);
                        goto test_failure;
                        goto test_failure;
                        break;
                        break;
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
        }
        }
 
 
        printf("SINGLE-READ TEST PASSES\n");
        printf("SINGLE-READ TEST PASSES\n");
 
 
        for(int i=0; i<1000; i++)
        for(int i=0; i<1000; i++)
                rdbuf[i] = -1;
                rdbuf[i] = -1;
        tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
        tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
        if (tb->bombed())
        if (tb->bombed())
                goto    test_failure;
                goto    test_failure;
        for(int i=0; i<1000; i++) {
        for(int i=0; i<1000; i++) {
                if ((*tb)[i+1000] != rdbuf[i]) {
                if ((*tb)[i+1000] != rdbuf[i]) {
                        printf("BOMB: V-READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+1000+i, rdv, (*tb)[i+1000]);
                        printf("BOMB: V-READ[%08x] %08x, EXPECTED %08x\n", QSPIFLASH+1000+i, rdv, (*tb)[i+1000]);
                        goto    test_failure;
                        goto    test_failure;
                }
                }
        } if (tb->bombed())
        } if (tb->bombed())
                goto test_failure;
                goto test_failure;
        printf("VECTOR TEST PASSES!\n");
        printf("VECTOR TEST PASSES!\n");
 
 
        // Read the status register
        // Read the status register
        printf("EWCTRL-REG = %02x\n", rdv=tb->wb_read(0));
        printf("EWCTRL-REG = %02x\n", rdv=tb->wb_read(0));
        if(tb->bombed()) goto test_failure;
        if(tb->bombed()) goto test_failure;
        printf("STATUS-REG = %02x\n", rdv=tb->wb_read(1));
        printf("STATUS-REG = %02x\n", rdv=tb->wb_read(1));
        if ((rdv != 0x1c)||(tb->bombed())) goto test_failure;
        if ((rdv != 0x1c)||(tb->bombed())) goto test_failure;
        printf("NVCONF-REG = %02x\n", tb->wb_read(2)); if(tb->bombed()) goto test_failure;
        printf("NVCONF-REG = %02x\n", tb->wb_read(2)); if(tb->bombed()) goto test_failure;
        printf("VCONFG-REG = %02x\n", tb->wb_read(3)); if(tb->bombed()) goto test_failure;
        printf("VCONFG-REG = %02x\n", tb->wb_read(3)); if(tb->bombed()) goto test_failure;
        printf("EVCONF-REG = %02x\n", tb->wb_read(4)); if(tb->bombed()) goto test_failure;
        printf("EVCONF-REG = %02x\n", tb->wb_read(4)); if(tb->bombed()) goto test_failure;
        printf("LOCK  -REG = %02x\n", tb->wb_read(5)); if(tb->bombed()) goto test_failure;
        printf("LOCK  -REG = %02x\n", tb->wb_read(5)); if(tb->bombed()) goto test_failure;
        printf("FLAG  -REG = %02x\n", tb->wb_read(6)); if(tb->bombed()) goto test_failure;
        printf("FLAG  -REG = %02x\n", tb->wb_read(6)); if(tb->bombed()) goto test_failure;
 
 
        if (tb->bombed())
        if (tb->bombed())
                goto test_failure;
                goto test_failure;
 
 
        printf("ID[%2d]-RG = %08x\n", 0, rdv = tb->wb_read(8+0));
        printf("ID[%2d]-RG = %08x\n", 0, rdv = tb->wb_read(8+0));
        if (rdv != 0x20ba1810) {
        if (rdv != 0x20ba1810) {
                printf("BOMB: ID[%2d]-RG = %08x != %08x\n", 0, rdv,
                printf("BOMB: ID[%2d]-RG = %08x != %08x\n", 0, rdv,
                        0x20ba1810);
                        0x20ba1810);
                goto test_failure;
                goto test_failure;
        }
        }
 
 
        for(int i=1; i<5; i++)
        for(int i=1; i<5; i++)
                printf("ID[%2d]-RG = %02x\n", i, tb->wb_read(8+i));
                printf("ID[%2d]-RG = %02x\n", i, tb->wb_read(8+i));
        if (tb->bombed())
        if (tb->bombed())
                goto test_failure;
                goto test_failure;
 
 
        for(int i=0; i<16; i++)
        for(int i=0; i<16; i++)
                printf("OTP[%2d]-R = %02x\n", i, tb->wb_read(16+i));
                printf("OTP[%2d]-R = %02x\n", i, tb->wb_read(16+i));
        if (tb->bombed())
        if (tb->bombed())
                goto test_failure;
                goto test_failure;
        printf("OTP[CT]-R = %02x\n", tb->wb_read(15)>>24);
        printf("OTP[CT]-R = %02x\n", tb->wb_read(15)>>24);
 
 
        if (tb->bombed())
        if (tb->bombed())
                goto test_failure;
                goto test_failure;
 
 
        printf("Attempting to switch in Quad mode\n");
        printf("Attempting to switch in Quad mode\n");
        // tb->wb_write(4, (tb->wb_read(4)&0x07f)); // Adjust EVconfig
        // tb->wb_write(4, (tb->wb_read(4)&0x07f)); // Adjust EVconfig
 
 
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
                unsigned        tblv;
                unsigned        tblv;
                tblv = (*tb)[i];
                tblv = (*tb)[i];
                rdv = tb->wb_read(QSPIFLASH+i);
                rdv = tb->wb_read(QSPIFLASH+i);
 
 
                if(tblv != rdv) {
                if(tblv != rdv) {
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
                        goto test_failure;
                        goto test_failure;
                        break;
                        break;
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
        } tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
        } tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
        if (tb->bombed())
        if (tb->bombed())
                goto    test_failure;
                goto    test_failure;
        for(int i=0; i<1000; i++) {
        for(int i=0; i<1000; i++) {
                if ((*tb)[i+1000] != rdbuf[i]) {
                if ((*tb)[i+1000] != rdbuf[i]) {
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
                        goto    test_failure;
                        goto    test_failure;
                }
                }
        } printf("VECTOR TEST PASSES! (QUAD)\n");
        } printf("VECTOR TEST PASSES! (QUAD)\n");
 
 
        printf("Attempting to switch to Quad mode with XIP\n");
        printf("Attempting to switch to Quad mode with XIP\n");
        tb->wb_write(3, tb->wb_read(3)|0x08);
        {
 
                int     nv;
 
                nv = tb->wb_read(3);
 
                printf("READ VCONF = %02x\n", nv);
 
                printf("WRITING VCONF= %02x\n", nv | 0x08);
 
                tb->wb_write(3, nv|0x08);
 
        }
        // tb->wb_write(0, 0x22000000);
        // tb->wb_write(0, 0x22000000);
 
 
        printf("Attempting to read in Quad mode, using XIP mode\n");
        printf("Attempting to read in Quad mode, using XIP mode\n");
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
        for(int i=0; (i<1000)&&(!tb->bombed()); i++) {
                unsigned        tblv;
                unsigned        tblv;
                tblv = (*tb)[i];
                tblv = (*tb)[i];
                rdv = tb->wb_read(QSPIFLASH+i);
                rdv = tb->wb_read(QSPIFLASH+i);
 
 
                if(tblv != rdv) {
                if(tblv != rdv) {
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, tblv);
                        goto test_failure;
                        goto test_failure;
                        break;
                        break;
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
                } else printf("MATCH: %08x == %08x\n", rdv, tblv);
        }
        }
 
 
        // Try a vector read
        // Try a vector read
        tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
        tb->wb_read(QSPIFLASH+1000, 1000, rdbuf);
        if (tb->bombed())
        if (tb->bombed())
                goto    test_failure;
                goto    test_failure;
        for(int i=0; i<1000; i++) {
        for(int i=0; i<1000; i++) {
                if ((*tb)[i+1000] != rdbuf[i]) {
                if ((*tb)[i+1000] != rdbuf[i]) {
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
                        printf("BOMB: READ %08x, EXPECTED %08x\n", rdv, (*tb)[i+1000]);
                        goto    test_failure;
                        goto    test_failure;
                }
                }
        } printf("VECTOR TEST PASSES! (QUAD+XIP)\n");
        } printf("VECTOR TEST PASSES! (QUAD+XIP)\n");
 
 
        rdbuf[0] = tb->wb_read(QSPIFLASH+1023);
        rdbuf[0] = tb->wb_read(QSPIFLASH+1023);
        rdbuf[1] = tb->wb_read(QSPIFLASH+2048);
        rdbuf[1] = tb->wb_read(QSPIFLASH+2048);
 
 
        printf("Turning off write-protect, calling WEL\n");
        printf("Turning off write-protect, calling WEL\n");
        tb->wb_write(0, 0x620001be);
        tb->wb_write(0, 0x620001be);
        printf("Attempting to erase subsector 1\n");
        printf("Attempting to erase subsector 1\n");
        tb->wb_write(0, 0xf20005be);
        tb->wb_write(0, 0xf20005be);
 
 
        while (tb->wb_read(0)&0x01000000)
        while((tb->wb_read(0)&0x01000000)&&(!tb->bombed()))
                ;
                ;
        while(tb->wb_read(0)&0x80000000)
        while((tb->wb_read(0)&0x80000000)&&(!tb->bombed()))
                ;
                ;
 
        if (tb->bombed())
 
                goto test_failure;
        if (tb->wb_read(QSPIFLASH+1023) != rdbuf[0])
        if (tb->wb_read(QSPIFLASH+1023) != rdbuf[0])
                goto test_failure;
                goto test_failure;
        if (tb->wb_read(QSPIFLASH+2048) != rdbuf[1])
        if (tb->wb_read(QSPIFLASH+2048) != rdbuf[1])
                goto test_failure;
                goto test_failure;
        tb->wb_read(QSPIFLASH+1024, 1024, rdbuf);
        tb->wb_read(QSPIFLASH+1024, 1024, rdbuf);
        for(int i=0; i<1024; i++) {
        for(int i=0; i<1024; i++) {
                if (rdbuf[i] != 0xffffffff) {
                if (rdbuf[i] != 0xffffffff) {
                        printf("BOMB: SUBSECTOR ERASE, EXPECTED[0x%02x] = 0xffffffff != %08x\n", i, rdv);
                        printf("BOMB: SUBSECTOR ERASE, EXPECTED[0x%02x] = 0xffffffff != %08x\n", i, rdv);
                        goto test_failure;
                        goto test_failure;
                } break;
                } break;
        }
        }
 
 
        // Try to execute a single write
        // Try to execute a single write
        // Check that this will work ...
        // Check that this will work ...
        for(idx=4; idx<4096; idx++) {
        for(idx=4; idx<4096; idx++) {
                if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
                if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
                        break;
                        break;
        }
        }
        // First, turn the write-enable back on
        // First, turn the write-enable back on
        tb->wb_write(0, 0x620001be);
        tb->wb_write(0, 0x620001be);
        // Now, write the value
        // Now, write the value
        tb->wb_write(QSPIFLASH+idx, 0x11111111);
        tb->wb_write(QSPIFLASH+idx, 0x11111111);
        while (tb->wb_read(0)&0x01000000)
        while (tb->wb_read(0)&0x01000000)
                ;
                ;
        while(tb->wb_read(0)&(0x80000000))
        while(tb->wb_read(0)&(0x80000000))
                ;
                ;
        if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
        if (0 != (tb->wb_read(QSPIFLASH+idx)&(~0x11111111)))
                goto test_failure;
                goto test_failure;
 
 
        // Try to write a complete block
        // Try to write a complete block
        {
        {
                FILE *fp = fopen(fname, "r"); // Open /dev/urandom
                FILE *fp = fopen(fname, "r"); // Open /dev/urandom
                if (4096 != fread(rdbuf, sizeof(unsigned), 4096, fp)) {
                if (4096 != fread(rdbuf, sizeof(unsigned), 4096, fp)) {
                        perror("Couldnt read /dev/urandom into buffer!");
                        perror("Couldnt read /dev/urandom into buffer!");
                        goto test_failure;
                        goto test_failure;
                } fclose(fp);
                } fclose(fp);
        }
        }
 
 
        printf("Attempting to write subsector 1\n");
        printf("Attempting to write subsector 1\n");
        for(int i=0; i<1024; i+= 64) {
        for(int i=0; i<1024; i+= 64) {
                printf("Turning off write-protect, calling WEL\n");
                printf("Turning off write-protect, calling WEL\n");
                tb->wb_write(0, 0x620001be);
                tb->wb_write(0, 0x620001be);
 
 
                printf("Writing from %08x to %08x from rdbuf\n",
                printf("Writing from %08x to %08x from rdbuf\n",
                        QSPIFLASH+1024+i, QSPIFLASH+1024+i+63);
                        QSPIFLASH+1024+i, QSPIFLASH+1024+i+63);
                // tb->wb_write(QSPIFLASH+1024+i, 64, &rdbuf[i]);
                // tb->wb_write(QSPIFLASH+1024+i, 64, &rdbuf[i]);
                tb->wb_write_slow(QSPIFLASH+1024+i, 64, &rdbuf[i], 32);
                tb->wb_write_slow(QSPIFLASH+1024+i, 64, &rdbuf[i], 32);
                while(tb->wb_read(0)&(0x80000000))
                while(tb->wb_read(0)&(0x80000000))
                        ;
                        ;
        }
        }
 
 
        tb->wb_read(QSPIFLASH+1024, 1024, &rdbuf[1024]);
        tb->wb_read(QSPIFLASH+1024, 1024, &rdbuf[1024]);
        for(int i=0; i<1024; i++) {
        for(int i=0; i<1024; i++) {
                if (rdbuf[i] != rdbuf[i+1024]) {
                if (rdbuf[i] != rdbuf[i+1024]) {
                        printf("BOMB: SUBSECTOR PROGRAM, EXPECTED[0x%02x] = 0x%08x != %08x\n", i, rdbuf[i], rdbuf[i+1024]);
                        printf("BOMB: SUBSECTOR PROGRAM, EXPECTED[0x%02x] = 0x%08x != %08x\n", i, rdbuf[i], rdbuf[i+1024]);
                        goto test_failure;
                        goto test_failure;
                }
                }
        }
        }
 
 
        // -Try to write an OTP register
        // -Try to write an OTP register
        printf("Turning off write-protect, calling WEL\n");
        printf("Turning off write-protect, calling WEL\n");
        tb->wb_write( 0, 0x620001be);
        tb->wb_write( 0, 0x620001be);
        printf("Writing OTP[2]\n");
        printf("Writing OTP[2]\n");
        tb->wb_write(18, 0x620001be);
        tb->wb_write(18, 0x620001be);
        while (tb->wb_read(0)&0x01000000)
        while (tb->wb_read(0)&0x01000000)
                ;
                ;
        while(tb->wb_read(0)&(0x80000000))
        while(tb->wb_read(0)&(0x80000000))
                ;
                ;
        if (0x620001be != tb->wb_read(18))
        if (0x620001be != tb->wb_read(18))
                goto test_failure;
                goto test_failure;
 
 
        // -Try to write protect all OTP register
        // -Try to write protect all OTP register
        printf("Turning off write-protect, calling WEL\n");
        printf("Turning off write-protect, calling WEL\n");
        tb->wb_write( 0, 0x620001be);
        tb->wb_write( 0, 0x620001be);
        printf("Writing OTP[END]\n");
        printf("Writing OTP[END]\n");
        tb->wb_write(15, 0);
        tb->wb_write(15, 0);
        while (tb->wb_read(0)&0x01000000)
        while (tb->wb_read(0)&0x01000000)
                ;
                ;
        while(tb->wb_read(0)&(0x80000000))
        while(tb->wb_read(0)&(0x80000000))
                ;
                ;
        if (0 != tb->wb_read(15))
        if (0 != tb->wb_read(15))
                goto test_failure;
                goto test_failure;
 
 
        // -Try to write OTP after write protecting all OTP registers
        // -Try to write OTP after write protecting all OTP registers
        printf("Turning off write-protect, calling WEL\n");
        printf("Turning off write-protect, calling WEL\n");
        tb->wb_write( 0, 0x620001be);
        tb->wb_write( 0, 0x620001be);
        printf("Writing OTP[7]\n");
        printf("Writing OTP[7]\n");
        tb->wb_write(16+7, 0);
        tb->wb_write(16+7, 0);
        while (tb->wb_read(0)&0x01000000)
        while (tb->wb_read(0)&0x01000000)
                ;
                ;
        while(tb->wb_read(0)&(0x80000000))
        while(tb->wb_read(0)&(0x80000000))
                ;
                ;
 
 
        // -Verify OTP not written
        // -Verify OTP not written
        if (0 == tb->wb_read(16+7))
        if (0 == tb->wb_read(16+7))
                goto test_failure;
                goto test_failure;
 
 
 
 
        printf("SUCCESS!!\n");
        printf("SUCCESS!!\n");
        exit(0);
        exit(0);
test_failure:
test_failure:
        printf("FAIL-HERE\n");
        printf("FAIL-HERE\n");
        for(int i=0; i<64; i++)
        for(int i=0; i<64; i++)
                tb->tick();
                tb->tick();
        printf("TEST FAILED\n");
        printf("TEST FAILED\n");
        exit(-1);
        exit(-1);
}
}
 
 

powered by: WebSVN 2.1.0

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