HDMI Pass Through с переключением фильтра RGB

Я очень новичок в VHDL и FPGA и ударил по скале. В настоящее время я работаю над видеофильтрами на zybo z7-10 и начал использовать это руководство для создания сквозного HDMI на плате: https://github.com/dpaul24/hdmi_pass_through_ZyboZ7-10?_ga=2.34188391.796043983.19957.8a10279-2106>

Итак, после того, как я заработал, все, что я хочу сделать, это иметь возможность влиять на вывод видео. Для этого я попытался установить последние 8 бит 24-битных векторов RGB в 0, удалив весь синий цвет из вывода. Если я попробую следующий код (с блоком процесса или без него), я получу синтаксическую ошибку в строке оператора «если».

process is 
begin
    if sw ='0' then
        vid_pData(7 downto 0) <= sw
    end if;
end process;

Проблема в том, что я, кажется, не могу поместить это где-нибудь в код, не вызывая ошибки. Может кто-нибудь объяснить, что здесь происходит?

Полный код ниже:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity hdmi_pass_top is
    Port ( 
        sysclk_i         : in  std_logic; -- 125MH System Clock Input
        async_reset_i    : in  std_logic; -- Reset switch on board

        -- HDMI In/Rx
        tmds_rx_clk_p_i  : in  std_logic;
        tmds_rx_clk_n_i  : in  std_logic;
        tmds_rx_data_p_i : in  std_logic_vector(2 downto 0);
        tmds_rx_data_n_i : in  std_logic_vector(2 downto 0);
        hdmi_rx_hpd_o    : out std_logic := '1'; -- HPD must be driven
        -- I2C
        sda_io           : inout std_logic;
        scl_io           : inout std_logic;

        -- HDMI Out/Tx
        tmds_tx_clk_p_o  : out std_logic;
        tmds_tx_clk_n_o  : out std_logic;
        tmds_tx_data_p_o : out std_logic_vector(2 downto 0);
        tmds_tx_data_n_o : out std_logic_vector(2 downto 0);    

        sw               : in std_logic
         );
end hdmi_pass_top;


architecture hdmi_pass_top_arc of hdmi_pass_top is

component dvi2rgb_0
  port (
    TMDS_Clk_p    : in std_logic;
    TMDS_Clk_n    : in std_logic;
    TMDS_Data_p   : in std_logic_vector(2 downto 0);
    TMDS_Data_n   : in std_logic_vector(2 downto 0);
    RefClk        : in std_logic;
    aRst          : in std_logic;
    vid_pData     : out std_logic_vector(23 downto 0);
    vid_pVDE      : out std_logic;   
    vid_pHSync    : out std_logic;
    vid_pVSync    : out std_logic;
    PixelClk      : out std_logic;
    aPixelClkLckd : out std_logic;
    SDA_I         : in std_logic;
    SDA_O         : out std_logic;
    SDA_T         : out std_logic;
    SCL_I         : in std_logic;
    SCL_O         : out std_logic;
    SCL_T         : out std_logic;
    pRst          : in std_logic
  );
end component;

component rgb2dvi_0
  PORT (
    TMDS_Clk_p  : out std_logic;
    TMDS_Clk_n  : out std_logic;
    TMDS_Data_p : out std_logic_vector(2 downto 0);
    TMDS_Data_n : out std_logic_vector(2 downto 0);
    aRst        : in std_logic;
    vid_pData   : in std_logic_vector(23 downto 0);
    vid_pVDE    : in std_logic;
    vid_pHSync  : in std_logic;
    vid_pVSync  : in std_logic;
    PixelClk    : in std_logic
  );
end component;


component clk_wiz_0
port
 (-- Clock in ports
  -- Clock out ports
  clk_out1          : out    std_logic;
  -- Status and control signals
  reset             : in     std_logic;
  locked            : out    std_logic;
  clk_in1           : in     std_logic
 );
end component;

signal vid_pData          : std_logic_vector(23 downto 0);
signal vid_pVDE           : std_logic;
signal vid_pHSync         : std_logic;
signal vid_pVSync         : std_logic;
signal pixelclk           : std_logic;
signal locked             : std_logic;
signal clk_200M           : std_logic;
signal pixel_clk_sync_rst : std_logic;

signal sda_i              : std_logic;
signal sda_o              : std_logic;
signal sda_t              : std_logic;
signal scl_i              : std_logic;
signal scl_o              : std_logic;
signal scl_t              : std_logic;

begin

