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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sim/] [verilator/] [zipmmu_tb.cpp] - Diff between revs 204 and 209

Show entire file | Details | Blame | View Log

Rev 204 Rev 209
Line 25... Line 25...
// 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
 
// 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
 
// <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
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Line 40... Line 45...
#include <verilated_vcd_c.h>
#include <verilated_vcd_c.h>
#include "testb.h"
#include "testb.h"
#include "Vzipmmu_tb.h"
#include "Vzipmmu_tb.h"
 
 
#define MMUFLAG_RONW    8 // Read only (not writeable)
#define MMUFLAG_RONW    8 // Read only (not writeable)
#define MMUFLAG_ACCS    4 // Accessed
#define MMUFLAG_EXE     4 // Page may be executed
#define MMUFLAG_CCHE    2 // Cachable
#define MMUFLAG_CCHE    2 // Cachable
#define MMUFLAG_THSP    1 // Page has this context
#define MMUFLAG_ACCS    1 // Accessed
 
#define ROFLAG  8       // This page is read-only
 
#define EXFLAG  4       // This page is executable
 
#define CHFLAG  2       // This page may be cached
 
#define AXFLAG  1       // This page has been accessed since loading
 
 
 
#define setup_stb       i_ctrl_cyc_stb
 
#define setup_ack       o_rtn_ack
 
#define setup_stall     o_rtn_stall
 
#define setup_data      o_rtn_data
 
#define mem_cyc         v__DOT__mem_cyc
 
#define mem_stb         v__DOT__mem_stb
 
#define mem_we          v__DOT__mem_we
 
#define mem_r_we        v__DOT__mut__DOT__r_we
 
#define mem_r_valid     v__DOT__mut__DOT__r_valid
 
#define mem_addr        v__DOT__mem_addr
 
#define mem_err         v__DOT__mem_err
 
#define wr_vtable       v__DOT__mut__DOT__wr_vtable
 
#define wr_ptable       v__DOT__mut__DOT__wr_ptable
 
#define wr_control      v__DOT__mut__DOT__wr_control
 
#define z_context       __PVT__mut__DOT__z_context
 
#define context_word    v__DOT__mut__DOT__r_context_word
 
#define r_pending       v__DOT__mut__DOT__r_pending
 
#define r_we            v__DOT__mut__DOT__r_we
 
#define r_valid         v__DOT__mut__DOT__r_valid
 
#define r_addr          v__DOT__mut__DOT__r_addr
 
#define r_data          v__DOT__mut__DOT__r_data
 
 
 
#define R_CONTROL               0
 
#define R_STATUS                4
 
#define R_TABLESZ(LGSZ)         (8<<LGSZ)
 
#define R_ENTRYSZ(LGSZ,K)       (R_TABLESZ(LGSZ)+(K<<3))
 
#define R_TABLE         (8<<LGTBL)
 
#define R_VENTRY(K)     ((8<<LGTBL)+(K<<3))
 
#define R_PENTRY(K)     (R_VENTRY(K)+4)
 
#define LOCONTEXT(C)    ((C<<4)&((1<<LGPGSZ)-1))
 
#define HICONTEXT(C)    (((C>>(LGPGSZ-4))<<4)&((1<<LGPGSZ)-1))
 
 
const int       BOMBCOUNT = 32,
const int       BOMBCOUNT = 32,
                LGMEMSIZE = 15;
                LGMEMSIZE = 15;
 
 
class   ZIPMMU_TB : public TESTB<Vzipmmu_tb> {
class   ZIPMMU_TB : public TESTB<Vzipmmu_tb> {
Line 58... Line 99...
        ZIPMMU_TB(void) {
        ZIPMMU_TB(void) {
                m_debug = true;
                m_debug = true;
                m_last_tlb_index = 0;
                m_last_tlb_index = 0;
        }
        }
 
 
#define v__DOT__mem_stb v__DOT__mut__DOT__r_valid
 
