ã¨ããã§ãRISC-V Rocket-Chipãã·ãã¥ã¬ã¼ã·ã§ã³ããã¨ããä½æ°ãªãmakeãå©ãã¦ã
make CONFIG=DefaultConfig output/rv64ui-p-add.out
ã¨ããã¦ãåæã«å®è¡ããã¦ãããã©ãããèããã¨å ·ä½çã«ã©ã®ããã«ãã¦åä½ãã¦ããã®ãåãããªãããããç解ããããã«ã¯ãRocketChipãã©ã®ããã«ã³ã³ãã¤ã«ãããå®è¡ããã¦ããã®ãã«ã¤ãã¦ç¥ããªããã°ãªããªãã
ãããç解ããããã«ã¯ãRISC-V FrontEnd Server (fesvr)ã«ã¤ãã¦ç解ããªããã°ãªããªãã
RISC-V Rocket Chipãåä½ããã¾ã§ã®ä»çµã¿
ã¾ããVCSã·ãã¥ã¬ã¼ã¿ã§å®è¡ããå ´åãè¦ã¦ã¿ããæå ã«VCSãå®è¡ã§ããªãã®ã§makeã®ä¸èº«ãåç §ããªããã ãã
cd vsim make CONFIG=DefaultConfig
ã¨ããã¨ãMakefile群ã¨ãã¦ä»¥ä¸ãçæãããã¯ãã ã
ãããã«ãRocketChipãç解ããããã®ç§å¯ãé ããã¦ããã
å¿ è¦ãªãã¡ã¤ã«ç¾¤
Makefragãåç §ããã¨ã以ä¸ã®ãã¡ã¤ã«ãå¿ è¦ãªãã¨ãåãããjtagã¯ã¨ããããç¡è¦ãã¦ãOKã ããSimDTM.v, SimDTM.ccã¨ããã®ã¯RocketChipã®å ¨ä½å¶å¾¡ã管çãã¦ãããã®ã ã
bb_vsrcs = \ $(base_dir)/vsrc/jtag_vpi.v \ $(base_dir)/vsrc/plusarg_reader.v \ $(base_dir)/vsrc/ClockDivider2.v \ $(base_dir)/vsrc/ClockDivider3.v \ $(base_dir)/vsrc/AsyncResetReg.v \ sim_vsrcs = \ $(generated_dir)/$(long_name).v \ $(generated_dir)/$(long_name).behav_srams.v \ $(base_dir)/vsrc/$(TB).v \ $(base_dir)/vsrc/SimDTM.v \ $(bb_vsrcs) # C sources sim_csrcs = \ $(base_dir)/csrc/SimDTM.cc \ $(base_dir)/csrc/jtag_vpi.c
ã¾ããVCSã®ã³ã³ãã¤ã«ãªãã·ã§ã³ã«ãRISC-Vã®ã©ã¤ãã©ãªãæå®ããã¦ãããã¨ãåããããããRISC-Vã®ããã³ãã¨ã³ããµã¼ãfesvrã ã
VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -error=PCWM-L -timescale=1ns/10ps -quiet \ +rad +v2k +vcs+lic+wait \ +vc+list -CC "-I$(VCS_HOME)/include" \ -CC "-I$(RISCV)/include" \ -CC "-std=c++11" \ -CC "-Wl,-rpath,$(RISCV)/lib" \ $(RISCV)/lib/libfesvr.so \ -sverilog \ +incdir+$(generated_dir) \ +define+CLOCK_PERIOD=1.0 $(sim_vsrcs) $(sim_csrcs) \ +define+PRINTF_COND=$(TB).printf_cond \ +define+STOP_COND=!$(TB).reset \ +define+RANDOMIZE_MEM_INIT \ +define+RANDOMIZE_REG_INIT \ +define+RANDOMIZE_GARBAGE_ASSIGN \ +define+RANDOMIZE_INVALID_ASSIGN \ +libext+.v \
RocketChipã®ã·ãã¥ã¬ã¼ã·ã§ã³æããã¼
ååç´¹ä»ããããã«ãRocketChipã®æ§é ã¯ä»¥ä¸ã®ããã«ãªã£ã¦ããã
TestDriver.v
ã·ãã¥ã¬ã¼ã·ã§ã³ã®ãªãã·ã§ã³ã管çããé¨åã$value$plusargs
ã®å¦çãªã©ã¯ããã§è¡ããã¦ãããTestDriverå
ã§TestHarnessãã¤ã³ã¹ã¿ã³ã¹ããã¦ããã
TestHarness
TestHarnessã®ä¸ã«ã¤ã³ã¹ã¿ã³ã¹ããã¦ãããã®ãå ·ä½çã«åæããã¨ã
- ExampleRocketTop : RocketChipæ¬ä½ã«å½ããã
- SimAXIMem : mem_axi4 ãæ¥ç¶ããã¦ããRAMã«ããããããããé常ã®å½ä»¤ããã¼ã¿ã¢ã¯ã»ã¹ã«å½ããã
- SimAXIMem_1 : mmio_axi4ãæ¥ç¶ããã¦ããRAMã«ããããMMIOã®ãã¼ã¿ã¢ã¯ã»ã¹ã«å½ããã
- SimDTM : RTLã®ã³ã³ããã¼ã«é¨ã«ãªãã
ããã§ã¯ã¨ããããRocketChipã®æ¬ä½ã¨ããSimAXIMemã¯ã»ãã£ã¦ããã¦ãSimDTMã«ã¤ãã¦çç®ããã
SimDTM.vãåç §ãã
SimDTM.vãåç §ãã¦ã¿ãã
module SimDTM( input clk, input reset, ... __exit = debug_tick( __debug_req_valid, __debug_req_ready, __debug_req_bits_addr, __debug_req_bits_op, __debug_req_bits_data, __debug_resp_valid, __debug_resp_ready, __debug_resp_bits_resp, __debug_resp_bits_data );
ãã®debug_tick()
ããæ¯ãµã¤ã¯ã«å®è¡ãããã¨ããããã ããã®debug_tick()
ã¯
if (!dtm) { s_vpi_vlog_info info; if (!vpi_get_vlog_info(&info)) abort(); dtm = new dtm_t(filter_argv_for_dtm(info.argc, info.argv)); }
ã¨ãã¦å®ç¾©ããã¦ããããã®dtm_t
ãfesvr
ã«å®ç¾©ããã¦ããããã®dtm㯠riscv-tools/riscv-fesvr/fesvr/dtm.cc
ã«å®ç¾©ããã¦ãããããã§ã¯ã³ã³ã¹ãã©ã¯ã¿ãå¼ãã§ããã®ã§ã
dtm_t::dtm_t(const std::vector<std::string>& args) : htif_t(args) { start_host_thread(); } ... htif_t::htif_t(const std::vector<std::string>& args) : mem(this), entry(DRAM_BASE), sig_addr(0), sig_len(0), tohost_addr(0), fromhost_addr(0), exitcode(0), stopped(false), syscall_proxy(this) { signal(SIGINT, &handle_signal); signal(SIGTERM, &handle_signal); signal(SIGABRT, &handle_signal); // we still want to call static destructors size_t i;
ããã§ãæåã«load_program()
ãå¼ã°ãããã¨ã§ãELFãã¡ã¤ã«ããã¼ããããã
void htif_t::load_program() { std::string path; if (access(targs[0].c_str(), F_OK) == 0) path = targs[0]; else if (targs[0].find('/') == std::string::npos) { std::string test_path = PREFIX TARGET_DIR + targs[0]; if (access(test_path.c_str(), F_OK) == 0) path = test_path; } if (path.empty()) throw std::runtime_error("could not open " + targs[0]); std::map<std::string, uint64_t> symbols = load_elf(path.c_str(), &mem, &entry); if (symbols.count("tohost") && symbols.count("fromhost")) { tohost_addr = symbols["tohost"]; fromhost_addr = symbols["fromhost"]; } else { fprintf(stderr, "warning: tohost and fromhost symbols not in ELF; can't communicate with target\n"); } // detect torture tests so we can print the memory signature at the end if (symbols.count("begin_signature") && symbols.count("end_signature")) { sig_addr = symbols["begin_signature"]; sig_len = symbols["end_signature"] - sig_addr; } }