clkwiz_inst : clk_wiz_0
   port map ( 
  -- Clock out ports  
   clk_out1 => clk_200M,
  -- Status and control signals                
   reset   => async_reset_i,
   locked  => locked,
   -- Clock in ports
   clk_in1 => sysclk_i
 );

dvi2rgb_inst : dvi2rgb_0
  port map (
    TMDS_Clk_p    => tmds_rx_clk_p_i,
    TMDS_Clk_n    => tmds_rx_clk_n_i,
    TMDS_Data_p   => tmds_rx_data_p_i,
    TMDS_Data_n   => tmds_rx_data_n_i,
    RefClk        => clk_200M,
    aRst          => async_reset_i, --Active high asynchronous RefClk reset
    vid_pData     => vid_pData,
    vid_pVDE      => vid_pVDE,
    vid_pHSync    => vid_pHSync,
    vid_pVSync    => vid_pVSync,
    PixelClk      => pixelclk,
    aPixelClkLckd => open, -- 
    SDA_I         => sda_i,
    SDA_O         => sda_o,
    SDA_T         => sda_t,
    SCL_I         => scl_i,
    SCL_O         => scl_o,
    SCL_T         => scl_t,
    pRst          => '0'   -- Active high PixelClk synchronous reset
  );


SDA_IOBUF_inst: IOBUF
    generic map(
    DRIVE      => 12,
    IOSTANDARD => "DEFAULT",
    SLEW       => "SLOW"
    )
    port map(
    O  => sda_i,  -- Buffer output
    IO => sda_io, -- Buffer inout port(connect directly to top-level port)
    I  => sda_o,  -- Bufferinput
    T  => sda_t   -- 3-state enable input,high=input,low=output
    ); 



SCL_IOBUF_inst: IOBUF
    generic map(
    DRIVE      => 12,
    IOSTANDARD => "DEFAULT",
    SLEW       => "SLOW"
    )
    port map(
    O  => scl_i,  -- Buffer output
    IO => scl_io, -- Buffer inout port(connect directly to top-level port)
    I  => scl_o,  -- Buffer input
    T  => scl_t   -- 3-state enable input,high=input,low=output
    ); 

rgb2dvi_inst : rgb2dvi_0
  port map (
    TMDS_Clk_p  => tmds_tx_clk_p_o,
    TMDS_Clk_n  => tmds_tx_clk_n_o,
    TMDS_Data_p => tmds_tx_data_p_o,
    TMDS_Data_n => tmds_tx_data_n_o,
    aRst        => async_reset_i,
    vid_pData   => vid_pData,
    vid_pVDE    => vid_pVDE,
    vid_pHSync  => vid_pHSync,
    vid_pVSync  => vid_pVSync,
    PixelClk    => pixelclk
  );

end hdmi_pass_top_arc;

РЕДАКТИРОВАТЬ: изменил мой оператор if на

vid_pData(7 downto 0) <= "00000000" when sw = '0';

и он избавился от ошибки, но реализация не удалась. Неудача:

[DRC MDRV-1] Несколько сетей драйверов: сеть dvi2rgb_inst/U0/GenerateBUFG.ResyncToBUFG_X/vid_pData[0] имеет несколько драйверов: vid_pData_reg[0]/Q и dvi2rgb_inst/U0/GenerateBUFG.ResyncToBUFG_X/poData_reg[0]/Q.


person Jkind9    schedule 21.01.2020    source источник
comment
1/ Укажите в своем описании что происходит не так. Теперь мы должны угадать 2 / Я предполагаю, что вы создаете защелки. Читайте о том, как избежать защелок. А пока вот совет: убедитесь, что у вашего if sw ='0' .. есть else.   -  person Oldfart    schedule 21.01.2020
comment
Отредактировал сейчас. Хорошо, попробовал, все равно такая же проблема   -  person Jkind9    schedule 21.01.2020
comment
Вы не говорите, в чем проблема, и не показываете код, где проблема.   -  person Tricky    schedule 21.01.2020
comment
У меня есть синтаксическая ошибка в операторе if, и если я изменю его на первую реализацию редактирования, произойдет сбой.   -  person Jkind9    schedule 21.01.2020
comment
Ваш полный код не показывает оператор if с синтаксической ошибкой. Это просто экземпляры нескольких компонентов, которые, по-видимому, не имеют ничего общего с заявленной вами проблемой. Несколько драйверов находятся внутри компонента dvi2rgb_0. Вы не показываете код.   -  person Tricky    schedule 21.01.2020
comment
Ваше дополнение проясняет ситуацию. Я подожду ответа от кого-нибудь другого, так как я очень плохо разбираюсь в точном синтаксисе VHDL. Если никто не откликнется, я попытаюсь создать какой-нибудь псевдокод.   -  person Oldfart    schedule 21.01.2020


