Переназначение целочисленного сигнала VHDL не работает в соответствии с оператором `report`

У меня есть этот простой код VHDL aufg4.vhd:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity aufg4 is
    Port ( 
        clock : in  std_logic
            );
end aufg4;

architecture Behavioral of aufg4 is

    signal tut_counter : integer range 0 to 90 := 0; -- counts tutorial time

begin

    do_process :process(clock)
        begin
            if(rising_edge(clock)) then
                report "tut_counter " & integer'image(tut_counter);
                if(tut_counter >= 90) then
                    tut_counter <= 0;   
                    report "tut_counter reset";
                end if;
                tut_counter <= tut_counter + 1;
            end if;
        end process;

end Behavioral;

И тестовый стенд aufg4_tb.vhd:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY aufg4_tb IS
END aufg4_tb;

ARCHITECTURE behavior OF aufg4_tb IS 

     COMPONENT aufg4
     PORT(
        clock : IN  std_logic
          );
     END COMPONENT;

    --Inputs
    signal clock : std_logic := '0';

    -- Clock period definitions
    constant clock_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
    uut: aufg4 PORT MAP (
    clock => clock
          );

    -- Clock process definitions
    clock_process :process
    begin
        clock <= '0';
        wait for clock_period/2;
        clock <= '1';
        wait for clock_period/2;
    end process;

END;

Когда я моделирую поведенческую модель report, результаты:

 ...
at 885 ns(1): Note: tut_counter 88 (/aufg4_tb/uut/).
at 895 ns(1): Note: tut_counter 89 (/aufg4_tb/uut/).
at 905 ns(1): Note: tut_counter 90 (/aufg4_tb/uut/).
at 905 ns(1): Note: tut_counter reset (/aufg4_tb/uut/).
at 915 ns(1): Note: tut_counter 91 (/aufg4_tb/uut/).
at 915 ns(1): Note: tut_counter reset (/aufg4_tb/uut/).
at 925 ns(1): Note: tut_counter 92 (/aufg4_tb/uut/).
at 925 ns(1): Note: tut_counter reset (/aufg4_tb/uut/).
at 935 ns(1): Note: tut_counter 93 (/aufg4_tb/uut/).
...

Так if-оператор работает правильно, а вот переназначение сигнала tut_counter не работает.

Так почему же?

И почему симуляция не проходит через ошибку, потому что tut_counter просто имеет диапазон от 0 to 90?


person goulashsoup    schedule 06.11.2016    source источник
comment
Кстати, +1 за хорошо заданный вопрос. Что касается того, почему он не сообщает об ошибке - в дикой догадке вы используете Xilinx ISIM. По умолчанию он не работает, и так было годами, но есть опция свойств (на вкладке «Дополнительно», я думаю), чтобы включить проверку диапазона и исправить это.   -  person user_1818839    schedule 06.11.2016
comment
@BrianDrummond Как я могу заставить такое переназначение event работать правильно?   -  person goulashsoup    schedule 06.11.2016
comment
помните, что последнее задание побеждает, а также есть ключевое слово else.   -  person user_1818839    schedule 06.11.2016
comment
@BrianDrummond хорошо, спасибо! Просто чтобы убедиться, что я правильно понимаю: 1. Все events в VHDL происходят одновременно, поэтому нет никакого порядка для команд любого типа, но последнее присваивание побеждает? 2. Можно имитировать заказ с помощью операторов ожидания, что невозможно в моем случае, потому что я использую список чувствительности, верно?   -  person goulashsoup    schedule 06.11.2016
comment
Не совсем. Команды выполняются в строгом порядке, но в нулевое время, но назначения сигналов происходят только тогда, когда процесс приостанавливается (поэтому более поздние команды переопределяют более ранние). Ожидание просто приостанавливает процесс в ожидании, а не в конце.   -  person user_1818839    schedule 06.11.2016
comment
Просто чтобы уточнить ответ Брайана о победах в последнем задании. Это касается последовательных процессов. Параллельные назначения происходят в одно и то же время (грубо говоря, каждое из них происходит в разные дельта-циклы, но с одним и тем же значением времени (пс, нс и т. д.).   -  person PlayDough    schedule 07.11.2016


Ответы (1)


Использование вместо этого else решает проблему довольно хорошо!

do_process :process(clock)
    begin
        if(rising_edge(clock)) then
            report "tut_counter " & integer'image(tut_counter);
            if(tut_counter >= 90) then
                tut_counter := 0;   
                report "tut_counter reset";
            else
                tut_counter := tut_counter + 1;
            end if;
        end if;
    end process;

В противном случае вы можете использовать переменную: variable tut_counter : integer range 0 to 90 := 0; -- counts tutorial time

person goulashsoup    schedule 06.11.2016
comment
Сорта. Это сбросит счетчик на 1, а не на 0. Таким образом, вы получите 0, 1, 2, ..., 90, 1, 2, 3, ...., 90, 1, 2, .... Обратите внимание на замечание Брайана по поводу оператора else. - person PlayDough; 07.11.2016
comment
Помимо того, что это на самом деле не решает проблему, использование переменных, в которых сигналы будут работать идеально, — отличный способ создать неэффективное синтезированное оборудование и трудно идентифицировать ошибки. Если бы вы просто переместили строку tut_counter <= tut_counter + 1; в предложение else строки if(tut_counter >= 90) then, все бы работало нормально (также избегая перезаписи присваивания). - person QuantumRipple; 08.11.2016
comment
Да, я знаю... @QuantumRipple Почему в VHDL есть переменные, если их нельзя использовать? - person goulashsoup; 08.11.2016
comment
@goulashsoup По той же причине в C есть указатели/динамическое выделение, с помощью которых вы можете легко вызвать утечку памяти; они имеют допустимое использование. Есть места, где переменные могут значительно упростить представление, а некоторые аппаратные средства нельзя описать модульным (параметризованным) способом без переменных. Они также отлично подходят для использования в коде, предназначенном только для моделирования, где вы можете обращаться с VHDL больше как с программным обеспечением, а не как с аппаратным обеспечением. Тем не менее, как и указатели, они опасны и, вероятно, не должны использоваться там, где они не нужны. - person QuantumRipple; 08.11.2016