UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer
Adventurer
11,537 Views
Registered: ‎06-23-2015

Interfacing Kintex 7 with FT232h

Hi,

 

I am trying to send data from the Kintex 7 to a computer using the ft232h operating in the fifo 245 sync mode. In this mode, the ft232h sends a signal indicating it is ready to accept data (txe# low) and then the fpga sends data (we# low, and data#=values). The clock governing this relashionship is produced by the ft232h and runs at a fixed frequency of 60Mhz.

 

A naive implementation gave me a highly unrelaiable transfer, and after diggining into this I learned that:

- the ft232h clock should be decoupled from the rest of the clocks in the system (by grouping in the constraints file - shown below)

- I should declare the input and output delays of the ft232 pins as well.

 

I've found the following constraits which seem to be consistent with the manufacturer numbers:


create_clock -period 16.667 -name ft_clk -waveform {0.000 8.333} -add [get_ports {ftdi_clk}]
set_input_delay -clock ft_clk -min -add_delay 9.000 [get_ports {ftdi_txe}]
set_input_delay -clock ft_clk -max -add_delay 0.000 [get_ports {ftdi_txe}]
set_output_delay -clock ft_clk -max -add_delay 7.500 [get_ports {ftdi_data[*]}

set_output_delay -clock ft_clk -max -add_delay 7.500 [get_ports {ftdi_wr}
set_output_delay -clock ft_clk -min -add_delay 0.000 [get_ports {ftdi_data[*]}

set_output_delay -clock ft_clk -min -add_delay 0.000 [get_ports {ftdi_wr}


set_clock_groups -name ftdi -asynchronous -group [get_clocks ft_clk]
set_clock_groups -name rest -asynchronous -group [get_clocks {clk_disp90_Clock clk_disp_Clock ...}]

 

The implementation keeps on failing to meet these constraints: it fails to pass the signal into the ftdi_data and ftdi_wr pins in time, giving a negative slack of 1.24ns in the setup time of the Intra-clock path between the data_reg and the ftdi_data. This is made of 3.5ns logic delat and 1ns net delay (I tried using a flop to buffer the logic and the output pin and it doesn't seem to do much).

 

As far as I can tell, the constraints are reasonable (definitely given the Kintex 7 perfomance) so I guess I am doing something wrong.. Should I use some kind of io buffers (although I saw that the synthesis already does that)?

 

Any idea?

 

Thanks,

Raanan

Tags (2)
0 Kudos
30 Replies
Historian
Historian
11,505 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

So, a couple of things before we get to the "real" stuff...

 

Remove all the -add_delay options on your set_input_delay/set_output_delay commands - they shouldn't be there. These constraints are the only constraints on these pins, and if there were any other ones, they should be overridden (the -add_delay allows you to keep multiple sets of constraints on the same ports).

 

Second, I am always very worried about set_clock_groups -asynchronous. In this command you are telling your tool that these clocks are asynchronous so all timing checks between the groups are to be disabled. This can only be done if you have designed the proper clock domain crossing (CDC) circuits between the ft_clk clock and the rest of the clocks. I don't know anything about the internals of your FPGA - so I don't know where the data you are sending on ftdi_data is coming from, but if that data comes from a different clock domain, then you need to ensure that there is a proper CDC  on that path (most likely a clock crossing FIFO), and the appropriate constraints for that clock crossing circuit.

 

For more on this stuff, see my comment in the technical blog and the posts that are referenced there.

 

Now, as to the constraints...

 

The constraints themselves look correct, with the possible exception of some other factors that you haven't budgetted for:

  - clock jitter on ft_clk (which doesn't seem to be spec'ed by the FTDI chip)

  - board routing delay on both the clock and data signals (this can be a factor)

 

So, why do these constraints fail?

 

You haven't given us enough information (like the failing timing report), but I would speculate that this is due to how you are managing the ft_clk. The relationship between the FTDI chip and the FPGA is "System Synchronous" (yes, the FTDI is sourcing the clock, but the communication goes both ways using this common clock). So your clock structure needs to be compatible with this kind of communication scheme.

 

Pretty much the only clocking architecture that is going to work for you is

  - bring ft_clk in on a clock capable pin (SRCC or MRCC)

  - use a PLL or MMCM to do clock deskew

      - program the MMCM to give you the same clock frequency on CLKOUT0 as on CLKIN

          - use the clocking wizard to help you choose the mutlipliers and dividers - ask for 60MHz in and 60MHz out

      - connect CLKFBOUT to CLKFBIN using a BUFG

      - connect CLKOUT0 to a BUFG

   - use this buffered clock to clock your interface

 

(If this whole interface and related logic is restricted to one clock region, you can replace both BUFGs with BUFHs, but you have to replace both at the same time. You should only do this if you are running out of BUFGs).

 

Ideally you should have the ftdi_data and ftdi_wr signals come directly from flip-flops clocked by this clock, and the flip-flops should be packed into the IOB.

 

With this clocking structure, you shouldn't have any trouble meeting the timing requirements of this interface.

 

Avrum

   

Tags (2)
0 Kudos
Adventurer
Adventurer
11,480 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Hi Avrum.

 

Thank you for your reply. I have tried what you suggested but I am getting more failing constraints (now with other clocks) and I guess, as you've said, the side generating the data is an important factor here.

 

Basically, there is a dual-port ram (block mem) which is filled by another process running at a different frequency (75Mhz). The way things work is that there are two signals to corrdinate the two processes: one saying the ram buffer was filled (by the 75Mhz proces) and one saying the entire buffer was read (and sent to the ftdi). One process works, the other waits. These processes exchange very little data (once in a long which a single bit) and an arbitrary delay in the response (buffer read can happen anytime after the buffer filled) is allowed so I thought this is not a sensitive issue. Nonetheless, it is not clear how the timing are computed between these two process, where besides that lack of natural compatability between 60 and 75, there is an unknown phase shift. I can try generating the 75Mhz clock from the 60Mhz using the MCMM, however, the former depends on other clock and the arbitrary phase comes in again..

 

I am attaching the timing report (I think..)

 

I also added the vhdl code I wrote below (there's something intricate about the way pixels are read from the continuously transmissed image in the second process).

 

Thanks a lot!

Raanan

 

-- clk_pixel is the 75Mhz clock I mentioned.

 

entity FTDI is
  generic (vt : in VideoTiming);
  port (clk_pixel : in  std_logic;
        rgb       : in  RGBpixel;
        clk_ftdi  : in  std_logic;
        data_ftdi : out std_logic_vector(7 downto 0);
        txe_ftdi  : in  std_logic;
        wr_ftdi   : out std_logic;
        led       : out std_logic_vector(6 downto 0)
        ) ;
end FTDI;

 

.

.

.


--
----    read buffer, transmit to ftdi
--

  data_ftdi <= data_ftdi_t;
  wr_ftdi   <= wr_ftdi_t;

  process(clk_ftdi)
  begin
    if rising_edge(clk_ftdi) then
      
      wr_ftdi_t <= '1';

      if txe_ftdi = '0' then
        
        if buf_ready_to_read = '1' and tx_transmit = '0' then
          tx_transmit <= '1';
        end if;

        if tx_transmit = '1' then
          
          wr_ftdi_t <= '0';


          if read_ind < out_mlb_len(vt) then
            maddr_ftdi_rd <= std_logic_vector(to_unsigned(read_ind, c_addr_bits));
          end if;

          if read_ind = 0 then
            case rgb_cnt is
              when 0 =>
                data_ftdi_t <= std_logic_vector(line_send(7 downto 0));
              when 1 =>
                data_ftdi_t <= std_logic_vector(line_send(15 downto 8));
              when others =>
                data_ftdi_t <= x"a5";
            end case;
          else
            case rgb_cnt is
              when 0 =>
                data_ftdi_t <= mdout_ftdi_rd(c_b_end downto c_b_start);
              when 1 =>
                data_ftdi_t <= mdout_ftdi_rd(c_g_end downto c_g_start);
              when 2 =>
                data_ftdi_t <= mdout_ftdi_rd(c_r_end downto c_r_start);
            end case;
          end if;

          if rgb_cnt < 2 then
            rgb_cnt <= rgb_cnt + 1;
          else
            rgb_cnt <= 0;

            if read_ind < lc_buf_end + 1 then
              read_ind <= read_ind + 1;
            else
              read_ind    <= 0;
              tx_transmit <= '0';
              wr_ftdi_t   <= '1';
            end if;
          end if;
        end if;  -- transmit
      end if;  -- txe
    end if;  -- clk
  end process;

--
----    read img, write to buffer
--

  process(clk_pixel)
  begin
    if rising_edge(clk_pixel) then

      if tx_transmit = '1' then
        buf_ready_to_read <= '0';
      else
        if buf_ready_to_read = '0' then  -- needed to prevent new fill before tx had the chance to act
          
          if rgb.sync.de = c_de_signal and (write_ind > 0 or (rgb.sync.x = hdisp_start(vt) and rgb.sync.y = next_line)) then

            -- wait for line and fill buffer
            
            if write_ind = 0 then
              
              line_send <= to_unsigned(rgb.sync.y-vdisp_start(vt), 16);

              if next_line + lc_advance_lines > vdisp_end(vt) then
                next_line <= vdisp_start(vt) + start_line;

                if start_line < lc_advance_lines - 2 then
                  start_line <= start_line + 2;
                else
                  start_line <= 0;
                end if;
              else
                next_line <= next_line + lc_advance_lines;
              end if;
            end if;

            maddr_vin_wr                          <= std_logic_vector(to_unsigned(write_ind, c_addr_bits));
            mdin_vin_wr(c_b_end downto c_b_start) <= rgb.b;
            mdin_vin_wr(c_g_end downto c_g_start) <= rgb.g;
            mdin_vin_wr(c_r_end downto c_r_start) <= rgb.r;

            if write_ind < lc_buf_end then
              write_ind <= write_ind + 1;
            else
              write_ind         <= 0;
              buf_ready_to_read <= '1';  -- start send
            end if;
          end if;  -- wait for line / read pixels
        end if;  -- buffer busy
      end if;  -- transmit
    end if;  -- clk
  end process;

 

 

0 Kudos
Historian
Historian
11,447 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

So, I am assuming the two clocks, clk_pixel and clk_ftdi are not related.

 

If so, then any signal going between these two clock domains need a clock domain crossing (CDC) circuit.

 

Your primary communication between them is the dual port RAM. This is a CDC circuit (thats one of the nice things about a dual port block RAM). In most of the technologies (including the 7 series), there are no timing arcs between the two ports, so no timing exceptions or anything else is needed between them.

 

However, you have other signals between these two domains. I haven't looked too closely at your code, but the buf_ready_to_read and tx_transmit appear to be the two control signals that cross between the two domains (there may be others). Assuming these are slow changing signals (i.e. not one clock wide pulses), then a simple metastability resolution circuit is acceptable on these paths. This consists of two back to back flip-flops on the destination domain to synchronize the signal coming in to that domain.

 

MetaHarden.gif

 

Once you put these two flip-flops in, you need to put in the special attributes and constraints to make this a true CDC. The first is that both of the flip-flops need the ASYNC_REG property set to TRUE (in your RTL or your XDC). This does a number of things, including forcing the placer to keep these flip-flops "close" together.

 

Now you need to deal with the timing path from the final flop on the source domain and the first of these two flip-flops on the destination domain. In Vivado, all clocks are related by default. Therefore, without any timing exceptions the tools will assume a synchronous timing relationship will exist between these clock, and hence will attempt to time this path using its rules for synchronous clock crossings, which is not correct for this path, and will likely lead to a timing failure. You have dealt with the path architecturally by putting in the CDC, so now you need to override the timing requirement on this path.  For a slow changing single bit signal, this can be a set_false_path, but I prefer a set_max_delay -datapath_only. Since the faster clock is 75MHz I would use a constraint of 13.3ns

 

set_max_delay -from [get_cells tx_transmit_reg] -to [get_cells meta_harden_tx/signal_meta_reg] -datapath_only 13.3

 

(and the same on the buf_ready_to_read in the other direction).

 

If you are still having trouble after fixing the constraints, post just the worst failing path from the timing report (as text, not .rpx file - I didn't open [and am not even entirely certain how to] the .rpx file)

 

Avrum

Tags (2)
Adventurer
Adventurer
11,392 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Hi Avrum,

 

As you say, there seem to be two issues:

(i) the CDC - here I think I have a somewhat simpler solution: use a FIFO. While the data is large and usign only a FIFO would not work, I designed the following system: alg => bloack ram => fifo => ftdi. This way I have a large buffer to capture scanline, as well as a decoupling fifo where one of its sides if fully operated by the external ft232h 60Mhz clock, and the other by the internal 75Mhz clock (which now runs both sides of the block ram). This seems to do the trick as far as time failure between clocks.

 

Still, however, I am getting the

 

(ii) Intra-clock time failures between ft_clk and ft_clk (see the attaced) saying the output from the fifo (data_ftdi) cannot reach the output pins (now called lpc_gpio). Here I am puzzled and need clues (are there special lines/buffer needed - and why?).

 

Thanks again,

Raanan 

screenshot.png
0 Kudos
Adventurer
Adventurer
11,337 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Perhaps a more detailed timing report of the failing path could help..

screenshot2.png
0 Kudos
Adventurer
Adventurer
11,102 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Perhaps the conversation above grew too lengthy, let me state the current issue I am facing:

 

The Kintex 7 (KC705) fails to meet the following output timing constraints, needed to drive th eFT232h, 

 

create_clock -period 16.667 -name ft_clk -waveform {0.000 8.333} -add [get_ports {ftdi_clk}]
set_input_delay -clock ft_clk -min -add_delay 9.000 [get_ports {ftdi_txe}]
set_input_delay -clock ft_clk -max -add_delay 0.000 [get_ports {ftdi_txe}]
set_output_delay -clock ft_clk -max -add_delay 7.500 [get_ports {[*]}

set_output_delay -clock ft_clk -max -add_delay 7.500 [get_ports {ftdi_wr}
set_output_delay -clock ft_clk -min -add_delay 0.000 [get_ports {ftdi_data[*]}

set_output_delay -clock ft_clk -min -add_delay 0.000 [get_ports {ftdi_wr}

 

The failing paths are shown above; basically all the output lines (ftdi_data, ftdi_wr ---> their physical IO pins lpc_gpio).

 

I wonder if someone has a clue or suggestion

 

Thanks!

0 Kudos
Explorer
Explorer
11,007 Views
Registered: ‎04-09-2008

Re: Interfacing Kintex 7 with FT232h

 

Are your set_input_delay minimum and maximum values reversed?

 

Adventurer
Adventurer
11,001 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

I don't think so. But it worth your extra look:

 

from this post I understand that:

 

The set_output_delay -max should be the setup requirement of the external device.

The set_output_delay -min should be the negative of the hold requirement.

 

and the ft232h time specs say 7.5ns setup time, and zero hold time - as shown here:

 

http://imagizer.imageshack.us/v2/xq90/13/7cmg.png

 

Does it make sense?

 

 

0 Kudos
Historian
Historian
10,915 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

Are your set_input_delay minimum and maximum values reversed?

 

@pcurt is right. The set_input_delay commands are reversed, -min should be 0, and -max should be 9 (not the other way around).

 

Again, remove the -add_delay options. Where do these come from? I have seen a lot of posts where the -add_delays are used - is there some reference in the documentation or templates that has these? If so, could you point it out to me so that I can get the reference fixed. The -add_delay is needed for very specific purposes (when you are trying to put a second set of min/max delays on a port - like you would for DDR interfaces, for example).

 

Avrum

 

 

Tags (2)
Historian
Historian
10,455 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

As for why the path is failing - that's harder to determine. Clearly there is a VERY long route from the final flip-flop to the OBUF, which is part of the problem. Normally on an interface like this you would use the IOB flip-flop for the outputs, which would eliminate this delay

 

set_property IOB TRUE [get_ports ftdi_data[*]]

 

The fact that the IOB (hence the PACKAGE_PIN) for this pin is so far away from the logic is contributing to this. I don't know why the tools are putting all the logic up there when the outputs are at the bottom of the chip - maybe the inputs are "up there".

 

Pushing the flip-flop into the IOB, though, will probably just move the violation to the path from the "logic up there" to the IOB flip-flop. If this is the case, then you will need to add pipelining to the path going out of the FPGA. You will have to look at the design to determine where to do this - simply pipelining the data and the wr signals (together) will probably work, but will increase the latency from the bus turnaround, which will affect performance...

 

Also, the delay of the OBUF itself is pretty high. Are you sure you are using the right I/O standard with the right drive strength and slew rate (if it has these controls)? All of these will affect the delay of the OBUF, and hence the margin on this path.

 

Avrum

Tags (2)
Adventurer
Adventurer
10,442 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Let me first thank you both. As to all the comments raised:

 

1) I agree, I failed to see the reveresed values of the txe#. Fising this value just gives a setup and hold failures for the txe (on top of the setup failures of the wr# and data#). In any event, this should be fixed and I appreaciate you detected this.

 

2) the -add_delay (which I removed from my .xdc as you, avrum, suggested) was added by the timing constraits editor. I first wrote the .xdc without these flags, then discovered the editor and started working with it, and then it was added (althought I did not explicitly added it in the editor - so I am not sure why it was added). Perhaps this is the source you're looking for.

 

3) I may have a solution to my timing problem (which perhaps you assumed I was doing..) and hadnt' had the chance of actually running on the board (but Vivado no longer complains on time failure). This is done by running the ftdi_clk through a IBUFG buffer. If I am not mistaken, this is not what the DCM does (unless bufg is ibufg - but then again what didn't solve the timing as it does now?) Upon an inquiry I found that: An IBUFG drives a global clock net from an external pin, whereas, A BUFG drives a global clock net from an internal signal.

 

4) FPGAs are intricate creatures.

 

I hope I'll be able to report positive news once I reach the board!

 

0 Kudos
Adventurer
Adventurer
10,440 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

I have also reached this idea - it did lower the negative slack but didn't eliminate it. Once I used the ibufg, it is no longer needed (although the new implementation seems to be using these pad blocks on its own - which it didn't do before - perhaps due to the need to properly connect to the clock line?). Thanks!
0 Kudos
Highlighted
Historian
Historian
10,404 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

This is done by running the ftdi_clk through a IBUFG buffer.

 

This doesn't really make sense...

 

The voltages and currents used on a PCB are (grossly) different than those used inside the FPGA. Therefore all signals going in to or out of an FPGA need go through an IBUF (input) or OBUF (output). These "cells" are really just logical representations of the real, physical structures on the FPGA die that surround the bond site that actually connects to the package and from there to the PCB. These consist of level translators and amplifiers and protection devices (and pull-up/down resistances and termination and a whole bunch of other things). Configuring this circuitry is what gives us the different IO_STANDARDS (LVCMOS vs. HSTL vs. SSTL, single ended vs. differential, drive strengths, pull-up/down).

 

So all signals coming in go through an IBUF whether you instantiate one or not. If you don't instantiate it, the tools will automatically insert it when the design is synthesized.

 

An IBUFG isn't "real". It is merely a shorthand for an IBUF that can only be LOC'ed (or PACKAGE_PIN'ed) to a clock capable site. Within the FPGA there are some "special" pins (in the 7 series, there are 4 in each I/O bank) where the output of the IBUF has additional dedicated connections to the clocking logic. These are denoted in the package list with names that have SRCC (Single Region Clock Capable) or MRCC (Multi-Region Clock Capable). You should always use these pins for clocks,

 

If you try an do a "set_property PACKAGE_PIN <pin_name> [get_ports <top_level_port_name>]" for a <top_level_port_name> which is connected to an IBUFG and a <pin_name> that is not an MRCC or SRCC pin, you will get a critical warning - that's really the only difference between an IBUF and an IBUFG.

 

So, instantiating the IBUFG doesn't really make a difference - the tool auto-inserted it for you in the version of the design that didn't have it.

 

Now, if you don't have the PACKAGE_PIN properties set for all your top level ports (i.e. you haven't defined the mapping between the logical ports in your RTL description to the physical pins of the FPGA package) then the tools will do so automatically for you when you place the design. This is merely for the purpose of getting through the place_design process - you will not be able to generate a bitstream from this, because the tools know that you never specified where the pins went (so it can't possibly match up with your board).

 

It is possible (but I sort of doubt it) that if you both have no PACKAGE_PIN definitions and do not instantiate an IBUFG, it could have mapped your clock port to a non-SRCC/MRCC pin. This would have a seriously negative effect on your timing.

 

But I doubt it. The tools actually can recognize a clock net - if a net in your design drives clock pins of library cells (i.e. the C pin of FDRE/FDSE/FDCE/FDPE, the C pin of ISERDES/OSERDES/IDDR/ODDR, the CLKA/CLKB pins of RAMs, the various clock pins of DSP48E1 cells) the tools will recognize this as a clock. If it doesn't already have a BUFG on it, it will instantiate one for you. If the input of the BUFG comes from a non-SRCC/MRCC pin, it will issue a critical warning. Given that it can do all of this, I suspect that it can determine that an SRCC/MRCC pin is needed for a top level port even if it doesn't have an IBUFG or a BUFG instantiated on it and it has no PACKAGE_PIN definition...

 

So, why did instantiating this IBUFG make a difference. Its possible that the improvement was not causal. Any time you change your RTL, your constraints or any tool options and run implementation, you will end up with a different design - the placement and routing will be different. Even if the change is minor, you can still end up with a huge difference in the final implemented design. So, it may just be this "chaos" that caused your timing to improve when you changed the design, rather than any causal improvement caused by inserting the IBUFG.

 

Yes, FPGAs are intricate devices, and it can be quite difficult to get started on this stuff. As you can see from my postings there are a lot of interconnected concepts; RTL design, clocking architecture, tools and processes, constraints, etc... It is for this reason that Xilinx offers a whole range of courses that tries to put all of this in place. Take a look at the course at http://www.xilinx.com/training/ - at the Essentials of FPGA Design might be a good class to start putting this stuff together...

 

Avrum

0 Kudos
Adventurer
Adventurer
10,235 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Hi Avrum,

 

According to the schematic produced, when using IBUFG the  BUFIO is not created before the BUFG (i.e., there is BUFG) which seem to reduce some amount of the clock skew delay. I am not sure why, but this only happens when I use hardware fifo and it doesn't have effect otherwise (btw: I am using a clock capable pin). While I am barely meeting timing with the fifo implementation, I want to insist on doing this without it, i.e., use the block memory as the CDC and managed to avoid the timing errors with the two slowly changing signals using set_false_path.

 

I came to realize that the major issue when not using a DCM is the clock skew inside the system -- it arrives to the internal logic of the fpga late (5.89ns). Then comes the data path with its own 5.4ns and we're 16.66 - 7.5 - 11.5 ~ 2.2ns late. Deskewing, as you suggested initially should do the trick. Nevertheless, it didn't. I looked at it again and saw that for some reason it seems to be adding more delay, I mean there is a negative value in the clock path -8.07ns (deskewing?) but it is accompanied with large positive figures which add around an entire clock cycle?! This solution ends with a  longer delay of 11.8ns.

 

I am attaching the failed path in both options one next to the other - and I guess my big question is why does the PLL deskewing doesn't pay off.

 

btw: I am not sure the minues -9ns in the txe# setup time was wrong as, according to the schematics it arrives late by 9ns. The main problem is however related to the data# and wr# which need to arrive 7.5ns before raising clock.

 

Thanks again,

Raanan

paths.png
0 Kudos
Adventurer
Adventurer
10,221 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

In fact, it is easy to see that the DCM starts with a delay of one cycle 16.667, where the naive bufg starts with 0. It is as if the DCM is delayed by a cycle. How can a periodic clock be delayed by a cycle? (undefined mathematically I believe..)
0 Kudos
Historian
Historian
10,209 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

What you hare seeing now is something messed up with your constraints.

 

With the MMCM (there are no DCMs in 7 series devices) in the path, you have TWO clocks - the path starts at clk_out_Clock_FTDI (which is presumably the clock created by the clocking wizard) and ends at ft_clk, which is the clock created in your XDC constraint file.

 

These clocks are different; one has a period of 16.666 and the other has a period of 16.667. Because of this, the requirement on the path is 0.001ns, which is what is causing the failure.

 

You must make sure to have only one constraint - this is usually not a problem, but you have created the problem by having the -add in your constraint file. Without the -add, the clock you define in your XDC (ft_clk) would override the one created by the wizard. With the -add, it keeps both, and you get this path between the two clocks. Get rid of the -add (and the -add_delay on the inputs) - they should not be there and they are messing things up.

 

Avrum

Tags (1)
Historian
Historian
10,208 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

According to the schematic produced, when using IBUFG the  BUFIO is not created before the BUFG (i.e., there is BUFG) which seem to reduce some amount of the clock skew delay

 

I cannot follow this. You need to show me the schematics and the RTL code that you are using. I suspect that you are somehow making/forcing the tools to infer some clock buffers, and you are ending up with different clock structures as a result. This is more an issue with how you are creating your clock structure - there is some imprecision in how you are creating your structure which is leading to unintentional structure changes based on "unrelated" things (like whether the IBUFG is manually instantiated or inferred).

 

Avrum

0 Kudos
Adventurer
Adventurer
10,201 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

OK, this seems to have been the major issue.

 

When I switched to 16.666 I started getting the following message:

 

 [Constraints 18-1055] Clock 'ft_clk' completely overrides clock 'ftdi_clk', which is referenced by one or more other constraints. Any constraints that refer to the overridden clock will be ignored.
New: create_clock -period 16.666 -name ft_clk -waveform {0.000 8.333} [get_ports ftdi_clk], [F:/srs-1080p-pipeline/kc705.xdc:246]
Previous: create_clock -period 16.666 [get_ports ftdi_clk], [F:/vivado/vivado.srcs/sources_1/ip/Clock_FTDI/Clock_FTDI.xdc:55]
Resolution: Review the constraint files and remove the redundant clock definition(s). If the clock constraints are not saved in a file, you can first save the constraints to an XDC file and reload the design once the constraints have been corrected.

 

Which refers to a file created by the wizard and containing:

 

create_clock -period 16.666 [get_ports clk_in]
set_input_jitter [get_clocks -of_objects [get_ports clk_in]] 0.16666

 

So basically by creating an MMCM and specifiying the input clock info. the system already created this constraint over the input pin (ftdi_clk) and by having:

 

create_clock -period 16.666 -name ft_clk -waveform {0.000 8.333} [get_ports {ftdi_clk}] 

 

in the constraint file, I generated another clock? (and as long as it was 16.667 it was different?)

 

I saw some solution for this error saying I should abndom the new clock name (ft_clk) which I used in the constraints file and just use the physical name of the clock i.e., ftdi_clk -- which worked. This leaves me with the question why is there such a field called -name. Anyway this is not critical.

 

I will re-run the fifo version with and without the IBUFG and send you the schematics I get (although I am about to declare this bleeding open issue as closed!) -- I never imagined what can a (16.667-16.666)ns = 1ps do...

 

Thanks a lot (soon I'll be able to see if I am downloading images properly from the fpga).

0 Kudos
Adventurer
Adventurer
10,171 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Hi Avrum.

 

The 1ps is a great catch! I greatly appreaciate it. The story is not quite over - let me make it as brief as possible.

 

As you can see in the attached image, the naive PLL-less version which fails the timing constraints manages to transmit the image much (much) more accurately from the two possible deskewed option I'll describe next (one of which is shown - the other is basically very similar).

 

In the PLL-ed option, there seem to be two clocks in the game: the physical pin clk_ftdi, and the output from the wizard clk_out_FTDI_Clock. The constraints between wr# and data# can be formulated with respect to any of those (btw: the green text above shows the two lines in an .xdc file generated by the wizard in which the input, clk_ftdi, is declared as a 60MHz clock - the source of the conflict reported in the blue text). I tried both, and both seem to meet the timing (one would appear in the inter-clock report, one in the intra-clock report). In the attached image you can see the intra-case (results from constrints like: set_output_delay  -clock clk_out_Clock_FTDI -max  7.5 [get_ports {ftdi_wr}] where as the other option is: set_output_delay  -clock clk_ftdi -max  7.5 [get_ports {ftdi_wr}] ).

 

While the (successful) path report seems reasonable (containing a negative descewing step, and positive route and data steps) the general feeling is that somehow the constraints fail to describe reality.. I think the fact that I am gettign reasonable results from the failing case, means that the basic FTDI entity is ok, and it must be something to do with the timing. (btw: after reading carefully the meaning of min and max in case of input delay, I agree the txe# should be -min 9ns as you suggested).

 

You mentioned there should be a single clock - let me know if what I said makes sense or I am missing (yet again) something crucial. I thought of looking at the signals outputted from the fpga with a scope to see the differences between the failed and sucessful cases. Any other thoughts?

 

Many thanks for your help so far,

Raanan 

paths2.png
0 Kudos
Adventurer
Adventurer
9,343 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Here's that other option, which make more sense, of constraining data# and wr# w.r.t clk_ftdi, and descewing using a PLL. Its source clock path looks great, compensates for the delays, and the data path identical to that of the working-yet-failing design without the time compensation. It must be something else..  

path3.png
0 Kudos
Adventurer
Adventurer
9,304 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Hi Avrum,

 

So here is what I pomised to send you. A comparison between regular clock assignement (i.e., use the pin clock with no explicit buffering statement or mcmm/pll) and the one through IBUFG.

 

The attached image shows you the schematic generated by the synthesis step in which there is no ibuf in the ibufg buffering case. As I wrote to you - this version achieves faster rates as it has one less buffering stage. I take it that signals cannot enter the chip without going through the approperiate recieveing circuit, nevertheless, I've seen some descriptions (maybe one eda) saying there are some specialized pins (perhaps the clock capable?) which are supposed to better relate to bufg.

 

For some unknown reason this only happens in the version where I use fifo to decouple the clock domains.

 

I'll be happy to send you whatever if this indeed interests you. I am hoping to get things working without the fifo and waiting to see if you'll have any advice to my previous messages.

 

Thanks again,

Raanan

ibufg.png
0 Kudos
Historian
Historian
9,294 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

OK - now I understand the confusion...

 

You have been consistently talking about instantiation of the IBUFG (note the "I"), but really the difference is the instantiation of the BUFG (without the I). These are very different things

  - an IBUFG is an input buffer (its really an IBUF, as I talked about before)

  - a BUFG is a global clock buffer

 

How these two implementations differ depends greatly on what is in the FTDI module - is there some kind of clock buffer already in there? If so, instantiating a second one will greatly mess up timing....

 

Avrum

 

 

 

 

0 Kudos
Adventurer
Adventurer
9,282 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

No, I am not using the IBUFG anymore. 

 

The two post before the last describe two scenarios:

(i) no clock buffering (which creates IBUF and BUFG automatically)

(ii) use of PLL to deskew the timing (where there are still IBUF and BUFG - but their delay is roughly compensated).

 

The funny thing is that option (ii) meets the timing constraints, but its transfer is bad (see the images two posts above), and option (i) fails to meet the timing, nevertheless transfers the data up to occasional errors.

 

I was wondering whether the contraints should be w.r.t to the input ftdi clock or the buffered clock - while my guess is the input ftdi clock, both seem to fail the same way.

 

Raanan

0 Kudos
Scholar trenz-al
Scholar
9,237 Views
Registered: ‎11-09-2013

Re: Interfacing Kintex 7 with FT232h

there is one more way:

 

if you KNOW the FPGA primitives, and check that all what you wanted is clocked in the IOB, you may get away with one single constraint for the master clock. And all will work and reliable as the "important" timing path are all hardwired connections with fixed timing delays and any additonal constraint would not change them anyway.

0 Kudos
Adventurer
Adventurer
9,177 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Hi trenz-al, I am afraid I am not sure I understand your suggestion. Do you mean that I should constrain all the signals used in this path to the IOB?

Thanks!
0 Kudos
Adventurer
Adventurer
9,177 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

There is one path that seems odd to me, but perhaps I am not reading it correctly. The attached path goes from the input txe# (which allows writing to the ft232) to the data# w(which is the actual writing bus). The first is an input to the fpga and the other is an output.

 

In the path timing it appears that the data path is, I think, slow. Well, much like we had to descew/re-time the clock input - perhaps we should do the same for the txe? 

 

What's seems odd, is that the destination clock path time-count starts at 16.666 and not 0 -- I cannot understand why that is and whether it is a bad symptom.

 

One thing to note regarding the txe# - data# relashipship is that they are "half-slow" meaning that, when txe# goes down, I have all the time in the world to bring wr# down and fill-in data#. When it goes up, however, I should stop outputting - however if I miss doing that, all should happen is that a few bytes will be lost. As you can see from my previous post, the image is currupted -- there are weird values that the image should not contain. Hence, I think it is _the_ issue.

 

So, does the path seem ok - and should I somehow deskew txe#

 

Thanks 

susp_mmcm.png
0 Kudos
Adventurer
Adventurer
9,174 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

meant to say: it is NOT _the_ issue.
0 Kudos
Historian
Historian
9,169 Views
Registered: ‎01-23-2009

Re: Interfacing Kintex 7 with FT232h

The path is not going to the data#, but to the internal flip-flops in the FPGA that drive the data - i.e. this is not a combinatorial path through the FPGA (which would be pretty bad...)

 

The Data Path for this path is not slow at all. The external device supplies the TXE signal at 9ns after the rising edge of the clock, it goes through the IBUF, a LUT, and from there to a flip-flop, taking 3.5ns (or so), and it needs to be available before the next clock edge (at 16.66, which when deskewed is at around 15.6). Timing on this path is made with tons of slack - I don't know why you are concerned about this path.

 

As for "deskewing" data, that cannot be done. The whole concept of "deskewing" assumes that any edge of a periodic signal is identical to any other edge of the signal; a new clock is generated that has the correct phase so that, when delayed, it arrives at the time you want it. By definition it can only be done for a periodic signal (i.e. a clock).

 

Avrum

Tags (1)
0 Kudos
Adventurer
Adventurer
9,159 Views
Registered: ‎06-23-2015

Re: Interfacing Kintex 7 with FT232h

Mmm, say I have as inputs both a clock and a data bus. If I deskew the clock (so that some other output meets that clock in time) the input data and the clock are no longer in sync within_the_fpga_fabric. Could that happen?

If so, then the txe# which is an input to the fpga, is not synced with the (input) clock.

Raanan
0 Kudos