cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
275 Views
Registered: ‎02-02-2020

Setting timing constraints for input and output delay, simulation mismatch and wrong clock behavior

Hello everyone,

I'm implementing a hashing algorithm in Verilog using Vivado 2019.2.1. Everything (including synthesis and implementation) worked quite well but I noticed recently that the results of the behavioral simulation (correct hash digest) differs from the post-synthesis/-implementation functional and timing simulation, i.e. I receive three different values for the same circuit design/code.

My base configuration contained a testbench using the default `timescale 1ns / 1ps and a #1 delay for toggling the clock register. I further constrained the clock to a frequency of 10 MHz using an xdc file. During synthesis, no errors (or even warnings, except some "parameter XYZ is used before its declaration") are shown and no non-blocking and blocking assignments are mixed inside my code. Nevertheless, I noticed that the post-* simulation (no matter if functional or timing) needs more clock cycles (e.g. 58 instead of 50 until the value of a specific register was toggled) for achieving the same state of the circuit. My design is entirely synchronous and driven by one clock.

This brought me to the Timing Report and I noticed that 10 input and 10 output delays are not constrained. In addition, the Design Timing Summary shows a `worst negative slack` for setup that is very close to the time of one clock cycle. I tried some combinations of input and output delays following the Vivado documentation and tutorial videos but I'm not sure how to find out which values are suitable. The total slack (TNS, THS and TPWS) is zero.

Furthermore, I tried to reduce the clock frequency because the propagation delay of some signals that control logic in the FSM (= top) module might be too large. The strange thing that happened then is that the simulation never reached the $finish; in my testbench and nothing except the clock register changed its value in the waveform. In the behavioral simulation everything works as expected but this doesn't seem to be influenced by constraints or even timing. Monitoring the o_round_done wire (determined by an LFSR in a separate submodule) in my testbench, I noticed that for the behavioral simulation the value of this wire changes with the clock whereas for the post-* simulations the value is changed with a small delay:

Behavioral Simulation

clock cycles: 481, round_done: 0
clock cycles: 482, round_done: 1
clock cycles: 483, round_done: 0

total of 1866 clock cycles

Post-Implementation Functional Simulation

clock cycles: 482, round_done: 0
clock cycles: 482, round_done: 1
clock cycles: 483, round_done: 1
clock cycles: 483, round_done: 0

total of 1914 clock cycles

Post-Implementation Timing Simulation

WARNING: "C:\Xilinx\Vivado\2019.2\data/verilog/src/unisims/BUFG.v" Line 57: Timing violation in scope /tb/fsm/i_clk_IBUF_BUFG_inst/TChk57_10300 at time 997845 ps $period (posedge I,(0:0:0),notifier)
WARNING: "C:\Xilinx\Vivado\2019.2\data/verilog/src/unisims/BUFG.v" Line 56: Timing violation in scope /tb/fsm/i_clk_IBUF_BUFG_inst/TChk56_10299 at time 998845 ps $period (negedge I,(0:0:0),notifier)

simulation never stops (probably because round_done is never 1)

Do you know what I'm doing wrong here? I'm wondering why the circuit is not behaving correctly at very low clock frequencies (e.g. 500 kHz) as, to my knowledge, this will provide enough time for each signal to "travel" to the correct destination.

Another thing I noticed is that one wire that is assigned to a register in a submodule is 8'bXX in the behavioral simulation until the connected register is "filled" but in the post-* simulations it is 8'b00 from the beginning. Any idea here?

Moreover, what is actually defining the clock frequency for the simulations? The values in the testbench (timescale and delay #) or the constraint in the xdc file?

Thanks in advance!

Regards,

laundy

Design Timing Summary_10 MHz.png
0 Kudos
3 Replies
Highlighted
Moderator
Moderator
212 Views
Registered: ‎03-16-2017

@laundy 

Multiple queries in one thread. 

Since you have mentioned that the behavioural simulation is working fine and post-synthesis functional simulation shows a functional discrepancy. 

So, for the first point of debug here is we need to check that if synthesis engine is causing any misbehaviour here or not. And to check that we need to do a test with Onespin to find the equivalency of the code with the synthesized netlist. And for that can you share your source code with us? 

If yes, then i can arrange a secured ftp ezmove for you through which you can provide it. 

Regards,
hemangd

Don't forget to give kudos and mark it as accepted solution if your issue gets resolved.
Highlighted
Voyager
Voyager
201 Views
Registered: ‎06-20-2012

@laundy 

"Moreover, what is actually defining the clock frequency for the simulations?".

The concept of clock frequency does not exist for a simulator.
The RTL simulator is event driven and changes the clock signal each time it changes on the testbench.

== If this was helpful, please feel free to give Kudos, and close if it answers your question ==
Highlighted
Visitor
Visitor
162 Views
Registered: ‎02-02-2020


@calibra wrote:

@laundy 

"Moreover, what is actually defining the clock frequency for the simulations?".

The concept of clock frequency does not exist for a simulator.
The RTL simulator is event driven and changes the clock signal each time it changes on the testbench.


Got this, but I'm getting different switching activity for different delays on the clock `always` block.

@hemangdI fear that I can't share my whole code, but I finally managed to get the post-* functional simulations to work! Strangely, the reset FSM state lasts exactly 25 clock cycles no matter of the clock frequency in the post-* functional simulations instead of 1 in the behavioral simulation. My testbench is just doing this:

initial begin
    clk = 1'b0;
    rst = 1'b0;
    @(posedge clk);
    @(posedge clk) rst = 1'b1;    
    @(posedge clk) rst = 1'b0;
end

This triggers a reset on my FSM (i.e. it initializes to the `FSM_RESET` state:

always @(posedge i_clk) begin
    if(i_rst) begin
        fsm_state <= FSM_RESET;
    end else begin
        fsm_state <= fsm_state;
    end
end

The reset state only resets three registers to all zero and one a two-digit decimal number, so there is not much going on in this FSM state.

Is solved it by letting the testbench wait for the FSM to be in the next state, i.e. completed reset which took always 25 clock cycles. Do you have any ideas why this reset takes so long?

However, the post-* timing simulation is outputting completely different values but the design meets all timing constraints.

0 Kudos