FPGARelated.com
Forums

[Xilinx 2VP] DDR + Differential Input

Started by I.U. Hernandez July 5, 2004
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



"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;
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) 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; >
"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;
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 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; >
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 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; >