Author Topic: Learning clock domain transitions on FPGAs (Xilinx)  (Read 6083 times)

0 Members and 1 Guest are viewing this topic.

Offline KorkenTopic starter

  • Regular Contributor
  • *
  • Posts: 84
  • Country: se
Learning clock domain transitions on FPGAs (Xilinx)
« on: August 24, 2017, 08:18:53 am »
Hi all!

I have been testing how to transition a signal from one clock domain to another, and read a lot of different blogs on the matter.
So I decided to test a simple 2 flip flop synchronization in an Xilinx (Artix-7) FPGA, but I am not getting the expected result.

What I have done to test this is to have the input signal be in a 50 MHz domain (the system clock), and I have generated a 26 MHz domain (to not be a multiple of the input clock) in which I want the output signal.
But I get a Setup timing constraint violation from the Vivado tool that I do not understand why I am getting. As I understood the synchronization is there to solve exactly this problem.

I know that the input signal must be stable for more than 1 clock in the output clock domain, but for now I am only testing signals doing one transition (low -> high) - so there are no fast pulses.

This is my synchronization entity:
Code: [Select]
entity sync_2ff is

  port (
    clk_in  : in std_logic;
    clk_out : in std_logic;
    input   : in std_logic;
    output  : out std_logic
  );

end sync_2ff;


architecture Behavioral of sync_2ff is
  signal s_r1 : std_logic := '0';
  signal s_r2 : std_logic := '0';
  signal s_r3 : std_logic := '0';
begin

  -- Input register, in the input clock domain
  process (clk_in) is
  begin
    if rising_edge(clk_in) then
      s_r1 <= input;
    end if;
  end process;

  -- Output registers, synchronizing the signal
  process (clk_out) is
  begin
    if rising_edge(clk_out) then
      s_r2 <= s_r1; -- metastable
      s_r3 <= s_r2; -- stable
    end if;
  end process;

  -- Connect the output
  output <= s_r3;

end Behavioral;
Attached is an conceptual image over the design.

And I get a timing violation between s_r1 and s_r2, so when I am crossing the clock domains.

Could someone help a beginner in FPGAs, and help me get better insight? Thanks!
« Last Edit: August 24, 2017, 08:55:12 am by Korken »
 

Offline jefflieu

  • Contributor
  • Posts: 43
  • Country: au
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #1 on: August 24, 2017, 01:39:41 pm »
Hi,
The timing tool doesn't solve your timing problem, it just reports a that you WILL have problem transferring that signal from s_r1 to s_r2, and it is right, because you WILL violate setup/hold time of s_r2.
What you did there with the synchroniser is not to avoid that violation, but tolerate it. By having another stage, the output of s_r3 will be much less likely to get into metastable state, therefore, subsequent logic will not be affected by the VIOLATION at s_r2.
So in practice, people use:
- Double Flop Synchroniser
- Assign an attribute of "ASYNC" to the flop s_r2, s_r3
- And tell the timing tool that, this path is special (false path or use a different maximum delay rather than the timing relationship between the 2 clocks).
i love Melbourne
 

Offline fourtytwo42

  • Super Contributor
  • ***
  • Posts: 1185
  • Country: gb
  • Interested in all things green/ECO NOT political
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #2 on: August 24, 2017, 05:55:37 pm »
Yes another interesting point with HDL's is that compilers have been known to optimise out double flop synchronisers so make sure you label the intermediate signal and apply a keep to it  ;D
 

Offline marshallh

  • Supporter
  • ****
  • Posts: 1462
  • Country: us
    • retroactive
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #3 on: August 24, 2017, 08:09:37 pm »
You need to tell the timing analyzer that your 2 clock domains are separate and not mesosychnronous. You can set false paths or put them in separate clock groups (two ways to accomplish the same thing).
Verilog tips
BGA soldering intro

11:37 <@ktemkin> c4757p: marshall has transcended communications media
11:37 <@ktemkin> He speaks protocols directly.
 

