[Xilinx 2VP] DDR + Differential Input

Hi guys,

It's been ages since I haven't posted anything here...

Well, I have a problem trying to build a design:

- 311 MHz LVDS clock to IBUFGDS

- to DCM

- generates CLK0 to BUFG (rxclk0_311a_ig)

- generates CLK180 to BUFG (rxclk180_311a_ig)

easy so far...

Data comes in as an LVDS differential nibble (or nybble :O) apologies from my Spanish-English), I am supposed to Double Data Rate the data...

I have tried instantiating the whole thing:

i_rxdata_a0: IBUFDS_LVDS_25 port map ( I => rxdata_a(0), IB => rxdata_a(1), O => rxdata_a_diff(0) );

i_rxdata_a1: IBUFDS_LVDS_25 port map ( I => rxdata_a(2), IB => rxdata_a(3), O => rxdata_a_diff(1) );

i_rxdata_a2: IBUFDS_LVDS_25 port map ( I => rxdata_a(4), IB => rxdata_a(5), O => rxdata_a_diff(2) );

i_rxdata_a3: IBUFDS_LVDS_25 port map ( I => rxdata_a(6), IB => rxdata_a(7), O => rxdata_a_diff(3) );

G_1: for i in rxdata_a_diff'range generate i_rxdata_a: IFDDRRSE port map ( Q0 => rxdata_a0(i), Q1 => rxdata_a1(i), C0 => rxclk0_311a_ig, C1 => rxclk180_311a_ig, CE => '1', D => rxdata_a_diff(i), R => areset, S => '0' ); end generate G_1;

Fair enough! I synthesize it with Precision and looks all right...

Then I use ISE to build it and during the translate process I get:

ERROR:NgdBuild:455 - logical net 'rxdata_a_diff(0)' has multiple drivers. The possible drivers causing this are pin O on block i_rxdata_a0 with type IBUFDS, pin PAD on block rxdata_a_diff(0) with type PAD

and the same for the 3 remaining bits...

It seems to thing that the 'rx_data_a_diff' is a block with PADs (?), I have try to remove PAD insertion in the whole design and still fails...

Any ideas in how to use DDR with differntial inputs?

Regards,

--
I.U. Hernandez
Reply to
I.U. Hernandez
Loading thread data ...

I hope my English translates well to Spanish.

Did you try just writing behavioral code and seeing what it did?

XST at least (I don't have Synplify or Precision at home) handles the following code correctly. The final output from PAR is an input buffer with DDR flip flops.

-- Phil Hays Phil-hays at posting domain should work for email ______________________ Cut Here ______________________________

library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; library unisim; use unisim.vcomponents.all; entity diffddr is port ( mainclk : in std_logic; rst : in std_logic; diffa : in std_logic; diffb : in std_logic; diffout : out std_logic; diffout_n : out std_logic ); end entity;

-- architecture insts of diffddr is signal clkin : std_logic; signal clkdv : std_logic; signal clk2x : std_logic; signal clk0 : std_logic; signal clk90 : std_logic; signal clk180 : std_logic; signal clk270 : std_logic; signal clkfx : std_logic; signal locked : std_logic; signal clk : std_logic; signal clk_n : std_logic; signal diff : std_logic; begin -- put in a DCM dcm_inst: dcm port map ( clkin => clkin, clkfb => clk, clk0 => clk0, clkdv => clkdv, clk2x => clk2x, clkfx => clkfx, clk90 => clk90, clk180 => clk180, clk270 => clk270, rst => rst, locked => locked ); --And a clock pad buffer clkbuf: IBUF port map ( o => clkin, i => mainclk ); -- and a bufg clktree: bufg port map ( i => clk0, o => clk ); clk_n diffa, IB => diffb, O => diff ); process (clk) begin if rising_edge(clk) then diffout

Reply to
Phil Hays

Thanks Phil,

Your English translates brilliantly to Spanish :O)

I have built successfully your 'diffddr' module with Leonardo and Precision, still a problem though...

