DiffTest (差分测试): a modern co-simulation framework for RISC-V processors.
DiffTest interfaces are provided in Chisel bundles and expected to be integrated into Chisel designs with auto-generated C++ interfaces. However, we also provide examples of the generated Verilog modules.
make difftest_verilog NOOP_HOME=$(pwd)
- Add this submodule to your design.
In Git .gitmodules
:
[submodule "difftest"]
path = difftest
url = https://github.com/OpenXiangShan/difftest.git
In Mill build.sc
:
object difftestDep extends difftest.build.CommonDiffTest with PublishModule {
override def millSourcePath = os.pwd / "difftest"
override def pomSettings = T {
your_design.pomSettings()
}
override def publishVersion = T {
your_design.publishVersion()
}
}
In Makefile
:
emu: sim-verilog
@$(MAKE) -C difftest emu WITH_CHISELDB=0 WITH_CONSTANTIN=0
- Add difftest modules (in Chisel or Verilog) to your design.
import difftest._
val difftest = DifftestModule(new DiffInstrCommit, delay = 1, dontCare = true)
difftest.clock := clock
difftest.coreid := 0.U
difftest.index := 0.U
difftest.valid := io.in.valid
difftest.pc := SignExt(io.in.bits.decode.cf.pc, AddrBits)
difftest.instr := io.in.bits.decode.cf.instr
difftest.skip := io.in.bits.isMMIO
difftest.isRVC := io.in.bits.decode.cf.instr(1, 0)=/="b11".U
difftest.rfwen := io.wb.rfWen && io.wb.rfDest =/= 0.U
difftest.wdest := io.wb.rfDest
difftest.wpdest := io.wb.rfDest
-
Generate verilog files for simulation.
-
make emu
and start simulating & debugging!
We provide example designs, including:
Currently we are supporting the RISC-V base ISA as well as some extensions, including Float/Double, Debug, and Vector. We also support checking the cache coherence via RefillTest.
Probe Name | Descriptions | Mandatory |
---|---|---|
DiffArchEvent |
Exceptions and interrupts | Yes |
DiffInstrCommit |
Executed instructions | Yes |
DiffTrapEvent |
Simulation environment call | Yes |
DiffArchIntRegState |
General-purpose registers | Yes |
DiffArchFpRegState |
Floating-point registers | No |
DiffArchVecRegState |
Floating-point registers | No |
DiffCSRState |
Control and status registers | Yes |
DiffVecCSRState |
Control and status registers | No |
DiffDebugMode |
Debug mode registers | No |
DiffIntWriteback |
General-purpose writeback operations | No |
DiffFpWriteback |
Floating-point writeback operations | No |
DiffArchIntDelayedUpdate |
Delayed general-purpose writeback | No |
DiffArchFpDelayedUpdate |
Delayed floating-point writeback | No |
DiffStoreEvent |
Store operations | No |
DiffSbufferEvent |
Store buffer operations | No |
DiffLoadEvent |
Load operations | No |
DiffAtomicEvent |
Atomic operations | No |
DiffL1TLBEvent |
L1 TLB operations | No |
DiffL2TLBEvent |
L2 TLB operations | No |
DiffRefillEvent |
Cache refill operations | No |
DiffLrScEvent |
Executed LR/SC instructions | No |
The DiffTest framework comes with a simulation framework with some top-level IOs.
LogCtrlIO
PerfInfoIO
UARTIO
For compatibility on different platforms, the CPU should access a C++ memory via DPI-C interfaces. This memory will be initialized in C++.
val mem = DifftestMem(memByte, 8)
when (wen) {
mem.write(
addr = wIdx,
data = in.w.bits.data.asTypeOf(Vec(DataBytes, UInt(8.W))),
mask = in.w.bits.strb.asBools
)
}
val rdata = mem.readAndHold(rIdx, ren).asUInt
To use DiffTest, please include all necessary modules and top-level IOs in your design. It's worth noting the Chisel Bundles may have arguments with default values. Please set the correct parameters for the interfaces.