Sei sulla pagina 1di 9

INTERFACE

`timescale 1ns/1ps
interface cordic_if(input bit clk,rst);
logic [11:0] sin,cos,angle;
modport TEST(input sin,cos,clk,rst,output angle);
modport DUT(input angle,clk,rst,output sin,cos);
endinterface
TEST BENCH
`timescale 1ns/1ps
module top;
`include"ovm.svh"
import Pack_classes::*;
reg clk=0,rst=0;
cordic_if corif(clk,rst);
cordictop c1(corif); //TOP LEVEL DUT
//cordictest c2(corif);
class Cordic_test extends ovm_test;
Cordic_env Cordic_env_o;
function new(string name, ovm_component parent = null);
super.new(name, parent);
endfunction
function void build();
Cordic_env_o = new("Cordic_env");
endfunction
function void connect();
Cordic_env_o.Cordic_driver_o.corif = corif.TEST;
Cordic_env_o.Cordic_monitor_o.corif = corif.TEST;
endfunction
endclass : Cordic_test
Cordic_test Cordic_test_o;
initial begin
$recordfile("cordicfileovm");
$recordvars();
Cordic_test_o = new("Cordic_test");
set_global_timeout(2500us);
run_test();
end
initial begin
#1 rst=1;
#30000 $finish;

end
initial
begin
clk=0;
forever
#1 clk=~clk;
end
endmodule

PACKAGE
//=========================================
//
//
Cordic Package
//
//==========================================
`timescale 1ns/1ps
package Pack_classes;
`define PI 3.14159265
`include "ovm.svh"
real angle_in_degrees=0;
int num_err=0;
event trans_start,trans_end;
import "DPI" function real c_sin(real x);
import "DPI" function real c_cos(real x);
//=========================================
//
//
Transaction class
//
//=========================================
class Transaction extends ovm_sequence_item;
rand bit [11:0] angle_rand;
endclass
class Exp_tran extends ovm_transaction;
real exp_data_sin[$];
real exp_data_cos[$];
function new();
exp_data_sin.delete();
exp_data_cos.delete();
endfunction
endclass
class Act_tran extends ovm_transaction;
real act_data_sin[$];
real act_data_cos[$];
function new();

act_data_sin.delete();
act_data_cos.delete();
endfunction
endclass
//========================================
//
//
Cordic Sequencer
//
//========================================
class Cordic_sequencer extends ovm_sequencer#(Transaction); //not
required??
`ovm_sequencer_utils(Cordic_sequencer)
function new(string name, ovm_component parent);
super.new(name, parent);
endfunction
endclass
//=======================================
//
//
Cordic Sequence
//
//=======================================
class Cordic_sequence extends ovm_sequence;
`ovm_sequence_utils(Cordic_sequence, Cordic_sequencer)
Transaction req;
Exp_tran Exp_tran_o;
function new(string name="Cordic_sequence");
super.new(name);
endfunction
task body();
real sin_from_c,cos_from_c;
//real angle_degrees=0;
req = new();
Exp_tran_o = new();
repeat(4095) begin
wait_for_grant();
req.randomize;
angle_in_degrees = $signed(req.angle_rand)*180.0/4096.0;
//angle_in_degrees = angle_degrees;
// Calculate the expected value of sin and cos from c function
sin_from_c = c_sin(angle_in_degrees*(`PI/180.0));
Exp_tran_o.exp_data_sin.push_back(sin_from_c);
cos_from_c = c_cos(angle_in_degrees*(`PI/180.0));
Exp_tran_o.exp_data_cos.push_back(cos_from_c);
//Send the angle to driver
send_request(req);
wait_for_item_done();

