3个或更多的序列:Verilog调试

问题描述

我是 Verilog 编码的新手,并且在我的代码中遇到错误。有人可以帮忙调试吗?

主要代码

module tff (q,t,clk,clear);
  input t,clear;
  output reg q;
  always @(negedge clk or posedge clear)
  begin
    if (clear) q <= 0;
    else if(t==1) q <= ~q;
    else q<= q;
  end
endmodule

module seriesof3 (y,q1,q2,a,clear);
  input a,clear,q2;
  output reg y,q2;
  always @(negedge clk or posedge clear)
  begin
    if (clear) begin
        q1 <= 0;
        q2 <= 0;
     end
    else begin
        tff ta (q1,clear);
        tff tb (q2,~q1&(q2^a),clear);
        y <= a&q2;
     end
  end
endmodule

测试平台代码

'timescale = 1 ms/1 ms
module testbench(y,clear)
  reg a,clear;
  wire y,q2;
  seriesof3 DUT (y,clear);
  initial
    begin 
        $ dumpvars(0,test_bench);
        $ dumpfile("first.vcd");
        $ monitor ($time,"a=%b,Y= %b",y);
        clear<=0;
        a<=0;
        #2 clear<=1;
        #5 clear<=0;
    end
  forever #5 clk= ~clk;
  begin
    #8 a=0;
    #5 a=1;
    #5 a=1;
    #5 a=1;
    #5 a=1;
    #5 a=0;
    #5 a=1;
    #5 a=1;
    #5 a=0;
    #5 a=1;
    #5 a=1;
    #5 $finish;
  end
endmodule

在这里,我希望使用程序方法检测三个或更多。我知道我可以直接使用状态图和更新状态来实现它,但我想将它实现为硬件实现。 提前致谢!

解决方法

是的,你有几个问题:-)

  1. module tff 在 always 块内实例化(实例 tatb)。在 verilog 中这是非法的。您需要将实例移到外面。
  2. 您非法将端口 q1q2 定义为输入,同时将其定义为输出。它们应该只是输出
  3. 您在时间刻度之前使用了错误的字符。它应该是反引号'`'。时间尺度语法中没有 = 的位置。
  4. 你在声明模块后忘记了分号testbench
  5. $display 和其他中的 $ 后有空格。 $ 是名称的一部分。
  6. 你的 forever 必须在 initial 块内,你把它放在外面。
  7. 您在测试平台模块定义中列出了端口,但没有指定它们的方向。我认为您根本不需要任何端口。
  8. 没有像您在 $dumpvars 中使用的 test_bench 这样的想法。有测试平台(无下划线)。
  9. 在您的情况下,q1q2aways 块和模块实例驱动多次。由于您也在 tff 模块中初始化它们,因此您不需要在 seriesof3 中初始化它们。
  10. forever 语句之后有一些代码。这段代码永远不会执行。您需要另一个initial 块,我建议为forever 语句使用一个单独的块。此外,您还需要初始化您的 clk 信号,否则它将保持在“x”。
  11. 您不应该在初始块中使用非阻塞赋值,除非您完全理解为什么需要它们。

这是一个语法固定的代码:

module tff (q,t,clk,clear);
  input t,clear;
  output reg q;
  always @(negedge clk or posedge clear)
  begin
    if (clear) q <= 0;
    else if(t==1) q <= ~q;
    else q<= q;
  end
endmodule

module seriesof3 (y,q1,q2,a,clear);
  input a,clear;
  output reg y,q2;
  always @(negedge clk or posedge clear)
  begin
    if (clear) begin
        //q1 <= 0;
        //q2 <= 0;
     end
    else begin
        y <= a&q2;
     end
  end
  tff ta (q1,clear);
  tff tb (q2,~q1&(q2^a),clear);

endmodule


`timescale  1 ms/1 ms
module testbench(); //(y,clear);
  reg a,clear;
  wire y,q2;
  seriesof3 DUT (y,clear);
  initial
    begin 
        $dumpvars(0,testbench);
        $dumpfile("first.vcd");
        $monitor ($time,"a=%b,Y= %b",y);
        clear=0;
        a=0;
        #2 clear=1;
        #5 clear=0;
 
          #8 a=0;
          #5 a=1;
          #5 a=1;
          #5 a=1;
          #5 a=1;
          #5 a=0;
          #5 a=1;
          #5 a=1;
          #5 a=0;
          #5 a=1;
          #5 a=1;
          #5 $finish;
        end

    initial begin
        clk = 0;
        forever #5 clk= ~clk;
    end
  
   
endmodule