@posedge clk无法正常工作

时间:2014-10-13 15:14:44

标签: verilog clock

我正在学习Verilog并且我正在实现一个半加法器,只有在时钟的上升沿到来时才会改变其输出,但结果会随输入而改变,而不是时钟。

以下是该计划的代码:

module Full_adder_clk_chng(
  input a,b, clk,
  output sum,cout
);
reg sum,cout;
always @ (posedge clk)
begin
  assign cout= a&b;
  assign sum=a ^b;
end
endmodule

这是testbench代码:

module tb2;

// Inputs
reg a;
reg b;
reg clk;

// Outputs
wire sum;
wire cout;

// Instantiate the Unit Under Test (UUT)
Full_adder_clk_chng uut (
    .a(a), 
    .b(b), 
    .clk(clk), 
    .sum(sum), 
    .cout(cout)
);

initial begin
clk=0;
end
always begin
#5; clk=~clk;
end
initial begin
    // Initialize Inputs
    a = 0;
    b = 0;
    #20;

    a=1;
    b=0;
    #23;

    a=0;
    b=0;
    #25;

    a=1;
    b=1;
    #3;

    a=0;
    b=0;
    #1;

    a=1;
    b=1;
    #1;

    a=0;
    b=0;
    #1;

    a=1;
    b=1;
    #20;
    $finish;
end

endmodule

1 个答案:

答案 0 :(得分:4)

assign关键字创建了连续分配。如果放在过程代码(例如always块)中,则在过程代码执行时开始连续分配。在这种情况下,正边沿时钟会不断重新启动连续分配。

在程序assign是必要的情况下,这种情况很少见。加入最新的LRM程序assign / deassign正在考虑弃用,因为它可能是“低效,容易滥用,以及设计问题的根源”,IEEE Std 1800-2012§C.4(注意:IEEE于2009年合并了Verilog& SystemVerilog。)

要在每个上升沿时钟上更新coutsum,只需省略assign即可。由于这是同步逻辑,因此重新开始使用非阻塞分配(<=)。组合逻辑应该使用阻塞分配(=)。

always @ (posedge clk)
begin
  cout <= a&b;
  sum  <= a^b;
end