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

时间:2015-10-24 20:55:51

标签: 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] <= 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;。

1 个答案:

答案 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