Процедура в VHDL никогда не возвращает значение - PullRequest
0 голосов
/ 31 августа 2018

У меня есть процедура, которая никогда не возвращает значение.

procedure gen_start_impulse (
    signal rising_signal        : out std_logic;                             
    signal carier_clk           : in std_logic;
    constant duration           : in integer)    is                         
variable clk_counter    : integer := 0;
begin 
    if (rising_edge(carier_clk)) then
        if (clk_counter = duration) then
            rising_signal <= '0';
            clk_counter := 0;
        else
            rising_signal <= '1';
            clk_counter := clk_counter + 1;
        end if;
    end if;
end gen_start_impulse;

Я называю это здесь

process (start)
begin
    if (start = '1') then
        gen_start_impulse(start_impulse, clk, 1);           
    end if;
end process;

В тестовом стенде start_impulse не инициализирован.

Результат теста

Я не понимаю, почему в осциллограмме start_impulse неинициализирован.

1 Ответ

0 голосов
/ 31 августа 2018

Добро пожаловать в Stackoverflow. Ваш вопрос интересен, но на самом деле он не содержит достаточно информации, чтобы получить полный ответ (быстрый взгляд на справочный центр и особенно на Как создать минимальный, полный и проверяемый пример * Раздел 1004 *, возможно, поможет вам улучшить его, если хотите).

В любом случае, давайте попробуем угадать. Ваш процесс возобновляется каждый раз, когда изменяется start, и, благодаря вашему выражению if, он вызывает вашу процедуру gen_start_impulse, только если новое значение start равно '1'. Итак, просто чтобы прояснить ситуацию, мы могли бы сгладить вашу модель и переписать ваш процесс следующим образом:

process (start)
    variable clk_counter: integer := 0;
    constant duration: integer := 1;
begin
    if (start = '1') then
        if (rising_edge(clk)) then
            if (clk_counter = duration) then
                start_impulse <= '0';
                clk_counter := 0;
            else
                start_impulse <= '1';
                clk_counter := clk_counter + 1;
            end if;
        end if;
    end if;
end process;

Важное примечание : это не является строго эквивалентным вашему исходному коду, потому что в вашем коде переменная clk_counter переинициализируется каждый раз, когда ваша процедура gen_start_impulse вызывается, в то время как здесь она сохраняет свое предыдущее значение . * * 1019

Теперь, как вы думаете, что произойдет, если start является синхронным? То есть всегда ли он меняется сразу после нарастающего фронта clk? Просто: условие:

if (rising_edge(clk)) then
Оператор

всегда ложен, и ваши присвоения сигналов start_impulse никогда не выполняются. Это потому, что start и clk никогда не изменяются одновременно. Между ними всегда есть хотя бы один шаг моделирования (« дельта-цикл »).

Если вы разрабатываете синхронную систему, подождите или проверьте нарастающие фронты ваших часов, а затем протестируйте другие сигналы, а не наоборот. Пример:

procedure gen_start_impulse (
    signal rising_signal        : out std_logic;                             
    signal starter              : in std_logic;
    constant duration           : in integer)    is                         
    variable clk_counter    : integer := 0;
begin 
    if (starter = '1') then
        if (clk_counter = duration) then
            rising_signal <= '0';
            clk_counter := 0;
        else
            rising_signal <= '1';
            clk_counter := clk_counter + 1;
        end if;
    end if;
end gen_start_impulse;
...
process (clk)
begin
    if (rising_edge(clk)) then
        gen_start_impulse(start_impulse, start, 1);           
    end if;
end process;

Важное примечание : поскольку переменная clk_counter переинициализируется каждый раз, когда вызывается процедура gen_start_impulse (см. Предыдущее примечание), это не будет работать так, как вы ожидаете. Если вы хотите, чтобы это работало, вам нужно будет немного переделать его, либо полностью удалив процедуру (кстати, зачем она вам нужна) и используя только один синхронный процесс, либо добавив четвертый параметр inout в Ваша процедура для переменной clk_counter и ее объявление в качестве переменной процесса.

...