Asynchronous 异步复位神秘地设置输出寄存器

Asynchronous 异步复位神秘地设置输出寄存器,asynchronous,verilog,reset,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

我有以下代码:

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
模块定时器(
输入时钟,
输入复位,

输出reg信号//
信号
没有初始值,因此其在时间0时的值未定义。一些模拟器将其初始化为0,其他模拟器将其初始化为1,其他模拟器将其初始化为X

使用初始块将
信号
初始化为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
模块定时器(
输入时钟,
输入复位,
输出线信号
);
reg-rsignal;
分配信号=rsignal;
初始开始
r信号=1'b0;
结束
始终@(posedge clk或posedge重置)
开始
如果(重置)

rsignalreg的默认值为'x'或未定义,导线的默认值为'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
模块定时器(
输入时钟,
输入复位,
输出位信号
);
始终@(posedge clk或posedge重置)
开始
如果(重置)

信号您的波形具有时钟到q的延迟,但您的RTL模型没有任何延迟。这意味着您没有运行RTL模拟。相反,您正在运行合成门级模拟或从FPGA获取输出

要考虑的是,在测试台上,<代码> CLK 和<代码> RESET 以x为0开始。在时间零时变为0。Verilog允许并行处理的不确定顺序,无论其敏感度列表如何,都可以在时间零时执行一个常量块,而一个比较的X值则为真。供应商实施模拟器时,可能会首先执行始终块。

reset
被X评估为真,并将
信号分配给1。然后
clk
reset
分配给0。所有这些都发生在时间0,在波形中看不到

这种允许的不可预测性是一种无意的现实。当您第一次给电路通电时,您最初得到的可能是不可预测的(这是由于工艺变化、物理路由、电源斜坡时的故障等)。您使用重置使设计进入已知状态

如果要防止
clk
重置
从X开始,则将测试台中的数据类型从
逻辑
更改为
(注意:
逻辑
为SystemVerilog)。另一个选项应该有效(不100%保证)是在声明的同一行中初始化
clk
reset

logic clk = 1'b0;
logic reset = 1'b0;
假设您正在运行模拟,这应该是可行的。如果您在FPGA上运行,则无法通过更改测试台来保证此时间为零


最干净的解决方案是从启用<代码>重置开始。在时间零点重置之前,您不应该关心值是什么。

谢谢您的回答。但我不能使用初始语句,因为我需要构建一个可合成的设计。另一点是,我测试了没有“或posedge重置”的设计感性和我得到“信号”正确地从0开始。我不知道为什么插入异步重置后会发生这种情况…
initial
是可合成的,至少对于FPGA和CPLD是如此。对于ASIC可能不是。我使用了initial语句和您的代码。但信号一直高起点。看看这些打印:| |可能是您的测试bench.看看这个交互式Verilog编辑器,看看你的设计和一个只有Verilog的测试台(没有<代码>逻辑<代码>数据类型):不幸的是,我只能开发一个Verilog设计。我不能使用系统Verilog分配或构造。因此,在quartus软件中,我在尝试使用“位”构造后得到这个错误:“错误(10161):Verilog HDL定时器错误。v(5):对象“位”未声明“谢谢你的解释。你是对的,我正在modelsim altera软件上运行门级模拟。我尝试应用你的建议(在测试台上从逻辑更改为位,并在声明的同一行中初始化clk并重置为0。),但我仍然得到了相同的结果。这是难以置信的。仍然切换到1,然后在clk站起来时返回,即使每个人都以0(而不是X)开始。这很奇怪。
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
logic clk = 1'b0;
logic reset = 1'b0;