VHDL-带复位的推断锁存器-FSM

VHDL-带复位的推断锁存器-FSM,vhdl,fpga,fsm,Vhdl,Fpga,Fsm,我在这个过程中遇到了一个问题,如果我包含一个reset语句,我会得到一个推断的锁存。但是,如果我不包括reset语句,我就不会得到一个推断的闩锁占空比三角形 SIGNAL duty_cycle_triangle : INTEGER := 0; SIGNAL count_up : STD_LOGIC; SIGNAL tick_zero : STD_LOGIC; triangle_count: PROCESS(clk, reset signal, tick_zero

我在这个过程中遇到了一个问题,如果我包含一个reset语句,我会得到一个推断的锁存。但是,如果我不包括reset语句,我就不会得到一个推断的闩锁占空比三角形

    SIGNAL duty_cycle_triangle : INTEGER := 0;
    SIGNAL count_up : STD_LOGIC;
    SIGNAL tick_zero : STD_LOGIC;

    triangle_count: PROCESS(clk, reset signal, tick_zero)
        BEGIN
            IF (reset = '1') THEN
                duty_cycle_triangle <= 0;
            ELSIF (RISING_EDGE(clk)) THEN
                IF (tick_zero = '1') THEN
                    IF (count_up = '1') THEN
                        duty_cycle_triangle <= duty_cycle_triangle + 2;
                    ELSE
                        duty_cycle_triangle <= duty_cycle_triangle - 2;
                    END IF;
                END IF;
            END IF;
    END PROCESS;
信号占空比\u三角形:整数:=0;
信号计数:标准逻辑;
信号勾零:标准逻辑;
三角计数:过程(时钟、复位信号、勾零)
开始
如果(重置='1'),则

占空比\u三角形如果您想创建一个顺序过程,请在灵敏度列表中只包括一个复位和一个时钟。我怀疑这是在推断闩锁,因为在此过程中包含了太多信号:

triangle\u count:进程(时钟、复位信号、勾选零)

应该是

triangle\u计数:过程(重置、时钟)


这些工具没有将其视为一个顺序过程,并将其组合起来,这就是获得闩锁的方式。

如果不尝试,我想知道当删除reset语句时,工具是否将该过程识别为同步过程并推断寄存器。在这种情况下,您不需要为流程的每个结果显式定义占空比三角,因为值存储在寄存器中

在包含reset语句的情况下,它可能将该过程视为组合过程,因此在未明确定义的情况下推断锁存器以存储占空比三角形的状态


无论哪种方式,我都同意Russell关于更改流程敏感度列表的建议,该列表应去掉闩锁。

合成对敏感度列表的关注历史上来自要求合成后模拟行为匹配输入行为,现在通过正式方法验证。无论有无闩锁,模拟和合成模型行为都将匹配。将行为映射到应该依赖于固有优先级的合成原语并不依赖于敏感度列表。存在闩锁是一个特定的合成工具映射缺陷,而不是流程语句的问题。
        FSM_comb: PROCESS(currentState, duty_cycle_triangle)
        BEGIN
            CASE currentState IS
                WHEN triangle_up =>
                    PWM_enable <= '1';
                    count_up <= '1';
                    IF (duty_cycle_triangle > 99) THEN
                        nextState <= triangle_down;
                    ELSE
                        nextState <= triangle_up;
                    END IF;
                WHEN triangle_down =>
                    PWM_enable <= '1';
                    count_up <= '0';
                    IF (duty_cycle_triangle < 1) THEN
                        nextState <= triangle_up;
                    ELSE
                        nextState <= triangle_down;
                    END IF;
            END CASE;
    END PROCESS;


    FSM_seq: PROCESS(clk, reset)
        BEGIN
            IF (reset = '1') THEN
                currentState <= triangle_up;
            ELSIF (RISING_EDGE(clk)) THEN
                currentState <= nextState;
            END IF;
    END PROCESS FSM_seq;