diff --git a/generators/chipyard/src/main/resources/csrc/cospike.cc b/generators/chipyard/src/main/resources/csrc/cospike.cc index 36b15ccf..bc065860 100644 --- a/generators/chipyard/src/main/resources/csrc/cospike.cc +++ b/generators/chipyard/src/main/resources/csrc/cospike.cc @@ -35,6 +35,11 @@ extern std::map backing_mem_data; #define PLIC_BASE (0xc000000) #define PLIC_SIZE (0x4000000) +#define COSPIKE_PRINTF(...) { \ + printf(__VA_ARGS__); \ + fprintf(stderr, __VA_ARGS__); \ + } + typedef struct system_info_t { std::string isa; int pmpregions; @@ -42,19 +47,21 @@ typedef struct system_info_t { uint64_t mem0_size; int nharts; std::vector bootrom; + std::string priv; }; class read_override_device_t : public abstract_device_t { public: - read_override_device_t(std::string n, reg_t sz) : was_read_from(false), size(size), name(n) { }; - bool load(reg_t addr, size_t len, uint8_t* bytes) { - if (addr + len < addr || addr + len > size) return false; - printf("Read from device %s at %lx\n", name.c_str(), addr); + read_override_device_t(std::string n, reg_t sz) : was_read_from(false), size(sz), name(n) { }; + virtual bool load(reg_t addr, size_t len, uint8_t* bytes) override { + if (addr + len > size) return false; + COSPIKE_PRINTF("Read from device %s at %lx\n", name.c_str(), addr); was_read_from = true; return true; } - bool store(reg_t addr, size_t len, const uint8_t* bytes) { - return (addr + len >= addr && addr + len <= size); + virtual bool store(reg_t addr, size_t len, const uint8_t* bytes) override { + COSPIKE_PRINTF("Store to device %s at %lx\n", name.c_str(), addr); + return (addr + len <= size); } bool was_read_from; private: @@ -82,7 +89,7 @@ static std::vector> make_mems(const std::vectorisa = std::string(isa) + "_zicntr"; + info->priv = std::string(priv); info->pmpregions = pmpregions; info->mem0_base = mem0_base; info->mem0_size = mem0_size; @@ -118,7 +126,7 @@ extern "C" void cospike_cosim(long long int cycle, assert(info); if (unlikely(!sim)) { - printf("Configuring spike cosim\n"); + COSPIKE_PRINTF("Configuring spike cosim\n"); std::vector mem_cfg; std::vector hartids; mem_cfg.push_back(mem_cfg_t(info->mem0_base, info->mem0_size)); @@ -128,7 +136,7 @@ extern "C" void cospike_cosim(long long int cycle, cfg = new cfg_t(std::make_pair(0, 0), nullptr, info->isa.c_str(), - "MSU", + info->priv.c_str(), "vlen:128,elen:64", false, endianness_little, @@ -200,12 +208,13 @@ extern "C" void cospike_cosim(long long int cycle, .support_impebreak = true }; - printf("isa string: %s\n", info->isa.c_str()); - printf("htif args: "); + COSPIKE_PRINTF("isa string: %s\n", info->isa.c_str()); + COSPIKE_PRINTF("htif args: "); for (int i = 0; i < htif_args.size(); i++) { - printf("%s", htif_args[i].c_str()); + COSPIKE_PRINTF("%s", htif_args[i].c_str()); } - printf("\n"); + COSPIKE_PRINTF("\n"); + std::vector plugin_device_factories; sim = new sim_t(cfg, false, mems, @@ -229,9 +238,9 @@ extern "C" void cospike_cosim(long long int cycle, for (auto& pair : backing_mem_data) { size_t base = pair.first; size_t size = pair.second.size; - printf("Matching spike memory initial state for region %lx-%lx\n", base, base + size); + COSPIKE_PRINTF("Matching spike memory initial state for region %lx-%lx\n", base, base + size); if (!temp_mem_bus.store(base, size, pair.second.data)) { - printf("Error, unable to match memory at address %lx\n", base); + COSPIKE_PRINTF("Error, unable to match memory at address %lx\n", base); abort(); } } @@ -251,17 +260,17 @@ extern "C" void cospike_cosim(long long int cycle, sim->set_debug(cospike_debug); sim->set_histogram(true); sim->set_procs_debug(cospike_debug); - printf("Setting up htif for spike cosim\n"); + COSPIKE_PRINTF("Setting up htif for spike cosim\n"); ((htif_t*)sim)->start(); - printf("Spike cosim started\n"); + COSPIKE_PRINTF("Spike cosim started\n"); tohost_addr = ((htif_t*)sim)->get_tohost_addr(); fromhost_addr = ((htif_t*)sim)->get_fromhost_addr(); - printf("Tohost : %lx\n", tohost_addr); - printf("Fromhost: %lx\n", fromhost_addr); - printf("BootROM base : %lx\n", default_boot_rom_addr); - printf("BootROM size : %lx\n", boot_rom->contents().size()); - printf("Memory base : %lx\n", info->mem0_base); - printf("Memory size : %lx\n", info->mem0_size); + COSPIKE_PRINTF("Tohost : %lx\n", tohost_addr); + COSPIKE_PRINTF("Fromhost: %lx\n", fromhost_addr); + COSPIKE_PRINTF("BootROM base : %lx\n", default_boot_rom_addr); + COSPIKE_PRINTF("BootROM size : %lx\n", boot_rom->contents().size()); + COSPIKE_PRINTF("Memory base : %lx\n", info->mem0_base); + COSPIKE_PRINTF("Memory size : %lx\n", info->mem0_size); } if (priv & 0x4) { // debug @@ -270,7 +279,7 @@ extern "C" void cospike_cosim(long long int cycle, if (cospike_timeout && cycle > cospike_timeout) { if (sim) { - printf("Cospike reached timeout cycles = %ld, terminating\n", cospike_timeout); + COSPIKE_PRINTF("Cospike reached timeout cycles = %ld, terminating\n", cospike_timeout); delete sim; } exit(0); @@ -281,7 +290,7 @@ extern "C" void cospike_cosim(long long int cycle, state_t* s = p->get_state(); #ifdef COSPIKE_DTM if (dtm && dtm->loadarch_done && !spike_loadarch_done) { - printf("Restoring spike state from testchip_dtm loadarch\n"); + COSPIKE_PRINTF("Restoring spike state from testchip_dtm loadarch\n"); // copy the loadarch state into the cosim loadarch_state_t &ls = dtm->loadarch_state[hartid]; s->pc = ls.pc; @@ -313,11 +322,11 @@ extern "C" void cospike_cosim(long long int cycle, RESTORE(CSR_MCYCLE , mcycle); RESTORE(CSR_MINSTRET , minstret); if (ls.VLEN != p->VU.VLEN) { - printf("VLEN mismatch loadarch: $d != spike: $d\n", ls.VLEN, p->VU.VLEN); + COSPIKE_PRINTF("VLEN mismatch loadarch: $d != spike: $d\n", ls.VLEN, p->VU.VLEN); abort(); } if (ls.ELEN != p->VU.ELEN) { - printf("ELEN mismatch loadarch: $d != spike: $d\n", ls.ELEN, p->VU.ELEN); + COSPIKE_PRINTF("ELEN mismatch loadarch: $d != spike: $d\n", ls.ELEN, p->VU.ELEN); abort(); } for (size_t i = 0; i < 32; i++) { @@ -337,7 +346,7 @@ extern "C" void cospike_cosim(long long int cycle, bool mtip_interrupt = interrupt_cause == 0x7; bool debug_interrupt = interrupt_cause == 0xe; if (raise_interrupt) { - printf("%d interrupt %lx\n", cycle, cause); + COSPIKE_PRINTF("%d interrupt %lx\n", cycle, cause); if (ssip_interrupt || stip_interrupt) { // do nothing @@ -348,41 +357,41 @@ extern "C" void cospike_cosim(long long int cycle, } else if (debug_interrupt) { return; } else { - printf("Unknown interrupt %lx\n", interrupt_cause); + COSPIKE_PRINTF("Unknown interrupt %lx\n", interrupt_cause); abort(); } } if (raise_exception) - printf("%d exception %lx\n", cycle, cause); + COSPIKE_PRINTF("%d exception %lx\n", cycle, cause); if (valid) { p->clear_waiting_for_interrupt(); - printf("%d Cosim: %lx", cycle, iaddr); + COSPIKE_PRINTF("%d Cosim: %lx", cycle, iaddr); // if (has_wdata) { - // printf(" s: %lx", wdata); + // COSPIKE_PRINTF(" s: %lx", wdata); // } - printf("\n"); + COSPIKE_PRINTF("\n"); } if (valid || raise_interrupt || raise_exception) { p->clear_waiting_for_interrupt(); for (auto& e : read_override_devices) e.get()->was_read_from = false; p->step(1); if (unlikely(cospike_debug)) { - printf("spike pc is %lx\n", s->pc); - printf("spike mstatus is %lx\n", s->mstatus->read()); - printf("spike mip is %lx\n", s->mip->read()); - printf("spike mie is %lx\n", s->mie->read()); - printf("spike wfi state is %d\n", p->is_waiting_for_interrupt()); + COSPIKE_PRINTF("spike pc is %lx\n", s->pc); + COSPIKE_PRINTF("spike mstatus is %lx\n", s->mstatus->read()); + COSPIKE_PRINTF("spike mip is %lx\n", s->mip->read()); + COSPIKE_PRINTF("spike mie is %lx\n", s->mie->read()); + COSPIKE_PRINTF("spike wfi state is %d\n", p->is_waiting_for_interrupt()); } } if (valid && !raise_exception) { if (s_pc != iaddr) { - printf("%d PC mismatch spike %llx != DUT %llx\n", cycle, s_pc, iaddr); + COSPIKE_PRINTF("%d PC mismatch spike %llx != DUT %llx\n", cycle, s_pc, iaddr); if (unlikely(cospike_debug)) { - printf("spike mstatus is %lx\n", s->mstatus->read()); - printf("spike mcause is %lx\n", s->mcause->read()); - printf("spike mtval is %lx\n" , s->mtval->read()); - printf("spike mtinst is %lx\n", s->mtinst->read()); + COSPIKE_PRINTF("spike mstatus is %lx\n", s->mstatus->read()); + COSPIKE_PRINTF("spike mcause is %lx\n", s->mcause->read()); + COSPIKE_PRINTF("spike mtval is %lx\n" , s->mtval->read()); + COSPIKE_PRINTF("spike mtinst is %lx\n", s->mtinst->read()); } exit(1); } @@ -403,7 +412,7 @@ extern "C" void cospike_cosim(long long int cycle, } // Try to remember magic_mem addrs, and ignore these in the future if ( waddr == tohost_addr && w_data >= info->mem0_base && w_data < (info->mem0_base + info->mem0_size)) { - printf("Probable magic mem %lx\n", w_data); + COSPIKE_PRINTF("Probable magic mem %lx\n", w_data); magic_addrs.insert(w_data); } } @@ -451,7 +460,7 @@ extern "C" void cospike_cosim(long long int cycle, uint64_t csr_addr = (insn >> 20) & 0xfff; bool csr_read = (insn & 0x7f) == 0x73; if (csr_read) - printf("CSR read %lx\n", csr_addr); + COSPIKE_PRINTF("CSR read %lx\n", csr_addr); if (csr_read && ((csr_addr == 0x301) || // misa (csr_addr == 0x306) || // mcounteren (csr_addr == 0xf13) || // mimpid @@ -465,17 +474,17 @@ extern "C" void cospike_cosim(long long int cycle, (csr_addr >= 0x7a0 && csr_addr <= 0x7aa) || // debug trigger registers (csr_addr >= 0x3b0 && csr_addr <= 0x3ef) // pmpaddr )) { - printf("CSR override\n"); + COSPIKE_PRINTF("CSR override\n"); s->XPR.write(rd, wdata); } else if (ignore_read) { // Don't check reads from tohost, reads from magic memory, or reads // from clint Technically this could be buggy because log_mem_read // only reports vaddrs, but no software ever should access // tohost/fromhost/clint with vaddrs anyways - printf("Read override %lx = %lx\n", mem_read_addr, wdata); + COSPIKE_PRINTF("Read override %lx = %lx\n", mem_read_addr, wdata); s->XPR.write(rd, wdata); } else if (wdata != regwrite.second.v[0]) { - printf("%d wdata mismatch reg %d %lx != %lx\n", cycle, rd, + COSPIKE_PRINTF("%d wdata mismatch reg %d %lx != %lx\n", cycle, rd, regwrite.second.v[0], wdata); exit(1); } @@ -483,7 +492,7 @@ extern "C" void cospike_cosim(long long int cycle, // TODO FIX: Rocketchip TracedInstruction.wdata should be Valid(UInt) // if (scalar_wb ^ has_wdata) { - // printf("Scalar wdata behavior divergence between spike and DUT\n"); + // COSPIKE_PRINTF("Scalar wdata behavior divergence between spike and DUT\n"); // exit(-1); // } } diff --git a/generators/chipyard/src/main/resources/vsrc/cospike.v b/generators/chipyard/src/main/resources/vsrc/cospike.v index 824e8d35..b95670a9 100644 --- a/generators/chipyard/src/main/resources/vsrc/cospike.v +++ b/generators/chipyard/src/main/resources/vsrc/cospike.v @@ -1,5 +1,6 @@ import "DPI-C" function void cospike_set_sysinfo( input string isa, + input string priv, input int pmpregions, input longint mem0_base, input longint mem0_size, @@ -23,6 +24,7 @@ import "DPI-C" function void cospike_cosim(input longint cycle, module SpikeCosim #( parameter ISA, + parameter PRIV, parameter PMPREGIONS, parameter MEM0_BASE, parameter MEM0_SIZE, @@ -57,7 +59,7 @@ module SpikeCosim #( ); initial begin - cospike_set_sysinfo(ISA, PMPREGIONS, MEM0_BASE, MEM0_SIZE, NHARTS, BOOTROM); + cospike_set_sysinfo(ISA, PRIV, PMPREGIONS, MEM0_BASE, MEM0_SIZE, NHARTS, BOOTROM); end; always @(posedge clock) begin diff --git a/generators/chipyard/src/main/scala/Cospike.scala b/generators/chipyard/src/main/scala/Cospike.scala index de04b032..182af91a 100644 --- a/generators/chipyard/src/main/scala/Cospike.scala +++ b/generators/chipyard/src/main/scala/Cospike.scala @@ -14,6 +14,7 @@ import testchipip.TileTraceIO case class SpikeCosimConfig( isa: String, + priv: String, pmpregions: Int, mem0_base: BigInt, mem0_size: BigInt, @@ -24,6 +25,7 @@ case class SpikeCosimConfig( class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map( "ISA" -> StringParam(cfg.isa), + "PRIV" -> StringParam(cfg.priv), "PMPREGIONS" -> IntParam(cfg.pmpregions), "MEM0_BASE" -> IntParam(cfg.mem0_base), "MEM0_SIZE" -> IntParam(cfg.mem0_size), diff --git a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala index 681b4cb2..ac50e52d 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala @@ -365,6 +365,7 @@ class WithCospike extends ComposeHarnessBinder({ val tiles = chipyardSystem.tiles val cfg = SpikeCosimConfig( isa = tiles.headOption.map(_.isaDTS).getOrElse(""), + priv = tiles.headOption.map(t => if (t.usingUser) "MSU" else if (t.usingSupervisor) "MS" else "M").getOrElse(""), mem0_base = p(ExtMem).map(_.master.base).getOrElse(BigInt(0)), mem0_size = p(ExtMem).map(_.master.size).getOrElse(BigInt(0)), pmpregions = tiles.headOption.map(_.tileParams.core.nPMPs).getOrElse(0), diff --git a/toolchains/riscv-tools/riscv-isa-sim b/toolchains/riscv-tools/riscv-isa-sim index 9a57a364..09a3c644 160000 --- a/toolchains/riscv-tools/riscv-isa-sim +++ b/toolchains/riscv-tools/riscv-isa-sim @@ -1 +1 @@ -Subproject commit 9a57a364ffbc5d13514e6f5569283c7cca2f40ff +Subproject commit 09a3c644d48337edadf16915448de7c6e9f1e91f