VHDL 仿真挂起,即使它没有显示错误

VHDL simulation hangs even though it shows no error

我是 VHDL 语言的新手,现在我正在尝试制作可控步进电机。它应该类似于 this(我实际上是从我与 Tina 的代码中得到这张照片的)

这是我的代码:

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. 我可以通过 "plus" 和 "minus" 开关选择步进电机(用 LED 指示)旋转多少次(它可以从 -9 计数到 9)
2. 7段的点是显示屏显示数字的负号
3. 正值将使电机顺时针旋转
4. 负值(7段圆点表示)会使电机逆时针旋转
5.电机每转一圈,7段数减1
6.步进电机只有在我启动时才会开始旋转(给"start"输入一个高逻辑)


每当我尝试模拟电路并点击 "start" 时,就会出现问题。蒂娜会挂掉然后 "Not Responding"。老实说,我不确定我在代码中犯了什么错误,因为每当我尝试 "Enter New Macro" 我的 VHDL 代码时,Tina 都没有显示任何错误。


我最好的猜测是我在循环命令中犯了错误

    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;


如果有人能指出错误,我将非常高兴。提前谢谢你,祝你有美好的一天!

您想要实现的是从计算机语言到 VHDL 的直接移植。 HDL 不是这样工作的,如果你想实现这种设计,你就必须改变你的范例。这里有一些提示:

  1. 您的实体和架构的描述似乎没问题
  2. 主进程的敏感度列表显示您希望它像线程一样 运行 "step by step",但在 HDL 中不能以这种方式进行综合。硬件设计描述的模型是一个过程是运行一次,每次在敏感列表中列出的信号上有一个事件。进程在等待更多事件时不能阻塞。如果您的灵敏度列表信号经过值测试,则意味着您的过程是组合的(纯逻辑)。这不是您想要得到的(您有一个 clk 信号)。因此,您的进程在其敏感列表中应该只有一个信号:clk。之后,您的流程主体可以以唯一的 IF rising_edge(clk) THEN 开头,清楚地表明一个时钟流程。
  3. 时钟进程不管理通过当前时钟周期的数据,因此您必须考虑要从一个周期保存到下一个周期的状态并将它们作为信号驱动。
  4. 与变量相比,信号是奇异的野兽,您需要了解它们如何根据事件和时间工作。例如counter <= counter;是没有用的。
  5. 您的系统行为的文本规范类似于状态机的描述。为什么不正式地改进它并将其充实为您的系统状态呢?看一个简单的例子here
  6. 一般来说,对于综合,您需要一种复位信号来确保您的所有状态都由硬件初始化。