OpenCores
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:

powered by: WebSVN 2.1.0

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