end
endtask
endclass
/*class Cordic_seq_no_constrain extends Cordic_sequence;
`ovm_sequence_utils(Cordic_seq_no_constrain, Cordic_sequencer)
Transaction req;
function new(string name="Cordic_seq_no_contrain");
super.new(name);
endfunction
task body();
real sin_from_c,cos_from_c;
//real angle_degrees=0;
req = new();
repeat(4095) begin
wait_for_grant();
req.randomize;
angle_in_degrees = $signed(req.angle_rand)*180.0/4096.0;
//angle_in_degrees = angle_degrees;
// Calculate the expected value of sin and cos from c function
sin_from_c = c_sin(angle_in_degrees*(`PI/180.0));
req.exp_data_sin.push_back(sin_from_c);
cos_from_c = c_cos(angle_in_degrees*(`PI/180.0));
req.exp_data_cos.push_back(cos_from_c);
//Send the angle to driver
send_request(req);
wait_for_item_done();
end
endtask:body
endclass : Cordic_seq_no_constrain*/
/*class Cordic_seq_with_constraint extends Cordic_sequence;
`ovm_sequence_utils(Cordic_seq_with_constraint, Cordic_sequencer)
Transaction req;
function new(string name="Cordic_seq_with_contraint");
super.new(name);
endfunction
task body();
real sin_from_c,cos_from_c;
//real angle_degrees=0;
req = new();
constraint c{ req.angle_rand<=12'b0111111111111;req.angle_rand>=0; }
repeat(4095) begin

wait_for_grant();
req.randomize;
angle_in_degrees = $signed(req.angle_rand*180.0/4096);
//angle_in_degrees = angle_in_degrees;
// Calculate the expected value of sin and cos from c function
sin_from_c = c_sin(angle_in_degrees*(`PI/180.0));
req.exp_data_sin.push_back(sin_from_c);
cos_from_c = c_cos(angle_in_degrees*(`PI/180.0));
req.exp_data_cos.push_back(cos_from_c);
//Send the angle to driver
send_request(req);
wait_for_item_done();
end
endtask
endclass : Cordic_seq_with_constraint*/
//===========================================================
//
//
Cordic Driver
//
//===========================================================
class Cordic_driver extends ovm_driver #(Transaction);
`ovm_component_utils(Cordic_driver)
Transaction req;
virtual cordic_if.TEST corif;
ovm_seq_item_pull_port #(Transaction) seq_pull_port;
function new(string name, ovm_component parent);
super.new(name, parent);
endfunction
virtual function void build();
seq_pull_port = new("seq_pull_port", this);
endfunction
task run();
req=new();
seq_pull_port.get_next_item(req);
repeat(4095) begin
repeat(20) @(posedge corif.clk);
corif.angle = req.angle_rand;
->trans_start;
wait(trans_end.triggered);
seq_item_port.item_done();
end
endtask
endclass

//============================================================
//
//
Monitor
//
//============================================================
class Cordic_monitor extends ovm_component;
`ovm_component_utils(Cordic_monitor)
function new(string name, ovm_component parent);
super.new(name, parent);
endfunction
Act_tran actual;
virtual cordic_if.TEST corif;
task run();
forever begin
wait(trans_start.triggered);
actual =new();
repeat(13) @(posedge corif.clk);
actual.act_data_sin.push_back($signed(corif.sin)/2048.0);
actual.act_data_cos.push_back($signed(corif.cos)/2048.0);
->trans_end;
end
endtask
endclass
//==============================================================
//
//
Scoreboard
//
//==============================================================
class Cordic_sb extends ovm_component;
`ovm_component_utils(Cordic_sb)
real sin_err, abs_sin_err, cos_err,abs_cos_err;
Act_tran actual;
Exp_tran expected;
function new(string name, ovm_component parent);
super.new(name, parent);
endfunction
task run();
actual=new();
expected = new();
wait(trans_end.triggered);
foreach(expected.exp_data_sin[i]) begin
sin_err = expected.exp_data_sin[i] - actual.act_data_sin[i];
cos_err = expected.exp_data_cos[i] - actual.act_data_cos[i];
abs_sin_err = (sin_err < 0.0) ? -1.0 * sin_err : sin_err;

abs_cos_err = (cos_err < 0.0) ? -1.0 * cos_err : cos_err;


if((abs_sin_err > 0.01) | (abs_cos_err > 0.01)) begin
ovm_report_error("SB", $psprintf("Angle_degrees = %f, Sine= %f
Cosine = %f sin_err = %f cos_err =
%f\n",angle_in_degrees,actual.act_data_sin[i],
actual.act_data_cos[i],abs_sin_err, abs_cos_err),OVM_MEDIUM);
num_err = num_err +1;
end
else
ovm_report_info("SB", $psprintf("Angle_degrees = %f, Sine= %f
Cosine = %f sin_err = %f cos_err =
%f\n",angle_in_degrees,actual.act_data_sin[i],
actual.act_data_cos[i],abs_sin_err, abs_cos_err),OVM_MEDIUM);
end:foreach_loop
endtask
endclass
//===============================================================
//
//
Environment
//
//===============================================================
class Cordic_env extends ovm_env;
`ovm_component_utils(Cordic_env)
Cordic_sequence Cordic_sequence_o;
Cordic_sequencer
Cordic_driver
Cordic_monitor
Cordic_sb

