uvm白皮书练习_ch2_ch231_加入transaction

2.3 为验证平平台加入各种组件

uvm白皮书练习_ch2_ch231_加入transaction

代码部分

top_tb.sv

python 复制代码
`timescale 1ns / 1ps
`include "uvm_macros.svh"

import uvm_pkg::*;
/*只能现在*/

`include "my_if.sv"
`include "my_transaction.sv"
`include "my_driver.sv"


module top_tb();
/*time set*/
initial begin
    $display("start sim");
    #1.5ms;
    $finish;
end

/*fsdb*/
initial begin
    $display("fsdbDumpfilrs is start at %d",$time);
    $fsdbDumpfile("verilog.fsdb");
    $fsdbDumpvars(0);
end



reg             clk;
reg             rst_n;
reg     [7:0]   rxd;
reg             rx_dv;
wire    [7:0]   txd;
wire            tx_en;

my_if input_if  (clk,rst_n);
my_if output_if (clk,rst_n);

initial begin
    clk = 0;
    forever begin
        #100ns clk = ~ clk;
    end
end

initial begin
    rst_n =1'b0 ;
    #1us;
    rst_n =1'b1 ;
end


dut my_dut(.clk   (clk      ),
           .rst_n (rst_n    ),
           .rxd   (input_if.data      ),
           .rx_dv (input_if.valid    ),
           .txd   (output_if.data      ),
           .tx_en (output_if.valid    ) );

// initial begin
//     my_driver drv;
//     drv=new("drv",null);
//     drv.main_phase(null);
//     $finish;
// end
initial begin
    run_test("my_driver");
end

initial begin
    uvm_config_db#(virtual my_if)::set(null, "uvm_test_top", "vif", input_if);    
end



endmodule

my_if.sv

python 复制代码
`ifndef MY_IF__SV
`define MY_IF__SV
interface my_if(input clk,input rst_n);
    logic [7:0] data;
    logic       valid;
endinterface //my_if


`endif 

my_transaction.sv

python 复制代码
`ifndef MY_TRANSACTION__SV
`define MY_TRANSACTION__SV

class my_transaction extends uvm_sequence_item;

   rand bit[47:0] dmac;
   rand bit[47:0] smac;
   rand bit[15:0] ether_type;
   rand byte      pload[];
   rand bit[31:0] crc;

   constraint pload_cons{
      pload.size >= 46;
      pload.size <= 1500;
   }

   function bit[31:0] calc_crc();
      return 32'h0;
   endfunction

   function void post_randomize();
      crc = calc_crc;
   endfunction

   `uvm_object_utils(my_transaction)

   function new(string name = "my_transaction");
      super.new();
   endfunction
endclass
`endif

my_driver.sv

python 复制代码
// `ifndef MY_DRIVER__SV
// `define MY_DRIVER__SV
// class my_driver extends uvm_driver;
//    virtual my_if vif;
//    `uvm_component_utils(my_driver)    //没有后缀

//    function new(string name="my_driver",uvm_component parent = null);
//       super.new(name,parent);
//       `uvm_info("my_driver", "new is called", UVM_LOW)
//    endfunction //new()

//    virtual function void build_phase(uvm_phase phase);
//       super.build_phase(phase);
//       `uvm_info("my_driver", "build phase is caslled", UVM_LOW)
//       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 //my_driver extends uvm_driver

`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver;

   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);
   my_transaction tr ; /*先声明数组*/

   phase.raise_objection(this);    //有后缀,项目真起始点
   vif.data    <= 8'b0; 
   vif.valid   <= 1'b0;//先来一个初始化
   while(!vif.rst_n)
      @(posedge vif.clk);
   for(int i = 0; i < 2; i++)begin   //发两轮数据包
      tr = new("tr");
      // assert (tr.randomize() with {pload.size ==20;});//源码200,这里减到20,进行随机初始化
      assert (tr.randomize() with {pload.size ==50;});//源码200,这里减到20,进行随机初始化
      // else   error_process  //本来此处还有断言,源码处暂时没有
      drive_one_pkt(tr);
   end
   repeat(5) @(posedge vif.clk);//等待5个时钟
   // vif.valid <= 1'b0;
   phase.drop_objection(this);//运行结束
endtask //my_driver::main_phase

task my_driver::drive_one_pkt(my_transaction tr);
   bit [47:0] tmp_data;
   bit [7:0] data_q[$]; 

   //push dmac to data_q
   tmp_data = tr.dmac;
   for(int i = 0; i < 6; i++) begin
   data_q.push_back(tmp_data[7:0]);
   tmp_data = (tmp_data >> 8);
   end
   //push smac to data_q
   tmp_data = tr.smac;
   for(int i = 0; i < 6; i++) begin
   data_q.push_back(tmp_data[7:0]);
   tmp_data = (tmp_data >> 8);
   end
   //push ether_type to data_q
   tmp_data = tr.ether_type;
   for(int i = 0; i < 2; i++) begin
   data_q.push_back(tmp_data[7:0]);
   tmp_data = (tmp_data >> 8);
   end
   //push payload to data_q
   for(int i = 0; i < tr.pload.size; i++) begin
   data_q.push_back(tr.pload[i]);
   end
   //push crc to data_q
   tmp_data = tr.crc;
   for(int i = 0; i < 4; i++) begin
   data_q.push_back(tmp_data[7:0]);
   tmp_data = (tmp_data >> 8);
   end

   `uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
   repeat(3) @(posedge vif.clk);

   while(data_q.size() > 0) begin
      @(posedge vif.clk);
      vif.valid <= 1'b1;
      vif.data <= data_q.pop_front(); 
   end

   @(posedge vif.clk);
   vif.valid <= 1'b0;
   `uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask


`endif

// /*
// 注册
// main phase

// driver one pkt

// */

仿真结果

python 复制代码
UVM_INFO @ 0: reporter [RNTST] Running test my_driver...
UVM_INFO my_driver.sv(100) @ 1100000: uvm_test_top [my_driver] begin to drive one pkt
UVM_INFO my_driver.sv(111) @ 15500000: uvm_test_top [my_driver] end drive one pkt
UVM_INFO my_driver.sv(100) @ 15500000: uvm_test_top [my_driver] begin to drive one pkt
UVM_INFO my_driver.sv(111) @ 29900000: uvm_test_top [my_driver] end drive one pkt

--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :    5
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[RNTST]     1
[my_driver]     4

小结

python 复制代码
Error-[CNST-CIF] Constraints inconsistency failure
my_driver.sv, 57
  Constraints are inconsistent and cannot be solved.
  Please check the inconsistent constraints being printed above and rewrite 
  them.

约束超出预设范围,会导致失败

解决方法,使用范围内的数据值进行随机化

相关推荐
逍遥xiaoy3 个月前
SystemVerilog测试框架示例
systemverilog·uvm
谷公子的藏经阁4 个月前
设计模式在芯片验证中的应用——迭代器
设计模式·systemverilog·uvm·芯片验证·design pattern
小邦是名小ICer9 个月前
7.2 uvm_resource_db in UVM
uvm
一只迷茫的小狗9 个月前
UVM建造测试用例
uvm
中古传奇10 个月前
Pass cfg from cmd to test
uvm
mrbone111 年前
UVM-什么是UVM方法学
systemverilog·uvm·验证·方法学
EXCitrus1 年前
uvm中transaction的response和id的解读
学习·数字ic·uvm·ic验证
谷公子的藏经阁1 年前
UVM Heartbeat机制
systemverilog·heartbeat·看门狗·uvm·objection