        void    tick(void) {
        void    tick(void) {
 
 
                TESTB<Vzipmmu_tb>::tick();
                TESTB<Vzipmmu_tb>::tick();
 
 
                bool    writeout = true;
                bool    writeout = true;
 
 
                if ((m_debug)&&(writeout)) {
                if ((m_debug)&&(writeout)) {
                        printf("%08lx-MMU: ", m_tickcount);
                        printf("%08lx-MMU: ", m_tickcount);
                        printf("(%s%s%s%s) %08x (%s%s%s)%08x%s %s %08x/%08x %s%s%s%s%s",
                        printf("(%s%s%s%s%s%s) %08x (%s%s%s)%08x%s %s %08x/%08x %s%s%s%s",
                                (m_core->i_ctrl_cyc_stb)?"CT":"  ",
                                (m_core->setup_stb)?"CT":"  ",
                                (m_core->i_wbm_cyc)?"CYC":"   ",
                                (m_core->i_wbm_cyc)?"CYC":"   ",
                                (m_core->i_wbm_stb)?"STB":"   ",
                                (m_core->i_wbm_stb)?"STB":"   ",
                                (m_core->i_wb_we)?"WE":"  ",
                                (m_core->i_wb_we)?"WE":"  ",
 
                                (m_core->i_gie)?"IE":"  ",
 
                                (m_core->i_exe)?"EX":"  ",
                                (m_core->i_wb_addr),
                                (m_core->i_wb_addr),
                                (m_core->v__DOT__mem_cyc)?"CYC":"   ",
                                (m_core->mem_cyc)?"CYC":"   ",
                                (m_core->v__DOT__mem_stb)?"STB":"   ",
                                (m_core->mem_stb)?"STB":"   ",
#define v__DOT__mem_we  v__DOT__mut__DOT__r_we
                                (m_core->mem_we)?"WE":"  ",
                                (m_core->v__DOT__mem_we)?"WE":"  ",
                                (m_core->mem_addr),
                                (m_core->v__DOT__mem_addr),
                                (m_core->mem_err)?"ER":"  ",
                                (m_core->v__DOT__mem_err)?"ER":"  ",
 
                                (m_core->i_wb_we)?"<-":"->",
                                (m_core->i_wb_we)?"<-":"->",
                                (m_core->i_wb_we)?m_core->i_wb_data:m_core->o_rtn_data,
                                (m_core->i_wb_we)?m_core->i_wb_data:m_core->o_rtn_data,
                                (m_core->v__DOT__mem_we)?m_core->v__DOT__mut__DOT__r_data:m_core->v__DOT__mem_odata,
                                (m_core->mem_we)?m_core->r_data:m_core->v__DOT__mem_odata,
                                (m_core->o_rtn_stall)?"STALL":"     ",
                                (m_core->o_rtn_stall)?"STALL":"     ",
                                (m_core->v__DOT__mut__DOT__setup_ack)?"S":" ",
 
                                (m_core->o_rtn_ack )?"ACK":"   ",
                                (m_core->o_rtn_ack )?"ACK":"   ",
                                (m_core->o_rtn_miss)?"MISS":"    ",
                                (m_core->o_rtn_miss)?"MISS":"    ",
                                (m_core->o_rtn_err )?"ERR":"   ");
                                (m_core->o_rtn_err )?"ERR":"   ");
 
 
                        printf("[%d,%d]",
                        printf("[%c]",
                                m_core->v__DOT__mut__DOT__wr_vtable,
                                (m_core->wr_control)?'C'
                                m_core->v__DOT__mut__DOT__wr_ptable);
                                :(m_core->wr_vtable)?'V'
                        printf("[%d,%d,%04x]",
                                :(m_core->wr_ptable)?'P'
                                m_core->v__DOT__mut__DOT__wr_control,
                                :'-');
                                m_core->v__DOT__mut__DOT__z_context,
                        printf("[%c,%04x]",
 
                                (m_core->v__DOT__mut__DOT__kernel_context)?'K'
 
                                :(m_core->v__DOT__mut__DOT__z_context)?'Z':'-',
                                m_core->v__DOT__mut__DOT__r_context_word);
                                m_core->v__DOT__mut__DOT__r_context_word);
                        /*
 
                        printf("[%08x,%08x-%08x]",
 
                                m_core->v__DOT__mut__DOT__w_vtable_reg,
 
                                m_core->v__DOT__mut__DOT__w_ptable_reg,
 
                                m_core->v__DOT__mut__DOT__setup_data);
 
                        */
 
                        printf(" %s[%s%s@%08x,%08x]",
                        printf(" %s[%s%s@%08x,%08x]",
                                (m_core->v__DOT__mut__DOT__r_pending)?"R":" ",
                                (m_core->r_pending)?"R":" ",
                                (m_core->v__DOT__mut__DOT__r_we)?"W":" ",
                                (m_core->r_we)?"W":" ",
                                (m_core->v__DOT__mut__DOT__r_valid)?"V":" ",
                                (m_core->r_valid)?"V":" ",
                                (m_core->v__DOT__mut__DOT__r_addr),
                                (m_core->r_addr),
                                (m_core->v__DOT__mut__DOT__r_data));
                                (m_core->r_data));
                        printf("@%2x[%s%s%s][%s%s%s%s]",
                        printf("@%2x[%s%s%s][%s%s%s%s%s]",
                                (m_core->v__DOT__mut__DOT__s_tlb_addr),
                                (m_core->v__DOT__mut__DOT__s_tlb_addr),
                                (m_core->v__DOT__mut__DOT__s_pending)?"P":" ",
                                (m_core->v__DOT__mut__DOT__s_pending)?"P":" ",
                                (m_core->v__DOT__mut__DOT__s_tlb_hit)?"HT":"  ",
                                (m_core->v__DOT__mut__DOT__s_tlb_hit)?"HT":"  ",
                                (m_core->v__DOT__mut__DOT__s_tlb_miss)?"MS":"  ",
                                (m_core->v__DOT__mut__DOT__s_tlb_miss)?"MS":"  ",
                                (m_core->v__DOT__mut__DOT__ro_flag)?"RO":"  ",
                                (m_core->v__DOT__mut__DOT__ro_flag)?"RO":"  ",
                                (m_core->v__DOT__mut__DOT__simple_miss)?"SM":"  ",
                                (m_core->v__DOT__mut__DOT__simple_miss)?"SM":"  ",
                                (m_core->v__DOT__mut__DOT__ro_miss)?"RM":"  ",
                                (m_core->v__DOT__mut__DOT__ro_miss)?"RM":"  ",
 
                                (m_core->v__DOT__mut__DOT__exe_miss)?"EX":"  ",
                                (m_core->v__DOT__mut__DOT__table_err)?"TE":"  ");
                                (m_core->v__DOT__mut__DOT__table_err)?"TE":"  ");
                                //(m_core->v__DOT__mut__DOT__cachable)?"CH":"  ");
                                //(m_core->v__DOT__mut__DOT__cachable)?"CH":"  ");
                        /*
                        /*
                        printf(" M[%016lx]",
                        printf(" M[%016lx]",
                                m_core->v__DOT__mut__DOT__r_tlb_match);
                                m_core->v__DOT__mut__DOT__r_tlb_match);
                        printf(" P[%3d] = 0x%08x, V=0x%08x, C=0x%08x, CTXT=%04x",
 
                                m_last_tlb_index,
 
                                m_core->v__DOT__mut__DOT__tlb_pdata[m_last_tlb_index],
 
                                m_core->v__DOT__mut__DOT__tlb_vdata[m_last_tlb_index],
 
                                m_core->v__DOT__mut__DOT__tlb_cdata[m_last_tlb_index],
 
                                m_core->v__DOT__mut__DOT__r_context_word);
 
                        */
                        */
 
                        printf(" P[%3d%c] = 0x%03x, V=0x%03x, C=0x%04x, CTXT=%04x",
 
                                m_last_tlb_index,
 
                                ((m_core->v__DOT__mut__DOT__tlb_valid>>m_last_tlb_index)&1)?'V':'u',
 
                                m_core->v__DOT__mut__DOT__tlb_pdata[m_last_tlb_index],
 
                                m_core->v__DOT__mut__DOT__tlb_vdata[m_last_tlb_index],
 
                                m_core->v__DOT__mut__DOT__tlb_cdata[m_last_tlb_index],
 
                                m_core->v__DOT__mut__DOT__r_context_word);
                        printf("\n");
                        printf("\n");
                }
                }
        }
        }
 
 
        void reset(void) {
        void reset(void) {
                m_core->i_rst    = 1;
                m_core->i_reset    = 1;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_ctrl_cyc_stb = 0;
 
                m_core->i_gie      = 0;
 
                m_core->i_exe      = 0;
                m_core->i_wbm_cyc  = 0;
                m_core->i_wbm_cyc  = 0;
                m_core->i_wbm_stb  = 0;
                m_core->i_wbm_stb  = 0;
                tick();
                tick();
                m_core->i_rst  = 0;
                m_core->i_reset  = 0;
        }
        }
 
 
        void wb_tick(void) {
        void wb_tick(void) {
                m_core->i_rst  = 0;
                m_core->i_reset  = 0;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_wbm_cyc  = 0;
                m_core->i_wbm_cyc  = 0;
                m_core->i_wbm_stb  = 0;
                m_core->i_wbm_stb  = 0;
                tick();
                tick();
                assert(!m_core->o_rtn_ack);
                assert(!m_core->o_rtn_ack);
                assert(!m_core->o_rtn_err);
                assert(!m_core->o_rtn_err);
        }
        }
 
 
        unsigned operator[](unsigned a) {
        unsigned operator[](unsigned a) {
                a &= ((1<<LGMEMSIZE)-1);
                unsigned        msk = (1<<LGMEMSIZE)-1;
 
// printf("OP[] Reading from %08x\n", a);
 
                assert((a&3)==0);
 
                a = (a>>2)&(msk);
 
// printf("OP[] ----> %08x\n", a);
                return m_core->v__DOT__ram__DOT__mem[a];
                return m_core->v__DOT__ram__DOT__mem[a];
        }
        }
 
 
        unsigned setup_read(unsigned a) {
        unsigned setup_read(unsigned a) {
                int             errcount = 0;
                int             errcount = 0;
                unsigned        result;
                unsigned        result;
                m_miss = false; m_err = false;
                m_miss = false; m_err = false;
 
 
                printf("WB-READS(%08x)\n", a);
                printf("WB-READS(%08x)\n", a);
 
 
                m_core->i_ctrl_cyc_stb = 1;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_wbm_cyc = 0;
                m_core->i_wbm_cyc = 0;
                m_core->i_wbm_stb = 0;
                m_core->i_wbm_stb = 0;
                m_core->i_wb_we  = 0;
                m_core->i_wb_we  = 0;
                m_core->i_wb_addr= a;
                m_core->i_wb_addr= a>>2;
 
 
 
                if (m_core->i_gie) {
 
                        m_core->i_gie = 0;
 
                        wb_tick();
 
                }
 
 
 
                m_core->i_ctrl_cyc_stb = 1;
 
 
                if (m_core->o_rtn_stall) {
                if (m_core->o_rtn_stall) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall))
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall))
                                tick();
                                tick();
                } tick();
                } tick();
