Verilog:使用寄存器的一个时钟周期延迟

时间:2017-05-22 10:08:06

标签: verilog

我试图延迟两个信号。我写了一个寄存器来做这件事并实例化它但发生了一件奇怪的事情。延迟"州"信号似乎有效,但延迟" nb_bits"信号没有。

这是我的注册码:

`timescale 1ns / 1ps

module register(
    input CLK,
    input clr,
    input en,
    input [7:0] in,
    output [7:0] out
    );

    reg [7:0] temp;

    always @ (posedge CLK or posedge clr) begin
        if (clr) begin
            temp <= 8'b00010000;
        end
        else if (en) begin
            temp <= in;
        end
        else begin
            temp <= temp;
        end
    end

    assign out = temp;

endmodule

那个实例化:

wire [3:0] nbb;
nb_bits_register nb_bits_reg(
    .CLK(CLK),
    .clr(clr),
    .en(en),
    .in(nb_bits),
    .out(nbb)
);

wire [7:0] stt;
register state_reg(
    .CLK(CLK),
    .clr(clr),
    .en(en),
    .in(state),
    .out(stt)
);

nb_bits_register模块是类比的;在解决这个问题之前,我不想参数化。

`timescale 1ns / 1ps

module nb_bits_register(
    input CLK,
    input clr,
    input en,
    input [3:0] in,
    output [3:0] out
    );

    reg [3:0] temp;

    always @ (posedge CLK or posedge clr) begin
        if (clr) begin
            temp <= 4'b0000;
        end
        else if (en) begin
            temp <= in;
        end
        else begin
            temp <= temp;
        end
    end

    assign out = temp;

endmodule

这是一个模拟: enter image description here

和testbench:

`timescale 1ns / 1ps

module state_machine_tb();

    reg CLK, clr, en;
    reg [7:0] symbol;
    reg [3:0] nb_bits;
    wire [7:0] state;

    initial begin
        CLK <= 1;
        clr <= 0;
        en <= 0;
        symbol <= 8'b00110010;
        nb_bits <= 1;
        #10

        clr <= 1;
        en <= 1;
        #10

        clr <= 0;
        symbol <= 8'b00110001;
        nb_bits <= 1;
        #10

        symbol <= 8'b00110010;
        nb_bits <= 2;
        #10

        symbol <= 8'b00110001;
        nb_bits <= 1;
        #10

        symbol <= 8'b00110001;
        nb_bits <= 1;
        #10

        symbol <= 8'b00110000;
        nb_bits <= 3;
        #10

        $finish;
    end

    always begin
        #5 CLK <= ~CLK;
    end

    state_machine state_machine_inst(
        .CLK(CLK),
        .clr(clr),
        .en(en),
        .symbol(symbol),
        .nb_bits(nb_bits),
        .state(state)
    );

endmodule

2 个答案:

答案 0 :(得分:0)

这似乎是竞争条件:CLK的更改与nb_bits的正边缘重合,因此模拟器以这种方式解决了歧义:

  • 更改CLK(从1到2等)
  • nb_bits_register从0更改为1
  • 执行if (en) temp <= in; ... assign out = temp;out = in

结果是nb_bits_register中的#10

解决方案是避免这种巧合,例如通过将测试平台中的第一个#11更改为shared = memcache.Client([('127.0.0.1:11211')]) imagefile= pygame.image.load(image.png) data = pygame.image.tostring(imagefile, "RGBA", True) shared.set('SharedImage',data)

答案 1 :(得分:0)

在调度程序中看起来似乎是一种诡计。根据Verilog LRM的定义,评估程序块(总是块和初始块)的顺序是不确定的。您可能会注意到具有特定模拟器和版本的模式,但在更改模拟器或更改同一模拟器的版本时,该模式可能会发生变化。

  • 使用时钟阻止分配(例如:always #5 CLK = ~CLK;)。保证CLK将在其他刺激之前更新。
  • 在测试平台中,将所有#10更改为@(posedge CLK)。时间将是相同的,但在评估新值CLK和其他刺激之前,它保证symbol已更新。

仅供参考:如果您将output [7:0] out更改为output reg [7:0] out,则可以直接在始终屏蔽中指定out,从而无需temp。这在功能上没有任何改变;只需更少的变量和代码行。