Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
System verilog 模拟永远不会结束_System Verilog_Uvm - Fatal编程技术网

System verilog 模拟永远不会结束

System verilog 模拟永远不会结束,system-verilog,uvm,System Verilog,Uvm,我正在尝试在SystemVerilog中学习UVM。我理解UVM的理念,但我很难写出一个工作案例。 我想写一个apb测试台。它编译并运行,这对我来说已经是一个胜利,但是监视器接收到的事务具有零值并且是不间断的 我一直在寻找关于这个问题的信息,得出的结论是,这个问题与提出/放弃异议有关 下面是测试类代码,包含以下调用 `include "uvm_macros.svh" import uvm_pkg::*; class apb_test extends uvm_test; `uvm_comp

我正在尝试在SystemVerilog中学习UVM。我理解UVM的理念,但我很难写出一个工作案例。
我想写一个apb测试台。它编译并运行,这对我来说已经是一个胜利,但是监视器接收到的事务具有零值并且是不间断的

我一直在寻找关于这个问题的信息,得出的结论是,这个问题与提出/放弃异议有关

下面是测试类代码,包含以下调用

`include "uvm_macros.svh"
import uvm_pkg::*;
class apb_test extends uvm_test;
    `uvm_component_utils(apb_test);
    apb_env env;
    function new(string name, uvm_component parent);
        super.new(name,parent);
    endfunction: new

    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        begin
            apb_configuration apb_cfg;
            apb_cfg = new;
            assert(apb_cfg.randomize());
            uvm_config_db#(apb_configuration)::set(.cntxt(this), .inst_name("*"), .field_name("config"), .value(apb_cfg) );
            env = apb_env::type_id::create(.name("env"), .parent(this));
        end
    endfunction: build_phase

    task run_phase(uvm_phase phase);
        apb_sequence apb_seq;
        phase.raise_objection(.obj(this));
        apb_seq = apb_sequence::type_id::create(.name("apb_seq"));
        //assert(apb_seq.randomize());
        `uvm_info("apb_test", {"\n",apb_seq.sprint()}, UVM_LOW)
        apb_seq.start(env.agent.apb_seq);
        #10ns;
        phase.drop_objection(.obj(this));
    endtask: run_phase
endclass: apb_test
整个项目:

//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 30.04.2019 17:12:58
// Design Name:
// Module Name: apb_interface
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////

`include "uvm_macros.svh"
interface apb_if #(  ADDR_WIDTH = 3
            ,  SEL_WIDTH = 2
            ,WRITE_WIDTH = 32
            , READ_WIDTH = WRITE_WIDTH
            )
            (input bit clk, reset_n);

    localparam STRB_WIDTH = WRITE_WIDTH%8? (WRITE_WIDTH/8)+1 : WRITE_WIDTH/8;


    logic [ADDR_WIDTH:0]    addr;
    logic [ 2:0]            prot;
    logic [SEL_WIDTH-1:0]   sel;
    logic                   enable;
    logic                   write;
    logic [WRITE_WIDTH-1:0] wdata;
    logic [STRB_WIDTH-1:0]  strb;
    logic                   ready;
    logic [READ_WIDTH-1:0]  rdata;
    logic                   slv_err;

    clocking master_cb @ (posedge clk);
        default input #1ns output #1ns;
        output addr, prot, sel, enable, write, wdata, strb;
        input ready, rdata, slv_err;
    endclocking: master_cb

    clocking slave_cb @(posedge clk);
        default input #1ns output #1ns;
        input addr, prot, sel, enable, write, wdata, strb;
        output ready, rdata, slv_err;
    endclocking: slave_cb

    clocking monitor_cb @(posedge clk);
        default input #1ns output #1ns;
        input addr, prot, sel, enable, write, wdata, strb, ready, rdata, slv_err;
    endclocking: monitor_cb

    modport master_mp (input clk, reset_n, ready, rdata, slv_err, output addr, prot, sel, enable, write, wdata, strb);
    modport slave_mp  (input clk, reset_n, addr, prot, sel, enable, write, wdata, strb, output ready, rdata, slv_err);
    modport master_sync_mp (clocking master_cb);
    modport slave_sync_mp  (clocking slave_cb );

endinterface: apb_if

