使用D'触发器的波纹计数器

时间:2013-02-27 16:49:36

标签: counter verilog

我编写了这段代码,用于使用D触发器模拟异步计数器。程序为第一次迭代提供正确的输出,但输出完全没有变化。我做错了什么?

以下是代码:

第一个模块:

module DFF(d,q,reset,clk);
  input      d,reset,clk;
  output reg q;

  always @(posedge reset, posedge clk) begin
    if(reset) begin
      q=0;
    end
    if(d)
      q=d;
    else
      q=q;
   end
endmodule

第二个模块:

module RippleCounter(d,clk,reset,out);
  input  [3:0] d;
  input        clk, reset;
  output [3:0] out; // 4bit

  DFF a(d[0],out[0],reset,clk);
  DFF b(d[1],out[1],reset,out[0]);
  DFF c(d[2],out[2],reset,out[1]);
  DFF dx(d[3],out[3],reset,out[2]);
endmodule

第3单元:

module RippleCounterTOP;
  reg  [3:0] d;
  reg        clk, reset;
  wire [3:0] out;

  RippleCounter r(d,clk,reset,out);

  initial begin
    d=0;clk=0;reset=1;
  end

  always begin 
    #5 d=d+1; clk=~clk;
  end
endmodule

2 个答案:

答案 0 :(得分:1)

查看纹波计数器的this picture,来自testharness的唯一输入应该是时钟。

使用的翻牌类型通常类似于:

always @(posedge reset, posedge clk) begin
  if(reset) begin
    q <= 'b0;
  end
  else begin
    q <= ~q;
  end
end

在模块1 always@(posedge clk ..中,您应该使用非阻止<=分配而不是=

在模块3中,你总是有一个没有灵敏度列表的块,我会添加@*,这看起来你真的想要一个带有repeat或for循环的初始化来执行你的测试然后调用{{ 1}}一旦完成。我在下面使用了$finish() SystemVerilog,但如果需要,您可以更改为#5ns

#5

试试你的例子,这就是我最终的结果我认为这是你要做的事情:注意正确的答案是integer i; initial begin d=0;clk=0;reset=1; #5ns reset=0; for (i=0; i<5'b1000; i=i+1) begin #5ns d=d+1; clk=~clk; $display("%4b, %4b", d, out); end $finish; end

第1单元,可以使用q和q_bar输出进行扩展。

~out

第2单元

module DFF(q,reset,clk);
  input      reset,clk;
  output reg q;

  always @(posedge reset, posedge clk) begin
    if(reset) begin
      q<=0;
    end
    else begin
      q<=~q;
   end
 end
endmodule

第3单元(Testharness)

module RippleCounter(clk,reset,out);
  input        clk, reset;
  output [3:0] out; // 4bit

  DFF ax(out[0],reset,clk);
  DFF bx(out[1],reset,out[0]);
  DFF cx(out[2],reset,out[1]);
  DFF dx(out[3],reset,out[2]);
endmodule

答案 1 :(得分:0)

我不确定您对输出的期望是什么,但有一个问题是您总是要重置DFF。