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

时间:2013-09-13 15:14:49

标签: vhdl

我刚开始学习vhdl。 请考虑以下代码: - http://esd.cs.ucr.edu/labs/tutorial/jkff.vhd

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

2 个答案:

答案 0 :(得分:2)

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

Q <= state;

从功能上讲,Q 完全遵循 state而不会有任何延迟。

我猜测使用中间信号state而不是直接在流程中分配Q的原因是,如果您直接指定一个输出Q在此过程中,您无法“读取”输出以获取Qbar信号。

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

Qbar <= not Q;

这是因为在VHDL中不严格允许读取输出信号。通过使用“状态”,您可以获得内部信号,从中可以得出QQbar

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


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

答案 1 :(得分:0)

没有理由不在流程中进行QQbar分配。你需要小心一点。

无论何时分配信号,该值都不会更新,直到模拟器移动到下一个“delta-cycle”。这意味着在进程中,当您分配信号时,您实际上只是 cheduling 并更新,如果您读取信号,您将获得“旧”值。为了获得您可能期望的那种顺序更新,您可以使用变量。所以你可以这样建模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)之外,因此将被解释为与并发驱动程序一样。