Заявление VHDL IF в заявлении о случае

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

На самом деле часть, которая ведет себя не так, как мне хотелось бы, вообще ничего не делает.

Чтобы упростить понимание, я хотя бы немного объясню, что это должно делать. Во-первых, порт IN New_Data указывает на 1, что новые данные доступны и должны быть оценены. Входной код - это значение для оценки / интерпретации. Выходные данные - это новое значение скорости, а текущее - текущее / предыдущее. Направление инвертируется кодом входа 10.

Часть, которая не работает или фактически ничего не делает: если код равен + (val 43), вы увеличиваете его на 1, если код - (val 45), вы уменьшаете его на 1, а затем результат, который он отправляет на вывод скорости .

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY Code_Interpret IS
    PORT (
            New_Data: IN STD_LOGIC;
            Current_Speed: IN UNSIGNED(7 DOWNTO 0);
            Code: IN UNSIGNED(7 DOWNTO 0);
            Speed: OUT UNSIGNED(7 DOWNTO 0);
            Direction: OUT STD_LOGIC
         );
END Code_Interpret;

ARCHITECTURE rtl OF Code_Interpret IS

SIGNAL s_speed: UNSIGNED(7 DOWNTO 0):= "00110000";
SIGNAL s_case: INTEGER RANGE 0 TO 64 := 48;
SIGNAL s_direction: STD_LOGIC := '1';

BEGIN
    PROCESS (New_Data, Code)
    BEGIN
        s_case <= TO_INTEGER(Code);
        IF RISING_EDGE(New_Data) THEN
            CASE s_case IS
                WHEN 48 TO 55 =>
                    --s_speed <= Code;
                    s_speed <= Code;
                WHEN 43 =>
                    IF Current_Speed < 55 THEN
                        s_speed <= Current_Speed + 1;
                    ELSE
                        s_speed <= Current_Speed;
                    END IF;
                WHEN 45 =>
                    IF Current_Speed > 48 THEN
                        s_speed <= Current_Speed - 1;
                    ELSE
                        s_speed <= Current_Speed;
                    END IF;
                WHEN 10 =>
                    s_direction <= NOT s_direction;
                WHEN OTHERS =>
                    NULL;
            END CASE;
        END IF;
        Speed <= s_speed;
        Direction <= s_direction;
    END PROCESS;
END;

Часть, которая делает не то, что я хочу:

WHEN 43 =>
    IF Current_Speed < 55 THEN
        s_speed <= Current_Speed + 1;
    ELSE
        s_speed <= Current_Speed;
    END IF;
WHEN 45 =>
    IF Current_Speed > 48 THEN
        s_speed <= Current_Speed - 1;
    ELSE
        s_speed <= Current_Speed;
    END IF;

Вот как выглядит моя симуляция. На шкале времени есть 6 маркеров, первый - +, затем - переключатель направления и те же коды, повторяющиеся в том же порядке.

Quartus Simulation # 1

Я пробовал много разных вещей, но мне не удалось понять, в чем проблема, и я хотел бы знать, почему это не работает.

Хорошо, теперь я симулирую только код VHDL и работаю прямо с входами и выходами вместо использования бесполезных контактов и схемы, которая мне не нужна. Также я прочитал руководство по моделированию Quartus II, которое помогло мне исправить систему счисления. (Как я уже сказал, я новичок в этом ...)

Измените код, чтобы попытаться использовать VAR:

--....
--SIGNAL s_case: INTEGER RANGE 0 TO 64 := 48;
SIGNAL s_direction: STD_LOGIC := '1';

BEGIN
    PROCESS (New_Data, Code)
        VARIABLE s_case: INTEGER RANGE 0 TO 64 := 48;
    BEGIN
        s_case := TO_INTEGER(Code);
        IF RISING_EDGE(New_Data) THEN
            CASE s_case IS
    --....

Результирующая симуляция:  Quartus Simulation # 2


