Оператор if-else с теми же условиями, что и у другого оператора if-else, не выдает такой же вывод - PullRequest
2 голосов
/ 22 октября 2019

Так что мне нужно сделать задание, в котором я должен написать счетчик, который имеет режим upcount = 1 -> increment = 5 и режим downcount = 0 -> decment = -9. Существует недопустимое значение -69, через которое счетчик должен перепрыгнуть.

Существуют также верхняя и нижняя границы: от -250 до 248.

Для проверки нашего счетчика был предоставлен испытательный стенд.

Я использовал следующую инструкцию if-else внутри процесса с сигналом clk в качестве записи списка чувствительности.

if((cnt_intern + 5) <= 248) then
    cnt_intern <= cnt_intern + 5;
end if;


if(cnt_intern = -69) then
    cnt_intern <= cnt_intern + 5;
end if;

это не сработало, так как для cnt_intern было установлено значение -69, котороево-вторых, если заявление должно помешать. Я переписал оператор if следующим образом:

if(cnt_intern <= 243) then#
    if(cnt_intern = -73) then
        cnt_intern <= cnt_intern + 10;
    else
        cnt_intern <= cnt_intern + 5;
    end if;
end if;

На этот раз он сработал и сразу перепрыгнул через -69 до -64.

Кто-нибудь знает почему? что не так с первым способом?

С наилучшими пожеланиями

1 Ответ

2 голосов
/ 23 октября 2019

Причиной наблюдаемого поведения является то, что назначение сигнала внутри процесса не сразу меняет значение сигнала. Вместо этого транзакция запланирована на сигнал, который вступит в силу, когда процесс приостанавливается (то есть когда достигнут конец процесса или оператор wait).

В вашемпервый пример, если cnt_intern равен -74 в начале процесса, первый оператор if планирует как транзакцию, это означает, что изменение значения сигнала на -69 произойдет в конце процесса, если нет других графиков назначениятранзакция на cnt_intern. Однако фактическое значение cnt_intern остается -74 до конца процесса. Таким образом, второе утверждение if будет оцениваться как ложное и ничего не делать. В конце процесса значение -69 присваивается cnt_intern.

Эта концепция кажется запутанной, если вы начинаете работать с языками описания аппаратного обеспечения, но она необходима.

Выможет использовать вспомогательную переменную, чтобы обойти эту проблему и обеспечить читабельность кода:

process(clk)
    variable v_cnt_intern : integer;
begin
    if rising_edge(clk) then
        v_cnt_intern := cnt_intern;

        if((v_cnt_intern + 5) <= 248) then
            v_cnt_intern := v_cnt_intern + 5;
        end if;

        if (v_cnt_intern = -69) then
            v_cnt_intern := v_cnt_intern + 5;
        end if;

        cnt_intern <= v_cnt_intern;
    end if;
end process;

Другие решения похожи на код во втором примере, который выглядит хорошо.

...