Sequence of 3 or more ones: Verilog debugging

125 Views Asked by At

I'm new to Verilog coding and stuck with an error in my code. Can someone help to debug it?

Main code:

module tff (q,t,clk,clear);
  input t,clk,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,clk,clear);
  input a,clk,clear,q1,q2;
  output reg y,q1,q2;
  always @(negedge clk or posedge clear)
  begin
    if (clear) begin
        q1 <= 0;
        q2 <= 0;
     end
    else begin
        tff ta (q1,a,clk,clear);
        tff tb (q2,~q1&(q2^a),clk,clear);
        y <= a&q2;
     end
  end
endmodule

testbench code:

'timescale = 1 ms/1 ms
module testbench(y,a,clk,clear)
  reg a,clk,clear;
  wire y,q1,q2;
  seriesof3 DUT (y,q1,q2,a,clk,clear);
  initial
    begin 
        $ dumpvars(0,test_bench);
        $ dumpfile("first.vcd");
        $ monitor ($time,"a=%b, Y= %b",a,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

Here I'm looking to detect three or more one's using the procedural method. I know I could have implemented it directly using the state diagram and updating states but I want to implement it as hardware implementation. Thanks in advance!

1

There are 1 best solutions below

1
On

Yes, you have several issues :-)

  1. module tff is instantiated inside of the always block (instances ta and tb). It is illegal in verilog. You need to move the instantiations outside.
  2. you illegaly define ports q1 and q2 as input and simultaneously as output. They should be only outputs.
  3. you use incorrect character before timescale. It should be the backtick ' ` '. There is no place for = in time scale syntax.
  4. you forgot semicolon after declaration of moduel testbench
  5. you have spaces after $ in $display and others. $ is a part of the name.
  6. your forever must be inside the initial block, you put it outside.
  7. you listed ports in your testbench module definition but did not specify their directions. I think that you do not need any port there at all.
  8. there is no such thinkg as test_bench which you used in $dumpvars. There is the testbench (no underscore).
  9. in your case q1 and q2 are driven multiple times by the aways block and the module instance. Since you also initialize them inside the tff module, you don not need to initialize them in seriesof3.
  10. you have some code after the forever statement. This code will never execute. You need another initial block, I suggest a separate block for the forever statement. Also, you need to initialize your clk signal as well or it will stay at 'x'.
  11. you should not use nonblocking assignments in initial blocks, unless you fully understand why you need them.

Here is a syntactically fixed code:

module tff (q,t,clk,clear);
  input t,clk,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,clk,clear);
  input a,clk,clear;
  output reg y,q1,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,a,clk,clear);
  tff tb (q2,~q1&(q2^a),clk,clear);

endmodule


`timescale  1 ms/1 ms
module testbench(); //(y,a,clk,clear);
  reg a,clk,clear;
  wire y,q1,q2;
  seriesof3 DUT (y,q1,q2,a,clk,clear);
  initial
    begin 
        $dumpvars(0,testbench);
        $dumpfile("first.vcd");
        $monitor ($time,"a=%b, Y= %b",a,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