Verilog 为什么模块的输出可以';无法从模块外部到达

Verilog 为什么模块的输出可以';无法从模块外部到达,verilog,Verilog,我用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]

我用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
模块异步计数器(clk、res、out);
输入时钟;
输入res;
输出[3:0]输出;
注册[3:0]输出;
电线电缆;
钢丝绳;
首字母
out=4'b0;
始终@(negedge clk或posedge res)
如果(res)开始

在[0]这里,
res
tripleInputClk
模块中声明为
wire

我模拟了你的代码,观察到信号
tripledClk
三个时钟脉冲后变高。因此,怀疑必须出现
res
信号的
posedge
。但是,
res
在连续赋值语句中。一旦
res
变为HIGH,reg
out
就会改变(
@(posedge res)
)并再次使
res
变为LOW;所有这些都在一个时间戳中。因此,您无法查看res信号的转换

另外,在那之后,
tripledClk
信号也不会像预期的那样切换,我猜

一种方法是在
tripleInputClk
模块中将
res
声明为
reg
,并将其从连续赋值中删除。相反,使其仅在时钟信号的边缘上工作

这是因为,reg用于存储值。这里,在
out
上存在
res
循环依赖关系,反之亦然(即
out
也依赖于
res
)。从今往后,它创造了一些令人困惑的条件(我不会确切地将其称为绕场比赛条件)

当您继续进行合成时(即使初始块在此不可合成!),该工具可能会发出此循环依赖项警告。并且,可能无法形成适当的硬件

我已经修改了您的代码,并为其提供了一个测试台。唯一的变化是我在这里描述的变化,即
res
信号。请浏览下面的链接。
tripledClk
现在也可以正常工作(3*clk频率)

链接到

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