From 5ec810907e9963419f4fc0b946a9d71833b32c03 Mon Sep 17 00:00:00 2001 From: Colin Date: Thu, 27 Mar 2025 15:49:16 +0800 Subject: [PATCH] Refine soc_cxxrtl and pass demo. --- .gitignore | 1 + test/sim/common/src_only_app.mk | 2 +- test/sim/common/tb_cxxrtl_io.h | 2 +- test/sim/soc_cxxrtl/Makefile | 11 ++- test/sim/soc_cxxrtl/tb.cpp | 136 ++++++++++++++++---------------- test/sim/soc_cxxrtl/tb.f | 3 +- 6 files changed, 83 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index 2c19c05..206cd3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store *.todo +.vscode diff --git a/test/sim/common/src_only_app.mk b/test/sim/common/src_only_app.mk index 6507a68..e382a6d 100644 --- a/test/sim/common/src_only_app.mk +++ b/test/sim/common/src_only_app.mk @@ -9,7 +9,7 @@ endif DOTF ?= tb.f CCFLAGS ?= LDSCRIPT ?= ../common/memmap.ld -CROSS_PREFIX ?= riscv32-unknown-elf- +CROSS_PREFIX ?= /opt/riscv/bin/riscv32-unknown-elf- TBEXEC ?= ../tb_cxxrtl/tb TBDIR := $(dir $(abspath $(TBEXEC))) INCDIR ?= ../common diff --git a/test/sim/common/tb_cxxrtl_io.h b/test/sim/common/tb_cxxrtl_io.h index 3835bfb..7635bc5 100644 --- a/test/sim/common/tb_cxxrtl_io.h +++ b/test/sim/common/tb_cxxrtl_io.h @@ -9,7 +9,7 @@ // ---------------------------------------------------------------------------- // Testbench IO hardware layout -#define IO_BASE 0x80000000 +#define IO_BASE 0x40000000 typedef struct { volatile uint32_t print_char; diff --git a/test/sim/soc_cxxrtl/Makefile b/test/sim/soc_cxxrtl/Makefile index 92753cb..61b72f0 100644 --- a/test/sim/soc_cxxrtl/Makefile +++ b/test/sim/soc_cxxrtl/Makefile @@ -3,7 +3,7 @@ include ../project_paths.mk -TOP := tb +TOP := example_soc DOTF := tb.f CONFIG := default TBEXEC := $(patsubst %.f,%,$(DOTF)) @@ -30,6 +30,15 @@ $(BUILD_DIR)/dut.cpp: $(FILE_LIST) $(wildcard *.vh) clean:: rm -rf $(BUILD_DIR) $(TBEXEC) +sim: $(TBEXEC) + ./$(TBEXEC) --port 9824 + +openocd: + openocd -f openocd.cfg + +gdb: + /opt/riscv/bin/riscv32-unknown-elf-gdb -x gdb_init + $(TBEXEC): $(BUILD_DIR)/dut.cpp tb.cpp $(CLANGXX) -O3 -std=c++14 $(addprefix -D,$(CDEFINES) $(CDEFINES_$(DOTF))) -I $(shell yosys-config --datdir)/include/backends/cxxrtl/runtime -I $(BUILD_DIR) tb.cpp -o $(TBEXEC) diff --git a/test/sim/soc_cxxrtl/tb.cpp b/test/sim/soc_cxxrtl/tb.cpp index d2c9a0d..d6a9b75 100644 --- a/test/sim/soc_cxxrtl/tb.cpp +++ b/test/sim/soc_cxxrtl/tb.cpp @@ -74,10 +74,10 @@ struct mem_io_state { // Where we're going we don't need a destructor B-) - void step(cxxrtl_design::p_tb &tb) { + void step(cxxrtl_design::p_example__soc &tb) { // Default update logic for mtime, mtimecmp ++mtime; - tb.p_timer__irq.set((mtime >= mtimecmp[0]) | (mtime >= mtimecmp[1]) << 1); + // tb.p_timer__irq.set((mtime >= mtimecmp[0]) | (mtime >= mtimecmp[1]) << 1); } }; @@ -105,7 +105,7 @@ struct bus_response { bus_response(): rdata(0), stall_cycles(0), err(false), exokay(true) {} }; -bus_response mem_access(cxxrtl_design::p_tb &tb, mem_io_state &memio, bus_request req) { +bus_response mem_access(cxxrtl_design::p_example__soc &tb, mem_io_state &memio, bus_request req) { bus_response resp; // Global monitor. When monitor is not enabled, HEXOKAY is tied high @@ -171,19 +171,19 @@ bus_response mem_access(cxxrtl_design::p_tb &tb, mem_io_state &memio, bus_reques } } else if (req.addr == IO_BASE + IO_SET_SOFTIRQ) { - tb.p_soft__irq.set(tb.p_soft__irq.get() | req.wdata); + // tb.p_soft__irq.set(tb.p_soft__irq.get() | req.wdata); } else if (req.addr == IO_BASE + IO_CLR_SOFTIRQ) { - tb.p_soft__irq.set(tb.p_soft__irq.get() & ~req.wdata); + // tb.p_soft__irq.set(tb.p_soft__irq.get() & ~req.wdata); } else if (req.addr == IO_BASE + IO_GLOBMON_EN) { memio.monitor_enabled = req.wdata; } else if (req.addr == IO_BASE + IO_SET_IRQ) { - tb.p_irq.set(tb.p_irq.get() | req.wdata); + // tb.p_irq.set(tb.p_irq.get() | req.wdata); } else if (req.addr == IO_BASE + IO_CLR_IRQ) { - tb.p_irq.set(tb.p_irq.get() & ~req.wdata); + // tb.p_irq.set(tb.p_irq.get() & ~req.wdata); } else if (req.addr == IO_BASE + IO_MTIME) { memio.mtime = (memio.mtime & 0xffffffff00000000u) | req.wdata; @@ -217,10 +217,10 @@ bus_response mem_access(cxxrtl_design::p_tb &tb, mem_io_state &memio, bus_reques memio.mem[req.addr + 3] << 24; } else if (req.addr == IO_BASE + IO_SET_SOFTIRQ || req.addr == IO_BASE + IO_CLR_SOFTIRQ) { - resp.rdata = tb.p_soft__irq.get(); + // resp.rdata = tb.p_soft__irq.get(); } else if (req.addr == IO_BASE + IO_SET_IRQ || req.addr == IO_BASE + IO_CLR_IRQ) { - resp.rdata = tb.p_irq.get(); + // resp.rdata = tb.p_irq.get(); } else if (req.addr == IO_BASE + IO_MTIME) { resp.rdata = memio.mtime; @@ -449,7 +449,7 @@ int main(int argc, char **argv) { } } - cxxrtl_design::p_tb top; + cxxrtl_design::p_example__soc top; std::ofstream waves_fd; cxxrtl::vcd_writer vcd; @@ -470,8 +470,8 @@ int main(int argc, char **argv) { req_d.reservation_id = 1; // Set bus interfaces to generate good IDLE responses at first - top.p_i__hready.set(true); - top.p_d__hready.set(true); + // top.p_i__hready.set(true); + // top.p_d__hready.set(true); // Reset + initial clock pulse @@ -580,68 +580,68 @@ int main(int argc, char **argv) { // - A single, single-ported processor (instruction fetch + load/store muxed internally) // - A pair of single-ported processors, for dual-core debug tests - if (top.p_d__hready.get()) { - // Clear bus error by default - top.p_d__hresp.set(false); + // if (top.p_d__hready.get()) { + // // Clear bus error by default + // top.p_d__hresp.set(false); - // Handle current data phase - req_d.wdata = top.p_d__hwdata.get(); - bus_response resp; - if (req_d_vld) - resp = mem_access(top, memio, req_d); - else - resp.exokay = !memio.monitor_enabled; - if (resp.err) { - // Phase 1 of error response - top.p_d__hready.set(false); - top.p_d__hresp.set(true); - } - top.p_d__hrdata.set(resp.rdata); - top.p_d__hexokay.set(resp.exokay); + // // Handle current data phase + // req_d.wdata = top.p_d__hwdata.get(); + // bus_response resp; + // if (req_d_vld) + // resp = mem_access(top, memio, req_d); + // else + // resp.exokay = !memio.monitor_enabled; + // if (resp.err) { + // // Phase 1 of error response + // top.p_d__hready.set(false); + // top.p_d__hresp.set(true); + // } + // top.p_d__hrdata.set(resp.rdata); + // top.p_d__hexokay.set(resp.exokay); - // Progress current address phase to data phase - req_d_vld = top.p_d__htrans.get() >> 1; - req_d.write = top.p_d__hwrite.get(); - req_d.size = (bus_size_t)top.p_d__hsize.get(); - req_d.addr = top.p_d__haddr.get(); - req_d.excl = top.p_d__hexcl.get(); - } - 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); - } + // // Progress current address phase to data phase + // req_d_vld = top.p_d__htrans.get() >> 1; + // req_d.write = top.p_d__hwrite.get(); + // req_d.size = (bus_size_t)top.p_d__hsize.get(); + // req_d.addr = top.p_d__haddr.get(); + // req_d.excl = top.p_d__hexcl.get(); + // } + // 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); + // } - if (top.p_i__hready.get()) { - top.p_i__hresp.set(false); + // if (top.p_i__hready.get()) { + // top.p_i__hresp.set(false); - req_i.wdata = top.p_i__hwdata.get(); - bus_response resp; - if (req_i_vld) - resp = mem_access(top, memio, req_i); - else - resp.exokay = !memio.monitor_enabled; - if (resp.err) { - // Phase 1 of error response - top.p_i__hready.set(false); - top.p_i__hresp.set(true); - } - top.p_i__hrdata.set(resp.rdata); - top.p_i__hexokay.set(resp.exokay); + // req_i.wdata = top.p_i__hwdata.get(); + // bus_response resp; + // if (req_i_vld) + // resp = mem_access(top, memio, req_i); + // else + // resp.exokay = !memio.monitor_enabled; + // if (resp.err) { + // // Phase 1 of error response + // top.p_i__hready.set(false); + // top.p_i__hresp.set(true); + // } + // top.p_i__hrdata.set(resp.rdata); + // top.p_i__hexokay.set(resp.exokay); - // Progress current address phase to data phase - req_i_vld = top.p_i__htrans.get() >> 1; - req_i.write = top.p_i__hwrite.get(); - req_i.size = (bus_size_t)top.p_i__hsize.get(); - req_i.addr = top.p_i__haddr.get(); - req_i.excl = top.p_i__hexcl.get(); - } - 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_i__hready.set(true); - } + // // Progress current address phase to data phase + // req_i_vld = top.p_i__htrans.get() >> 1; + // req_i.write = top.p_i__hwrite.get(); + // req_i.size = (bus_size_t)top.p_i__hsize.get(); + // req_i.addr = top.p_i__haddr.get(); + // req_i.excl = top.p_i__hexcl.get(); + // } + // 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_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/soc_cxxrtl/tb.f b/test/sim/soc_cxxrtl/tb.f index db7c58d..8d85051 100644 --- a/test/sim/soc_cxxrtl/tb.f +++ b/test/sim/soc_cxxrtl/tb.f @@ -1,2 +1,3 @@ -file tb.v +list $HDL/../example_soc/soc/soc.f +file $HDL/debug/cdc/hazard3_reset_sync.v list tb_common.f