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
My VHDL was merely illustrative. :)
You should use whatever edge is more convenient and gives you the most timing margin. Ie, a quick look tell's me that in SPI mode 0, the MCU will capture the data in the rising edge of SCK. Launching (shifting) on the rising edge should give you the biggest setup margin (one entire SCK period) but it makes it "easy" to violate the 10 ns hold requirement. Launching on the falling edge should make it easier to meet both setup and hold requirements. So, yes, I think you should use the falling edge. Yes, you can just invert the input clock of LPM_SHIFTREG. Though, there isn't much point in using LPM_SHIFTREG: Quartus will infer from the behavioral description I wrote above just fine. - Altera_Forum
Honored Contributor
Thank you!
Just a tiny question: you code suggests that I should use the rising edge of SCK to shift out the bit. I'm using SPI in mode 0 which means I should be shifting out bits on the falling edge of SCK. So, shouldn't I be using the falling edge of SCK? Secondly, I was using the shift register made by Altera's mega function utility: LPM_SHIFTREG. However, this shift register clocks out data at the rising edge again. Maybe I should invert SCK to make it do on the falling edge or perhaps make my own component? What would you suggest? - Altera_Forum
Honored Contributor
Ah, I see your problem..
One solution would be to have the MCU send a "command" to U2 over SPI, which would be used to sample PI. Another solution would be to feed the first bit asynchronously from PI to SO and sample the rest of the bits on the first edge of SCK. You'd have to asynchronously generate a "first_bit" condition. Non-verified illustrative VHDL
All that said, another option is take your current logic and make it output earlier. Make "tmp" shift after a rising SCK. This should give you 250 ns more margin in SO!process(nCS, SCK) begin if nCS = '1' then first_bit <= '1'; else if rising_edge(SCK) then first_bit <= '0'; end if; end process; process(nReset, SCK) begin if nReset = '0' then tmp <= (others => '0'); else if rising_edge(SCK) then if nCS = '0' then if first_bit = '1' then tmp <= PI; else tmp <= tmp(tmp'high-1 downto tmp'low) & '0'; end if; end if; end SO <= PI(0) when nCS = '0' and first_bit = '1' else tmp(tmp'high-1) when nCS = '0' and first_bit = '0' else 'Z'; - Altera_Forum
Honored Contributor
If I design using SCK as clock, how should I synchronously load the parallel inputs? I want the inputs to be loaded when CS is high but there is no guarantee that SCK will be running when CS is high because it's not a free running clock.
- Altera_Forum
Honored Contributor
Oh!
So, the MCU runs on a internal RC oscillator and produces the SCK based on that? My first suggestion would be to run the SPI interface using the SCK and interfacing with sys_clk only when needed. Which begs the question: what's the purpose of sys_clk? - Altera_Forum
Honored Contributor
So I have some updates:
I think that the SO/MISO waveform is arriving a bit late. The difference between the falling edge of SO and the rising edge of SCK (where the MCU samples) is just 40 ns. I'm thinking that, occasionally, the waveform arrives too late and I get a bad transfer. The AVR datasheet states 10 ns for setup and hold but these are typical values. Min/max are not provided. Here's a o-scope picture with SCK at 2 Mhz. The top waveform is MISO and bottom is SCK. http://i.imgur.com/EQWzz.png Same waveforms at higher timebase: http://i.imgur.com/jUpqx.png and here's another picture with SCK at 1 MHz: http://i.imgur.com/ewmQj.png At 1 Mhz, the waveform arrives in time very comfortably but I think 2 MHz is a bit of an edge case. I'd prefer to make it arrive a bit earlier. I adjusted the SDC constraints but they had little effect. I'm beginning to think that it might be because of my design. The other thing I noticed is that my SCK's frequency doesn't stay constant - it increases to 2.1 Mhz and decreases some too. My guess is that because the MCU is running from it's internal RC oscillator. It could be that, once in a while, SCK's freq. increases just slightly and because of the very narrow time to setup MISO, it reads in a bad value? Tomorrow, I will calibrate the internal RC oscillator and see if SCK's performance improves. However, any suggestions on what to do with my CPLD design? Will I need to increase the sys_clk frequency if I want SCK t obe 2 MHz? A lot of designs can run at just 1/4th the system frequency but I'm having to run at less than 1/10th! Would appreciate any advice on where to go from here. - Altera_Forum
Honored Contributor
That's a good test: change the speed of sys_clk vs SCK.
This way, you can pin-point which interface is giving you problems: the PO/PI or the SPI interface. Also, if the situation improves when you lower the operating frequency, there are two main possibilities. One, you have a setup timing problem. That means, some signal is taking too much time to become stable and, occasionally, it's samples before it has becomes stable. But again, with a 7 ns rise time I don't see that happening. Another possibility is Inter Symbol Interference: the signal of one bit overlaps with another one and as a result U2 samples the wrong value. You can try to take a look at the eye pattern of PI. Try to see if the error is specific to a given signal in the PI vector or if it's random. But you can pretty much discard hold violation issues. A third possibility: the problem is noise related and it's also happening at 1 MHz, you just haven't noticed it yet. - Altera_Forum
Honored Contributor
--- Quote Start --- With a 8 MHz MCU, I guess the time between CS_U1 going down up and CS_U2 going will probably be several times 125 ns. So, plenty of time to meet setup time. And since you're not changing the values right after U2 samples them, plenty of time to meet hold time. Really, don't see why it's failing occasionally. That said.. - U2 samples PI at the rising edge of clk.. when CS_sync is '1', not CS. So, it's happening 2 clocks later. You probably have something similar in U1, so it evens out. But best keep it in mind. - The signal can take some time from U1 setting it and becoming stable at U2's inputs, because of the pull-up scheme, connection cable, etc. I've seen pull-up schemes being unexpectedly slow, so this would be my first guess. - Since there are two different boards, the clocks at U1 and U2 won't be in perfect phase and this may work against you too. Try to draw a timing diagram of the signals involved, it's usually worth the trouble. Try measuring the delay between the rising edge of U2's clock and PI[*] reaching a stable value. Try to get a min/max range for some of the 72 signals. This will be the min/max input delays you should to set on PI, by the way. Other nice things to measure may be the phase between U1's clock and U2's clock; and the time between U1's CS and U2's CS. --- Quote End --- If I remember correctly, the rising time of P[*] was a hundred or so ns long due to the 1K pull up. If the timing between U1's CS and U2's CS is too close, the simplest solution would be to just put a delay of a uS between them. Very easy in an AVR. The boards are the same i.e U1 and U2 are on the same board and share the same clock. Because this is just internal equipment we didn't care much about aesthetics - the wires just connect at one end, wrap around and connect on the other end. However, the board has the capability to be extended i.e. there's another board which only has CPLDs and no MCU. This board connects via ribbon cable to the 'main' board. Interestingly, the data transmission between the MCU and the CPLDs that are on same board as the MCU is always OK. I have, so far, never seen a bad data transfer between them. However, the other boards, which connect via the ribbon cause the issues. But as I said, even that was reduced drastically to be 1 in 10,000 data transfers now. The only difference is that the SCK, CS, SO and SI travel quite a bit more but at just 2 MHz (and 7 ns rise times) one would think that signal integrity wouldn't be an issue. The overshoot on these signals is 1.3 V but it settles quickly and there is no ringing. Perhaps I should slow down these signals even further? The system works great if SCK is 1 MHz, by the way. No bad transfers. - Altera_Forum
Honored Contributor
With a 8 MHz MCU, I guess the time between CS_U1 going down up and CS_U2 going will probably be several times 125 ns. So, plenty of time to meet setup time.
And since you're not changing the values right after U2 samples them, plenty of time to meet hold time. Really, don't see why it's failing occasionally. That said.. - U2 samples PI at the rising edge of clk.. when CS_sync is '1', not CS. So, it's happening 2 clocks later. You probably have something similar in U1, so it evens out. But best keep it in mind. - The signal can take some time from U1 setting it and becoming stable at U2's inputs, because of the pull-up scheme, connection cable, etc. I've seen pull-up schemes being unexpectedly slow, so this would be my first guess. - Since there are two different boards, the clocks at U1 and U2 won't be in perfect phase and this may work against you too. Try to draw a timing diagram of the signals involved, it's usually worth the trouble. Try measuring the delay between the rising edge of U2's clock and PI[*] reaching a stable value. Try to get a min/max range for some of the 72 signals. This will be the min/max input delays you should to set on PI, by the way. Other nice things to measure may be the phase between U1's clock and U2's clock; and the time between U1's CS and U2's CS. - Altera_Forum
Honored Contributor
U2 samples PI whenever CS is high and there is a rising edge on sys_clk. So PI is being sampled quite often, whenever the CS isn't active.
U1 will keep PO stable until and unless a new command is given and CS is rises. The command isn't executed until and unless CS goes back high.process(CLK, nRESET) begin if (nRESET = '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';
What the MCU does is that it first sends the command "shiftVector" to U1. As soon as the transmission is done, the CS for U1 is brought high and the MCU begins lowering CS for U2 and starts receiving data. So the amount of cycles between when the vector is shifted and when data is received will depends on how fast the MCU is executing. This should be straight forward to measure, I have a 2-channel o-scope and I'll put channel 1 on the CS of U1 and channel 2 on CS of U2. The time we're interested in is between the rising edge of U1's CS and the falling edge of U2's CS. This should be sufficient enough that PI is sampled, right? So, basically, greater than 50 ns - at least 100 ns? The MCU, by the way, is working at 8 MHz. Thank you replying, by the way. I have nobody here to discuss it with and it really helps to go through about with someone who really knows what they're doing. :)if (nRESET = '0') then temp <= (others => '0'); shift_count := 0; elsif rising_edge(CLK) then if CS_rising = '1' then case cmd is when "00000001" => temp <= (others => '0'); temp(0) <= '1'; shift_count := 1; when "00001111" => temp <= (others => '0'); shift_count := 0; when "10101010" => temp <= temp(WIDTH - 2 downto 0) & '0'; shift_count := shift_count + 1; when "11110000" => ACK <= '1'; when others => null; end case; shift_count_vector <= std_logic_vector(to_unsigned(shift_count,shift_count_vector'length)); elsif CS_falling = '1' then ACK <= '0'; end if; end if;