首页 文章

为什么在VHDL中使用并发语句?

提问于
浏览
1

我刚开始学习vhdl . 考虑一下这里的代码: - http://esd.cs.ucr.edu/labs/tutorial/jkff.vhd

我无法理解什么是并发语句,为什么它们需要在这里?如果我们直接在过程p中修改Q和Qbar而不使用内部信号'state',这是否正确?另外为什么J,K不在代码片段中的过程p的敏感性列表中?

2 回答

  • 0

    正如您所知,并发声明在纯粹的功能意义上(即不考虑硬件实现)不会产生任何延迟 . 所以当你写作

    Q <= state;
    

    从功能上讲, Q 完全遵循 state ,没有任何延迟 .

    我猜测使用中间信号 state 而不是直接在过程中分配 Q 的原因是,如果你在过程中直接指定了一个输出 Q ,那么你不能"read"输出来得出你的 Qbar 信号 .

    也就是说,你不能这样做:

    Qbar <= not Q;
    

    这是因为不严格允许以VHDL读取输出信号 . 通过使用"state",您有一个内部信号,您可以从中获取 QQbar .

    对此的另一种等效实现是在状态机中的每种情况下分配输出 QQbar ,并完全消除中间 state 信号 . 但是,这看起来有点复杂,因为对于同等功能,您将拥有几乎两倍的代码行 .


    要回答第二个问题:J,K不在敏感度列表中,因为进程 p 是一个同步过程 . 您正在描述一个内存元素(JK FlipFlop),根据定义,它仅在 clockreset 更改时更新其输出 . 输入信号 JK 可以更改,并且过程不会更新其输出 . 每次有时钟边沿或 reset 被置位时,进程"wakes up"并评估输入,并确定输出应该是什么 . 即使在J中,K也包含在灵敏度列表中,只要您的输出仅在 rising_edge(clock) 上更新,那么整体功能将是相同的(尽管您的代码会令人困惑) .

  • 2

    没有理由不在进程中进行 QQbar 赋值 . 你需要小心一点 .

    无论何时分配信号,该值都不会更新,直到模拟器移动到下一个"delta-cycle" . 这意味着在进程中,当您分配信号时,您通常只是调度和更新,如果您读取信号,您将获得"old"值 . 为了获得您可能期望的那种顺序更新,您可以使用变量 . 所以你可以这样建模JKFF:

    architecture behv of JK_FF is
    begin
        p : process(clock, reset) is
        variable state : std_logic;
            variable input : std_logic_vector(1 downto 0);
        begin
            if (reset = '1') then
                state := '0';
            elsif (rising_edge(clock)) then
                input := J & K;
                case (input) is
                    when "11" =>
                        state := not state;
                    when "10" =>
                        state := '1';
                    when "01" =>
                        state := '0';
                    when others =>
                        null;
                end case;
            end if;
            Q  <= state;
            Qbar <= not state;
        end process;
    end behv;
    

    综合注释:Q和Qbar的赋值发生在 if rising_edge(clk) 之外,因此将被解释为与并发驱动程序一样 .

相关问题