异步重置神秘地设置输出寄存器
Asynchronous reset mysteriously setting up output reg
我有以下代码:
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
输出 reg signal
开始为 HIGH,但在代码中,此 reg 取决于 reset
,而 reset
开始为 DOWN。我不明白为什么 signal
寄存器在模拟开始时为高电平,因为 reset
肯定开始向下。
我需要 signal
开始 DOWN 并且仅在 reset
转到 1 时设置(条件 posedge reset
就像我的代码一样)。
请查看 this print of the waveform 以便清楚地了解我的问题。
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
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
您的波形有时钟到 q 延迟,但您的 RTL 模型没有任何延迟。这意味着您不是 运行 RTL 仿真。相反,您是 运行 综合门级模拟或从 FPGA 获取输出。
需要考虑的是,在测试台中,clk
和 reset
以 X 而不是 0 开始。在时间为零时变为 0。 Verilog 允许并行进程的不确定顺序,无论其敏感度列表如何,都可以选择在时间为零时执行 always 块,并且用于比较的 X 评估为真。根据供应商如何实施模拟器,always 块可能首先执行。 reset
being X 求值为真,将signal
赋值为1。然后clk
和reset
赋值为0。所有这些都发生在时间0,在波形中看不到.
这种允许的不可预测性是现实的无意片段。当您第一次给电路上电时,您最初得到的结果可能是不可预测的(这是由于工艺变化、物理布线、电源上升时的毛刺等)。您使用重置使设计进入已知状态。
如果你想阻止 clk
和 reset
从 X 开始,然后将测试平台中的数据类型从 logic
更改为 bit
(注意:bit
和 logic
是 SystemVerilog)。另一个应该有效的选项(不是 100% 保证)是在声明的同一行中初始化 clk
和 reset
。
logic clk = 1'b0;
logic reset = 1'b0;
假设您是 运行 模拟,这应该可以工作。如果您 运行 在 FPGA 上,您无法保证这次通过更改测试平台实现零行为。
最干净的解决方案是从启用 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
输出 reg signal
开始为 HIGH,但在代码中,此 reg 取决于 reset
,而 reset
开始为 DOWN。我不明白为什么 signal
寄存器在模拟开始时为高电平,因为 reset
肯定开始向下。
我需要 signal
开始 DOWN 并且仅在 reset
转到 1 时设置(条件 posedge reset
就像我的代码一样)。
请查看 this print of the waveform 以便清楚地了解我的问题。
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
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
您的波形有时钟到 q 延迟,但您的 RTL 模型没有任何延迟。这意味着您不是 运行 RTL 仿真。相反,您是 运行 综合门级模拟或从 FPGA 获取输出。
需要考虑的是,在测试台中,clk
和 reset
以 X 而不是 0 开始。在时间为零时变为 0。 Verilog 允许并行进程的不确定顺序,无论其敏感度列表如何,都可以选择在时间为零时执行 always 块,并且用于比较的 X 评估为真。根据供应商如何实施模拟器,always 块可能首先执行。 reset
being X 求值为真,将signal
赋值为1。然后clk
和reset
赋值为0。所有这些都发生在时间0,在波形中看不到.
这种允许的不可预测性是现实的无意片段。当您第一次给电路上电时,您最初得到的结果可能是不可预测的(这是由于工艺变化、物理布线、电源上升时的毛刺等)。您使用重置使设计进入已知状态。
如果你想阻止 clk
和 reset
从 X 开始,然后将测试平台中的数据类型从 logic
更改为 bit
(注意:bit
和 logic
是 SystemVerilog)。另一个应该有效的选项(不是 100% 保证)是在声明的同一行中初始化 clk
和 reset
。
logic clk = 1'b0;
logic reset = 1'b0;
假设您是 运行 模拟,这应该可以工作。如果您 运行 在 FPGA 上,您无法保证这次通过更改测试平台实现零行为。
最干净的解决方案是从启用 reset
开始。您不应该关心在零时间重置之前的值是什么。