Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема стыковки блоков в VHDL коде
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Саша Z
Есть 2 блока написанных на VHDLе. Один - (назовем его TG) файл кода генерирующего видео тайминг для TFT LCD (syncs и т.д.), другой генерирует данные картинки согласно таймингу TFT генерируемому первым блоком (назовем его DG).
Затем набросал код топового VHDL файла который соединяет два этих блока нужным образом так что-бы на выходе проэкта (т.е. топового файла) был тайминг и видео дата дисплея.

Оба блока (TG & DG) отработаны в симуляции, работают нормально по отдельности. при их соединении - проэкт тоже работает (т.е. на выходе идет нужный тайминг), но данные генрируемые DG - не передаются на выход проэкта (шина выхода данных на дисплаы называется DATA_TFT).
Код топового файла:

Код
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.constants.all;        --library containing package of constants of TFT LCD timing and other ADU related parameters

entity TFT_IPG is
port (
    nRST, CLK: in std_logic;
    EXT_VIDEO_DATA: in std_logic_vector(17 downto 0);    --external video data input
    VIDEO_INPUT: in std_logic;                            --IDG video pattern input config.
    IPG_PATTERN: in std_logic;                            --IDG video pattern type config.
    
    HSYNC_TFT, VSYNC_TFT, ENAB_TFT: out std_logic;        --TG syncs output to TFT
    DATA_TFT: out std_logic_vector(17 downto 0)            --DG data output to TFT
    );
end entity;

architecture TFT_IPG_arch of TFT_IPG is

    component TFT_TG
        port (nRST, CLK: in std_logic;
              HSYNC, VSYNC, ENAB: out std_logic;
              active_video_flag: out boolean;
              line_cnt_out: out natural range 0 to TH
             );
    end component;
    
    component TFT_DG
        port (nRST, CLK, PATTERN_TYPE: in std_logic;
              HSYNC, VSYNC, ENAB: in std_logic;
              active_video_flag: in boolean;
              --color_switch_debug: out std_logic;    --for debug only
              line_cnt: in natural range 0 to TH;
              DATA_OUT: out std_logic_vector(17 downto 0)
             );
    end component;
    
    signal HSYNC_sig, VSYNC_sig, ENAB_sig: std_logic;
    signal act_v_flag: boolean;
    signal l_cnt: natural range 0 to TH;
    signal data_switch: std_logic;
    signal DATA_sig: std_logic_vector(17 downto 0);
    
begin
    TFT_TG_inst: TFT_TG port map(nRST => nRST, CLK => CLK, HSYNC => HSYNC_sig, VSYNC => VSYNC_sig, ENAB => ENAB_sig, active_video_flag => act_v_flag, line_cnt_out => l_cnt);
    TFT_DG_inst: TFT_DG port map(nRST => nRST, CLK => CLK, PATTERN_TYPE => IPG_PATTERN, HSYNC => HSYNC_sig, VSYNC => VSYNC_sig, ENAB => ENAB_sig, active_video_flag => act_v_flag, line_cnt => l_cnt, DATA_OUT => DATA_sig);
    
    HSYNC_TFT <= HSYNC_sig;    --pass through HSYNC from TFT_TG to IPG output
    VSYNC_TFT <= VSYNC_sig; --pass through VSYNC from TFT_TG to IPG output
    ENAB_TFT <= ENAB_sig;   --pass through ENAB from TFT_TG to IPG output
    DATA_TFT <= DATA_sig when data_switch = '1' else EXT_VIDEO_DATA;
    
    process(nRST, CLK)        --reading video input config. input during Reset while clock is present
    begin
        if CLK'event and CLK = '1' the
            if nRST = RST_pol then
                data_switch <= VIDEO_INPUT;
            else
                data_switch <= data_switch;
            end if;
        end if;
    end process;
    
    --process(data_switch)
    --begin
        
            --if data_switch = '1' then
                --DATA_TFT <= DATA_sig;
            --else
                --DATA_TFT <= EXT_VIDEO_DATA;
            --end if;
        
    --end process;
end;


DATA_OUT есть выходна шина виде даты блока DG, она должна идти на главный выход данных на дисплей (DATA_TFT).
DATA_sig и другие сигналы (с _sig) используются как промежуточные для передачи входов/выходов между блоками и наружу.

Если передача видео шины сделана как в коде:
Код
DATA_TFT <= DATA_sig when data_switch = '1' else EXT_VIDEO_DATA;

то тогда главная выходная шина работает как положено и DATA_OUT передается напрямую на DATA_TFT.

Однако, если написано так как там в коментах:
Код
--process(data_switch)
    --begin
        
            --if data_switch = '1' then
                --DATA_TFT <= DATA_sig;
            --else
                --DATA_TFT <= EXT_VIDEO_DATA;
            --end if;
        
    --end process;

то передачи данных на главную выходную шину не происходит (хотя внутренняя DATA_OUT работает как положено).

Тоже самое с сигналом data_switch - не реагирует на измеение VIDEO_INPUT. подозреваю что по похожей причине. Уверен что ежели я-бы написал вместо ifов просто:
Код
ata_switch <= VIDEO_INPUT

то начало бы работать.

Итак, что-же происходит ? Почему ifовый код не работает в топовом файле-связке ? Где моя ошибка ?

Спасибо.
BSV
Для комбинаторного процесса все сигналы, участвующие в формировании выхода должны быть указаны в списке чувствительности. Наверняка об этом предупреждал синтезатор (или симулятор при включении опции Check for Synthesis в свойствах компиляции). Нужно так:
Код
process(data_switch, DATA_sig, EXT_VIDEO_DATA)
begin
  if data_switch = '1' then
    DATA_TFT <= DATA_sig;
  else
    DATA_TFT <= EXT_VIDEO_DATA;
  end if;
