Real-Time Measurement and Control

cancel
Showing results for 
Search instead for 
Did you mean: 

PXIe-7975R with Kintex-7 FPGA - LVDS problem

Solved!
Go to solution

Hi,

I've developed a custom FLEX RIO module (Digitizer18, 0xAB66 - vendor id) and trying to use it  with PXIe-7975R FPGA card (Kintex-7 FPGA)

I have a problem trying to output LVDS signal via aUserGpio(61) and  aUserGpio_n(61).

These pins are not K7 clock capable, but I used this FLEX RIO module with PXIe-7962R (Virtex-5 FPGA) where these pins are REGIONAL clock capable and it worked fine.

With Kintex-7 it compiles without errors but i didn't see signals on pins aUserGpio(61) and aUserGpio_n(61), although ADC2_FSM is switching its state.

Is it possible to use pins which is not clock capable to output LVDS or I am doomed to use MRCC or SRCC pins?

Thank you

 

My xdc file ( aUserGpio(61) and aUserGpio_n(61) belong to Bank 18) :

set_property IOSTANDARD LVDS_25 [get_ports {aUserGpio[61]}]
set_property DIFF_TERM FALSE [get_ports {aUserGpio[61]}]
set_property IOSTANDARD LVDS_25 [get_ports {aUserGpio_n[61]}]
set_property DIFF_TERM FALSE [get_ports {aUserGpio_n[61]}]

 

# all unused pins of Bank 18 are LVCMOS25 

set_property IOSTANDARD LVCMOS25      [get_ports {aUserGpio[49]}]
set_property SLEW SLOW                             [get_ports {aUserGpio[49]}]
set_property DRIVE 8                                      [get_ports {aUserGpio[49]}]
set_property IOB FALSE                                  [get_ports {aUserGpio[49]}]

...

 