package apb_pkg;
    import uvm_pkg::*;
    class apb_configuration extends uvm_object;
       `uvm_object_utils( apb_configuration )

       function new( string name = "" );
          super.new( name );
       endfunction: new
    endclass: apb_configuration
    class apb_seq_item #(  ADDR_WIDTH = 3
                ,  SEL_WIDTH = 2
                ,WRITE_WIDTH = 32
                , READ_WIDTH = WRITE_WIDTH
                ) extends uvm_sequence_item;
        localparam STRB_WIDTH = WRITE_WIDTH%8? (WRITE_WIDTH/8)+1 : WRITE_WIDTH/8;
        `uvm_object_utils(apb_seq_item)

        // Control information
        rand bit [31:0]            addr;
        rand bit [ 2:0]            prot;
        rand bit [SEL_WIDTH-1:0]   sel;
        rand bit                   write;
        rand bit                   ready;
        // Payload information
        rand bit [WRITE_WIDTH-1:0] wdata;
        rand bit [STRB_WIDTH-1:0]  strb;
        // Analysis information
        rand bit [READ_WIDTH-1:0]  rdata;
        rand bit                   slv_err;
        constraint read_constr {
            write == 0 -> strb == 0;
        }
        function new(string name = "apb_seq_item");
            super.new(name);
        endfunction: new

        virtual function void do_copy(uvm_object rhs);
            apb_seq_item rhs_;
            if(!$cast(rhs_, rhs)) begin
              uvm_report_error("do_copy:", "Cast failed");
              return;
            end
            super.do_copy(rhs); // Chain the copy with parent classes
            addr    = rhs_.addr;
            prot    = rhs_.prot;
            sel     = rhs_.sel;
            write   = rhs_.write;
            ready   = rhs_.ready;
            wdata   = rhs_.wdata;
            strb    = rhs_.strb;
            rdata   = rhs_.rdata;
            slv_err = rhs_.slv_err;
        endfunction: do_copy

        virtual function bit do_compare(uvm_object rhs, uvm_comparer comparer);
            apb_seq_item rhs_;
            // If the cast fails, comparison has also failed
             // A check for null is not needed because that is done in the compare()
             // function which calls do_compare()
             if(!$cast(rhs_, rhs)) begin
               return 0;
             end
             return( super.do_compare(rhs,comparer) &&
                    (addr   = rhs_.addr)    &&
                    (prot   = rhs_.prot)    &&
                    (sel    = rhs_.sel)     &&
                    (write  = rhs_.write)   &&
                    (ready  = rhs_.ready)   &&
                    (wdata  = rhs_.wdata)   &&
                    (strb   = rhs_.strb)    &&
                    (rdata  = rhs_.rdata)   &&
                    (slv_err= rhs_.slv_err));
        endfunction: do_compare

        virtual function string convert2string();
            string s;

            s = super.convert2string();
            // Note the use of \t (tab) and \n (newline) to format the data in columns
            // The enumerated op_code types .name() method returns a string corresponding to its value
            s = {s, $psprintf("\naddr\t\t: %0h",addr)};
            s = {s, $psprintf("\nprot\t\t: %0b",prot)};
            s = {s, $psprintf("\nsel\t\t: %0b",sel)};
            s = {s, $psprintf("\nwrite\t\t: %0b",write)};
            s = {s, $psprintf("\nready\t\t: %0b",ready)};
            s = {s, $psprintf("\nwdata\t\t: %0h",wdata)};
            s = {s, $psprintf("\nstrb\t\t: %0b",strb)};
            s = {s, $psprintf("\nrdata\t\t: %0h",rdata)};
            s = {s, $psprintf("\nslv_err\t: %0b",slv_err)};
            return s;
        endfunction: convert2string

        virtual function void do_print(uvm_printer printer);
            $display(convert2string());
        endfunction: do_print

        // This implementation is simulator specific.
        // In order to get transaction viewing to work with Questa you need to
        // Set the recording_detail config item to UVM_FULL:
        // set_config_int("*", "recording_detail", UVM_FULL);
        virtual function void do_record(uvm_recorder recorder);
            super.do_record(recorder); // To record any inherited data members
            `uvm_record_field("addr", addr)
            `uvm_record_field("prot", prot)
            `uvm_record_field("sel", sel)
            `uvm_record_field("write", write)
            `uvm_record_field("ready", ready)
            `uvm_record_field("wdata", wdata)
            `uvm_record_field("strb", strb)
            `uvm_record_field("rdata", rdata)
            `uvm_record_field("slv_err", slv_err)
        endfunction: do_record

        virtual function void do_pack(uvm_packer packer);
            super.do_pack(packer);
            `uvm_pack_int(addr);
            `uvm_pack_int(prot);
            `uvm_pack_int(sel);
            `uvm_pack_int(write);
            `uvm_pack_int(ready);
            `uvm_pack_int(wdata);
            `uvm_pack_int(strb);
            `uvm_pack_int(rdata);
            `uvm_pack_int(slv_err);
        endfunction: do_pack

        virtual function void do_unpack(uvm_packer packer);
            super.do_unpack(packer);
            `uvm_unpack_int(addr);
            `uvm_unpack_int(prot);
            `uvm_unpack_int(sel);
            `uvm_unpack_int(write);
            `uvm_unpack_int(ready);
            `uvm_unpack_int(wdata);
            `uvm_unpack_int(strb);
            `uvm_unpack_int(rdata);
            `uvm_unpack_int(slv_err);
        endfunction: do_unpack

    endclass: apb_seq_item

    class apb_sequence extends uvm_sequence#(apb_seq_item);
        `uvm_object_utils(apb_sequence)

        function new(string name = "");
            super.new(name);
        endfunction: new

        task body();
            apb_seq_item trans;
            repeat(2) begin
                trans = apb_seq_item#()::type_id::create("ap_it");
                start_item(trans);
                assert(req.randomize());
                finish_item(trans);
            end
        endtask: body
    endclass: apb_sequence

    class apb_sequencer extends uvm_sequencer#(apb_seq_item);
        `uvm_component_utils(apb_sequencer)
        function new(string name, uvm_component parent = null);
            super.new(name, parent);
        endfunction: new
    endclass: apb_sequencer

    class apb_driver extends uvm_driver#(apb_seq_item);
        `uvm_component_utils(apb_driver)
        virtual apb_if apb_vi;
        function new (string name, uvm_component parent);
            super.new(name, parent);
        endfunction: new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            void'(uvm_resource_db#(virtual apb_if)::read_by_name
            (.scope("ifs"), .name("apb_if"), .val(apb_vi) ) );
        endfunction: build_phase

        task run_phase(uvm_phase phase);
            apb_seq_item trans;
            //super.run_phase(phase);
            apb_vi.master_cb.sel    <= 0;
            apb_vi.master_cb.enable <= 1'b0;
            forever begin
                seq_item_port.get_next_item(trans);
                uvm_report_info("APB_DRIVER ", $psprintf("Got Transaction %s",trans.convert2string()));
                @apb_vi.master_cb;
                apb_vi.master_cb.addr   <= trans.addr;
                apb_vi.master_cb.sel    <= trans.sel;
                apb_vi.master_cb.prot   <= trans.prot;
                if(trans.write)begin
                    apb_vi.master_cb.write  <= 1'b1;
                    //apb_vi.master_cb.wdata  <= trans.wdata;
                    apb_vi.master_cb.strb   <= trans.strb;
                    @apb_vi.master_cb;
                    apb_vi.master_cb.enable <= 1'b1;
                    // while(!apb_vi.master_cb.ready)begin
                    //     @apb_vi.master_cb;
                    // end
                end
                else begin
                    apb_vi.master_cb.write  <= 1'b0;
                    @apb_vi.master_cb;
                    apb_vi.master_cb.enable <= 1'b1;
                    // while(!apb_vi.master_cb.ready)begin
                    //     @apb_vi.master_cb;
                    // end
                    trans.rdata     <= apb_vi.master_cb.rdata;
                    trans.slv_err   <= apb_vi.master_cb.slv_err;
                end
                apb_vi.master_cb.sel    <= 0;
                apb_vi.master_cb.enable <= 1'b0;
                seq_item_port.item_done();
            end
        endtask: run_phase
    endclass: apb_driver
    class apb_monitor extends uvm_monitor;
        `uvm_component_utils(apb_monitor);
        uvm_analysis_port#(apb_seq_item) apb_ap;
        virtual apb_if apb_vi;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction: new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            void'(uvm_resource_db#(virtual apb_if)::read_by_name(.scope("ifs"), .name("apb_if"), .val(apb_vi) ) );
            apb_ap = new(.name("apb_ap"), .parent(this));
        endfunction: build_phase

        task run_phase(uvm_phase phase);
            forever begin
                apb_seq_item trans;
                trans = apb_seq_item#()::type_id::create(.name("trans"));
                trans.addr      <= apb_vi.monitor_cb.addr;
                trans.prot      <= apb_vi.monitor_cb.prot;
                trans.sel       <= apb_vi.monitor_cb.sel;
                trans.write     <= apb_vi.monitor_cb.write;
                trans.wdata     <= apb_vi.monitor_cb.wdata;
                trans.strb      <= apb_vi.monitor_cb.strb;
                trans.rdata     <= apb_vi.monitor_cb.rdata;
                trans.slv_err   <= apb_vi.monitor_cb.slv_err;
                uvm_report_info("APB_MONITOR", $psprintf("Got Transaction %s", trans.convert2string()));
                apb_ap.write(trans);
            end
        endtask: run_phase
    endclass: apb_monitor
    class apb_agent extends uvm_agent;
        `uvm_component_utils(apb_agent)
        uvm_analysis_port#(apb_seq_item) apb_ap;

        apb_sequencer   apb_seq;
        apb_driver      apb_drv;
        apb_monitor     apb_mon;

        function new(string name, uvm_component parent);
            super.new(name,parent);
        endfunction: new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);

            apb_ap  = new(.name("apb_ap"), .parent(this));
            apb_seq = apb_sequencer ::type_id::create(.name("apb_seq"), .parent(this) );
            apb_drv = apb_driver    ::type_id::create(.name("apb_drv"), .parent(this) );
            apb_mon = apb_monitor   ::type_id::create(.name("apb_mon"), .parent(this) );
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            apb_drv.seq_item_port.connect(apb_seq.seq_item_export);
            apb_mon.apb_ap.connect(apb_ap);
        endfunction: connect_phase
    endclass: apb_agent
    class apb_fc_subs#(  ADDR_WIDTH = 3
                ,  SEL_WIDTH = 2
                ,WRITE_WIDTH = 32
                , READ_WIDTH = WRITE_WIDTH
                ) extends uvm_subscriber#(apb_seq_item);
        `uvm_component_utils(apb_fc_subs);
        apb_seq_item trans;
        covergroup apb_cg;
            address: coverpoint trans.addr {
                bins low    = {0, 1 << ADDR_WIDTH/4 - 1};
                bins med    = {1 << ADDR_WIDTH/4, 1 << ADDR_WIDTH/2 - 1};
                bins high   = {1 << ADDR_WIDTH/2, 1 << ADDR_WIDTH - 1};
            }
            select: coverpoint trans.sel;
            prot:   coverpoint trans.prot;
            wdata:  coverpoint trans.wdata;// iff(write);
            strb:   coverpoint trans.strb;// iff(write);
            rw:  coverpoint trans.write{
                bins read   = {0};
                bins write  = {1};
            }
        endgroup: apb_cg

        function new(string name, uvm_component parent);
            super.new(name,parent);
            apb_cg = new();
        endfunction: new

        function void write(apb_seq_item t);
            trans = t;
            apb_cg.sample();
        endfunction: write
    endclass: apb_fc_subs

    typedef class apb_scoreboard;
    class apb_sb_subs extends uvm_subscriber#(apb_seq_item);
        `uvm_component_utils(apb_sb_subs)

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction: new

        function void write(apb_seq_item t);
            apb_scoreboard apb_sb;
            $cast(apb_sb, m_parent);
            apb_sb.apb_check(t);
        endfunction: write
    endclass: apb_sb_subs
    class apb_scoreboard extends uvm_scoreboard;
        `uvm_component_utils(apb_scoreboard)

        uvm_analysis_export#(apb_seq_item) apb_analysis_export;

        local apb_sb_subs sb_sub;

        function new(string name, uvm_component parent);
            super.new(name,parent);
        endfunction: new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            apb_analysis_export = new(.name("apb_analysis_export"), .parent(this));
            sb_sub = apb_sb_subs::type_id::create(.name("sb_sub"), .parent(this));
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            apb_analysis_export.connect(sb_sub.analysis_export);
        endfunction: connect_phase

        virtual function void apb_check(apb_seq_item trans);
            `uvm_info("SCOREBOARD","Dummy check",UVM_LOW);
        endfunction: apb_check
    endclass: apb_scoreboard
    class apb_env extends uvm_env;
        `uvm_component_utils(apb_env)

        apb_agent       agent;
        apb_fc_subs     fc_sub;
        apb_scoreboard  sco;

        function new(string name, uvm_component parent);
            super.new(name,parent);
        endfunction: new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            agent   = apb_agent     ::type_id::create(.name("agent")    , .parent(this));
            fc_sub  = apb_fc_subs#()::type_id::create(.name("fc_sub")   , .parent(this));
            sco     = apb_scoreboard::type_id::create(.name("sco")      , .parent(this));
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            agent.apb_ap.connect(fc_sub.analysis_export);
            agent.apb_ap.connect(sco.apb_analysis_export);
        endfunction: connect_phase
    endclass: apb_env
    class apb_test extends uvm_test;
        `uvm_component_utils(apb_test);
        apb_env env;
        function new(string name, uvm_component parent);
            super.new(name,parent);
        endfunction: new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            begin
                apb_configuration apb_cfg;
                apb_cfg = new;
                assert(apb_cfg.randomize());
                uvm_config_db#(apb_configuration)::set(.cntxt(this), .inst_name("*"), .field_name("config"), .value(apb_cfg) );
                env = apb_env::type_id::create(.name("env"), .parent(this));
            end
        endfunction: build_phase

        task run_phase(uvm_phase phase);
            apb_sequence apb_seq;
            phase.raise_objection(.obj(this));
            apb_seq = apb_sequence::type_id::create(.name("apb_seq"));
            //assert(apb_seq.randomize());
            `uvm_info("apb_test", {"\n",apb_seq.sprint()}, UVM_LOW)
            apb_seq.start(env.agent.apb_seq);
            #10ns;
            phase.drop_objection(.obj(this));
        endtask: run_phase
    endclass: apb_test
endpackage: apb_pkg
module apb_memory #( parameter ADDR_WIDTH
                    ,parameter SEL_WIDTH
                    ,parameter WRITE_WIDTH
                    ,parameter READ_WIDTH
                   )
                   (apb_if.slave_mp apb_intf);
    localparam IDLE = 2'd0;
    localparam WRITE= 2'd1;
    localparam READ = 2'd2;

    bit [1:0] state;

    bit [ADDR_WIDTH-1:0]addr;
    bit [WRITE_WIDTH-1:0]data[1<<ADDR_WIDTH];
    initial begin
        state = 0;
    end

    always@(apb_intf.clk) begin
    if(!apb_intf.reset_n) state <= IDLE;
    else
        case(state)
        IDLE:   if(apb_intf.sel != 0) begin
                    if(apb_intf.write)begin
                        state <= WRITE;
                    end
                    else begin
                        state <= READ;
                        apb_intf.rdata <= data[apb_intf.addr];
                    end
                    apb_intf.ready <= 1;
                end
        WRITE:  if(apb_intf.enable) begin
                    data[apb_intf.addr] <= apb_intf.wdata;
                    apb_intf.ready <= 0;
                    state <= IDLE;
                end
        READ:   if(apb_intf.enable) begin
                    apb_intf.slv_err <= 0;
                    state <= IDLE;
                end
        default: state <= IDLE;
        endcase
    end
endmodule
module test_bench;
    import uvm_pkg::*;
    import apb_pkg::*;
    parameter ADDR_WIDTH    = 3;
    parameter SEL_WIDTH     = 2;
    parameter WRITE_WIDTH   = 32;
    parameter READ_WIDTH    = WRITE_WIDTH;
    bit clk,reset;
    apb_if #(  ADDR_WIDTH
                ,  SEL_WIDTH
                ,WRITE_WIDTH
                , READ_WIDTH
                )apb_intf(clk,~reset);
    apb_memory #(  ADDR_WIDTH
                ,  SEL_WIDTH
                ,WRITE_WIDTH
                , READ_WIDTH
                )DUT(apb_intf);
    initial begin
        clk = 0;
       #5ns ;
       forever #5ns clk = ! clk;
    end

    initial begin
       uvm_resource_db#( virtual apb_if )::set
     ( .scope( "ifs" ), .name( "apb_if" ), .val( apb_intf ) );
       run_test();
    end
endmodule
//////////////////////////////////////////////////////////////////////////////////
//公司:
//工程师:
//
//创建日期:30.04.2019 17:12:58
//设计名称:
//模块名称:apb_接口
//项目名称:
//目标设备:
//工具版本:
//说明:
//
//依赖项:
//
//修订:
//版本0.01-已创建文件
//补充意见:
//
//////////////////////////////////////////////////////////////////////////////////
`包括“uvm_macros.svh”
接口apb_if#(地址宽度=3
,选择宽度=2
,写入宽度=32
,读取宽度=写入宽度
)
(输入位时钟,复位);
localparam STRB_WIDTH=写入宽度%8?(写入宽度/8)+1:写入宽度/8;
逻辑[ADDR\u WIDTH:0]ADDR;
逻辑[2:0]保护;
逻辑[SEL_WIDTH-1:0]SEL;
逻辑使能;
逻辑写入;
逻辑[WRITE_WIDTH-1:0]wdata;
逻辑[STRB_WIDTH-1:0]STRB;
逻辑就绪;
逻辑[READ_WIDTH-1:0]rdata;
逻辑逻辑错误;
时钟主机(posedge时钟);
默认输入#1ns输出#1ns;
输出地址、保护、选择、启用、写入、wdata、strb;
输入就绪、rdata、slv_错误;
结束计时:master_cb
时钟从机(posedge时钟);
默认输入#1ns输出#1ns;
输入地址、保护、选择、启用、写入、wdata、strb;
输出就绪、rdata、slv_err;
结束计时:从机\u cb
时钟监视器(posedge时钟);
默认输入#1ns输出#1ns;
输入地址、保护、选择、启用、写入、wdata、strb、就绪、rdata、slv_err;
结束计时:监视器\u cb
modport master(输入时钟、复位、就绪、rdata、slv错误、输出地址、保护、选择、启用、写入、wdata、strb);
modport从机mp(输入时钟、复位、地址、保护、选择、启用、写入、wdata、strb、输出就绪、rdata、slv错误);
modport主控器同步器mp(时钟主控器cb);
modport从站同步(时钟从站cb);
endinterface:apb_if
成套apb_包装;
进口uvm_包装::*;
类apb_配置扩展了uvm_对象;
`uvm_对象_utils(apb_配置)
新函数(字符串名称=”);
超级新(名称);
端功能:新
endclass:apb_配置
分类apb顺序项目(地址宽度=3)
,选择宽度=2
,写入宽度=32
,读取宽度=写入宽度
)扩展uvm_序列_项;
localparam STRB_WIDTH=写入宽度%8?(写入宽度/8)+1:写入宽度/8;
`uvm对象实用程序(apb顺序项目)
//控制信息
随机位[31:0]地址;
随机位[2:0]保护;
随机位[SEL_WIDTH-1:0]SEL;
随机位写入;
兰德比特就绪;
//有效载荷信息
随机位[WRITE_WIDTH-1:0]wdata;
随机位[STRB_WIDTH-1:0]STRB;
//分析信息
随机位[READ_WIDTH-1:0]rdata;
兰德比特slv_错误;
约束读取构造{
写入==0->strb==0;
}
新函数(string name=“apb_seq_item”);
超级新(名称);
端功能:新
虚拟函数void do_copy(uvm_对象rhs);
apb顺序项目rhs;
如果(!$cast(rhs,rhs))开始
uvm_报告_错误(“do_复制:”,“强制转换失败”);
返回;
结束
超级。复制(右);//将副本链接到父类
地址=rhs_uu.addr;
防护装置=右侧防护装置;
sel=rhs_u2;.sel;
write=rhs_u2;write;
就绪=rhs_u2;就绪;
wdata=rhs_uuu.wdata;
strb=rhs_.strb;
rdata=rhs_uu.rdata;
slv_err=rhs_.slv_err;
endfunction:复制吗
虚拟功能位进行比较(uvm_对象rhs、uvm_比较器);
apb顺序项目rhs;
//如果强制转换失败,比较也会失败
//不需要检查null,因为这是在compare()中完成的
//调用do_compare()的函数
如果(!$cast(rhs,rhs))开始
返回0;
结束
返回(super.do_compare(rhs,comparer)&&
(地址=右侧地址)&&
(保护=右侧保护)&&
(sel=rhs_uu.sel)&&
(write=rhs_u2;write)&&
(准备就绪=右侧准备就绪)&&
(wdata=rhs_uUdata)&&
(strb=rhs_uu.strb)&&
(rdata=rhs_uu.rdata)&&
(slv_err=rhs_.slv_err));
endfunction:do_比较
虚拟函数字符串convert2string();
字符串s;
s=super.convert2string();
//请注意使用\t(制表符)和\n(换行符)来格式化列中的数据
//枚举的op_代码类型.name()方法返回与其值对应的字符串
s={s$psprintf(“\naddr\t\t:%0h”,addr)};
s={s,$psprintf(“\nprot\t\t:%0b”,prot)};
s={s,$psprintf(“\nsel\t\t:%0b”,sel)};
s={s$psprintf(“\nwrite\t\t:%0b”,write)};
s={s$psprintf(“\nready\t\t:%0b”,就绪)};
s={s$psprintf(“\nwdata\t\t:%0h”,wdata)};
s