I'm currently working on a Verilog implementation of the CHIP-8 console, would like to implement a RISC-V softcore next. I'm still a bit green with hardware design and HDLs, coming from the software development world. I've developed the emulators for these architectures in C beforehand to get more familiar, but the HDL is of course a completely different territory.
So far I've been testing the opcodes in a crude way - generating a RAM with the program binary loaded at a correct address, executing several instructions and then looking at the waveform from simulation, spending some mental energy to assert whether the state is correct after various clock cycles.
I suppose this really doesn't scale well, so:
How does one test (and debug) the design in a reasonable way?
When working on a software emulator, I was able to use a battery of tests (handwritten or assembled to binary) that followed a certain structure - for example set up a special register to mark a success or a failure state and a invoke a system call opcode to state that the test is finished. However, as these tests relied on several fundamental instructions (branching, storing a value into a register, syscall), I needed a way to make sure these work first.
To assert that the fundamental instructions work correctly I loaded a tiny test binary directly in the test suite, and peeked into the CPU/memory internals within the software-based emulator after the instruction executed to validate the resulting internal state.
Does this kind of approach translate to hardware as well?
I suppose I could write a script that would generate a testbench per each test case, that would load the program binary into the RAM, reset the CPU, run the clock until we get the special call, then use Verilog assertions on the final state of the "result register". This way I would end up with a bunch of testbenches that I could then run in sequence with Modelsim or Icarus Verilog.
Is there a better way of testing soft CPUs?
Aucun commentaire:
Enregistrer un commentaire