電子錶設計與驗證(暫存器模組驗證)
阿新 • • 發佈:2021-01-22
暫存器模組驗證
利用UVM搭建
package reg_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
`include "parameter_clock.v"
class reg_trans extends uvm_sequence_item;
rand int up;
rand int dn;
rand bit [7:0] reg_i;
rand bit [1:0] flag;
constraint clkcons{
up inside {[0:1]};
dn inside {[0:1]};
if (flag > 0) up + dn == 1;
if (flag == 0) up + dn == 0;
reg_i[`CMD_ZERO] == up;
reg_i[`CMD_LOW] == dn;
reg_i[`CMD_HIGH:`CMD_MID] == flag;
};
`uvm_object_utils_begin (reg_trans)
`uvm_field_int(up,UVM_ALL_ON)
`uvm_field_int(dn,UVM_ALL_ON)
`uvm_field_int(flag,UVM_ALL_ON)
`uvm_field_int(reg_i,UVM_ALL_ON)
`uvm_object_utils_end
function new (string name = "clock_trans");
super.new(name);
endfunction
endclass
class reg_driver extends uvm_driver #( reg_trans);
local virtual reg_inter intf;
`uvm_component_utils(reg_driver)
function new (string name = "reg_driver", uvm_component parent);
super.new(name,parent);
endfunction
function void set_interface(virtual reg_inter intf);
this.intf = intf;
endfunction
task run_phase (uvm_phase phase);
fork
this.do_trans();
this.do_reset();
join
endtask
task do_trans();
reg_trans req,rsp;
@(posedge intf.rstn)
forever begin
seq_item_port.get_next_item(req);
this.do_write(req);
void'($cast(rsp,req.clone()));
rsp.set_sequence_id(req.get_sequence_id());
seq_item_port.item_done(rsp);
end
endtask
task do_write(input reg_trans req);
repeat (1000) @(posedge intf.clk)
intf.reg_cb.reg_i <= req.reg_i;
endtask
task do_reset();
forever begin
@(negedge intf.rstn)
intf.reg_i = 0;
end
endtask
endclass
class reg_sequencer extends uvm_sequencer #(reg_trans);
`uvm_component_utils(reg_sequencer)
function new(string name = "sequencer", uvm_component parent);
super.new(name,parent);
endfunction
endclass
class reg_sequence extends uvm_sequence #(reg_trans);
local virtual reg_inter intf;
rand int reg_i = -1;
`uvm_object_utils_begin(reg_sequence)
`uvm_field_int(reg_i,UVM_ALL_ON)
`uvm_object_utils_end
function new (string name = "reg_sequence");
super.new(name);
endfunction
function void set_interface (virtual reg_inter intf);
this.intf = intf;
endfunction
task body();
repeat (500) do_gen();
endtask
task do_gen();
reg_trans req,rsp;
`uvm_do_with(req, {
local::reg_i >= 0 -> reg_i == local::reg_i;
})
get_response(rsp);
endtask
endclass
class reg_monitor extends uvm_monitor;
local virtual reg_inter intf;
uvm_tlm_fifo #(reg_trans) reg_bg_fifo;
`uvm_component_utils(reg_monitor)
function new(string name = "reg_monitor", uvm_component parent);
super.new(name,parent);
reg_bg_fifo = new("reg_bg_fifo",this);
endfunction
function void set_interface (virtual reg_inter intf);
if(intf == null)
$error("clock_reg interface handle is NULL");
else begin
this.intf = intf;
`uvm_info("SET_INTREFACE"," get handle of reg_interface", UVM_LOW)
end
endfunction
task run_phase(uvm_phase phase);
this.do_mon();
endtask
task do_mon();
reg_trans m;
forever begin
repeat (1000) @(posedge intf.clk);
m = new();
m.reg_i = intf.reg_cb.reg_i;
m.dn = intf.reg_cb.dn;
m.up = intf.reg_cb.up;
reg_bg_fifo.put(m);
`uvm_info(get_type_name(), $sformatf("monitored reg_i %8b ", m.reg_i), UVM_LOW)
end
endtask
endclass
class reg_agent extends uvm_agent;
reg_driver driver;
reg_monitor monitor;
reg_sequencer sequencer;
local virtual reg_inter intf;
`uvm_component_utils(reg_agent)
function new(string name = "reg_agent", uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
driver = reg_driver::type_id::create("driver",this);
monitor = reg_monitor::type_id::create("monitor",this);
sequencer = reg_sequencer::type_id::create("sequencer",this);
endfunction
function void set_interface(virtual reg_inter intf);
this.intf = intf;
driver.set_interface(intf);
monitor.set_interface(intf);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
driver.seq_item_port.connect(sequencer.seq_item_export);
this.set_interface(intf);
endfunction
endclass
class reg_test extends uvm_test;
reg_agent agent;
virtual reg_inter intf;
`uvm_component_utils(reg_test)
function new(string name = "reg_test", uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase (uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(virtual reg_inter)::get(this,"","intf",intf)) begin
`uvm_info("GETINTF","cannot get the handle of interface",UVM_LOW)
end
agent = reg_agent::type_id::create("agent",this);
endfunction
function void set_interface(virtual reg_inter intf);
this.intf = intf;
agent.set_interface(intf);
endfunction
function void connect_phase (uvm_phase phase);
super.connect_phase(phase);
this.set_interface(intf);
endfunction
task run_phase(uvm_phase phase);
reg_sequence seq;
phase.raise_objection(this);
seq = new ("seq");
seq.start(agent.sequencer);
phase.drop_objection(this);
endtask
endclass
endpackage
模擬結果