part of my vhd clip  file (cause it's too large and all other LVTTL logic works fine except LVDS):

 

    attribute dont_touch : string;
    signal ADC2_CNV_buf : std_logic := '1' ;    
    attribute dont_touch of ADC2_CNV_buf : signal is "true";

 

    OBUFDS_ADC2_CNV : OBUFDS
    port map (
        O  => aUserGpio(61),     -- Diff_p output (connect directly to top-level port)
        OB => aUserGpio_n(61),   -- Diff_n output (connect directly to top-level port)
        I => ADC2_CNV_buf  -- Buffer input
    );

....

 

    process ( LVDS_CLK ) -- 200 MHz
    begin    
        if LVDS_CLK'event and LVDS_CLK='1' then
            case ADC2_FSM is            
                when s0 =>
                    if ADC2_CNV = '0' then
                        ADC2_timer1 <= (others=>'0');
                        ADC2_timer2 <= (others=>'0');                     
                        ADC2_CLK <= '1';
                        ADC2_READY <= '0';
                        ADC2_CNV_buf <= '1' ;
                        ADC2_FSM <= s1;
                    end if;
                when s1 =>
                    if ADC2_CNV = '1' then         
                        ADC2_CNV_buf <= '0' ;                            
                        ADC2_RESET <= '1';                                    
                        ADC2_FSM <= s2;
                    end if;
                when s2 => ADC2_FSM <= s3;
                when s3 => ADC2_FSM <= s4;
                when s4 => ADC2_FSM <= s5;
                when s5 =>
                    ADC2_CNV_buf <= '1' ;    
                    ADC2_RESET <= '0';
                    ADC2_FSM <= s6;     
                when s6 =>
                    if ADC2_timer1 < x"28" then -- x"28"
                        ADC2_timer1 <= ADC2_timer1 + 1;  
                    else
                        ADC2_FSM <= s7;
                    end if;        
                when s7 =>
                    ADC2_CLK <= not ADC2_CLK;
                    if ADC2_timer2 < x"24" then
                        ADC2_timer2 <= ADC2_timer2 + 1;
                    else
                        ADC2_READY <= '1';
                        ADC2_FSM <= s0;        
                    end if;         
                when others => ADC2_FSM <= s0;    
            end case;          
        end if;               
    end process;

 

    -- the host uses the rising edge of DCO± to capture D±
    process ( UserGClk2, ADC1_RESET ) -- DCO2 echo clock
    begin    
        if ADC1_RESET = '1' then
            ADC2_READ_FSM <= s0;    
            ADC2_BUF <= (others=>'0');        
        elsif UserGClk2'event and UserGClk2='0' then -- the host uses the rising edge of DCO± to capture D±
            case ADC2_READ_FSM is            
                when s0 =>  ADC2_BUF(17) <= not D2 ; ADC2_READ_FSM <= s1;
                when s1 =>  ADC2_BUF(16) <= not D2 ; ADC2_READ_FSM <= s2;
                when s2 =>  ADC2_BUF(15) <= not D2 ; ADC2_READ_FSM <= s3;
                when s3 =>  ADC2_BUF(14) <= not D2 ; ADC2_READ_FSM <= s4;
                when s4 =>  ADC2_BUF(13) <= not D2 ; ADC2_READ_FSM <= s5;
                when s5 =>  ADC2_BUF(12) <= not D2 ; ADC2_READ_FSM <= s6;
                when s6 =>  ADC2_BUF(11) <= not D2 ; ADC2_READ_FSM <= s7;
                when s7 =>  ADC2_BUF(10) <= not D2 ; ADC2_READ_FSM <= s8;
                when s8 =>  ADC2_BUF(9)  <= not D2 ; ADC2_READ_FSM <= s9;
                when s9 =>  ADC2_BUF(8)  <= not D2 ; ADC2_READ_FSM <= s10;
                when s10 => ADC2_BUF(7)  <= not D2 ; ADC2_READ_FSM <= s11;
                when s11 => ADC2_BUF(6)  <= not D2 ; ADC2_READ_FSM <= s12;
                when s12 => ADC2_BUF(5)  <= not D2 ; ADC2_READ_FSM <= s13;
                when s13 => ADC2_BUF(4)  <= not D2 ; ADC2_READ_FSM <= s14;
                when s14 => ADC2_BUF(3)  <= not D2 ; ADC2_READ_FSM <= s15;
                when s15 => ADC2_BUF(2)  <= not D2 ; ADC2_READ_FSM <= s16;
                when s16 => ADC2_BUF(1)  <= not D2 ; ADC2_READ_FSM <= s17;
                when s17 => ADC2_BUF(0)  <= not D2 ; ADC2_READ_FSM <= s18;
                when s18 => ADC2_READ_FSM <= s18;
                when others => ADC2_READ_FSM <= s0;    
            end case;          
        end if;               
    end process;
    
    ADC2_DATA <= "00000000000000" & ADC2_BUF ;

 

 

0 Kudos
Message 1 of 8
(7,360 Views)

Hi cornflyer,

 

I'm currently looking into this issue to see if there are any workarounds for the behavior you are experiencing.  I should have more information within two days.

0 Kudos
Message 2 of 8
(7,323 Views)

ADC1 is connected to gpio(58) pins (which is SRCC i.e. clock capable) and there is no signals on ADC1_CNV_buf  LVDS output pins although ADC1_CNV_buf  is continuously toggling within ADC1_FSM - take a look below at ADC1_FSM !

 

    OBUFDS_ADC1_CNV : OBUFDS
    generic map (
      IOSTANDARD => "LVDS_25", -- Specify the output I/O standard
      SLEW => "FAST")          -- Specify the output slew rate
    port map (
        O  => aUserGpio(58),     -- Diff_p output (connect directly to top-level port)
        OB => aUserGpio_n(58),   -- Diff_n output (connect directly to top-level port)
        I => ADC1_CNV_buf     -- Buffer input
    );    
   

    process ( LVDS_CLK ) -- 200 MHz
    begin    
        if LVDS_CLK'event and LVDS_CLK='1' then
            case ADC1_FSM is            
                when s0 =>
                    if ADC1_CNV = '0' then
                        ADC1_timer1 <= (others=>'0');
                        ADC1_timer2 <= (others=>'0');                     
                        ADC1_CLK <= '0';
                        ADC1_READY <= '0';     
                        ADC1_FSM <= s1;
                    end if;
                when s1 =>
                    if ADC1_CNV = '1' then         
                        ADC1_CNV_buf <= '1' ;                            
                        ADC1_RESET <= '1';                                    
                        ADC1_FSM <= s2;
                    end if;
                when s2 => ADC1_FSM <= s3;
                when s3 => ADC1_FSM <= s4;
                when s4 => ADC1_FSM <= s5;
                when s5 =>
                    ADC1_CNV_buf <= '0' ;    
                    ADC1_RESET <= '0';
                    ADC1_FSM <= s6;     
                when s6 =>
                    if ADC1_timer1 < x"28" then -- x"28"
                        ADC1_timer1 <= ADC1_timer1 + 1;  
                    else
                        ADC1_FSM <= s7;
                    end if;        
                when s7 =>
                    ADC1_CLK <= not ADC1_CLK;
                    if ADC1_timer2 < x"24" then
                        ADC1_timer2 <= ADC1_timer2 + 1;
                    else
                        ADC1_READY <= '1';
                        ADC1_FSM <= s0;        
                    end if;         
                when others => ADC1_FSM <= s0;    
            end case;          
        end if;               
    end process;

 

PS

look at my current clip files (LVDS output still doesn't work) attached below

Download All
0 Kudos
Message 3 of 8
(7,306 Views)

Hi cornflyer,

 

Thank you for providing more information.  I'm currently in the process of escalating this issue to see if we can find a workaround.

0 Kudos
Message 4 of 8
(7,279 Views)

Kintex-7 datasheet  (http://www.xilinx.com/support/documentation/user_guides/ug471_7Series_SelectIO.pdf😞

 

The LVDS I/O standard is only available in the HP I/O banks. It requires a VCCO to be
powered at 1.8V for outputs and for inputs when the optional internal differential
termination is implemented (DIFF_TERM = TRUE).

The LVDS_25 I/O standard is only available in the HR I/O banks. It requires a VCCO to be
powered at 2.5V for outputs and for inputs when the optional internal differential
termination is implemented (DIFF_TERM = TRUE).

 

For current xc7k410t package Bank 18(i use aUserGpio(58) and aUserGpio_n(58))

and Bank 17 (i use aUserGpio(38) and  aUserGpio_n(38)) are HR.

 

So it must work with LVDS_25 and LVCMOS25

 

 

0 Kudos
Message 5 of 8
(7,269 Views)

Today i've done a simle clip for investigating my problem:

1) xdc file is emplty

2) clip vhdl code is very simple:

Library IEEE;
use IEEE.Std_Logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity TestCLIP is port(
    aResetSl                    : in std_logic;
    aUserGpio                   : inout std_logic_vector(67 downto 0);
    aUserGpio_n                 : inout std_logic_vector(67 downto 0);
    rIoModGpioEn                : in    std_logic;
    rLvFpgaReqI2cBus            : out  std_logic;
    rLvFpgaAckI2cBus            : in   std_logic;
    rLvFpgaI2cGo                : out  std_logic;
    rLvFpgaI2cStart             : out  std_logic;
    rLvFpgaI2cStop              : out  std_logic;
    rLvFpgaI2cRd                : out  std_logic;
    rLvFpgaI2cWtData            : out  std_logic_vector(7 downto 0);
    rLvFpgaI2cAck               : in   std_logic;
    rLvFpgaI2cDone              : in   std_logic;
    rLvFpgaI2cRdData            : in   std_logic_vector(7 downto 0);
    rClkToSocket                : in   std_logic;	
	c100TdcDeassert : out std_logic;
	Clk100 : in std_logic;
	rTdcPulseWidth : in std_logic_vector(15 downto 0);	
	rTdcPulseWidthValid : in std_logic;
	TdcAssertClk : in std_logic; 
	tTdcAssert : out std_logic;
    
	-- CLOCK
	Clock_RIO : in std_logic
);    
end TestCLIP;

architecture behavioral of TestCLIP is
    
	component OBUFDS generic (
		IOSTANDARD:string := "LVDS";
		SLEW :string :=  "FAST");
	port ( 
		O : out std_logic; 
		OB : out std_logic; 
		I : in  std_logic 
	);
	end component;

	component BUFG
	port (
	  I : in std_logic;
	  O : out std_logic);
	end component; 
  
 	type ADC_STATE is ( s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18 ) ;  
	
	signal ADC2_FSM : ADC_STATE := s0 ; 
	signal zzz : std_logic := '0' ;
begin
	OBUFDS_inst : OBUFDS
    generic map (
      IOSTANDARD => "LVDS", 
      SLEW => "FAST")         
	port map (
	   O =>  aUserGpio(61),
	   OB => aUserGpio_n(61),
	   I =>  zzz
	);	
	
	process ( Clock_RIO ) -- 40 MHz
	begin	
		if Clock_RIO'event and Clock_RIO='1' then 
			case ADC2_FSM is			
				when s0 => 
					zzz <= '0' ;
					ADC2_FSM <= s1; 
				when s1 => 
					zzz <= '1' ;
					ADC2_FSM <= s0; 
				when others => ADC2_FSM <= s0;	
			end case;  		
		end if;	   		
	end process;
	

 

ERROR: [Place 30-743] IO/clock placer failed to collectively place all IOs and clock instances. This is likely due to design requirements or user constraints specified in the constraint file such as IO standards, bank/voltage/DCI/VREF specifications, together with the part and package being used for the implementation. Please check the above for any possible conflicts.
ERROR: [Drc 23-20] Rule violation (BIVB-1) Bank IO standard Support - Bank 18 has incompatible IO(s) because: The LVDS I/O standard is not supported.  Move the following ports or change their properties:  
aUserGpio[61]

0 Kudos
Message 6 of 8
(7,257 Views)

Luke, wish you solved the problem

 

0 Kudos
Message 7 of 8
(7,207 Views)
Solution
Accepted by cornflyer

i've made some changes to TestCLIP.fam :

...

[FlexRIO-K7IOModule]
DefaultCLIP = TestCLIP
VccoLevel=2.5

...

 

And my xdc file now looks like:

 

# Set the bank voltage for bank 18.
#set_property IOSTANDARD LVCMOS25 [get_ports -filter { IOBANK == 18 } ]

set_property IOSTANDARD LVCMOS25 [get_ports {aUserGpio[*]}]
set_property IOSTANDARD LVCMOS25 [get_ports {aUserGpio_n[*]}]
set_property IOSTANDARD LVDS_25 [get_ports {aUserGpio[58]}]
set_property IOSTANDARD LVDS_25 [get_ports {aUserGpio_n[58]}]
set_property IOSTANDARD LVDS_25 [get_ports {aUserGpio[67]}]
set_property IOSTANDARD LVDS_25 [get_ports {aUserGpio_n[67]}]

 

Now it works.

 

0 Kudos
Message 8 of 8
(7,194 Views)