我用Verilog写了两个模块。 第一个模块是4位计数器:
module ASYNCHRONOUS_COUNTER( clk, res, out);
input clk;
input res;
output[3:0] out;
reg[3:0] out;
wire clk;
wire res;
initial
out = 4'b0;
always @(negedge clk or posedge res)
if(res) begin
out[0] <= 1'b0;
end else begin
out[0] <= ~out[0];
end
always @(negedge out[0] or posedge res)
if(res) begin
out[1] <= 1'b0;
end else begin
out[1] <= ~out[1];
end
always @(negedge out[1] or posedge res)
if(res) begin
out[2] <= 1'b0;
end else begin
out[2] <= ~out[2];
end
always @(negedge out[2] or posedge res)
if(res) begin
out[3] <= 1'b0;
end else begin
out[3] <= ~out[3];
end
endmodule
第二个模块使用第一个模块:
module tripleInputClk(clk,tripledClk);
input clk;
wire clk;
output tripledClk;
wire tripledClk;
wire res;
wire[3:0] out;
reg temp;
initial
temp <= 1'b0;
//assign out = 3'b0;
assign res = ~out[3] & ~out[2] & out[1] & out[0];
ASYNCHRONOUS_COUNTER myCounter(
.clk(clk),
.res(res),
.out(out)
);
always @(posedge res)
begin
temp <= ~temp;
end
assign tripledClk = temp;
endmodule
第一个模块正常工作,但是当我编译它并制作它的波形时,我明白第一个模块的输出没有正确传递,并且“&#39; res&#39;总是等于&#39; 0&#39;。
答案 0 :(得分:0)
此处,res
模块中wire
被声明为tripleInputClk
。
我模拟了您的代码并观察到信号tripledClk
在三个时钟脉冲后变为高电平。因此,怀疑必须发生posedge
res
信号。但是,res
在连续赋值语句中。只要res
变为高级,注册out
就会发生变化(@(posedge res)
)并再次使res
低;所有这些在一个时间戳中。因此您无法查看res信号的转换。
此外,在此之后,我猜测tripledClk
信号没有按预期切换。
一种方法是在res
模块中将reg
声明为tripleInputClk
,将从连续作业中删除。相反,只能使其适用于时钟信号的边缘。
这是因为,reg用于存储值。这里,res
上的out
存在循环依赖,反之亦然(即out
也依赖于res
)。从此以后,它会产生某种令人困惑的条件(我不会将其称为完全符合条件的竞赛)。
当您进行综合时(即使初始块在此处无法合成......!),该工具可能会发出此循环依赖警告。并且,可能不会形成适当的硬件。
我修改了您的代码,并为其提供了 testbench 。唯一的变化是我在这里描述的那个,即res
信号。请点击以下链接。 tripledClk
现在也可以正常工作(3 * frequency_of_clk)。
链接到EDAPlayground。