Rocky_s
Rocky_s

Reputation: 1

Unable to find bug in Simulator, because $display & Wave window of simulator Show Different Result?

I am try to design a BIST (Built in Self Test System) For Multiplier. I created a Multiplier which is working fine and now I try to compare its result(Multiplier's output) with the correct result of(ORA's output). I am simulating with the Modelsim's Simulator. I don't understand why the waveform is showing different results than from the $display task. ....... I am blank now and not know what to do .........help me

Here is my code (Top level module)----

module top(input wire clk,input wire sw1,input wire sw2,input wire sw3,input wire start,output reg[7:0 ]out,output reg rs,output reg rw,output reg en);  

//Slow Clock Instance
wire sclk;
sender send1(clk,sclk);     

//Releated to Braun Multiplier
reg [3:0]a=4'b0000;
reg [3:0]b=4'b0000;
wire [7:0]outb;
reg[7:0]hold;//Used for Holding Output/Return of Function
braun sd(.x(a),.y(b),.out(outb));

integer state5=0;  //State for start checking

//Integer for Array for a & b
integer s=0;

reg cnt=1'b0;

always @(posedge sclk)
begin
  //Fault Checking Condition
  if( (start==1'b0) & (sw3==1'b0) & (cnt==1'b0) )
  begin:close
    case(state5)
    0:begin
      a=4'b0100;
      s=s+1;
      b=b + 1'b1;
      hold=ora(a,b);
      $display("hold=%b",hold);
      $display("outb=%b",outb);

      if(s!=15)
      begin
        if(outb==hold)
        begin
          state5=0;
        end
        else if(outb!=hold)
        begin
          cnt=1'b1;
          disable close;
        end
      end
      else if(s==15)
      begin
        if(outb==hold)
        begin
          s=0;
          state5=1;
        end
        else if(outb!=hold)
        begin
          cnt=1'b1;
          disable close;
        end
      end
    end

    1:begin
      a=4'b0001;
      s=s+1;
      b=b+ 1'b1;
      hold=ora(a,b);
      $display("hold=%b",hold);
      $display("outb=%b",outb);

      if(s!=15)
       begin
        if(outb==hold)
          begin
          state5=1; 
        end
        else if(outb!=hold)
        begin
          cnt=1'b1;
          disable close;
        end
      end
      else if(s==15 )
      begin
        if(outb==hold)
        begin
          s=0;
          state5=2;
        end
        else if(outb!=hold)
        begin
          cnt=1'b1;
          disable close;
        end
      end  
    end             

    2:begin
      a=4'b0010;
      s=s+1;
      b=b+ 1'b1;
      hold=ora(a,b);
      $display("hold=%b",hold);
      $display("outb=%b",outb);

      if(s!=15)
      begin
        if(outb==hold)
        begin
          state5=2;
        end
        else if(outb!=hold)
        begin
          cnt=1'b1;
          disable close;
        end
      end
      else if(s==15 )
      begin
        if(outb==hold)
        begin
          s=0;
          state5=3;
        end
        else if(outb!=hold)
        begin
          cnt=1'b1;
          disable close;
        end
      end
    end
    endcase
  end //if end
end//always end

//Function For ORA Checking Purpose......         
function  [7:0]ora (input reg [3:0]X,input reg [3:0]Y);
  begin 
    $display("X=%b & Y=%b",X,Y);
    //Positive-Positive Operations
    ora=X * Y;
  end
endfunction

endmodule

and here is my another file of Counter(i named it sender.v) file-

`timescale 1ns / 1ps

module sender(input wire clkin, output reg clkout);
 reg [2:0]tmp=3'b000;

//Delay Generation////////

always@(posedge clkin)
 begin 
  tmp <= tmp+1'b1;
  clkout<=tmp[2];
 end
endmodule

and the file of Multiplier(Braun Multiplier) is here-

module braun(x,y,out);
input wire [3:0]x;
input wire [3:0]y; //Input/Output Port Declarations
output [7:0]out;
wire [5:0]a;
wire [8:0]b;
wire [5:0]sa;
wire [1:0]cc;
//If we place 1'b0 in place of "zero"then this was not work so we use this...
wire k[8:0];

//There are 16 And Gates used here....
and a1(out[0],x[0],y[0]);
and a2(a[0],x[1],y[0]);
and a3(a[1],x[2],y[0]);
and a4(a[2],x[3],y[0]); 
and a5(b[0],x[0],y[1]);
and a6(b[1],x[1],y[1]);
and a7(b[2],x[2],y[1]);
and a8(a[3],x[3],y[1]);
and a9(b[3],x[0],y[2]);
and a10(b[4],x[1],y[2]);
and a11(b[5],x[2],y[2]);
and a12(a[4],x[3],y[2]);
and a13(b[6],x[0],y[3]);
and a14(b[7],x[1],y[3]);
and a15(b[8],x[2],y[3]);
and a16(a[5],x[3],y[3]);

//There are 12 Full Adder used here....
full_adder f1(out[1],k[0],a[0],b[0],1'b0);
full_adder f2(sa[0],k[1],a[1],b[1],1'b0);
full_adder f3(sa[1],k[2],a[2],b[2],1'b0);
full_adder f4(out[2],k[3],sa[0],b[3],k[0]);
full_adder f5(sa[2],k[4],sa[1],b[4],k[1]);
full_adder f6(sa[3],k[5],a[3],b[5],k[2]);
full_adder f7(out[3],k[6],sa[2],b[6],k[3]);
full_adder f8(sa[4],k[7],sa[3],b[7],k[4]);
full_adder f9(sa[5],k[8],a[4],b[8],k[5]);
full_adder f10(out[4],cc[0],sa[4],k[6],1'b0);
full_adder f11(out[5],cc[1],sa[5],k[7],cc[0]);
full_adder f12(out[6],out[7],a[5],k[8],cc[1]);

endmodule

module full_adder(output reg sum,output reg carry,input wire a,input wire b,input wire c);

always@(a,b,c)
begin
  case({a,b,c})
    3'b000:begin
             sum=1'b0;
             carry=1'b0;
           end
    3'b001:begin
             sum=1'b1;
             carry=1'b0;
           end
    3'b010:begin
             sum=1'b1;
             carry=1'b0;
           end
    3'b011:begin
             sum=1'b0;
             carry=1'b1;
           end
    3'b100:begin
             sum=1'b1;
             carry=1'b0;
           end
    3'b110:begin
             sum=1'b0;
             carry=1'b1;
           end
    3'b111:begin
             sum=1'b1;
             carry=1'b1;
            end
    3'b101:begin
             sum=1'b0;
             carry=1'b1;
           end
  endcase
end

endmodule

Because I don't have 10 reputation I am unable to post image please check this in your Modelsim...

and the ouput of Transcript window is here which show different result is here-

# X=0100 & Y=0001
# hold=00000100
# outb=00000000

Upvotes: 0

Views: 500

Answers (1)

Chiggs
Chiggs

Reputation: 2864

The waveform is showing the values at end of each timestep. Your call to $display will execute in the active events region of the scheduler timestep where the following can occur in any order:

  • Execute all module blocking assignments.
  • Evaluate the Right-Hand-Side (RHS) of all nonblocking assignments and schedule updates into the NBA region.
  • Execute all module continuous assignments
  • Evaluate inputs and update outputs of Verilog primitives.
  • Execute the $display and $finish commands.

You are probably seeing different results due to the unknown order that these events are scheduled. The waveform will show what happened after all these events have run. More information from testbench.in:

According to scheduling semantics of verilog, $display executes before the nonblocking statements update LHS. Therefore if $display contains LHS variable of nonblocking assignment, the results are not proper. The $strobe command shows updated values at the end of the time step after all other commands, including nonblocking assignments, have completed.

I'd suggest it's worth writing a separate self-checking testbench rather than relying on $display calls to check your functionality. Note also that you can share code examples (with waveforms) on EDA Playground.

Upvotes: 3

Related Questions