Offline John_ITIC

  • Frequent Contributor
  • **
  • Posts: 514
  • Country: us
  • ITIC Protocol Analyzers
    • International Test Instruments Corporation
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #4 on: August 24, 2017, 09:02:08 pm »
In other words; the first FF in the synchronizer chain will have its setup time violated / unspecified. Setting a false path from the signal being synchronized to the first FF's D input will make the timing analyzer ignore this path for timing closure purposes. The first FF can (and will most likely) still go meta-stable but the meta-stable signal will not make its way through the second FF in the synchronizer chain.
Pocket-Sized USB 2.0 LS/FS/HS Protocol Analyzer Model 1480A with OTG decoding.
Pocket-sized PCI Express 1.1 Protocol Analyzer Model 2500A. 2.5 Gbps with x1, x2 and x4 lane widths.
https://www.internationaltestinstruments.com
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #5 on: August 24, 2017, 09:03:10 pm »
Obviously, it doesn't make any sense to do timing analysis between asynchronous clock domains, so you either use "set_false_path" in XDC to tell Vivado not to attempt this for your specific path, or you tell it that your clocks are asynchronous by using "set_clock_groups" (this is the same as using "set_false_path" many times at once). Otherwise Vivado assumes all the clocks are synchronus and analyzes all the paths.

https://www.xilinx.com/support/answers/44651.html


 

Offline KE5FX

  • Super Contributor
  • ***
  • Posts: 1891
  • Country: us
    • KE5FX.COM
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #6 on: August 24, 2017, 09:44:25 pm »
Quote from: Xilinx answer record above
Copy the clock names from the report_clocks command and paste them into the .xdc.
Then it is just a matter of formatting them into this command, and making sure all of the clock names are spelled correctly.

Be careful of the escape character at the end of each line.  If there is a space or tab after it, you will not see it, but the escape character will just escape that space or tab and not the end of line.   The next line will be considered a new, unrecognizable command and it will cause an error.

Any clocks not in this command are related to all clocks.  So, if you add another output called PLL2_c3 and forget to add it to this command, it will be related to all of the clocks.

<rant>
   Jeez, constraints are such a dumpster fire.  Somebody fix this, please.
</rant>
 

Offline KorkenTopic starter

  • Regular Contributor
  • *
  • Posts: 84
  • Country: se
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #7 on: August 28, 2017, 07:15:04 am »
Thank you all for the clarification! I finally understand why the timing is failing.

Though, it feels like a large design would really clutter the constraints file. Is this common?
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #8 on: August 28, 2017, 07:55:57 am »
Yes another interesting point with HDL's is that compilers have been known to optimise out double flop synchronisers so make sure you label the intermediate signal and apply a keep to it  ;D

For Xilinx best practice, you want to define the "ASYNC_REG" attribute. This will not only preserve the register, but also attempt to minimize the routing delays between the registers.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: kony

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #9 on: August 28, 2017, 03:32:09 pm »
Yes another interesting point with HDL's is that compilers have been known to optimise out double flop synchronisers so make sure you label the intermediate signal and apply a keep to it  ;D

For Xilinx best practice, you want to define the "ASYNC_REG" attribute. This will not only preserve the register, but also attempt to minimize the routing delays between the registers.

I guess "how" would be an obvious question.  I'll concede to not having much of a clue about constraints...
Same story with "keep" - I have no idea!

It is staggering how little I know about this stuff.  That anything works must have been a matter of luck!

 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #10 on: August 28, 2017, 04:34:51 pm »
It is staggering how little I know about this stuff.  That anything works must have been a matter of luck!

For pure single-click RTL design you don't need much. If you just specify the clock, and it'll do all the timing analysis automatically.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #11 on: August 28, 2017, 04:45:46 pm »
It is staggering how little I know about this stuff.  That anything works must have been a matter of luck!
For pure single-click RTL design you don't need much. If you just specify the clock, and it'll do all the timing analysis automatically.
Not entirely true. You will need to constrain the delay between the inputs to flipflops and the flipflops to outputs as well otherwise you can get funny behaviour as well.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #12 on: August 28, 2017, 06:26:11 pm »
It is staggering how little I know about this stuff.  That anything works must have been a matter of luck!

For pure single-click RTL design you don't need much. If you just specify the clock, and it'll do all the timing analysis automatically.

