异步复位神秘地设置输出reg

时间:2015-04-12 19:22:57

标签: asynchronous verilog reset

我的代码如下:

module timer(
    input clk,
    input reset,
    output reg signal // <--- PROBLEMATIC SIGNAL
);

    always@(posedge clk or posedge reset)
    begin
    if(reset)
        signal <= 1;
    else
        signal <= 0;
    end
endmodule

和这个测试平台,在modelsim上执行:

`timescale 1ns / 1ps
`define PERIOD 20

module timer_tb;
    logic clk;
    logic reset;
    logic signal;

    timer inst(
        .clk(clk),
        .reset(reset),
        .signal(signal)
    );

    initial
    begin
        clk = 0;
        forever clk = #(`PERIOD/2) ~clk;
    end

    initial
    begin
        reset = 0; //<--- RESET STARTS CLEANED. 
        #(`PERIOD)
        reset = 1;
        #(`PERIOD)
        reset = 0;
        #(`PERIOD*3)
        reset = 1;
        #(`PERIOD)
        reset = 0;

        #(`PERIOD*3)
        $display("End of the simulation");
        $stop;
    end
endmodule

输出注册signal开始为高,但在代码中,此注册表取决于resetreset启动为DOWN。我不明白为什么signal在模拟开始时注册为HIGH,因为reset肯定是DOWN开始。

我需要signal开始向下,只需设置为reset转到1(条件posedge reset就像我的代码一样)。

请查看this print of the waveform,了解我的问题。

3 个答案:

答案 0 :(得分:0)

signal没有初始值,因此在时间0的值未定义。一些模拟器将其初始化为0,其他模拟器初始化为1,其他模拟器初始化为X.

使用初始块将signal初始化为0。

module timer(
    input clk,
    input reset,
    output wire signal
);

    reg rsignal;
    assign signal = rsignal;

    initial begin
      rsignal = 1'b0;
    end

    always@(posedge clk or posedge reset)
    begin
    if(reset)
        rsignal <= 1;
    else
        rsignal <= 0;
    end
endmodule

答案 1 :(得分:0)

reg的默认值是'x'或未定义,wire的默认值是'Hi-Z',所以在这种情况下你的输出(信号)是reg类型,因此模拟器相应地采用默认值,以获得默认值'0'SystemVerilog(IEEE1800-2012)附带位数据类型,您可以尝试使用输出中的位,如下所示

 module timer(
    input clk,
    input reset,
    output bit signal 
);

    always@(posedge clk or posedge reset)
    begin
    if(reset)
        signal <= 1;
    else
        signal <= 0;
    end
endmodule

编辑:我不确定quartus但反过来你可以尝试通过这种方法在输出处将值初始化为0或1,它应该在Verilog中工作

module timer(
    input clk,
    input reset,
    output reg signal=0
);

    always@(posedge clk or posedge reset)
    begin
    if(reset)
        signal <= 1;
    else
        signal <= 0;
    end
endmodule

答案 2 :(得分:0)

您的波形具有时钟到q的延迟,但您的RTL型号没有任何延迟。这意味着您没有运行RTL模拟。而是运行合成门级仿真或从FPGA获得输出。

需要考虑的是,在测试平台中,clkreset从X开始不是0.在零时刻变为0。 Verilog允许并行处理的不确定顺序,可以选择在零时刻执行始终块,而不管其灵敏度列表如何,并且用于比较的X in评估为真。根据供应商实现模拟器的方式,可以首先执行始终块。 reset被X评估为真,并将signal指定为1.然后clkreset被指定为0.所有这些都发生在0时,无法在波形中看到

这使得不可预测性成为一种无意的现实。当您第一次接通电路时,您最初得到的信息可能无法预测(这是因为工艺变化,物理布线,电源斜坡时的毛刺等)。您可以使用重置将设计置于已知状态。

如果您想阻止clkreset开始使用X,请将测试平台中的数据类型从logic更改为bit(注意:bitlogic是SystemVerilog)。应该起作用的另一个选项(不是100%保证)是在{1}}和clk的同一行中初始化它。

reset

假设您正在运行模拟,这应该可行。如果您在FPGA上运行,则无法通过测试平台的更改来保证此时的零行为。

最干净的解决方案是从启用logic clk = 1'b0; logic reset = 1'b0; 开始。在零时间重置之前,您不应该关心值是什么。

相关问题