So, after getting some advice from some good people here, I managed to put together my first (very modest) FPGA design. It is basically just a few registers and counters, and only runs at a few MHz, but I could synthesise and implement it with no warnings, and the real signals coming out seem to do what simulation made me think they would. I learned a few things along the way.

Now I want to learn how to set timing constraints and run timing analysis. So I am reading through the Xilinx doc UG612 and I see at the top of page 205:

"Use only one edge of the clock"

Hmm. Seems I broke the law. Part of my design is a parallel load shift register - I used the negedge of the last cycle of the clock to load it (from a counter which was clocked on the previous posedge). A quick sketch:

clocking and loading

Of course, I am not directly using the negedge here, but the load signal is derived from it. I thought that this was good - but Xilinx tells me - don't do that.

Am I wrong? If so, why? What should I do instead?

  • \$\begingroup\$ The error xilinx gives you is about a gated clock ? \$\endgroup\$ – Simeon R May 26 '18 at 19:19
  • 1
    \$\begingroup\$ no, my design compiles completely cleanly - no warnings or errors. I am referring to advice given in the linked document (page number in text above). \$\endgroup\$ – danmcb May 26 '18 at 19:24
  • 1
    \$\begingroup\$ You can mix them, but from a timing perspective that means that the setup/hold paths become half as long, and timing becomes harder to meet. What is SRCLK derived from? \$\endgroup\$ – Tom Carpenter May 26 '18 at 19:47
  • \$\begingroup\$ SRCLK is a 2MHz clock, the main clock of my design. (There is a 100MHz crystal oscillator on the dev board, I used a synchronous counter to get the 2MHz.) I figure at these frequencies there is unlikely to be a problem, but I would like to know what is "best practice" and why. \$\endgroup\$ – danmcb May 26 '18 at 19:50
  • 2
    \$\begingroup\$ @Paebbels "most FPGAs do not support slow clocks below 10 MHz" I understand the PLL may not be able to generate slow clocks, but what would prevent the FPGA to proceed at this slow speed if the clock is externally generated (or even internally using some frequency divider logic)? Do you have references for this constraint? \$\endgroup\$ – dim lost faith in SE May 26 '18 at 20:17

"Use only one edge of the clock"

I don't know why they would say that. You can use both rising and falling clock edges in the design and the timing analyser will take that into account.

Thus a 200MHz clock will give you 5 ns from rising edge to rising edge but only 2.5 ns from rising edge to falling edge. I made a small example using 16 bit values:

always @(posedge clk)
   result1 <= counter + hold;
always @(negedge clk)
   result2 <= counter + hold;

Below is a screenshot of the ISE timing analysis. It is for a 5ns 50% duty cycle clock.

The text is about a failing path from bit 3 of counter to bit 15 of result2. As you can see it uses the rising edge as source and the falling edge for the destination.

enter image description here

  • \$\begingroup\$ I think they say it to prevent anymore SR tickets... and, because KISS is better anyway. But, yeh, completely valid to use different edges, and their timing tools can handle it \$\endgroup\$ – CapnJJ May 26 '18 at 23:23
  • \$\begingroup\$ Thank you. Indeed, it does seem it can be done - but as Photon points out below - that doesn't mean it should be. \$\endgroup\$ – danmcb May 27 '18 at 5:33

The logic elements in the FPGA are usually designed with zero hold time, specifically to enable you to design with only one clock edge.

In your example, this means that both the CTR INC signal and the SR LOAD signal are seen as asserted on edge 0, and neither one is seen as asserted on edge 15. The value that gets loaded into the shift register will be the one that is in the counter prior to edge 0. The effect of incrementing the counter won't be seen in the shift register until the next time SR LOAD is asserted.

If you made the SR signal follow the same waveform as CTR INC, this would still be true, and the circuit behavior would be the same.

  • \$\begingroup\$ Right. This is very helpful, because this is where I was not thinking quite straight. When I did this I was worrying about the SR skipping a count if I would use the same signal. This won't happen as FPGA's flip flops are not yet able to predict the future. Reassuring! \$\endgroup\$ – danmcb May 27 '18 at 5:37

You are not wrong, you are just making your life more difficult than it needs to be... especially where timing closure is concerned (developing accurate constraints is harder). You can easily make this design operate on rising edge only.

Seems to me, if you want to load when counter = 0, you could have some combinatorial logic that: assign load = (counter==15) (or similar). This will shift your load signal back 1/2 clock cycle, and be seen on the rising edge of edge0 as asserted. There are many ways to do this (using all rising edge clocked FFs) though, and probably a little googling will go a long way.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.