Line 36... |
Line 36... |
//
|
//
|
#include <signal.h>
|
#include <signal.h>
|
#include <time.h>
|
#include <time.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <poll.h>
|
#include <poll.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
#include <ctype.h>
|
#include <ctype.h>
|
#include <ncurses.h>
|
#include <ncurses.h>
|
|
|
#include "verilated.h"
|
#include "verilated.h"
|
Line 53... |
Line 56... |
#include "zopcodes.h"
|
#include "zopcodes.h"
|
#include "zparser.h"
|
#include "zparser.h"
|
|
|
#define CMD_REG 0
|
#define CMD_REG 0
|
#define CMD_DATA 1
|
#define CMD_DATA 1
|
|
#define CMD_GIE (1<<13)
|
|
#define CMD_SLEEP (1<<12)
|
|
#define CMD_CLEAR_CACHE (1<<11)
|
#define CMD_HALT (1<<10)
|
#define CMD_HALT (1<<10)
|
#define CMD_STALL (1<<9)
|
#define CMD_STALL (1<<9)
|
#define CMD_INT (1<<7)
|
#define CMD_INT (1<<7)
|
#define CMD_RESET (1<<6)
|
#define CMD_RESET (1<<6)
|
#define CMD_STEP ((1<<8)|CMD_HALT)
|
#define CMD_STEP ((1<<8)|CMD_HALT)
|
Line 65... |
Line 71... |
#define KEY_RETURN 10
|
#define KEY_RETURN 10
|
#define CTRL(X) ((X)&0x01f)
|
#define CTRL(X) ((X)&0x01f)
|
|
|
#define MAXERR 10000
|
#define MAXERR 10000
|
|
|
|
#define LGRAMLEN 20
|
|
#define RAMBASE 0x100000
|
|
#define MEMWORDS (1<<LGRAMLEN)
|
|
|
class SPARSEMEM {
|
class SPARSEMEM {
|
public:
|
public:
|
bool m_valid;
|
bool m_valid;
|
unsigned int m_a, m_d;
|
unsigned int m_a, m_d;
|
Line 95... |
Line 104... |
class ZIPPY_TB : public TESTB<Vzipsystem> {
|
class ZIPPY_TB : public TESTB<Vzipsystem> {
|
public:
|
public:
|
unsigned long m_mem_size;
|
unsigned long m_mem_size;
|
MEMSIM m_mem;
|
MEMSIM m_mem;
|
// QSPIFLASHSIM m_flash;
|
// QSPIFLASHSIM m_flash;
|
FILE *dbg_fp, *m_profile_fp;
|
FILE *m_dbgfp, *m_profile_fp;
|
bool dbg_flag, bomb, m_show_user_timers;
|
bool dbg_flag, bomb, m_show_user_timers;
|
int m_cursor;
|
int m_cursor;
|
unsigned long m_last_instruction_tickcount;
|
unsigned long m_last_instruction_tickcount;
|
ZIPSTATE m_state;
|
ZIPSTATE m_state;
|
|
|
ZIPPY_TB(void) : m_mem_size(1<<20), m_mem(m_mem_size) {
|
ZIPPY_TB(void) : m_mem_size(MEMWORDS), m_mem(m_mem_size) {
|
if (false) {
|
if (false) {
|
dbg_fp = fopen("dbg.txt", "w");
|
m_dbgfp = fopen("dbg.txt", "w");
|
dbg_flag = true;
|
dbg_flag = true;
|
} else {
|
} else {
|
dbg_fp = NULL;
|
m_dbgfp = NULL;
|
dbg_flag = false;
|
dbg_flag = false;
|
}
|
}
|
bomb = false;
|
bomb = false;
|
m_cursor = 0;
|
m_cursor = 0;
|
m_show_user_timers = false;
|
m_show_user_timers = false;
|
Line 122... |
Line 131... |
m_profile_fp = NULL;
|
m_profile_fp = NULL;
|
}
|
}
|
}
|
}
|
|
|
~ZIPPY_TB(void) {
|
~ZIPPY_TB(void) {
|
if (dbg_fp)
|
if (m_dbgfp)
|
fclose(dbg_fp);
|
fclose(m_dbgfp);
|
if (m_profile_fp)
|
if (m_profile_fp)
|
fclose(m_profile_fp);
|
fclose(m_profile_fp);
|
}
|
}
|
|
|
void reset(void) {
|
void reset(void) {
|
Line 152... |
Line 161... |
for(int i=0; i<16; i++)
|
for(int i=0; i<16; i++)
|
m_state.m_uR[i] = cmd_read(i+16);
|
m_state.m_uR[i] = cmd_read(i+16);
|
for(int i=0; i<20; i++)
|
for(int i=0; i<20; i++)
|
m_state.m_p[i] = cmd_read(i+32);
|
m_state.m_p[i] = cmd_read(i+32);
|
|
|
m_state.m_gie = (m_state.m_sR[14] & 0x020);
|
m_state.m_gie = wb_read(CMD_REG) & CMD_GIE;
|
m_state.m_pc = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]);
|
m_state.m_pc = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]);
|
m_state.m_sp = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]);
|
m_state.m_sp = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]);
|
|
|
if (m_state.m_last_pc_valid)
|
if (m_state.m_last_pc_valid)
|
m_state.m_imem[0].m_a = m_state.m_last_pc;
|
m_state.m_imem[0].m_a = m_state.m_last_pc;
|
Line 201... |
Line 210... |
for(int i=0; i<16; i++)
|
for(int i=0; i<16; i++)
|
m_state.m_uR[i] = m_core->v__DOT__thecpu__DOT__regset[i+16];
|
m_state.m_uR[i] = m_core->v__DOT__thecpu__DOT__regset[i+16];
|
m_state.m_uR[14] = (m_state.m_uR[14]&0xffffe000)|m_core->v__DOT__thecpu__DOT__w_uflags;
|
m_state.m_uR[14] = (m_state.m_uR[14]&0xffffe000)|m_core->v__DOT__thecpu__DOT__w_uflags;
|
m_state.m_uR[15] = m_core->v__DOT__thecpu__DOT__upc;
|
m_state.m_uR[15] = m_core->v__DOT__thecpu__DOT__upc;
|
|
|
m_state.m_gie = (m_state.m_sR[14] & 0x020);
|
m_state.m_gie = m_core->v__DOT__thecpu__DOT__gie;
|
m_state.m_pc = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]);
|
m_state.m_pc = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]);
|
m_state.m_sp = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]);
|
m_state.m_sp = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]);
|
|
|
m_state.m_p[0] = m_core->v__DOT__pic_data;
|
m_state.m_p[0] = m_core->v__DOT__pic_data;
|
m_state.m_p[1] = m_core->v__DOT__watchdog__DOT__r_value;
|
m_state.m_p[1] = m_core->v__DOT__watchdog__DOT__r_value;
|
Line 246... |
Line 255... |
mvprintw(y, x, ">%s> 0x%08x<", n, v);
|
mvprintw(y, x, ">%s> 0x%08x<", n, v);
|
else
|
else
|
mvprintw(y, x, " %s: 0x%08x ", n, v);
|
mvprintw(y, x, " %s: 0x%08x ", n, v);
|
}
|
}
|
|
|
|
void dbgreg(FILE *fp, int id, const char *n, unsigned int v) {
|
|
/*
|
|
if ((id == 14)||(id == 14+16)) {
|
|
//char buf[64];
|
|
//fprintf(fp, " %s:",
|
|
fprintf(fp, " %s: 0x%08x ", n, v);
|
|
} else
|
|
*/
|
|
fprintf(fp, " %s: 0x%08x ", n, v);
|
|
}
|
|
|
void showreg(int y, int x, const char *n, int r, bool c) {
|
void showreg(int y, int x, const char *n, int r, bool c) {
|
if (r < 16)
|
if (r < 16)
|
dispreg(y, x, n, m_state.m_sR[r], c);
|
dispreg(y, x, n, m_state.m_sR[r], c);
|
else
|
else
|
dispreg(y, x, n, m_state.m_uR[r-16], c);
|
dispreg(y, x, n, m_state.m_uR[r-16], c);
|
Line 305... |
Line 325... |
void dbgins(const char *lbl, const int ce, const int valid,
|
void dbgins(const char *lbl, const int ce, const int valid,
|
const int gie, const int stall, const unsigned int pc,
|
const int gie, const int stall, const unsigned int pc,
|
const bool phase, const bool illegal) {
|
const bool phase, const bool illegal) {
|
char la[80], lb[80];
|
char la[80], lb[80];
|
|
|
if (!dbg_fp)
|
if (!m_dbgfp)
|
return;
|
return;
|
|
|
if (ce)
|
if (ce)
|
fprintf(dbg_fp, "%s Ck ", lbl);
|
fprintf(m_dbgfp, "%s Ck ", lbl);
|
else
|
else
|
fprintf(dbg_fp, "%s ", lbl);
|
fprintf(m_dbgfp, "%s ", lbl);
|
if (stall)
|
if (stall)
|
fprintf(dbg_fp, "Stl ");
|
fprintf(m_dbgfp, "Stl ");
|
else
|
else
|
fprintf(dbg_fp, " ");
|
fprintf(m_dbgfp, " ");
|
fprintf(dbg_fp, "0x%08x: ", pc);
|
fprintf(m_dbgfp, "0x%08x: ", pc);
|
|
|
if (valid) {
|
if (valid) {
|
zipi_to_string(m_mem[pc], la, lb);
|
zipi_to_string(m_mem[pc], la, lb);
|
if ((phase)||((m_mem[pc]&0x80000000)==0))
|
if ((phase)||((m_mem[pc]&0x80000000)==0))
|
fprintf(dbg_fp, " %-24s", la);
|
fprintf(m_dbgfp, " %-24s", la);
|
else
|
else
|
fprintf(dbg_fp, " %-24s", lb);
|
fprintf(m_dbgfp, " %-24s", lb);
|
} else {
|
} else {
|
fprintf(dbg_fp, " (0x%08x)", m_mem[pc]);
|
fprintf(m_dbgfp, " (0x%08x)", m_mem[pc]);
|
} if (illegal)
|
} if (illegal)
|
fprintf(dbg_fp, " (Illegal)");
|
fprintf(m_dbgfp, " (Illegal)");
|
fprintf(dbg_fp, "\n");
|
fprintf(m_dbgfp, "\n");
|
}
|
}
|
|
|
void show_state(void) {
|
void show_state(void) {
|
int ln= 0;
|
int ln= 0;
|
|
|
Line 783... |
Line 803... |
m_show_user_timers = v;
|
m_show_user_timers = v;
|
}
|
}
|
|
|
unsigned int cmd_read(unsigned int a) {
|
unsigned int cmd_read(unsigned int a) {
|
int errcount = 0;
|
int errcount = 0;
|
if (dbg_fp) {
|
if (m_dbgfp) {
|
dbg_flag= true;
|
dbg_flag= true;
|
fprintf(dbg_fp, "CMD-READ(%d)\n", a);
|
fprintf(m_dbgfp, "CMD-READ(%d)\n", a);
|
}
|
}
|
wb_write(CMD_REG, CMD_HALT|(a&0x3f));
|
wb_write(CMD_REG, CMD_HALT|(a&0x3f));
|
while(((wb_read(CMD_REG) & CMD_STALL) == 0)&&(errcount<MAXERR))
|
while(((wb_read(CMD_REG) & CMD_STALL) == 0)&&(errcount<MAXERR))
|
errcount++;
|
errcount++;
|
if (errcount >= MAXERR) {
|
if (errcount >= MAXERR) {
|
Line 817... |
Line 837... |
|
|
assert(errcount < MAXERR);
|
assert(errcount < MAXERR);
|
unsigned int v = wb_read(CMD_DATA);
|
unsigned int v = wb_read(CMD_DATA);
|
|
|
if (dbg_flag)
|
if (dbg_flag)
|
fprintf(dbg_fp, "CMD-READ(%d) = 0x%08x\n", a, v);
|
fprintf(m_dbgfp, "CMD-READ(%d) = 0x%08x\n", a, v);
|
dbg_flag = false;
|
dbg_flag = false;
|
return v;
|
return v;
|
}
|
}
|
|
|
void cmd_write(unsigned int a, int v) {
|
void cmd_write(unsigned int a, int v) {
|
Line 831... |
Line 851... |
wb_write(CMD_REG, CMD_HALT|(a&0x3f));
|
wb_write(CMD_REG, CMD_HALT|(a&0x3f));
|
while(((wb_read(CMD_REG) & CMD_STALL) == 0)&&(errcount < MAXERR))
|
while(((wb_read(CMD_REG) & CMD_STALL) == 0)&&(errcount < MAXERR))
|
errcount++;
|
errcount++;
|
assert(errcount < MAXERR);
|
assert(errcount < MAXERR);
|
if (dbg_flag)
|
if (dbg_flag)
|
fprintf(dbg_fp, "CMD-WRITE(%d) <= 0x%08x\n", a, v);
|
fprintf(m_dbgfp, "CMD-WRITE(%d) <= 0x%08x\n", a, v);
|
wb_write(CMD_DATA, v);
|
wb_write(CMD_DATA, v);
|
}
|
}
|
|
|
bool halted(void) {
|
bool halted(void) {
|
return (m_core->v__DOT__cmd_halt != 0);
|
return (m_core->v__DOT__cmd_halt != 0);
|
Line 893... |
Line 913... |
}
|
}
|
|
|
ln++;
|
ln++;
|
ln++;
|
ln++;
|
unsigned int cc = m_state.m_sR[14];
|
unsigned int cc = m_state.m_sR[14];
|
if (dbg_fp) fprintf(dbg_fp, "CC = %08x, gie = %d\n", cc,
|
if (m_dbgfp) fprintf(m_dbgfp, "CC = %08x, gie = %d\n", cc,
|
m_core->v__DOT__thecpu__DOT__gie);
|
m_core->v__DOT__thecpu__DOT__gie);
|
gie = (cc & 0x020);
|
gie = (cc & 0x020);
|
if (gie)
|
if (gie)
|
attroff(A_BOLD);
|
attroff(A_BOLD);
|
else
|
else
|
Line 1092... |
Line 1112... |
if ((m_core->o_wb_addr & (-1<<20))!=1)
|
if ((m_core->o_wb_addr & (-1<<20))!=1)
|
stb = 0;
|
stb = 0;
|
if ((m_core->o_wb_cyc)&&(m_core->o_wb_stb)&&(!stb))
|
if ((m_core->o_wb_cyc)&&(m_core->o_wb_stb)&&(!stb))
|
m_core->i_wb_ack = 1;
|
m_core->i_wb_ack = 1;
|
|
|
if ((dbg_flag)&&(dbg_fp)) {
|
if ((dbg_flag)&&(m_dbgfp)) {
|
fprintf(dbg_fp, "DBG %s %s %s @0x%08x/%d[0x%08x] %s %s [0x%08x] %s %s %s%s%s%s%s%s%s%s%s\n",
|
fprintf(m_dbgfp, "DBG %s %s %s @0x%08x/%d[0x%08x] %s %s [0x%08x] %s %s %s%s%s%s%s%s%s%s%s\n",
|
(m_core->i_dbg_cyc)?"CYC":" ",
|
(m_core->i_dbg_cyc)?"CYC":" ",
|
(m_core->i_dbg_stb)?"STB":
|
(m_core->i_dbg_stb)?"STB":
|
((m_core->v__DOT__dbg_stb)?"DBG":" "),
|
((m_core->v__DOT__dbg_stb)?"DBG":" "),
|
((m_core->i_dbg_we)?"WE":" "),
|
((m_core->i_dbg_we)?"WE":" "),
|
(m_core->i_dbg_addr),0,
|
(m_core->i_dbg_addr),0,
|
Line 1114... |
Line 1134... |
(m_core->v__DOT__thecpu__DOT__mem_cyc_lcl)?"LC":" ",
|
(m_core->v__DOT__thecpu__DOT__mem_cyc_lcl)?"LC":" ",
|
(m_core->v__DOT__thecpu__DOT__alu_wr)?"ALUW ":"",
|
(m_core->v__DOT__thecpu__DOT__alu_wr)?"ALUW ":"",
|
(m_core->v__DOT__thecpu__DOT__alu_ce)?"ALCE ":"",
|
(m_core->v__DOT__thecpu__DOT__alu_ce)?"ALCE ":"",
|
(m_core->v__DOT__thecpu__DOT__alu_valid)?"ALUV ":"",
|
(m_core->v__DOT__thecpu__DOT__alu_valid)?"ALUV ":"",
|
(m_core->v__DOT__thecpu__DOT__mem_valid)?"MEMV ":"");
|
(m_core->v__DOT__thecpu__DOT__mem_valid)?"MEMV ":"");
|
fprintf(dbg_fp, " SYS %s %s %s @0x%08x/%d[0x%08x] %s [0x%08x]\n",
|
fprintf(m_dbgfp, " SYS %s %s %s @0x%08x/%d[0x%08x] %s [0x%08x]\n",
|
(m_core->v__DOT__sys_cyc)?"CYC":" ",
|
(m_core->v__DOT__sys_cyc)?"CYC":" ",
|
(m_core->v__DOT__sys_stb)?"STB":" ",
|
(m_core->v__DOT__sys_stb)?"STB":" ",
|
(m_core->v__DOT__sys_we)?"WE":" ",
|
(m_core->v__DOT__sys_we)?"WE":" ",
|
(m_core->v__DOT__sys_addr),
|
(m_core->v__DOT__sys_addr),
|
(m_core->v__DOT__dbg_addr),
|
(m_core->v__DOT__dbg_addr),
|
(m_core->v__DOT__sys_data),
|
(m_core->v__DOT__sys_data),
|
(m_core->v__DOT__dbg_ack)?"ACK":" ",
|
(m_core->v__DOT__dbg_ack)?"ACK":" ",
|
(m_core->v__DOT__wb_data));
|
(m_core->v__DOT__wb_data));
|
}
|
}
|
|
|
if (dbg_fp)
|
if (m_dbgfp)
|
fprintf(dbg_fp, "CEs %d/0x%08x,%d/0x%08x DCD: ->%02x, OP: ->%02x, ALU: halt=%d,%d ce=%d, valid=%d, wr=%d Reg=%02x, IPC=%08x, UPC=%08x\n",
|
fprintf(m_dbgfp, "CEs %d/0x%08x,%d/0x%08x DCD: ->%02x, OP: ->%02x, ALU: halt=%d,%d ce=%d, valid=%d, wr=%d Reg=%02x, IPC=%08x, UPC=%08x\n",
|
dcd_ce(),
|
dcd_ce(),
|
m_core->v__DOT__thecpu__DOT__dcd_pc,
|
m_core->v__DOT__thecpu__DOT__dcd_pc,
|
op_ce(),
|
op_ce(),
|
op_pc(),
|
op_pc(),
|
dcdA()&0x01f,
|
dcdA()&0x01f,
|
Line 1142... |
Line 1162... |
m_core->v__DOT__thecpu__DOT__alu_wr,
|
m_core->v__DOT__thecpu__DOT__alu_wr,
|
m_core->v__DOT__thecpu__DOT__alu_reg,
|
m_core->v__DOT__thecpu__DOT__alu_reg,
|
m_core->v__DOT__thecpu__DOT__ipc,
|
m_core->v__DOT__thecpu__DOT__ipc,
|
m_core->v__DOT__thecpu__DOT__upc);
|
m_core->v__DOT__thecpu__DOT__upc);
|
|
|
if ((dbg_fp)&&(!gie)&&(m_core->v__DOT__thecpu__DOT__w_release_from_interrupt)) {
|
if ((m_dbgfp)&&(!gie)&&(m_core->v__DOT__thecpu__DOT__w_release_from_interrupt)) {
|
fprintf(dbg_fp, "RELEASE: int=%d, %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d\n",
|
fprintf(m_dbgfp, "RELEASE: int=%d, %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d\n",
|
m_core->v__DOT__genblk9__DOT__pic__DOT__r_interrupt,
|
m_core->v__DOT__genblk9__DOT__pic__DOT__r_interrupt,
|
m_core->v__DOT__thecpu__DOT__wr_reg_ce,
|
m_core->v__DOT__thecpu__DOT__wr_reg_ce,
|
m_core->v__DOT__thecpu__DOT__wr_reg_id,
|
m_core->v__DOT__thecpu__DOT__wr_reg_id,
|
m_core->v__DOT__thecpu__DOT__wr_reg_vl,
|
m_core->v__DOT__thecpu__DOT__wr_spreg_vl,
|
m_core->v__DOT__cmd_addr,
|
m_core->v__DOT__cmd_addr,
|
m_core->v__DOT__dbg_idata,
|
m_core->v__DOT__dbg_idata,
|
m_core->v__DOT__thecpu__DOT__master_ce,
|
m_core->v__DOT__thecpu__DOT__master_ce,
|
m_core->v__DOT__thecpu__DOT__alu_wr,
|
m_core->v__DOT__thecpu__DOT__alu_wr,
|
m_core->v__DOT__thecpu__DOT__alu_valid,
|
m_core->v__DOT__thecpu__DOT__alu_valid,
|
m_core->v__DOT__thecpu__DOT__mem_valid);
|
m_core->v__DOT__thecpu__DOT__mem_valid);
|
} else if ((dbg_fp)&&(gie)&&(m_core->v__DOT__thecpu__DOT__w_switch_to_interrupt)) {
|
} else if ((m_dbgfp)&&(gie)&&(m_core->v__DOT__thecpu__DOT__w_switch_to_interrupt)) {
|
fprintf(dbg_fp, "SWITCH: %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d, F%02x,%02x\n",
|
fprintf(m_dbgfp, "SWITCH: %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d, F%02x,%02x\n",
|
m_core->v__DOT__thecpu__DOT__wr_reg_ce,
|
m_core->v__DOT__thecpu__DOT__wr_reg_ce,
|
m_core->v__DOT__thecpu__DOT__wr_reg_id,
|
m_core->v__DOT__thecpu__DOT__wr_reg_id,
|
m_core->v__DOT__thecpu__DOT__wr_reg_vl,
|
m_core->v__DOT__thecpu__DOT__wr_spreg_vl,
|
m_core->v__DOT__cmd_addr,
|
m_core->v__DOT__cmd_addr,
|
m_core->v__DOT__dbg_idata,
|
m_core->v__DOT__dbg_idata,
|
m_core->v__DOT__thecpu__DOT__master_ce,
|
m_core->v__DOT__thecpu__DOT__master_ce,
|
m_core->v__DOT__thecpu__DOT__alu_wr,
|
m_core->v__DOT__thecpu__DOT__alu_wr,
|
m_core->v__DOT__thecpu__DOT__alu_valid,
|
m_core->v__DOT__thecpu__DOT__alu_valid,
|
m_core->v__DOT__thecpu__DOT__mem_valid,
|
m_core->v__DOT__thecpu__DOT__mem_valid,
|
m_core->v__DOT__thecpu__DOT__w_iflags,
|
m_core->v__DOT__thecpu__DOT__w_iflags,
|
m_core->v__DOT__thecpu__DOT__w_uflags);
|
m_core->v__DOT__thecpu__DOT__w_uflags);
|
fprintf(dbg_fp, "\tbrk=%s %d,%d\n",
|
fprintf(m_dbgfp, "\tbrk=%s %d,%d\n",
|
(m_core->v__DOT__thecpu__DOT__master_ce)?"CE":" ",
|
(m_core->v__DOT__thecpu__DOT__master_ce)?"CE":" ",
|
m_core->v__DOT__thecpu__DOT__break_en,
|
m_core->v__DOT__thecpu__DOT__break_en,
|
m_core->v__DOT__thecpu__DOT__op_break);
|
m_core->v__DOT__thecpu__DOT__op_break);
|
} else if ((dbg_fp)&&
|
} else if ((m_dbgfp)&&
|
((m_core->v__DOT__thecpu__DOT__op_break)
|
((m_core->v__DOT__thecpu__DOT__op_break)
|
||(m_core->v__DOT__thecpu__DOT__r_alu_illegal)
|
||(m_core->v__DOT__thecpu__DOT__r_alu_illegal)
|
||(m_core->v__DOT__thecpu__DOT__dcd_break))) {
|
||(m_core->v__DOT__thecpu__DOT__dcd_break))) {
|
fprintf(dbg_fp, "NOT SWITCHING TO GIE (gie = %d)\n", gie);
|
fprintf(m_dbgfp, "NOT SWITCHING TO GIE (gie = %d)\n", gie);
|
fprintf(dbg_fp, "\tbrk=%s breaken=%d,dcdbreak=%d,opbreak=%d,alu_illegal=%d\n",
|
fprintf(m_dbgfp, "\tbrk=%s breaken=%d,dcdbreak=%d,opbreak=%d,alu_illegal=%d\n",
|
(m_core->v__DOT__thecpu__DOT__master_ce)?"CE":" ",
|
(m_core->v__DOT__thecpu__DOT__master_ce)?"CE":" ",
|
m_core->v__DOT__thecpu__DOT__break_en,
|
m_core->v__DOT__thecpu__DOT__break_en,
|
m_core->v__DOT__thecpu__DOT__dcd_break,
|
m_core->v__DOT__thecpu__DOT__dcd_break,
|
m_core->v__DOT__thecpu__DOT__op_break,
|
m_core->v__DOT__thecpu__DOT__op_break,
|
m_core->v__DOT__thecpu__DOT__r_alu_illegal);
|
m_core->v__DOT__thecpu__DOT__r_alu_illegal);
|
}
|
}
|
|
|
if (dbg_fp) {
|
if (m_dbgfp) {
|
if(m_core->v__DOT__thecpu__DOT__clear_pipeline)
|
if(m_core->v__DOT__thecpu__DOT__clear_pipeline)
|
fprintf(dbg_fp, "\tClear Pipeline\n");
|
fprintf(m_dbgfp, "\tClear Pipeline\n");
|
if(m_core->v__DOT__thecpu__DOT__new_pc)
|
if(m_core->v__DOT__thecpu__DOT__new_pc)
|
fprintf(dbg_fp, "\tNew PC\n");
|
fprintf(m_dbgfp, "\tNew PC\n");
|
}
|
}
|
|
|
if (dbg_fp)
|
if (m_dbgfp)
|
fprintf(dbg_fp, "----------- TICK ----------\n");
|
fprintf(m_dbgfp, "----------- TICK ----------\n");
|
if (false) {
|
if (false) {
|
m_core->i_clk = 1;
|
m_core->i_clk = 1;
|
m_mem(m_core->i_clk, m_core->o_wb_cyc, m_core->o_wb_stb, m_core->o_wb_we,
|
m_mem(m_core->i_clk, m_core->o_wb_cyc, m_core->o_wb_stb, m_core->o_wb_we,
|
m_core->o_wb_addr & ((1<<20)-1), m_core->o_wb_data,
|
m_core->o_wb_addr & ((1<<20)-1), m_core->o_wb_data,
|
m_core->i_wb_ack, m_core->i_wb_stall,m_core->i_wb_data);
|
m_core->i_wb_ack, m_core->i_wb_stall,m_core->i_wb_data);
|
Line 1216... |
Line 1236... |
m_core->i_wb_err = 1;
|
m_core->i_wb_err = 1;
|
else
|
else
|
m_core->i_wb_err = 0;
|
m_core->i_wb_err = 0;
|
TESTB<Vzipsystem>::tick();
|
TESTB<Vzipsystem>::tick();
|
}
|
}
|
if ((dbg_fp)&&(gie != m_core->v__DOT__thecpu__DOT__gie)) {
|
if ((m_dbgfp)&&(gie != m_core->v__DOT__thecpu__DOT__gie)) {
|
fprintf(dbg_fp, "SWITCH FROM %s to %s: sPC = 0x%08x uPC = 0x%08x pf_pc = 0x%08x\n",
|
fprintf(m_dbgfp, "SWITCH FROM %s to %s: sPC = 0x%08x uPC = 0x%08x pf_pc = 0x%08x\n",
|
(gie)?"User":"Supervisor",
|
(gie)?"User":"Supervisor",
|
(gie)?"Supervisor":"User",
|
(gie)?"Supervisor":"User",
|
m_core->v__DOT__thecpu__DOT__ipc,
|
m_core->v__DOT__thecpu__DOT__ipc,
|
m_core->v__DOT__thecpu__DOT__upc,
|
m_core->v__DOT__thecpu__DOT__upc,
|
m_core->v__DOT__thecpu__DOT__pf_pc);
|
m_core->v__DOT__thecpu__DOT__pf_pc);
|
} if (dbg_fp) {
|
} if (m_dbgfp) {
|
#ifdef OPT_TRADITIONAL_PFCACHE
|
#ifdef OPT_TRADITIONAL_PFCACHE
|
fprintf(dbg_fp, "PFCACHE %s(%08x,%08x%s),%08x - %08x %s%s%s\n",
|
fprintf(m_dbgfp, "PFCACHE %s(%08x,%08x%s),%08x - %08x %s%s%s\n",
|
(m_core->v__DOT__thecpu__DOT__new_pc)?"N":" ",
|
(m_core->v__DOT__thecpu__DOT__new_pc)?"N":" ",
|
m_core->v__DOT__thecpu__DOT__pf_pc,
|
m_core->v__DOT__thecpu__DOT__pf_pc,
|
m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_branch_pc,
|
m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_branch_pc,
|
((m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch)
|
((m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch)
|
&&(dcdvalid())
|
&&(dcdvalid())
|
Line 1299... |
Line 1319... |
#endif
|
#endif
|
);
|
);
|
|
|
}
|
}
|
|
|
|
if ((m_dbgfp)&&((m_core->v__DOT__thecpu__DOT__div_valid)
|
|
||(m_core->v__DOT__thecpu__DOT__div_ce)
|
|
||(m_core->v__DOT__thecpu__DOT__div_busy)
|
|
)) {
|
|
fprintf(m_dbgfp, "DIV: %s %s %s %s[%2x] GP:%08x/SP:%08x %s:0x%08x\n",
|
|
(m_core->v__DOT__thecpu__DOT__div_ce)?"CE":" ",
|
|
(m_core->v__DOT__thecpu__DOT__div_busy)?"BUSY":" ",
|
|
(m_core->v__DOT__thecpu__DOT__div_valid)?"VALID":" ",
|
|
(m_core->v__DOT__thecpu__DOT__wr_reg_ce)?"REG-CE":" ",
|
|
m_core->v__DOT__thecpu__DOT__wr_reg_id,
|
|
m_core->v__DOT__thecpu__DOT__wr_gpreg_vl,
|
|
m_core->v__DOT__thecpu__DOT__wr_spreg_vl,
|
|
(m_core->v__DOT__thecpu__DOT__alu_pc_valid)?"PCV":" ",
|
|
m_core->v__DOT__thecpu__DOT__alu_pc);
|
|
|
|
fprintf(m_dbgfp, "ALU-PC: %08x %s %s\n",
|
|
m_core->v__DOT__thecpu__DOT__alu_pc,
|
|
(m_core->v__DOT__thecpu__DOT__r_alu_pc_valid)?"VALID":"",
|
|
(m_core->v__DOT__thecpu__DOT__alu_gie)?"ALU-GIE":"");
|
|
}
|
|
|
if ((m_core->v__DOT__thecpu__DOT__alu_pc_valid)
|
if ((m_core->v__DOT__thecpu__DOT__alu_pc_valid)
|
&&(!m_core->v__DOT__thecpu__DOT__clear_pipeline)) {
|
&&(!m_core->v__DOT__thecpu__DOT__clear_pipeline)) {
|
unsigned long iticks = m_tickcount - m_last_instruction_tickcount;
|
unsigned long iticks = m_tickcount - m_last_instruction_tickcount;
|
if (m_profile_fp) {
|
if (m_profile_fp) {
|
unsigned buf[2];
|
unsigned buf[2];
|
Line 1513... |
Line 1554... |
m_cursor++;
|
m_cursor++;
|
else m_cursor = 0;
|
else m_cursor = 0;
|
}
|
}
|
|
|
int cursor(void) { return m_cursor; }
|
int cursor(void) { return m_cursor; }
|
|
|
|
void jump_to(ZIPI address) {
|
|
m_core->v__DOT__thecpu__DOT__pf_pc = address;
|
|
m_core->v__DOT__thecpu__DOT__clear_pipeline = 1;
|
|
m_core->v__DOT__thecpu__DOT__new_pc = 1;
|
|
}
|
|
|
|
void dump_state(void) {
|
|
if (m_dbgfp)
|
|
dump_state(m_dbgfp);
|
|
}
|
|
|
|
void dump_state(FILE *fp) {
|
|
if (!fp)
|
|
return;
|
|
fprintf(fp, "FINAL STATE: %s\n",
|
|
(m_state.m_gie)?"GIE(User-Mode)":"Supervisor-mode");
|
|
fprintf(fp, "Supervisor Registers\n");
|
|
for(int i=0; i<16; i++) {
|
|
char str[16];
|
|
if (i==13)
|
|
sprintf(str, "sSP");
|
|
else if (i==14)
|
|
sprintf(str, "sCC");
|
|
else if (i==15)
|
|
sprintf(str, "sPC");
|
|
else // if (i<=12)
|
|
sprintf(str, "s-%2d", i);
|
|
dbgreg(fp, i, str, m_state.m_sR[i]);
|
|
if ((i&3)==3)
|
|
fprintf(fp, "\n");
|
|
}
|
|
fprintf(fp, "User Registers\n");
|
|
for(int i=0; i<16; i++) {
|
|
char str[16];
|
|
if (i==13)
|
|
sprintf(str, "uSP");
|
|
else if (i==14)
|
|
sprintf(str, "uCC");
|
|
else if (i==15)
|
|
sprintf(str, "uPC");
|
|
else // if (i<=12)
|
|
sprintf(str, "u-%2d", i);
|
|
dbgreg(fp, i, str, m_state.m_uR[i]);
|
|
if ((i&3)==3)
|
|
fprintf(fp, "\n");
|
|
}
|
|
}
|
};
|
};
|
|
|
void get_value(ZIPPY_TB *tb) {
|
void get_value(ZIPPY_TB *tb) {
|
int wy, wx, ra;
|
int wy, wx, ra;
|
int c = tb->cursor();
|
int c = tb->cursor();
|
Line 1636... |
Line 1725... |
} else
|
} else
|
tb->cmd_write(ra, v);
|
tb->cmd_write(ra, v);
|
}
|
}
|
}
|
}
|
|
|
|
|
|
bool iself(const char *fname) {
|
|
FILE *fp;
|
|
bool ret = true;
|
|
fp = fopen(fname, "rb");
|
|
|
|
if (!fp) return false;
|
|
if (0x7f != fgetc(fp)) ret = false;
|
|
if ('E' != fgetc(fp)) ret = false;
|
|
if ('L' != fgetc(fp)) ret = false;
|
|
if ('F' != fgetc(fp)) ret = false;
|
|
fclose(fp);
|
|
return ret;
|
|
}
|
|
|
|
long fgetwords(FILE *fp) {
|
|
// Return the number of words in the current file, and return the
|
|
// file as though it had never been adjusted
|
|
long fpos, flen;
|
|
fpos = ftell(fp);
|
|
if (0 != fseek(fp, 0l, SEEK_END)) {
|
|
fprintf(stderr, "ERR: Could not determine file size\n");
|
|
perror("O/S Err:");
|
|
exit(-2);
|
|
} flen = ftell(fp);
|
|
if (0 != fseek(fp, fpos, SEEK_SET)) {
|
|
fprintf(stderr, "ERR: Could not seek on file\n");
|
|
perror("O/S Err:");
|
|
exit(-2);
|
|
} flen /= sizeof(ZIPI);
|
|
return flen;
|
|
}
|
|
|
|
class SECTION {
|
|
public:
|
|
unsigned m_start, m_len;
|
|
ZIPI m_data[1];
|
|
};
|
|
|
|
SECTION **singlesection(int nwords) {
|
|
fprintf(stderr, "NWORDS = %d\n", nwords);
|
|
size_t sz = (2*(sizeof(SECTION)+sizeof(SECTION *))
|
|
+(nwords-1)*(sizeof(ZIPI)));
|
|
char *d = (char *)malloc(sz);
|
|
SECTION **r = (SECTION **)d;
|
|
memset(r, 0, sz);
|
|
r[0] = (SECTION *)(&d[2*sizeof(SECTION *)]);
|
|
r[0]->m_len = nwords;
|
|
r[1] = (SECTION *)(&r[0]->m_data[r[0]->m_len]);
|
|
r[0]->m_start = 0;
|
|
r[1]->m_start = 0;
|
|
r[1]->m_len = 0;
|
|
|
|
return r;
|
|
}
|
|
|
|
SECTION **rawsection(const char *fname) {
|
|
SECTION **secpp, *secp;
|
|
unsigned num_words;
|
|
FILE *fp;
|
|
int nr;
|
|
|
|
fp = fopen(fname, "r");
|
|
if (fp == NULL) {
|
|
fprintf(stderr, "Could not open: %s\n", fname);
|
|
exit(-1);
|
|
}
|
|
|
|
if ((num_words=fgetwords(fp)) > MEMWORDS) {
|
|
fprintf(stderr, "File overruns Block RAM\n");
|
|
exit(-1);
|
|
}
|
|
secpp = singlesection(num_words);
|
|
secp = secpp[0];
|
|
secp->m_start = RAMBASE;
|
|
secp->m_len = num_words;
|
|
nr= fread(secp->m_data, sizeof(ZIPI), num_words, fp);
|
|
if (nr != (int)num_words) {
|
|
fprintf(stderr, "Could not read entire file\n");
|
|
perror("O/S Err:");
|
|
exit(-2);
|
|
} assert(secpp[1]->m_len == 0);
|
|
|
|
return secpp;
|
|
}
|
|
|
|
unsigned byteswap(unsigned n) {
|
|
unsigned r;
|
|
|
|
r = (n&0x0ff); n>>= 8;
|
|
r = (r<<8) | (n&0x0ff); n>>= 8;
|
|
r = (r<<8) | (n&0x0ff); n>>= 8;
|
|
r = (r<<8) | (n&0x0ff); n>>= 8;
|
|
|
|
return r;
|
|
}
|
|
|
|
#include <libelf.h>
|
|
#include <gelf.h>
|
|
|
|
void elfread(const char *fname, unsigned &entry, SECTION **§ions) {
|
|
Elf *e;
|
|
int fd, i;
|
|
size_t n;
|
|
char *id;
|
|
Elf_Kind ek;
|
|
GElf_Ehdr ehdr;
|
|
GElf_Phdr phdr;
|
|
const bool dbg = false;
|
|
|
|
if (elf_version(EV_CURRENT) == EV_NONE) {
|
|
fprintf(stderr, "ELF library initialization err, %s\n", elf_errmsg(-1));
|
|
perror("O/S Err:");
|
|
exit(EXIT_FAILURE);
|
|
} if ((fd = open(fname, O_RDONLY, 0)) < 0) {
|
|
fprintf(stderr, "Could not open %s\n", fname);
|
|
perror("O/S Err:");
|
|
exit(EXIT_FAILURE);
|
|
} if ((e = elf_begin(fd, ELF_C_READ, NULL))==NULL) {
|
|
fprintf(stderr, "Could not run elf_begin, %s\n", elf_errmsg(-1));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
ek = elf_kind(e);
|
|
if (ek == ELF_K_ELF) {
|
|
; // This is the kind of file we should expect
|
|
} else if (ek == ELF_K_AR) {
|
|
fprintf(stderr, "Cannot run an archive!\n");
|
|
exit(EXIT_FAILURE);
|
|
} else if (ek == ELF_K_NONE) {
|
|
;
|
|
} else {
|
|
fprintf(stderr, "Unexpected ELF file kind!\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (gelf_getehdr(e, &ehdr) == NULL) {
|
|
fprintf(stderr, "getehdr() failed: %s\n", elf_errmsg(-1));
|
|
exit(EXIT_FAILURE);
|
|
} if ((i=gelf_getclass(e)) == ELFCLASSNONE) {
|
|
fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1));
|
|
exit(EXIT_FAILURE);
|
|
} if ((id = elf_getident(e, NULL)) == NULL) {
|
|
fprintf(stderr, "getident() failed: %s\n", elf_errmsg(-1));
|
|
exit(EXIT_FAILURE);
|
|
} if (i != ELFCLASS32) {
|
|
fprintf(stderr, "This is a 64-bit ELF file, ZipCPU ELF files are all 32-bit\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (dbg) {
|
|
printf(" %-20s 0x%jx\n", "e_type", (uintmax_t)ehdr.e_type);
|
|
printf(" %-20s 0x%jx\n", "e_machine", (uintmax_t)ehdr.e_machine);
|
|
printf(" %-20s 0x%jx\n", "e_version", (uintmax_t)ehdr.e_version);
|
|
printf(" %-20s 0x%jx\n", "e_entry", (uintmax_t)ehdr.e_entry);
|
|
printf(" %-20s 0x%jx\n", "e_phoff", (uintmax_t)ehdr.e_phoff);
|
|
printf(" %-20s 0x%jx\n", "e_shoff", (uintmax_t)ehdr.e_shoff);
|
|
printf(" %-20s 0x%jx\n", "e_flags", (uintmax_t)ehdr.e_flags);
|
|
printf(" %-20s 0x%jx\n", "e_ehsize", (uintmax_t)ehdr.e_ehsize);
|
|
printf(" %-20s 0x%jx\n", "e_phentsize", (uintmax_t)ehdr.e_phentsize);
|
|
printf(" %-20s 0x%jx\n", "e_shentsize", (uintmax_t)ehdr.e_shentsize);
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
// Check whether or not this is an ELF file for the ZipCPU ...
|
|
if (ehdr.e_machine != 0x0dadd) {
|
|
fprintf(stderr, "This is not a ZipCPU ELF file\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Get our entry address
|
|
entry = ehdr.e_entry;
|
|
|
|
|
|
// Now, let's go look at the program header
|
|
if (elf_getphdrnum(e, &n) != 0) {
|
|
fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
unsigned total_octets = 0, current_offset=0, current_section=0;
|
|
for(i=0; i<(int)n; i++) {
|
|
total_octets += sizeof(SECTION *)+sizeof(SECTION);
|
|
|
|
if (gelf_getphdr(e, i, &phdr) != &phdr) {
|
|
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (dbg) {
|
|
printf(" %-20s 0x%x\n", "p_type", phdr.p_type);
|
|
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
|
|
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
|
|
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
|
|
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
|
|
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
|
|
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
|
|
|
|
if (phdr.p_flags & PF_X) printf(" Execute");
|
|
if (phdr.p_flags & PF_R) printf(" Read");
|
|
if (phdr.p_flags & PF_W) printf(" Write");
|
|
printf("]\n");
|
|
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
|
|
}
|
|
|
|
total_octets += phdr.p_memsz;
|
|
}
|
|
|
|
char *d = (char *)malloc(total_octets + sizeof(SECTION)+sizeof(SECTION *));
|
|
memset(d, 0, total_octets);
|
|
|
|
SECTION **r = sections = (SECTION **)d;
|
|
current_offset = (n+1)*sizeof(SECTION *);
|
|
current_section = 0;
|
|
|
|
for(i=0; i<(int)n; i++) {
|
|
r[i] = (SECTION *)(&d[current_offset]);
|
|
|
|
if (gelf_getphdr(e, i, &phdr) != &phdr) {
|
|
fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (dbg) {
|
|
printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset);
|
|
printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr);
|
|
printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr);
|
|
printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz);
|
|
printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz);
|
|
printf(" %-20s 0x%x [", "p_flags", phdr.p_flags);
|
|
|
|
if (phdr.p_flags & PF_X) printf(" Execute");
|
|
if (phdr.p_flags & PF_R) printf(" Read");
|
|
if (phdr.p_flags & PF_W) printf(" Write");
|
|
printf("]\n");
|
|
|
|
printf(" %-20s 0x%jx\n", "p_align", phdr.p_align);
|
|
}
|
|
|
|
current_section++;
|
|
|
|
r[i]->m_start = phdr.p_vaddr;
|
|
r[i]->m_len = phdr.p_filesz/ sizeof(ZIPI);
|
|
|
|
current_offset += phdr.p_memsz + sizeof(SECTION);
|
|
|
|
// Now, let's read in our section ...
|
|
if (lseek(fd, phdr.p_offset, SEEK_SET) < 0) {
|
|
fprintf(stderr, "Could not seek to file position %08lx\n", phdr.p_offset);
|
|
perror("O/S Err:");
|
|
exit(EXIT_FAILURE);
|
|
} if (phdr.p_filesz > phdr.p_memsz)
|
|
phdr.p_filesz = 0;
|
|
if (read(fd, r[i]->m_data, phdr.p_filesz) != (int)phdr.p_filesz) {
|
|
fprintf(stderr, "Didnt read entire section\n");
|
|
perror("O/S Err:");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Next, we need to byte swap it from big to little endian
|
|
for(unsigned j=0; j<r[i]->m_len; j++)
|
|
r[i]->m_data[j] = byteswap(r[i]->m_data[j]);
|
|
|
|
if (dbg) for(unsigned j=0; j<r[i]->m_len; j++)
|
|
fprintf(stderr, "ADR[%04x] = %08x\n", r[i]->m_start+j,
|
|
r[i]->m_data[j]);
|
|
}
|
|
|
|
r[i] = (SECTION *)(&d[current_offset]);
|
|
r[current_section]->m_start = 0;
|
|
r[current_section]->m_len = 0;
|
|
|
|
elf_end(e);
|
|
close(fd);
|
|
}
|
|
|
void usage(void) {
|
void usage(void) {
|
printf("USAGE: zippy_tb [-a] <testfile.out>\n");
|
printf("USAGE: zippy_tb [-a] <testfile.out>\n");
|
printf("\n");
|
printf("\n");
|
printf("\tWhere testfile.out is an output file from the assembler.\n");
|
printf("\tWhere testfile.out is an output file from the assembler.\n");
|
printf("\tThis file needs to be in a raw format and not an ELF\n");
|
printf("\tThis file needs to be in a raw format and not an ELF\n");
|
Line 1672... |
Line 2038... |
|
|
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
ZIPPY_TB *tb = new ZIPPY_TB();
|
ZIPPY_TB *tb = new ZIPPY_TB();
|
bool autorun = false, exit_on_done = false, autostep=false;
|
bool autorun = false, exit_on_done = false, autostep=false;
|
|
ZIPI entry = RAMBASE;
|
|
|
// mem[0x00000] = 0xbe000010; // Halt instruction
|
// mem[0x00000] = 0xbe000010; // Halt instruction
|
unsigned int mptr = 0;
|
unsigned int mptr = 0;
|
|
|
signal(SIGINT, sigint);
|
signal(SIGINT, sigint);
|
Line 1704... |
Line 2071... |
usage();
|
usage();
|
exit(-1);
|
exit(-1);
|
break;
|
break;
|
}
|
}
|
} else if (access(argv[argn], R_OK)==0) {
|
} else if (access(argv[argn], R_OK)==0) {
|
|
if (iself(argv[argn])) {
|
|
SECTION **secpp = NULL, *secp;
|
|
elfread(argv[argn], entry, secpp);
|
|
for(int i=0; secpp[i]->m_len; i++) {
|
|
secp = secpp[i];
|
|
assert(secp->m_start >= RAMBASE);
|
|
assert(secp->m_start+secp->m_len <= RAMBASE+MEMWORDS);
|
|
memcpy(&tb->m_mem[secp->m_start-RAMBASE],
|
|
&secp->m_data,
|
|
secp->m_len*sizeof(ZIPI));
|
|
mptr = secp->m_start+secp->m_len;
|
|
}
|
|
} else {
|
FILE *fp = fopen(argv[argn], "r");
|
FILE *fp = fopen(argv[argn], "r");
|
int nr, nv = 0;
|
int nr, nv = 0;
|
if (fp == NULL) {
|
if (fp == NULL) {
|
printf("Cannot open %s\n", argv[argn]);
|
printf("Cannot open %s\n", argv[argn]);
|
perror("O/S Err: ");
|
perror("O/S Err: ");
|
Line 1725... |
Line 2105... |
} if (nv == 0) {
|
} if (nv == 0) {
|
printf("Read nothing but zeros from %s\n", argv[argn]);
|
printf("Read nothing but zeros from %s\n", argv[argn]);
|
perror("O/S Err?:");
|
perror("O/S Err?:");
|
exit(-2);
|
exit(-2);
|
}
|
}
|
|
}
|
} else {
|
} else {
|
fprintf(stderr, "No access to %s, or unknown arg\n", argv[argn]);
|
fprintf(stderr, "No access to %s, or unknown arg\n", argv[argn]);
|
exit(-2);
|
exit(-2);
|
}
|
}
|
}
|
}
|
Line 1743... |
Line 2124... |
printf("Running in non-interactive mode\n");
|
printf("Running in non-interactive mode\n");
|
tb->reset();
|
tb->reset();
|
for(int i=0; i<2; i++)
|
for(int i=0; i<2; i++)
|
tb->tick();
|
tb->tick();
|
tb->m_core->v__DOT__cmd_halt = 0;
|
tb->m_core->v__DOT__cmd_halt = 0;
|
|
tb->wb_write(CMD_REG, CMD_HALT|CMD_RESET|15);
|
|
tb->wb_write(CMD_DATA, entry);
|
|
tb->wb_write(CMD_REG, 15);
|
while(!done) {
|
while(!done) {
|
tb->tick();
|
tb->tick();
|
|
|
// tb->m_core->v__DOT__thecpu__DOT__step = 0;
|
// tb->m_core->v__DOT__thecpu__DOT__step = 0;
|
// tb->m_core->v__DOT__cmd_halt = 0;
|
// tb->m_core->v__DOT__cmd_halt = 0;
|
Line 1764... |
Line 2148... |
}
|
}
|
} else if (autostep) {
|
} else if (autostep) {
|
bool done = false;
|
bool done = false;
|
|
|
printf("Running in non-interactive mode, via step commands\n");
|
printf("Running in non-interactive mode, via step commands\n");
|
tb->wb_write(CMD_REG, CMD_HALT|CMD_RESET);
|
tb->wb_write(CMD_REG, CMD_HALT|CMD_RESET|15);
|
|
tb->wb_write(CMD_DATA, entry);
|
|
tb->wb_write(CMD_REG, 15);
|
while(!done) {
|
while(!done) {
|
tb->wb_write(CMD_REG, CMD_STEP);
|
tb->wb_write(CMD_REG, CMD_STEP);
|
done = (tb->test_success())||(tb->test_failure());
|
done = (tb->test_success())||(tb->test_failure());
|
done = done || signalled;
|
done = done || signalled;
|
}
|
}
|
Line 1782... |
Line 2168... |
// for(int i=0; i<2; i++)
|
// for(int i=0; i<2; i++)
|
// tb->tick();
|
// tb->tick();
|
tb->m_core->v__DOT__cmd_reset = 1;
|
tb->m_core->v__DOT__cmd_reset = 1;
|
tb->m_core->v__DOT__cmd_halt = 0;
|
tb->m_core->v__DOT__cmd_halt = 0;
|
|
|
/*
|
tb->jump_to(entry);
|
// For debugging purposes: do we wish to skip some number of
|
|
// instructions to fast forward to a time of interest??
|
// For debugging purposes: do we wish to skip some number of
|
for(int i=0; i<0x4d0; i++) {
|
// instructions to fast forward to a time of interest??
|
tb->m_core->v__DOT__cmd_halt = 0;
|
for(int i=0; i<0x3f80; i++) {
|
tb->tick();
|
tb->m_core->v__DOT__cmd_halt = 0;
|
}
|
tb->tick();
|
*/
|
}
|
|
|
int chv = 'q';
|
int chv = 'q';
|
|
|
bool done = false, halted = true, manual = true,
|
bool done = false, halted = true, manual = true,
|
high_speed = false;
|
high_speed = false;
|
Line 1917... |
Line 2303... |
}
|
}
|
|
|
if (manual) {
|
if (manual) {
|
tb->show_state();
|
tb->show_state();
|
} else if (halted) {
|
} else if (halted) {
|
if (tb->dbg_fp)
|
if (tb->m_dbgfp)
|
fprintf(tb->dbg_fp, "\n\nREAD-STATE ******\n");
|
fprintf(tb->m_dbgfp, "\n\nREAD-STATE ******\n");
|
tb->read_state();
|
tb->read_state();
|
} else
|
} else
|
tb->show_state();
|
tb->show_state();
|
|
|
if (tb->m_core->i_rst)
|
if (tb->m_core->i_rst)
|
Line 1956... |
Line 2342... |
}
|
}
|
}
|
}
|
#endif
|
#endif
|
|
|
printf("\n");
|
printf("\n");
|
|
if (tb->test_failure()) {
|
|
tb->dump_state();
|
|
}
|
|
|
printf("Clocks used : %08x\n", tb->m_core->v__DOT__mtc_data);
|
printf("Clocks used : %08x\n", tb->m_core->v__DOT__mtc_data);
|
printf("Instructions Issued : %08x\n", tb->m_core->v__DOT__mic_data);
|
printf("Instructions Issued : %08x\n", tb->m_core->v__DOT__mic_data);
|
printf("Tick Count : %08lx\n", tb->m_tickcount);
|
printf("Tick Count : %08lx\n", tb->m_tickcount);
|
if (tb->m_core->v__DOT__mtc_data != 0)
|
if (tb->m_core->v__DOT__mtc_data != 0)
|
printf("Instructions / Clock: %.2f\n",
|
printf("Instructions / Clock: %.2f\n",
|