Forum Discussion

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

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's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored 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's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored 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

    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';

    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!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored 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's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored 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.