为什么模块的输出无法从外部模块到达

why output of a module can't reach from outside module

我用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

第一个模块工作正常,但是当我编译它并制作它的波形时,我明白第一个模块的输出没有正确通过并且 'res' 的值总是等于'0'。

此处,res 在您的 tripleInputClk 模块中声明为 wire

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

而且,在那之后,tripledClk 信号没有按预期切换,我猜。

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

这是因为,reg是用来存储值的。这里,resout 上存在 循环依赖性 ,反之亦然(即 out 也依赖于 res) .从今以后,它创造了某种令人困惑的条件(我不会将其准确地称为围绕条件的竞赛)。

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

我已经修改了您的代码并为其提供了一个 testbench。唯一的变化是我在这里描述的变化,即 res 信号。请仔细阅读下面的link。 tripledClk 现在也可以正常工作 (3*frequency_of_clk)。

Link 到 EDAPlayground.