电子表设计与验证(时钟频率选择模块验证)

电子表设计与验证(时钟频率选择模块验证)

利用UVM搭建简单验证平台

package div_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
 
class div_trans extends uvm_sequence_item;

rand int  div_n;
rand int  clk_out;
constraint divc{
                div_n inside {[10:50]};
               };

 `uvm_object_utils_begin(div_trans)
  `uvm_field_int(div_n,UVM_ALL_ON)
  `uvm_field_int(clk_out,UVM_ALL_ON)
 `uvm_object_utils_end
 
 function new(string name = "div_trans");
   super.new(name);
 endfunction
endclass

class div_driver extends uvm_driver #(div_trans);
  virtual div_inter intf;
 `uvm_component_utils(div_driver)

  function new(string name = "div_driver", uvm_component parent);
   super.new(name,parent);
  endfunction

  function void set_interface(virtual div_inter intf);
    this.intf = intf;
  endfunction

  task run_phase (uvm_phase phase);
    super.run_phase(phase);
    fork    
     this.do_driver();
     this.do_reset();
    join
  endtask

  task do_driver();
    div_trans req,rsp;
    forever begin
       repeat (100) @(posedge intf.clk)
       seq_item_port.get_next_item(req);
       this.write(req);
       void'($cast(rsp,req.clone()));
       rsp.set_sequence_id(req.get_sequence_id());
       seq_item_port.item_done(rsp);
    end
  endtask

  task write(input div_trans t);
    intf.div_cb.div_n <= t.div_n;
  endtask
  
  task do_reset();
    forever begin
      @(negedge intf.rstn);
      intf.div_cb.div_n <= 10;
    end
  endtask
endclass

class div_sequencer extends uvm_sequencer #(div_trans);
  `uvm_component_utils(div_sequencer)
  function new(string name = "div_sequencer", uvm_component parent);
    super.new(name,parent);
  endfunction
endclass

class div_sequence extends uvm_sequence #(div_trans);
  virtual div_inter intf;
  rand int div_n = -1;
  rand int clk_out = -1;

 `uvm_object_utils_begin(div_trans)
  `uvm_field_int(div_n,UVM_ALL_ON)
  `uvm_field_int(clk_out,UVM_ALL_ON)
 `uvm_object_utils_end

  function new (string name = "div_sequence");
    super.new(name);
  endfunction
 
  function void set_interface (virtual div_inter intf);
    this.intf = intf;
  endfunction

  task body();
     repeat (50) gen();
  endtask

  task gen();
    div_trans req,rsp;
    `uvm_do_with(req, {
                       local::div_n >= 0 -> div_n == local::div_n;
                       local::clk_out >= 0 -> clk_out == local::clk_out;
                      })
     get_response(rsp);
  endtask
endclass

typedef struct packed {
                    int  clk_out;
                      } div_mon;

class div_monitor extends uvm_monitor;
   local virtual div_inter intf;
  `uvm_component_utils(div_monitor)
  function new(string name = "div_monitor", uvm_component parent);
    super.new(name,parent);
  endfunction

  function void set_interface (virtual div_inter intf);
    this.intf = intf;
  endfunction

  task run_phase (uvm_phase phase);
    super.run_phase(phase);
    this.do_mon();
  endtask

  task do_mon();
    div_mon mon;
    forever begin
    @(posedge intf.clk);
    mon.clk_out = intf.div_cb.clk_out;
    `uvm_info(get_type_name(),$sformatf("monitored TIME hour 'h%8x ",mon.clk_out ),UVM_HIGH)
    end
  endtask

endclass

class div_agent extends uvm_agent;
 virtual div_inter intf;
 div_driver driver;
 div_monitor monitor;
 div_sequencer sequencer;

 `uvm_component_utils(div_agent)
 function new (string name = "div_agent", uvm_component parent);
   super.new(name,parent);
 endfunction

 function void build_phase (uvm_phase phase);
   super.build_phase(phase);
   driver = div_driver::type_id::create("driver",this);
   monitor = div_monitor::type_id::create("monitor",this);
   sequencer = div_sequencer::type_id::create("sequencer",this);
 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

 function void set_interface(virtual div_inter intf);
   this.intf = intf;
   driver.set_interface(intf);
   monitor.set_interface(intf);
 endfunction
endclass

class div_test extends uvm_test;
  div_agent agent;
  virtual div_inter intf;
  `uvm_component_utils(div_test)
  
  function new (string name = "div_test", uvm_component parent);
    super.new(name,parent);
  endfunction

  function void build_phase (uvm_phase phase);
    super.build_phase(phase);
    agent = div_agent::type_id::create("agent",this);
    if(!uvm_config_db#(virtual div_inter)::get(this,"","intf",intf)) begin 
      `uvm_fatal("GETINTF","cannot get intf handle from config DB")
    end
  endfunction

  function void set_interface(virtual div_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);
     div_sequence seq;
     phase.raise_objection(this);
     seq = new("seq");
     seq.start(agent.sequencer);
     phase.drop_objection(this);
  endtask
endclass
endpackage 

顶层模块

`timescale 1ns/1ps
import uvm_pkg::*;
`include "uvm_macros.svh"

interface div_inter(input clk, input rstn);
  logic clk_out;
  logic [31:0]div_n;
  clocking div_cb @(posedge clk);
    default input #1ns output #1ns;
    input clk_out;
    output div_n;
  endclocking
endinterface

module div_tb();
logic clk;
logic rstn;

  int_div dut(
              .clk     (clk)
             ,.rstn    (rstn)
             ,.clk_out (intf.clk_out)
             ,.div_n   (intf.div_n)
            );

initial begin
  clk <= 0;
  forever begin
    #5 clk <= ~clk;
  end
end

initial begin
  rstn <= 0;
  repeat (10) @(posedge clk)begin
    rstn <= 1;
  end
end

import div_pkg::*;

div_inter intf(.*);

initial begin
  uvm_config_db #(virtual div_inter)::set(uvm_root::get(),"uvm_test_top","intf",intf);
  run_test("div_test");
end
endmodule

仿真结果在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值