UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer matthuszagh
Observer
514 Views
Registered: ‎07-16-2018

BUG REPORT: synchronization between PLL derived clock and base clock -- timing of synchronous assignments

I noticed something unusual when simulating a design that uses a Xilinx PLL (simulated with unisims). Here's a minimal example that demonstrates the effect:

 

`default_nettype none

`include "PLLE2_BASE.v"
`include "PLLE2_ADV.v"
`include "glbl.v"

`timescale 1ns/1ps
module top;

   reg base_clk = 0;
   reg fst_clk = 0;
   wire clk_fb;
   wire pll_lock;
   wire clk_100mhz;

   PLLE2_BASE #(
      .CLKFBOUT_MULT  (24),
      .DIVCLK_DIVIDE  (1),
      .CLKOUT0_DIVIDE (8),
      .CLKIN1_PERIOD  (30)
   ) PLLE2_BASE_120mhz (
      .CLKOUT0  (clk_100mhz),
      .LOCKED   (pll_lock),
      .CLKIN1   (base_clk),
      .RST      (1'b0),
      .CLKFBOUT (clk_fb),
      .CLKFBIN  (clk_fb)
   );

   reg cond = 1'b0;
   reg some_reg = 1'b0;
   reg other_reg = 1'b0;

   always #15 base_clk = !base_clk;
   always #5 fst_clk = !fst_clk;

   initial begin
      $dumpfile("top.vcd");
      $dumpvars(0, top);
      #10000 $finish;
   end

   always @(posedge base_clk) begin
      if (pll_lock)
        cond <= 1'b1;
   end

   always @(posedge fst_clk) begin
      if (pll_lock)
        if (cond)
          some_reg <= 1'b1;
   end

   always @(posedge clk_100mhz) begin
      if (cond)
        other_reg <= 1'b1;
   end

endmodule

And here's a screenshot of the corresponding waveform:

clocks.png

The interesting part is from 2775ns to 2785ns. I've got 3 clocks here: (1) the base clock, (2) a clock that is 3 times faster generated with an always delay, and (3) a PLL derived clock from the base clock with the same frequency and phase shift as the 2nd clock. Why does other_reg register the new value at 2775ns instead of at 2785ns like some_reg? Since base_clk and clk_100mhz are fully synchronous (right?) shouldn't other_reg see a 0 at it's input? Have I triggered a race condition somehow or otherwise misused the simulation? How would this behave in actual hardware?

Tags (2)
0 Kudos
4 Replies
Xilinx Employee
Xilinx Employee
301 Views
Registered: ‎07-16-2008

回复: BUG REPORT: synchronization between PLL derived clock and base clock -- timing of synchronous assignments

Yes, it looks a race condition issue. 

I'd suggest that you don't change 'cond' at the same time as rising_edge clk.

-------------------------------------------------------------------------
Don't forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Observer matthuszagh
Observer
287 Views
Registered: ‎07-16-2018

回复: BUG REPORT: synchronization between PLL derived clock and base clock -- timing of synchronous assignments

Thanks for the reply @graces . Would you mind explaining why this is a race condition? Since the PLL is locked with the base clock, the edges should occur simultaneously (or at least the timing difference would be much less than the propagation delay of a register). So, I don't see how there's any worry that cond violates the hold timing requirement of other_reg. In any event, I thought this was the main point of using a PLL. Or, is it the case that PLL locking doesn't really provide any guarantee of synchronization? By the way, I've asked a related question here (albeit in general terms, not Xilinx-specific) and people seem to echo my thinking that this shouldn't create a race condition. Thanks.

0 Kudos
Observer matthuszagh
Observer
249 Views
Registered: ‎07-16-2018

回复: BUG REPORT: synchronization between PLL derived clock and base clock -- timing of synchronous assignments

Another thing: if it truly were a race condition wouldn't the simulator decide the outcome based on if cond changed before the clock edge? However, this is not the case: if you run that simulation and zoom in on the clock edge, cond and the clock edge occur at the exact same picosecond (the simulation has picosecond resolution). I belive nonblocking assignments all have to occur at the same time unit (correct?). In which case this shouldn't be reading the new value of cond. Maybe the PLL simulation file uses blocking and non-blocking assignments incorrectly?

0 Kudos
Xilinx Employee
Xilinx Employee
227 Views
Registered: ‎07-16-2008

回复: BUG REPORT: synchronization between PLL derived clock and base clock -- timing of synchronous assignments

When you change data and clock at the same time, event based simulators may schedule delta events differently, which may result in unexpected result. This is typically seen in behavioral simulation.

You may take a look at UG900, pg228, section "Race Conditions and Delta Cycles".

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_1/ug900-vivado-logic-simulation.pdf

 

You should also be able to find quite a few resources online if you search the topic. In Modelsim, you can view the delta events in List window. 

-------------------------------------------------------------------------
Don't forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos