VHDL模拟即使没有显示错误

时间:2018-05-04 20:19:24

标签: vhdl hang state-machine

我是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.我可以选择步进电机(用LED指示)与“加”和“减”开关一起旋转的次数(它可以从-9到9计数)
    2. 7段的点是显示屏中显示的数字的负号     3.正值使电机顺时针旋转     4.负值(用7段中的点表示)将使电机沿逆时针方向旋转     5.每次电机完成1次旋转时,7段数应减少1位数     6.步进电机只有在启动时才会开始旋转(为“启动”输入提供高逻辑)


每当我试图模拟电路并点击“开始”时就会出现问题。蒂娜只会挂起然后“不回应”。说实话,我不确定我在代码中犯了什么错误,因为每当我尝试用我的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;


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

1 个答案:

答案 0 :(得分:0)

您要实现的是从计算机语言到VHDL的直接端口。 HDL不会以这种方式工作,如果你想实现这个设计,你必须改变你的范例。以下是一些提示:

  1. 您的实体和架构的描述似乎没问题
  2. 主要流程&#39;灵敏度列表显示你希望它能够像线程一样逐步运行,但是在HDL中无法通过这种方式进行综合。硬件设计描述的模型是每次在敏感性列表中列出的信号上存在事件时,整个过程运行一次。等待进一步的事件时,该过程无法阻止。如果您的灵敏度列表信号是针对值进行测试的,那意味着您的过程是组合的(纯逻辑)。这不是你打算得到的(你有一个clk信号)。所以你的过程在灵敏度列表中应该只有一个信号:clk。在此之后,您的流程正文可以使用唯一的IF rising_edge(clk) THEN开头,该counter <= counter;可以清楚地显示时钟流程。
  3. 时钟进程不管理通过当前时钟周期的数据,因此您必须考虑要从一个周期到下一个周期保存的状态并将其作为信号驱动。
  4. 与变量相比,信号是异国情调的野兽,您需要了解它们如何在事件和时间方面发挥作用。例如{{1}}没用。
  5. 系统行为的文本规范类似于状态机的描述。为什么不正式改进它并将其充实为系统状态?请参阅一个简单示例here
  6. 通常,对于合成,您需要一种复位信号,以确保所有状态都由硬件初始化。