Hello,
I’m trying to see how UVM is used by taking a simple adder as an example under verification, when I go to compile the code it gives me this error:
vlog -work work -vopt -sv -stats=none /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_test.sv
QuestaSim-64 vlog 10.7c Compiler 2018.08 Aug 17 2018
** Note: (vlog-2286) /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_pkg.sv(1): Using implicit +incdir+/software/europractice-release-2019/mentor/questa10.7c/questasim/uvm-1.1d/…/verilog_src/uvm-1.1d/src from import uvm_pkg
– Compiling package simpleadder_pkg
– Importing package mtiUvm.uvm_pkg (uvm-1.1d Built-in)
** Error: (vlog-13069) ** while parsing file included at /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_test.sv(1)
** while parsing file included at /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_env.sv(2)
** at /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_sequencer.sv(2): near “uvm_sequence_item”: syntax error, unexpected IDENTIFIER.
** Error: ** while parsing file included at /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_test.sv(1)
** while parsing file included at /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_env.sv(2)
** at /home/thesis/zaidrawhi.mohammadmohaidat/UVM/simpleadder_sequencer.sv(2): Error in class extension specification.
my code is the following:
“simpleadder.v”
module simpleadder(
input wire clk,
input wire en_i,
input wire ina,
input wire inb,
output reg en_o,
output reg out);
integer counter, state;
reg[1:0] temp_a, temp_b;
reg[2:0] temp_out;
//Init
initial begin
counter = 0;
temp_a = 2'b00;
temp_b = 2'b00;
temp_out = 3'b000;
out = 0;
en_o <= 0;
state = 0;
end
always@(posedge clk)
begin
//State 0: Wait for en_i
if(en_i==1'b1)
begin
state = 1;
end
case(state)
//State 1: Start reading inputs
1: begin
temp_a = temp_a << 1;
temp_a = temp_a | ina;
temp_b = temp_b << 1;
temp_b = temp_b | inb;
counter = counter + 1;
//After 2 bits, do the operation an move to the next state
if(counter==2) begin
temp_out = temp_a + temp_b;
state = 2;
end
end
//State 2: Enable en_o and sends result to the output
2: begin
out <= temp_out[2];
temp_out = temp_out << 1;
counter = counter + 1;
if(counter==3) en_o <= 1'b1;
if(counter==4) en_o <= 1'b0;
if(counter==6) begin
counter = 0;
out <= 1'b0;
state = 0;
end
end
endcase
end
endmodule
“simpleadder_sequencer.sv”
//`include “uvm_macros.svh”
class simpleadder_transaction extends uvm_sequence_item;
rand bit[1:0] ina;
rand bit[1:0] inb;
bit[2:0] out;
function new(string name = "");
super.new(name);
endfunction: new
`uvm_object_utils_begin(simpleadder_transaction)
`uvm_field_int(ina, UVM_ALL_ON )
`uvm_field_int(inb, UVM_ALL_ON )
`uvm_field_int(out, UVM_ALL_ON)
`uvm_object_utils_end
endclass: simpleadder_transaction
class simpleadder_sequence extends uvm_sequence#(simpleadder_transaction);
`uvm_object_utils(simpleadder_sequence)
function new(string name = "");
super.new(name);
endfunction: new
task body();
simpleadder_transaction sa_tx;
repeat(15) begin
sa_tx = simpleadder_transaction::type_id::create(.name("sa_tx"), .contxt(get_full_name()));
start_item(sa_tx);
assert(sa_tx.randomize());
//`uvm_info("sa_sequence", sa_tx.sprint(), UVM_LOW);
finish_item(sa_tx);
end
endtask: body
endclass: simpleadder_sequence
typedef uvm_sequencer#(simpleadder_transaction) simpleadder_sequencer;
“simpleadder_driver.sv”
class simpleadder_driver extends uvm_driver#(simpleadder_transaction);
`uvm_component_utils(simpleadder_driver)
virtual simpleadder_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual simpleadder_if)::read_by_name
(.scope("ifs"), .name("simpleadder_if"), .val(vif)));
endfunction: build_phase
task run_phase(uvm_phase phase);
drive();
endtask: run_phase
virtual task drive();
simpleadder_transaction sa_tx;
integer counter = 0, state = 0;
vif.sig_ina = 0'b0;
vif.sig_inb = 0'b0;
vif.sig_en_i = 1'b0;
forever begin
if(counter==0)
begin
seq_item_port.get_next_item(sa_tx);
//`uvm_info("sa_driver", sa_tx.sprint(), UVM_LOW);
end
@(posedge vif.sig_clock)
begin
if(counter==0)
begin
vif.sig_en_i = 1'b1;
state = 1;
end
if(counter==1)
begin
vif.sig_en_i = 1'b0;
end
case(state)
1: begin
vif.sig_ina = sa_tx.ina[1];
vif.sig_inb = sa_tx.inb[1];
sa_tx.ina = sa_tx.ina << 1;
sa_tx.inb = sa_tx.inb << 1;
counter = counter + 1;
if(counter==2) state = 2;
end
2: begin
vif.sig_ina = 1'b0;
vif.sig_inb = 1'b0;
counter = counter + 1;
if(counter==6)
begin
counter = 0;
state = 0;
seq_item_port.item_done();
end
end
endcase
end
end
endtask: drive
endclass: simpleadder_driver
“simpleadder_config.sv”
class simpleadder_configuration extends uvm_object;
`uvm_object_utils(simpleadder_configuration)
function new(string name = "");
super.new(name);
endfunction: new
endclass: simpleadder_configuration
“simpleadder_agent.sv”
class simpleadder_agent extends uvm_agent;
`uvm_component_utils(simpleadder_agent)
uvm_analysis_port#(simpleadder_transaction) agent_ap_before;
uvm_analysis_port#(simpleadder_transaction) agent_ap_after;
simpleadder_sequencer sa_seqr;
simpleadder_driver sa_drvr;
simpleadder_monitor_before sa_mon_before;
simpleadder_monitor_after sa_mon_after;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agent_ap_before = new(.name("agent_ap_before"), .parent(this));
agent_ap_after = new(.name("agent_ap_after"), .parent(this));
sa_seqr = simpleadder_sequencer::type_id::create(.name("sa_seqr"), .parent(this));
sa_drvr = simpleadder_driver::type_id::create(.name("sa_drvr"), .parent(this));
sa_mon_before = simpleadder_monitor_before::type_id::create(.name("sa_mon_before"), .parent(this));
sa_mon_after = simpleadder_monitor_after::type_id::create(.name("sa_mon_after"), .parent(this));
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
sa_drvr.seq_item_port.connect(sa_seqr.seq_item_export);
sa_mon_before.mon_ap_before.connect(agent_ap_before);
sa_mon_after.mon_ap_after.connect(agent_ap_after);
endfunction: connect_phase
endclass: simpleadder_agent
“simpleadder_env.sv”
include "simpleadder_pkg.sv"
include “simpleadder_sequencer.sv”
include "simpleadder_driver.sv"
include “simpleadder_monitor.sv”
`include “simpleadder_scoreboard.sv”
class simpleadder_env extends uvm_env;
`uvm_component_utils(simpleadder_env)
simpleadder_agent sa_agent;
simpleadder_scoreboard sa_sb;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
sa_agent = simpleadder_agent::type_id::create(.name("sa_agent"), .parent(this));
sa_sb = simpleadder_scoreboard::type_id::create(.name("sa_sb"), .parent(this));
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
sa_agent.agent_ap_before.connect(sa_sb.sb_export_before);
sa_agent.agent_ap_after.connect(sa_sb.sb_export_after);
endfunction: connect_phase
endclass: simpleadder_env
“simpleadder_if.sv”
interface simpleadder_if;
logic sig_clock;
logic sig_ina;
logic sig_inb;
logic sig_en_i;
logic sig_out;
logic sig_en_o;
endinterface: simpleadder_if
“simpleadder_monitor.sv”
class simpleadder_monitor_before extends uvm_monitor;
`uvm_component_utils(simpleadder_monitor_before)
uvm_analysis_port#(simpleadder_transaction) mon_ap_before;
virtual simpleadder_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual simpleadder_if)::read_by_name
(.scope("ifs"), .name("simpleadder_if"), .val(vif)));
mon_ap_before = new(.name("mon_ap_before"), .parent(this));
endfunction: build_phase
task run_phase(uvm_phase phase);
integer counter_mon = 0, state = 0;
simpleadder_transaction sa_tx;
sa_tx = simpleadder_transaction::type_id::create
(.name("sa_tx"), .contxt(get_full_name()));
forever begin
@(posedge vif.sig_clock)
begin
if(vif.sig_en_o==1'b1)
begin
state = 3;
end
if(state==3)
begin
sa_tx.out = sa_tx.out << 1;
sa_tx.out[0] = vif.sig_out;
counter_mon = counter_mon + 1;
if(counter_mon==3)
begin
state = 0;
counter_mon = 0;
//Send the transaction to the analysis port
mon_ap_before.write(sa_tx);
end
end
end
end
endtask: run_phase
endclass: simpleadder_monitor_before
class simpleadder_monitor_after extends uvm_monitor;
`uvm_component_utils(simpleadder_monitor_after)
uvm_analysis_port#(simpleadder_transaction) mon_ap_after;
virtual simpleadder_if vif;
simpleadder_transaction sa_tx;
//For coverage
simpleadder_transaction sa_tx_cg;
//Define coverpoints
covergroup simpleadder_cg;
ina_cp: coverpoint sa_tx_cg.ina;
inb_cp: coverpoint sa_tx_cg.inb;
cross ina_cp, inb_cp;
endgroup: simpleadder_cg
function new(string name, uvm_component parent);
super.new(name, parent);
simpleadder_cg = new;
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual simpleadder_if)::read_by_name
(.scope("ifs"), .name("simpleadder_if"), .val(vif)));
mon_ap_after= new(.name("mon_ap_after"), .parent(this));
endfunction: build_phase
task run_phase(uvm_phase phase);
integer counter_mon = 0, state = 0;
sa_tx = simpleadder_transaction::type_id::create
(.name("sa_tx"), .contxt(get_full_name()));
forever begin
@(posedge vif.sig_clock)
begin
if(vif.sig_en_i==1'b1)
begin
state = 1;
sa_tx.ina = 2'b00;
sa_tx.inb = 2'b00;
sa_tx.out = 3'b000;
end
if(state==1)
begin
sa_tx.ina = sa_tx.ina << 1;
sa_tx.inb = sa_tx.inb << 1;
sa_tx.ina[0] = vif.sig_ina;
sa_tx.inb[0] = vif.sig_inb;
counter_mon = counter_mon + 1;
if(counter_mon==2)
begin
state = 0;
counter_mon = 0;
//Predict the result
predictor();
sa_tx_cg = sa_tx;
//Coverage
simpleadder_cg.sample();
//Send the transaction to the analysis port
mon_ap_after.write(sa_tx);
end
end
end
end
endtask: run_phase
virtual function void predictor();
sa_tx.out = sa_tx.ina + sa_tx.inb;
endfunction: predictor
endclass: simpleadder_monitor_after
“simpleadder_pkg.sv”
`include “uvm_macros.svh”
package simpleadder_pkg;
import uvm_pkg::*;
//include "uvm_macros.svh"
include “simpleadder_sequencer.sv”
include "simpleadder_monitor.sv"
include “simpleadder_driver.sv”
include "simpleadder_agent.sv"
include “simpleadder_scoreboard.sv”
include "simpleadder_config.sv" //
include “simpleadder_env.sv”
// `include “simpleadder_test.sv”
endpackage: simpleadder_pkg
“simpleadder_scoreboard.sv”
uvm_analysis_imp_decl(_before)
uvm_analysis_imp_decl(_after)
class simpleadder_scoreboard extends uvm_scoreboard;
`uvm_component_utils(simpleadder_scoreboard)
uvm_analysis_export #(simpleadder_transaction) sb_export_before;
uvm_analysis_export #(simpleadder_transaction) sb_export_after;
uvm_tlm_analysis_fifo #(simpleadder_transaction) before_fifo;
uvm_tlm_analysis_fifo #(simpleadder_transaction) after_fifo;
simpleadder_transaction transaction_before;
simpleadder_transaction transaction_after;
function new(string name, uvm_component parent);
super.new(name, parent);
transaction_before = new("transaction_before");
transaction_after = new("transaction_after");
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
sb_export_before = new("sb_export_before", this);
sb_export_after = new("sb_export_after", this);
before_fifo = new("before_fifo", this);
after_fifo = new("after_fifo", this);
endfunction: build_phase
function void connect_phase(uvm_phase phase);
sb_export_before.connect(before_fifo.analysis_export);
sb_export_after.connect(after_fifo.analysis_export);
endfunction: connect_phase
task run();
forever begin
before_fifo.get(transaction_before);
after_fifo.get(transaction_after);
compare();
end
endtask: run
virtual function void compare();
if(transaction_before.out == transaction_after.out) begin
`uvm_info("compare", {"Test: OK!"}, UVM_LOW);
end else begin
`uvm_info("compare", {"Test: Fail!"}, UVM_LOW);
end
endfunction: compare
endclass: simpleadder_scoreboard
“simpleadder_test.sv”
`include “simpleadder_env.sv”
class simpleadder_test extends uvm_test;
`uvm_component_utils(simpleadder_test)
simpleadder_env sa_env;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
sa_env = simpleadder_env::type_id::create(.name("sa_env"), .parent(this));
endfunction: build_phase
task run_phase(uvm_phase phase);
simpleadder_sequence sa_seq;
phase.raise_objection(.obj(this));
sa_seq = simpleadder_sequence::type_id::create(.name("sa_seq"), .contxt(get_full_name()));
assert(sa_seq.randomize());
sa_seq.start(sa_env.sa_agent.sa_seqr);
phase.drop_objection(.obj(this));
endtask: run_phase
endclass: simpleadder_test
“simpleadder_tb_top.sv”
//`include “uvm_macros.svh”
//`include “simpleadder_test.sv”
include "simpleadder_pkg.sv"
include “simpleadder.sv”
`include “simpleadder_if.sv”
module simpleadder_tb_top;
import uvm_pkg::*;
//Interface declaration
simpleadder_if vif();
//Connects the Interface to the DUT
simpleadder dut(vif.sig_clock,
vif.sig_en_i,
vif.sig_ina,
vif.sig_inb,
vif.sig_en_o,
vif.sig_out);
initial begin
//Registers the Interface in the configuration block so that other
//blocks can use it
uvm_resource_db#(virtual simpleadder_if)::set
(.scope("ifs"), .name("simpleadder_if"), .val(vif));
//Executes the test
#0;run_test();
end
//Variable initialization
initial begin
vif.sig_clock <= 1'b1;
end
//Clock generation
always
#5 vif.sig_clock = ~vif.sig_clock;
endmodule