Line 207... Line 258...
                int             errcount = 0;
                int             errcount = 0;
                m_miss = false; m_err = false;
                m_miss = false; m_err = false;
 
 
                printf("WB-WRITES(%08x,%08x)\n", a,v);
                printf("WB-WRITES(%08x,%08x)\n", a,v);
 
 
                m_core->i_ctrl_cyc_stb = 1;
                m_core->i_ctrl_cyc_stb = 0;
 
                m_core->i_exe = 0;
                m_core->i_wbm_cyc = 0;
                m_core->i_wbm_cyc = 0;
                m_core->i_wbm_stb = 0;
                m_core->i_wbm_stb = 0;
                m_core->i_wb_we  = 1;
                m_core->i_wb_we  = 1;
                m_core->i_wb_addr= a;
                m_core->i_wb_addr= a>>2;
                m_core->i_wb_data= v;
                m_core->i_wb_data= v;
 
                m_core->i_wb_sel= 15;
 
 
 
                if (m_core->i_gie) {
 
                        m_core->i_gie = 0;
 
                        wb_tick();
 
                }
 
                m_core->i_ctrl_cyc_stb = 1;
 
 
                if (a & 0x080)
 
                        m_last_tlb_index = (a>>1)&0x3f;
                if (a & 0x0200)
 
                        m_last_tlb_index = (a>>3)&0x3f;
 
 
                if (m_core->o_rtn_stall) {
                if (m_core->o_rtn_stall) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall))
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall))
                                tick();
                                tick();
                } tick();
                } tick();
