C
Carl
Guest
Hi,
This question deals both with an actual problem, and with some more conceptual thoughts on simulation deltas and how an RTL entity should behave with regards to this.
This post regards the case of a simulation with ideal time - that is, no delays (in time) modelled, rather trusting only simulation deltas for the ordering of events.
*Conceptual*
I would argue that for a well-behaved synchronous RTL entity, the following must be true:
*All readings of the input ports must be made *on* the delta of the rising flank of the clock - not one or any other number of deltas after that.*
Would people agree on that?
It follows from the possibility of other logic, hierarchically above the entity in question, altering the input ports as little as one delta after the rising flank. That must be allowed.
*My actual problem*
After a lot of debugging of one of my simulations, I found a Xilinx simulation primitive (IDELAYE2 in Unisim) *not* adhering to the statement in the previous section, which had caused all the problems.
See the signals plotted here:
http://www.fpga-dev.com/misc/deltaDelayProblem.png
It's enough to focus on the "ports" section. The ports are:
- c: in, the clock
- cntValueIn: in
- ld: in, writeEnable for writing cntValueIn to an internal register
- cntValueOut: out, giving the contents of that register
As can be seen, my 'ld' operation is de-asserted one delta after the rising flank. I argue this should be OK, but it is obvious that the data is never written (cntValueOut remains 0). If I delay the de-assertion of 'ld' just one more delta, the write *does* take effect as desired.
I would argue this is a (serious) flaw of the Xilinx primitive. Would people agree on that as well?
(The following is not central for the above discussion, may be skipped.)
I have checked the actual reason for the problem. See the "internals" section of the signals. First, Xilinx delays both the clock and the ports to the *_dly signals. Fully OK, if from now on operating on the delayed signals. The problem is that the process writing to the internal register is not clocked by c_dly, but by another signal, c_in, which is delayed *one more* delta. This causes my requested 'ld' to be missed. (c_in is driven from c_dly in another process, inverting the the clock input if the user has requested that.)
I argue that synchronous entities must be modelled in such a way that all processes reading input ports *must* be clocked directly by the input clock port - not by some derived signal that is lagging (if only by one delta). If this is not possible, the input ports being read must be delayed accordingly. In this case, if Xilinx wishes to conditionally invert the clock like this, causing another delta of delay, the input ports must also be delayed the corresponding number of deltas.
Cheers,
Carl
This question deals both with an actual problem, and with some more conceptual thoughts on simulation deltas and how an RTL entity should behave with regards to this.
This post regards the case of a simulation with ideal time - that is, no delays (in time) modelled, rather trusting only simulation deltas for the ordering of events.
*Conceptual*
I would argue that for a well-behaved synchronous RTL entity, the following must be true:
*All readings of the input ports must be made *on* the delta of the rising flank of the clock - not one or any other number of deltas after that.*
Would people agree on that?
It follows from the possibility of other logic, hierarchically above the entity in question, altering the input ports as little as one delta after the rising flank. That must be allowed.
*My actual problem*
After a lot of debugging of one of my simulations, I found a Xilinx simulation primitive (IDELAYE2 in Unisim) *not* adhering to the statement in the previous section, which had caused all the problems.
See the signals plotted here:
http://www.fpga-dev.com/misc/deltaDelayProblem.png
It's enough to focus on the "ports" section. The ports are:
- c: in, the clock
- cntValueIn: in
- ld: in, writeEnable for writing cntValueIn to an internal register
- cntValueOut: out, giving the contents of that register
As can be seen, my 'ld' operation is de-asserted one delta after the rising flank. I argue this should be OK, but it is obvious that the data is never written (cntValueOut remains 0). If I delay the de-assertion of 'ld' just one more delta, the write *does* take effect as desired.
I would argue this is a (serious) flaw of the Xilinx primitive. Would people agree on that as well?
(The following is not central for the above discussion, may be skipped.)
I have checked the actual reason for the problem. See the "internals" section of the signals. First, Xilinx delays both the clock and the ports to the *_dly signals. Fully OK, if from now on operating on the delayed signals. The problem is that the process writing to the internal register is not clocked by c_dly, but by another signal, c_in, which is delayed *one more* delta. This causes my requested 'ld' to be missed. (c_in is driven from c_dly in another process, inverting the the clock input if the user has requested that.)
I argue that synchronous entities must be modelled in such a way that all processes reading input ports *must* be clocked directly by the input clock port - not by some derived signal that is lagging (if only by one delta). If this is not possible, the input ports being read must be delayed accordingly. In this case, if Xilinx wishes to conditionally invert the clock like this, causing another delta of delay, the input ports must also be delayed the corresponding number of deltas.
Cheers,
Carl