I am implementing DSO controller in FPGA and I am having trouble with too many hold time violations (so far best P&R result was 3 hold time errors somwhere around -2ns slack).

Core of my problem is that I have FIFO buffer with input from ADC sample decimator and then output to synchronous FT245 (60MHz). Input decimator could be set to decimate in powers of 2 (eg. 1, 2, 4, 8, 16...) which also divides clock frequency of ADC samples (150MHz).

And my approach now is that I supply divided (or direct if decimator ratio is 0) clock frequency to buffer when I am capturing data and then I switch to supply 60MHz clock from FT245 when I am pushing samples to PC. In simulation it is working perfectly, but problem is in placement and route, that router will spit out this error:

Route:466 - Unusually high hold time violation detected among 226 connections. The top 20 such instances are printed below. The
   router will continue and try to fix it

Then it crunches for 10-15minutes until it gives me timing report informing me that All setup time constraints was met and that there are 3 hold time violations for 150MHz clock (60MHz clock is OK).

I have read that problem might be using of gated clock, that FPGA couldn't distribute clock properly, but I tried approach with instead of gating clock of FIFO I connected 150MHz clock directly to FIFO and I was gating data in FIFO with dataReady (it actually ended up being the same signal as previously gated clock) then I got much more (50-60) hold time violations than now.

Is there some known good approach for multiple clock FIFO? Not just two (these are plenty even in examples in Xilinx ISE). Or is idea of decimating ADC samples in FPGA no go?

Target FPGA is Spartan 6 LX25 speed grade -2 (Unfortunately I couldn't get my hands on -3 speed grade).

Here is example of slack it is giving me:

Slack (hold path):      -2.031ns (requirement - (clock path skew + uncertainty - data path))
  Source:               decimator_clock_divisor/decimationRatio_0 (FF)
  Destination:          trigger_analog1/previousValue_2 (FF)

The mentioned source is signal (and all violations it gives me are) that is not changed very often, it's actually controlled by GUI so I don't know how could it have hold time violation there. It is path from ratio of decimator to trigger buffer (or my FIFO buffer in other violation).

Basically my question is that should I even care about these violations ?

Because after changing the ratio of decimator there might be thousands of clock cycles before I actually start using results of decimator in trigger.

I know that router couldn't know how often I change asynchronous signal (it's asynchronous since I am setting it from 60MHz clock domain) and how long it would take me to use result of some module. The problem is that I don't know if when it shows me these 3 violations after completed PAR if it is final that there are no other violations that was just shadowed by these 3 violations?

Could post PAR simulation verify if it would work on board? I would try it on board but I have to wait 2 weeks for BGA soldering and I have only 4 weeks left to complete thesis so I want to be sure that my design will work.

有帮助吗?

解决方案

The FIFO can act as async. boundary bridge between the two main clock domains 60Mhz and 150Mhz. Strictly separate the logic of both clock domains. There should be only a few known slow control signals (slow enough so a false paths timing constraints can applied) on them to communicate. For example the GUI writes the clock ratio into a register on the 60Mhz side. Then it signals the fast side there is a new value. The fast side captures this value some cycles after it received the notification (for example an rising edge detect with some extra care for meta stability). The functional logic on the fast side always uses the output of this shadow register that also is on the fast side.

For clock dividing on the fast ADC side you can use the full clock and enable as you described (and I would prefer too) or you can divide the clock it self. When dividing the clock then make sure to follow the examples in Xilinx documentation. For example sometimes a clock buffer is required to distribute the clock.

If there are remaining hold path violations then have a look at the clock and clock arrival times of source and destination FF. Sometimes when the capturing clock of the destination FF is delayed then the data is to early. The router might fix this by simply delaying the data. It can not fix it when the setup requirement does not allow further delay (can be the case when uncertainty between both clocks is too high).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top