06-26-2016 02:10 PM
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 ;
Solved! Go to Solution.
06-27-2016 04:42 PM
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.
06-28-2016 10:07 AM - edited 06-28-2016 10:09 AM
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
06-29-2016 04:47 PM
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.
06-30-2016 03:16 AM - edited 06-30-2016 03:37 AM
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
06-30-2016 09:20 AM
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]
07-04-2016 06:32 PM
Luke, wish you solved the problem
07-06-2016 04:10 AM
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.