1

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

我不明白什么是并发语句,为什么这里需要它们?如果我们直接在进程 p 中修改 Q 和 Qbar 而不使用内部信号“状态”,是否正确?还有为什么 J,K 不在片段中进程 p 的敏感度列表中?

4

2 回答 2

2

您可能知道,并发语句在纯功能意义上(即不考虑硬件实现)不会产生任何延迟。所以当你写

Q <= state;

在功能上,Q 完全遵循 state,没有任何延迟。

我猜想使用中间信号state而不是直接Q在流程内部分配的原因是,如果您在流程中直接分配一个输出Q,那么您无法“读取”输出来导出您的Qbar信号。

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

Qbar <= not Q;

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

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


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

于 2013-09-13T16:42:43.773 回答
0

没有理由不在流程中进行QandQbar分配。不过,您需要稍微小心。

每当分配一个信号时,该值不会更新,直到模拟器进入下一个“增量周期”。这意味着在进程中,当您分配给信号时,您实际上只是在调度和更新,如果您读取信号,您将获得“旧”值。为了获得您可能期望的那种顺序更新,您使用了一个变量。所以你可以像这样对 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)so 之外,将被解释为就像并发驱动程序一样。

于 2013-09-16T12:20:17.013 回答