New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simulated project deviates from real device behavior #668
Comments
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. |
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.
I have simplified the project and created a simplified serial controller with a FSM that is able to reproduce the issue. (Example can be found in the attachment along with examples of the two issues)
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
Data
state into theIdle
state, thus failing to make it ready for receiving a second transfer. However in simulation despite the needed and missing extra clock cycle the simulation says it will come toIdle
state at the end of transfer, whenserialCSn
signal goes high/inactive. This simulation result is generated when the signals between the modules are set like so:The result can be seen here:
that is, the serial clock is generated only when
serialCSn
when signal is low/active and an extra clock cycle is generated by theserialCSn
signal itself. Here thesimpleFSMClient2.simpleFSM.fsmState != 0
condition is not required in reality, but only for simulation, because serialCSn starts low by default, despite the simulation process setting it high as early as it can. The condition ensures that the extra cycle is only generated when the FSM machine has its current state set to a nonIdle
state.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
Data
state, thus failing the second transfer. This simulation result is caused when the followingserialCSn
signal assignment is used:as depicted here:
In summary:
serialCSn
is assigned with:serialCSn
is assigned with:Data
state at the end of the first transferIdle
state at the end of the first transferSimpleFSM.txt
SimpleFSMClient1.txt
SimpleFSMClient2.txt
The text was updated successfully, but these errors were encountered: