UVM验证平台搭建四:spi env

10 篇文章 25 订阅


一、spi_cfg

`ifndef SPI_CFG_SVH
`define SPI_CFG_SVH

package spi_cfg_pkg;

    import uvm_pkg::*;
    `include "uvm_macros.svh"
class spi_cfg extends uvm_object;

    `uvm_object_utils(spi_cfg)
    
    //spi cr1
    bit cpha;
    bit cpol;
    bit mstr;
    bit [2:0] br;
    bit spe;
    bit lsbfirst;
    bit ssi;
    bit ssm;
    bit rxonly;
    bit dff;
    bit crcnext;
    bit crcen;
    bit bidioe;
    bit bidimode;
    
    .......
    
    function new(string name = "spi_cfg");
        super.new(name);
    endfunction

endclass: spi_cfg

endpackage: spi_cfg_pkg
`endif //SPI_CFG_SVH

二、spi interface

interface spi_if(input spi_clk, input spi_rstn);

    logic spi_miso_pin;
    logic spi_miso_pout;
    logic spi_mosi_pin;
    logic spi_mosi_pout;
    logic spi_nss_pin;
    logic spi_nss_pout;
    logic spi_sck_pin;
    logic spi_sck_pout;
    logic spi_nss_poe;
    logic spi_sck_poe;
    logic spi_mosi_poe;
    logic spi_miso_poe;
    
endinterface

三、spi scoreboard

`ifnef  SPI_SCOREBOARD_SVH
`define SPI_SCOREBOARD_SVH

`include "spi_work_mode_define.sv"
class spi_scoreboard extends uvm_scoreboard;
    
    `uvm_component_utils(spi_scoreboard)
    
    process processes[string];
    spi_cfg cfg;
    virtual spi_if sif;
    
    uvm_blocking_get_port #(apb_trans) apb_tdr_port;
    uvm_blocking_get_port #(apb_trans) apb_rdr_port;
    
    uvm_blocking_get_port #(spi_slv_transaction) vip_slv_port;
    uvm_blocking_get_port #(spi_slv_transaction) vip_mst_port;
    
    apb_trans apb_tdr_queue[$], apb_rdr_queue[$];
    spi_slv_transaction vip_slv_queue[$];
    spi_mst_transaction vip_mst_queue[$];
    
    function new(string name = "spi_scoreboard", uvm_compoent parent);
        supre.new(name,parent);
    endfunction
    
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        
        if(!uvm_config_db#(virtual spi_if)::get(this,"","sif",sif)) begin
            `uvm_fatal("spi_scoreboard","No Interface specified for this scoreboard!")
        end
        
        if(!uvm_config_db#(spi_cfg)::get(this,"","sif",sif)) begin
            `uvm_fatal("spi_scoreboard","No specified for this spi_sys_cofig!")
        end
        
        apb_tdr_port = new("apb_tdr_port",this);
        apb_rdr_port = new("apb_rdr_port",this);
        vip_slv_port = new("vip_slv_port",this);
        vip_mst_port = new("vip_mst_port",this);
        
    endfunction
    
    extern virtual task run_phase(uvm_phase phase);
    extern virtual function void compare_fun(input [15:0] tdr_data,input [15:0] rdr_data, input [15:0] vip_txdata, input [15:0] vip_rxdata, output dut_compare_tx, output dut_compare_rx, input [3:0] pstrb);  
    extern virtual function void compare_fun_rcv_only(input [15:0] tdr_data,input [15:0] rdr_data, input [15:0] vip_txdata, input [15:0] vip_rxdata, output dut_compare_tx, output dut_compare_rx);  
    extern virtual task dut_rdr_save(apb_trans get_rdr, ref int rdr_cnt_num);
    extern virtual task dut_tdr_save(apb_trans get_tdr, ref int tdr_cnt_num);
    extern virtual task get_dut_tdr(ref apb_trans tdr_tr);
    extern virtual task get_dut_rdr(ref apb_trans rdr_tr);
    extern virtual task dut_rdr_save_rcv_only(apb_trans get_rdr, ref int rdr_cnt_num);
    extern virtual task get_vip_slv_data(ref spi_slv_transaction vip_slv);
    extern virtual task get_vip_mst_data(ref spi_mst_transaction vip_mst);
    extern virtual wait_reset();

endclass: spi_scoreboard

//function or task
......
`endif SPI_SCOREBOARD_SVH

四、spi_monitor

`ifndef SPI_MONITOR_SVH
`define SPI_MONITOR_SVH
class spi_monitor extends uvm_monitor;

    `uvm_component_utils(spi_monitor)
    
    virtual apb_if bif;
    process processes[string];
    
    uvm_analysis_port #(apb_trans) ap;
    
    function new(string name = "spi_monitor", uvm_component parent);
        super.new(name,parent);
    endfunction
    
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        if(!uvm_config_db#(virtual apb_if)::get(this,"","bif",bif)) begin
            `uvm_fatal("spi_monitor","No Interface speceifed for spi monitor")
        end
        ap = new("ap",this);
    endfunction

    extern task run_phase(uvm_phase phase);
    extern task collect_data(apb_trans apb_tr);
    extern virtual task wait_reset();
    
endclass

task spi_monitor::run_phase(uvm_phase phase);
    apb_trans apb_tr;
    process proc_monitor;
    
    fork
        begin
            while(1) begin
                proc_monitor = process::self();
                processes["proc_monitor"] = proc_monitor;
                apb_tr = new("apb_tr");
                collect_data(apb_tr);
                ap.write(apb_tr);
            end
        end
        
        begin
            wait_reset();
        end
    join
endtask:run_phase

task spi_monitor::collect_data(apb_trans apb_tr);
    ......
    ......
endtask:collec_data

task spi_monitor::wait_reset();
    
    forever begin
        @(negedge bif.presetn);
        foreach(precesses[i])
            processes[i].kill();
        @(posedge bif.presetn);
    end
endtask:wait_reset
`endif //SPI_MONITOR_SVH

五、spi coverage

`ifndef SPI_COVERAGE_SVH
`define SPI_COVERAGE_SVH
class spi_coverage extends uvm_subscriber #(apb_trans);
    
    `uvm_component_utils(spi_coverage)
    
    apb_trans apb_tr;
    ral_block_reg_model rm;
    
    covergroup spi_reg_cv;
        option.per_instance = 0;
        
        
        
    endgroup
    
    function new(string name = "spi_coverage", uvm_component parent = null);
        super.new(name,parent);
        
        spi_reg_cv = new();
    endfunction
    
    function void write(T t);
        spi_reg_cv.sample();
    endfunction
endclass
`endif //SPI_COVERAGE_SVH

六、spi env

class spi_env extends uvm_env;

    virtual spi_if sif;
    virtual apb_if bif;
    
    apb_agent       apb_agt;
    spi_slv_agent   slv_agt;
    spi_mst_agent   mst_agt;
    spi_scoreboard  spi_scb;
    spi_monitor     spi_mon;
    
    ral_block_reg_model p_rm;
    
    uvm_tlm_analysis_fifo #(apb_trans)  apb_tdr_scb_fifo;
    uvm_tlm_analysis_fifo #(apb_trans)  apb_rdr_scb_fifo;
    
    uvm_tlm_analysis_fifo #(spi_mst_transaction)    vip_mst_scb_fifo;
    uvm_tlm_analysis_fifo #(spi_slv_transaction)    vip_slv_scb_fifo;
    
    function new(string name = "spi_env", uvm_component parent);
        super.new(name,parent);
    endfunction
    
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
    
        p_rm    = ral_block_reg_block::type_id::create("p_rm",this);
        apb_agt = apb_agent::type_id::create("apb_agt",this);
        apb_agt.is_active = UVM_ACTIVE;
        slv_agt = spi_slv_agent::type_id::create("slv_agt",this);
        slv_agt.is_active = UVM_ACTIVE;
        mst_agt = spi_mst_agent::type_id::create("mst_agt",this);
        mst_agt.is_active = UVM_ACTIVE;
        spi_scb = spi_scoreboard::type_id::create("spi_scb",this);
        spi_cvr = spi_coverage::type_id::create("spi_cvr",this);
        spi_mon = spi_monitor::type_id::create("spi_mon",this);
        
        apb_tdr_scb_fifo = new("apb_tdr_scb_fifo",this);
        apb_rdr_scb_fifo = new("apb_rdr_scb_fifo",this);
        vip_mst_scb_fifo = new("vip_mst_scb_fifo",this);
        vip_slv_scb_fifo = new("vip_slv_scb_fifo",this);
    
        if(!uvm_config_db#(virtual spi_if)::get(this,"","sif",sif)) begin
            `uvm_fatal("spi_env","No Interface specified for this spi!")
        end
    
        if(!uvm_config_db#(virtual apb_if)::get(this,"","bif",bif)) begin
            `uvm_fatal("spi_env","No Interface specified for this spi!")
        end
    endfunction
    
    extern virtual function void connect_phase(uvm_phase phase);
    
    `uvm_component_utils(spi_env)
    
endclass

//connect_phase
function void spi_env::connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    
    //apb_tx_monitor and spi scb connect
    apb_agt.tdr_ap.connect(apb_tdr_scb_fifo.analysis_export);
    spi_scb.apb_tdr_port.connect(apb_tdr_scb_fifo.blocking_get_export);
    
    //apb_rx_monitor and spi_scb connect
    apb_agt.rdr_ap.connect(apb_rdr_fifo.analysis_export);
    spi_scb.apb_rdr_port.connec(apb_rdr_fifo.blocking_export);
    
    //spi_mst_agt and spi_scb connect
    mst_agt.mst_ap.connect(vip_mst_scb_fifo.analysis_export);
    spi_scb.vip_mst_port.connect(vip_mst_scb_fifo.blocking_get_export);
    
    //spi_slv_agt and spi_scb connect
    slv_agt.slv_ap.connect(vip_slv_scb_fifo.analysis_export);
    spi_scb.vip_slv_port.connect(vip_slv_scb_fifo.blocking_export);
    
    

endfunction: connect_phase

七、spi vsqr

`ifndef SPI_VSQR_SVH
`define SPI_VSQR_SVH
class spi_vsqr extends uvm_sequencer;

    virtual spi_if p_sif;
    virtual apb_if p_bif;

    apb_sequencer       p_apb_sqr;
    ral_block_reg_model p_rm;
    spi_slv_sequencer   p_slv_sqr;
    spi_mst_sequencer   p_mst_sqr;
    spi_cfg             cfg;
    
    function new(string name = "spi_vsqr", uvm_component parent);
        supre.new(name,parent);
    endfunction
    
    `uvm_component_utils(spi_vsqr)
endclass: spi_vsqr
`endif //SPI_VSQR_SVH

八、spi base test

`ifndef SPI_BASE_TEST
`define SPI_BASE_TEST
class spi_base_test extends uvm_test;

    virtual spi_if sif;
    virtual apb_if bif;
    
    spi_env env;
    spi_vsqr            v_sqr;
    ral_block_reg_model rm;
    apb_adgpter         reg_sqr_adapter;
    spi_cfg             cfg;
    spi_scoreboard      scb;
    
    function new(string name = "spi_base_test", uvm_component parent);
        super.new(name,parent);
    endfunction
    
    extern virtual function void build_phase(uvm_phase phase);
    extern virtual function void connect_phase(uvm_phase phase);
    extern virtual function void report_phase(uvm_phase phase);
    extern virtual function void final_phase(uvm_phase phase);
    extern virtual task wait_scb_done();
    
    `uvm_component_utils(spi_base_test)
    
endclass: spi_base_test

function void spi_base_test::build_phase(uvm_phase phase);
    super.build_phase(phase);
    
    env = spi_env::type_id::create("env",this);
    cfg = spi_cfg::type_id::create("cfg",this);
    v_sqr   = spi_vsqr::type_id::create("v_sqr",this);
    rm      = ral_block_reg_model:type_id::create("rm", this);
    rm.configure(null, "");
    rm.build();
    rm.lock_model();
    rm.reset();
    rm.set_hdl_path_root("top_tb.spi_dut");
    reg_sqr_adapter = new("reg_sqr_adapter");
endfunction

function void spi_base_test::connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    
    v_sqr.p_apb_sqr = env.apb_agt.sqr;
    v_sqr.p_slv_sqr = env.slv_agt.slv_sqr;
    v_sqr.p_mst_sqr = env.mst_agt.mst_sqr;
    v_sqr.cfg       = this.cfg;
    v_sqr.p_sif     = env.sif;
    v_sqr.p_bif     = env.bif;
    env.p_rm        = this.rm;
    env.spi_cvr.rm  = this.rm;
    scb             = env.spi_scb;
    rm.default_map.set_sequencer(env.apb_agt.sqr, reg_sqr_adapter);
    rm.default_map.set_auto_predict(1);
endfunction

funciton void spi_base_test::report_phase(uvm_phase phase);
    uvm_report_server server;
    int err_num;
    super.report_phase(phase);
    
    server  = get_report_server();
    err_num = server.get_severity_count(UVM_ERROR);
    
    if(err_num != 0) begin
        $display("TEST CASE FAILED");
    end
    else begin
        $display("TEST CASE PASSED");
    end
endfunction

function void spi_base_test::final_phase(uvm_phase phase);
    super.final_phase(phase);
    
    `uvm_info("TRACE",$sformatf("%m"),UVM_HIGH);
    //uvm_top.print_topology();
    //factory.print();
endfunction

task spi_base_test::wait_scb_done();
    wait(scb.apb_tdr_queue.size() == 0);
    wait(scb.apb_rdr_queue.size() == 0);
    wait(scb.vip_slv_queue.size() == 0);
    wait(scb.vip_mst_queue.size() == 0);
endtask: wait_scb_done
`endif //SPI_BASE_TEST
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值