Author Topic: [FPGA][Verilog] How to detect synchronized edges of two different signals?  (Read 4422 times)

0 Members and 2 Guests are viewing this topic.

Offline gauravmpTopic starter

  • Regular Contributor
  • *
  • Posts: 77
  • Country: us
Hi,

I'm working on a Xilinx FPGA design in Verilog and I'm working with multiple clocks. I'm using a 105MHz clock and a 100MHz clock generated by a PLL, so both of the signals are phase synchronized and they rise at the same time every 20 cycles for the 100MHz clock and every 21 cycles for the 105MHz clock. My goal is to have a pulse be generated (based either on the 100MHz or 105MHz clock) when this golden event happens.

In an ideal world, I would have loved to use the PLL to also generate a 5MHz clock which would essentially rise at the same time that these two signals rise thus eliminating my need to post this question. However, Xilinx's PLLs (at least for this device - Zynq7000) are only capable of giving clock outputs >8.125MHz. Hence, I decided to use a 10MHz clock and have a clock divider give me a 5MHz clock. However, the problem now is, this divided 5MHz can rise in two different scenarios only one of which would be synchronized with the rising of the 100MHz and the 105MHz.

Can anyone tell me a way to do it so I can have this 5MHz clock rise only at the time when 100MHz and 105MHz clocks rise and not at the other case?

Thanks
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #1 on: November 07, 2016, 06:59:52 am »
What are you using the three clocks for? What sort of data flows are needed between the three domains?

Can you not use a fifo?  Or use a handshake to safely pass values regardless of phase?
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 obiwanjacobi

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: nl
  • What's this yippee-yayoh pin you talk about!?
    • Marctronix Blog
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #2 on: November 07, 2016, 09:43:37 am »
I must admit I don't fully understand your problem but my first thought was divide the 100Mhz clock by 20...? (count to 10 and then toggle a FF to get 50% duty?)    :-//
Arduino Template Library | Zalt Z80 Computer
Wrong code should not compile!
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #3 on: November 07, 2016, 10:36:07 am »
Oh, and if you look on page 37 of https://www.xilinx.com/support/documentation/data_sheets/ds181_Artix_7_Data_Sheet.pdf, you will find that the MMCM can go down to 4.69 MHz - maybe that will help.

I've tried a few numbers, but it looks like you want a VCO frequency of 1050, so you can divide by 10.5 or 10 to generate 100MHz and 105MHz, but you can't divide by the 210 needed to generate the 5Mhz signal - it is limited to a maximum divide value of 128
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 AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #4 on: November 07, 2016, 11:08:39 am »
I'd start by dividing the 100 MHz clock by 20 (or 105 Mhz by 21) and generate a pulse which is regular, but not actually related to the other clock.

Beyond that, you need to consider very carefully what you mean by the clock edges being synchronised. In a perfect world, and perhaps in a simulator, it might indeed be possible for two edges to occur at precisely the same time, but in any real device there will be skew. The nominally "coincident" edges won't be; one will occur slightly before the other, and this skew can and will vary with temperature and between devices.

With this in mind, the idea of the two clocks actually being coincident is a bit nonsensical. They won't ever coincide, though there will be times at which the delta between an edge on one clock and an edge on the other it at a local minumum.

If you're lucky, and both are derived from the same VCO, then maybe both VCO dividers will initialise to zero at the same time. If your own divide-by-20 (or divide-by-21) logic starts its own counter from zero, then it'll start synchronised and remain that way.

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4427
  • Country: dk
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #5 on: November 07, 2016, 11:33:38 am »
Hi,

I'm working on a Xilinx FPGA design in Verilog and I'm working with multiple clocks. I'm using a 105MHz clock and a 100MHz clock generated by a PLL, so both of the signals are phase synchronized and they rise at the same time every 20 cycles for the 100MHz clock and every 21 cycles for the 105MHz clock. My goal is to have a pulse be generated (based either on the 100MHz or 105MHz clock) when this golden event happens.

In an ideal world, I would have loved to use the PLL to also generate a 5MHz clock which would essentially rise at the same time that these two signals rise thus eliminating my need to post this question. However, Xilinx's PLLs (at least for this device - Zynq7000) are only capable of giving clock outputs >8.125MHz. Hence, I decided to use a 10MHz clock and have a clock divider give me a 5MHz clock. However, the problem now is, this divided 5MHz can rise in two different scenarios only one of which would be synchronized with the rising of the 100MHz and the 105MHz.

Can anyone tell me a way to do it so I can have this 5MHz clock rise only at the time when 100MHz and 105MHz clocks rise and not at the other case?

Thanks


afaict any 100MHz/20 is as good as is gets, there will always be skew between the clocks so you have to handle that no matter if it is close
to zero
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #6 on: November 07, 2016, 12:14:25 pm »
You may find this document and concept interesting:

