When you run a Post-PAR (Timing Simulation) of a Synchronous Counter, you might observe some glitches in the form of unwanted states between two expected states.
This is more visible when seen under a timescale of ps.
Refer to the time 123791 ps.
You can see that after 0001 the expected state is 0010 but an unexpected state 0011 exists for a period of 28 ps.
This behavior is visible only in Timing Simulation.
Behavioral simulation runs fine.
This article explains this behavior.
This is a 4 bit counter design created using core generator and has been instantiated in a small design.
The design is getting its required clock stimulus from a top level testbench.
Attached is the sample project.
For this discussion we are focusing on output bit q  for reference.
Other 3 bits follow the same pattern.
Refer to the waveform below:
Here, the output q  is driven by an OBUF (q0_OBUF) which gets its input from a BUF.
This BUF is connected to a flip-flop (FF) which in turn is driven by the output of CARRY4.
Refer to 119.513 ns.
The output of the FF (o port of q0_FF) goes to 0.
As this is passed to the output port via a BUF and OBUF, you can see that this output goes 0 at time 123.826 ns which is q .
Refer to q0_BUF (o port) and q0_OBUF (o port).
The expected output appears at the OBUF's output after some delays.
This is aligned to model actual hardware delays.
Now, for this reason, if you zoom to around 123.826 ns you can see that for a small period of time the value of q  stays at 1 (refer to the waveform below).
The same behavior can be explained in this way for the rest of the 3 output bits.
These delays are pulled from the SDF file and emulate the typical hardware delays.
The SDF is generated by NetGen which gets the delays from the routed .ncd file.
As a result, this is not a bug or fault in design but reflects the timing delays which might get incurred in the real hardware.
1. As its a synchronous circuit we are more concerned with the values at the rising edge of the clock.
In this case we are getting the correct counter values. (refer to the waveform below)
2. Run Static Timing Analysis and look for timing violations to be sure that it would work without issues on hardware.
Note: The same behavior can also be observed with an Inferred counter code.