Симуляция VHDL зависает даже при отсутствии ошибок - PullRequest
0 голосов
/ 04 мая 2018

Я новичок в языке VHDL и сейчас пытаюсь создать управляемый шаговый двигатель. Это должно быть что-то вроде this (я на самом деле получил эту картинку из своего кода с Тиной)

И это мой код:

LIBRARY ieee;                
USE ieee.std_logic_1164.ALL;            
USE ieee.std_logic_signed.ALL;         
ENTITY state_stepper_halfstep IS         
PORT(clk, plus, minus, start: IN    STD_LOGIC;
     q0,q1,q2,q3: OUT STD_LOGIC;
         a7,b7,c7,d7,e7,f7,g7,h7: OUT std_logic);
END state_stepper_halfstep;

ARCHITECTURE arc OF state_stepper_halfstep IS
    TYPE state_type IS (s0, s1, s2, s3, s4, s5, s6, s7);
    SIGNAL state: state_type;
        SIGNAL q: STD_LOGIC_VECTOR(3 downto 0);
        SIGNAL counter: integer range 0 to 21 :=11;
        SIGNAL digit: std_logic_vector (7 downto 0);
BEGIN

PROCESS (plus, minus, start, clk)
BEGIN 

IF rising_edge(plus) THEN  --  + Rotation value
    counter <= counter+1;
    IF counter > 20 THEN
        counter <= 20;
    END IF; 

ELSIF rising_edge(minus) THEN  --  - Rotation Value
    counter <= counter-1;
    IF counter < 2 THEN
        counter <= 2;
    END IF;
END IF;

    IF start = '1' THEN
        IF counter > 11 THEN  -- When value > 0
            WHILE counter > 11 LOOP  -- Clockwise looping
                EXIT WHEN counter = 11;
                IF rising_edge(clk) THEN        -- Clockwise Steps
                    CASE state IS
                        WHEN s0 => state <= s1;
                        WHEN s1 => state <= s2;
                        WHEN s2 => state <= s3;
                        WHEN s3 => state <= s4;
                        WHEN s4 => state <= s5;
                        WHEN s5 => state <= s6;
                        WHEN s6 => state <= s7;
                                   counter <= counter-1;
                        WHEN s7 => state <= s0;
                    END CASE;
                END IF;
            END LOOP;

        ELSIF counter < 11 THEN  -- When value < 0
            WHILE counter < 11 LOOP -- Counter-clockwise looping
                EXIT WHEN counter = 11;             
                IF rising_edge(clk) THEN        -- Counter-clockwise Steps
                    CASE state IS
                        WHEN s0 => state <= s7;
                        WHEN s7 => state <= s6;
                        WHEN s6 => state <= s5;
                        WHEN s5 => state <= s4;
                        WHEN s4 => state <= s3;
                        WHEN s3 => state <= s2;
                        WHEN s2 => state <= s1;
                                   counter <= counter+1;
                        WHEN s1 => state <= s0;
                    END CASE;
                END IF;
            END LOOP;

        ELSIF counter = 11 THEN -- When value = 0
            counter <= counter;

        END IF;

    ELSE state <= state;

    END IF;

END PROCESS;

WITH state SELECT
    q   <=  "0001"  WHEN    s0,
            "0011"  WHEN    s1,
            "0010"  WHEN    s2,
            "0110"  WHEN    s3,
            "0100"  WHEN    s4,
            "1100"  WHEN    s5,
            "1000"  WHEN    s6,
            "1001"  WHEN    s7;

q0 <= q(0);
q1 <= q(1);
q2 <= q(2);
q3 <= q(3);

    with counter select
digit<= "11000000" when 11,
    "11111001" when 12,
    "10100100" when 13,
    "10110000" when 14,
    "10011001" when 15,
    "10010010" when 16,
    "10000010" when 17,
    "11111000" when 18,
    "10000000" when 19,
    "10010000" when 20,
    "01111001" when 10,
    "00100100" when 9,
    "00110000" when 8,
    "00011001" when 7,
    "00010010" when 6,
    "00000010" when 5,
    "01111000" when 4,
    "00000000" when 3,
    "00010000" when 2;
    a7 <= digit(0);
b7 <= digit(1);
c7 <= digit(2);
d7 <= digit(3);
e7 <= digit(4);
f7 <= digit(5);
g7 <= digit(6);
h7 <= digit(7);
END arc;


