Forum Discussion

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

Managing multiple clock domains in verilog

Hopefully a pretty basic question with a simple solution (ha ha ha)

I've got a project with two major sub blocks. The first block includes a NIOS II processor and lots of verilog glue logic to the external world. That's all in a single clock domain and works great. The second block is used to drive a variety of monitors so it has 3 different potential clocks none of which have any relationships with each other, nor do they have any relationship to the clock domain that has the NIOS processor in it.

The only places that two worlds meet are:

1) a block of dual port RAM each side of which is clocked by it's respective clock signal

2) 2 control wires from the NIOS side to the display side to tell the display side which clock to use. I've put handshaking for the two control lines from NIOS to the display section.

It runs OK but I'm getting a TON of timing warnings because it appears that the project is trying to get timing closure between all 4 clocks.

I've gone into the Settings an have set Cut Paths Between Unrelated Clock Domains to ON but that doesn't seem to do anything. This isn't so much a "it's not working" as "how do I get rid of all these timing warnings?"

Even within the "display" block of my project (which is in a separate .v file) it appears that it's trying to reach closure between all the different clock domains ... but that's not necessary as they never are active at the same time. I've got that piece set up as follows:

wire ChosenClock;

assign ChosenClock = (Clock1) ? OSC_53 :

(Clock2) ? OSC_68 : OSC_95;

always @ (posedge ChosenClock)

begin

<<lots of verilog code >>

end

where Clock1 and Clock2 are the signals coming from the NIOS side

Thoughts / suggestions?

4 Replies

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

    Cutting paths between the unrelated clock domains should do the trick. Here are a few things to check.

    1 - You are using the Classic Timing Analyzer right? The Cut paths setting won't do any good if not.

    2 - If the multiple clock domains are being driven from the same PLL, the timing analyzer may determine them to be related (because they are). Are you driving your different clocks from the same PLL?

    3 - You may wish to consider using TimeQuest. The learning curve will cost you several days but it does give you more control over these things.

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

    jakob -

    Thanks for the quick reply ..

    1) Yes I'm using the Classic Timing Analyzer

    2) Yes, all the clocks are on the same PLL.

    Until such time as I invest the effort to learn the TimeQuest analyzer any ideas about how to care for my issues? Can't I have 3 different outputs from a given PLL and NOT have have them related for Timing Analysis?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You can. Just do a cut timing between the clocks. I look at the timing report with the failures, and literally cut and paste from the From/To Clock columns into the Assignment Editor and just make Cut = On. That way I don't do it incorrectly. Note that you need to do both directions, from OSC_53 to OSC_68 and from OSC_68 to OSC_53. With three clocks, that'll be 6 different CUT combinations.

    (And good job designing for the asynchronous clocks. That's the hard part.) When you get a chance, take your design, launch TimeQuest, and run the QSF to SDC conversion and then just run TimeQuest with that newly created SDC. Note that you haven't committed or anything, as Classic is still your timing analyzer for the whole flow, but you can use it as back end tool to just kick the tires. You'll hate it at first, but you'll quickly love it.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Rysc of course is correct. Because all of your clocks come from a single PLL, the global "Cut paths between unrelated clock domains" setting does nothing for you. This is because the clocks are in fact related by some combination of multipliers and dividers and they are all derived from the same base clock. You must therefore make individual cuts between the clock domains.