1

I'm writing a program to hopefully eventually communicate with the DVI codec on the SP605 board.

However, I am having problems outputting a differential clock to the DVI codec that is required and, it appears I need to use a ODDR2 in order to do so.

Although mentioned, I'm unsure on how to go about actually instantiating this in code; after reading the SelectIO resources and Spartan-6 Libraries guide it appears I should be able to instantiate this direction in code as below; however, when I do, I get the errors (1 for each ODDR2);

ERROR:HDLCompiler:432 - "C:\Users\EEEuser\Xilinix_Projects\i2c1\chron.vhd" Line 50: Formal <c1> has no actual or default value.
ERROR:HDLCompiler:432 - "C:\Users\EEEuser\Xilinix_Projects\i2c1\chron.vhd" Line 65: Formal <c1> has no actual or default value.

Why is this and how do I instantiate an ODDR2 (and other library resources)? I have been looking for a use library statement but haven't found one.

For reference, my overall aim is to output data to the DVI codec which should then be able to run the DVI port and output the data to a screen. At present, the data is all '1' because to begin with I'm looking just to get a white screen output.

The code showing my attempts at instantiating two ODDR2 modules are below.

Thanks very much!

David

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity chron is
    Port ( SYSCLK_N : in STD_LOGIC;
     SYSCLK_P : in STD_LOGIC;
              USRCLK: in STD_LOGIC; --27 MHz user clock
              PXLCLK_N : out  STD_LOGIC; --differential pixel clock
           PXLCLK_P : out  STD_LOGIC;
           D : out  STD_LOGIC_VECTOR (11 downto 0); --data bus
           H : out  STD_LOGIC; --hysnc
           V : out  STD_LOGIC; --vsync
           DE : out  STD_LOGIC); -- data enable
end chron;

architecture Behavioral of chron is

    component DCM
    port
     (-- Clock in ports
      SYSCLK_N           : in     std_logic;
      SYSCLK_P           : in     std_logic;
      -- Clock out ports
      PXLCLK_P          : out    std_logic;
      PXLCLK_N          : out    std_logic
     );
    end component;


    signal data_enable : std_logic := '1';--Data enable high when data video input
    signal data : std_logic_vector (11 downto 0) := (others => '1'); --data bus
    signal hsync, vsync : std_logic; --active low
    signal hsync_counter : integer range 0 to 512; --counter 0 to 450 for hsync using 27 MHz input clock
    signal vsync_counter : integer range 0 to 524288; --counter 0 to 359856 for vsync using 27 MHz
    signal pxlclk_p_int, pxlclk_n_int: std_logic; 

begin

  DCM_clock : DCM
  port map
  (-- Clock in ports
  SYSCLK_N => SYSCLK_N,
  SYSCLK_P => SYSCLK_P,
  -- Clock out ports
  PXLCLK_P => pxlclk_p_int,
  PXLCLK_N => pxlclk_n_int);

  ODDR_pxlclk_p : ODDR2
  generic map(
    DDR_ALIGNMENT => "NONE",
    INIT => '0',
    SRTYPE => "SYNC")
  port map (
    Q => PXLCLK_P,
    C0 => pxlclk_p_int,
    CE => not(pxlclk_p_int),
    D0 => '1',
    D1 => '0',
    R => '0',
    S =>'0'
  );

  ODDR_pxlclk_n : ODDR2
  generic map(
    DDR_ALIGNMENT => "NONE",
    INIT => '0',
    SRTYPE => "SYNC")
  port map (
    Q => PXLCLK_N,
    C0 => pxlclk_n_int,
    CE => not(pxlclk_n_int),
    D0 => '1',
    D1 => '0',
    R => '0',
    S =>'0'
  );

    hsync_proc : process(usrclk)
    begin
        if rising_edge(usrclk) then --only on rising edge
            if hsync_counter > 450 then
                hsync_counter <= 0; --reset counter to 0
            else
                if  hsync_counter < 33 then --else take low for 33 time periods
                    hsync <= '0';
                else --and then set high
                    hsync <= '1';
                end if;
                hsync_counter <= hsync_counter + 1; --increment counter
            end if;
        end if;
    end process;

    vsync_proc : process(usrclk)
    begin
        if rising_edge(usrclk) then --only on rising edge
            if vsync_counter > 359856 then
                vsync_counter <= 0; --reset counter to 0
            else
                if  vsync_counter < 1350 then --else take low for 1350 time periods
                    vsync <= '0';
                else --and then set high
                    vsync <= '1';
                end if;
                vsync_counter <= vsync_counter + 1; --increment counter
            end if;
        end if;
    end process;

    D <= (others => '1');
    H <= hsync;
    V <= vsync;
    DE <= '1';

