Why does iSim give a different result than hardware

simulationspartanverilog

I am working on a MIPS CPU for an FPGA – this is mostly a personal project to understand FPGA's.

I have a 5 stage pipeline CPU implementation working correctly when run on iSim, however when I run it directly on the hardware (Spartan 6) I get a different result.

The test program I have is simple:

load 0x128 into reg[1]   
nop*
load 0x160 into reg[2]
nop*
add reg[1] to reg[2]
assert "finished" flag

when I run this in iSim, I get the correct result in reg[2] (0x288) however, when I run the program on the FPGA I get the result 0x3b0 – it appears that the final instruction is running multiple tiems

The nop instructions are present to force a cache miss during execution, and this is what causes the problem – without these the result is correct.

What I think is happening is that I assert a "stall" flag at the positive edge of the clock cycle – and something else that runs at the positive edge relies on the presence/absence of this flag. iSim by chance runs correctly (due to the arbitrary order in which it executes the simulation of always blocks) however the FPGA fails as the stall change is not available until the negative edge.

I have already scoured my verilog implementation to find where this is – and am still looking. My question is: how can I force iSim to expose this error?

Best Answer

The issue was caused by RAMB16WER reading data on the positive edge. My fetch code was changing these signals on the positive edge too. Moving this code to the negative always block fixed it.

Its odd that it worked up to a certain point on the device, and that it worked fully on iSim, but I guess this is due to the way iSim executes the always blocks.