0

我想设计一个简单的 Verilog 代码,它包含两个 always 块,交替执行,如握手。我想使用两个标志 do_A 和 do_B 来控制两个块 block_A 和 block_B。预期的结果一定是 ABABAB... 有没有办法更正下面的代码?谢谢你帮助我。

    module tb;
    reg clock, reset, do_A, do_B;

    initial begin clock = 0; reset = 0; #50; reset = 150; #50; reset = 0; end
    always #50 clock = ~clock;

    always @(posedge clock) begin: block_A
        if (reset) do_B <= 0;
        else if (do_A) begin
            do_B <= 0;
            $display("A");
        end 
    end

    always @(posedge clock) begin:block_B
        if (reset) do_A <= 1;
        else if (do_B) begin
            do_A <= 0;
            $display("B");
        end 
    end
endmodule

感谢 Vesiliy,以下代码可以很好地达到预期的效果。

always @(posedge clock) begin: Block_A
        if (reset) do_B = 0;
        else if (do_A) begin
            do_B = 0;
            $display("A");
        end 
        else do_B <= 1;
    end

    always @(posedge clock) begin:Block_B
        if (reset) do_A = 1;
        else if (do_B) begin
            do_A = 1;
            $display("B");
        end 
        else do_A <= 0;

这似乎很奇怪,但效果很好。

4

1 回答 1

3

首先reset = 150;看起来很奇怪(错字?)。不过,它在这种情况下有效。

您在第一个顺序中有另一个错字always-您(似乎)打算写的是:

else if (do_A) begin
    do_B <= 1;
    $display("A");
end 

else但是,我认为您的主要问题是您的顺序always块中没有(默认)子句。

看看这个块(例如):

always @(posedge clock) begin:block_B
    if (reset) do_A <= 1;
    else if (do_B) begin
        do_A <= 0;
        $display("B");
    end 
end

复位后置低do_A = 1;然后,假设您修复了之前的错字,do_B将变为 1,这将导致do_A变为 0。达到此状态后,do_A将卡在 0 直到您重置所有内容。

以下添加应解决此问题(第一个always块相同):

always @(posedge clock) begin:block_B
    if (reset) do_A <= 1;
    else if (do_B) begin
        do_A <= 0;
        $display("B");
    end
    else do_A <= 1; 
end

我相信您的带有上述修复的代码将起作用,但是,描述此功能的正确方法是实现具有 2 个状态的(简单)状态机。去谷歌上查询。

于 2013-07-01T06:22:35.180 回答