Line 258... Line 318...
 
 
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wb_we  = 0;
                m_core->i_wb_we  = 0;
                m_core->i_wb_addr= a;
                m_core->i_wb_addr= a>>2;
 
 
                if (m_core->o_rtn_stall) {
                if (m_core->o_rtn_stall) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
                                tick();
                                tick();
                                if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) {
                                if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) {
Line 343... Line 403...
 
 
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wb_we   = 0;
                m_core->i_wb_we   = 0;
                m_core->i_wb_addr = a;
                m_core->i_wb_addr = a>>2;
 
 
                rdidx =0; cnt = 0;
                rdidx =0; cnt = 0;
                inc = 1;
                inc = 1;
 
 
                do {
                do {
Line 415... Line 475...
                printf("WB-WRITEM(%08x) <= %08x\n", a, v);
                printf("WB-WRITEM(%08x) <= %08x\n", a, v);
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wb_we  = 1;
                m_core->i_wb_we  = 1;
                m_core->i_wb_addr= a;
                m_core->i_wb_addr= a>>2;
                m_core->i_wb_data= v;
                m_core->i_wb_data= v;
 
                m_core->i_wb_sel= 15;
 
 
                if (m_core->o_rtn_stall)
                if (m_core->o_rtn_stall)
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
                                printf("Stalled, so waiting, errcount=%d\n", errcount);
                                printf("Stalled, so waiting, errcount=%d\n", errcount);
                                tick();
                                tick();
Line 495... Line 556...
                printf("WB-WRITEM(%08x, %d, ...)\n", a, ln);
                printf("WB-WRITEM(%08x, %d, ...)\n", a, ln);
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_ctrl_cyc_stb = 0;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_cyc = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wbm_stb = 1;
                m_core->i_wb_we  = 1;
                m_core->i_wb_we  = 1;
 
                m_core->i_wb_sel= 15;
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
                for(unsigned stbcnt=0; stbcnt<ln; stbcnt++) {
                        m_core->i_wb_addr= a+stbcnt;
                        m_core->i_wb_addr= (a>>2)+stbcnt;
                        m_core->i_wb_data= buf[stbcnt];
                        m_core->i_wb_data= buf[stbcnt];
                        errcount = 0;
                        errcount = 0;
 
 
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
                        while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) {
                                tick();
                                tick();
Line 590... Line 652...
 
 
void    install_page(ZIPMMU_TB *tb, int idx, unsigned va, unsigned pa, int flags) {
void    install_page(ZIPMMU_TB *tb, int idx, unsigned va, unsigned pa, int flags) {
        int     LGTBL, LGPGSZ, LGCTXT;
        int     LGTBL, LGPGSZ, LGCTXT;
        int     c;
        int     c;
        unsigned base;
        unsigned base;
        bool    hdebug = tb->debug();
        // bool hdebug = tb->debug();
 
 
        tb->debug(false);
        // tb->debug(false);
        c=tb->setup_read(0);
        c=tb->setup_read(R_CONTROL);
        printf("CONTEXT-REG = %08x\n", c);
        printf("CONTEXT-REG = %08x\n", c);
        LGTBL  = ((c>>24)&15);
        LGTBL  = ((c>>24)&15);
        LGPGSZ= (((c>>20)&15)+8)&31;
        LGPGSZ= (((c>>20)&15)+10)&31;   // In bytes
        LGCTXT= (((c>>16)&15)+1)&31;
        LGCTXT= (((c>>16)&15)+1)&31;
        c &= ((1<<LGCTXT)-1);
        c &= ((1<<LGCTXT)-1);
        base  = (2<<LGTBL)+(idx<<1);
        base  = R_ENTRYSZ(LGTBL, idx);
        va &= -(1<<LGPGSZ);
        va &= -(1<<LGPGSZ);
        pa &= -(1<<LGPGSZ);
        pa &= -(1<<LGPGSZ);
 
 
        printf("INSTALL[%2d] %04x:%08xV -> %08xP %s%s\n",
        printf("INSTALL[%2d] %04x:%03x[%04x]%xV -> %03x[%04x]%xP %s%s\n",
                idx, c, va, pa,
                idx, c,
 
                (va>>LGPGSZ), LOCONTEXT(c)>>4, flags,
 
                (pa>>LGPGSZ), HICONTEXT(c)>>4, 0,
                (flags&MMUFLAG_RONW)?"RO":"  ",
                (flags&MMUFLAG_RONW)?"RO":"  ",
                (flags&MMUFLAG_CCHE)?"Cachable":"");
                (flags&MMUFLAG_CCHE)?"Cachable":"");
        tb->setup_write(base  , va|(( c    &0x0ff)<<4)|flags);
        tb->setup_write(base  , va|(LOCONTEXT(c))|flags);
        tb->setup_write(base+1, pa|(((c>>8)&0x0ff)<<4)|flags);
        tb->setup_write(base+4, pa|(HICONTEXT(c)));
        tb->debug(hdebug);
        // tb->debug(hdebug);
 
        tb->tick();
 
        tb->m_core->i_gie = 1;
}
}
 
 
int main(int  argc, char **argv) {
int main(int  argc, char **argv) {
        Verilated::commandArgs(argc, argv);
        Verilated::commandArgs(argc, argv);
        ZIPMMU_TB       *tb = new ZIPMMU_TB;
        ZIPMMU_TB       *tb = new ZIPMMU_TB;
        unsigned        *rdbuf; // *mbuf;
        unsigned        *rdbuf; // *mbuf;
        unsigned        mlen = (1<<LGMEMSIZE), c, blen;
        unsigned        mlen = (1<<LGMEMSIZE), c, blen;
 
        const unsigned  CONTEXT = 0x0fef7;
 
 
        tb->opentrace("zipmmu_tb.vcd");
        tb->opentrace("zipmmu_tb.vcd");
        printf("Giving the core 2 cycles to start up\n");
        printf("Giving the core 2 cycles to start up\n");
        // Before testing, let's give the unit time enough to warm up
        // Before testing, let's give the unit time enough to warm up
        tb->reset();
        tb->reset();
Line 634... Line 701...
        // mbuf  = new unsigned[mlen]; // Match buffer
        // mbuf  = new unsigned[mlen]; // Match buffer
        printf("Charging my memory with random values\n");
        printf("Charging my memory with random values\n");
        uload(mlen, rdbuf);
        uload(mlen, rdbuf);
 
 
 
 
        int     LGADR, LGTBL, LGPGSZ, LGCTXT, sr;
        int     LGADR, LGTBL, LGPGSZ, LGCTXT, sr, PAGESZ;
 
 
        c=tb->setup_read(0);
        c=tb->setup_read(R_CONTROL);
        printf("CONTROL-REG = %08x\n = %2d\n", c, c);
        printf("CONTROL-REG = %08x\n = %2d\n", c, c);
        sr = tb->setup_read(1);
        sr = tb->setup_read(R_STATUS);
        printf("STATUS-REG  = %08x = %2d\n", sr, sr);
        printf("STATUS-REG  = %08x = %2d\n", sr, sr);
        LGADR = (((c>>28)&15)+17)&31;
        LGADR = (((c>>28)&15)+17)&31;
        LGTBL = ((c>>24)&15);
        LGTBL = ((c>>24)&15);
        LGPGSZ= (((c>>20)&15)+8)&31;
        LGPGSZ= (((c>>20)&15)+10)&31;
 
        PAGESZ= 1ul<<LGPGSZ;
        LGCTXT= (((c>>16)&15)+1)&31;
        LGCTXT= (((c>>16)&15)+1)&31;
        printf("LGADR       = %08x = %2d\n", LGADR, LGADR);
        printf("LGADR       = %08x = %2d\n", LGADR, LGADR);
        printf("LGTBL       = %08x = %2d\n", LGTBL, LGTBL);
        printf("LGTBL       = %08x = %2d\n", LGTBL, LGTBL);
        printf("LGPGSZ      = %08x = %2d\n", LGPGSZ, LGPGSZ);
        printf("LGPGSZ      = %08x = %2d\n", LGPGSZ, LGPGSZ);
        printf("LGCTXT      = %08x = %2d\n", LGCTXT, LGCTXT);
        printf("LGCTXT      = %08x = %2d\n", LGCTXT, LGCTXT);
 
        printf("PAGESZ      = %08x = %2d\n", PAGESZ, PAGESZ);
 
 
        // First, let's make sure we can read/write the context
        // First, let's make sure we can read/write the context
        printf("\n\nTest: Can we read/write the context register?\n");
        printf("\n\nTest: Can we read/write the context register?\n");
        tb->setup_write(0,0x01fec);
        tb->setup_write(R_CONTROL,CONTEXT);
        c=tb->setup_read(0);
        c=tb->setup_read(R_CONTROL);
        printf("CONTEXT     = %08x (0x1fec?)\n", c&0x0ffff);
        printf("CONTEXT     = %04x (0x%04x)\n", c &0x0ffff, CONTEXT & 0x0ffff);
        if ((c&0x0ffff) != 0x01fec)
        if ((c&0x0ffff) != CONTEXT)
                goto test_failure;
                goto test_failure;
 
 
        // Load the table with TLB misses
        // Load the table with TLB misses
        printf("\n\nTest: Can we load the table with TLB misses? (%d entries)\n", (1<<LGTBL));
        printf("\n\nTest: Can we load the table with TLB misses? (%d entries)\n", (1<<LGTBL));
        for(int i=0; i<(1<<LGTBL); i++) {
        for(int i=0; i<(1<<LGTBL); i++) {
                c = 0x0f70; // Context: 0xfef7
                c = CONTEXT; // Context: 0xfef7, no flags
                tb->setup_write((2<<LGTBL)+(i<<1)  , c+(((1<<LGTBL)-1-i)<<LGPGSZ));
                tb->setup_write(R_VENTRY(i), (LOCONTEXT(c))
                c = 0x0fe2; // CCHE flag only
                        |(((1<<LGTBL)-1-i)<<LGPGSZ) | ROFLAG);
                tb->setup_write((2<<LGTBL)+(i<<1)+1, c+(((1<<LGTBL)-1-i)<<LGPGSZ));
                tb->setup_write(R_PENTRY(i), (HICONTEXT(c))
 
                        |(((1<<LGTBL)-1-i)<<LGPGSZ));
        }
        }
 
 
        // Dump the table, make sure we got it right
        // Dump the table, make sure we got it right
        for(int i=0; i<(1<<LGTBL); i++) {
        for(int i=0; i<(1<<LGTBL); i++) {
                unsigned v, p;
                unsigned v, p, c;
                v=tb->setup_read((2<<LGTBL)+(i<<1)  );
 
                p=tb->setup_read((2<<LGTBL)+(i<<1)+1);
                c = 0x0fef7;
 
                v=tb->setup_read(R_VENTRY(i));
 
                p=tb->setup_read(R_PENTRY(i));
 
 
                printf("TBL[%2d] = %08x -> %08x\n", i, v, p);
                printf("TBL[%2d] = %08x -> %08x", i, v, p);
                if (v != (unsigned)(0x00f72+(((1<<LGTBL)-1-i)<<LGPGSZ)))
                printf("\tEXPECTING %08x -> %08x\n",
 
                        (unsigned)((LOCONTEXT(c))|(((1<<LGTBL)-1-i)<<LGPGSZ)|ROFLAG),
 
                        (unsigned)(HICONTEXT(c))|(((1<<LGTBL)-1-i)<<LGPGSZ));
 
                if (v != (unsigned)((LOCONTEXT(c))|(((1<<LGTBL)-1-i)<<LGPGSZ)|ROFLAG))
                        goto test_failure;
                        goto test_failure;
                if (p != (unsigned)(0x00fe2+(((1<<LGTBL)-1-i)<<LGPGSZ)))
                if (p != (unsigned)((HICONTEXT(c))|(((1<<LGTBL)-1-i)<<LGPGSZ)))
                        goto test_failure;
                        goto test_failure;
        }
        } printf("-- PASS\n\n");
 
 
        // Now, let's create a fictitious process, context 1, with no pages.
        // Now, let's create a fictitious process, context 1, with no pages.
        // See what happens when we try to access his stack at 0xffffffff
        // See what happens when we try to access his stack at 0xffffffff
        bool    tberr;
        bool    tberr;
        printf("\n\nTest: Do we get a TLB miss when attempting to find a non-existent page?\n");
        printf("\n\nTest: Do we get a TLB miss when attempting to find a non-existent page?\n");
 
        tb->m_core->i_gie = 1;
 
        tb->tick();
        tberr = false;
        tberr = false;
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
        tb->wb_write(0xfffffffc, 0x0fe, &tberr);
        if ((!tberr)||(!tb->miss())||(tb->err())) {
        if ((!tberr)||(!tb->miss())||(tb->err())) {
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tb->err())?"true":"false");
                        (tb->err())?"true":"false");
                goto test_failure;
                goto test_failure;
        }
        } printf("-- PASS\n\n");
 
 
        tberr = false;
        tberr = false;
        install_page(tb, 0, 0x0ffffffff, (1<<LGMEMSIZE)+0*(1<<LGPGSZ),
        install_page(tb, 0, 0xfffffffc, (4<<LGMEMSIZE)+0*PAGESZ,
                        MMUFLAG_RONW);
                        MMUFLAG_RONW);
        printf("\n\nTest: Do we get a TLB miss when attempting to write a RO page?\n");
        printf("\n\nTest: Do we get a TLB miss when attempting to write a RO page?\n");
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
        if ((!tberr)||(!tb->miss())||(tb->err())) {
        if ((!tberr)||(!tb->miss())||(tb->err())) {
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tb->err())?"true":"false");
                        (tb->err())?"true":"false");
                goto test_failure;
                goto test_failure;
        }
        } printf("-- PASS\n\n");
 
 
        tberr = false;
        tberr = false;
        printf("\n\nTest: What if we make this into a writeable page?\n");
        printf("\n\nTest: What if we make this into a writeable page?\n");
        install_page(tb, 0, 0xffffffff, (1<<LGMEMSIZE)+0*(1<<LGPGSZ), 0);
        install_page(tb, 0, 0xfffffffc, (4<<LGMEMSIZE)+0*PAGESZ, 0);
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
        tb->m_core->i_gie = 1;
 
        tb->m_core->i_exe = 0;
 
        tb->wb_write(0xfffffff8, 0x0fe, &tberr);
        if (tberr) {
        if (tberr) {
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tb->err())?"true":"false");
                        (tb->err())?"true":"false");
                goto test_failure;
                goto test_failure;
        }
        } printf("-- PASS\n\n");
        printf("\n\nTest: Is the next access done w/in a single clock?\n");
        printf("\n\nTest: Is the next access done w/in a single clock?\n");
        tb->wb_write(0xfffffff7, 0xdeadbeef, &tberr);
        tb->wb_write(0xfffffffc, 0xdeadbeef, &tberr);
        if (tberr) {
        if (tberr) {
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tb->err())?"true":"false");
                        (tb->err())?"true":"false");
                goto test_failure;
                goto test_failure;
        }
        } printf("-- PASS\n\n");
 
 
 
 
        tberr = false;
        tberr = false;
        printf("\n\nTest: What if we make this into a writeable page?\n");
        printf("\n\nTest: What if we make this into a writeable page?\n");
        install_page(tb, 0, 0xffffffff, (1<<LGMEMSIZE)+0*(1<<LGPGSZ), 0);
        install_page(tb, 0, 0xffffffff, (4<<LGMEMSIZE)+0*PAGESZ, 0);
        tb->wb_write(0xffffffff, 0x0fe, &tberr);
        tb->wb_write(0xfffffffc, 0x0fe, &tberr);
        if ((tberr)||((*tb)[0x0fff]!=0x0fe)) {
        if ((tberr)||((*tb)[0x0ffc]!=0x0fe)) {
                unsigned v;
                unsigned v;
                v = ((*tb)[0x0fff]!=0x0fe);
                v = ((*tb)[0x0ffc]!=0x0fe);
                printf("V     = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS  = %s\nERR   = %s\n",
                printf("V     = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS  = %s\nERR   = %s\n",
                        v, (tberr)?"true":"false", (tb->miss())?"true":"false",
                        v, (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tb->err())?"true":"false");
                        (tb->err())?"true":"false");
                goto test_failure;
                goto test_failure;
        }
        } printf("-- PASS\n\n");
 
 
        tberr = false;
        tberr = false;
        printf("\n\nTest: How about a read from the same location?\n");
        printf("\n\nTest: How about a read from the same location?\n");
        {
        {
                unsigned        v;
                unsigned        v;
                v = tb->wb_read(0xffffffff, &tberr);
                v = tb->wb_read(0xfffffffc, &tberr);
                if ((tberr)||(v != 0x0fe)) {
                if ((tberr)||(v != 0x0fe)) {
                        printf("V     = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS  = %s\nERR   = %s\n",
                        printf("V     = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS  = %s\nERR   = %s\n",
                                v,
                                v,
                                (tberr)?"true":"false", (tb->miss())?"true":"false",
                                (tberr)?"true":"false", (tb->miss())?"true":"false",
                                (tb->err())?"true":"false");
                                (tb->err())?"true":"false");
                        goto test_failure;
                        goto test_failure;
                }
                }
        }
        } printf("-- PASS\n\n");
 
 
        printf("Test: Burst write, within page\n");
        printf("Test: Burst write, within page (PAGESZ = %04x)\n", PAGESZ);
        tb->setup_write(0, 0x0dad);
        tb->setup_write(R_CONTROL, 0x0dad);
        install_page(tb, 0, ((0x0ffffffffl)&(-(1l<<LGPGSZ)))-2*(1<<LGPGSZ), (1<<LGMEMSIZE)+0*(1<<LGPGSZ), 0);