Cordic_sequencer_o;
Cordic_driver_o;
Cordic_monitor_o;
Cordic_sb_o;

function new(string name, ovm_component parent = null);


super.new(name, parent);
endfunction
virtual function void build();
Cordic_sequencer_o =
Cordic_sequencer::type_id::create("Cordic_sequencer_o",this);
Cordic_driver_o =
Cordic_driver::type_id::create("Cordic_driver_o", this);
Cordic_monitor_o =
Cordic_monitor::type_id::create("Cordic_monitor_o", this);
Cordic_sb_o = Cordic_sb::type_id::create("Cordic_sb_c", this);
//set_type_override("Cordic_sequence",
"Cordic_seq_no_constrain");
endfunction

virtual function void connect();


Cordic_driver_o.seq_pull_port.connect(Cordic_sequencer_o.seq_item_export);
endfunction
task run();
string str;
Cordic_sequence_o =
Cordic_sequence::type_id::create("Cordic_sequence_o", this);
Cordic_sequence_o.start(Cordic_sequencer_o);
if(num_err != 0)
str = $psprintf("Test failed! : Errors = %6d", num_err);
else str = $psprintf("Test case passed!");
ovm_report_info("Result", str, OVM_LOW);
global_stop_request();
endtask
endclass : Cordic_env
endpackage : Cordic_pkg

DUT
`timescale 1ns/1ps
module cordictop(cordic_if.DUT corif);//angle, clk, rst, sin, cos);
//input [11:0] angle;
//input clk,rst;
///output [11:0] sin,cos;
//wire [11:0] sin,cos;
wire [11:0]
alpha0,alpha1,alpha2,alpha3,alpha4,alpha5,alpha6,alpha7,alpha8,alpha9,alph
a10,alpha11;
wire [11:0]
X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8,Y9,Y1
0,Y11,Y12;
wire [11:0] Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9,Z10,Z11,Z12;
assign
assign
assign
assign
assign
assign

X0 = 12'b010011011011;
Y0 = 0;
alpha0 = 12'b010000000000;
alpha1 = 12'b001001011101;
alpha2 = 12'b000100111111;
alpha3 = 12'b000010100010;

assign
assign
assign
assign
assign
assign
assign
assign

alpha4 = 12'b000001010001;
alpha5 = 12'b000000101001;
alpha6 = 12'b000000010100;
alpha7 = 12'b000000001010;
alpha8 = 12'b000000000101;
alpha9 = 12'b000000000010;
alpha10 = 12'b000000000001;
alpha11 = 12'b0000000000001;

cordic_iter #(1)
s1(.Xi(X0),.Yi(Y0),.Zi(corif.angle),.alpha(alpha0),.clk(corif.clk),.rst(co
rif.rst),.Xip1(X1),.Yip1(Y1),.Zip1(Z1));
cordic_iter #(2)
s2(.Xi(X1),.Yi(Y1),.Zi(Z1),.alpha(alpha1),.clk(corif.clk),.rst(corif.rst),
.Xip1(X2),.Yip1(Y2),.Zip1(Z2));
cordic_iter #(3)
s3(.Xi(X2),.Yi(Y2),.Zi(Z2),.alpha(alpha2),.clk(corif.clk),.rst(corif.rst),
.Xip1(X3),.Yip1(Y3),.Zip1(Z3));
cordic_iter #(4)
s4(.Xi(X3),.Yi(Y3),.Zi(Z3),.alpha(alpha3),.clk(corif.clk),.rst(corif.rst),
.Xip1(X4),.Yip1(Y4),.Zip1(Z4));
cordic_iter #(5)
s5(.Xi(X4),.Yi(Y4),.Zi(Z4),.alpha(alpha4),.clk(corif.clk),.rst(corif.rst),
.Xip1(X5),.Yip1(Y5),.Zip1(Z5));
cordic_iter #(6)SO ON

Potrebbero piacerti anche