Ответы (1)


Вы не пишете программное обеспечение, вы проектируете аппаратное обеспечение. Ваш дополнительный код управляет сигналом vid_pData. Итак, компонент dvi2rgb_0. Итак, у вас есть два драйвера на этом сигнале. Другими словами, короткое замыкание.

Кроме того, вы не говорите, какое значение должно принимать vid_pData, если sw не равно '0'. Таким образом, вы получите защелки в своем оборудовании. (Гугл "предполагает защелку".)

Вам нужен новый сигнал, например:

signal vid_pData_new      : std_logic_vector(23 downto 0);

тогда вам нужно присвоить значение как для sw равно '0', так и для '1', иначе вы получите защелку:

vid_pData_new(7 downto 0) <= vid_pData(23 downto 8) & "00000000" when sw = '0' else vid_pData;

Оператор & – это оператор объединения. Наконец, вам нужно управлять компонентом rgb2dvi_0 с вашим новым сигналом:

rgb2dvi_inst : rgb2dvi_0
  port map (
    TMDS_Clk_p  => tmds_tx_clk_p_o,
    TMDS_Clk_n  => tmds_tx_clk_n_o,
    TMDS_Data_p => tmds_tx_data_p_o,
    TMDS_Data_n => tmds_tx_data_n_o,
    aRst        => async_reset_i,
    vid_pData   => vid_pData_new,   --  <-----------------
    vid_pVDE    => vid_pVDE,
    vid_pHSync  => vid_pHSync,
    vid_pVSync  => vid_pVSync,
    PixelClk    => pixelclk
  );

Вы видите, что здесь сделано? Мы вставили новую часть оборудования, которая управляет новым сигналом vid_pData_new, и определили его значение для обоих возможных значений sw. Мы должны сделать это, иначе получим защелки. Мы проектируем аппаратное обеспечение, а не пишем программное обеспечение.

person Matthew Taylor    schedule 21.01.2020
comment
Да, это имеет смысл, я пытался сделать это вчера после последнего, но не смог правильно понять синтаксис. К сожалению, я привык только к языкам высокого уровня, а оборудование для программирования совершенно новое для меня. Спасибо за подробное объяснение, это большая помощь - person Jkind9; 22.01.2020
comment
У вас есть тип в вашем решении, я полагаю, v_pData_new должен быть от 23 до 0 правильно? - person Jkind9; 22.01.2020
comment
Есть ли причина, по которой запись полного оператора if не сработала? Сейчас я пытаюсь использовать 3 переключателя для управления компонентами rgb, но я получаю синтаксические ошибки слева направо и по центру. - person Jkind9; 22.01.2020
comment
В VHDL оператор if может существовать только внутри оператора process. Это последовательный оператор. Конструкция when-else эквивалентна и может существовать вне process только как непрерывное условное присваивание. (Если вы не используете VHDL-2008). То, что вы используете здесь, не имеет значения. Ваша проблема возникла из-за того, что вы думаете как инженер-программист, из-за того, что вы думаете, что vid_pData похоже на программную переменную, которую можно перезаписать. vid_pData это сигнал, который управляется аппаратным блоком -dvi2rgb_0 - и подключается к другому аппаратному блоку - rgb2dvi_0... - person Matthew Taylor; 22.01.2020
comment
... так что вам нужно было вставить еще один аппаратный элемент между vi2rgb_0 - и rgb2dvi_0, чтобы изменить этот сигнал. Это ваше новое when-else утверждение. И сигнал о том, что этот новый бит аппаратных дисков ДОЛЖЕН иметь другое имя, иначе вы только что создали короткое замыкание, соединив его выход с его входом. - person Matthew Taylor; 22.01.2020
comment
И всякий раз, когда вы пишете какой-то код, который станет комбинационной логикой (которым является ваш новый оператор when-else — в нем нет триггеров), вы ДОЛЖНЫ определить значение, управляемое выводом эта комбинационная логика ДЛЯ ВСЕХ ВОЗМОЖНЫХ ВХОДОВ. Если вы этого не сделаете (например, вы не сказали, что делать, когда sw было '1'), то ваш код больше не ведет себя как условная логика, потому что любые неуказанные входные данные заставят вывод запомнить свое предыдущее значение. Комбинационная логика никогда ничего не запоминает; следовательно, синтезатор делает вывод о защелках. - person Matthew Taylor; 22.01.2020