#define TEST_VPAGE      ((0x0ffffffffl)&(-(1l<<LGPGSZ)))
        install_page(tb, 1, ((0x0ffffffffl)&(-(1l<<LGPGSZ)))-1*(1<<LGPGSZ), (1<<LGMEMSIZE)+1*(1<<LGPGSZ), 0);
        install_page(tb, 0, TEST_VPAGE-2*PAGESZ, (4<<LGMEMSIZE)+0*PAGESZ, 0);
        install_page(tb, 2, ((0x0ffffffffl)&(-(1l<<LGPGSZ)))+0*(1<<LGPGSZ), (1<<LGMEMSIZE)+2*(1<<LGPGSZ), 0);
        install_page(tb, 1, TEST_VPAGE-1*PAGESZ, (4<<LGMEMSIZE)+1*PAGESZ, 0);
 
        install_page(tb, 2, TEST_VPAGE-0*PAGESZ, (4<<LGMEMSIZE)+2*PAGESZ, 0);
 
 
        tberr = false;
        tberr = false;
        blen = (1<<(LGPGSZ-2));
        blen = (1<<(LGPGSZ-2));
        tb->wb_write(((0xffffffff)&(-(1l<<LGPGSZ)))-2*(1<<LGPGSZ), blen, rdbuf, &tberr);
        tb->wb_write(TEST_VPAGE-2*(1<<LGPGSZ), blen, rdbuf, &tberr);
        if (tberr) {
        if (tberr) {
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tb->err())?"true":"false");
                        (tb->err())?"true":"false");
                printf("STATUS= %08x\n", tb->setup_read(1));
                printf("STATUS= %08x\n", tb->setup_read(R_STATUS));
                goto test_failure;
                goto test_failure;
        } for(unsigned i=0; i<blen; i++) {
        } for(unsigned i=0; i<blen; i++) {
                if ((*tb)[i] != rdbuf[i]) {
                if ((*tb)[i*4] != rdbuf[i]) {
                        printf("MEM[%04x] = %08x (!= %08x as expected)\n",
                        printf("MEM[%04x] = %08x (!= %08x as expected)\n",
                                i, (*tb)[i], rdbuf[i]);
                                i, (*tb)[4*i], rdbuf[i]);
                        goto test_failure;
                        goto test_failure;
                }
                }
        }
        } printf("-- PASS\n\n");
 
 
        printf("Test: Burst read\n");
        printf("Test: Burst read\n");
        // Try somewhere within that last page
        // Try somewhere within that last page
        tberr = false;
        tberr = false;
        tb->wb_read(((0xffffffff)&(-(1<<LGPGSZ)))-2*(1<<LGPGSZ)+18, blen, rdbuf, &tberr);
        tb->wb_read(TEST_VPAGE-2*(1<<LGPGSZ)+(18*4), blen, rdbuf, &tberr);
        if (tberr) {
        if (tberr) {
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                printf("TBERR = %s\nMISS  = %s\nERR   = %s\n",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tberr)?"true":"false", (tb->miss())?"true":"false",
                        (tb->err())?"true":"false");
                        (tb->err())?"true":"false");
                printf("STATUS= %08x\n", tb->setup_read(1));
                printf("STATUS= %08x\n", tb->setup_read(R_STATUS));
                goto test_failure;
                goto test_failure;
        } for(unsigned i=0; i<blen; i++) {
        } for(unsigned i=0; i<blen; i++) {
                if ((*tb)[i+18] != rdbuf[i]) {
                if ((*tb)[(i+18)*4] != rdbuf[i]) {
                        printf("MEM[%04x] = %08x (!= %08x as expected)\n",
                        printf("MEM[%04x] = %08x (!= %08x as expected)\n",
                                i+18, (*tb)[i+18], rdbuf[i]);
                                i+18, (*tb)[i+18], rdbuf[i]);
                        goto test_failure;
                        goto test_failure;
                }
                }
        }
        } printf("-- PASS\n\n");
 
 
 
 
        printf("Tests not (yet) implemented\n");
        printf("Tests not (yet) implemented\n");
        printf("Test: Burst read crossing pages, second page valid\n");
        printf("Test: Burst read crossing pages, second page valid\n");
        printf("Test: Burst read crossing pages, second page invalid\n");
        printf("Test: Burst read crossing pages, second page invalid\n");

powered by: WebSVN 2.1.0

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