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
[Xilinx 2VP] DDR + Differential Input
Started by ●July 5, 2004
Reply by ●July 5, 20042004-07-05
"I.U. Hernandez" <ulises@aliathon.com> wrote:>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 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 <= not clk; -- Now the test code diff0: IBUFDS_LVDS_25 port map ( I => diffa, IB => diffb, O => diff ); process (clk) begin if rising_edge(clk) then diffout <= diff; end if; end process; process(clk) begin if falling_edge(clk) then diffout_n <= diff; end if; end process; end;
Reply by ●July 6, 20042004-07-06
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 <= not clk; -- Now the test code g_ibufds: for i in diff'range generate diff0: IBUFDS_LVDS_25 port map ( I => diff_p(i), IB => diff_n(i), O => diff(i) ); end generate; process (clk) begin if rising_edge(clk) then diffout <= diff; end if; if falling_edge(clk) then diffout_n <= diff; end if; end process; end; -------------Code ends here-------------------- As soon as I add the generic width (even if is not a generic), nahh, it doesn't work! The synthesizer output is 'the same' for module 'idiffddr' and 'idiffddr_g' but ISE seems to push only the 'rising_edge' FF and then the falling edge into the output IOB...is not using the DDR. It's like if the mapper considers the IOB as a bit-wide structure and when it sees a bus, even if the bus is 1-bit wide :) it breaks. Have you tried your module with x-bit wide input data...? Thanks in advance, I.U. Hernandez "Phil Hays" <Spampostmaster@comcast.net> wrote in message news:b58je01vq60g3a8aql4h8ck7il2ta83eoj@4ax.com...> "I.U. Hernandez" <ulises@aliathon.com> wrote: > > >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) apologiesfrom> >my Spanish-English), I am supposed to Double Data Rate the data... > > > >I have tried instantiating the whole thing: > > 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 <= not clk; > -- Now the test code > diff0: IBUFDS_LVDS_25 port map ( > I => diffa, > IB => diffb, > O => diff > ); > process (clk) begin > if rising_edge(clk) then > diffout <= diff; > end if; > end process; > process(clk) begin > if falling_edge(clk) then > diffout_n <= diff; > end if; > end process; > end; >
Reply by ●July 6, 20042004-07-06
"I. Ulises Hernandez" <delete@e-vhdl.com> wrote:>Your English translates brilliantly to Spanish :O)Good, as my Spanish is beyond awful ;-)>I have built successfully your 'diffddr' module with Leonardo and Precision, >still a problem though...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 <= not clk; -- Now the test code g_ibufds: for i in diff'range generate diff0: IBUFDS_LVDS_25 port map ( I => diff_p(i), IB => diff_n(i), O => diff(i) ); end generate; process (clk) begin if rising_edge(clk) then difft <= diff; diffout <= difft; end if; end process; -- Falling edge clock is in a seperate process to avoid -- problems with some synthesis tools. process (clk) begin if falling_edge(clk) then difft_n <= diff; diffout_n <= difft_n; end if; end process; end;
Reply by ●July 6, 20042004-07-06
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 "Phil Hays" <Spampostmaster@comcast.net> wrote in message news:cr2me0pm20cbkok7htbv1mifhifegbt95k@4ax.com...> "I. Ulises Hernandez" <delete@e-vhdl.com> wrote: > > >Your English translates brilliantly to Spanish :O) > > Good, as my Spanish is beyond awful ;-) > > > >I have built successfully your 'diffddr' module with Leonardo andPrecision,> >still a problem though... > > 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 <= not clk; > > -- Now the test code > g_ibufds: for i in diff'range generate > diff0: IBUFDS_LVDS_25 port map ( > I => diff_p(i), > IB => diff_n(i), > O => diff(i) > ); > end generate; > > process (clk) begin > if rising_edge(clk) then > difft <= diff; > diffout <= difft; > end if; > end process; > -- Falling edge clock is in a seperate process to avoid > -- problems with some synthesis tools. > process (clk) begin > if falling_edge(clk) then > difft_n <= diff; > diffout_n <= difft_n; > end if; > end process; > end; >
Reply by ●July 7, 20042004-07-07
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 "Phil Hays" <Spampostmaster@comcast.net> wrote in message news:cr2me0pm20cbkok7htbv1mifhifegbt95k@4ax.com...> "I. Ulises Hernandez" <delete@e-vhdl.com> wrote: > > >Your English translates brilliantly to Spanish :O) > > Good, as my Spanish is beyond awful ;-) > > > >I have built successfully your 'diffddr' module with Leonardo andPrecision,> >still a problem though... > > 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 <= not clk; > > -- Now the test code > g_ibufds: for i in diff'range generate > diff0: IBUFDS_LVDS_25 port map ( > I => diff_p(i), > IB => diff_n(i), > O => diff(i) > ); > end generate; > > process (clk) begin > if rising_edge(clk) then > difft <= diff; > diffout <= difft; > end if; > end process; > -- Falling edge clock is in a seperate process to avoid > -- problems with some synthesis tools. > process (clk) begin > if falling_edge(clk) then > difft_n <= diff; > diffout_n <= difft_n; > end if; > end process; > end; >