Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Quick Question - How to event on multiple clocks rising edges?

Very quick question...

If I have two clocks of different speeds, and want something to happen when the rising edge of both clocks occur at the same time.... how do I do this?

I have tried a few different ways, but am relatively new to VHDL...e.g. I tried something like:

 
if ((intRCLK'EVENT) and (intRCLK = '1')) then
  if((MULT_CLK'EVENT) and (MULT_CLK='1')) then
   Load_State <= Load_Byte1;
  else
   Load_State <= Load_IDLE;
  end if;
 end if;

But got errors such as:

error (10820): netlist error at lvds_fifo_control.vhd(229): can't infer register for load_state[0] because its behavior depends on the edges of multiple distinct clocks

and:

error (10822): hdl error at lvds_fifo_control.vhd(221): couldn't implement registers for assignments on this clock edge

I know I am going about this in the wrong way, but I don't really know what approach to take with this.

As always, any pointers or help greatly appreciated!

17 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I haven't read all the replies so I may be saying something redundant. Can you attack the problem from a different approach. Suppose all we are really looking for is a moment when the two clocks are both high. Use the faster clock to sample the slower clock. Provide registers for metastability and edge detection. Use the edge detect as the enable for your logic which is driven from the faster clock.

    Jake
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It's alright I was over complicating things loads, and it appears to be simulating correctly now...

    I already had one state machine running from the slow clock, and then the load state machine on the faster clock to load in all 3 bytes from each word.

    I just used a signal generated in the first statemachine (that is synchronised to the slow clock) called Load_FIFO to cause the load state machine to move from the IDLE state into loading the firstbyte into the FIFO. I just have to make sure the clock was 4 times the speed not 3, and include a dummy state in the load state machine to compensate for the 1 clock delay in writing each byte....

    Seems to be working so far.. but thanks everyone for all their comments...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I agree with the josyb solution.

    Run a state machine on the falling edge of the fast clock.

    The state machine counts for consecutive low levels of the slow clock, then it enables a second state machine clocked on the rising edge of the fast clock that will be enabled when both slow and fast clock are rising (or something like that).

    P.S. How many answers. Your question has triggered the FPGA design people :-)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I agree with the josyb solution.

    Run a state machine on the falling edge of the fast clock.

    --- Quote End ---

    What ???? Why on earth complicate things with both falling and rasing edges. There is absolutely no need for that.

    I agree with Tricky. By far, the simplest solution is to run the whole thing on a single clock (single edge, of course), and use a clock enable.

    If for some reason it is still desirable to use the slow clock as well, then it is pretty simple to have a clock enable on the fast clock that is synced to the slow clock. Both clocks are edge aligned because they are just different multiples on the same PLL.

    --- Quote Start ---

    P.S. How many answers. Your question has triggered the FPGA design people :-)

    --- Quote End ---

    Indeed :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    As there is a Fifo in play, the solution can be as simple as:

    Use a DCFIFO of 24 bits wide and write the data into this fifo with the slow Clk1x.

    Then at the read side use a clock of at least 3 times the frequency to read 24 bits out of the fifo and multiplex the 24 bits into packets of 8 bits.

    Don't try to dodge clock domain crossing (as Tricky advises), it will come back and haunt you (no pun intended with the upcoming Halloween frenzy).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It seems to me, that the discussion is partly ignoring the fact, that both clocks are said to be sourced from one PLL. They aren't unrelated, you don't need domain crossing techniques for it and Quartus is generally able to deal with the timing relation of both clocks. It does this correctly in various situations, e.g. with software SERDES.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I overlooked the fact that both clocks come from the same PLL. In that case one can set "CLOCKS_ARE_SYNCHRONIZED" to "TRUE" saving a bit on logic resources and decreasing latencies. The 'rdempty' signal going (or staying) inactive tells when to start (or continue) the state machine to 'unpack' the 24 bits into 8 bit packets.