end process;


Здесь тоже кое-что лишнее. При отсутствии nRST data_switch и так останется в своем предыдущем состоянии, явно это не нужно описывать. А RST_pol - это константа?
Код
process(nRST, CLK)        --reading video input config. input during Reset while clock is present
begin
  if CLK'event and CLK = '1' the
    if nRST = RST_pol then
      data_switch <= VIDEO_INPUT;
--    else
--      data_switch <= data_switch;
    end if;
  end if;
end process;
sazh
line_cnt: in natural range 0 to TH;
/////////////////////////////////////////////
А почему не line_cnt: in natural range 0 to TH-1;
Ведь состояние 0 такое же равноправное. Тогда не нужно иметь сравнение по 1.
И не будут выпадать значения 2**n. Не будет "лишней" разрядности по этому значению и это тогда
легко ляжет на параметризуемость при взаимодействии с log2
Саша Z
Цитата(BSV @ Feb 2 2008, 11:15) *
Для комбинаторного процесса все сигналы, участвующие в формировании выхода должны быть указаны в списке чувствительности. Наверняка об этом предупреждал синтезатор (или симулятор при включении опции Check for Synthesis в свойствах компиляции). Нужно так:
Код
process(data_switch, DATA_sig, EXT_VIDEO_DATA)
begin
  if data_switch = '1' then
    DATA_TFT <= DATA_sig;
  else
    DATA_TFT <= EXT_VIDEO_DATA;
  end if;
end process;


Здесь тоже кое-что лишнее. При отсутствии nRST data_switch и так останется в своем предыдущем состоянии, явно это не нужно описывать. А RST_pol - это константа?
Код
process(nRST, CLK)        --reading video input config. input during Reset while clock is present
begin
  if CLK'event and CLK = '1' the
    if nRST = RST_pol then
      data_switch <= VIDEO_INPUT;
--    else
--      data_switch <= data_switch;
    end if;
  end if;
end process;


Да, насчет sense list процессов - вы правы. Я поначалу их набросал в рассчете использовать все сигналы из списка, но затем передумал а подправить sense list соответственно - забыл.
Но не уверен что оно поможет насчет моей проблемы. Попробую, если поможет - значит я получил ноый хороший урок VHDLя...

Цитата(sazh @ Feb 2 2008, 13:09) *
line_cnt: in natural range 0 to TH;
/////////////////////////////////////////////
А почему не line_cnt: in natural range 0 to TH-1;
Ведь состояние 0 такое же равноправное. Тогда не нужно иметь сравнение по 1.
И не будут выпадать значения 2**n. Не будет "лишней" разрядности по этому значению и это тогда
легко ляжет на параметризуемость при взаимодействии с log2


В том что вы говорите есть логика, я знаю и обычно так и делаю. Но тут источник сигнала line_cnt - счетчик в блоке TG. Там в коде используются значения от нуля до TH включительно (считает в приципе от 1 до TH, но в особых случаю должен прыгать в ноль тоже). Посему для соответствия источнику, и тут его определил именно так.
AsJohnAs
Ну если использовать это
--process(data_switch)
--begin

--if data_switch = '1' then
--DATA_TFT <= DATA_sig;
--else
--DATA_TFT <= EXT_VIDEO_DATA;
--end if;

--end process;

то тогда сигнал будет проходить через latch у которого как-бы тактовой будет data_switch, a при записи через when это будет мультиплексор без тактовой и соответственно без задержки.

Тут надо пенять если надо тригер - то ставить тригер и именно на той тактовой на которой нужно. Если не нужен тригер, то тогда использовать when
Саша Z
Цитата(AsJohnAs @ Feb 2 2008, 20:21) *
Ну если использовать это
--process(data_switch)
--begin

--if data_switch = '1' then
--DATA_TFT <= DATA_sig;
--else
--DATA_TFT <= EXT_VIDEO_DATA;
--end if;

--end process;

то тогда сигнал будет проходить через latch у которого как-бы тактовой будет data_switch, a при записи через when это будет мультиплексор без тактовой и соответственно без задержки.

Тут надо пенять если надо тригер - то ставить тригер и именно на той тактовой на которой нужно. Если не нужен тригер, то тогда использовать when


Да, этоьто понятно, но все-равно по идее должно работать и с ifом, хоьт и через latch. Сейчас пробовал опять, на сей раз в sense list оставил только daat_switch - все равно не помогает, не работает. Если-же меняю на конструкцию с when - работает как положено.

Кроме того, другой процесс:
Код
process(nRST, CLK)        --reading video input config. input during Reset while clock is present
begin
  if CLK'event and CLK = '1' the
    if nRST = RST_pol then
        data_switch <= VIDEO_INPUT;
    else
        data_switch <= data_switch;
    end if;
  end if;
end process;


тоже не работает в том-же топовом файле проэкта, видимо по схожим причинам которых пока не пойму...
.
.
.

хмм, сорри, я кажется идиот... cranky.gif , я же сам специально написал это так что-бы изменение состяния data_switch защелкивалось только в процессе активного Resetа, ...и забыл об этом... smile.gif
а теперь ломаю голову почему не срабатывает в процессе симуляции далеко после Resetа..
Ладно, с этим разобрались.
Но все-равно не пойму почему не работает первый кусок с if, но when да работает...
AsJohnAs
Ну если последний процесс не работает, то необходимо проверить тактувую сигнал ресета. Посмотреть не пишет ли кто как-нибудь в эту же шину. Проверить распиновку. Потому как тригер должен рабоать smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.