寄存器模型集成
总线UVC的实现
MCDF访问寄存器的总线接口时序较为简单。控制寄存器接口首先需要在每一个时钟解析cmd。当cmd为写指令时,即需要把数据cmd_data_in写入到cmd_addr对应的寄存器中。当cmd为读指令时,即需要cmd_addr对应的寄存器中读取数据,在下一个周期,cmd_addr对应的寄存器数据被输送到cmd_data_out接口。下例时8位地址,32位数据线的总线UVC实现代码。
class mcdf_bus_trans extends uvm_sequence_item;
rand bit[1:0] cmd;
rand bit[7:0] addr;
rand bit[31:0] wdata;
bit[31:0] rdata;
`uvm_object_utils_begin(mcdf_bus_trans)
...
`uvm_object_utils_end
...
endclass
class mcdf_bus_sequencer extends uvm_sequencer;
virtual mcdf_if vif;
`uvm_component_utils(mcdf_bus_sequencer)
...
function void build_phase(uvm_phase phase);
if(!uvm_config_db#(virtual mcdf_if)::get(this, "", "vif", vif)) begin
`uvm_error("GETVIF", "no virtual interface is assigned")
end
endfunction
endclass
class mcdf_bus_monitor extends uvm_monitor;
virtual mcdf_if vif;
uvm_analysis_port #(mcdf_bus_trans) ap;
`uvm_component_utils(mcdf_bus_monitor)
...
function void build_phase(uvm_phase);
if(!uvm_config_db#(virtual mcdf_if)::get(this, "", "vif", vif)) begin
`uvm_error("GETVIF", "no virtual interface is assigned")
end
ap = new("ap", this);
endfunction
task run_phase(uvm_phase phase);
forever begin
mon_trans();
end
endtask
task mon_trans();
mcdf_bus_trans t;
@(posedge vif.clk);
if(vif.cmd == `WRITE) begin
t = new();
t.cmd = `WRITE;
t.addr = vif.addr;
t.wdata = vif.wdata;
ap.write(t);
end
else if(vif.cmd == `READ) begin
t = new();
t.cmd = `READ;
t.addr = vif.addr;
fork
begin
@(posedge vif.clk);
#10ns;
t.rdata = vif.rdata;
ap.write(t);
end
join_none
end
endtask
endclass
class mcdf_bus_driver extends uvm_driver;
virtual mcdf_if vif;
`uvm_component_utils(mcdf_bus_driver)
...
fucntion void build_phase(uvm_phase phase);
if(!uvm_config_db#(virtual mcdf_if)::get(this, &#