• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

UVM中uvm_driver的写法

书本上的一般写法:

`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver#(my_transaction);
   virtual my_if vif;
   `uvm_component_utils(my_driver)
   function new(string name = "my_driver", uvm_component parent = null);
      super.new(name, parent);
   endfunction
   virtual function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
         `uvm_fatal("my_driver", "virtual interface must be set for vif!!!")
   endfunction
   extern task main_phase(uvm_phase phase);
   extern task drive_one_pkt(my_transaction tr);
endclass
task my_driver::main_phase(uvm_phase phase);
   vif.data <= 8'b0;
   vif.valid <= 1'b0;
   while(!vif.rst_n)                    //
      @(posedge vif.clk);               //
   while(1) begin                       //
      seq_item_port.get_next_item(req); //
      drive_one_pkt(req);               //
      seq_item_port.item_done();        //
   end
endtask
task my_driver::drive_one_pkt(my_transaction tr);  //
   byte unsigned     data_q[];
   int  data_size;
   data_size = tr.pack_bytes(data_q) / 8; 
   `uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
   repeat(3) @(posedge vif.clk);
   for ( int i = 0; i < data_size; i++ ) begin
      @(posedge vif.clk);
      vif.valid <= 1'b1;
      vif.data <= data_q[i]; 
   end
   @(posedge vif.clk);
   vif.valid <= 1'b0;
   `uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask
`endif

课本上的一般写法:有response

`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver#(my_transaction);
   virtual my_if vif;
   `uvm_component_utils(my_driver)
   function new(string name = "my_driver", uvm_component parent = null);
      super.new(name, parent);
   endfunction
   virtual function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
         `uvm_fatal("my_driver", "virtual interface must be set for vif!!!")
   endfunction
   extern task main_phase(uvm_phase phase);
   extern task drive_one_pkt(my_transaction tr);
endclass
task my_driver::main_phase(uvm_phase phase);
   vif.data <= 8'b0;
   vif.valid <= 1'b0;
   while(!vif.rst_n)                            //
      @(posedge vif.clk);                       //
   while(1) begin
      seq_item_port.get_next_item(req);         //
      drive_one_pkt(req);                       //
      rsp = new("rsp");                         //
      rsp.set_id_info(req);                     //
      seq_item_port.put_response(rsp);          //
      seq_item_port.item_done();                //
   end
  或者
  while(1) begin
    seq_item_port.get_next_item(req);            //
    drive_one_pkt(req);                          //
    rsp = new("rsp");                            //
    rsp.set_id_info(req);                        //
    seq_item_port.item_done(rsp);                //
  end
endtask  
task my_driver::drive_one_pkt(my_transaction tr);  //
   byte unsigned     data_q[];
   int  data_size;
   data_size = tr.pack_bytes(data_q) / 8; 
   //`uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
   repeat(3) @(posedge vif.clk);
   for ( int i = 0; i < data_size; i++ ) begin
      @(posedge vif.clk);
      vif.valid <= 1'b1;
      vif.data <= data_q[i]; 
   end
   @(posedge vif.clk);
   vif.valid <= 1'b0;
   //`uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask
`endif

其他driver的写法:

  class chnl_driver extends uvm_driver #(chnl_trans);
    local virtual chnl_intf intf;
    `uvm_component_utils(chnl_driver)
    function new (string name = "chnl_driver", uvm_component parent);
      super.new(name, parent);
    endfunction
    function void set_interface(virtual chnl_intf intf);
      if(intf == null)
        $error("interface handle is NULL, please check if target interface has been intantiated");
      else
        this.intf = intf;
    endfunction
    task run_phase(uvm_phase phase);  
      fork                //
       this.do_drive();   //
       this.do_reset();   //
      join                //
    endtask
    task do_reset();
      forever begin
        @(negedge intf.rstn);
        intf.ch_valid <= 0;
        intf.ch_data <= 0;
        intf.ch_data_p <= 0;
      end
    endtask
    task do_drive();          //
      chnl_trans req, rsp;
      @(posedge intf.rstn);
      forever begin
        seq_item_port.get_next_item(req);
        this.chnl_write(req);
        void'($cast(rsp, req.clone()));
        rsp.rsp = 1;
        rsp.set_sequence_id(req.get_sequence_id());
        seq_item_port.item_done(rsp);
      end
    endtask
    task chnl_write(input chnl_trans t);
      foreach(t.data[i]) begin
        @(posedge intf.clk);
        intf.drv_ck.ch_valid <= 1;
        intf.drv_ck.ch_data <= t.data[i];
        intf.drv_ck.ch_data_p <= get_parity(t.data[i]);
        @(negedge intf.clk);
        wait(intf.ch_wait === 'b0);
        `uvm_info(get_type_name(), $sformatf("sent data 'h%8x", t.data[i]), UVM_HIGH)
        repeat(t.data_nidles) chnl_idle();
      end
      repeat(t.pkt_nidles) chnl_idle();
    endtask
    task chnl_idle();
      @(posedge intf.clk);
      intf.drv_ck.ch_valid <= 0;
      intf.drv_ck.ch_data <= 0;
      intf.drv_ck.ch_data_p <= 0;
    endtask
    function get_parity(bit[31:0] data);
      return ^data;
    endfunction
  endclass: chnl_driver

posted on 2022-09-08 22:06  SOC验证工程师  阅读(1872)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3