URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/zipcpu/trunk/bench/cpp
- from Rev 155 to Rev 154
- ↔ Reverse comparison
Rev 155 → Rev 154
/zippy_tb.cpp
38,9 → 38,6
#include <time.h> |
#include <unistd.h> |
#include <poll.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <fcntl.h> |
|
#include <ctype.h> |
#include <ncurses.h> |
58,9 → 55,6
|
#define CMD_REG 0 |
#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_STALL (1<<9) |
#define CMD_INT (1<<7) |
73,9 → 67,6
|
#define MAXERR 10000 |
|
#define LGRAMLEN 20 |
#define RAMBASE 0x100000 |
#define MEMWORDS (1<<LGRAMLEN) |
|
class SPARSEMEM { |
public: |
106,18 → 97,18
unsigned long m_mem_size; |
MEMSIM m_mem; |
// QSPIFLASHSIM m_flash; |
FILE *m_dbgfp, *m_profile_fp; |
FILE *dbg_fp, *m_profile_fp; |
bool dbg_flag, bomb, m_show_user_timers; |
int m_cursor; |
unsigned long m_last_instruction_tickcount; |
ZIPSTATE m_state; |
|
ZIPPY_TB(void) : m_mem_size(MEMWORDS), m_mem(m_mem_size) { |
ZIPPY_TB(void) : m_mem_size(1<<20), m_mem(m_mem_size) { |
if (false) { |
m_dbgfp = fopen("dbg.txt", "w"); |
dbg_fp = fopen("dbg.txt", "w"); |
dbg_flag = true; |
} else { |
m_dbgfp = NULL; |
dbg_fp = NULL; |
dbg_flag = false; |
} |
bomb = false; |
133,8 → 124,8
} |
|
~ZIPPY_TB(void) { |
if (m_dbgfp) |
fclose(m_dbgfp); |
if (dbg_fp) |
fclose(dbg_fp); |
if (m_profile_fp) |
fclose(m_profile_fp); |
} |
163,7 → 154,7
for(int i=0; i<20; i++) |
m_state.m_p[i] = cmd_read(i+32); |
|
m_state.m_gie = wb_read(CMD_REG) & CMD_GIE; |
m_state.m_gie = (m_state.m_sR[14] & 0x020); |
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]); |
|
212,7 → 203,7
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_gie = m_core->v__DOT__thecpu__DOT__gie; |
m_state.m_gie = (m_state.m_sR[14] & 0x020); |
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]); |
|
257,17 → 248,6
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) { |
if (r < 16) |
dispreg(y, x, n, m_state.m_sR[r], c); |
327,30 → 307,30
const bool phase, const bool illegal) { |
char la[80], lb[80]; |
|
if (!m_dbgfp) |
if (!dbg_fp) |
return; |
|
if (ce) |
fprintf(m_dbgfp, "%s Ck ", lbl); |
fprintf(dbg_fp, "%s Ck ", lbl); |
else |
fprintf(m_dbgfp, "%s ", lbl); |
fprintf(dbg_fp, "%s ", lbl); |
if (stall) |
fprintf(m_dbgfp, "Stl "); |
fprintf(dbg_fp, "Stl "); |
else |
fprintf(m_dbgfp, " "); |
fprintf(m_dbgfp, "0x%08x: ", pc); |
fprintf(dbg_fp, " "); |
fprintf(dbg_fp, "0x%08x: ", pc); |
|
if (valid) { |
zipi_to_string(m_mem[pc], la, lb); |
if ((phase)||((m_mem[pc]&0x80000000)==0)) |
fprintf(m_dbgfp, " %-24s", la); |
fprintf(dbg_fp, " %-24s", la); |
else |
fprintf(m_dbgfp, " %-24s", lb); |
fprintf(dbg_fp, " %-24s", lb); |
} else { |
fprintf(m_dbgfp, " (0x%08x)", m_mem[pc]); |
fprintf(dbg_fp, " (0x%08x)", m_mem[pc]); |
} if (illegal) |
fprintf(m_dbgfp, " (Illegal)"); |
fprintf(m_dbgfp, "\n"); |
fprintf(dbg_fp, " (Illegal)"); |
fprintf(dbg_fp, "\n"); |
} |
|
void show_state(void) { |
805,9 → 785,9
|
unsigned int cmd_read(unsigned int a) { |
int errcount = 0; |
if (m_dbgfp) { |
if (dbg_fp) { |
dbg_flag= true; |
fprintf(m_dbgfp, "CMD-READ(%d)\n", a); |
fprintf(dbg_fp, "CMD-READ(%d)\n", a); |
} |
wb_write(CMD_REG, CMD_HALT|(a&0x3f)); |
while(((wb_read(CMD_REG) & CMD_STALL) == 0)&&(errcount<MAXERR)) |
839,7 → 819,7
unsigned int v = wb_read(CMD_DATA); |
|
if (dbg_flag) |
fprintf(m_dbgfp, "CMD-READ(%d) = 0x%08x\n", a, v); |
fprintf(dbg_fp, "CMD-READ(%d) = 0x%08x\n", a, v); |
dbg_flag = false; |
return v; |
} |
853,7 → 833,7
errcount++; |
assert(errcount < MAXERR); |
if (dbg_flag) |
fprintf(m_dbgfp, "CMD-WRITE(%d) <= 0x%08x\n", a, v); |
fprintf(dbg_fp, "CMD-WRITE(%d) <= 0x%08x\n", a, v); |
wb_write(CMD_DATA, v); |
} |
|
915,7 → 895,7
ln++; |
ln++; |
unsigned int cc = m_state.m_sR[14]; |
if (m_dbgfp) fprintf(m_dbgfp, "CC = %08x, gie = %d\n", cc, |
if (dbg_fp) fprintf(dbg_fp, "CC = %08x, gie = %d\n", cc, |
m_core->v__DOT__thecpu__DOT__gie); |
gie = (cc & 0x020); |
if (gie) |
1114,8 → 1094,8
if ((m_core->o_wb_cyc)&&(m_core->o_wb_stb)&&(!stb)) |
m_core->i_wb_ack = 1; |
|
if ((dbg_flag)&&(m_dbgfp)) { |
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", |
if ((dbg_flag)&&(dbg_fp)) { |
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", |
(m_core->i_dbg_cyc)?"CYC":" ", |
(m_core->i_dbg_stb)?"STB": |
((m_core->v__DOT__dbg_stb)?"DBG":" "), |
1136,7 → 1116,7
(m_core->v__DOT__thecpu__DOT__alu_ce)?"ALCE ":"", |
(m_core->v__DOT__thecpu__DOT__alu_valid)?"ALUV ":"", |
(m_core->v__DOT__thecpu__DOT__mem_valid)?"MEMV ":""); |
fprintf(m_dbgfp, " SYS %s %s %s @0x%08x/%d[0x%08x] %s [0x%08x]\n", |
fprintf(dbg_fp, " 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_stb)?"STB":" ", |
(m_core->v__DOT__sys_we)?"WE":" ", |
1147,8 → 1127,8
(m_core->v__DOT__wb_data)); |
} |
|
if (m_dbgfp) |
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", |
if (dbg_fp) |
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", |
dcd_ce(), |
m_core->v__DOT__thecpu__DOT__dcd_pc, |
op_ce(), |
1164,12 → 1144,12
m_core->v__DOT__thecpu__DOT__ipc, |
m_core->v__DOT__thecpu__DOT__upc); |
|
if ((m_dbgfp)&&(!gie)&&(m_core->v__DOT__thecpu__DOT__w_release_from_interrupt)) { |
fprintf(m_dbgfp, "RELEASE: int=%d, %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d\n", |
if ((dbg_fp)&&(!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", |
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_id, |
m_core->v__DOT__thecpu__DOT__wr_spreg_vl, |
m_core->v__DOT__thecpu__DOT__wr_reg_vl, |
m_core->v__DOT__cmd_addr, |
m_core->v__DOT__dbg_idata, |
m_core->v__DOT__thecpu__DOT__master_ce, |
1176,11 → 1156,11
m_core->v__DOT__thecpu__DOT__alu_wr, |
m_core->v__DOT__thecpu__DOT__alu_valid, |
m_core->v__DOT__thecpu__DOT__mem_valid); |
} else if ((m_dbgfp)&&(gie)&&(m_core->v__DOT__thecpu__DOT__w_switch_to_interrupt)) { |
fprintf(m_dbgfp, "SWITCH: %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d, F%02x,%02x\n", |
} else if ((dbg_fp)&&(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", |
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_spreg_vl, |
m_core->v__DOT__thecpu__DOT__wr_reg_vl, |
m_core->v__DOT__cmd_addr, |
m_core->v__DOT__dbg_idata, |
m_core->v__DOT__thecpu__DOT__master_ce, |
1189,16 → 1169,16
m_core->v__DOT__thecpu__DOT__mem_valid, |
m_core->v__DOT__thecpu__DOT__w_iflags, |
m_core->v__DOT__thecpu__DOT__w_uflags); |
fprintf(m_dbgfp, "\tbrk=%s %d,%d\n", |
fprintf(dbg_fp, "\tbrk=%s %d,%d\n", |
(m_core->v__DOT__thecpu__DOT__master_ce)?"CE":" ", |
m_core->v__DOT__thecpu__DOT__break_en, |
m_core->v__DOT__thecpu__DOT__op_break); |
} else if ((m_dbgfp)&& |
} else if ((dbg_fp)&& |
((m_core->v__DOT__thecpu__DOT__op_break) |
||(m_core->v__DOT__thecpu__DOT__r_alu_illegal) |
||(m_core->v__DOT__thecpu__DOT__dcd_break))) { |
fprintf(m_dbgfp, "NOT SWITCHING TO GIE (gie = %d)\n", gie); |
fprintf(m_dbgfp, "\tbrk=%s breaken=%d,dcdbreak=%d,opbreak=%d,alu_illegal=%d\n", |
fprintf(dbg_fp, "NOT SWITCHING TO GIE (gie = %d)\n", gie); |
fprintf(dbg_fp, "\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__break_en, |
m_core->v__DOT__thecpu__DOT__dcd_break, |
1206,15 → 1186,15
m_core->v__DOT__thecpu__DOT__r_alu_illegal); |
} |
|
if (m_dbgfp) { |
if (dbg_fp) { |
if(m_core->v__DOT__thecpu__DOT__clear_pipeline) |
fprintf(m_dbgfp, "\tClear Pipeline\n"); |
fprintf(dbg_fp, "\tClear Pipeline\n"); |
if(m_core->v__DOT__thecpu__DOT__new_pc) |
fprintf(m_dbgfp, "\tNew PC\n"); |
fprintf(dbg_fp, "\tNew PC\n"); |
} |
|
if (m_dbgfp) |
fprintf(m_dbgfp, "----------- TICK ----------\n"); |
if (dbg_fp) |
fprintf(dbg_fp, "----------- TICK ----------\n"); |
if (false) { |
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, |
1238,16 → 1218,16
m_core->i_wb_err = 0; |
TESTB<Vzipsystem>::tick(); |
} |
if ((m_dbgfp)&&(gie != m_core->v__DOT__thecpu__DOT__gie)) { |
fprintf(m_dbgfp, "SWITCH FROM %s to %s: sPC = 0x%08x uPC = 0x%08x pf_pc = 0x%08x\n", |
if ((dbg_fp)&&(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", |
(gie)?"User":"Supervisor", |
(gie)?"Supervisor":"User", |
m_core->v__DOT__thecpu__DOT__ipc, |
m_core->v__DOT__thecpu__DOT__upc, |
m_core->v__DOT__thecpu__DOT__pf_pc); |
} if (m_dbgfp) { |
} if (dbg_fp) { |
#ifdef OPT_TRADITIONAL_PFCACHE |
fprintf(m_dbgfp, "PFCACHE %s(%08x,%08x%s),%08x - %08x %s%s%s\n", |
fprintf(dbg_fp, "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__pf_pc, |
m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_branch_pc, |
1321,27 → 1301,6
|
} |
|
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) |
&&(!m_core->v__DOT__thecpu__DOT__clear_pipeline)) { |
unsigned long iticks = m_tickcount - m_last_instruction_tickcount; |
1556,54 → 1515,6
} |
|
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) { |
1727,283 → 1638,6
} |
} |
|
|
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) { |
printf("USAGE: zippy_tb [-a] <testfile.out>\n"); |
printf("\n"); |
2040,7 → 1674,6
Verilated::commandArgs(argc, argv); |
ZIPPY_TB *tb = new ZIPPY_TB(); |
bool autorun = false, exit_on_done = false, autostep=false; |
ZIPI entry = RAMBASE; |
|
// mem[0x00000] = 0xbe000010; // Halt instruction |
unsigned int mptr = 0; |
2073,19 → 1706,6
break; |
} |
} 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"); |
int nr, nv = 0; |
if (fp == NULL) { |
2107,7 → 1727,6
perror("O/S Err?:"); |
exit(-2); |
} |
} |
} else { |
fprintf(stderr, "No access to %s, or unknown arg\n", argv[argn]); |
exit(-2); |
2126,9 → 1745,6
for(int i=0; i<2; i++) |
tb->tick(); |
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) { |
tb->tick(); |
|
2150,9 → 1766,7
bool done = false; |
|
printf("Running in non-interactive mode, via step commands\n"); |
tb->wb_write(CMD_REG, CMD_HALT|CMD_RESET|15); |
tb->wb_write(CMD_DATA, entry); |
tb->wb_write(CMD_REG, 15); |
tb->wb_write(CMD_REG, CMD_HALT|CMD_RESET); |
while(!done) { |
tb->wb_write(CMD_REG, CMD_STEP); |
done = (tb->test_success())||(tb->test_failure()); |
2170,14 → 1784,14
tb->m_core->v__DOT__cmd_reset = 1; |
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(int i=0; i<0x3f80; i++) { |
for(int i=0; i<0x4d0; i++) { |
tb->m_core->v__DOT__cmd_halt = 0; |
tb->tick(); |
} |
*/ |
|
int chv = 'q'; |
|
2305,8 → 1919,8
if (manual) { |
tb->show_state(); |
} else if (halted) { |
if (tb->m_dbgfp) |
fprintf(tb->m_dbgfp, "\n\nREAD-STATE ******\n"); |
if (tb->dbg_fp) |
fprintf(tb->dbg_fp, "\n\nREAD-STATE ******\n"); |
tb->read_state(); |
} else |
tb->show_state(); |
2344,10 → 1958,6
#endif |
|
printf("\n"); |
if (tb->test_failure()) { |
tb->dump_state(); |
} |
|
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("Tick Count : %08lx\n", tb->m_tickcount); |