Forum Discussion

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

New to TimeQuest... Need help to add constraints and delays!

Hi all,

I want to first start by saying a massive thanks to Rysc for putting out this TimeQuest guide:

http://alteraforums.net/forum/showthread.php?t=25676&highlight=guide

Unfortunately due to being very short of time I have pretty much just read the first 30-odd pages (the getting started section) and am struggling slightly already...

I am trying to properly constrain my design, but I am not used to working with FPGA's so am finding Quartus II, ModelSim, TimeQuest etc a lot to take in just to design and compile a working design... however I am trying to persevere.

The main thing I am struggling with is Rysc's Step 5 from the getting started, i.e. Modify the -max and -min delays to account for external delays.

I was trying to use an iterative approach, and even with the max and min input and output delays set as 0.0 for the time being, the majority of paths find this acceptable. The only timing problems I have seem to be coming from the output of my PLL. (The output from my PLL is basically 4x the speed of my LVDS clock)

Did I need to define my generated clock specifically or does using "derive_pll_clocks" suffice?

I've attached a screenshot of setup Report Timing for the PLL output.

If anyone can help and save me hours of staring blankly at user guides and tutorials until the penny drops, then it is much appreciated!!

Cheers,

Lee H

17 Replies

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

    Lee,

    Am I right that you are in fact using a FT232 chip but then in FT245 synchronous style? I had to search a bit before I found that application note.

    One way to go is to make sure that the IO data for output is registered, e.g. being the registered output of a FIFO.

    Another way is to add a register to everything that goes to the FT-chip. This will meet timing. But not function as you now may write when the FT-chip signals full. The idea is that you now recognize such a 'MISSED_WRITE' and modify your writing state machine to cope with that and re-submit that not-written data when the flag goes inactive again.

    BTW you don't have to declare a virtual clock, you can use the incoming clock to specify the output delays.

    Good luck!

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

    Yes, sorry it is the FT2232H chip functioning in FT245 synchronous interface mode, as I am using the FTDI Morph-IC-II board which has a Cyclone II FPGA on it.

    I will try sending all outputs through registers to try to sort out timing.

    Cheers,

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

    Hiya, I am struggling with this a little.

    even putting a register before my outputs doesn't seem to work, as the 3ns delay appears to be across the tristate buffer for the IO pin. As I need the pin to be an IO pin is there another way to make it meet the 11ns setup time requirement? or do I need to look into multicycling and rather than having my latch clock on the next rising edge of the latch clock, have it on the rising edge after that?

    with registers, here is my timing, and the locations of the paths within the RTL viewer.

    I don't really know how FTDI expect you to be able to meet the 11ns setup with a clock period of 16.67ns and the typical data and clock delays that I am recieving!?

    Reagrds,

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

    Lee,

    you have to 'promote' the register to be an IO-register. It is not the tri-state function adding the delay but the path from an internal register over the IO-buffer to the pin. You can use the assignment editor to do this:

    From | To | AssignementName | Value | Enabled

    <empty> | AD | Fast Output regsiter | On | Yes

    I had the same issue with Cypress' CY7C69013 FX2 USB controller
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I had the same problem with those hideous setup-times of FT2232, even with forcing the register to be in the I/O-pad. The clock-delay is too long if you route the incoming clock to the registers.

    I had to recreate an 1:1 copy of the incoming USB clock with a PLL in Normal compensation mode. This automatically shifts the PLL outclock to compensate for the bulk of the delay in the clocktree. After this, you still have no time to do any logic, but all inputs and outputs from the FT2232 have to be registered. Yes, inputs too - the FT2232 has up to 7.15 ns delay in the fifo signals RXF and TXE leaving little margin inside the FPGA for anything except a register.

    I'm still struggling with the write-state machine though, where I have to monitor the external fifo-full signal (TXF), which is registred and thus delayed 1 cycle, to see if a write "didn't take". Unfortunately it's not very simple, as by the time you detect this, you will have acked *two* bytes from the fifo in the FPGA, leaving you to juggle around up to two bytes (one if the internal FIFO got empty), causing a real MESS when trying to resend them :/ You could conceivably even run into the situation where bytes are read out-of-order by the FT2232.

    If anybody has any ideas: writes occurs through pin-based FPGA-registers data_out_r and wr_n_r, and the FT2232 fifo-full is from the registred input txe_n_r.

    If we have data to write, and load 0 in wr_n_r and data in data_out_r, the cycle it shows on the output the FT2232 might inactivate txe_n. We won't see this until the cycle after, when we need to have yet another byte out on the bus to get the full throughput. So at that point, we have the byte we lost completely, and we have the byte currently on the data_out_r.

    I tried adding another register that keeps the last byte from data_out_r. But then I got into the mess with trying to resend them both after txe_n_r activates again in a clean way preferably not going into a special state where they are both completely transmitted before starting reading from the internal FIFO. I don't know if the FT2232 is designed so it can end up in a state toggling txe for every byte, which would cause a huge loss in performance with the above solution :/

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

    Hi Exolon,

    I spoke to FTDI a while ago when I was having problems with my design, and they sent me a revised, relaxed set of timing constraints which they assured me work (and they seem fine to me) which helps a little... I have attached the document they sent.

    Also I managed to avoid your problems as my design was quite a simple one. Basically as I was using the FT245 synchronous mode, no matter what you set the TX and RX buffer sizes to on the FT2232H, they are only 512 Bytes as that's the maximum packet size in USB Bulk mode.

    I was multiplexing 24bit words into my 8 bit output buffer, so I just filled the TX buffer with 510 bytes, and stopped writing to the buffer. Which meant I never needed to look for the TXF flag, and once my application had finished reading the buffer, so that it was empty again, the application sent a byte to trigger my next packet of data to be loaded into the FT2232's TX buffer....

    It's not the most elegant solution, and probably not what you are looking for, but for my simple design it seems to have worked well enough...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thats funny, I'm also multiplexing 24-bit words into the 8-bit USB bus :)

    Anyway, thanks for the FTDI-document - seems like they relaxed the 11 ns setup times to 8 ns. This will surely give me some nice slack. I can't take the easy route like you did with ignoring TXE since I have huge data-buffers to send continously more or less.

    Though, this morning I managed to get timing closure and good function of my interface even with the 11 ns timing.

    The resulting speed (writing from Cyclone-3 to FTDI2232H and reading from a Linux PC up to a user-mode program using libusb) was a whopping 43 mbyte/s! Satisfying! And it seems it works without glitches (yet).

    As a side-effect I learned a lot of SDC as well :)