Tuesday, May 17, 2011

Savior of the Carries

Today I tried clocking my recursive pseudo-dual-edged carry-save counter with the 600 MHz clock from the PLL that I configured yesterday. No dice! ( Of course, the single-edged version of the counter works just fine.)

I tried some tweaks: Inserting a CLKCTRL unit after the PLL, and inserting a CARRY_SAVE primitive on the carry/save outputs of each half-adder cell, to tell Quartus to use dedicated carry-chain resources. These seemed to help a little, but still no dice. Of course, after turning the PLL output frequency down to 300 MHz, it worked fine - that is, up to bit 4 of the counter; but then I still had trouble with bit 8!

After some more fiddling, I got up to 400 MHz (dual-edge). Weird, I'm finding that things work better if I take out my manual clock buffering. That means I don't even really need the recursive register design (with the clock buffer tree) any more. But, then I tried an array design and now it doesn't work again! Argh. Everything is so sensitive to seemingly irrelevant changes. Who knows, maybe the recursive design got fitted in a way that reduced local clock skew... Now I can only seem able to get up to 350 MHz, even in the design that I thought got to 400 before...

OK, I got back up to 400 MHz now, after taking out KEEP attributes from the PDE_DFF. Let's try 500 MHz... OK, that works. Now 600 MHz (where we started out): OK, there it breaks down again. Let's try 550: That works.


The traces are, from top to bottom: (a) 50 MHz board clock (digital trace), (b) 550 MHz PLL output (analog trace, too fine to see anyway), (c) digital trace of the foregoing, (d) bit 4 of the counter (34.375 MHz digital trace), (e) bit 8 of the counter (2.148 MHz digital trace).

This is good, because reaching 550 MHz with the dual-edge counter means we can do 1.1 billion counts per second, and this translates to 0.9 ns time resolution (+/- 0.45 ns time uncertainty). This, then meets our goal of better than 1 ns time resolution.

No comments:

Post a Comment