This commit is contained in:
2026-06-12 07:53:32 +02:00
commit 59e71f3297
259 changed files with 29010 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
`ifndef CALC_AGENT_PKG
`define CALC_AGENT_PKG
package calc_agent_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
//////////////////////////////////////////////////////////
// include Agent components : driver,monitor,sequencer
/////////////////////////////////////////////////////////
`include "calc_seq_item.sv"
`include "calc_sequencer.sv"
`include "calc_monitor.sv"
`include "calc_driver.sv"
endpackage
`endif

View File

@@ -0,0 +1,41 @@
`ifndef CALC_DRIVER_SV
`define CALC_DRIVER_SV
class calc_driver extends uvm_driver#(calc_seq_item);
`uvm_component_utils(calc_driver)
virtual interface calc_if vif;
function new(string name = "calc_driver", uvm_component parent = null);
super.new(name,parent);
endfunction // new
function void build_phase(uvm_phase phase);
if (!uvm_config_db#(virtual calc_if)::get(null, "*", "calc_if", vif))
`uvm_fatal("NOVIF",{"virtual interface must be set:",get_full_name(),".vif"})
endfunction // build_phase
task main_phase(uvm_phase phase);
forever begin
@(posedge vif.clk);
if (!vif.rst)
begin
seq_item_port.get_next_item(req);
`uvm_info(get_type_name(),
$sformatf("Driver sending...\n%s", req.sprint()),
UVM_HIGH)
vif.req1_data_in = req.operand1;
vif.req1_cmd_in = req.cmd;
@(posedge vif.clk);
vif.req1_data_in = req.operand2;
vif.req1_cmd_in = 0;
seq_item_port.item_done();
end
end
endtask : main_phase
endclass : calc_driver
`endif

View File

@@ -0,0 +1,44 @@
class calc_monitor extends uvm_monitor;
// control fileds
bit checks_enable = 1;
bit coverage_enable = 1;
uvm_analysis_port #(calc_seq_item) item_collected_port;
`uvm_component_utils_begin(calc_monitor)
`uvm_field_int(checks_enable, UVM_DEFAULT)
`uvm_field_int(coverage_enable, UVM_DEFAULT)
`uvm_component_utils_end
// The virtual interface used to drive and view HDL signals.
virtual interface calc_if vif;
// current transaction
calc_seq_item curr_it;
// coverage can go here
// ...
function new(string name = "calc_monitor", uvm_component parent = null);
super.new(name,parent);
if (!uvm_config_db#(virtual calc_if)::get(null, "*", "calc_if", vif))
`uvm_fatal("NOVIF",{"virtual interface must be set:",get_full_name(),".vif"})
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
endfunction : connect_phase
task main_phase(uvm_phase phase);
// forever begin
// curr_it = calc_seq_item::type_id::create("curr_it", this);
// ...
// collect transactions
// ...
// item_collected_port.write(curr_it);
// end
endtask : main_phase
endclass : calc_monitor

View File

@@ -0,0 +1,20 @@
`ifndef CALC_SEQ_ITEM_SV
`define CALC_SEQ_ITEM_SV
class calc_seq_item extends uvm_sequence_item;
rand logic [31:0] operand1;
rand logic [31:0] operand2;
rand logic [3:0] cmd;
`uvm_object_utils_begin(calc_seq_item)
`uvm_object_utils_end
function new (string name = "calc_seq_item");
super.new(name);
endfunction // new
endclass : calc_seq_item
`endif

View File

@@ -0,0 +1,15 @@
`ifndef CALC_SEQUENCER_SV
`define CALC_SEQUENCER_SV
class calc_sequencer extends uvm_sequencer#(calc_seq_item);
`uvm_component_utils(calc_sequencer)
function new(string name = "calc_sequencer", uvm_component parent = null);
super.new(name,parent);
endfunction
endclass : calc_sequencer
`endif

View File

@@ -0,0 +1,30 @@
`ifndef CALC_BASE_SEQ_SV
`define CALC_BASE_SEQ_SV
class calc_base_seq extends uvm_sequence#(calc_seq_item);
`uvm_object_utils(calc_base_seq)
`uvm_declare_p_sequencer(calc_sequencer)
function new(string name = "calc_base_seq");
super.new(name);
endfunction
// objections are raised in pre_body
virtual task pre_body();
uvm_phase phase = get_starting_phase();
if (phase != null)
phase.raise_objection(this, {"Running sequence '", get_full_name(), "'"});
uvm_test_done.set_drain_time(this, 200ms);
endtask : pre_body
// objections are dropped in post_body
virtual task post_body();
uvm_phase phase = get_starting_phase();
if (phase != null)
phase.drop_objection(this, {"Completed sequence '", get_full_name(), "'"});
endtask : post_body
endclass : calc_base_seq
`endif

View File

@@ -0,0 +1,11 @@
`ifndef CALC_SEQ_PKG_SV
`define CALC_SEQ_PKG_SV
package calc_seq_pkg;
import uvm_pkg::*; // import the UVM library
`include "uvm_macros.svh" // Include the UVM macros
import calc_agent_pkg::calc_seq_item;
import calc_agent_pkg::calc_sequencer;
`include "calc_base_seq.sv"
`include "calc_simple_seq.sv"
endpackage
`endif

View File

@@ -0,0 +1,29 @@
`ifndef CALC_SIMPLE_SEQ_SV
`define CALC_SIMPLE_SEQ_SV
class calc_simple_seq extends calc_base_seq;
`uvm_object_utils (calc_simple_seq)
function new(string name = "calc_simple_seq");
super.new(name);
endfunction
virtual task body();
// simple example - just send one item
calc_seq_item calc_it;
// prvi korak kreiranje transakcije
calc_it = calc_seq_item::type_id::create("calc_it");
// drugi korak start
start_item(calc_it);
// treci korak priprema
// po potrebi moguce prosiriti sa npr. inline ogranicenjima
assert (calc_it.randomize() with {calc_it.cmd==1; calc_it.operand1==3;});
// cetvrti korak finish
finish_item(calc_it);
endtask : body
endclass : calc_simple_seq
`endif

View File

@@ -0,0 +1,29 @@
`ifndef CALC_IF_SV
`define CALC_IF_SV
interface calc_if (input clk, logic [6 : 0] rst);
parameter DATA_WIDTH = 32;
parameter RESP_WIDTH = 2;
parameter CMD_WIDTH = 4;
logic [DATA_WIDTH - 1 : 0] out_data1;
logic [DATA_WIDTH - 1 : 0] out_data2;
logic [DATA_WIDTH - 1 : 0] out_data3;
logic [DATA_WIDTH - 1 : 0] out_data4;
logic [RESP_WIDTH - 1 : 0] out_resp1;
logic [RESP_WIDTH - 1 : 0] out_resp2;
logic [RESP_WIDTH - 1 : 0] out_resp3;
logic [RESP_WIDTH - 1 : 0] out_resp4;
logic [CMD_WIDTH - 1 : 0] req1_cmd_in;
logic [DATA_WIDTH - 1 : 0] req1_data_in;
logic [CMD_WIDTH - 1 : 0] req2_cmd_in;
logic [DATA_WIDTH - 1 : 0] req2_data_in;
logic [CMD_WIDTH - 1 : 0] req3_cmd_in;
logic [DATA_WIDTH - 1 : 0] req3_data_in;
logic [CMD_WIDTH - 1 : 0] req4_cmd_in;
logic [DATA_WIDTH - 1 : 0] req4_data_in;
endinterface : calc_if
`endif

View File

@@ -0,0 +1,23 @@
`ifndef CALC_TEST_PKG_SV
`define CALC_TEST_PKG_SV
package calc_test_pkg;
import uvm_pkg::*; // import the UVM library
`include "uvm_macros.svh" // Include the UVM macros
import calc_agent_pkg::*;
import calc_seq_pkg::*;
`include "test_base.sv"
`include "test_simple.sv"
`include "test_simple_2.sv"
endpackage : calc_test_pkg
`include "calc_if.sv"
`endif

View File

@@ -0,0 +1,52 @@
module calc_verif_top;
import uvm_pkg::*; // import the UVM library
`include "uvm_macros.svh" // Include the UVM macros
import calc_test_pkg::*;
logic clk;
logic [6 : 0] rst;
// interface
calc_if calc_vif(clk, rst);
// DUT
calc_top DUT(
.c_clk ( clk ),
.reset ( rst ),
.out_data1 ( calc_vif.out_data1 ),
.out_data2 ( calc_vif.out_data2 ),
.out_data3 ( calc_vif.out_data3 ),
.out_data4 ( calc_vif.out_data4 ),
.out_resp1 ( calc_vif.out_resp1 ),
.out_resp2 ( calc_vif.out_resp2 ),
.out_resp3 ( calc_vif.out_resp3 ),
.out_resp4 ( calc_vif.out_resp4 ),
.req1_cmd_in ( calc_vif.req1_cmd_in ),
.req1_data_in ( calc_vif.req1_data_in ),
.req2_cmd_in ( calc_vif.req2_cmd_in ),
.req2_data_in ( calc_vif.req2_data_in ),
.req3_cmd_in ( calc_vif.req3_cmd_in ),
.req3_data_in ( calc_vif.req3_data_in ),
.req4_cmd_in ( calc_vif.req4_cmd_in ),
.req4_data_in ( calc_vif.req4_data_in )
);
// run test
initial begin
uvm_config_db#(virtual calc_if)::set(null, "*", "calc_if", calc_vif);
run_test();
end
// clock and reset init.
initial begin
clk <= 0;
rst <= 1;
#50 rst <= 0;
end
// clock generation
always #50 clk = ~clk;
endmodule : calc_verif_top

View File

@@ -0,0 +1,29 @@
`ifndef TEST_BASE_SV
`define TEST_BASE_SV
class test_base extends uvm_test;
`uvm_component_utils(test_base)
calc_driver drv;
calc_monitor mon;
calc_sequencer seqr;
calc_seq_item seq_item1;
function new(string name = "test_base", uvm_component parent = null);
super.new(name,parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv = calc_driver::type_id::create("drv", this);
mon = calc_monitor::type_id::create("mon", this);
seqr = calc_sequencer::type_id::create("seqr", this);
endfunction : build_phase
function void connect_phase(uvm_phase phase);
drv.seq_item_port.connect(seqr.seq_item_export);
endfunction : connect_phase
endclass : test_base
`endif

View File

@@ -0,0 +1,28 @@
`ifndef TEST_SIMPLE_SV
`define TEST_SIMPLE_SV
class test_simple extends test_base;
`uvm_component_utils(test_simple)
calc_simple_seq simple_seq;
function new(string name = "test_simple", uvm_component parent = null);
super.new(name,parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
simple_seq = calc_simple_seq::type_id::create("simple_seq");
endfunction : build_phase
task main_phase(uvm_phase phase);
phase.raise_objection(this);
simple_seq.start(seqr);
#100ms;
phase.drop_objection(this);
endtask : main_phase
endclass
`endif

View File

@@ -0,0 +1,23 @@
`ifndef TEST_SIMPLE_2_SV
`define TEST_SIMPLE_2_SV
class test_simple_2 extends test_base;
`uvm_component_utils(test_simple_2)
function new(string name = "test_simple_2", uvm_component parent = null);
super.new(name,parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(uvm_object_wrapper)::set(this,
"seqr.main_phase",
"default_sequence",
calc_simple_seq::type_id::get());
endfunction : build_phase
endclass
`endif