diff --git a/test/sim/openocd/tb.cpp b/test/sim/openocd/tb.cpp index 951f366..8c56a0d 100644 --- a/test/sim/openocd/tb.cpp +++ b/test/sim/openocd/tb.cpp @@ -17,6 +17,7 @@ static const unsigned int MEM_SIZE = 16 * 1024 * 1024; uint8_t mem[MEM_SIZE]; static const unsigned int IO_BASE = 0x80000000; +static const unsigned int IO_MASK = 0xffffff00; enum { IO_PRINT_CHAR = 0, IO_PRINT_U32 = 4, @@ -219,56 +220,91 @@ int main(int argc, char **argv) { } } - // Handle current data phase, then move current address phase to data phase - uint32_t rdata = 0; - if (bus_trans && bus_write) { - uint32_t wdata = top.p_d__hwdata.get(); - if (bus_addr <= MEM_SIZE) { - unsigned int n_bytes = 1u << bus_size; - // Note we are relying on hazard3's byte lane replication - for (unsigned int i = 0; i < n_bytes; ++i) { - mem[bus_addr + i] = wdata >> (8 * i) & 0xffu; + if (top.p_d__hready.get()) { + // Clear bus error by default + top.p_d__hresp.set(false); + // Handle current data phase + uint32_t rdata = 0; + bool bus_err = false; + if (bus_trans && bus_write) { + uint32_t wdata = top.p_d__hwdata.get(); + if (bus_addr <= MEM_SIZE - 4u) { + unsigned int n_bytes = 1u << bus_size; + // Note we are relying on hazard3's byte lane replication + for (unsigned int i = 0; i < n_bytes; ++i) { + mem[bus_addr + i] = wdata >> (8 * i) & 0xffu; + } + } + else if (bus_addr == IO_BASE + IO_PRINT_CHAR) { + putchar(wdata); + } + else if (bus_addr == IO_BASE + IO_PRINT_U32) { + printf("%08x\n", wdata); + } + else if (bus_addr == IO_BASE + IO_EXIT) { + printf("CPU requested halt. Exit code %d\n", wdata); + printf("Ran for %ld cycles\n", cycle + 1); + break; + } + else { + bus_err = true; } } - else if (bus_addr == IO_BASE + IO_PRINT_CHAR) { - putchar(wdata); + else if (bus_trans && !bus_write) { + if (bus_addr <= MEM_SIZE) { + bus_addr &= ~0x3u; + rdata = + (uint32_t)mem[bus_addr] | + mem[bus_addr + 1] << 8 | + mem[bus_addr + 2] << 16 | + mem[bus_addr + 3] << 24; + } + else { + bus_err = true; + } } - else if (bus_addr == IO_BASE + IO_PRINT_U32) { - printf("%08x\n", wdata); - } - else if (bus_addr == IO_BASE + IO_EXIT) { - printf("CPU requested halt. Exit code %d\n", wdata); - printf("Ran for %ld cycles\n", cycle + 1); - break; + if (bus_err) { + // Phase 1 of error response + top.p_d__hready.set(false); + top.p_d__hresp.set(true); } + top.p_d__hrdata.set(rdata); + + // Progress current address phase to data phase + bus_trans = top.p_d__htrans.get() >> 1; + bus_write = top.p_d__hwrite.get(); + bus_size = top.p_d__hsize.get(); + bus_addr = top.p_d__haddr.get(); } - else if (bus_trans && !bus_write) { - if (bus_addr <= MEM_SIZE) { - bus_addr &= ~0x3u; - rdata = - (uint32_t)mem[bus_addr] | - mem[bus_addr + 1] << 8 | - mem[bus_addr + 2] << 16 | - mem[bus_addr + 3] << 24; - } - } - top.p_d__hrdata.set(rdata); - if (bus_trans_i) { - bus_addr_i &= ~0x3u; - top.p_i__hrdata.set( - (uint32_t)mem[bus_addr_i] | - mem[bus_addr_i + 1] << 8 | - mem[bus_addr_i + 2] << 16 | - mem[bus_addr_i + 3] << 24 - ); + else { + // hready=0. Currently this only happens when we're in the first + // phase of an error response, so go to phase 2. + top.p_d__hready.set(true); } - bus_trans = top.p_d__htrans.get() >> 1; - bus_write = top.p_d__hwrite.get(); - bus_size = top.p_d__hsize.get(); - bus_addr = top.p_d__haddr.get(); - bus_trans_i = top.p_i__htrans.get() >> 1; - bus_addr_i = top.p_i__haddr.get(); + if (top.p_i__hready.get()) { + top.p_i__hresp.set(false); + if (bus_trans_i) { + bus_addr_i &= ~0x3u; + if (bus_addr_i <= MEM_SIZE - 4u) { + top.p_i__hrdata.set( + (uint32_t)mem[bus_addr_i] | + mem[bus_addr_i + 1] << 8 | + mem[bus_addr_i + 2] << 16 | + mem[bus_addr_i + 3] << 24 + ); + } + else { + top.p_i__hready.set(false); + top.p_i__hresp.set(true); + } + } + bus_trans_i = top.p_i__htrans.get() >> 1; + bus_addr_i = top.p_i__haddr.get(); + } + else { + top.p_i__hready.set(true); + } if (dump_waves) { // The extra step() is just here to get the bus responses to line up nicely diff --git a/test/sim/openocd/waves.gtkw b/test/sim/openocd/waves.gtkw index 80fb43a..c56e5e7 100644 --- a/test/sim/openocd/waves.gtkw +++ b/test/sim/openocd/waves.gtkw @@ -1,15 +1,17 @@ [*] [*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI -[*] Mon Jul 12 17:15:59 2021 +[*] Sat Jul 17 18:13:53 2021 [*] -[dumpfile] "/home/luke/proj/hazard3/test/sim/debug_openocd_bitbang/waves.vcd" -[dumpfile_mtime] "Mon Jul 12 17:11:32 2021" -[dumpfile_size] 2961061 -[savefile] "/home/luke/proj/hazard3/test/sim/debug_openocd_bitbang/waves.gtkw" -[timestart] 0 +[dumpfile] "/home/luke/proj/hazard3/test/sim/openocd/waves.vcd" +[dumpfile_mtime] "Sat Jul 17 18:07:33 2021" +[dumpfile_size] 6782392 +[savefile] "/home/luke/proj/hazard3/test/sim/openocd/waves.gtkw" +[timestart] 140588 [size] 1920 1043 [pos] -1 -1 -*-13.000000 18597 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-3.000000 140615 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] cpu. +[treeopen] cpu.core. [treeopen] inst_hazard3_jtag_dtm. [sst_width] 233 [signals_width] 222 @@ -21,7 +23,6 @@ trst_n rst_n_dmi @200 - -@201 -DTM @28 tck @@ -63,5 +64,32 @@ cpu.dbg_halted cpu.dbg_running @200 - +-Trap stuff +@22 +cpu.core.inst_hazard3_csr.trap_addr[31:0] +@28 +cpu.core.inst_hazard3_csr.trap_enter_rdy +cpu.core.inst_hazard3_csr.trap_enter_vld +cpu.core.inst_hazard3_csr.trap_is_irq +@22 +cpu.core.inst_hazard3_csr.except[3:0] +@28 +cpu.core.m_stall +@29 +cpu.core.bus_dph_err_d +@200 +- +-D Bus +@22 +d_haddr[31:0] +@28 +d_htrans[1:0] +d_hwrite +d_hsize[2:0] +d_hready +d_hresp +@22 +d_hwdata[31:0] +d_hrdata[31:0] [pattern_trace] 1 [pattern_trace] 0