1. 程式人生 > 其它 >電子錶設計與驗證(暫存器模組驗證)

電子錶設計與驗證(暫存器模組驗證)

技術標籤:筆記verilogsystemverilog

暫存器模組驗證

利用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

模擬結果在這裡插入圖片描述