In reply to alexd555:
This has to be done in the connect_phase of the agent.
calc_agent.sv
`include "calc_trans.sv"
`include "calc_sequencer.sv"
`include "calc_driver.sv"
`include "calc_monitor.sv"
`include "calc_scoreboard.sv"
class calc_agent extends uvm_agent;
`uvm_component_utils(calc_agent)
uvm_analysis_port #(calc_trans) aport;
calc_sequencer calc_sequencer_h;
calc_driver calc_driver_h;
calc_monitor calc_monitor_h;
function new(string name="calc_agent", uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
aport = new ("aport", this);
calc_sequencer_h = calc_sequencer::type_id::create("calc_sequencer", this);
calc_driver_h = calc_driver::type_id::create("calc_driver", this);
calc_monitor_h = calc_monitor::type_id::create("calc_monitor", this);
endfunction: build_phase
function void connect_phase(uvm_phase phase);
calc_monitor_h.aport.connect(this.aport);
endfunction: connect_phase
endclass: calc_agent
You are right. I forgot it:
calc_driver_h.seq_item_port.connect(calc_sequencer_h.seq_item_export);
But I have another problem. The test runs forever. I replace “forever” to repeat but it doesn’t help.
I get:
objections raised, skipping phase
In reply to alexd555:
In the connect_phase the connection between the driver and the sequencer is missing:
calc_driver_h.seq_item_port.connect(calc_sequencer_h.seq_item_export);
What about
Phase ‘uvm.uvm_sched.post_shutdown’ (id=324) No objections raised, skipping phase
?
Another problem,
dump is not created
module calc_tb_top;
import uvm_pkg::*;
//clock and reset signal declaration
logic clk;
logic reset;
//creatinng instance of interface, inorder to connect DUT and testcase
calc_if dut_ifc1(clk, reset);
//enabling the wave dump
initial begin
forever begin
#5ns;
clk = ~clk;
end
end
//DUT instance, interface signals are connected to the DUT ports
calculator DUT (
.clk(dut_ifc1.clk),
.rstn(dut_ifc1.rstn),
.a(dut_ifc1.a),
.b(dut_ifc1.b),
.opcode(dut_ifc1.opcode),
.result(dut_ifc1.res),
.error(dut_ifc1.error)
);
initial begin
uvm_config_db#(virtual calc_if)::set(null,"*","dut_vif", dut_ifc1);
$dumpfile("b.vcd");
$dumpvars;
end
initial begin
run_test(“calc_test”);
end
endmodule
In reply to alexd555:
Did you close the simulator? It might flash the buffer only after closing the simulation.
BTW, why do you use the $dumpvars/$dumpfile? In the simulator you are able to display all signals/variables in the wave window.
I closed.
The clock is not generated.
I use with synopsis vcs
In reply to alexd555:
Then you know where it comes from …
In such a case check always the progress in time. If it stucks at runtime 0 you’ll not see any waveform.
it doesn’t stuck.
Do you have any idea ?
$finish at simulation time 0
V C S S i m u l a t i o n R e p o r t
Time: 0 ns
CPU Time: 0.830 seconds; Data structure size: 0.5Mb
Thu Jun 13 13:21:50 2019
CPU time: 10.461 seconds to compile + .536 seconds to elab + .752 seconds to link + .888 seconds in simulation
Do you have idea how I can solve it ?
In reply to alexd555:
Looks like your clock is not working or you did not implement an objection mechanism.
How can I check ?
In reply to alexd555:
Look into your toplevel module if there is a clock generator. Afterwards look to your driver. It might hang at time 0.
If possible post the beginning of your run_phase of the driver around get_next_item.
Objections have to be implemented. They can be in different places. Look to your test, driver and sequences. These are the most common constructs objections can be implemented.
I posted my toplevel model. You can there is a clock(clk).
calc_driver.sv
include "calc_sequence.sv" class calc_driver extends uvm_driver #(calc_trans);
uvm_component_utils(calc_driver)
virtual calc_if dut_ifc1;
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual calc_if)::get(this,“”,“dut_vif”, dut_ifc1))
`uvm_fatal(“NOVIF”,{“virtual interface must be set for: “,get_full_name(),”.dut_ifc”});
$display(“driver”);
endfunction: build_phase
task run_phase(uvm_phase phase);
repeat(300)
begin
calc_trans tx;
seq_item_port.get_next_item(tx);
dut_ifc1.a <= tx.a;
dut_ifc1.b <= tx.b;
dut_ifc1.opcode <= tx.opcode;
seq_item_port.item_done();
end
endtask: run_phase
endclass: calc_driver
calc_sequence.sv
class calc_sequence extends uvm_sequence#(calc_trans);
`uvm_object_utils(calc_sequence)
function new(string name = “calc_sequence”);
super.new(name);
endfunction: new
task body();
calc_trans req;
$display("calc_seq");
repeat(300) begin
req = calc_trans::type_id::create("req");
start_item(req);
assert(req.randomize());
finish_item(req);
$display("a = ", req.a);
$display("b = ", req.b);
$display("opcode = ", req.opcode);
end
endtask: body
endclass: calc_sequence
calc_test.sv
class calc_test extends uvm_test;
`uvm_component_utils(calc_test)
calc_env env;
calc_sequence calc_seq;
function new(string name = “calc_test”,uvm_component parent=null);
super.new(name,parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = calc_env::type_id::create(“env”, this);
calc_seq = calc_sequence::type_id::create(“calc_seq”, this);
endfunction : build_phase
task run_phase(uvm_phase phase);
phase.raise_objection(this);
calc_seq.start(env.calc_agent_h.calc_sequencer_h);
phase.drop_objection(this);
endtask : run_phase
endclass : calc_test
In reply to alexd555:
The run_phase of your driver is not a clocked process, i.e. it does not progress in time and stays always at time 0.
After get_next_item there should be a statement like this:
@(posedge dut_ifc1.clk);
What about of monitor ? should there be posedge clk ?
Where else ?