The 'diffddr' module double-data-rates a single bit (std_logic) and I need to DDR an 8 bit bus, I've tried a data_width of 4 but it behaves the same as with a data_width = 1, follows the code (with data_width = 1 you basically have an std_logic although for the tools is considered a bus):

-------------Code starts here-------------------- library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; library unisim; use unisim.vcomponents.all; entity idiffddr_g is generic ( data_width : integer:=1 ); port ( mainclk_p : in std_logic; mainclk_n : in std_logic; rst : in std_logic; diff_p : in std_logic_vector(data_width-1 downto 0); diff_n : in std_logic_vector(data_width-1 downto 0); diffout : out std_logic_vector(data_width-1 downto 0); diffout_n : out std_logic_vector(data_width-1 downto 0) ); end entity;

architecture rtl of idiffddr_g is signal mainclk : std_logic; signal clk0 : std_logic; signal clk : std_logic; signal clk_n : std_logic; signal diff : std_logic_vector(data_width-1 downto 0); begin

i_ibufgds: IBUFGDS_LVDS_25 port map ( I => mainclk_p, IB => mainclk_n, O => mainclk );

-- put in a DCM i_dcm : DCM port map ( CLKIN => mainclk, CLKFB => clk, DSSEN => '0', PSINCDEC => '0', PSEN => '0', PSCLK => '0', RST => rst, CLK0 => clk0, LOCKED => open );

-- and a bufg i_bufg: bufg port map ( i => clk0, o => clk ); clk_n following code correctly. The final output from PAR is an input

Reply to
I. Ulises Hernandez

Good, as my Spanish is beyond awful ;-)

Please try the following code. I increased the generic width to 8, as that is what you are targeting. I added another layer of FFs to make sure there was no ambiguity as to where to force the FF into, and verified the map was forcing FFs into IOBs (map report file will have "-pr b" on the command line). I also split the clocked process into rising and falling edge sections as I have seen problems with this in the past. XST handles the following code correctly.

-- Phil Hays Phil-hays at posting domain should work for email

---------------------------- Cut Here -----------------------------

library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; library unisim; use unisim.vcomponents.all; entity idiffddr_g is generic ( data_width : integer:=8 ); port ( mainclk_p : in std_logic; mainclk_n : in std_logic; rst : in std_logic; diff_p : in std_logic_vector(data_width-1 downto 0); diff_n : in std_logic_vector(data_width-1 downto 0); diffout : out std_logic_vector(data_width-1 downto 0); diffout_n : out std_logic_vector(data_width-1 downto 0) ); end entity;

architecture rtl of idiffddr_g is signal mainclk : std_logic; signal clk0 : std_logic; signal clk : std_logic; signal clk_n : std_logic; signal diff : std_logic_vector(data_width-1 downto 0); signal difft : std_logic_vector(data_width-1 downto 0); signal difft_n : std_logic_vector(data_width-1 downto 0); begin

i_ibufgds: IBUFGDS_LVDS_25 port map ( I => mainclk_p, IB => mainclk_n, O => mainclk );

-- put in a DCM i_dcm : DCM port map ( CLKIN => mainclk, CLKFB => clk, DSSEN => '0', PSINCDEC => '0', PSEN => '0', PSCLK => '0', RST => rst, CLK0 => clk0, LOCKED => open );

-- and a bufg i_bufg: bufg port map ( i => clk0, o => clk ); clk_n

Reply to
Phil Hays

Hi Phil,

Good thinking ;o)

Thanks a lot, I haven't tried it yet but sounds good to me. I'll try it tomorrow in the office with Precision and XST and let you know.

Regards,

-- I.Ulises Hernandez 'postmaster' at posting domain should work for email

Precision,

Reply to
I.U. Hernandez

Phil,

It works just fine with Precision. The "-pr b" option is the default one so... just adding the extra pipe of FFs made the trick. Excellent!

Thanks again, very appreciated.

Regards,

-- I. Ulises Hernandez 'ulises' at posting domain should work for email

Precision,

Reply to
I. Ulises Hernandez

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.