URL
https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk
Subversion Repositories xulalx25soc
Compare Revisions
- This comparison shows the changes necessary to convert path
/xulalx25soc
- from Rev 112 to Rev 113
- ↔ Reverse comparison
Rev 112 → Rev 113
/trunk/bench/cpp/busmaster_tb.cpp
71,13 → 71,16
QSPIFLASHSIM m_flash; |
SDSPISIM m_sdcard; |
SDRAMSIM m_sdram; |
unsigned m_last_led; |
unsigned m_last_led, m_last_pic, m_last_tx_state; |
time_t m_start_time; |
bool m_last_writeout; |
UARTSIM m_uart; |
int m_last_bus_owner, m_busy; |
|
BUSMASTER_TB(void) : PIPECMDR(FPGAPORT), m_uart(FPGAPORT+1) { |
m_start_time = time(NULL); |
m_last_pic = 0; |
m_last_tx_state = 0; |
} |
|
void reset(void) { |
132,15 → 135,505
m_core->v__DOT__serialport__DOT__r_setup); |
PIPECMDR::tick(); |
|
// #define DEBUGGING_OUTPUT |
#define XULA25 |
#ifdef DEBUGGING_OUTPUT |
bool writeout = false; |
/* |
if (m_core->v__DOT__sdram__DOT__r_pending) |
writeout = true; |
else if (m_core->v__DOT__sdram__DOT__bank_active[0]) |
writeout = true; |
else if (m_core->v__DOT__sdram__DOT__bank_active[1]) |
writeout = true; |
else if (m_core->v__DOT__sdram__DOT__bank_active[2]) |
writeout = true; |
else if (m_core->v__DOT__sdram__DOT__bank_active[3]) |
writeout = true; |
*/ |
|
if ((m_core->v__DOT__wbu_cyc)&&(!m_core->v__DOT__wbu_we)) |
writeout = true; |
/* |
if ((m_core->v__DOT__wbu_cyc)&&(!m_core->v__DOT__wbu_we)) |
writeout = true; |
if (m_core->v__DOT__genbus__DOT__exec_stb) |
writeout = true; |
*/ |
|
if ((m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch) |
&&(m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction == 0x7883ffff)) |
m_busy+=2; |
else if (m_busy > 0) m_busy--; |
#define v__DOT__wb_addr v__DOT__dwb_addr |
#define v__DOT__dwb_stall v__DOT__wb_stall |
#define v__DOT__dwb_ack v__DOT__wb_ack |
#define v__DOT__wb_cyc v__DOT__dwb_cyc |
#define v__DOT__wb_stb v__DOT__dwb_stb |
#define v__DOT__wb_we v__DOT__dwb_we |
#define v__DOT__dwb_idata v__DOT__wb_idata |
#define v__DOT__wb_data v__DOT__dwb_odata |
|
if ((!m_core->v__DOT__zippy__DOT__cmd_halt) |
&&(!m_core->v__DOT__zippy__DOT__thecpu__DOT__sleep)) |
writeout = true; |
// if (m_core->v__DOT__uart_tx_int) |
// writeout = true; |
#ifdef XULA25 |
if (m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_any) |
writeout = true; |
#endif |
|
#ifdef XULA25 |
unsigned this_pic = ((m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_int_enable)<<16) | |
(m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_int_state); |
#else |
unsigned this_pic = 0; |
#endif |
|
// if (this_pic != m_last_pic) |
// writeout = true; |
unsigned tx_state = ((m_core->v__DOT__serialport__DOT__txmod__DOT__zero_baud_counter)<<20) |
|((m_core->v__DOT__serialport__DOT__txmod__DOT__r_busy)<<16) |
|((m_core->v__DOT__serialport__DOT__txmod__DOT__lcl_data)<<8) |
|((m_core->v__DOT__serialport__DOT__txmod__DOT__baud_counter&0x0f)<<4) |
|(m_core->v__DOT__serialport__DOT__txmod__DOT__state); |
if (tx_state != m_last_tx_state) |
writeout = true; |
int bus_owner = m_core->v__DOT__wbu_zip_arbiter__DOT__r_a_owner; |
bus_owner |= (m_core->v__DOT__wbu_cyc)?2:0; |
bus_owner |= (m_core->v__DOT__dwb_cyc)?4:0; |
bus_owner |= (m_core->v__DOT__wb_cyc)?8:0; |
bus_owner |= (m_core->v__DOT__wb_cyc)?16:0; |
bus_owner |= (m_core->v__DOT__wbu_stb)?32:0; |
bus_owner |= (m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_stb_gbl)?64:0; |
bus_owner |= (m_core->v__DOT__wb_stb)?128:0; |
bus_owner |= (m_core->v__DOT____Vcellinp__wbu_zip_arbiter____pinNumber10)?256:0; |
#ifdef XULA25 |
bus_owner |= (m_core->v__DOT__zippy__DOT__ext_cyc)?512:0; |
#endif |
if (bus_owner != m_last_bus_owner) |
writeout = true; |
/* |
writeout = (writeout)||(m_core->i_rx_stb) |
||((m_core->o_tx_stb)&&(!m_core->i_tx_busy)); |
writeout = (writeout)||(m_core->v__DOT____Vcellinp__genbus____pinNumber9); |
writeout = (writeout)||(m_core->v__DOT__wb_stb); |
writeout = (writeout)||(m_core->v__DOT__wb_err); |
*/ |
|
if ((writeout)||(m_last_writeout)) { |
m_last_bus_owner = bus_owner; |
m_last_pic = this_pic; |
m_last_tx_state = tx_state; |
printf("%08lx:", m_tickcount); |
|
/* |
printf("%d/%02x %d/%02x%s ", |
m_core->i_rx_stb, m_core->i_rx_data, |
m_core->o_tx_stb, m_core->o_tx_data, |
m_core->i_tx_busy?"/BSY":" "); |
*/ |
|
printf("(%d/%d,%d/%d->%d),(%c:%d,%d->%d)|%c[%08x/%08x]@%08x %c%c%c", |
m_core->v__DOT__wbu_cyc, |
m_core->v__DOT____Vcellinp__wbu_zip_arbiter____pinNumber10, |
m_core->v__DOT__dwb_cyc, // was zip_cyc |
#ifdef XULA25 |
(m_core->v__DOT__zippy__DOT__ext_cyc), |
#else |
0, |
#endif |
m_core->v__DOT__wb_cyc, |
// |
m_core->v__DOT__wbu_zip_arbiter__DOT__r_a_owner?'Z':'j', |
m_core->v__DOT__wbu_stb, |
// 0, // m_core->v__DOT__dwb_stb, // was zip_stb |
m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_stb_gbl, |
m_core->v__DOT__wb_stb, |
// |
(m_core->v__DOT__wb_we)?'W':'R', |
m_core->v__DOT__wb_data, |
m_core->v__DOT__dwb_idata, |
m_core->v__DOT__wb_addr, |
(m_core->v__DOT__dwb_ack)?'A': |
(m_core->v__DOT____Vcellinp__genbus____pinNumber9)?'a':' ', |
(m_core->v__DOT__dwb_stall)?'S': |
(m_core->v__DOT____Vcellinp__genbus____pinNumber10)?'s':' ', |
(m_core->v__DOT__wb_err)?'E':'.'); |
|
/* |
// UART-Wishbone bus converter debug lines |
printf(" RUNWB %d:%09lx %d@0x%08x %3x %3x %d %d/%d/%d %d:%09lx", |
m_core->v__DOT__genbus__DOT__fifo_in_stb, |
m_core->v__DOT__genbus__DOT__fifo_in_word, |
m_core->v__DOT__genbus__DOT__runwb__DOT__wb_state, |
m_core->v__DOT__wbu_addr, |
m_core->v__DOT__genbus__DOT__runwb__DOT__r_len, |
m_core->v__DOT__genbus__DOT__runwb__DOT__r_acks_needed, |
m_core->v__DOT__genbus__DOT__runwb__DOT__w_eow, |
m_core->v__DOT__genbus__DOT__runwb__DOT__last_read_request, |
m_core->v__DOT__genbus__DOT__runwb__DOT__last_ack, |
m_core->v__DOT__genbus__DOT__runwb__DOT__zero_acks, |
m_core->v__DOT__genbus__DOT__exec_stb, |
m_core->v__DOT__genbus__DOT__exec_word); |
*/ |
|
/* |
// UART-Wishbone bus converter debug lines |
printf(" WBU[%d,%3d,%3d]", |
m_core->v__DOT__genbus__DOT__runwb__DOT__wb_state, |
m_core->v__DOT__genbus__DOT__runwb__DOT__r_len, |
m_core->v__DOT__genbus__DOT__runwb__DOT__r_acks_needed); |
*/ |
|
/* |
// SDRAM debug lines |
printf("%c[%d%d%d%d,%d:%04x%c]@%06x(%d) ->%06x%c", |
(m_core->v__DOT__sdram_sel)?'!':' ', |
m_core->o_ram_cs_n, m_core->o_ram_ras_n, |
m_core->o_ram_cas_n, m_core->o_ram_we_n, |
m_core->o_ram_bs, m_core->o_ram_data, |
(m_core->o_ram_drive_data)?'D':'-', |
m_core->o_ram_addr, |
(m_core->o_ram_addr>>10)&1, |
m_core->i_ram_data, |
(m_core->o_ram_drive_data)?'-':'V'); |
|
printf(" SD[%d,%d-%3x%d]", |
m_core->v__DOT__sdram__DOT__r_state, |
m_sdram.pwrup(), |
m_core->v__DOT__sdram__DOT__refresh_clk, |
m_core->v__DOT__sdram__DOT__need_refresh); |
|
printf(" BNK[%d:%6x,%d:%6x,%d:%6x,%d:%6x],%x%d", |
m_core->v__DOT__sdram__DOT__bank_active[0], |
m_core->v__DOT__sdram__DOT__bank_row[0], |
m_core->v__DOT__sdram__DOT__bank_active[1], |
m_core->v__DOT__sdram__DOT__bank_row[1], |
m_core->v__DOT__sdram__DOT__bank_active[2], |
m_core->v__DOT__sdram__DOT__bank_row[2], |
m_core->v__DOT__sdram__DOT__bank_active[3], |
m_core->v__DOT__sdram__DOT__bank_row[3], |
m_core->v__DOT__sdram__DOT__clocks_til_idle, |
m_core->v__DOT__sdram__DOT__r_barrell_ack); |
|
printf(" %s%s%c[%08x@%06x]", |
(m_core->v__DOT__sdram__DOT__bus_cyc)?"C":" ", |
(m_core->v__DOT__sdram__DOT__r_pending)?"PND":" ", |
(m_core->v__DOT__sdram__DOT__r_we)?'W':'R', |
(m_core->v__DOT__sdram__DOT__r_we) |
?(m_core->v__DOT__sdram__DOT__r_data) |
:(m_core->v__DOT__sdram_data), |
(m_core->v__DOT__sdram__DOT__r_addr)); |
*/ |
|
// CPU Pipeline debugging |
printf("%s%s%s%s%s%s%s%s%s%s%s", |
// (m_core->v__DOT__zippy__DOT__dbg_ack)?"A":"-", |
// (m_core->v__DOT__zippy__DOT__dbg_stall)?"S":"-", |
// (m_core->v__DOT__zippy__DOT__sys_dbg_cyc)?"D":"-", |
(m_core->v__DOT__zippy__DOT__cpu_lcl_cyc)?"L":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_halted)?"Z":"-", |
(m_core->v__DOT__zippy__DOT__cpu_break)?"!":"-", |
(m_core->v__DOT__zippy__DOT__cmd_halt)?"H":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__gie)?"G":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_cyc)?"P":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_valid)?"V":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_illegal)?"i":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__new_pc)?"N":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_gbl)?"G":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_lcl)?"L":"-"); |
printf("|%s%s%s%s%s%s", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_dcdvalid)?"D":"-", |
(dcd_ce())?"d":"-", |
"x", // (m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdA_stall)?"A":"-", |
"x", // (m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdB_stall)?"B":"-", |
"x", // (m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdF_stall)?"F":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__dcd_illegal)?"i":"-"); |
|
printf("|%s%s%s%s%s%s%s%s%s%s", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid)?"O":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_ce)?"k":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_stall)?"s":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_illegal)?"i":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_break)?"B":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__genblk5__DOT__r_op_lock)?"L":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_op_pipe)?"P":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__break_pending)?"p":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_gie)?"G":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid_alu)?"A":"-"); |
printf("|%s%s%s%s%s", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_ce)?"a":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_stall)?"s":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__doalu__DOT__genblk2__DOT__r_busy)?"B":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_gie)?"G":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_alu_illegal)?"i":"-"); |
printf("|%s%s%s%2x %s%s%s %2d %2d", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid_mem)?"M":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_ce)?"m":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__adf_ce_unconditional)?"!":"-", |
(m_core->v__DOT__zippy__DOT__cmd_addr), |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__bus_err)?"BE":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__ibus_err_flag)?"IB":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__ubus_err_flag)?"UB":" ", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__domem__DOT__rdaddr, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__domem__DOT__wraddr); |
#ifdef XULA25 |
printf("|%s%s", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__div_busy)?"D":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__div_error)?"E":"-"); |
#endif |
printf("|%s%s[%2x]%08x", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_reg_ce)?"W":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_flags_ce)?"F":"-", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_reg_id, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_gpreg_vl); |
|
// Program counter debugging |
printf(" PC0x%08x/%08x/%08x-%08x %s0x%08x", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_pc, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__ipc, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__upc, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction, |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch)?"EB":" ", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_branch_pc |
); |
// More in-depth |
printf("[%c%08x,%c%08x,%c%08x]", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_dcdvalid)?'D':'-', |
m_core->v__DOT__zippy__DOT__thecpu__DOT__dcd_pc, |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid)?'O':'-', |
m_core->v__DOT__zippy__DOT__thecpu__DOT__op_pc, |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_valid)?'A':'-', |
m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_pc); |
|
#ifdef XULA25 |
// Prefetch debugging |
printf(" [PC%08x,LST%08x]->[%d%s%s](%d,%08x/%08x)->%08x@%08x", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_pc, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__lastpc, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__rvsrc, |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__rvsrc) |
?((m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_v_from_pc)?"P":" ") |
:((m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_v_from_pc)?"p":" "), |
(!m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__rvsrc) |
?((m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_v_from_last)?"l":" ") |
:((m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_v_from_last)?"L":" "), |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__isrc, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_pc_cache, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_last_cache, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction_pc); |
#else |
printf(" [PC%08x,R%08x]%s%s%s", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_pc, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_addr, |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__w_pc_out_of_bounds)?"OOB":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__w_running_out_of_cache)?"RUN":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__w_ran_off_end_of_cache)?"END":" "); |
#endif |
|
// Decode Stage debugging |
// (nothing) |
|
// Op Stage debugging |
printf(" Op(%02x,%02x->%02x)", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdOp, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__opn, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__opR); |
|
printf(" %s[%02x]=%08x(%08x)", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_reg_ce?"WR":"--", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_reg_id, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_gpreg_vl, |
#ifdef XULA25 |
m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_spreg_vl |
#else |
0 |
#endif |
); |
printf(" Rid=(%d|%d)?%02x:%02x", |
m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_wr, |
#ifdef XULA25 |
m_core->v__DOT__zippy__DOT__thecpu__DOT__div_valid, |
#else |
0, |
#endif |
m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_reg, |
m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_wreg); |
|
// domem, the pipelined memory unit debugging |
printf(" M[%s@0x%08x]", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid_mem) |
?((m_core->v__DOT__zippy__DOT__thecpu__DOT__opn&1)?"W":"R") |
:"-", |
#ifdef XULA25 |
m_core->v__DOT__zippy__DOT__cpu_addr |
#else |
0 |
#endif |
); |
printf("%s%s", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__domem__DOT__cyc)?"B":"-", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_rdbusy)?"r":"-"); |
/* |
printf(" %s-%s %04x/%04x", |
(m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_any)?"PIC":"pic", |
(m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_gie)?"INT":"( )", |
m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_int_enable, |
m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_int_state); |
*/ |
|
|
printf(" %s", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__cc_invalid_for_dcd)?"CCI":" "); |
/* |
// Illegal instruction debugging |
printf(" ILL[%s%s%s%s%s%s]", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_err)?"WB":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_illegal)?"PF":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__dcd_illegal)?"DCD":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_illegal)?"OP":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_alu_illegal)?"ALU":" ", |
(m_core->v__DOT__zippy__DOT__thecpu__DOT__ill_err_u)?"ILL":" "); |
|
*/ |
|
/* |
printf(" UART%08x/%d-%08x", m_last_tx_state, |
m_core->v__DOT__serialport__DOT__txmod__DOT__zero_baud_counter, |
m_core->v__DOT__serialport__DOT__txmod__DOT__baud_counter); |
*/ |
|
// Debug some conditions |
if (m_core->v__DOT__zippy__DOT__thecpu__DOT__ubreak) |
printf(" BREAK"); |
// if (m_core->v__DOT__zippy__DOT__thecpu__DOT__w_switch_to_interrupt) |
// printf(" TO-INT"); |
#ifdef XULA25 |
if (m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_interrupt) |
printf(" INTERRUPT"); |
#endif |
|
/* |
printf(" SDSPI[%d,%d(%d),(%d)]", |
m_core->v__DOT__sdcard_controller__DOT__r_cmd_busy, |
m_core->v__DOT__sdcard_controller__DOT__r_sdspi_clk, |
m_core->v__DOT__sdcard_controller__DOT__r_cmd_state, |
m_core->v__DOT__sdcard_controller__DOT__r_rsp_state); |
printf(" LL[%d,%2x->CK=%d/%2x,%s,ST=%2d,TX=%2x,RX=%2x->%d,%2x] ", |
m_core->v__DOT__sdcard_controller__DOT__ll_cmd_stb, |
m_core->v__DOT__sdcard_controller__DOT__ll_cmd_dat, |
m_core->v__DOT__sdcard_controller__DOT__lowlevel__DOT__r_z_counter, |
// (m_core->v__DOT__sdcard_controller__DOT__lowlevel__DOT__r_clk_counter==0)?1:0, |
m_core->v__DOT__sdcard_controller__DOT__lowlevel__DOT__r_clk_counter, |
(m_core->v__DOT__sdcard_controller__DOT__lowlevel__DOT__r_idle)?"IDLE":" ", |
m_core->v__DOT__sdcard_controller__DOT__lowlevel__DOT__r_state, |
m_core->v__DOT__sdcard_controller__DOT__lowlevel__DOT__r_byte, |
m_core->v__DOT__sdcard_controller__DOT__lowlevel__DOT__r_ireg, |
m_core->v__DOT__sdcard_controller__DOT__ll_out_stb, |
m_core->v__DOT__sdcard_controller__DOT__ll_out_dat |
); |
printf(" CRC=%02x/%2d", |
m_core->v__DOT__sdcard_controller__DOT__r_cmd_crc, |
m_core->v__DOT__sdcard_controller__DOT__r_cmd_crc_cnt); |
printf(" SPI(%d,%d,%d/%d,%d)->?", |
m_core->o_sf_cs_n, |
m_core->o_sd_cs_n, |
m_core->o_spi_sck, m_core->v__DOT__sdcard_sck, |
m_core->o_spi_mosi); |
|
printf(" CK=%d,LN=%d", |
m_core->v__DOT__sdcard_controller__DOT__r_sdspi_clk, |
m_core->v__DOT__sdcard_controller__DOT__r_lgblklen); |
|
|
if (m_core->v__DOT__sdcard_controller__DOT__r_use_fifo){ |
printf(" FIFO"); |
if (m_core->v__DOT__sdcard_controller__DOT__r_fifo_wr) |
printf("-WR(%04x,%d,%d,%d)", |
m_core->v__DOT__sdcard_controller__DOT__fifo_rd_crc_reg, |
m_core->v__DOT__sdcard_controller__DOT__fifo_rd_crc_stb, |
m_core->v__DOT__sdcard_controller__DOT__ll_fifo_pkt_state, |
m_core->v__DOT__sdcard_controller__DOT__r_have_data_response_token); |
else |
printf("-RD(%04x,%d,%d,%d)", |
m_core->v__DOT__sdcard_controller__DOT__fifo_wr_crc_reg, |
m_core->v__DOT__sdcard_controller__DOT__fifo_wr_crc_stb, |
m_core->v__DOT__sdcard_controller__DOT__ll_fifo_wr_state, |
m_core->v__DOT__sdcard_controller__DOT__ll_fifo_wr_complete |
); |
} |
|
if (m_core->v__DOT__sdcard_controller__DOT__ll_fifo_rd) |
printf(" LL-RD"); |
if (m_core->v__DOT__sdcard_controller__DOT__ll_fifo_wr) |
printf(" LL-WR"); |
if (m_core->v__DOT__sdcard_controller__DOT__r_have_start_token) |
printf(" START-TOK"); |
printf(" %3d/%02x", |
m_core->v__DOT__sdcard_controller__DOT__ll_fifo_addr, |
m_core->v__DOT__sdcard_controller__DOT__fifo_byte&0x0ff); |
*/ |
|
|
/* |
printf(" DMAC[%d]: %08x/%08x/%08x(%03x) -- (%d,%d,%c)%c%c:@%08x-[%4d,%4d/%4d,%4d-#%4d]%08x", |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__dma_state, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_waddr, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_raddr, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_len, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_blocklen_sub_one, |
m_core->v__DOT__zippy__DOT__dc_cyc, |
// m_core->v__DOT__zippy__DOT__dc_stb, |
(m_core->v__DOT__zippy__DOT__dma_controller__DOT__dma_state == 2)?1:0, |
|
((m_core->v__DOT__zippy__DOT__dma_controller__DOT__dma_state == 4) |
||(m_core->v__DOT__zippy__DOT__dma_controller__DOT__dma_state == 5) |
||(m_core->v__DOT__zippy__DOT__dma_controller__DOT__dma_state == 6))?'W':'R', |
//(m_core->v__DOT__zippy__DOT__dc_we)?'W':'R', |
(m_core->v__DOT__zippy__DOT__dc_ack)?'A':' ', |
(m_core->v__DOT__zippy__DOT__dc_stall)?'S':' ', |
m_core->v__DOT__zippy__DOT__dc_addr, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__rdaddr, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__nread, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__nracks, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__nwacks, |
m_core->v__DOT__zippy__DOT__dma_controller__DOT__nwritten, |
m_core->v__DOT__zippy__DOT__dc_data); |
|
printf(" %08x-PIC%08x", |
m_core->v__DOT__zippy__DOT__main_int_vector, |
m_core->v__DOT__zippy__DOT__pic_data); |
*/ |
|
printf("\n"); fflush(stdout); |
} m_last_writeout = writeout; |
|
int writing_to_uart; |
writing_to_uart = (m_core->v__DOT__wb_stb) |
&&(m_core->v__DOT__wb_addr == 0x010b) |
&&(m_core->v__DOT__wb_we); |
if (writing_to_uart) { |
printf("SENT-TO-UART: %02x %c\n", |
(m_core->v__DOT__wb_data & 0x0ff), |
isgraph(m_core->v__DOT__wb_data&0x0ff) |
? m_core->v__DOT__wb_data&0x0ff |
: '.'); |
assert((m_core->v__DOT__wb_data & (~0xff))==0); |
} |
#endif // DEBUGGING_OUTPUT |
} |
|
bool dcd_ce(void) { |
if (!m_core->v__DOT__zippy__DOT__thecpu__DOT__r_dcdvalid) |
return true; |
if (!m_core->v__DOT__zippy__DOT__thecpu__DOT__op_stall) |
return true; |
return false; |
} |
|
}; |
|
BUSMASTER_TB *tb; |
/trunk/rtl/memdev.v
49,10 → 49,10
always @(posedge i_clk) |
o_wb_data <= mem[i_wb_addr]; |
always @(posedge i_clk) |
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we)) |
if ((i_wb_stb)&&(i_wb_we)) |
mem[i_wb_addr] <= i_wb_data; |
always @(posedge i_clk) |
o_wb_ack <= (i_wb_cyc)&&(i_wb_stb); |
o_wb_ack <= (i_wb_stb); |
assign o_wb_stall = 1'b0; |
|
endmodule |
/trunk/rtl/rtclight.v
66,11 → 66,11
reg [25:0] timer; |
|
wire ck_sel, tm_sel, sw_sel, sp_sel, al_sel; |
assign ck_sel = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_addr[2:0]==3'b000)); |
assign tm_sel = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_addr[2:0]==3'b001)); |
assign sw_sel = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_addr[2:0]==3'b010)); |
assign al_sel = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_addr[2:0]==3'b011)); |
assign sp_sel = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_addr[2:0]==3'b100)); |
assign ck_sel = ((i_wb_stb)&&(i_wb_addr[2:0]==3'b000)); |
assign tm_sel = ((i_wb_stb)&&(i_wb_addr[2:0]==3'b001)); |
assign sw_sel = ((i_wb_stb)&&(i_wb_addr[2:0]==3'b010)); |
assign al_sel = ((i_wb_stb)&&(i_wb_addr[2:0]==3'b011)); |
assign sp_sel = ((i_wb_stb)&&(i_wb_addr[2:0]==3'b100)); |
|
reg [39:0] ck_counter; |
reg ck_carry; |
/trunk/rtl/sdspi.v
97,7 → 97,7
// |
reg r_cmd_busy; |
wire wb_stb, write_stb, cmd_stb; // read_stb |
assign wb_stb = ((i_wb_cyc)&&(i_wb_stb)&&(~o_wb_stall)); |
assign wb_stb = ((i_wb_stb)&&(~o_wb_stall)); |
assign write_stb = ((wb_stb)&&( i_wb_we)); |
// assign read_stb = ((wb_stb)&&(~i_wb_we)); |
assign cmd_stb = (~r_cmd_busy)&&(write_stb) |
/trunk/rtl/cpu/div.v
57,6 → 57,11
reg r_sign, pre_sign, r_z, r_c, last_bit; |
reg [(LGBW-1):0] r_bit; |
|
reg zero_divisor; |
initial zero_divisor = 1'b0; |
always @(posedge i_clk) |
zero_divisor <= (r_divisor == 0)&&(r_busy); |
|
initial r_busy = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
63,7 → 68,7
r_busy <= 1'b0; |
else if (i_wr) |
r_busy <= 1'b1; |
else if ((last_bit)||(o_err)) |
else if ((last_bit)||(zero_divisor)) |
r_busy <= 1'b0; |
|
initial o_busy = 1'b0; |
72,7 → 77,7
o_busy <= 1'b0; |
else if (i_wr) |
o_busy <= 1'b1; |
else if (((last_bit)||(o_err))&&(~r_sign)) |
else if (((last_bit)&&(~r_sign))||(zero_divisor)) |
o_busy <= 1'b0; |
else if (~r_busy) |
o_busy <= 1'b0; |
82,21 → 87,22
o_valid <= 1'b0; |
else if (r_busy) |
begin |
if ((last_bit)||(o_err)) |
o_valid <= (o_err)||(~r_sign); |
if ((last_bit)||(zero_divisor)) |
o_valid <= (zero_divisor)||(~r_sign); |
end else if (r_sign) |
begin |
// if (o_err), o_valid is already one. |
// if not, o_valid has not yet become one. |
o_valid <= (~o_err); // 1'b1; |
o_valid <= (~zero_divisor); // 1'b1; |
end else |
o_valid <= 1'b0; |
|
initial o_err = 1'b0; |
always @(posedge i_clk) |
if((i_rst)||(o_valid)) |
o_err <= 1'b0; |
else if (o_busy) |
o_err <= (r_divisor == 0); |
else if (((r_busy)||(r_sign))&&(zero_divisor)) |
o_err <= 1'b1; |
else |
o_err <= 1'b0; |
|
initial last_bit = 1'b0; |
always @(posedge i_clk) |
172,6 → 178,7
o_quotient[r_bit[(LGBW-1):0]] <= 1'b1; |
r_z <= 1'b0; |
end |
r_sign <= (r_sign)&&(~zero_divisor); |
end else if (r_sign) |
begin |
r_sign <= 1'b0; |
/trunk/rtl/cpu/zipbones.v
45,7 → 45,7
i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data, |
o_dbg_ack, o_dbg_stall, o_dbg_data |
`ifdef DEBUG_SCOPE |
, o_zip_debug |
, o_cpu_debug |
`endif |
); |
parameter RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=32, |
71,7 → 71,7
output wire [31:0] o_dbg_data; |
// |
`ifdef DEBUG_SCOPE |
output wire [31:0] o_zip_debug; |
output wire [31:0] o_cpu_debug; |
`endif |
|
// |
119,12 → 119,8
|
initial cmd_clear_pf_cache = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
cmd_clear_pf_cache <= 1'b0; |
else if (dbg_cmd_write) |
cmd_clear_pf_cache <= i_dbg_data[11]; |
else |
cmd_clear_pf_cache <= 1'b0; |
cmd_clear_pf_cache = (~i_rst)&&(dbg_cmd_write) |
&&((i_dbg_data[11])||(i_dbg_data[6])); |
// |
initial cmd_step = 1'b0; |
always @(posedge i_clk) |
176,10 → 172,10
cpu_lcl_cyc, cpu_lcl_stb, |
o_wb_we, o_wb_addr, o_wb_data, |
i_wb_ack, i_wb_stall, i_wb_data, |
(i_wb_err)||((cpu_lcl_cyc)&&(cpu_lcl_stb)), |
(i_wb_err)||(cpu_lcl_cyc), |
cpu_op_stall, cpu_pf_stall, cpu_i_count |
`ifdef DEBUG_SCOPE |
, o_zip_debug |
, o_cpu_debug |
`endif |
); |
|
188,7 → 184,7
initial o_dbg_ack = 1'b0; |
always @(posedge i_clk) |
o_dbg_ack <= (i_dbg_cyc)&&((~i_dbg_addr)||(~o_dbg_stall)); |
assign o_dbg_stall=(i_dbg_cyc)&&(cpu_dbg_stall)&&(i_dbg_addr); |
assign o_dbg_stall= 1'b0; //(i_dbg_cyc)&&(cpu_dbg_stall)&&(i_dbg_addr); |
|
assign o_ext_int = (cmd_halt) && (~i_wb_stall); |
|
/trunk/rtl/cpu/cpudefs.v
273,6 → 273,10
// |
// |
`define DEBUG_SCOPE |
`endif |
`else // XULA25 |
`ifdef VERILATOR |
`define DEBUG_SCOPE |
`endif // VERILATOR |
`endif // XULA25 |
// |
`endif // CPUDEFS_H |
/trunk/rtl/cpu/pfcache.v
44,8 → 44,8
input i_clear_cache; |
input i_stall_n; |
input [(AW-1):0] i_pc; |
output reg [(BUSW-1):0] o_i; |
output reg [(AW-1):0] o_pc; |
output wire [(BUSW-1):0] o_i; |
output wire [(AW-1):0] o_pc; |
output wire o_v; |
// |
output reg o_wb_cyc, o_wb_stb; |
64,8 → 64,7
assign o_wb_we = 1'b0; |
assign o_wb_data = 0; |
|
reg r_v; |
(* ram_style = "distributed" *) |
wire r_v; |
reg [(BUSW-1):0] cache [0:((1<<CW)-1)]; |
reg [(AW-CW-1):0] tags [0:((1<<(CW-PW))-1)]; |
reg [((1<<(CW-PW))-1):0] vmask; |
72,33 → 71,56
|
reg [(AW-1):0] lastpc; |
reg [(CW-1):0] rdaddr; |
reg [(AW-1):CW] tagval; |
reg [(AW-1):CW] tagvalipc, tagvallst; |
wire [(AW-1):CW] tagval; |
wire [(AW-1):PW] lasttag; |
reg illegal_valid; |
reg [(AW-1):PW] illegal_cache; |
|
initial o_i = 32'h76_00_00_00; // A NOOP instruction |
initial o_pc = 0; |
// initial o_i = 32'h76_00_00_00; // A NOOP instruction |
// initial o_pc = 0; |
reg [(BUSW-1):0] r_pc_cache, r_last_cache; |
reg [(AW-1):0] r_pc, r_lastpc; |
reg isrc; |
always @(posedge i_clk) |
if (~r_v) |
begin |
o_i <= cache[lastpc[(CW-1):0]]; |
o_pc <= lastpc; |
end else if ((i_stall_n)||(i_new_pc)) |
begin |
o_i <= cache[i_pc[(CW-1):0]]; |
o_pc <= i_pc; |
end |
begin |
// We don't have the logic to select what to read, we must |
// read both the value at i_pc and lastpc. cache[i_pc] is |
// the value we return if the cache is good, cacne[lastpc] is |
// the value we return if we've been stalled, weren't valid, |
// or had to wait a clock or two. (Remember i_pc can't stop |
// changing for a clock, so we need to keep track of the last |
// one from before it stopped.) |
// |
// Here we keep track of which answer we want/need |
isrc <= ((r_v)&&(i_stall_n))||(i_new_pc); |
|
initial tagval = 0; |
// Here we read both, and select which was write using isrc |
// on the next clock. |
r_pc_cache <= cache[i_pc[(CW-1):0]]; |
r_last_cache <= cache[lastpc[(CW-1):0]]; |
r_pc <= i_pc; |
r_lastpc <= lastpc; |
end |
assign o_pc = (isrc) ? r_pc : r_lastpc; |
assign o_i = (isrc) ? r_pc_cache : r_last_cache; |
|
reg tagsrc; |
always @(posedge i_clk) |
// It may be possible to recover a clock once the cache line |
// has been filled, but our prior attempt to do so has lead |
// to a race condition, so we keep this logic simple. |
if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc)) |
tagval <= tags[i_pc[(CW-1):PW]]; |
tagsrc <= 1'b1; |
else |
tagval <= tags[lastpc[(CW-1):PW]]; |
tagsrc <= 1'b0; |
initial tagvalipc = 0; |
always @(posedge i_clk) |
tagvalipc <= tags[i_pc[(CW-1):PW]]; |
initial tagvallst = 0; |
always @(posedge i_clk) |
tagvallst <= tags[lastpc[(CW-1):PW]]; |
assign tagval = (tagsrc)?tagvalipc : tagvallst; |
|
// i_pc will only increment when everything else isn't stalled, thus |
// we can set it without worrying about that. Doing this enables |
111,16 → 133,12
lastpc <= i_pc; |
|
assign lasttag = lastpc[(AW-1):PW]; |
// initial lasttag = 0; |
// always @(posedge i_clk) |
// if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc)) |
// lasttag <= i_pc[(AW-1):PW]; |
|
wire r_v_from_pc, r_v_from_last; |
assign r_v_from_pc = ((i_pc[(AW-1):PW] == lasttag) |
&&(tagval == i_pc[(AW-1):CW]) |
wire w_v_from_pc, w_v_from_last; |
assign w_v_from_pc = ((i_pc[(AW-1):PW] == lasttag) |
&&(tagvalipc == i_pc[(AW-1):CW]) |
&&(vmask[i_pc[(CW-1):PW]])); |
assign r_v_from_last = ( |
assign w_v_from_last = ( |
//(lastpc[(AW-1):PW] == lasttag)&& |
(tagval == lastpc[(AW-1):CW]) |
&&(vmask[lastpc[(CW-1):PW]])); |
128,23 → 146,54
reg [1:0] delay; |
|
initial delay = 2'h3; |
initial r_v = 1'b0; |
reg rvsrc; |
always @(posedge i_clk) |
if ((i_rst)||(i_clear_cache)||(i_new_pc)||((r_v)&&(i_stall_n))) |
begin |
r_v <= r_v_from_pc; |
// r_v <= r_v_from_pc; |
rvsrc <= 1'b1; |
delay <= 2'h2; |
end else if (~r_v) begin // Otherwise, r_v was true and we were |
r_v <= r_v_from_last; // stalled, hence only if ~r_v |
// stalled, hence only if ~r_v |
rvsrc <= 1'b0; |
if (o_wb_cyc) |
delay <= 2'h2; |
else if (delay != 0) |
delay <= delay + 2'b11; // i.e. delay -= 1; |
end |
reg r_v_from_pc, r_v_from_last; |
always @(posedge i_clk) |
r_v_from_pc <= w_v_from_pc; |
always @(posedge i_clk) |
r_v_from_last <= w_v_from_last; |
|
assign o_v = (r_v)&&(~i_new_pc); |
assign r_v = ((rvsrc)?(r_v_from_pc):(r_v_from_last)); |
assign o_v = (((rvsrc)?(r_v_from_pc):(r_v_from_last)) |
||((o_illegal)&&(~o_wb_cyc))) |
&&(~i_new_pc)&&(~i_rst); |
|
reg last_ack; |
initial last_ack = 1'b0; |
always @(posedge i_clk) |
last_ack <= (o_wb_cyc)&&( |
(rdaddr[(PW-1):1]=={(PW-1){1'b1}}) |
&&((rdaddr[0])||(i_wb_ack))); |
|
reg needload; |
initial needload = 1'b0; |
always @(posedge i_clk) |
needload <= ((~r_v)&&(delay==0) |
&&((tagvallst != lastpc[(AW-1):CW]) |
||(~vmask[lastpc[(CW-1):PW]])) |
&&((~illegal_valid) |
||(lastpc[(AW-1):PW] != illegal_cache))); |
|
reg last_addr; |
initial last_addr = 1'b0; |
always @(posedge i_clk) |
last_addr <= (o_wb_cyc)&&(o_wb_addr[(PW-1):1] == {(PW-1){1'b1}}) |
&&((~i_wb_stall)|(o_wb_addr[0])); |
|
initial o_wb_cyc = 1'b0; |
initial o_wb_stb = 1'b0; |
initial o_wb_addr = {(AW){1'b0}}; |
158,53 → 207,72
begin |
if (i_wb_err) |
o_wb_stb <= 1'b0; |
else if ((o_wb_stb)&&(~i_wb_stall)) |
begin |
if (o_wb_addr[(PW-1):0] == {(PW){1'b1}}) |
o_wb_stb <= 1'b0; |
else |
o_wb_addr[(PW-1):0] <= o_wb_addr[(PW-1):0]+1; |
end |
else if ((o_wb_stb)&&(~i_wb_stall)&&(last_addr)) |
o_wb_stb <= 1'b0; |
|
if (i_wb_ack) |
begin |
rdaddr <= rdaddr + 1; |
tags[o_wb_addr[(CW-1):PW]] <= o_wb_addr[(AW-1):CW]; |
end |
|
if (((i_wb_ack)&&(rdaddr[(PW-1):0]=={(PW){1'b1}}))||(i_wb_err)) |
if (((i_wb_ack)&&(last_ack))||(i_wb_err)) |
o_wb_cyc <= 1'b0; |
|
// else if (rdaddr[(PW-1):1] == {(PW-1){1'b1}}) |
// tags[lastpc[(CW-1):PW]] <= lastpc[(AW-1):CW]; |
|
end else if ((~r_v)&&(delay==0) |
&&((tagval != lastpc[(AW-1):CW]) |
||(~vmask[lastpc[(CW-1):PW]])) |
&&((~illegal_valid)||(lastpc[(AW-1):PW] != illegal_cache))) |
end else if (needload) |
begin |
o_wb_cyc <= 1'b1; |
o_wb_stb <= 1'b1; |
o_wb_addr <= { lastpc[(AW-1):PW], {(PW){1'b0}} }; |
rdaddr <= { lastpc[(CW-1):PW], {(PW){1'b0}} }; |
end |
|
always @(posedge i_clk) |
if (o_wb_cyc) // &&(i_wb_ack) |
tags[o_wb_addr[(CW-1):PW]] <= o_wb_addr[(AW-1):CW]; |
always @(posedge i_clk) |
if ((o_wb_cyc)&&(i_wb_ack)) |
rdaddr <= rdaddr + 1; |
else if (~o_wb_cyc) |
rdaddr <= { lastpc[(CW-1):PW], {(PW){1'b0}} }; |
|
always @(posedge i_clk) |
if ((o_wb_stb)&&(~i_wb_stall)&&(~last_addr)) |
o_wb_addr[(PW-1):0] <= o_wb_addr[(PW-1):0]+1; |
else if (~o_wb_cyc) |
o_wb_addr <= { lastpc[(AW-1):PW], {(PW){1'b0}} }; |
|
// Can't initialize an array, so leave cache uninitialized |
// We'll also never get an ack without sys being active, so skip |
// that check. Or rather, let's just use o_wb_cyc instead. This |
// will work because multiple writes to the same address, ending with |
// a valid write, aren't a problem. |
always @(posedge i_clk) |
if ((o_wb_cyc)&&(i_wb_ack)) |
if (o_wb_cyc) // &&(i_wb_ack) |
cache[rdaddr] <= i_wb_data; |
|
// VMask ... is a section loaded? |
// Note "svmask". It's purpose is to delay the vmask setting by one |
// clock, so that we can insure the right value of the cache is loaded |
// before declaring that the cache line is valid. Without this, the |
// cache line would get read, and the instruction would read from the |
// last cache line. |
reg svmask; |
initial vmask = 0; |
initial svmask = 1'b0; |
reg [(CW-PW-1):0] saddr; |
always @(posedge i_clk) |
if ((i_rst)||(i_clear_cache)) |
begin |
vmask <= 0; |
svmask<= 1'b0; |
end |
else begin |
if ((o_wb_cyc)&&(i_wb_ack)&&(rdaddr[(PW-1):0] == {(PW){1'b1}})) |
vmask[rdaddr[(CW-1):PW]] <= 1'b1; |
if ((~r_v)&&(tagval != lastpc[(AW-1):CW])&&(delay == 0)) |
svmask <= ((o_wb_cyc)&&(i_wb_ack)&&(last_ack)); |
|
if (svmask) |
vmask[saddr] <= 1'b1; |
if ((~o_wb_cyc)&&(needload)) |
vmask[lastpc[(CW-1):PW]] <= 1'b0; |
end |
always @(posedge i_clk) |
if ((o_wb_cyc)&&(i_wb_ack)) |
saddr <= rdaddr[(CW-1):PW]; |
|
initial illegal_cache = 0; |
initial illegal_valid = 0; |
221,7 → 289,7
|
initial o_illegal = 1'b0; |
always @(posedge i_clk) |
if ((i_rst)||(i_clear_cache)) |
if ((i_rst)||(i_clear_cache)||(o_wb_cyc)) |
o_illegal <= 1'b0; |
else |
o_illegal <= (illegal_valid) |
/trunk/rtl/cpu/idecode.v
104,7 → 104,7
wire [3:0] w_cond; |
wire w_wF, w_dcdM, w_dcdDV, w_dcdFP; |
wire w_wR, w_rA, w_rB, w_wR_n; |
wire w_ljmp; |
wire w_ljmp, w_ljmp_dly; |
wire [31:0] iword; |
|
|
148,7 → 148,9
// If the result register is either CC or PC, and this would otherwise |
// be a floating point instruction with floating point opcode of 0, |
// then this is a NOOP. |
assign w_noop = (w_op[4:0] == 5'h18)&&(w_dcdR[3:1] == 3'h7); |
assign w_noop = (w_op[4:0] == 5'h18)&&( |
((IMPLEMENT_FPU>0)&&(w_dcdR[3:1] == 3'h7)) |
||(IMPLEMENT_FPU==0)); |
|
// 4 LUTs |
assign w_dcdB = { ((~iword[31])&&(w_mov)&&(~i_gie))?iword[13]:i_gie, |
249,9 → 251,10
reg r_phase; |
initial r_phase = 1'b0; |
always @(posedge i_clk) |
if (i_rst) // When no instruction is in the pipe, phase is zero |
if ((i_rst) // When no instruction is in the pipe, phase is zero |
||(o_early_branch)||(w_ljmp_dly)) |
r_phase <= 1'b0; |
else if (i_ce) |
else if ((i_ce)&&(i_pf_valid)) |
r_phase <= (o_phase)? 1'b0:(i_instruction[31]); |
// Phase is '1' on the first instruction of a two-part set |
// But, due to the delay in processing, it's '1' when our output is |
276,7 → 279,7
`else |
o_illegal <= ((i_illegal) || (i_instruction[31])); |
`endif |
if ((IMPLEMENT_MPY!=1)&&(w_op[4:1]==4'h5)) |
if ((IMPLEMENT_MPY==0)&&((w_op[4:1]==4'h5)||(w_op[4:0]==5'h08))) |
o_illegal <= 1'b1; |
|
if ((IMPLEMENT_DIVIDE==0)&&(w_dcdDV)) |
357,10 → 360,14
o_M <= w_dcdM; |
o_DV <= w_dcdDV; |
o_FP <= w_dcdFP; |
|
o_break <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b001); |
|
o_break <= (w_op[4:0]==5'b11001)&&( |
((IMPLEMENT_FPU>0)&&(w_dcdR[3:1]==3'h7)) |
||(IMPLEMENT_FPU==0)); |
`ifdef OPT_PIPELINED |
r_lock <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b010); |
r_lock <= (w_op[4:0]==5'b11010)&&( |
((IMPLEMENT_FPU>0)&&(w_dcdR[3:1]==3'h7)) |
||(IMPLEMENT_FPU==0)); |
`endif |
`ifdef OPT_VLIW |
r_nxt_half <= { iword[31], iword[13:5], |
426,9 → 433,11
+ {{(AW-1){1'b0}},1'b1}; |
end |
|
assign w_ljmp_dly = r_ljmp; |
assign o_early_branch = r_early_branch; |
assign o_branch_pc = r_branch_pc; |
end else begin |
assign w_ljmp_dly = 1'b0; |
assign o_early_branch = 1'b0; |
assign o_branch_pc = {(AW){1'b0}}; |
assign o_ljmp = 1'b0; |
/trunk/rtl/cpu/pipefetch.v
257,10 → 257,10
|
initial r_addr_set = 1'b0; |
always @(posedge i_clk) |
if ((i_rst)||(i_clear_cache)) |
if ((i_rst)||(i_new_pc)) |
r_addr_set <= 1'b1; |
else if (i_clear_cache) |
r_addr_set <= 1'b0; |
else if (i_new_pc) |
r_addr_set <= 1'b1; |
|
// Now, read from the cache |
wire w_cv; // Cache valid, address is in the cache |
293,7 → 293,7
if ((o_wb_cyc)&&(i_wb_err)) |
ill_address <= o_wb_addr - {{(AW-LGCACHELEN-1){1'b0}}, r_acks_waiting}; |
|
assign o_illegal = (o_pc == ill_address); |
assign o_illegal = (o_pc == ill_address)&&(~i_rst)&&(~i_new_pc)&&(~i_clear_cache); |
|
|
endmodule |
/trunk/rtl/cpu/zipsystem.v
308,7 → 308,7
always @(posedge i_clk) |
cmd_reset <= ((dbg_cmd_write)&&(dbg_idata[6])); |
// |
initial cmd_halt = 1'b1; |
initial cmd_halt = START_HALTED; |
always @(posedge i_clk) |
if (i_rst) |
cmd_halt <= (START_HALTED == 1)? 1'b1 : 1'b0; |
317,6 → 317,7
else if ((cmd_step)||(cpu_break)) |
cmd_halt <= 1'b1; |
|
initial cmd_clear_pf_cache = 1'b0; |
always @(posedge i_clk) |
cmd_clear_pf_cache = (~i_rst)&&(dbg_cmd_write) |
&&((dbg_idata[11])||(dbg_idata[6])); |
/trunk/rtl/cpu/busdelay.v
23,7 → 23,7
// |
/////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
55,11 → 55,12
input [(AW-1):0] i_wb_addr; |
input [(DW-1):0] i_wb_data; |
output reg o_wb_ack; |
output wire o_wb_stall; |
output reg o_wb_stall; |
output reg [(DW-1):0] o_wb_data; |
output wire o_wb_err; |
output reg o_wb_err; |
// Delayed bus |
output reg o_dly_cyc, o_dly_stb, o_dly_we; |
output reg o_dly_cyc, o_dly_we; |
output wire o_dly_stb; |
output reg [(AW-1):0] o_dly_addr; |
output reg [(DW-1):0] o_dly_data; |
input i_dly_ack; |
67,24 → 68,29
input [(DW-1):0] i_dly_data; |
input i_dly_err; |
|
reg loaded; |
initial o_dly_cyc = 1'b0; |
initial o_dly_stb = 1'b0; |
initial loaded = 1'b0; |
|
always @(posedge i_clk) |
o_dly_cyc <= i_wb_cyc; |
o_wb_stall <= (loaded)&&(i_dly_stall); |
|
initial o_dly_cyc = 1'b0; |
always @(posedge i_clk) |
o_dly_cyc <= (i_wb_cyc); |
// Add the i_wb_cyc criteria here, so we can simplify the o_wb_stall |
// criteria below, which would otherwise *and* these two. |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_stb <= ((i_wb_cyc)&&(i_wb_stb)); |
loaded <= (i_wb_stb)||((loaded)&&(i_dly_stall)&&(~i_dly_err)&&(i_wb_cyc)); |
assign o_dly_stb = loaded; |
always @(posedge i_clk) |
if (~o_wb_stall) |
if (~i_dly_stall) |
o_dly_we <= i_wb_we; |
always @(posedge i_clk) |
if (~o_wb_stall) |
if (~i_dly_stall) |
o_dly_addr<= i_wb_addr; |
always @(posedge i_clk) |
if (~o_wb_stall) |
if (~i_dly_stall) |
o_dly_data <= i_wb_data; |
always @(posedge i_clk) |
o_wb_ack <= (i_dly_ack)&&(o_dly_cyc)&&(i_wb_cyc); |
91,11 → 97,7
always @(posedge i_clk) |
o_wb_data <= i_dly_data; |
|
// Our only non-delayed line, yet still really delayed. Perhaps |
// there's a way to register this? |
// o_wb_stall <= (i_wb_cyc)&&(i_wb_stb) ... or some such? |
// assign o_wb_stall=((i_wb_cyc)&&(i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_stall = ((i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_err = i_dly_err; |
always @(posedge i_clk) |
o_wb_err <= (i_dly_err)&&(o_dly_cyc)&&(i_wb_cyc); |
|
endmodule |
/trunk/rtl/cpu/cpuops.v
53,11 → 53,19
assign w_rol_result = w_rol_tmp[63:32]; // Won't set flags |
|
// Shift register pre-logic |
wire [32:0] w_lsr_result, w_asr_result; |
wire [32:0] w_lsr_result, w_asr_result, w_lsl_result; |
wire signed [32:0] w_pre_asr_input, w_pre_asr_shifted; |
assign w_pre_asr_input = { i_a, 1'b0 }; |
assign w_pre_asr_shifted = w_pre_asr_input >>> i_b[4:0]; |
assign w_asr_result = (|i_b[31:5])? {(33){i_a[31]}} |
: ( {i_a, 1'b0 } >>> (i_b[4:0]) );// ASR |
assign w_lsr_result = (|i_b[31:5])? 33'h00 |
: ( { i_a, 1'b0 } >> (i_b[4:0]) );// LSR |
: w_pre_asr_shifted;// ASR |
assign w_lsr_result = ((|i_b[31:6])||(i_b[5]&&(i_b[4:0]!=0)))? 33'h00 |
:((i_b[5])?{32'h0,i_a[31]} |
|
: ( { i_a, 1'b0 } >> (i_b[4:0]) ));// LSR |
assign w_lsl_result = ((|i_b[31:6])||(i_b[5]&&(i_b[4:0]!=0)))? 33'h00 |
:((i_b[5])?{i_a[0], 32'h0} |
: ({1'b0, i_a } << i_b[4:0])); // LSL |
|
// Bit reversal pre-logic |
wire [31:0] w_brev_result; |
116,7 → 124,7
4'b0011: o_c <= i_a | i_b; // Or |
4'b0100: o_c <= i_a ^ i_b; // Xor |
4'b0101:{o_c,c } <= w_lsr_result[32:0]; // LSR |
4'b0110:{c,o_c } <= (|i_b[31:5])? 33'h00 : {1'b0, i_a } << i_b[4:0]; // LSL |
4'b0110:{c,o_c } <= w_lsl_result[32:0]; // LSL |
4'b0111:{o_c,c } <= w_asr_result[32:0]; // ASR |
`ifndef LONG_MPY |
4'b1000: o_c <= { i_b[15: 0], i_a[15:0] }; // LODIHI |
296,7 → 304,7
4'b0011: o_c <= i_a | i_b; // Or |
4'b0100: o_c <= i_a ^ i_b; // Xor |
4'b0101:{o_c,c } <= w_lsr_result[32:0]; // LSR |
4'b0110:{c,o_c } <= (|i_b[31:5])? 33'h00 : {1'b0, i_a } << i_b[4:0]; // LSL |
4'b0110:{c,o_c } <= w_lsl_result[32:0]; // LSL |
4'b0111:{o_c,c } <= w_asr_result[32:0]; // ASR |
`ifdef LONG_MPY |
4'b1000: o_c <= r_mpy_result[31:0]; // MPY |
/trunk/rtl/cpu/zipcpu.v
103,6 → 103,8
// |
`define CPU_CC_REG 4'he |
`define CPU_PC_REG 4'hf |
`define CPU_CLRCACHE_BIT 14 // Floating point error flag, set on error |
`define CPU_PHASE_BIT 13 // Floating point error flag, set on error |
`define CPU_FPUERR_BIT 12 // Floating point error flag, set on error |
`define CPU_DIVERR_BIT 11 // Divide error flag, set on divide by zero |
`define CPU_BUSERR_BIT 10 // Bus error flag, set on error |
203,13 → 205,16
// Condition codes |
// (BUS, TRAP,ILL,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z |
reg [3:0] flags, iflags; |
wire [13:0] w_uflags, w_iflags; |
reg trap, break_en, step, gie, sleep, r_halted; |
wire [14:0] w_uflags, w_iflags; |
reg trap, break_en, step, gie, sleep, r_halted, |
break_pending; |
wire w_clear_icache; |
`ifdef OPT_ILLEGAL_INSTRUCTION |
reg ill_err_u, ill_err_i; |
`else |
wire ill_err_u, ill_err_i; |
`endif |
reg ubreak; |
reg ibus_err_flag, ubus_err_flag; |
wire idiv_err_flag, udiv_err_flag; |
wire ifpu_err_flag, ufpu_err_flag; |
226,7 → 231,7
reg [(AW-1):0] pf_pc; |
reg new_pc; |
wire clear_pipeline; |
assign clear_pipeline = new_pc || i_clear_pf_cache; |
assign clear_pipeline = new_pc; |
|
wire dcd_stalled; |
wire pf_cyc, pf_stb, pf_we, pf_busy, pf_ack, pf_stall, pf_err; |
281,7 → 286,7
wire [31:0] w_opA, w_opB; |
wire [31:0] opA_nowait, opB_nowait, opA, opB; |
reg opR_wr, opR_cc, opF_wr, op_gie; |
wire [13:0] opFl; |
wire [14:0] opFl; |
reg [5:0] r_opF; |
wire [7:0] opF; |
wire op_ce, op_phase, op_pipe, op_change_data_ce; |
349,12 → 354,7
&&(~mem_rdbusy)&&(~div_busy)&&(~fpu_busy) |
&&(set_cond); |
|
// ALU, DIV, or FPU CE ... equivalent to the OR of all three of these |
wire adf_ce, adf_ce_unconditional; |
assign adf_ce_unconditional = (master_ce)&&(~clear_pipeline)&&(opvalid) |
&&(~opvalid_mem)&&(~mem_rdbusy)&&(~div_busy) |
&&(~fpu_busy); |
assign adf_ce = (adf_ce_unconditional)&&(set_cond); |
wire adf_ce_unconditional; |
|
// |
// |
361,7 → 361,8
// PIPELINE STAGE #5 :: Write-back |
// Variable declarations |
// |
wire wr_reg_ce, wr_flags_ce, wr_write_pc, wr_write_cc; |
wire wr_reg_ce, wr_flags_ce, wr_write_pc, wr_write_cc, |
wr_write_scc, wr_write_ucc; |
wire [4:0] wr_reg_id; |
wire [31:0] wr_gpreg_vl, wr_spreg_vl; |
wire w_switch_to_interrupt, w_release_from_interrupt; |
400,6 → 401,14
// Calculate stall conditions |
wire op_lock_stall; |
`ifdef OPT_PIPELINED |
reg cc_invalid_for_dcd; |
always @(posedge i_clk) |
cc_invalid_for_dcd <= (wr_flags_ce) |
||(wr_reg_ce)&&(wr_reg_id[3:0] == `CPU_CC_REG) |
||(opvalid)&&((opF_wr)||((opR_wr)&&(opR[3:0] == `CPU_CC_REG))) |
||((alF_wr)||((alu_wr)&&(alu_reg[3:0] == `CPU_CC_REG))) |
||(mem_busy)||(div_busy)||(fpu_busy); |
|
assign op_stall = (opvalid)&&( // Only stall if we're loaded w/validins |
// Stall if we're stopped, and not allowed to execute |
// an instruction |
418,6 → 427,7
// that cannot be pipelined, and the memory is |
// already busy |
||(mem_stalled) // &&(opvalid_mem) part of mem_stalled |
||(opR_cc) |
) |
||(dcdvalid)&&( |
// Stall if we need to wait for an operand A |
433,6 → 443,8
||(dcdF_stall) |
); |
assign op_ce = ((dcdvalid)||(dcd_illegal))&&(~op_stall)&&(~clear_pipeline); |
|
|
// BUT ... op_ce is too complex for many of the data operations. So |
// let's make their circuit enable code simpler. In particular, if |
// op_ doesn't need to be preserved, we can change it all we want |
460,17 → 472,14
// the ALU. |
`ifdef OPT_PIPELINED |
assign alu_stall = (((~master_ce)||(mem_rdbusy)||(alu_busy))&&(opvalid_alu)) //Case 1&2 |
// Old case #3--this isn't an ALU stall though ... |
||((opvalid_alu)&&(wr_reg_ce)&&(wr_reg_id[4] == op_gie) |
&&(wr_write_cc)) // Case 3 |
||((opvalid)&&(op_lock)&&(op_lock_stall)) |
||((opvalid)&&(op_break)) |
||(wr_reg_ce)&&(wr_write_cc) |
||(div_busy)||(fpu_busy); |
assign alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall) |
&&(~clear_pipeline); |
`else |
assign alu_stall = ((~master_ce)&&(opvalid_alu)) |
||((opvalid_alu)&&(op_break)); |
assign alu_stall = (opvalid_alu)&&((~master_ce)||(op_break)); |
assign alu_ce = (master_ce)&&((opvalid_alu)||(op_illegal))&&(~alu_stall)&&(~clear_pipeline); |
`endif |
// |
520,6 → 529,11
`endif |
`endif |
|
// ALU, DIV, or FPU CE ... equivalent to the OR of all three of these |
assign adf_ce_unconditional = (master_ce)&&(~clear_pipeline)&&(opvalid) |
&&(~opvalid_mem)&&(~mem_rdbusy) |
&&((~opvalid_alu)||(~alu_stall))&&(~op_break) |
&&(~div_busy)&&(~fpu_busy)&&(~clear_pipeline); |
|
// |
// |
542,7 → 556,7
if ((i_rst)||(clear_pipeline)) |
r_dcdvalid <= 1'b0; |
else if (dcd_ce) |
r_dcdvalid <= (pf_valid); |
r_dcdvalid <= (pf_valid)||(pf_illegal); |
else if (op_ce) |
r_dcdvalid <= 1'b0; |
assign dcdvalid = r_dcdvalid; |
552,7 → 566,7
`ifdef OPT_TRADITIONAL_PFCACHE |
pfcache #(LGICACHE, ADDRESS_WIDTH) |
pf(i_clk, i_rst, (new_pc)||((dcd_early_branch)&&(~clear_pipeline)), |
i_clear_pf_cache, |
w_clear_icache, |
// dcd_pc, |
~dcd_stalled, |
((dcd_early_branch)&&(~clear_pipeline)) |
563,8 → 577,8
pf_illegal); |
`else |
pipefetch #(RESET_ADDRESS, LGICACHE, ADDRESS_WIDTH) |
pf(i_clk, i_rst, (new_pc)||((dcd_early_branch)&&(~clear_pipeline)), |
i_clear_pf_cache, ~dcd_stalled, |
pf(i_clk, i_rst, (new_pc)||(dcd_early_branch), |
w_clear_icache, ~dcd_stalled, |
(new_pc)?pf_pc:dcd_branch_pc, |
instruction, instruction_pc, pf_valid, |
pf_cyc, pf_stb, pf_we, pf_addr, pf_data, |
581,10 → 595,10
|
initial r_dcdvalid = 1'b0; |
always @(posedge i_clk) |
if ((i_rst)||(clear_pipeline)) |
if ((i_rst)||(clear_pipeline)||(w_clear_icache)) |
r_dcdvalid <= 1'b0; |
else if (dcd_ce) |
r_dcdvalid <= (pf_valid)&&(~dcd_ljmp)&&((~r_dcdvalid)||(~dcd_early_branch)); |
r_dcdvalid <= (pf_valid)&&(~dcd_ljmp)&&(~dcd_early_branch); |
else if (op_ce) |
r_dcdvalid <= 1'b0; |
assign dcdvalid = r_dcdvalid; |
591,10 → 605,12
`endif |
|
`ifdef OPT_NEW_INSTRUCTION_SET |
|
// If not pipelined, there will be no opvalid_ anything, and the |
idecode #(AW, IMPLEMENT_MPY, EARLY_BRANCHING, IMPLEMENT_DIVIDE, |
IMPLEMENT_FPU) |
instruction_decoder(i_clk, (i_rst)||(clear_pipeline), |
dcd_ce, dcd_stalled, instruction, instruction_gie, |
(~dcdvalid)||(~op_stall), dcd_stalled, instruction, instruction_gie, |
instruction_pc, pf_valid, pf_illegal, dcd_phase, |
dcd_illegal, dcd_pc, dcd_gie, |
{ dcdR_cc, dcdR_pc, dcdR }, |
735,7 → 751,7
else if (dcdA_pc) |
r_opA <= w_pcA_v; |
else if (dcdA_cc) |
r_opA <= { w_cpu_info, w_opA[22:14], (dcdA[4])?w_uflags:w_iflags }; |
r_opA <= { w_cpu_info, w_opA[22:15], (dcdA[4])?w_uflags:w_iflags }; |
else |
r_opA <= w_opA; |
`ifdef OPT_PIPELINED |
761,7 → 777,7
assign w_opBnI = (~dcdB_rd) ? 32'h00 |
: (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl |
: ((dcdB_pc) ? w_pcB_v |
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:14], // w_opB[31:14], |
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:15], // w_opB[31:14], |
(dcdB[4])?w_uflags:w_iflags} |
: w_opB))); |
|
825,6 → 841,8
opvalid <= 1'b0; |
opvalid_alu <= 1'b0; |
opvalid_mem <= 1'b0; |
opvalid_div <= 1'b0; |
opvalid_fpu <= 1'b0; |
end else if (op_ce) |
begin |
// Do we have a valid instruction? |
835,9 → 853,9
// Hence, the test on dcd_stalled here. If we must |
// wait until our operands are valid, then we aren't |
// valid yet until then. |
opvalid<= w_opvalid; |
opvalid<= (w_opvalid)||(dcd_illegal)&&(dcdvalid); |
`ifdef OPT_ILLEGAL_INSTRUCTION |
opvalid_alu <= ((dcdALU)||(dcd_illegal))&&(w_opvalid); |
opvalid_alu <= (w_opvalid)&&((dcdALU)||(dcd_illegal)); |
opvalid_mem <= (dcdM)&&(~dcd_illegal)&&(w_opvalid); |
opvalid_div <= (dcdDV)&&(~dcd_illegal)&&(w_opvalid); |
opvalid_fpu <= (dcdFP)&&(~dcd_illegal)&&(w_opvalid); |
868,7 → 886,7
initial op_break = 1'b0; |
always @(posedge i_clk) |
if (i_rst) op_break <= 1'b0; |
else if (op_ce) op_break <= (dcd_break); |
else if (op_ce) op_break <= (dcd_break); // &&(dcdvalid) |
else if ((clear_pipeline)||(~opvalid)) |
op_break <= 1'b0; |
|
913,11 → 931,13
op_illegal <= 1'b0; |
else if(op_ce) |
`ifdef OPT_PIPELINED |
op_illegal <=(dcd_illegal)||((dcd_lock)&&(IMPLEMENT_LOCK == 0)); |
op_illegal <= (dcdvalid)&&((dcd_illegal)||((dcd_lock)&&(IMPLEMENT_LOCK == 0))); |
`else |
op_illegal <= (dcd_illegal)||(dcd_lock); |
op_illegal <= (dcdvalid)&&((dcd_illegal)||(dcd_lock)); |
`endif |
`endif |
else if(alu_ce) |
op_illegal <= 1'b0; |
|
// No generate on EARLY_BRANCHING here, since if EARLY_BRANCHING is not |
// set, dcd_early_branch will simply be a wire connected to zero and |
989,7 → 1009,8
assign dcdA_stall = (dcdA_rd) // &&(dcdvalid) is checked for elsewhere |
&&((opvalid)||(mem_rdbusy) |
||(div_busy)||(fpu_busy)) |
&&((opF_wr)&&(dcdA_cc)); |
&&(((opF_wr)||(cc_invalid_for_dcd))&&(dcdA_cc)) |
||((dcdA_rd)&&(dcdA_cc)&&(cc_invalid_for_dcd)); |
`else |
// There are no pipeline hazards, if we aren't pipelined |
assign dcdA_stall = 1'b0; |
1042,11 → 1063,12
// Stall following any instruction that will |
// set the flags, if we're going to need the |
// flags (CC) register for opB. |
||((opF_wr)&&(dcdB_cc)) |
||(((opF_wr)||(cc_invalid_for_dcd))&&(dcdB_cc)) |
// Stall on any ongoing memory operation that |
// will write to opB -- captured above |
// ||((mem_busy)&&(~mem_we)&&(mem_last_reg==dcdB)&&(~dcd_zI)) |
); |
) |
||((dcdB_rd)&&(dcdB_cc)&&(cc_invalid_for_dcd)); |
assign dcdF_stall = ((~dcdF[3]) |
||((dcdA_rd)&&(dcdA_cc)) |
||((dcdB_rd)&&(dcdB_cc))) |
1082,7 → 1104,7
opA, opB, div_busy, div_valid, div_error, div_result, |
div_flags); |
end else begin |
assign div_error = 1'b1; |
assign div_error = 1'b0; // Can't be high unless div_valid |
assign div_busy = 1'b0; |
assign div_valid = 1'b0; |
assign div_result= 32'h00; |
1097,13 → 1119,13
// opA, opB, fpu_busy, fpu_valid, fpu_err, fpu_result, |
// fpu_flags); |
// |
assign fpu_error = 1'b1; |
assign fpu_error = 1'b0; // Must only be true if fpu_valid |
assign fpu_busy = 1'b0; |
assign fpu_valid = 1'b0; |
assign fpu_result= 32'h00; |
assign fpu_flags = 4'h0; |
end else begin |
assign fpu_error = 1'b1; |
assign fpu_error = 1'b0; |
assign fpu_busy = 1'b0; |
assign fpu_valid = 1'b0; |
assign fpu_result= 32'h00; |
1173,11 → 1195,15
reg r_alu_illegal; |
initial r_alu_illegal = 0; |
always @(posedge i_clk) |
if (clear_pipeline) |
if ((i_rst)||(clear_pipeline)) |
r_alu_illegal <= 1'b0; |
else if ((alu_ce)||(mem_ce)) |
else if (alu_ce) |
r_alu_illegal <= op_illegal; |
else |
r_alu_illegal <= 1'b0; |
assign alu_illegal = (alu_illegal_op)||(r_alu_illegal); |
`else |
assign alu_illegal = 1'b0; |
`endif |
|
initial r_alu_pc_valid = 1'b0; |
1299,6 → 1325,8
assign wr_reg_id = (alu_wr|div_valid|fpu_valid)?alu_reg:mem_wreg; |
// Are we writing to the CC register? |
assign wr_write_cc = (wr_reg_id[3:0] == `CPU_CC_REG); |
assign wr_write_scc = (wr_reg_id[4:0] == {1'b0, `CPU_CC_REG}); |
assign wr_write_ucc = (wr_reg_id[4:0] == {1'b1, `CPU_CC_REG}); |
// Are we writing to the PC? |
assign wr_write_pc = (wr_reg_id[3:0] == `CPU_PC_REG); |
// What value to write? |
1317,11 → 1345,11
// When shall we write to our flags register? alF_wr already |
// includes the set condition ... |
assign wr_flags_ce = ((alF_wr)||(div_valid)||(fpu_valid))&&(~clear_pipeline)&&(~alu_illegal); |
assign w_uflags = { uhalt_phase, ufpu_err_flag, |
assign w_uflags = { 1'b0, uhalt_phase, ufpu_err_flag, |
udiv_err_flag, ubus_err_flag, trap, ill_err_u, |
1'b0, step, 1'b1, sleep, |
ubreak, step, 1'b1, sleep, |
((wr_flags_ce)&&(alu_gie))?alu_flags:flags }; |
assign w_iflags = { ihalt_phase, ifpu_err_flag, |
assign w_iflags = { 1'b0, ihalt_phase, ifpu_err_flag, |
idiv_err_flag, ibus_err_flag, trap, ill_err_i, |
break_en, 1'b0, 1'b0, sleep, |
((wr_flags_ce)&&(~alu_gie))?alu_flags:iflags }; |
1330,7 → 1358,7
// What value to write? |
always @(posedge i_clk) |
// If explicitly writing the register itself |
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_cc)) |
if ((wr_reg_ce)&&(wr_write_ucc)) |
flags <= wr_gpreg_vl[3:0]; |
// Otherwise if we're setting the flags from an ALU operation |
else if ((wr_flags_ce)&&(alu_gie)) |
1338,7 → 1366,7
: alu_flags); |
|
always @(posedge i_clk) |
if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_cc)) |
if ((wr_reg_ce)&&(wr_write_scc)) |
iflags <= wr_gpreg_vl[3:0]; |
else if ((wr_flags_ce)&&(~alu_gie)) |
iflags <= (div_valid)?div_flags:((fpu_valid)?fpu_flags |
1354,8 → 1382,8
// if ((break_en) AND (break_instruction)) // user mode or not |
// HALT CPU |
// else if (break_instruction) // only in user mode |
// set an interrupt flag, go to supervisor mode |
// allow supervisor to step the CPU. |
// set an interrupt flag, set the user break bit, |
// go to supervisor mode, allow supervisor to step the CPU. |
// Upon a CPU halt, any break condition will be reset. The |
// external debugger will then need to deal with whatever |
// condition has taken place. |
1363,29 → 1391,26
always @(posedge i_clk) |
if ((i_rst)||(i_halt)) |
break_en <= 1'b0; |
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_cc)) |
else if ((wr_reg_ce)&&(wr_write_scc)) |
break_en <= wr_spreg_vl[`CPU_BREAK_BIT]; |
`ifdef OPT_ILLEGAL_INSTRUCTION |
assign o_break = ((break_en)||(~op_gie))&&(op_break) |
&&(~alu_valid)&&(~mem_valid)&&(~mem_busy) |
&&(~alu_busy) |
&&(~div_busy)&&(~fpu_busy) |
|
initial break_pending = 1'b0; |
always @(posedge i_clk) |
if ((i_rst)||(clear_pipeline)||(~opvalid)) |
break_pending <= 1'b0; |
else if (op_break) |
break_pending <= (~alu_busy)&&(~div_busy)&&(~fpu_busy)&&(~mem_busy); |
else |
break_pending <= 1'b0; |
|
|
assign o_break = ((break_en)||(~op_gie))&&(break_pending) |
&&(~clear_pipeline) |
||((~alu_gie)&&(bus_err)) |
||((~alu_gie)&&(div_valid)&&(div_error)) |
||((~alu_gie)&&(fpu_valid)&&(fpu_error)) |
||((~alu_gie)&&(alu_pc_valid)&&(alu_illegal)); |
`else |
assign o_break = (((break_en)||(~op_gie))&&(op_break) |
&&(~alu_valid)&&(~mem_valid)&&(~mem_busy) |
&&(~alu_busy)&&(~div_busy)&&(~fpu_busy) |
&&(~clear_pipeline)) |
||((~alu_gie)&&(bus_err)) |
||((~alu_gie)&&(div_valid)&&(div_error)) |
||((~alu_gie)&&(fpu_valid)&&(fpu_error)); |
`endif |
||((~alu_gie)&&(div_error)) |
||((~alu_gie)&&(fpu_error)) |
||((~alu_gie)&&(alu_illegal)); |
|
|
// The sleep register. Setting the sleep register causes the CPU to |
// sleep until the next interrupt. Setting the sleep register within |
// interrupt mode causes the processor to halt until a reset. This is |
1416,7 → 1441,7
always @(posedge i_clk) |
if ((i_rst)||(w_switch_to_interrupt)) |
step <= 1'b0; |
else if ((wr_reg_ce)&&(~alu_gie)&&(wr_reg_id[4])&&(wr_write_cc)) |
else if ((wr_reg_ce)&&(~alu_gie)&&(wr_write_ucc)) |
step <= wr_spreg_vl[`CPU_STEP_BIT]; |
else if (((alu_pc_valid)||(mem_pc_valid))&&(step)&&(gie)) |
step <= 1'b0; |
1429,18 → 1454,19
||(((alu_pc_valid)||(mem_pc_valid))&&(step)&&(~alu_phase)&&(~bus_lock)) |
// If we encounter a break instruction, if the break |
// enable isn't set. |
||((master_ce)&&(~mem_rdbusy)&&(~div_busy)&&(~fpu_busy) |
&&(op_break)&&(~break_en)) |
||((master_ce)&&(break_pending)&&(~break_en)) |
`ifdef OPT_ILLEGAL_INSTRUCTION |
// On an illegal instruction |
||((alu_pc_valid)&&(alu_illegal)) |
||(alu_illegal) |
`endif |
// On division by zero. If the divide isn't |
// implemented, div_valid and div_error will be short |
// circuited and that logic will be bypassed |
||((div_valid)&&(div_error)) |
// Same thing on a floating point error. |
||((fpu_valid)&&(fpu_error)) |
||(div_error) |
// Same thing on a floating point error. Note that |
// fpu_error must *never* be set unless fpu_valid is |
// also set as well, else this will fail. |
||(fpu_error) |
// |
||(bus_err) |
// If we write to the CC register |
1448,9 → 1474,9
&&(wr_reg_id[4])&&(wr_write_cc)) |
); |
assign w_release_from_interrupt = (~gie)&&(~i_interrupt) |
// Then if we write the CC register |
// Then if we write the sCC register |
&&(((wr_reg_ce)&&(wr_spreg_vl[`CPU_GIE_BIT]) |
&&(~wr_reg_id[4])&&(wr_write_cc)) |
&&(wr_write_scc)) |
); |
always @(posedge i_clk) |
if (i_rst) |
1462,16 → 1488,24
|
initial trap = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
if ((i_rst)||(w_release_from_interrupt)) |
trap <= 1'b0; |
else if (w_release_from_interrupt) |
trap <= 1'b0; |
else if ((alu_gie)&&(wr_reg_ce)&&(~wr_spreg_vl[`CPU_GIE_BIT]) |
&&(wr_write_cc)) // &&(wr_reg_id[4]) implied |
&&(wr_write_ucc)) // &&(wr_reg_id[4]) implied |
trap <= 1'b1; |
else if ((wr_reg_ce)&&(wr_write_cc)&&(wr_reg_id[4])) |
trap <= wr_spreg_vl[`CPU_TRAP_BIT]; |
else if ((wr_reg_ce)&&(wr_write_ucc)&&(~alu_gie)) |
trap <= (trap)&&(wr_spreg_vl[`CPU_TRAP_BIT]); |
|
initial ubreak = 1'b0; |
always @(posedge i_clk) |
if ((i_rst)||(w_release_from_interrupt)) |
ubreak <= 1'b0; |
else if ((op_gie)&&(break_pending)&&(w_switch_to_interrupt)) |
ubreak <= 1'b1; |
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)&&(wr_write_ucc)) |
ubreak <= (ubreak)&&(wr_spreg_vl[`CPU_BREAK_BIT]); |
|
|
`ifdef OPT_ILLEGAL_INSTRUCTION |
initial ill_err_i = 1'b0; |
always @(posedge i_clk) |
1478,25 → 1512,21
if (i_rst) |
ill_err_i <= 1'b0; |
// Only the debug interface can clear this bit |
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG}) |
&&(~wr_spreg_vl[`CPU_ILL_BIT])) |
ill_err_i <= 1'b0; |
else if ((alu_pc_valid)&&(alu_illegal)&&(~alu_gie)) |
else if ((dbgv)&&(wr_write_scc)) |
ill_err_i <= (ill_err_i)&&(wr_spreg_vl[`CPU_ILL_BIT]); |
else if ((alu_illegal)&&(~alu_gie)) |
ill_err_i <= 1'b1; |
initial ill_err_u = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
ill_err_u <= 1'b0; |
// The bit is automatically cleared on release from interrupt |
else if (w_release_from_interrupt) |
// or reset |
if ((i_rst)||(w_release_from_interrupt)) |
ill_err_u <= 1'b0; |
// If the supervisor writes to this register, clearing the |
// bit, then clear it |
else if (((~alu_gie)||(dbgv)) |
&&(wr_reg_ce)&&(~wr_spreg_vl[`CPU_ILL_BIT]) |
&&(wr_reg_id[4])&&(wr_write_cc)) |
ill_err_u <= 1'b0; |
else if ((alu_pc_valid)&&(alu_illegal)&&(alu_gie)) |
// If the supervisor (or debugger) writes to this register, |
// clearing the bit, then clear it |
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)&&(wr_write_ucc)) |
ill_err_u <=((ill_err_u)&&(wr_spreg_vl[`CPU_ILL_BIT])); |
else if ((alu_illegal)&&(alu_gie)) |
ill_err_u <= 1'b1; |
`else |
assign ill_err_u = 1'b0; |
1508,9 → 1538,8
always @(posedge i_clk) |
if (i_rst) |
ibus_err_flag <= 1'b0; |
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG}) |
&&(~wr_spreg_vl[`CPU_BUSERR_BIT])) |
ibus_err_flag <= 1'b0; |
else if ((dbgv)&&(wr_write_scc)) |
ibus_err_flag <= (ibus_err_flag)&&(wr_spreg_vl[`CPU_BUSERR_BIT]); |
else if ((bus_err)&&(~alu_gie)) |
ibus_err_flag <= 1'b1; |
// User bus error flag -- if ever set, it will cause an interrupt to |
1517,14 → 1546,10
// supervisor mode. |
initial ubus_err_flag = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
if ((i_rst)||(w_release_from_interrupt)) |
ubus_err_flag <= 1'b0; |
else if (w_release_from_interrupt) |
ubus_err_flag <= 1'b0; |
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce) |
&&(~wr_spreg_vl[`CPU_BUSERR_BIT]) |
&&(wr_reg_id[4])&&(wr_write_cc)) |
ubus_err_flag <= 1'b0; |
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)&&(wr_write_ucc)) |
ubus_err_flag <= (ubus_err_flag)&&(wr_spreg_vl[`CPU_BUSERR_BIT]); |
else if ((bus_err)&&(alu_gie)) |
ubus_err_flag <= 1'b1; |
|
1540,24 → 1565,20
always @(posedge i_clk) |
if (i_rst) |
r_idiv_err_flag <= 1'b0; |
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG}) |
&&(~wr_spreg_vl[`CPU_DIVERR_BIT])) |
r_idiv_err_flag <= 1'b0; |
else if ((div_error)&&(div_valid)&&(~alu_gie)) |
else if ((dbgv)&&(wr_write_scc)) |
r_idiv_err_flag <= (r_idiv_err_flag)&&(wr_spreg_vl[`CPU_DIVERR_BIT]); |
else if ((div_error)&&(~alu_gie)) |
r_idiv_err_flag <= 1'b1; |
// User divide (by zero) error flag -- if ever set, it will |
// cause a sudden switch interrupt to supervisor mode. |
initial r_udiv_err_flag = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
if ((i_rst)||(w_release_from_interrupt)) |
r_udiv_err_flag <= 1'b0; |
else if (w_release_from_interrupt) |
r_udiv_err_flag <= 1'b0; |
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce) |
&&(~wr_spreg_vl[`CPU_DIVERR_BIT]) |
&&(wr_reg_id[4])&&(wr_write_cc)) |
r_udiv_err_flag <= 1'b0; |
else if ((div_error)&&(alu_gie)&&(div_valid)) |
&&(wr_write_ucc)) |
r_udiv_err_flag <= (r_udiv_err_flag)&&(wr_spreg_vl[`CPU_DIVERR_BIT]); |
else if ((div_error)&&(alu_gie)) |
r_udiv_err_flag <= 1'b1; |
|
assign idiv_err_flag = r_idiv_err_flag; |
1577,9 → 1598,8
always @(posedge i_clk) |
if (i_rst) |
r_ifpu_err_flag <= 1'b0; |
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG}) |
&&(~wr_spreg_vl[`CPU_FPUERR_BIT])) |
r_ifpu_err_flag <= 1'b0; |
else if ((dbgv)&&(wr_write_scc)) |
r_ifpu_err_flag <= (r_ifpu_err_flag)&&(wr_spreg_vl[`CPU_FPUERR_BIT]); |
else if ((fpu_error)&&(fpu_valid)&&(~alu_gie)) |
r_ifpu_err_flag <= 1'b1; |
// User floating point error flag -- if ever set, it will cause |
1586,14 → 1606,11
// a sudden switch interrupt to supervisor mode. |
initial r_ufpu_err_flag = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
if ((i_rst)&&(w_release_from_interrupt)) |
r_ufpu_err_flag <= 1'b0; |
else if (w_release_from_interrupt) |
r_ufpu_err_flag <= 1'b0; |
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce) |
&&(~wr_spreg_vl[`CPU_FPUERR_BIT]) |
&&(wr_reg_id[4])&&(wr_write_cc)) |
r_ufpu_err_flag <= 1'b0; |
&&(wr_write_ucc)) |
r_ufpu_err_flag <= (r_ufpu_err_flag)&&(wr_spreg_vl[`CPU_FPUERR_BIT]); |
else if ((fpu_error)&&(alu_gie)&&(fpu_valid)) |
r_ufpu_err_flag <= 1'b1; |
|
1610,13 → 1627,17
initial r_ihalt_phase = 0; |
initial r_uhalt_phase = 0; |
always @(posedge i_clk) |
if (~alu_gie) |
if (i_rst) |
r_ihalt_phase <= 1'b0; |
else if ((~alu_gie)&&(alu_pc_valid)&&(~clear_pipeline)) |
r_ihalt_phase <= alu_phase; |
always @(posedge i_clk) |
if (alu_gie) |
if ((i_rst)||(w_release_from_interrupt)) |
r_uhalt_phase <= 1'b0; |
else if ((alu_gie)&&(alu_pc_valid)) |
r_uhalt_phase <= alu_phase; |
else if (w_release_from_interrupt) |
r_uhalt_phase <= 1'b0; |
else if ((~alu_gie)&&(wr_reg_ce)&&(wr_write_ucc)) |
r_uhalt_phase <= wr_spreg_vl[`CPU_PHASE_BIT]; |
|
assign ihalt_phase = r_ihalt_phase; |
assign uhalt_phase = r_uhalt_phase; |
1656,9 → 1677,9
always @(posedge i_clk) |
if (i_rst) |
pf_pc <= RESET_ADDRESS; |
else if (w_switch_to_interrupt) |
else if ((w_switch_to_interrupt)||((~gie)&&(w_clear_icache))) |
pf_pc <= ipc; |
else if (w_release_from_interrupt) |
else if ((w_release_from_interrupt)||((gie)&&(w_clear_icache))) |
pf_pc <= upc; |
else if ((wr_reg_ce)&&(wr_reg_id[4] == gie)&&(wr_write_pc)) |
pf_pc <= wr_spreg_vl[(AW-1):0]; |
1687,6 → 1708,21
else |
new_pc <= 1'b0; |
|
`ifdef OPT_PIPELINED |
reg r_clear_icache; |
initial r_clear_icache = 1'b1; |
always @(posedge i_clk) |
if ((i_rst)||(i_clear_pf_cache)) |
r_clear_icache <= 1'b1; |
else if ((wr_reg_ce)&&(wr_write_scc)) |
r_clear_icache <= wr_spreg_vl[`CPU_CLRCACHE_BIT]; |
else |
r_clear_icache <= 1'b0; |
assign w_clear_icache = r_clear_icache; |
`else |
assign w_clear_icache = 1'b0; |
`endif |
|
// |
// The debug interface |
generate |
1699,7 → 1735,8
o_dbg_reg <= {{(32-AW){1'b0}},(i_dbg_reg[4])?upc:ipc}; |
else if (i_dbg_reg[3:0] == `CPU_CC_REG) |
begin |
o_dbg_reg[13:0] <= (i_dbg_reg[4])?w_uflags:w_iflags; |
o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags; |
o_dbg_reg[31:23] <= w_cpu_info; |
o_dbg_reg[`CPU_GIE_BIT] <= gie; |
end |
end |
1711,7 → 1748,8
o_dbg_reg <= (i_dbg_reg[4])?upc:ipc; |
else if (i_dbg_reg[3:0] == `CPU_CC_REG) |
begin |
o_dbg_reg[13:0] <= (i_dbg_reg[4])?w_uflags:w_iflags; |
o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags; |
o_dbg_reg[31:23] <= w_cpu_info; |
o_dbg_reg[`CPU_GIE_BIT] <= gie; |
end |
end |
1722,11 → 1760,15
|
always @(posedge i_clk) |
r_halted <= (i_halt)&&( |
(pf_cyc)||(mem_cyc_gbl)||(mem_cyc_lcl)||(mem_busy) |
||(alu_busy)||(div_busy)||(fpu_busy) |
||((~opvalid)&&(~i_rst)&&(~dcd_illegal)) |
||((~dcdvalid)&&(~i_rst)&&(~pf_illegal))); |
assign o_dbg_stall = r_halted; |
// To be halted, any long lasting instruction must |
// be completed. |
(~pf_cyc)&&(~mem_busy)&&(~alu_busy) |
&&(~div_busy)&&(~fpu_busy) |
// Operations must either be valid, or illegal |
&&((opvalid)||(i_rst)||(dcd_illegal)) |
// Decode stage must be either valid, in reset, or ill |
&&((dcdvalid)||(i_rst)||(pf_illegal))); |
assign o_dbg_stall = ~r_halted; |
|
// |
// |
1739,7 → 1781,17
assign o_i_count = (alu_pc_valid)&&(~clear_pipeline); |
|
`ifdef DEBUG_SCOPE |
reg [31:0] r_stack; |
always @(posedge i_clk) |
if ((wr_reg_ce)&&(wr_reg_id == 5'h0d)) |
r_stack <= wr_gpreg_vl; |
reg r_stack_pre, r_stack_post; |
always @(posedge i_clk) |
r_stack_pre <= (r_stack == 32'h03fff); |
always @(posedge i_clk) |
r_stack_post <= (r_stack == 32'h03eeb); |
|
always @(posedge i_clk) |
o_debug <= { |
/* |
o_break, i_wb_err, pf_pc[1:0], |
1766,7 → 1818,7
pf_pc[7:0], pf_addr[7:0] |
*/ |
|
i_wb_err, gie, alu_illegal, |
(i_wb_err)||(r_stack_post), (gie)||(r_stack_pre), (alu_illegal)||(r_stack_post), |
(new_pc)||((dcd_early_branch)&&(~clear_pipeline)), |
mem_busy, |
(mem_busy)?{ (o_wb_gbl_stb|o_wb_lcl_stb), o_wb_we, |
1786,5 → 1838,28
*/ |
}; |
`endif |
|
/* |
always @(posedge i_clk) |
o_debug <= { |
// External control interaction (4b) |
i_halt, i_rst, i_clear_cache, o_break, |
// Bus interaction (8b) |
pf_cyc,(o_wb_gbl_cyc|o_wb_lcl_cyc), o_wb_gbl_stb, o_wb_lcl_stb, |
o_wb_we, i_wb_ack, i_wb_stall, i_wb_err, |
// PC control (4b) |
gie, new_pc, dcd_early_branch, 1'b0, |
// Our list of pipeline stage values (8b) |
pf_valid, pf_illegal, dcdvalid, opvalid, alu_valid, mem_valid, |
alu_pc_valid, mem_pc_valid, |
// Our list of circuit enables ... (8b) |
(new_pc)||((dcd_early_branch)&&(~clear_pipeline)), |
dcd_ce, op_ce, alu_ce, mem_ce, wr_reg_ce, wr_flags_ce, |
1'b0, |
// Useful PC values (64b) |
((dcd_early_branch)&&(~clear_pipeline)) |
? dcd_branch_pc[15:0]:pf_pc[15:0], |
(gie)?upc[15:0]:ipc[15:0], instruction_pc[15:0], instruction[31:16] }; |
*/ |
|
endmodule |
/trunk/rtl/wbgpio.v
62,7 → 62,7
|
// 9LUT's, 16 FF's |
always @(posedge i_clk) |
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we)) |
if ((i_wb_stb)&&(i_wb_we)) |
o_gpio <= ((o_gpio)&(~i_wb_data[(NOUT+16-1):16])) |
|((i_wb_data[(NOUT-1):0])&(i_wb_data[(NOUT+16-1):16])); |
|
/trunk/rtl/toplevel.v
88,7 → 88,7
.CLKFX_DIVIDE(3), |
.CLKFX_MULTIPLY(20), |
.CLKIN_DIVIDE_BY_2("FALSE"), |
.CLKIN_PERIOD(82), |
.CLKIN_PERIOD(82.0), // 12MHz clock period in ns |
.CLKOUT_PHASE_SHIFT("NONE"), |
.CLK_FEEDBACK("1X"), |
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), |
/trunk/rtl/wbufifo.v
45,6 → 45,9
reg [(BW-1):0] fifo[0:(FLEN-1)]; |
reg [(LGFLEN-1):0] r_first, r_last; |
|
wire [(LGFLEN-1):0] nxt_first; |
assign nxt_first = r_first+{{(LGFLEN-1){1'b0}},1'b1}; |
|
reg will_overflow; |
initial will_overflow = 1'b0; |
always @(posedge i_clk) |
54,7 → 57,7
will_overflow <= (will_overflow)&&(i_wr); |
else if (i_wr) |
will_overflow <= (r_first+2 == r_last); |
else if (r_first+1 == r_last) |
else if (nxt_first == r_last) |
will_overflow <= 1'b1; |
|
// Write |
65,7 → 68,7
else if (i_wr) |
begin // Cowardly refuse to overflow |
if ((i_rd)||(~will_overflow)) // (r_first+1 != r_last) |
r_first <= r_first+{{(LGFLEN-1){1'b0}},1'b1}; |
r_first <= nxt_first; |
// else o_ovfl <= 1'b1; |
end |
always @(posedge i_clk) |
114,8 → 117,6
o_data <= fifo[(i_rd)?(r_last+{{(LGFLEN-1){1'b0}},1'b1}) |
:(r_last)]; |
|
wire [(LGFLEN-1):0] nxt_first; |
assign nxt_first = r_first+{{(LGFLEN-1){1'b0}},1'b1}; |
assign o_err = ((i_wr)&&(will_overflow)&&(~i_rd)) |
||((i_rd)&&(will_underflow)&&(~i_wr)); |
|
/trunk/rtl/Makefile
52,7 → 52,7
wbucompress.v wbudecompress.v wbudeword.v wbuexec.v \ |
wbuidleint.v wbuinput.v wbuoutput.v wbureadcw.v wbusixchar.v \ |
wbutohex.v |
PERIPHERALS: wbgpio.v wbpwmaudio.v rxuart.v txuart.v uartdev.v \ |
PERIPHERALS:= wbgpio.v wbpwmaudio.v rxuart.v txuart.v uartdev.v \ |
rtcdate.v rtclight.v |
SOURCES := busmaster.v wbscope.v wbsdram.v \ |
ioslave.v rtclight.v rtcdate.v \ |
/trunk/rtl/uartdev.v
61,12 → 61,12
reg [7:0] r_tx_data; |
initial r_setup = DEFAULT_SETUP; |
always @(posedge i_clk) |
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we)&&(~i_wb_addr[1])) |
if ((i_wb_stb)&&(i_wb_we)&&(~i_wb_addr[1])) |
r_setup <= i_wb_data[29:0]; |
|
initial r_tx_stb = 1'b0; |
always @(posedge i_clk) |
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we)&&(i_wb_addr == 2'b11)) |
if ((i_wb_stb)&&(i_wb_we)&&(i_wb_addr == 2'b11)) |
begin |
// Note: there's no check for overflow here. |
// You're on your own: verify that the device |
102,13 → 102,13
2'b00: o_wb_data <= { 2'b00, r_setup }; |
2'b01: o_wb_data <= { 2'b00, r_setup }; |
2'b10: begin |
if ((i_wb_cyc)&&(i_wb_stb)&&(~i_wb_we)) |
if ((i_wb_stb)&&(~i_wb_we)) |
rx_rdy <= rx_stb; |
o_wb_data <= { 20'h00, rx_break, rx_frame_err, rx_parity_err, ~rx_rdy, r_data }; |
end |
2'b11: o_wb_data <= { 31'h00,tx_busy }; |
endcase |
o_wb_ack <= (i_wb_cyc)&&(i_wb_stb); // Read or write, we ack |
o_wb_ack <= (i_wb_stb); // Read or write, we ack |
end |
|
assign o_wb_stall = 1'b0; |
/trunk/rtl/wbpwmaudio.v
107,7 → 107,7
reg [(TIMING_BITS-1):0] r_reload_value; |
initial r_reload_value = DEFAULT_RELOAD; |
always @(posedge i_clk) // Data write |
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_addr)&&(i_wb_we)) |
if ((i_wb_stb)&&(i_wb_addr)&&(i_wb_we)) |
r_reload_value <= i_wb_data[(TIMING_BITS-1):0]; |
assign w_reload_value = r_reload_value; |
end else begin |
137,7 → 137,7
initial next_valid = 1'b1; |
initial next_sample = 16'h8000; |
always @(posedge i_clk) // Data write |
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we) |
if ((i_wb_stb)&&(i_wb_we) |
&&((~i_wb_addr)||(VARIABLE_RATE==0))) |
begin |
// Write with two's complement data, convert it |
174,7 → 174,7
reg [31:0] r_wb_data; |
always @(posedge i_clk) |
if (i_wb_addr) |
r_wb_data <= w_reload_value; |
r_wb_data <= { {(32-TIMING_BITS){1'b0}}, w_reload_value }; |
else |
r_wb_data <= { 15'h00, o_int, sample_out }; |
assign o_wb_data = r_wb_data; |
182,7 → 182,7
|
initial o_wb_ack = 1'b0; |
always @(posedge i_clk) |
o_wb_ack <= (i_wb_cyc)&&(i_wb_stb); |
o_wb_ack <= (i_wb_stb); |
assign o_wb_stall = 1'b0; |
|
endmodule |
/trunk/rtl/txuart.v
167,6 → 167,7
// baud_counter <= 0; |
r_setup <= i_setup; |
calc_parity <= 1'b0; |
lcl_data <= i_data; |
if ((i_wr)&&(~r_busy)) |
begin // Immediately start us off with a start bit |
o_uart <= 1'b0; |
177,12 → 178,10
2'b10: state <= `TXU_BIT_TWO; |
2'b11: state <= `TXU_BIT_THREE; |
endcase |
lcl_data <= i_data; |
// baud_counter <= clocks_per_baud-28'h01; |
end else begin // Stay in idle |
o_uart <= 1'b1; |
r_busy <= 0; |
// lcl_data is irrelevant |
// state <= state; |
end |
end else begin |
227,7 → 226,8
assign o_busy = (r_busy); |
|
|
initial zero_baud_counter = 1'b0; |
initial zero_baud_counter = 1'b1; |
initial baud_counter = 28'd80000; // 1ms |
always @(posedge i_clk) |
begin |
zero_baud_counter <= (baud_counter == 28'h01); |
/trunk/rtl/wbscope.v
111,7 → 111,7
wire [19:0] bw_holdoff; |
initial br_config = ((1<<(LGMEM-1))-4); |
always @(posedge i_wb_clk) |
if ((i_wb_cyc)&&(i_wb_stb)&&(~i_wb_addr)) |
if ((i_wb_stb)&&(~i_wb_addr)) |
begin |
if (i_wb_we) |
br_config <= { i_wb_data[31], |
195,18 → 195,20
initial counter = 20'h0000; |
always @(posedge i_clk) |
if (dw_reset) |
begin |
counter <= 0; |
dr_stopped <= 1'b0; |
end else if ((i_ce)&&(dr_triggered)) |
else if ((i_ce)&&(dr_triggered)&&(~dr_stopped)) |
begin // MUST BE a < and not <=, so that we can keep this w/in |
// 20 bits. Else we'd need to add a bit to comparison |
// here. |
if (counter < bw_holdoff) |
counter <= counter + 20'h01; |
else |
dr_stopped <= 1'b1; |
counter <= counter + 20'h01; |
end |
always @(posedge i_clk) |
if ((~dr_triggered)||(dw_reset)) |
dr_stopped <= 1'b0; |
else if (i_ce) |
dr_stopped <= (counter+20'd1 >= bw_holdoff); |
else |
dr_stopped <= (counter >= bw_holdoff); |
|
// |
// Actually do our writes to memory. Record, via 'primed' when |
226,7 → 228,7
begin |
waddr <= 0; // upon reset. |
dr_primed <= 1'b0; |
end else if ((i_ce)&&((~dr_triggered)||(counter < bw_holdoff))) |
end else if ((i_ce)&&((~dr_triggered)||(~dr_stopped))) |
begin |
// mem[waddr] <= i_data; |
waddr <= waddr + {{(LGMEM-1){1'b0}},1'b1}; |
233,7 → 235,7
dr_primed <= (dr_primed)||(&waddr); |
end |
always @(posedge i_clk) |
if ((i_ce)&&((~dr_triggered)||(counter < bw_holdoff))) |
if ((i_ce)&&((~dr_triggered)||(~dr_stopped))) |
mem[waddr] <= i_data; |
|
// |
274,7 → 276,7
reg br_wb_ack; |
initial br_wb_ack = 1'b0; |
wire bw_cyc_stb; |
assign bw_cyc_stb = ((i_wb_cyc)&&(i_wb_stb)); |
assign bw_cyc_stb = (i_wb_stb); |
always @(posedge i_wb_clk) |
begin |
if ((bw_reset_request) |
/trunk/rtl/ioslave.v
103,7 → 103,7
// default: begin end |
// endcase |
// end else |
if ((i_wb_cyc)&&(i_wb_stb)&&(~i_wb_we)) |
if ((i_wb_stb)&&(~i_wb_we)) |
begin |
casez(i_wb_addr[3:0]) |
4'h01: r_wb_data <= `DATESTAMP; |
131,7 → 131,7
i_uart_tx_int, i_uart_rx_int, i_pwm_int, gpio_int, |
i_scop_int, i_flash_int, ck_int, brd_interrupts[0] }; |
icontrol #(9) intcontroller(i_clk, 1'b0, |
((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we) |
((i_wb_stb)&&(i_wb_we) |
&&(i_wb_addr==5'h2)), i_wb_data, |
ictrl_data, interrupt_vector, |
o_interrupt); |
/trunk/rtl/busmaster.v
104,9 → 104,15
// |
// Position #4: The Zip CPU scope |
// |
`ifdef INCLUDE_ZIPCPU |
`ifdef VERILATOR |
`define ZIP_SCOPE |
`else // VERILATOR |
`ifdef XULA25 |
// `define ZIP_SCOPE |
`endif |
`define ZIP_SCOPE |
`endif // XULA25 |
`endif // VERILATOR |
`endif // INCLUDE_ZIPCPU |
|
module busmaster(i_clk, i_rst, |
i_rx_stb, i_rx_data, o_tx_stb, o_tx_data, i_tx_busy, |
208,9 → 214,11
wire [31:0] dwb_addr, dwb_odata; |
wire [8:0] w_ints_to_zip_cpu; |
`ifdef INCLUDE_ZIPCPU |
`ifdef ZIP_SCOPE |
wire [31:0] zip_debug; |
`endif |
`ifdef XULA25 |
wire [31:0] zip_debug; |
zipsystem #(24'h2000,ZA,9,1,9) |
zipsystem #(24'h2000,ZA,10,1,9) |
zippy(i_clk, 1'b0, |
// Zippys wishbone interface |
zip_cyc, zip_stb, zip_we, w_zip_addr, zip_data, |
220,8 → 228,11
((wbu_cyc)&&(wbu_zip_sel)), |
((wbu_stb)&&(wbu_zip_sel)),wbu_we, wbu_addr[0], |
wbu_data, |
zip_dbg_ack, zip_dbg_stall, zip_dbg_data, |
zip_debug); |
zip_dbg_ack, zip_dbg_stall, zip_dbg_data |
`ifdef ZIP_SCOPE |
, zip_debug |
`endif |
); |
`else |
zipbones #(24'h2000,ZA,8,1) |
zippy(i_clk, 1'b0, |
233,8 → 244,12
((wbu_cyc)&&(wbu_zip_sel)), |
((wbu_stb)&&(wbu_zip_sel)),wbu_we, wbu_addr[0], |
wbu_data, |
zip_dbg_ack, zip_dbg_stall, zip_dbg_data); |
zip_dbg_ack, zip_dbg_stall, zip_dbg_data |
`ifdef ZIP_SCOPE |
, zip_debug |
`endif |
); |
`endif |
generate |
if (ZA < 32) |
assign zip_addr = { {(32-ZA){1'b0}}, w_zip_addr }; |
368,7 → 383,8
: ((sdram_ack|sdcard_ack) |
?((sdram_ack)? sdram_data : sdcard_data) |
: ((mem_ack)?mem_data:flash_data)))); // if (flash_ack) |
assign wb_err = ((wb_cyc)&&(wb_stb)&&(none_sel || many_sel)) || many_ack; |
assign wb_err = ((wb_stb)&&(none_sel || many_sel)) |
|| ((wb_cyc)&&(many_ack)); |
|
// Addresses ... |
// 0000 xxxx configuration/control registers |
376,6 → 392,7
// 1xxx xxxx Up-sampler taps |
// 1 xxxx xxxx xxxx xxxx xxxx Up-sampler taps |
|
`define SPEEDY_IO |
`ifndef SPEEDY_IO |
|
wire pre_io, pre_pwm, pre_uart, pre_flctl, pre_scop; |
401,38 → 418,29
`endif |
assign sdram_sel=((wb_cyc)&&(wb_addr[31:23]== 9'h01)); |
`else |
// While the following would make the bus infinitely easier to decode, |
// it would also scramble where everything on the bus is located at, |
// while also making it difficult to access these values via offsets |
// of a register. Further, while simpler, everything would alias all |
// over the place as well--that is, devices would show up at multiple |
// locations on the bus. It's all a tradeoff. |
assign iovec = { wb_addr[23],wb_addr[18],wb_addr[15:13] } |
wire [3:0] iovec; |
assign iovec = { wb_addr[23],wb_addr[18],wb_addr[13],wb_addr[8] }; |
|
assign sdram_sel =((wb_cyc)&&(io_vec[4])); |
assign flash_sel =((wb_cyc)&&(io_vec[4:3]==2'b01)); |
assign mem_sel =((wb_cyc)&&(io_vec[4:0]==5'h07)); |
assign cfg_sel =((wb_cyc)&&(io_vec[4:0]==5'h06)); |
`ifdef SDCARD_ACCESS |
assign sdcard_sel=((wb_cyc)&&(io_vec[4:0]==5'h05)); |
`else |
assign sdcard_sel=1'b0; |
`endif |
assign scop_sel =((wb_cyc)&&(io_vec[4:0]==5'h04)); |
assign rtc_sel =((wb_cyc)&&(io_vec[4:0]==5'h03)); |
assign rtc_sel =((wb_cyc)&&(io_vec[4:0]==5'h03)); |
assign puf_sel =((wb_cyc)&&(io_vec[4:0]==5'h02)); |
assign io_sel =((wb_cyc)&&(io_vec[4:0]==5'h01)); |
assign wb_err =((wb_cyc)&&(io_vec[4:0]==5'h00)); |
assign flctl_sel = (puf_sel)&&(wb_addr[3]); |
assign pwm_sel = (puf_sel)&&(wb_addr[3:2]==2'b00); |
assign sdram_sel = (iovec[3]); |
assign flash_sel = (iovec[3:2]==2'b01); |
assign mem_sel = (iovec[3:1]==3'b001); |
assign io_bank = (iovec[3:0]==4'b0001)&&(wb_addr[7:5]==3'b000); |
assign cfg_sel = (iovec[3:0]==4'b0001)&&(wb_addr[6]); |
assign sdcard_sel= (iovec[3:0]==4'b0001)&&(wb_addr[6:5]==2'b01); |
assign scop_sel = (io_bank)&&(wb_addr[7:3]==5'b00011); |
assign io_sel = (io_bank)&&(wb_addr[7:5]==3'b000) |
&&(wb_addr[4:0] != 5'b00111) // Not UART Ctrl |
&&(wb_addr[3] != 1'b1);//Not PWM/UART/Flash/Scp |
assign flctl_sel = (io_bank)&&(wb_addr[4:2]==3'b011); |
assign pwm_sel = (io_bank)&&(wb_addr[4:1]==4'b0100); |
// Note that in the following definition, the UART is given four words |
// despite the fact that it can probably only use 3. |
assign uart_sel = (puf_sel)&&(wb_addr[3:2]==2'b01); |
assign uart_sel = (io_bank)&&((wb_addr[4:1]==4'b0101) |
||(wb_addr[4:0]==5'b00111)); |
|
`endif |
|
assign none_sel =((wb_cyc)&&(wb_stb)&&(~ |
assign none_sel =((wb_stb)&&(~ |
(io_sel |
||uart_sel |
||pwm_sel |
443,7 → 451,7
||sdram_sel |
||sdcard_sel |
||flash_sel))); |
assign many_sel =((wb_cyc)&&(wb_stb)&&( |
assign many_sel =((wb_stb)&&( |
{3'h0, io_sel} |
+{3'h0, uart_sel} |
+{3'h0, pwm_sel} |
519,12 → 527,12
// audio rate can be adjusted (1), or whether it is fixed within the |
// build (0). |
`ifdef XULA25 |
`define FMHACK |
// `define FMHACK |
|
`ifdef FMHACK |
wbfmtxhack #(16'd1813) // 44.1 kHz, user adjustable |
`else |
wbpwmaudio #(16'd1813,1) // 44.1 kHz, user adjustable |
wbpwmaudio #(16'd1813,1,16) // 44.1 kHz, user adjustable |
`endif |
|
`else |
558,7 → 566,7
reg r_flash_ack; |
initial r_flash_ack = 1'b0; |
always @(posedge i_clk) |
r_flash_ack <= (wb_cyc)&&(wb_stb)&&((flash_sel)||(flctl_sel)); |
r_flash_ack <= (wb_stb)&&((flash_sel)||(flctl_sel)); |
|
assign flash_ack = r_flash_ack; |
assign flash_stall = 1'b0; |
588,7 → 596,7
reg r_sdcard_ack; |
initial r_sdcard_ack = 1'b0; |
always @(posedge i_clk) |
r_sdcard_ack <= (wb_cyc)&&(wb_stb)&&(sdcard_sel); |
r_sdcard_ack <= (wb_stb)&&(sdcard_sel); |
assign sdcard_stall = 1'b0; |
assign sdcard_ack = r_sdcard_ack; |
assign sdcard_data = 32'h0000; |
654,7 → 662,7
reg r_cfg_ack; |
initial r_cfg_ack = 1'b0; |
always @(posedge i_clk) |
r_cfg_ack <= ((wb_cyc)&&(cfg_sel)&&(wb_stb)&&(~cfg_stall)); |
r_cfg_ack <= ((cfg_sel)&&(wb_stb)&&(~cfg_stall)); |
assign cfg_ack = r_cfg_ack; |
assign cfg_stall = 1'b0; |
assign cfg_data = 32'h0000; |
670,7 → 678,7
`else |
reg r_mem_ack; |
always @(posedge i_clk) |
r_mem_ack = (wb_cyc)&&(wb_stb)&&(mem_sel); |
r_mem_ack = (wb_stb)&&(mem_sel); |
assign mem_data = 32'h000; |
assign mem_stall = 1'b0; |
assign mem_ack = r_mem_ack; |
694,7 → 702,7
reg r_sdram_ack; |
initial r_sdram_ack = 1'b0; |
always @(posedge i_clk) |
r_sdram_ack <= (wb_cyc)&&(wb_stb)&&(sdram_sel); |
r_sdram_ack <= (wb_stb)&&(sdram_sel); |
assign sdram_ack = r_sdram_ack; |
assign sdram_stall = 1'b0; |
assign sdram_data = 32'h0000; |
756,7 → 764,7
wire scop_cfg_ack, scop_cfg_stall, scop_cfg_interrupt; |
`ifdef CFG_SCOPE |
wire scop_cfg_trigger; |
assign scop_cfg_trigger = (wb_cyc)&&(wb_stb)&&(cfg_sel); |
assign scop_cfg_trigger = (wb_stb)&&(cfg_sel); |
wbscope #(5'h7) wbcfgscope(i_clk, 1'b1, scop_cfg_trigger, cfg_scope, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b01)), |
766,7 → 774,7
`else |
`ifdef SDCARD_SCOPE |
wire scop_sd_trigger, scop_sd_ce; |
assign scop_sd_trigger = (wb_cyc)&&(wb_stb)&&(sdcard_sel)&&(wb_we); |
assign scop_sd_trigger = (wb_stb)&&(sdcard_sel)&&(wb_we); |
assign scop_sd_ce = 1'b1; // sdspi_scope[31]; |
wbscope #(5'h9) sdspiscope(i_clk, scop_sd_ce, |
scop_sd_trigger, sdspi_scope, |
819,8 → 827,13
wire [31:0] scop_zip_data; |
wire scop_zip_ack, scop_zip_stall, scop_zip_interrupt; |
`ifdef ZIP_SCOPE |
wire zip_trigger; |
assign zip_trigger=(wbu_zip_sel)&&(wbu_we)&&(wbu_stb)&&(~wbu_addr[0]); |
reg zip_trigger, pre_trigger_a, pre_trigger_b; |
always @(posedge i_clk) |
begin |
pre_trigger_a <= (wb_stb)&&(wb_addr[31:0]==32'h010b); |
pre_trigger_b <= (|wb_data[31:8]); |
zip_trigger= (pre_trigger_a)&&(pre_trigger_b)||(zip_debug[31]); |
end |
wbscope #(5'h9) zipscope(i_clk, 1'b1, zip_trigger, |
zip_debug, |
// Wishbone interface |
/trunk/rtl/wbucompress.v
205,7 → 205,7
reg dmatch, // Match, on clock 'd' |
vaddr; // Was the address valid then? |
reg [(DW-1):0] cword; |
reg [(TBITS-1):0] caddr, daddr, maddr; |
reg [(TBITS-1):0] caddr, maddr; |
always @(posedge i_clk) |
begin |
cword <= compression_tbl[rd_addr]; |
212,7 → 212,6
caddr <= rd_addr; |
|
dmatch <= (cword == { r_word[32:31], r_word[29:0] }); |
daddr <= caddr; |
maddr <= tbl_addr - caddr; |
|
vaddr <= ( {1'b0, caddr} < {tbl_filled, tbl_addr} ) |
250,10 → 249,8
end |
|
// Did we find something? |
wire [(TBITS-1):0] adr_diff; |
wire [9:0] adr_dbld; |
wire [2:0] adr_hlfd; |
assign adr_diff = matchaddr; |
assign adr_hlfd = matchaddr[2:0]- 3'd2; |
assign adr_dbld = matchaddr- 10'd10; |
reg [(CW-1):0] r_cword; // Record our result |
/trunk/xula.ucf
140,7 → 140,7
############################## |
NET "i_clk_12mhz" TNM_NET = "i_clk_12mhz"; |
NET "i_ram_feedback_clk" TNM_NET = "i_ram_feedback_clk"; |
TIMESPEC "TSi_clk_12mhz" = PERIOD "i_clk_12mhz" 82 ns HIGH 50%; |
TIMESPEC "TSi_clk_12mhz" = PERIOD "i_clk_12mhz" 82.0 ns HIGH 50%; |
# TIMESPEC "TSi_clk_12mhz" = PERIOD "i_clk_12mhz" 83.333333 ns HIGH 50%; |
# TIMESPEC "TSi_ram_feedback_clk" = PERIOD "i_ram_feedback_clk" 10.0 ns HIGH 50%; |
TIMESPEC "TSi_ram_feedback_clk" = PERIOD "i_ram_feedback_clk" 11.3 ns HIGH 50%; |
/trunk/sw/zipdbg.cpp
101,10 → 101,10
DEVBUS *m_fpga; |
int m_cursor; |
ZIPSTATE m_state; |
bool m_user_break, m_show_users_timers; |
bool m_user_break, m_show_users_timers, m_show_cc; |
public: |
ZIPPY(DEVBUS *fpga) : m_fpga(fpga), m_cursor(0), m_user_break(false), |
m_show_users_timers(false) {} |
m_show_users_timers(false), m_show_cc(false) {} |
|
void read_raw_state(void) { |
m_state.m_valid = false; |
209,6 → 209,10
m_show_users_timers = v; |
} |
|
void toggle_cc(void) { |
m_show_cc = !m_show_cc; |
} |
|
void showval(int y, int x, const char *lbl, unsigned int v, bool c) { |
if (c) |
mvprintw(y,x, ">%s> 0x%08x<", lbl, v); |
409,20 → 413,26
dispreg(ln, 0, "sR12", m_state.m_sR[12], (m_cursor==24)); |
dispreg(ln,20, "sSP ", m_state.m_sR[13], (m_cursor==25)); |
|
mvprintw(ln,40, "%ssCC :%s%s%s%s%s%s%s", |
(m_cursor == 26)?">":" ", |
(cc&0x1000)?"FE":"", // Floating point exception |
(cc&0x0800)?"DV":"", // Division by zero |
(cc&0x0400)?"BE":"", // Bus Error |
(cc&0x0200)?"TP":"", // Trap |
(cc&0x0100)?"IL":"", // Illegal instruction |
(cc&0x0080)?"BK":"", // Break |
((gie==0)&&(cc&0x0010))?"HLT":""); // Halted |
mvprintw(ln,54,"%s%s%s%s", |
(cc&8)?"V":" ", |
(cc&4)?"N":" ", |
(cc&2)?"C":" ", |
(cc&1)?"Z":" "); |
if (m_show_cc) { |
mvprintw(ln,40, " sCC :%16s", ""); |
dispreg(ln, 40, "sCC ", m_state.m_sR[14], (m_cursor==26)); |
} else { |
mvprintw(ln,40, " sCC :%16s", ""); |
mvprintw(ln,40, "%ssCC :%s%s%s%s%s%s%s", |
(m_cursor == 26)?">":" ", |
(cc&0x1000)?"FE":"", // Floating point exception |
(cc&0x0800)?"DV":"", // Division by zero |
(cc&0x0400)?"BE":"", // Bus Error |
(cc&0x0200)?"TP":"", // Trap |
(cc&0x0100)?"IL":"", // Illegal instruction |
(cc&0x0080)?"BK":"", // Break |
((gie==0)&&(cc&0x0010))?"HLT":""); // Halted |
mvprintw(ln,54,"%s%s%s%s", |
(cc&8)?"V":" ", |
(cc&4)?"N":" ", |
(cc&2)?"C":" ", |
(cc&1)?"Z":" "); |
} |
dispreg(ln,60, "sPC ", m_state.m_sR[15], (m_cursor==27)); |
ln++; |
|
449,20 → 459,26
dispreg(ln, 0, "uR12", m_state.m_uR[12], (m_cursor==40)); |
dispreg(ln,20, "uSP ", m_state.m_uR[13], (m_cursor==41)); |
cc = m_state.m_uR[14]; |
mvprintw(ln,40, "%suCC :%s%s%s%s%s%s%s", |
(m_cursor == 42)?">":" ", |
(cc&0x1000)?"FE":"", // Floating point Exception |
(cc&0x0800)?"DV":"", // Division by zero |
(cc&0x0400)?"BE":"", // Bus Error |
(cc&0x0200)?"TP":"", // Trap |
(cc&0x0100)?"IL":"", // Illegal instruction |
(cc&0x0040)?"ST":"", // Single-step |
((gie)&&(cc&0x0010))?"SL":""); // Sleep |
mvprintw(ln,54,"%s%s%s%s", |
(cc&8)?"V":" ", |
(cc&4)?"N":" ", |
(cc&2)?"C":" ", |
(cc&1)?"Z":" "); |
if (m_show_cc) { |
mvprintw(ln,40, " uCC :%16s", ""); |
dispreg(ln, 40, "uCC ", m_state.m_uR[14], (m_cursor==42)); |
} else { |
mvprintw(ln,40, " uCC :%16s", ""); |
mvprintw(ln,40, "%suCC :%s%s%s%s%s%s%s", |
(m_cursor == 42)?">":" ", |
(cc&0x1000)?"FE":"", // Floating point Exception |
(cc&0x0800)?"DV":"", // Division by zero |
(cc&0x0400)?"BE":"", // Bus Error |
(cc&0x0200)?"TP":"", // Trap |
(cc&0x0100)?"IL":"", // Illegal instruction |
(cc&0x0040)?"ST":"", // Single-step |
((gie)&&(cc&0x0010))?"SL":""); // Sleep |
mvprintw(ln,54,"%s%s%s%s", |
(cc&8)?"V":" ", |
(cc&4)?"N":" ", |
(cc&2)?"C":" ", |
(cc&1)?"Z":" "); |
} |
dispreg(ln,60, "uPC ", m_state.m_uR[15], (m_cursor==43)); |
|
attroff(A_BOLD); |
637,6 → 653,9
while((!done)&&(!gbl_err)) { |
chv = getch(); |
switch(chv) { |
case 'c': case 'C': |
zip->toggle_cc(); |
break; |
case 'g': case 'G': |
m_fpga->writeio(R_ZIPCTRL, CPU_GO); |
// We just released the CPU, so we're now done. |
/trunk/sw/cpuscope.cpp
49,6 → 49,7
#include "port.h" |
#include "llcomms.h" |
#include "regdefs.h" |
#include "scopecls.h" |
|
#define WBSCOPE R_CPUSCOPE |
#define WBSCOPEDATA R_CPUSCOPED |
78,9 → 79,68
return r; |
} |
|
void decode(DEVBUS::BUSW val) { |
|
} |
const char *opcodestr[] = { |
"SUB","AND","ADD","OR","XOR","LSR","LSL","ASR", |
"MPY","LDILO","MPYUHI","MPYSHI","BREV","POPC","ROL","MOV", |
"CMP","TEST","LOD","STO","DIVU","DIVS","LDI","LDI", |
"NOOP","BREAK","LOCK","(rsrvd)","(rsrvd)","(rsrvd)","(rsrvd)","(rsrvd)" |
}; |
const char *regstr[] = { |
"R0","R1","R2","R3","R4","R5","R6","R7","R8","R9","RA","RB","RC", |
"SP","CC","PC" |
}; |
|
class CPUSCOPE : public SCOPE { |
public: |
CPUSCOPE(FPGA *fpga, unsigned addr, bool vecread) |
: SCOPE(fpga, addr, false, false) {}; |
~CPUSCOPE(void) {} |
virtual void decode(DEVBUS::BUSW val) const { |
int i_wb_err, gie, alu_illegal, newpc, mem_busy, stb, we, |
maddr, ins, pfval, alu_pc; |
int pfcyc, pfstb, pfaddr; |
|
i_wb_err = (val>>31)&1; |
gie = (val>>30)&1; |
alu_illegal = (val>>29)&1; |
newpc = (val>>28)&1; |
mem_busy = (val>>27)&1; |
stb = (val>>26)&1; |
we = (val>>25)&1; |
maddr = (val>>16)&0x01ff; |
ins = (val>>16)&0x07ff; |
pfval = (val>>15)&1; |
pfcyc = (val>>14)&1; |
pfstb = (val>>13)&1; |
pfaddr = (val & 0x1fff); |
alu_pc = (val & 0x7fff); |
|
printf("%s%s%s%s%s ", |
(i_wb_err)?"E ":" ", |
(gie)?"GIE":" ", |
(alu_illegal)?"ILL":" ", |
(newpc)?"NPC":" ", |
(mem_busy)?"MBSY":" "); |
if (mem_busy) |
printf("M:%s%s@..%4x", (stb)?"STB":" ",(we)?"W":"R", |
maddr); |
else { |
int inreg = (ins>>6)&0x0f; |
int opcode = ((ins>>1)&0x1f); |
const char *incode = opcodestr[opcode]; |
printf("I:%03x %5s,%s", (ins<<1), incode, regstr[inreg]); |
} |
|
if (pfval) |
printf(" V: %04x%4s", alu_pc, ""); |
else |
printf(" %s%s@%04x", |
(pfcyc)?"CYC":" ", |
(pfstb)?"STB":" ", |
pfaddr); |
} |
}; |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
bool use_usb = true; |
108,66 → 168,12
signal(SIGSTOP, closeup); |
signal(SIGHUP, closeup); |
|
unsigned v, lgln, scoplen; |
v = m_fpga->readio(WBSCOPE); |
if (0x60000000 != (v & 0x60000000)) { |
CPUSCOPE *scope = new CPUSCOPE(m_fpga, WBSCOPE, false); |
if (!scope->ready()) { |
printf("Scope is not yet ready:\n"); |
printf("\tRESET:\t\t%s\n", (v&0x80000000)?"Ongoing":"Complete"); |
printf("\tSTOPPED:\t%s\n", (v&0x40000000)?"Yes":"No"); |
printf("\tTRIGGERED:\t%s\n", (v&0x20000000)?"Yes":"No"); |
printf("\tPRIMED:\t\t%s\n", (v&0x10000000)?"Yes":"No"); |
printf("\tMANUAL:\t\t%s\n", (v&0x08000000)?"Yes":"No"); |
printf("\tDISABLED:\t%s\n", (v&0x04000000)?"Yes":"No"); |
printf("\tZERO:\t\t%s\n", (v&0x02000000)?"Yes":"No"); |
exit(0); |
} else printf("SCOPD = %08x\n", v); |
|
lgln = (v>>20) & 0x1f; |
scoplen = (1<<lgln); |
|
DEVBUS::BUSW *buf; |
buf = new DEVBUS::BUSW[scoplen]; |
|
bool compressed = false, vector_read = true; |
DEVBUS::BUSW addrv = 0; |
|
if (vector_read) { |
m_fpga->readz(WBSCOPEDATA, scoplen, buf); |
} else { |
for(unsigned int i=0; i<scoplen; i++) |
buf[i] = m_fpga->readio(WBSCOPEDATA); |
} |
|
if(compressed) { |
for(int i=0; i<(int)scoplen; i++) { |
if ((buf[i]>>31)&1) { |
addrv += (buf[i]&0x7fffffff); |
printf(" ** \n"); |
continue; |
} |
printf("%10d %08x: ", addrv++, buf[i]); |
decode(buf[i]); |
printf("\n"); |
} |
} else { |
for(int i=0; i<(int)scoplen; i++) { |
if ((i>0)&&(buf[i] == buf[i-1])&&(i<(int)(scoplen-1))) { |
if ((i>2)&&(buf[i] != buf[i-2])) |
printf(" **** ****\n"); |
continue; |
} printf("%9d %08x: ", i, buf[i]); |
decode(buf[i]); |
printf("\n"); |
} |
} |
|
if (m_fpga->poll()) { |
printf("FPGA was interrupted\n"); |
m_fpga->clear(); |
m_fpga->writeio(R_ICONTROL, SCOPEN); |
} |
|
delete[] buf; |
scope->decode_control(); |
} else |
scope->read(); |
delete m_fpga; |
} |
|
/trunk/sw/ttybus.cpp
69,17 → 69,20
const unsigned TTYBUS::MAXWRLEN = 32; |
|
// #define DBGPRINTF printf |
#define DBGPRINTF filedump |
// #define DBGPRINTF filedump |
#ifndef DBGPRINTF |
#define DBGPRINTF null |
#endif |
|
void null(...) {} |
|
#include <stdarg.h> // replaces the (defunct) varargs.h include file |
void filedump(const char *fmt, ...) { |
static FILE *dbgfp = NULL; |
va_list args; |
|
assert(0); |
|
if (!dbgfp) |
dbgfp = fopen("debug.txt", "w"); |
va_start(args, fmt); |
/trunk/sw/Makefile
55,8 → 55,10
$(CXX) $(CFLAGS) -c $< -o $@ |
$(OBJDIR)/zipdbg.o: zipdbg.cpp |
$(CXX) $(CFLAGS) -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/cpuscope.o: cpuscope.cpp |
$(OBJDIR)/cpuscope.o: cpuscope.cpp scopecls.h |
$(CXX) $(CFLAGS) -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/scopecls.o: scopecls.cpp scopecls.h |
$(CXX) $(CFLAGS) -I$(ZIPD) -c $< -o $@ |
|
.PHONY: clean |
clean: |
96,7 → 98,7
# ZIPOBJS := $(addprefix $(ZIPD)/$(OBJDIR)/,$(ZIPOBJS_RAW)) |
zipdbg: $(OBJDIR)/zipdbg.o $(BUSOBJS) $(ZIPSRCS) $(OBJDIR)/twoc.o |
$(CXX) $(CFLAGS) $^ $(LIBS) -lncurses -o $@ |
cpuscope: $(OBJDIR)/cpuscope.o $(BUSOBJS) $(ZIPOBJS) |
cpuscope: $(OBJDIR)/cpuscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@ |
|
nothing: |