3
\$\begingroup\$

Using VHDL, How is it possible to receive a pair of LVDS signals (say external clock) on the FPGA and route them to another pairs of pins to go out, without any modification?

I have tried IBUFDS and OBUFDS with an intermediate single-ended signal in between but all I get at the output is a rising edge, not a clock. I also tried to put ODDR in between but I got the same.

I am using Xilinx 7 series FPGA (on Zynq) and it has LVDS pins. The VHDL code and the constraint file is like this:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity fanout is
  Port ( CLK_IN_P  : in  STD_LOGIC;
         CLK_IN_N  : in  STD_LOGIC;
         CLK_OUT_P : out STD_LOGIC;
         CLK_OUT_N : out STD_LOGIC;
         LD0       : out STD_LOGIC);
end Fanout;

architecture data_flow of fanout is
  signal clk_lvcmos : STD_LOGIC;
begin

  -- LVDS input to internal single
  CLK_IBUFDS : IBUFDS
  generic map(
    IOSTANDARD => "DEFAULT"
  )
  port map(
    I  => CLK_IN_P,
    IB => CLK_IN_N,
    O  => clk_lvcmos
  );

  -- Internal single to LVDS output  
  CLK_OBUFDS : OBUFDS
  generic map(
    IOSTANDARD => "DEFAULT"
  )
  port map(
    O  => CLK_OUT_P,
    OB => CLK_OUT_N,
    I  => clk_lvcmos
  );

end data_flow;

and the UCF file is:

# Input clock differential pair
NET CLK_IN_N LOC = C20  | IOSTANDARD=LVDS_25 | DIFF_TERM = TRUE;  # "FMC-LA18_CC_N"
NET CLK_IN_P LOC = D20  | IOSTANDARD=LVDS_25 | DIFF_TERM = TRUE;  # "FMC-LA18_CC_P"

# Output clock differential pair
NET CLK_OUT_N    LOC = G21  | IOSTANDARD=LVDS_25;  # "FMC-LA20_N"
NET CLK_OUT_P    LOC = G20  | IOSTANDARD=LVDS_25;  # "FMC-LA20_P"
\$\endgroup\$
  • 1
    \$\begingroup\$ Look at the pin constraint file/configuration for your device. Your FPGA may have diffPair inputs \$\endgroup\$ – JonRB Dec 11 '13 at 20:50
  • \$\begingroup\$ What does your VHDL code look like? What you describe sounds like the right thing to do, but there may be some detail in your code which is incorrect... \$\endgroup\$ – Martin Thompson Dec 13 '13 at 8:58
  • \$\begingroup\$ @MartinThompson I added the VHDL code to the question above. \$\endgroup\$ – dahma Dec 13 '13 at 12:05
  • \$\begingroup\$ I've never needed the generic map on an IBUF or OBUF, so try removing those. Can you try a trivial simulation to check things out also? \$\endgroup\$ – Martin Thompson Dec 13 '13 at 14:42
3
\$\begingroup\$

You can't properly describe an LVDS receiver or transmitter in VHDL. LVDS interfaces have electrical requirements that typically cannot be met by just using plain digital input and output pins. Your FPGA needs to have dedicated input and output macrocells for those functions and you would just instantiate them. Exactly how that is done depends on the exact FPGA and toolset you are using. Within the FPGA, there is just one signal that would come from the LVDS receiver and one signal that would go to the LVDS transmitter.

\$\endgroup\$
  • \$\begingroup\$ Thank you @JoeHass for the answer. I have modified the question with more information. I tired to assign the INs to the OUTs one by one (P to P and N to N) but I get errors. \$\endgroup\$ – dahma Dec 11 '13 at 21:12
2
\$\begingroup\$

What you need to do is to add an IBUFDS buffer and connct your signal to that pair.

IBUFDS is an input buffer that supports low-voltage, differential signaling. In IBUFDS, a design level interface signal is represented as two distinct ports (I and IB), one deemed the "master" and the other the "slave." The master and the slave are opposite phases of the same logical signal (for example, MYNET and MYNETB).

-- IBUFDS: Differential Input Buffer
--
-- The current version of the Xilinx HDL Libraries Guide
IBUFDS_inst : IBUFDS
-- Edit the following generic to specify the I/O standard for this port.
generic map (
IOSTANDARD => "LVDS_25")
port map (
          O => O, -- Clock buffer output
          I => I, -- Diff_p clock buffer input (connect to top-level port)
          IB => IB -- Diff_n clock buffer input (connect directly to top-level port)
);

++UPDATE The IOs from the UCF file of the Zedboard has the following signals:

NET FMC-LA18_CC_N LOC = C20  | IOSTANDARD=LVCMOS18;  # "FMC-LA18_CC_N"
NET FMC-LA18_CC_P LOC = D20  | IOSTANDARD=LVCMOS18;  # "FMC-LA18_CC_P"
NET FMC-LA20_N    LOC = G21  | IOSTANDARD=LVCMOS18;  # "FMC-LA20_N"
NET FMC-LA20_P    LOC = G20  | IOSTANDARD=LVCMOS18;  # "FMC-LA20_P"

So your IO standards are wrong. Maybe if you change that, you get it working.

\$\endgroup\$
  • \$\begingroup\$ as I said, I need LVSDS output not single-ended. So I have used IBUFDS to create a internal signal from the LVDS input and OBUFDS from the internal signal to a pair of LVDS output, but it doesn't work. \$\endgroup\$ – dahma Dec 11 '13 at 23:16
  • \$\begingroup\$ The problem is probably in your UCF file. Check out UG768 or look into this example : xilinx.com/member/adc_dac_lvds_interface/index.htm \$\endgroup\$ – FarhadA Dec 11 '13 at 23:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.