Simulated project deviates from real device behavior #668
When I was implementing a slave Quad SPI controller with amaranth I found two cases, one where the simulation indicates that the device will work, but in reality it does not, and another where in simulation it indicates that device will not work, but in reality it works.
that is, the serial clock signal is only generated during the data transmission, when the CSn (negated Chip Select) signal is active. In this case, in reality, the FSM misses one extra clock cycle to come out of the FSM
that is, the serial clock is generated only when
This scenario was tested with a Xilinx XC7S15 (Spartan-7) and is working properly in the device. The simulation however indicates that the FSM machine will get stuck in the
The text was updated successfully, but these errors were encountered:
In general, you should not generate clocks using logic; such clocks aren't guaranteed to work either in simulation (due to simulation semantics not being defined for such clocks) or in synthesis (due to LUTs not being glitchless on most FPGAs). See also #625.
Thanks for your reply. Still I have two additional questions and comment...
According to Peter Alfke of Xilinx Applications in this post: https://groups.google.com/g/comp.arch.fpga/c/F6AYhYzDmi0?pli=1
Function Generator Avoids Glitches
This still applies today."
Comment: According to the above there should be no glitch at least in the LUT output for the case where the clock signal is ANDed or ORed with the CSn signal, since they aren't simultaneously changing in reality. In the SPI protocol the SPI clock must be stable before CSn goes low or high.
So there are no glitches in reality,
Question 1: Given this limitation how does one simulate a clock signal that isn't always active? Like the SPI clock? In this case, this is only required for the simulation case, because in real applications there would be no need to add logic to the clock signal, since the clock is already generated that way.
Question 2: If I understand correctly the Amaranth FSM does not allow asynchronous reset. How could I insert an asynchronous reset to the FSM? Or should I emulate a FSM with a switch statement that would allow asynchronously resetting to the initial state? This could provide a workaround for part of the simulation.
This doesn't match my understanding of the current technology. That said, I will make no strong claims here--I haven't put in nearly enough time researching this issue to do so. In any case, that's the less important part.
Amaranth, and the FPGA-specific toolchain it feeds input to, generally make no guarantees about the synthesis results. It's certainly possible to translate logic to glitchless LUTs, but none of the components specifically attempt to do so. It may happen that the LUTs generated for your logic are glitchless for any particular input and toolchain versions, but I wouldn't recommend relying on that, since it's not a part of the toolchain contract.
You could, of course, instantiate the LUTs directly (with the
I suggest using a simulator process to generate the clock.
An Amaranth FSM can be placed in a clock domain with asynchronous reset. This is the same as any other logic; other than instantiating primitives directly, you can't get a register with an asynchronous reset either.
Thanks for your reply.
I was indeed able to simulate the dummy protocol by generating the clock signal using a simulator process that also exhibits the behavior of the combinatorial logic that has to be inserted in the real device. The simulation results with the clock generated this way are indeed consistent. This solution can be found in the attached SimpleFSMSolution1.zip
The other alternate way for achieving consistent simulation results was to also generate the clock using a simulator process and enabling asynchronous reset for clock domain to which the FSM is attached. This solution can be found in the attached SimpleFSMSolution2.zip
Both solutions work properly and simulate properly. From my side this issue is now clarified and can be closed.