• 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    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 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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
    
    // */
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124

    仿真结果

    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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    小结

    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.
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

  • 相关阅读:
    朋友问我,你都30岁了学编程来得及吗
    类初始化的顺序
    Linux系统编程
    设计模式—创建型模式之单例模式
    关于ETL的两种架构(ETL架构和ELT架构)
    如何实现三维虚拟数字人直播1:全身姿态预估
    内网穿透:针对小白的VSCode+云服务器+本地Ubuntu搭建GPU云服务器
    ubuntu开机自启动并且崩溃自启动程序/服务
    java虚拟机堆空间
    Actipro Editors for WPF高级数据输入组件
  • 原文地址:https://blog.csdn.net/qq_36683398/article/details/134534969