Вот как это на самом деле должно работать:
1. Я могу выбрать, сколько раз будет вращаться шаговый двигатель (обозначается светодиодами) с помощью переключателей «плюс» и «минус» (он может отсчитывать от -9 до 9)
2. Точка 7 сегмента является отрицательным знаком для числа, показанного на дисплее
3. Положительное значение заставит двигатель вращаться по часовой стрелке
4. Отрицательное значение (показано точкой в ​​7 сегментах) заставит двигатель вращаться против часовой стрелки
5. Каждый раз, когда двигатель выполняет 1 оборот, число 7 сегментов должно уменьшаться на 1 число
6. Шаговый двигатель начнет вращаться только в том случае, если я его запустил (с заданием высокой логики для входа «пуск»)


Проблема возникает всякий раз, когда я пытаюсь смоделировать цепь и нажимаю «старт». Тина просто повесится, а затем "Не отвечает". Честно говоря, я не уверен в том, какую ошибку я допустил в своем коде, потому что Тина не выдает ошибку, когда я пытаюсь «войти в новый макрос» с моим VHDL-кодом.


Мое лучшее предположение - я допустил ошибку в своей циклической команде

    IF start = '1' THEN
        IF counter > 11 THEN  -- When value > 0
            WHILE counter > 11 LOOP  -- Clockwise looping
                EXIT WHEN counter = 11;
                IF rising_edge(clk) THEN        -- Clockwise Steps
                    CASE state IS
                        WHEN s0 => state <= s1;
                        WHEN s1 => state <= s2;
                        WHEN s2 => state <= s3;
                        WHEN s3 => state <= s4;
                        WHEN s4 => state <= s5;
                        WHEN s5 => state <= s6;
                        WHEN s6 => state <= s7;
                                   counter <= counter-1;
                        WHEN s7 => state <= s0;
                    END CASE;
                END IF;
            END LOOP;

        ELSIF counter < 11 THEN  -- When value < 0
            WHILE counter < 11 LOOP -- Counter-clockwise looping
                EXIT WHEN counter = 11;             
                IF rising_edge(clk) THEN        -- Counter-clockwise Steps
                    CASE state IS
                        WHEN s0 => state <= s7;
                        WHEN s7 => state <= s6;
                        WHEN s6 => state <= s5;
                        WHEN s5 => state <= s4;
                        WHEN s4 => state <= s3;
                        WHEN s3 => state <= s2;
                        WHEN s2 => state <= s1;
                                   counter <= counter+1;
                        WHEN s1 => state <= s0;
                    END CASE;
                END IF;
            END LOOP;


Я был бы очень рад, если бы кто-то мог указать на ошибку. Заранее спасибо и хорошего дня!

1 Ответ

0 голосов
/ 07 мая 2018

То, что вы пытаетесь достичь, - это прямой порт с языка программирования VHDL. HDL не работают таким образом, и вам придется изменить свою парадигму, если вы хотите достичь этого дизайна. Вот несколько советов:

  1. Описание вашей сущности и архитектуры выглядит нормально
  2. Список чувствительности основного процесса показывает, что вы ожидаете, что он будет запускаться «шаг за шагом», как поток, но в HDL это невозможно сделать для синтеза. Модель для описания конструкции аппаратного обеспечения состоит в том, что процесс запускается один раз в течение каждого случая, когда в сигналах, перечисленных в списке чувствительности, происходит событие. Процесс не может блокироваться во время ожидания дальнейших событий. Если сигналы вашего списка чувствительности проверяются на значения, это означает, что ваш процесс комбинаторный (чистая логика). Это не то, что вы намереваетесь получить (у вас есть сигнал clk). Таким образом, у вашего процесса должен быть только один сигнал в списке чувствительности: После этого ваше тело процесса может начинаться с уникального IF rising_edge(clk) THEN, которое ясно указывает на синхронизированный процесс.
  3. Синхронизированные процессы не управляют данными, прошедшими текущий тактовый цикл, поэтому вам нужно думать о состояниях, которые вы хотите сохранить от одного цикла к следующему, и выводить их как сигналы.
  4. Сигналы - это экзотические звери по сравнению с переменными, и вам необходимо понять, как они работают в отношении событий и времени. Например, counter <= counter; бесполезен.
  5. Текстовая спецификация поведения вашей системы выглядит как описание конечного автомата. Почему бы не уточнить это формально и не конкретизировать это как состояние вашей системы? Смотрите простой пример здесь
  6. Как правило, для синтеза вам нужен своего рода сигнал сброса, чтобы убедиться, что все ваши состояния инициализируются аппаратно.
...