Reputation: 1
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
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:
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