Search code examples
verilogmodelsim

Tell me what's wrong with this code


This code describes this expression -> (a+b)(c+d). I used 2 summators, to first sum a and b, and then c and d. And then another one to multiply results. Unfortunately, I'm really bad at Verilog, so I'm unable to understand what's wrong.

  module automate(a,b,c,d,clk,start,result,ready);
  parameter n=8;
  input [7:0] a,b,c,d;
  input start,clk;
  output reg[17:0] result;
  output reg ready;
  reg[7:0] ra;
  reg[7:0] rb;
  reg[7:0] rc;
  reg[7:0] rd;
  reg[8:0] sm1;
  reg[8:0] sm2;
  reg[8:0] acc,q;

  always@(posedge start)
  begin
    ra=a;
    rb=b;
    rc=c;
    rd=d;

    sm1=ra+rb;
    sm2=rc+rd;

    q=sm2;
    acc=0;
    ready=0;

    repeat(9)
    begin
      @(posedge clk)
      if(q[0])
        acc=acc+sm1;
      else
        acc=acc;
      q=q>>1;
      q[8] = acc[0];
      acc=acc>>1;
    end

    ready=1;
    result={acc[8:0],q};
  end

endmodule

Testbench :

module test_bench;
reg[7:0] a,b,c,d;
reg clk,start;
wire ready;
wire[17:0] result;

automate res(a,b,c,d,clk,start,result,ready);
initial begin
  start = 0;
  clk=0;

  a=8'd7;
  b=8'd5;
  c=8'd9;
  d=8'd3;

  #30 start = 1;
  wait(ready);
  #20 start = 0;

  #500 $finish;
end

always #10 clk=~clk;

endmodule  

but here's what I get:


Solution

  • Your code is working fine as per @Matthew Taylor!!,

    Simulation is might not be of TB, as it is top module, nothing is driven to DUT so your signals are X and Z.

     .....
     automate res(a,b,c,d,clk,start,result,ready);
     initial begin
       $monitor (result, res.sm1, res.sm2); // added monitor system task
       start = 0;
     .....
    

    And just run it, you will see then output as below,

    #      x  x  x
    #      x 12 12
    #    144 12 12
    

    Even though, I would like to say, you are writing HDL code, a real Hardware so don't use repeat, use for loop.

    And if your requirement is just (A+B) / (C+D) then there is no use of clock.

    For addition,

      always@(*)
      begin
        ra = 0;
        rb = 0;
        rc = 0;
        sm1 = 0;
        sm2 = 0;
        result = 0;
    
        if(start) begin
          ra = a;
          rb = b;
          rc = c;
          rd = d;
    
          sm1 = ra + rb;
          sm2 = rc + rd;
    
          result = product(sm1, sm2);
        end
      end
    

    For function product which will multiply sm1 and sm2 can be,

      function [17:0] product;
        input [8:0]  multiplier, multiplicand;
    
        integer i;
    
        begin
          product = 0;
          for(i=0; i<17; i=i+1)
            if( multiplier[i] == 1'b1 )
              product = product + ( multiplicand << i );
         end
       endfunction
    

    So I think start and ready would be asserted on same cycle. No sequential logic is there in your code, as of now.

    Hope this will help you.

    Edit:

    for your second problem, use following transcript commands:

    vsim -novopt -c -do "add wave -r /*; run -all;" work.test_bench
    
    add wave -r /*
    
    run -all