It was pretty easy to tell ISE to ignore timing checks on signals coming in on pads from external, asynchronous sources.  Haven't tumbled to that with Vivado but, apparently, I haven't needed to.  My total experience with Vivado is really just the last few days implementing that LC3 project.  So far, it works well as does the project.  It's been interesting...

I am just about ready to concede that I like Vivado better than ISE.  Just about...
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #13 on: August 28, 2017, 06:38:39 pm »
LC3 project

Why do you need the special constraint for it?

it shouldn't been required since there is only one clock: the main clock, attached to external crystal.
You might want to use the DCM.PLL in order to triplicate it to handle external SRAM, but again ... there is just one source of synchronization.

p.s.
anyway, how do you handle it on ISE?
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #14 on: August 28, 2017, 06:58:32 pm »
LC3 project

Why do you need the special constraint for it?

it shouldn't been required since there is only one clock: the main clock, attached to external crystal.
You might want to use the DCM.PLL in order to triplicate it to handle external SRAM, but again ... there is just one source of synchronization.

p.s.
anyway, how do you handle it on ISE?

I was thinking more generally about the constraints file rather than specific timing issues.  All I have in the .xdc file is the pinout, clock definition and perhaps some ILA signals.

With ISE, I just added 'TIG' to the Net line in the UCF file:

NET "Switches<0>"  LOC = "G18" | TIG;

No need to analyze timing from an external toggle switch.  It will get debounced  and synchronized in a dual FF circuit.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #15 on: August 28, 2017, 07:34:22 pm »
( I said "triplicate the frequency" because I was thinking about the Papilio/Pro board: it comes with a crystal of 33Mhz, the SRAM need to be clocked at 99Mhz. The DCM.PLL should supply the 3X! )


 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #16 on: August 28, 2017, 08:02:15 pm »
( I said "triplicate the frequency" because I was thinking about the Papilio/Pro board: it comes with a crystal of 33Mhz, the SRAM need to be clocked at 99Mhz. The DCM.PLL should supply the 3X! )

Right, the timing generator IP takes care of this for Microblaze projects.  It's a pretty nice feature considering it is free.

My ISE interest was strictly in getting rid of the annoying warnings about timing analysis, thus the TIG.

Yes, the entire purpose of the DCMs is to keep things synchronized.  I used the DCM on a couple of projects but I don't recall the circumstances.  In any event, everything worked out.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #17 on: August 28, 2017, 09:11:33 pm »
Yes another interesting point with HDL's is that compilers have been known to optimise out double flop synchronisers so make sure you label the intermediate signal and apply a keep to it  ;D

For Xilinx best practice, you want to define the "ASYNC_REG" attribute. This will not only preserve the register, but also attempt to minimize the routing delays between the registers.

I guess "how" would be an obvious question.


Here's how I would do it (in VHDL):

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity synchronizer is
    generic ( stages : natural := 3 );
    Port ( clk : in STD_LOGIC;
           i : in STD_LOGIC;
           o : out STD_LOGIC);
end synchronizer;

architecture Behavioral of synchronizer is
    signal flipflops : std_logic_vector(stages-1 downto 0):= (others => '0');
    attribute ASYNC_REG : string;
    attribute ASYNC_REG of flipflops: signal is "true";
begin

    o <= flipflops(flipflops'high);

clk_proc: process(clk)
    begin
        if rising_edge(clk) then
            flipflops <= flipflops(flipflops'high-1 downto 0) & i;
        end if;
    end process;

end Behavioral;

Here's what the documentation says about ASYNC_REG:
Quote
Specifying ASYNC_REG also affects optimization, placement, and routing to improve Mean Time Between Failure (MTBF) for registers that may go metastable. If ASYNC_REG is applied, the placer will ensure the flip-flops on a synchronization chain are placed closely to maximize MTBF. Registers with ASYNC_REG that are directly connected will be grouped and placed together into a single SLICE, assuming they have a compatible control set and the number of registers does not exceed the available resources of the SLICE.
« Last Edit: August 28, 2017, 09:14:18 pm by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Learning clock domain transitions on FPGAs (Xilinx)
« Reply #18 on: August 28, 2017, 10:31:37 pm »

Here's how I would do it (in VHDL):


Very nice, thanks!

Elsewhere, I believe you posted code to read a hex file and initialize RAM - thanks for that as well!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf