sequencer 仲裁机制出错,driver没有接收到包,是什么原因
时间:10-02
整理:3721RD
点击:
ackage seq_arb_priorities_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
class seq_arb_item extends uvm_sequence_item;
int seq_no;
rand byte payload[$];
constraint c_size {payload.size() inside {[48:200]};}
`uvm_object_utils(seq_arb_item)
function new(string name = "seq_arb_item");
super.new(name);
endfunction
endclass: seq_arb_item
// Receives sequence items the sequences and and keeps a running total
class seq_arb_driver extends uvm_driver #(seq_arb_item);
`uvm_component_utils(seq_arb_driver)
// Counters to keep track of sequence accesses
int seq_1 = 0;
int seq_2 = 0;
int seq_3 = 0;
int seq_4 = 0;
function new(string name = "seq_arb_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
seq_arb_item REQ;
forever begin
seq_item_port.get(REQ);
case(REQ.seq_no)
1: seq_1++;
2: seq_2++;
3: seq_3++;
4: seq_4++;
endcase
uvm_report_info("RECEIVED_SEQ", $psprintf("Access totals: SEQ_1:%0d SEQ_2:%0d SEQ_3:%0d SEQ_4:%0d", seq_1, seq_2, seq_3, seq_4));
#10ns;
//seq_item_port.item_done();
end
endtask: run_phase
endclass: seq_arb_driver
// This sequencer implementation contains an overloaded user_priority_arbitration method
// to illustrate how to implement the SEQ_ARB_USER approach
typedef class arb_example_seq;
class seq_arb_sequencer extends uvm_sequencer #(seq_arb_item);
`uvm_component_utils(seq_arb_sequencer)
arb_example_seqm_global_sequence;
function new(string name = "seq_arb_sequencer", uvm_component parent = null);
super.new(name, parent);
endfunction
// This method overrides the default user method
// It returns the last item in the sequence queue rather than the first
function integer user_priority_arbitration(integer avail_sequences[$]);
int end_index;
end_index = avail_sequences.size() - 1;
return (avail_sequences[end_index]);
endfunction
endclass: seq_arb_sequencer
// The sequence which sends sequence items - four of these are run in parallel
class arb_seq extends uvm_sequence #(seq_arb_item);
`uvm_object_utils(arb_seq)
int seq_no;
function new(string name = "arb_seq");
super.new(name);
endfunction
task body;
seq_arb_item REQ;
//int seq_id;
REQ = seq_arb_item::type_id::create("REQ");
REQ.seq_no = seq_no;
repeat(4) begin
uvm_report_info("arb_seq",$sformatf("seq_no = %0d",REQ.seq_no), UVM_DEBUG);
start_item(REQ);
finish_item(REQ);
end
endtask: body
endclass: arb_seq
// Top level sequence which runs four sequences with different prioirty and time
// offsets. It also sets up the sequencer arbitration algorithm
class arb_example_seq extends uvm_sequence #(seq_arb_item);
`uvm_object_utils(arb_example_seq)
arb_seq seq_1, seq_2, seq_3, seq_4;
SEQ_ARB_TYPE arb_type;
function new(string name = "arb_example_seq");
super.new(name);
endfunction
task body;
seq_1 = arb_seq::type_id::create("seq_1");
seq_1.seq_no = 1;
seq_2 = arb_seq::type_id::create("seq_2");
seq_2.seq_no = 2;
seq_3 = arb_seq::type_id::create("seq_3");
seq_3.seq_no = 3;
seq_4 = arb_seq::type_id::create("seq_4");
seq_4.seq_no = 4;
m_sequencer.set_arbitration(arb_type);
fork
begin
repeat(4) begin
#1ns;
seq_1.start(m_sequencer, this, 500); // Highest priorit
uvm_report_info("seq1 start:",seq_1.get_name());
end
end
begin
repeat(4) begin
#2ns;
seq_2.start(m_sequencer, this, 500); // Highest priority
uvm_report_info("seq2 start:",seq_2.get_name());
end
end
begin
repeat(4) begin
#3ns;
seq_3.start(m_sequencer, this, 300); // Medium priority
uvm_report_info("seq3 start:",seq_3.get_name());
end
end
begin
repeat(4) begin
#4ns;
seq_4.start(m_sequencer, this, 200); // Lowest priority
uvm_report_info("seq4 start:",seq_4.get_name());
end
end
join
endtask: body
endclass: arb_example_seq
// Overall test class that builds the test bench and sets the arbitration
// algorithm according to the ARB_TYPE plusarg
class arb_test extends uvm_component;
`uvm_component_utils(arb_test)
uvm_table_printer printer;
seq_arb_driver m_driver;
seq_arb_sequencer m_sequencer;
arb_example_seq m_seq;
function new(string name = "arb_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
m_driver = seq_arb_driver::type_id::create("m_driver", this);
m_sequencer = seq_arb_sequencer::type_id::create("m_sequencer", this);
m_seq = arb_example_seq::type_id::create("m_seq", this);
printer = new();
printer.knobs.depth = -1; //print everything
endfunction: build_phase
function void connect_phase(uvm_phase phase);
m_driver.seq_item_port.connect(m_sequencer.seq_item_export);
endfunction: connect_phase
function void end_of_elaboration_phase(uvm_phase phase);
begin
`uvm_info(get_type_name(),"going through the end_of_elaboration_phase phase", UVM_LOW);
`uvm_info(get_type_name(), $sformatf("Printing the test topology :\n%s", this.sprint(printer)), UVM_DEBUG);
end
endfunction:end_of_elaboration_phase
task run_phase(uvm_phase phase);
string arb_type;
if($value$plusargs("ARB_TYPE=%s", arb_type)) begin
uvm_report_info("Sequencer Arbitration selected:", arb_type);
end
else begin
uvm_report_fatal("arb_test:", "The ARB_TYPE plusarg was not specified on the command line");
end
case(arb_type)
"SEQ_ARB_FIFO": m_seq.arb_type = SEQ_ARB_FIFO;
"SEQ_ARB_WEIGHTED": m_seq.arb_type = SEQ_ARB_WEIGHTED;
"SEQ_ARB_RANDOM": m_seq.arb_type = SEQ_ARB_RANDOM;
"SEQ_ARB_STRICT_FIFO": m_seq.arb_type = SEQ_ARB_STRICT_FIFO;
"SEQ_ARB_STRICT_RANDOM": m_seq.arb_type = SEQ_ARB_STRICT_RANDOM;
"SEQ_ARB_USER": m_seq.arb_type = SEQ_ARB_USER;
endcase
m_seq.start(m_sequencer);
#100ns;
global_stop_request();
endtask: run_phase
endclass: arb_test
endpackage: seq_arb_priorities_pkg
运行没有错误,就是没有打印出driver中的report,单步也没有办法跑到。
import uvm_pkg::*;
`include "uvm_macros.svh"
class seq_arb_item extends uvm_sequence_item;
int seq_no;
rand byte payload[$];
constraint c_size {payload.size() inside {[48:200]};}
`uvm_object_utils(seq_arb_item)
function new(string name = "seq_arb_item");
super.new(name);
endfunction
endclass: seq_arb_item
// Receives sequence items the sequences and and keeps a running total
class seq_arb_driver extends uvm_driver #(seq_arb_item);
`uvm_component_utils(seq_arb_driver)
// Counters to keep track of sequence accesses
int seq_1 = 0;
int seq_2 = 0;
int seq_3 = 0;
int seq_4 = 0;
function new(string name = "seq_arb_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
seq_arb_item REQ;
forever begin
seq_item_port.get(REQ);
case(REQ.seq_no)
1: seq_1++;
2: seq_2++;
3: seq_3++;
4: seq_4++;
endcase
uvm_report_info("RECEIVED_SEQ", $psprintf("Access totals: SEQ_1:%0d SEQ_2:%0d SEQ_3:%0d SEQ_4:%0d", seq_1, seq_2, seq_3, seq_4));
#10ns;
//seq_item_port.item_done();
end
endtask: run_phase
endclass: seq_arb_driver
// This sequencer implementation contains an overloaded user_priority_arbitration method
// to illustrate how to implement the SEQ_ARB_USER approach
typedef class arb_example_seq;
class seq_arb_sequencer extends uvm_sequencer #(seq_arb_item);
`uvm_component_utils(seq_arb_sequencer)
arb_example_seqm_global_sequence;
function new(string name = "seq_arb_sequencer", uvm_component parent = null);
super.new(name, parent);
endfunction
// This method overrides the default user method
// It returns the last item in the sequence queue rather than the first
function integer user_priority_arbitration(integer avail_sequences[$]);
int end_index;
end_index = avail_sequences.size() - 1;
return (avail_sequences[end_index]);
endfunction
endclass: seq_arb_sequencer
// The sequence which sends sequence items - four of these are run in parallel
class arb_seq extends uvm_sequence #(seq_arb_item);
`uvm_object_utils(arb_seq)
int seq_no;
function new(string name = "arb_seq");
super.new(name);
endfunction
task body;
seq_arb_item REQ;
//int seq_id;
REQ = seq_arb_item::type_id::create("REQ");
REQ.seq_no = seq_no;
repeat(4) begin
uvm_report_info("arb_seq",$sformatf("seq_no = %0d",REQ.seq_no), UVM_DEBUG);
start_item(REQ);
finish_item(REQ);
end
endtask: body
endclass: arb_seq
// Top level sequence which runs four sequences with different prioirty and time
// offsets. It also sets up the sequencer arbitration algorithm
class arb_example_seq extends uvm_sequence #(seq_arb_item);
`uvm_object_utils(arb_example_seq)
arb_seq seq_1, seq_2, seq_3, seq_4;
SEQ_ARB_TYPE arb_type;
function new(string name = "arb_example_seq");
super.new(name);
endfunction
task body;
seq_1 = arb_seq::type_id::create("seq_1");
seq_1.seq_no = 1;
seq_2 = arb_seq::type_id::create("seq_2");
seq_2.seq_no = 2;
seq_3 = arb_seq::type_id::create("seq_3");
seq_3.seq_no = 3;
seq_4 = arb_seq::type_id::create("seq_4");
seq_4.seq_no = 4;
m_sequencer.set_arbitration(arb_type);
fork
begin
repeat(4) begin
#1ns;
seq_1.start(m_sequencer, this, 500); // Highest priorit
uvm_report_info("seq1 start:",seq_1.get_name());
end
end
begin
repeat(4) begin
#2ns;
seq_2.start(m_sequencer, this, 500); // Highest priority
uvm_report_info("seq2 start:",seq_2.get_name());
end
end
begin
repeat(4) begin
#3ns;
seq_3.start(m_sequencer, this, 300); // Medium priority
uvm_report_info("seq3 start:",seq_3.get_name());
end
end
begin
repeat(4) begin
#4ns;
seq_4.start(m_sequencer, this, 200); // Lowest priority
uvm_report_info("seq4 start:",seq_4.get_name());
end
end
join
endtask: body
endclass: arb_example_seq
// Overall test class that builds the test bench and sets the arbitration
// algorithm according to the ARB_TYPE plusarg
class arb_test extends uvm_component;
`uvm_component_utils(arb_test)
uvm_table_printer printer;
seq_arb_driver m_driver;
seq_arb_sequencer m_sequencer;
arb_example_seq m_seq;
function new(string name = "arb_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
m_driver = seq_arb_driver::type_id::create("m_driver", this);
m_sequencer = seq_arb_sequencer::type_id::create("m_sequencer", this);
m_seq = arb_example_seq::type_id::create("m_seq", this);
printer = new();
printer.knobs.depth = -1; //print everything
endfunction: build_phase
function void connect_phase(uvm_phase phase);
m_driver.seq_item_port.connect(m_sequencer.seq_item_export);
endfunction: connect_phase
function void end_of_elaboration_phase(uvm_phase phase);
begin
`uvm_info(get_type_name(),"going through the end_of_elaboration_phase phase", UVM_LOW);
`uvm_info(get_type_name(), $sformatf("Printing the test topology :\n%s", this.sprint(printer)), UVM_DEBUG);
end
endfunction:end_of_elaboration_phase
task run_phase(uvm_phase phase);
string arb_type;
if($value$plusargs("ARB_TYPE=%s", arb_type)) begin
uvm_report_info("Sequencer Arbitration selected:", arb_type);
end
else begin
uvm_report_fatal("arb_test:", "The ARB_TYPE plusarg was not specified on the command line");
end
case(arb_type)
"SEQ_ARB_FIFO": m_seq.arb_type = SEQ_ARB_FIFO;
"SEQ_ARB_WEIGHTED": m_seq.arb_type = SEQ_ARB_WEIGHTED;
"SEQ_ARB_RANDOM": m_seq.arb_type = SEQ_ARB_RANDOM;
"SEQ_ARB_STRICT_FIFO": m_seq.arb_type = SEQ_ARB_STRICT_FIFO;
"SEQ_ARB_STRICT_RANDOM": m_seq.arb_type = SEQ_ARB_STRICT_RANDOM;
"SEQ_ARB_USER": m_seq.arb_type = SEQ_ARB_USER;
endcase
m_seq.start(m_sequencer);
#100ns;
global_stop_request();
endtask: run_phase
endclass: arb_test
endpackage: seq_arb_priorities_pkg
运行没有错误,就是没有打印出driver中的report,单步也没有办法跑到。
driver中没看到get_next_item方法
是不是你的ENV有问题?