uvm白皮书练习_ch2_ch231_加入transaction

2.3 为验证平平台加入各种组件
uvm白皮书练习_ch2_ch231_加入transaction

代码部分

top_tb.sv

`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

`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

`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

// `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

// */


仿真结果

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


小结

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.

约束超出预设范围,会导致失败
解决方法,使用范围内的数据值进行随机化

你可能感兴趣的:(uvm,笔记,UVM)