Forum Discussion
How to constraint my design using TimeQuest?
I am looking for some help to constrain my design. I've never done a timing constraint and my understanding of the subject isn't very deep at all.
An overview of my design: it consists of a 72 bit shift register which is loaded in parallel (so that's 72 inputs). This data, when requested, is sent out via SPI. The SPI interface consists of MISO, MOSI, SCK (2 MHz) and CS. I sync. the SCK and CS signals to a 20 MHz clock (CLK) and shift out the data on the falling edge of the synchronized SCK signal (i.e. SCK_falling). Similarly, the chip is only active the synced copy of CS goes low (CS_falling). When CS_rising is 1, I load the data into the 72 bit shift register. Now, my question is, how do I properly constrain this design so it works on a real design? From my limited understanding, it seems I need to first create two clocks (SCK and CLK). I note that TimeQuest asks for the rising and falling times of the signal. Do I simply measure this on my board and enter it? In my case, I actually remember this: the rising/falling time for SCK is just 7 ns. However, for CLK it's a bit more tricky. My o-scope is only 50 MHz and the 20 MHz waveform appears quite distorted so it will be hard to measure the rise/fall times - can I just leave them out? Secondly, do I need to constraint the 72 inputs? If so, how? What about CS, MISO and MOSI? None of these have a set frequency as CS can go low and high at any time. So how does one go about constraining these?34 Replies
- Altera_Forum
Honored Contributor
How many cycles go between U1 setting a new value on it's PO and U2 entering the mode where it samples PI?
And how many cycles will U1 keep PO stable after U2 has exited the PI sampling mode? - Altera_Forum
Honored Contributor
The resistors are 100 Ohms and the rising edges, after slowing down, are about 7 ns. So I don't think the signal is that slow.
As I mentioned, the other CPLD/FPGA (let's call this U1) n the design, has 72 outputs which connect to the 72 inputs of this CPLD (U2). We connect them together via a group of wires (these are actually the things the board tests by driving a test vector onto them). The U1 CPLD doesn't connect directly but instead drives 72 MOSFETs which in turn buffer the signals on the bunch of wires. To reduce ringing, I have a 1 K resistor at the gate and a 1 K pull-up as well (again, due to my inexperience, I didn't realize that I could control the ringing better via clamping diodes. A termination resistor wouldn't work well because the wires are not good transmission lines and their Zo varies. The next revision of the board will have clamping diodes instead of 1 K resistors to slow down the signal). The pull-up is located near to U2 so that it has a default value incase the wires are not connected. It could be that the 1K resistor + the length of the wire is causing the signal to appear a bit too late? However, I do sample PI at every rising edge of sys_clk, so I'm not sure. Will I need to increase the input delay for PI? - Altera_Forum
Honored Contributor
Random thoughts
a) I'd say there's no problem with SO. Even if you wait 7 cycles (350 ns), you still have 140 ns for the signal to get out of the FPGA, reach the MCU and meet it's setup requirement. But since you said you're using resistors to slow down the signal.. maybe it's so slow 140 ns aren't enough? b) For PI, you can try to be a bit more pessimistic on the min delay, using 7 or 8 ns instead of 10. Though, if it works at 500 kHz but not 20, it's unlikely to be a hold violation. - Altera_Forum
Honored Contributor
--- Quote Start --- You set SO as a false path just so TimeQuest won't complain. You ensure that you wait (at least) 1 clock cycle, not by setting constraints but by the working of your logic. In fact, you're already waiting 2 cycles (from the synchronizers) + 5 cycles (SCK falling) before changing tmp. I would just make SO depend on a synchronized/delayed version of nCS as well, to make sure SO doesn't go to Z too soon on the last bit. --- Quote End --- Ah I see. The last part should be trivial as I already have a synced version of nCS. - Altera_Forum
Honored Contributor
You set SO as a false path just so TimeQuest won't complain.
You ensure that you wait (at least) 1 clock cycle, not by setting constraints but by the working of your logic. In fact, you're already waiting 2 cycles (from the synchronizers) + 5 cycles (SCK falling) before changing tmp. I would just make SO depend on a synchronized/delayed version of nCS as well, to make sure SO doesn't go to Z too soon on the last bit. - Altera_Forum
Honored Contributor
--- Quote Start --- But then again, I'd take a very different approach to this problem. I'd run my SPI interface logic on SCK, constraining SCK as a clock and constraining nCS and SO in relation to SCK. --- Quote End --- It's interesting that you mention this as this was my initial approach. I had code like so:
However, from discussions here and other forums I was recommended to actually sample the SCK signal with a much faster clock so thats approach I took. I synchronize the SCK signal via two flop flops and then detect their falling and rising edges and do operations based on that. Here is my actual architecture in VHDL:if rising_edge(sck) then --do stuff
Based on your suggestion, I'll also set a false path for SO, like so:begin if (nRESET_sync = '0') then sck_rising <= '0'; sck_falling <= '0'; sck_delay <= '0'; elsif rising_edge(clk) then if cs_sync = '1' then sck_delay <= '0'; sck_rising <= '0'; sck_falling <= '0'; else sck_delay <= sck_sync; sck_rising <= sck_sync and (not sck_delay); sck_falling <= (not sck_sync) and sck_delay; end if; end if; end process; process(clk, nRESET_sync) begin if (nRESET_sync = '0') then cs_rising <= '0'; cs_falling <= '0'; cs_delay <= '0'; elsif rising_edge(clk) then cs_delay <= cs_sync; cs_rising <= cs_sync and (not cs_delay); cs_falling <= (not cs_sync) and cs_delay; end if; end process; process(CLK, nRESET_sync) begin if (nRESET_sync = '0') then tmp <= (others => '0'); elsif rising_edge(CLK) then if CS_sync = '0' then if SCK_falling = '1' then tmp <= tmp(PI'high -1 downto PI'low) & '0'; end if; elsif CS_sync = '1' then tmp <= PI; end if; end if; end process; SO <= tmp(PI'high) when nCS = '0' else 'Z';
Perhaps I should tell you more about the design regarding SO: SO is actually output with combinational logic:set_false_path -from -to
So SO depends upon nCS and tmp(PI'high) depends on the the synced version of the SCK signal (when it's falling, to be exact). Should I still go ahead and set this as a false path? Could you explain why I need to set this as a false path? I also didn't quite understand this bit: --- Quote Start --- Since your 20 MHz clock is way faster than the 2 MHz SCK, you should be able to generate a SO signal which meets the MCUs timing requirements easily. 10 ns tHold => make sure you wait at least 1 clock (of sys_clk) between the rising of SCK and changing SO. 10 ns tSetup => make sure you wait less than 9 clocks between the rising of SCK and changing SO. --- Quote End --- How do I ensure that I wait at least 1 clock cycle between the rising edge of SCK and SO? Do I set a delay for 10 ns for both mix/max? But I thought you said to set SO as a false path? Sorry if I'm way off the path here!SO <= tmp(PI'high) when nCS = '0' else 'Z'; - Altera_Forum
Honored Contributor
Regarding wire delay.
For PCB wire delay, I typically use 4-8 ps/mm. For cables.. depends on the cable. If I have it, I also tell TimeQuest the pin load capacitance, which it will use. But that assumes the load is mostly capacitive, with negligible resistance. Since you use Rs to slow down the slew, you have a RC load, which TimeQuest doesn't model. Either you calculate the effect of your RC load.. or you just measure the rise time in your scope and add that to your I/O delay. Regarding clock skew. The clocks in the two chips (sender and receiver) are not 100% in phase, due to wire delay between them (and clock buffers if you have them). If the sender's clock is a 5 ns ahead the receiver, then the receiver will get the data 5 ns earlier => subtract 5 ns to the delay If the sender's clock is a 5 ns behind the receiver, then the receiver will get the data 5 ns later => add 5 ns to the delay That said, the importance of precision in this estimates is relative. As long as your design isn't suffering from being over constrained, you can use rough but safe estimates. You're operating at low frequencies, you should have big timing margins. - Altera_Forum
Honored Contributor
Setting I/O constrains is all about describing to TimeQuest what's going on outside the FPGA.
Since the MCU is probably using SCK to sample SO, then that would be the way to go, if you want to apply an output constraint. But then again, I'd take a very different approach to this problem. I'd run my SPI interface logic on SCK, constraining SCK as a clock and constraining nCS and SO in relation to SCK. In the way you're doing it, using sys_clk to run the SPI interface logic, the best way may be to set a false path in SO as well. Since your 20 MHz clock is way faster than the 2 MHz SCK, you should be able to generate a SO signal which meets the MCUs timing requirements easily. 10 ns tHold => make sure you wait at least 1 clock (of sys_clk) between the rising of SCK and changing SO. 10 ns tSetup => make sure you wait less than 9 clocks between the rising of SCK and changing SO. - Altera_Forum
Honored Contributor
Thank you for taking out the time to reply. The Parallel-in Shift Out design has the following ports:
CLK, SO/MISO, SCK, CS, nRESET and PI[72] Regarding (2): The MCU is a AT Mega 1281 and the data sheet specifies only typical values for the SPI interface. It lists tSetup and tHold as 10 ns. How would I go about estimating wire delay and clock skew? Here's the table that lists the tSetup and tHold: http://i.imgur.com/KWPlG.png The MCU is the master and sets the SPI bus speed, which is yes 2 MHz. However, SCK is synchronized with the CPLD's 20 MHz clock. If I understand your suggestion correctly, you're saying that I should declare SCK to also be a clock in the SDC file and constrain SO in relation to that? Even though I'm not directly using SCK, I sync the signal via two flip-flops and detect the rising falling edges of the synced signal. I then shift out the data onto SO based on the falling edge of the synced SCK signal. - Altera_Forum
Honored Contributor
1) Doesn't your Parallel-in, Shift-Out design have more ports than those?
2) You should set a max output delay and a min output delay on SO. The max value will include the MCUs tSetup, while the min value will include the MCUs tHold. They should also include an estimate of wire delay and an estimate of clock to data skew. max output delay = tSetup + maxWireDelay + worseClockSkew min output delay = -Hold + minWireDelay - worseClockSkew And isn't your MCU capturing SO using the 2 MHz SCK? If so, you should constrain SCK and constraint SO in relation to SCK. 3) They look reasonable. But again max input delay = tCO + maxWireDelay + worseClockSkew min input delay = tCO_min + minWireDelay - worseClockSkew