Доступ к Spartan-6 ODDR и другим библиотекам selectIO в ISE

Я пишу программу для связи с кодеком DVI на плате SP605.

Однако у меня возникли проблемы с выводом дифференциального тактового сигнала на требуемый кодек DVI, и, похоже, для этого мне нужно использовать ODDR2.

Несмотря на упоминание, я не уверен, как на самом деле создать экземпляр этого в коде; после прочтения ресурсов SelectIO и руководства по библиотекам Spartan-6 кажется, что я должен быть в состоянии реализовать это направление в коде, как показано ниже; однако, когда я это делаю, я получаю ошибки (по 1 для каждого 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.

Почему это так и как создать экземпляр ODDR2 (и других библиотечных ресурсов)? Я искал оператор библиотеки use , но не нашел.

Для справки, моей общей целью является вывод данных в кодек DVI, который затем должен иметь возможность запускать порт DVI и выводить данные на экран. В настоящее время все данные '1', потому что для начала я просто хочу получить вывод на белый экран.

Код, показывающий мои попытки создания экземпляров двух модулей ODDR2, приведен ниже.

Спасибо большое!

Дэйвид

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;

person davidhood2    schedule 18.11.2015    source источник
comment
Подключены ли PXLCLK_P и PXLCLK_N к дифференциальной паре контактов FPGA?   -  person Paebbels    schedule 18.11.2015
comment
Я пытаюсь управлять кодеком Ch7301c DVI для получения любого вывода. Однако в техническом описании для Ch7301c требуется дифференциальная тактовая частота пикселей, что, насколько я понимаю, я попытался сделать, просто создав два тактовых сигнала PXLCLK_P и PXLCLK_N с частотой 60 МГц и смещением по фазе 180 друг от друга.   -  person davidhood2    schedule 18.11.2015
comment
Не запутайтесь. Можно использовать эти два ODDR2. Я уже делал это с помощью FPGA Virtex-5 и того же кодека DVI. Пэббельс просто хотел указать, что другой возможностью было бы использование одного ODDR2 и одного OBUFDS в случае, когда PXCLK_P и PCLK_N подключены к дифференциальной паре контактов.   -  person Martin Zabel    schedule 18.11.2015
comment
Я, безусловно, попробую OBUFDS - единственная мысль - если я буду управлять своими PXLCLK_P и PXLCLK_N с OBUFDS - для чего мне нужен ODDR2?   -  person davidhood2    schedule 18.11.2015
comment
Тактовая частота пикселя должна быть сдвинута по фазе на 90° относительно данных пикселя (центр тактовой частоты выровнен по данным), чтобы передатчик DVI мог захватывать данные с нарастающим и спадающим фронтом. Один из способов обеспечить синхронизацию — синхронизировать все выходы. Если вам нужен дополнительный совет, мы можем начать чат об этом.   -  person Martin Zabel    schedule 18.11.2015
comment
Привет, Мартин, проведя вчера второй раз, я хотел бы получить дополнительные советы! Я использовал (исправленный) код выше, чтобы попытаться получить выходной сигнал от CH7301c, но, несмотря на проверку моих сигналов на осциллографе, выходного сигнала от устройства не было - я могу только догадываться, что регистры должны быть установлены, чтобы использовать его .Любая помощь или образец кода или что-то подобное будут очень признательны!   -  person davidhood2    schedule 20.11.2015


Ответы (1)


Компонент ODDR2 имеет другой входной порт C1, который необходимо назначить. Нарастающий фронт на C0 назначает Q <= D0, а нарастающий фронт на C1 назначает Q <= D1.

Таким образом, чтобы отразить часы, вы должны назначить версию сигнала часов со сдвигом по фазе на 180° в порту C0 для порта C1. Но вместо этого вы назначили его порту CE, который поддерживает часы.

Следующее должно работать для первого экземпляра:

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

Дальнейшие улучшения

Вы должны выводить часы, только если DCM заблокирован. Вы можете включить выход LOCKED в мастере DCM. Подключите этот выход к входу CE. Таким образом, передатчик DVI увидит только стабильные часы.

Для управления входом C1 Xilinx рекомендует использовать часы с фазовым сдвигом на 180° от DCM. У вас уже есть это имя 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,
  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'
);
person Martin Zabel    schedule 18.11.2015
comment
Почему вы используете два экземпляра ODDR2 для управления diff. сигнальная пара? Spartan-6 должен иметь экземпляры OBUFDS для управления diff. сигнальная пара из одного регистра DDR. - person Paebbels; 18.11.2015
comment
Я не знал об OBUFDS и предположил, что два тактовых генератора, сдвинутые по фазе друг на друга на 180, будут работать (как указано выше). - person davidhood2; 18.11.2015