person Guillaume Drolet    schedule 28.04.2016    source источник
comment
Похоже, он работает, как и предполагалось, но вы можете ввести код 45 где-нибудь в своих тестах.   -  person user_1818839    schedule 28.04.2016
comment
На снимке экрана моделирования вы можете видеть, что значение для кода составляет 43 около 520 нс и 700 нс, но при этом ничего не происходит, и 45 также появляется в коде при 570 нс и изменениях скорости 760 нс при каждом нарастающем фронте new_data, за исключением 6 последних нарастающих фронтов. (ну разве что ведет себя как надо для кода 0000 1010)   -  person Guillaume Drolet    schedule 28.04.2016
comment
Ваша симуляция, похоже, не совсем отражает код. Например, «витесс» отсутствует в коде. Я думаю, вам нужно запустить поведенческое моделирование, зарегистрировав точные порты в вышеупомянутой сущности, а также три ваших сигнала. В его нынешнем виде вы, кажется, пытаетесь отладить, не глядя на самый нижний уровень.   -  person scary_jeff    schedule 28.04.2016
comment
Вы правы, что выдаются оба кода - 43 и 45 - я бы рекомендовал использовать разумные системы счисления на дисплее формы сигнала, чтобы избежать преобразования из двоичного кода - это просто безумно усложняет жизнь. Я думаю, у вас проблема с отложенным назначением (назначением сигнала) и неполным списком чувствительности процесса. Если вы сделали s_case переменную (она бесполезна вне процесса, и ограничение области действия является хорошей практикой), этого можно было бы избежать.   -  person user_1818839    schedule 28.04.2016
comment
@scary_jeff Я исправил эту часть. Я моделировал свой код VHDL после создания блока и подключения его к контактам (в этом не было необходимости, спасибо, что заставили меня это понять)   -  person Guillaume Drolet    schedule 28.04.2016
comment
@BrianDrummond Yaeh, спасибо, я исправил это, как видите, я отредактировал свой пост. Я попытался изменить сигнал на переменную, и, похоже, он ничего не меняет (вторая симуляция с var). Вы также можете посмотреть изменения в коде. Что касается списка чувствительности, нужно ли добавлять другие переменные? Я не хочу, чтобы мой процесс подвергался переоценке на изменение любого другого входа или сигнала, кроме моих часов.   -  person Guillaume Drolet    schedule 28.04.2016
comment
Ваш код не является минимальным, полным и поддающимся проверке примером, в котором отсутствует способ воспроизведения ваших результатов. Есть альтернатива сделать s_code переменной. Вы можете назначить его вне процесса (другой процесс или одновременное назначение сигнала). Также существует задержка назначения скорости и направления в первом сигнале, не учтенном в вашем коде, и эти назначения должны быть внешними по отношению к процессу, иначе они будут обновляться только при событии в new_data или коде. Список чувствительности должен содержать только new_data.   -  person    schedule 28.04.2016


Ответы (1)


Пожалуйста, прежде всего переосмыслите то, что вы пытаетесь сделать. Реализация вашего процесса представляет собой забавную смесь последовательной и комбинационной логики. Семантические ловушки, в которые вы попадаете:

  • Сигнал обновляется только в следующем дельта-цикле, т.е. изменения в ваших сигналах s_ * вступают в силу только на следующей итерации процесса.
  • Процесс запускается только изменениями на входах New_data и Code.

Убедитесь, что у вас есть четкое представление о том, что должно быть последовательным и, следовательно, запускать по тактовому сигналу и использовать «возрастающий_ край (часы)», а что должно быть комбинационным и, следовательно, должно запускаться на всех обрабатываемых входах - без проверки фронта.

person Thomas B Preusser    schedule 28.04.2016
comment
Спасибо за информацию. Итак, если я правильно понимаю, он обновится, когда процесс будет вызван снова, скорее всего, по часам. Кажется, что это происходит после нарастающего фронта, если я взгляну на свою первую симуляцию до + [0011 1011]. Моя проблема здесь в том, что моя скорость вообще не меняется для «+» и «-». Тогда я проведу еще тесты ... А что в случае с переменной? Будет ли он обновляться в следующем дельта-цикле или он будет обновляться в том же цикле? Из того, что я прочитал, он должен себя вести. - person Guillaume Drolet; 28.04.2016
comment
@GuillaumeDrolet Я действительно думаю, что вам было бы полезно добавить свои внутренние сигналы в окно волны симуляции. Это немедленно покажет любые проблемы с отложенным назначением. - person scary_jeff; 28.04.2016
comment
Выполнение процесса запускается событием по любому из сигналов в его списке чувствительности. Это должны быть часы тогда и только тогда, когда вы описываете последовательную логику. И да, переменные обновляются мгновенно. Однако многие инструменты не позволяют перетаскивать их в формы сигналов для проверки с течением времени. - person Thomas B Preusser; 28.04.2016