//The code uses the OOPs based layered techniq for architecting the testbench.The result generated by the DUT are passed to the acoreboard through monitor. But the result generated by the reference model differs due to synchronization. Whats the issue?
Any suggestion will be appreciated.
//code link : fullcode link
//================ design ===============//
module adder(a,b,c);
input [3:0] a,b;
output [4:0] c;
assign c=a+b;
endmodule
interface intr;
logic [3:0] a,b;
logic [4:0] c;
endinterface
//=============== test =================//
class transaction;
rand logic [3:0] a,b;
logic [4:0] c;
constraint c_a {a inside {[10:15]};}
constraint c_b {b inside {[0:9]};}
function dis(string name);
$display("----------%0s----------",name);
endfunction
endclass
class generator;
int test_vector;
mailbox gen2drive;
mailbox gen2scr;
transaction txn=new();
function new(mailbox gen2drive,mailbox gen2scr);
this.gen2drive=gen2drive;
this.gen2scr=gen2scr;
endfunction
task run(int test_vector);
for(int i=0;i<test_vector;i++)begin
if(!txn.randomize())
$display("transaction is not done");
else begin
gen2drive.put(txn);
gen2scr.put(txn);
txn.dis("[ Packet send ]");
end
#2;
end
endtask
endclass
class driver;
mailbox gen2drive;
virtual intr v_intr;
transaction trans;
int test_vector;
function new(virtual intr v_intr,mailbox gen2drive);
this.v_intr=v_intr;
this.gen2drive=gen2drive;
trans=new();
endfunction
task run(int test_vector);
for(int i=0;i<test_vector;i++)begin
gen2drive.get(trans);
v_intr.a=trans.a;
v_intr.b=trans.b;
#2;
trans.c=v_intr.c;
trans.dis("[ Packet received ]");
$display("%g a=%0d b=%0d sum=%0d",$time,v_intr.a,v_intr.b,v_intr.c);
end
endtask
endclass
class monitor;
virtual intr v_intr;
mailbox mon2scr;
function new(virtual intr v_intr,mailbox mon2scr);
this.v_intr=v_intr;
this.mon2scr=mon2scr;
endfunction
task run(int test_vector);
logic [4:0] c;
for(int i=0;i<test_vector;i++)begin
c=v_intr.c;
mon2scr.put(c);
#2;
end
endtask
endclass
class agent;//it contain monitor,generator,driver
mailbox mon2scr;
mailbox gen2scr;
mailbox gen2drive;
virtual intr v_intr;
generator gen;
driver drive;
monitor mon;
function new(virtual intr v_intr,mailbox gen2scr,mailbox mon2scr);
this.mon2scr=mon2scr;
this.gen2scr=gen2scr;
gen2drive=new();//no upper level access
drive=new(v_intr,gen2drive);
mon=new(v_intr,mon2scr);
gen=new(gen2drive,gen2scr);
endfunction
task run(int test_vector);
fork
gen.run(test_vector);
drive.run(test_vector);
mon.run(test_vector);
join
endtask
endclass
class score_board;
mailbox mon2scr;
mailbox gen2scr;
generator gen;
transaction txn;
function new(mailbox gen2scr,mailbox mon2scr);
this.mon2scr=mon2scr;
this.gen2scr=gen2scr;
txn=new();
endfunction
task check(int test_vector);
logic [4:0] exp_sum;
logic [4:0] calculated_sum;
for(int i=0;i<test_vector;i++)begin
gen2scr.get(txn);
mon2scr.get(calculated_sum);
exp_sum=txn.a+txn.b;
$display("calculated_sum=%0d,exp_sum=%0d",calculated_sum,exp_sum);
if(exp_sum==calculated_sum)
$display("PASS");
else
$display("FAIL");
#2;
end
endtask
endclass
class environment;
mailbox gen2scr;
mailbox mon2scr;
virtual intr v_intr;
agent age;
score_board scr;
function new(virtual intr v_intr);
gen2scr=new();
mon2scr=new();
this.v_intr=v_intr;
age=new(v_intr,gen2scr,mon2scr);
scr=new(gen2scr,mon2scr);
endfunction
task run(int test_vector);
fork
age.run(test_vector);
scr.check(test_vector);
join
endtask
endclass
program test(intr i_intr,int test_vector);
environment env;
initial begin
env=new(i_intr);
env.run(test_vector);
end
endprogram
module tb();
intr i_intr();
test ts(i_intr,5);
adder dut(.a(i_intr.a),.b(i_intr.b),.c(i_intr.c));
endmodule