end Behavioral;
davidhood2
  • 1,367
  • 17
  • 47
  • Are `PXLCLK_P` and `PXLCLK_N` connected to a differential pin pair of the FPGA? – Paebbels Nov 18 '15 at 16:08
  • I'm attempting to drive the Ch7301c DVI codec to produce any kind of output. In the data sheet, the Ch7301c requires a differential pixel clock, however - which to my understanding, I have attempted to do by simply creating two clock PXLCLK_P and PXLCLK_N at 60 MHz and 180 out of phase of each other – davidhood2 Nov 18 '15 at 17:00
  • 1
    Don't get confused. It is ok to use these two ODDR2. I have done this with an Virtex-5 FPGA and the same DVI codec before. Paebbels just wanted to point out, that another possibility would be to use one ODDR2 and one OBUFDS in the case that `PXCLK_P` and `PCLK_N` are connected to a differential pin pair. – Martin Zabel Nov 18 '15 at 19:13
  • I will certainly have a go with the OBUFDS - only thought is - if I'm driving my PXLCLK_P & PXLCLK_N with the OBUFDS - what will I need a ODDR2 for? – davidhood2 Nov 18 '15 at 19:47
  • 1
    The pixel clock must be 90° phase-shifted to the pixel data (clock center aligned to data), so that, the DVI transmittter can captured the data with rising and falling-edge. One way to ensure the timing is, to have all outputs clocked. If you need further advice, we can start a chat about it. – Martin Zabel Nov 18 '15 at 20:33
  • Hi Martin, after spending yesterday having a second go, I would love further advice! I used the (fixed) code above to try and get an output from the CH7301c but despite checking my signals on an oscilloscope, there was no output from the device - I can only guess that the registers have to be set in order to use it .Any help or sample code or similar would be massively appreciated! – davidhood2 Nov 20 '15 at 11:43

1 Answers1

2

The ODDR2 component has another input port C1 which must be assigned. A rising edge at C0 assigns Q <= D0 and a rising edge at C1 assigns Q <= D1.

So to mirror the clock, you must assign a 180° phase-shifted version of the clock-signal at port C0 to the port C1. But you have assigned it, to the port CE instead, which is the clock-enable.

The following should work for the first instance:

ODDR_pxlclk_p : ODDR2
generic map(
  DDR_ALIGNMENT => "NONE",
  INIT => '0',
  SRTYPE => "SYNC")
port map (
  Q => PXLCLK_P,
  C0 => pxlclk_p_int,
  C1 => not(pxlclk_p_int),
  CE => '1',
  D0 => '1',
  D1 => '0',
  R => '0',
  S =>'0'
);

Further improvements

You should output the clock only if the DCM has locked. You can enable an output LOCKED in the DCM wizard. Connect this output than with the CE input. Thus, only a stable clock will be seen by the DVI transmitter.

For driving the input C1 Xilinx recommends to use a 180° phase-shifted clock from the DCM. You already have this, named pxlclk_n_int.

Thus, the example could be improved to:

ODDR_pxlclk_p : ODDR2
generic map(
  DDR_ALIGNMENT => "NONE",
  INIT => '0',
  SRTYPE => "SYNC")
port map (
  Q => PXLCLK_P,
  C0 => pxlclk_p_int,
  C1 => pxlclk_n_int,  -- second clock signal from DCM
  CE => locked,        -- locked signal from DCM
  D0 => '1',
  D1 => '0',
  R => '0',
  S =>'0'
);

ODDR_pxlclk_n : ODDR2
generic map(
  DDR_ALIGNMENT => "NONE",
  INIT => '0',
  SRTYPE => "SYNC")
port map (
  Q => PXLCLK_N,
  C0 => pxlclk_p_int,  -- same clock signals as above
  C1 => pxlclk_n_int,  -- ...
  CE => locked,        -- 
  D0 => '0',           -- but inverted data
  D1 => '1',           -- ...
  R => '0',
  S =>'0'
);
Martin Zabel
  • 3,589
  • 3
  • 19
  • 34
  • 1
    Why are you using two ODDR2 instances to drive a diff. signal pair? The Spartan-6 should have OBUFDS instances to drive a diff. signal pair from one DDR register. – Paebbels Nov 18 '15 at 16:06
  • I didn't know about the OBUFDS and assumed two clocks 180 out of phase of each other would work (as above). – davidhood2 Nov 18 '15 at 17:03