https://www.febo.com/pipermail/time-nuts/attachments/20071201/e7833af5/attachment.pdf

See page 7 onwards.
 

Offline gauravmpTopic starter

  • Regular Contributor
  • *
  • Posts: 77
  • Country: us
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #7 on: November 08, 2016, 10:25:08 pm »
Hi all,

Thanks for your replies. Hamster_nz has given me a saver!!!!!!!! Yes, the MMCM gives me a 5MHz clock.

I will update you all with the work that I'm doing again later. This is for an interface to a high speed ADC (5MHz) (I know, not that high but yet in that realm) and my application requires high precision so i plan on using pulses every 5MHz to keep synchronization with the rest of the system.

Will give ya'll more details.

Thanks all again. As always, you're the best guys here and always help out!
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #8 on: November 09, 2016, 01:11:12 am »
One thought I did have was rather obscure You can use both rising edge and falling edge of the clock to latch data on.

Set a signal toggling in the slower 100Hz clock domain.

In the faster 105MHz domain register it in a flip-flop on the falling edge, and a rising flip-flop on the falling edge. That allows you to sample the toggling signal at  210MHz.

Where you always get a a transition between the two samples, you can be sure that you have at least had 4.76 ns of setup time on the earlier sample.

More than likely there will be a few options out of the 20:21 cycle where this holds true, and by taking the middle one you can ensure that you will also have enough hold time too. This can be used to establish when it is safe to pass data from the slow to the fast domain.

You can do the same from the faster domain by sampling three times in the slower domain, and when you get "010" or "101" you know where you are in the relative phasing, and can then work out where the ideal transfer window is.

With a bit of handshaking you could most likely dynamically negotiate both ways and identify the window which is stable, (as long as the two domains are tied to the same reference clock).


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: gauravmp

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #9 on: November 09, 2016, 08:08:07 am »
The trouble with that technique is that the 'correct' transfer window might not be the same for every bit in the ADC word, and there might not be any edge on which every bit has had enough setup and hold time. You also don't know anything at all about the timing relationship between each of the individual ADC bits and the toggling bit.

I've successfully used two techniques to transfer words from one clock domain into another.

Most commonly, I instantiate one of the dual-clock RAM blocks in FIFO mode. Write values into the FIFO in one domain, read them in the other, and take advantage of the fact that the FPGA manufacturer has solved this problem for me already. Add a 'toggle' bit to each word, which changes state with each sample, so the receiving logic can tell when a new sample has been received. The FIFO only needs to be one word deep. (Note: I use Altera, but I can't believe Xilinx doesn't have the same features).

Another option is to use a flag bit to indicate when a sample register is safe to read. In the ADC domain, write the new sample into a holding register, and flip the state of the flag. In the other domain, double-sample the flag (to avoid metastability), and read the holding register only when the sample-of-the-sample of the flag has changed state. This ensures the holding register is being read at a time when it's known to have held its value for at least a full clock cycle. Note, this only works if the ADC isn't generating new data too often.

Offline Someone

  • Super Contributor
  • ***
  • Posts: 4531
  • Country: au
    • send complaints here
Re: [FPGA][Verilog] How to detect synchronized edges of two different signals?
« Reply #10 on: November 09, 2016, 11:40:34 pm »
The trouble with that technique is that the 'correct' transfer window might not be the same for every bit in the ADC word, and there might not be any edge on which every bit has had enough setup and hold time. You also don't know anything at all about the timing relationship between each of the individual ADC bits and the toggling bit.

I've successfully used two techniques to transfer words from one clock domain into another.

Most commonly, I instantiate one of the dual-clock RAM blocks in FIFO mode. Write values into the FIFO in one domain, read them in the other, and take advantage of the fact that the FPGA manufacturer has solved this problem for me already. Add a 'toggle' bit to each word, which changes state with each sample, so the receiving logic can tell when a new sample has been received. The FIFO only needs to be one word deep. (Note: I use Altera, but I can't believe Xilinx doesn't have the same features).

Another option is to use a flag bit to indicate when a sample register is safe to read. In the ADC domain, write the new sample into a holding register, and flip the state of the flag. In the other domain, double-sample the flag (to avoid metastability), and read the holding register only when the sample-of-the-sample of the flag has changed state. This ensures the holding register is being read at a time when it's known to have held its value for at least a full clock cycle. Note, this only works if the ADC isn't generating new data too often.
Dont try and second guess or trick the timing analyser, it knows what its doing! Adding timing ignores across those sorts of async crossings even if you sample them after multiple cycles still doesnt make a safe system, the fifo is the correct way. Without further details from the OP they are probably trying to do some sort of synchronisation of the downstream logic/chips not just passing data (or they would have asked for that) but I'm not going to join in on the game of drip feeding requirements.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf