美文网首页UVM
自动搭建UVM环境--Auto ENV(V1.0)

自动搭建UVM环境--Auto ENV(V1.0)

作者: sarai_c7eb | 来源:发表于2020-07-14 15:51 被阅读0次

    如何的快速的搭建UVM环境呢,最好是一键式的创建,User只填空式的修改部分文件即可;基于这样的设想,开发了Auto Env的脚本;

    1 ENV的目录结构

    >-|--build.setup
      |--sim
      |   |--makefile
      |   |--synopsys_sim.setup
      |   |--dut.f
      |   |--filelist.f
      |
      |--rtl
      |   |--xxx.v
      |
      |--tb
          |--hdl
          |   |--xxx_top_tb.sv
          |   |--xxx_package.sv
          |
          |--env
          |   |--xxx_env.sv
          |   |--xxx_vsqr.sv
          |   |--xxx_rm.sv
          |   |--xxx_scoreboard.sv
          |
          |--yyy_agent
          |   |--yyy_if.sv
          |   |--yyy_transaction.sv
          |   |--yyy_driver.sv
          |   |--yyy_monitor.sv
          |   |--yyy_sequencer.sv
          |   |--yyy_agent.sv
          |
          |--cfg_agent
          |   |--cfg_if.sv
          |   |--cfg_transaction.sv
          |   |--//cfg_monitor.sv
          |   |--cfg_driver.sv
          |   |--cfg_sequencer.sv
          |   |--cfg_agent.sv
          | 
          |--reg_model
          |   |--xxx_reg_blk.sv
          |   |--xxx_adapter.sv
          | 
          |--testcase
              |--xxx_base_vsqs.sv
              |--xxx_base_case.sv
              |--xxx_seqlib.f
              |--xxx_caselib.f
    

    从最顶层讲起:

    1. build.setup:环境变量设置,要进入这个路径下,然后source build.setup;

    2. 剩下有3个目录,tb,rtl,sim:

      • rtl:将RTL代码放进去

      • sim:运行环境的地方

      • tb:环境主体

        • 默认加入一个cfg_agent(控制通路,agent)
        • 默认加入一个yyy_agent(数据通路,agent)
        • 默认加入一个reg_model(寄存器模型)
        • hdl顶层放入test_top和package
        • 默认建立一个base的sequence和testcase
        • env目录下放整个环境的env和package,还放整个环境的scoreboard和reference model

    xxx前缀为整个系统的名称;

    yyy为数据通路的前缀;

    本文以带rgmii口的MAC为例,构建一个auto_env的python类,这个类包含了很多成员和方法,

    • 可以满足一键式的建立UVM环境;
    • 也可满足后续调用类中的过程,只产生一些agent;

    2 本文模板

    此部分主要产生各个文件的模板,便于后面class的调用;

    2.1 sim路径下的文档模板

    sim路径下的主要文件为makefile,其模板如下:

    def mk_f(in_lst):
        return '''dirs    := %s tb
    
    DUT_TOP := %s 
    TB_TOP  := %s_top_tb
    CASE    := %s_base_case
    clean:
        rm -rf simv* csrc* ${VER_PATH}/libs *.log ucli.key vhdlanLog verdiLog *.fsdb novas.rc novas.conf profileReport* simprofile_dir vdCovLog vc_hdrs.h .vlogansetup.args partitionlib vhdl_objs_dir mkdir
        $(foreach i, $(dirs), mkdir -p ${VER_PATH}/libs/$i)
    
    ana:
        vlogan -l dut.log -sverilog -kdb -work $(DUT_TOP) -f dut.f
        vlogan -l uvm.log -sverilog -kdb -work tb -ntb_opts uvm
        vlogan -l tb.log  -sverilog -kdb -work tb -ntb_opts uvm -f filelist.f
    
    comp:
        vcs $(TB_TOP) -ntb_opts uvm -kdb -lca +warn=noLCA_FEATURES_ENABLED -timescale=1ns/1ps -debug_access+cbk -l comp.log
        #vcs -full64 $(TB_TOP) -cpp g++-4.8 -cc gcc-4.8 -LDFLAGS -Wl,--no-as-needed -ntb_opts uvm -kdb -lca +warn=noLCA_FEATURES_ENABLED -timescale=1ns/1ps -debug_access+cbk -l comp.log
    
    sim:
        ./simv +fsdbfile+top_tb.fsdb +UVM_VERBOSITY=UVM_LOW +UVM_TESTNAME=${CASE} +vcs+lic+wait -l sim.log
        #./simv +fsdbfile+top_tb.fsdb -licwait 1 +UVM_VERBOSITY=UVM_HIGH +UVM_TESTNAME=${CASE} +UVM_TIMEOUT=1000000 +UVM_OBJECTION_TRACE -l sim.log
    
    '''%in_lst
    

    2.2 agent路径下的文档模板

    主要包括agent,transaction,driver,monitor,interface,sequence

    def itf_f(in_lst):
        return '''`ifndef %s
    `define %s
    interface %s(input clk,input rst_n);
        logic a;
        clocking drv_cb@(posedge clk);
            default input #1 output #1;
            output a;
            input  b;
        endclocking
    
        clocking mon_cb@(posedge clk);
            default input #1 output #1;
            output b;
            input  a;
        endclocking
    endinterface
    `endif
    '''%in_lst
    
    def tr_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_sequence_item;
        rand bit         line_en   ;
        rand byte        pload[]   ;
    
        `uvm_object_utils_begin(%s)
            `uvm_field_int(line_en ,UVM_ALL_ON)
            `uvm_field_int_array(pload,UVM_ALL_ON)
        `uvm_object_utils_end
    
        function new(string name="%s");
            super.new(name);
        endfunction
    endclass
    `endif
    '''%in_lst
    
    def sqs_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_sequencer #(%s);
        %s m_trans;
        function new(string name,uvm_component parent);
            super.new(name,parent);
        endfunction
    
        `uvm_component_utils(%s)
    endclass
    `endif
    '''%in_lst
    
    def drv_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_driver #(%s);
        `uvm_component_utils(%s)
        virtual %s %s;
    
        function new(string name="%s",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 %s)::get(this,"","%s_vif",%s_vif))
                `uvm_fatal(get_full_name(),"virtual interface must be set for %s_vif")
        endfunction
    
        extern task main_phase(uvm_phase phase);
        extern task drive_one_pkt(%s tr);
    endclass
    
    task %s::main_phase(uvm_phase phase);
       xxx_vif.xxx = 0;
       while(!xxx_vif.rst_n)
           @(posedge xxx_vif.clk);
       while(1) begin
         seq_item_port.get_next_item(req);
         drive_one_pkt(req)
         seq_item_port.item_done()
       end
    endtask
    
    task %s::drive_one_pkt(%s tr);
        @(xxx_vif.cb)
        xxx_vif.vld=1'b1;
        xxx_vif.wr=tr.wr;
    
    endtask
    `endif
    
    '''%in_lst
    
    def mon_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_monitor #(%s);
        `uvm_component_utils(%s)
        uvm_analysis_port #(%s) ap;
        virtual %s %s;
    
        function new(string name="%s",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 %s)::get(this,"","%s_vif",%s_vif))
                `uvm_fatal(get_full_name(),"virtual interface must be set for %s_vif")
        endfunction
    
        extern task main_phase(uvm_phase phase);
        extern task collect_one_pkt(%s tr);
    endclass
    
    task %s::main_phase(uvm_phase phase);
        %s tr;
        while(1) begin
            tr=new("tr");
            collect_one_pkt(tr);
            ap.write(tr);
        end
    endtask
    
    task %s::collect_one_pkt(%s tr);
        byte unsigned data_q[$];
        byte unsigned data_array[$];
        logic [7:0] data;
    
        xxxx //collect a pkt from vif, put the pkt to a tr
    
    endtask
    `endif
    
    '''%in_lst
    
    def agent_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_agent;
        %s sqr;
        %s    drv;
        %s   mon;
        
        `uvm_component_utils_begin(%s)
            `uvm_field_object(sqr,UVM_ALL_ON)
            `uvm_field_object(drv,UVM_ALL_ON)
            `uvm_field_object(mon,UVM_ALL_ON)
        `uvm_component_utils_end
    
        function new(string name,uvm_component parent=null);
            super.new(name,parent);
        endfunction
    
        extern virtual function void build_phase(uvm_phase phase);
        extern virtual function void connect_phase(uvm_phase phase);
    endclass
    
    function void %s::build_phase(uvm_phase phase);
        super.build_phase(phase);
        if(is_active==UVM_ACTIVE) begin
            sqr=%s_sequencer::type_id::create("sqr",this);
            drv=%s_driver::type_id::create("drv",this);
        end
        mon=%s::type_id::create("mon",this);
    endfunction
    
    function void %s::connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        drv.seq_item_port.connect(sqr.seq_item_export);
        ap=mon.ap;
    endfunction
    `endif
    
    '''%in_lst
    

    2.3 env路径下的文档模板

    主要包括vsequencer,model,scoreboard,env

    def vsqr_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_sequencer;
        %s  p_sqr0;
        %s  p_sqr1;
        %s  p_rm;
        function new(string name, uvm_component parent);
            super.new(name,parent);
        endfunction
        `uvm_component_utils(%s)
    endclass
    `endif
    '''%in_lst
    
    def mdl_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_component;
        %s  p_rm;
        uvm_blocking_get_port #(%s_transaction) port;
        uvm_analysis_port #(%s_transaction) ap;
    
        extern function new(string name, uvm_component parent);
        extern function void build_phase(uvm_phase phase);
        extern virtual task  main_phase(uvm_phase phase);
        `uvm_component_utils(%s)
    endclass
    
    function %s::new(string name,uvm_component parent);
        super.new(name,parent);
    endfunction
    
    function void %s::build_phase(uvm_phase phase);
        super.build_phase(phase);
        port=new("port",this);
        ap=new("ap",this);
    endfunction
    
    task %s::main_phase(uvm_phase phase);
        %s_transaction tr;
        %s_transaction new_tr;
        uvm_status_e    status;
        uvm_reg_data_t  value;
    
        super.main_phase(phase);
        p_rm.xxxx.write(status,32'hFFFF_FFFF,UVM_FRONTDOOR);
        //p_rm.xxxx.read(status,value,UVM_FRONTDOOR);
        p_rm.xxxx.peek(status,value);
        `uvm_info(get_type_name(),$sformatf("begin to access register::is_value=0h",value),UVM_LOW)
    
        while(1) begin
            port.get(tr);
            new_tr=new("new_tr");
            new_tr.copy(tr);
            `uvm_info("rgmii_info","get one transaction,copy and print it",UVM_LOW)
            new_tr.print();
            ap.write(new_tr);
        end
    endtask
    `endif'''%in_lst
    
    def scb_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_scoreboard; 
        %s_transaction  expect_queue[$];
        uvm_blocking_get_port #(%s_transaction)  exp_port;
        uvm_blocking_get_port #(%s_transaction)  act_port;
    
        `uvm_component_utils(%s)
        extern function new(string name,uvm_component parent=null);
        extern virtual function void build_phase(uvm_phase phase);
        extern virtual task main_phase(uvm_phase phase);
    endclass
    
    function void %s::new(string name,uvm_component parent=null);
        super.new(name,parent);
    endfuntion
    
    function void %s::build_phase(uvm_phase phase);
        super.build_phase(phase);
        exp_port=new("exp_port",this);
        act_port=new("act_port",this);
    endfuntion
    
    task %s::main_phase(uvm_phase phase);
        %s_transaction get_expect,get_actual,tmp_tran;
        bit result;
    
        super.main_phase(phase);
        fork
            while(1) begin
                act_port.get(get_actual);
                if(expect_queue.size>0) begin
                    tmp_tran=expect_queue.pop_front();
                    result  =get_actual.compare(tmp_tran);
                    if(result) begin
                        `uvm_info("rgmii_scoreboard","Compare SUCCESSFULLY",UVM_LOW)
                    end
                    else begin
                        `uvm_error("rgmii_scoreboard","Compare FAILED")
                        $display("the expect pkt is");
                        tmp_tran.print();
                        $display("the acutal pkt is");
                        get_actual.print();
                    end
                end
                else begin
                    `uvm_error("rgmii_scoreboard","Received from DUT,while Expect queue is empty")
                    $display("the unexpect pkt is");
                    get_actual.print()
                end
            end
        join
    endtask
    `endif
    '''%in_lst
    
    def env_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_env;
        %s    vsqr
        %s   %s_agt;
        %s   %s_agt;
        
        %s   rm;
        %s   %s_adpt;
    
        uvm_tlm_analysis_fifo #(%s_transaction)  agt_scb_fifo;
        uvm_tlm_analysis_fifo #(%s_transaction)  agt_mdl_fifo;
        uvm_tlm_analysis_fifo #(%s_transaction)  mdl_scb_fifo;
        %s   mdl;
        %s   scb;
    
        `uvm_component_utils_begin(%s)
            `uvm_field_object(vsqr,UVM_ALL_ON)
            `uvm_field_object(%s_agt,UVM_ALL_ON)
            `uvm_field_object(%s_agt,UVM_ALL_ON)
            `uvm_field_object(mdl,UVM_ALL_ON)
            `uvm_field_object(scb,UVM_ALL_ON)
        `uvm_component_utils_end
    
        function new(string name="%s",uvm_component parent);
            super.new(name,parent);
        endfunction
    
        virtual function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            vsqr   =%s_vsqr::type_id::create("vsqr",this);
            %s_agt =%s_agent::type_id::create("%s_agt",this);
            %s_agt =%s_agent::type_id::create("%s_agt",this);
    
            rm=%s_reg_blk::type_id::create("rm",this);
            rm.configure(null,"%s_top_tb.U_%s.U_%s_RF");
            rm.build();
            rm.lock_model();
            rm.reset();
            %s_adpt=new("%s_adpt");
    
            mdl=%s::type_id::create("mdl",this);
            scb=%s::type_id::create("scb",this);
    
            agt_mdl_fifo=new("agt_mdl_fifo",this);
            mdl_scb_fifo=new("mdl_scb_fifo",this);
            agt_scb_fifo=new("agt_scb_fifo",this);
        endfunction
    
        virtual function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            vsqr.p_sqr0=this.%s_agt.sqr;
            vsqr.p_sqr1=this.%s_agt.sqr;
    
            vsqr.p_rm=this.rm;
            mdl.p_rm=this.rm;
            rm.default_map.set_sequencer(vsqr.p_sqr1,%s_adpt);
            rm.default_map.set_auto_predict(1);
    
            //agt1<-->model
            %s_agt.ap.connect(agt_mdl_fifo.analysis_export);
            mdl.port.connect(agt_mdl_fifo.blocking_get_export)
    
            //mdl<-->scb
            mdl.ap.connect(mdl_scb_fifo.analysis_export);
            scb.exp_export.conenct(mdl_scb_fifo.blocking_get_export);
    
            //agt1<-->scb
            %s_agt.ap.connect(agt_scb_fifo.analysis_export);
            scb.act_port.conenct(agt_scb_fifo.blocking_get_export);
        endfunction
    
        task main_phase(uvm_phase phase);
            super.main_phase(phase);
        endtask
    endclass
    `endif
    
    '''%in_lst
    

    2.4 hdl路径下的文档模板

    包括package和top

    def pkg_f(in_lst):
        return '''package %s;
    import uvm_pkg::*;
    `include "uvm_macros.svh"
    `include "../tb/%s/%s.sv"
    `include "../tb/%s/%s.sv"
    `include "../tb/%s/%s.sv"
    `include "../tb/%s/%s.sv"
    `include "../tb/%s/%s.sv"
    
    `include "../tb/%s/%s.sv"
    `include "../tb/%s/%s.sv"
    `include "../tb/%s/%s.sv"
    `include "../tb/%s/%s.sv"
    
    `include "../tb/reg_model/%s.sv"
    `include "../tb/reg_model/%s.sv"
    
    `include "../tb/env/%s.sv"
    `include "../tb/env/%s.sv"
    `include "../tb/env/%s.sv"
    `include "../tb/env/%s.sv"
    `include "../tb/testcase/%s_base_vsqs.sv"
    `include "../tb/testcase/%s_base_case.sv"
    endpackage
    '''%in_lst
    
    def top_f(in_lst):
        return '''`include "uvm_macros.svh"
    import uvm_pkg::*;
    import %s::*;
    //include all agent interface path here!!
    `include "$VER_PATH/tb/%s_agent/%s_if.sv"
    `include "$VER_PATH/tb/%s_agent/%s_if.sv"
    module %s;
    //clock and reset
        logic                clk_27m_i      ; 
        logic                rstn_27m_i     ;
    
    //itf1
        logic                ad_fid_i       ;
        logic                ad_hsync_i     ;
        logic                ad_vsync_i     ;
        logic      [7:0]     ad_yout_i      ;
    
    %s   u_%s(clk_27m_i,rstn_27m_i);
    %s   u_%s(clk_27m_i,rstn_27m_i);
    
    %s inst_%s(
        .clk_27m_i      (clk_27m_i              ), 
        .rstn_27m_i     (rstn_27m_i             ), 
        .ad_fid_i       (u_%s.ad_fid_i          ),
        .ad_hsync_i     (u_%s.ad_hsync_i        ),
        .ad_vsync_i     (u_%s.ad_vsync_i        ),
        .ad_yout_i      (u_%s.ad_yout_i         ),
        .fpga_pwm_o     (fpga_pwm_o             )
    );
    
    initial begin
        clk_27m_i =0;
        forever begin
            #18.51 clk_27m_i =~clk_27m_i ;
        end
    end
    
    initial begin
        rstn_27m_i=1'b0;
        repeat(2) @(posedge clk_27m_i);
        rstn_27m_i=1'b1;
    end
    
    initial begin
        run_test();
    end
    
    initial begin
        uvm_config_db#(virtual %s)::set(null,"uvm_test_top.env.%s_agt.drv","%s_vif",u_%s_if);
        uvm_config_db#(virtual %s)::set(null,"uvm_test_top.env.%s_agt.drv","%s_vif",u_%s_if);
        uvm_config_db#(virtual %s)::set(null,"uvm_test_top.env.%s_agt.mon","%s_vif",u_%s_if);
    end
    
    initial begin
         //$fsdbDumpfile("top_tb.fsdb");
         $fsdbDumpfile();
         $fsdbDumpvars;
    end
    
    endmodule
    '''%in_lst
    

    2.5 testcase下的模板

    包括sequence和testcase

    def vsqs_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_sequence;
        `uvm_object_utils(%s)
        `uvm_declare_p_sequencer(%s)
        %s  m_trans;
        uvm_status_e status;
        uvm_reg_data_t value;
    
        function new(string name="%s");
            super.new(name);
        endfunction
    
        extern virtual task body();
    endclass
    task %s::body();
        if(starting_phase!=null)
            starting_phase.raise_objection(this);
        begin
            p_sequrencer.p_rm.cfg_a_ins.write(status,32'hFFFF_FFFF,UVM_FRONTDOOR); //frontdoor access
            p_sequrencer.p_rm.cfg_a_ins.peek(status,value); //backdoor access
            `uvm_info(get_type_name(),$sfrormatf("begin to access register:read_value=0h",value),UVM_LOW)
    
            `uvm_do_on_with(m_trans,p_sequencer.p_sqr0,{xxxx_en==1'd1;})
            `uvm_do_on_with(m_trans,p_sequencer.p_sqr0,{xxxx_en==1'd1;})
        end
    
        if(starting_phase!=null)
            starting_phase.drop_objection(this);
    endtask
    `endif
    '''%in_lst
    
    
    def case_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_test;
        %s env;
    
        function new(string name="%s",uvm_component parent);
            super.new(name,parent);
        endfunction
        extern virtual function void build_phase(uvm_phase phase);
        extern task main_phase(uvm_phase phase);
    
        `uvm_component_utils(%s)
    endclass
    
    function void %s::build_phase(uvm_phase phase);
        super.build_phase(phase);
        env=%s::type_id::create("env",this);
        uvm_config_db#(uvm_object_wrapper)::set(this,
                                                "env.vsqr.main_phase",
                                                "default_sequence",
                                                %s::type_id::get());
    endfunction
    
    task %s::main_phase(uvm_phase phase);
        super.main_phase(phase);
    endtask
    `endif
    '''%in_lst
    
    

    2.6 reg_model下的模板

    主要为adapter

    def adpt_f(in_lst):
        return '''`ifndef %s
    `define %s
    class %s extends uvm_reg_adapter;
        string tID=get_type_name();
    
        `uvm_object_utils(%s)
    
        function new(string name="%s");
            super.new(name);
        endfunction
    
        function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
            %s_transaction tr;
            tr=new("tr");
            tr.addr=rw.addr;
            tr.wr  =(rw.kind==UVM_READ) ? 0 :1;
            tr.wdata=tr.wr ? rw.data :0
            return tr;
        endfunction
    
        function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
            %s_transaction tr;
            if(!$cast(tr,bus_item)) begin
                `uvm_fatal(tID,"Provided bus_item is not the correct type.Expecting %s_transaction")
                return;
            end
            rw.kind=(tr.wr==1) ? UVM_WRITE :UVM_READ;
            rw.addr=tr.addr;
            rw.byte_en='h3;
            rw.data=(tr.wr==1) ? tr.rdata : tr.wdta;
            rw.status=UVM_IS_OK;
        endfucntion
    endclass
    `endif
    '''%in_lst
    

    3 auto_env class

    3.1 函数简介

    主要包括2部分内容:

    • xxx_dir_gen:产生路径;
      • top_dir_gen:产生最顶层的文件夹和文件;
      • env_dir_gen:产生tb下除了agent之外的其他文件夹;
      • agent_dir_gen:产生agent文件夹
    • xxx_dec:根据模板产生代码;
      • sim_dec:生成makefile,filelist.f,dut.f,synopsys_sim.setup
      • agent_dec: 选择产生driver,monitor,iterface,transaction,sequencer,agent代码
        • 如果cfg=1则,不产生monitor
      • env_dec:生成vsequenser,model,scoreboard,env
      • hdl_dec:生成package和top_tb
      • case_dec:生成sequence和testcase以及sequencelib和testcaselib
      • rm_dec:生成adapter和blk file
        • blk_file为空文件,可用json2sv脚本直接产生sv文档;
    • new_env:直接产生完整的验证环境;
    class auto_env:
        def __init__(self,prefix,agent1,agent2,agent1_bi,agent2_bi,top_dir):
            self.prefix=prefix
            self.agent1=agent1
            self.agent2=agent2
            self.agent1_bi=agent1_bi
            self.agent2_bi=agent2_bi
    
            self.top_dir=top_dir
            self.sim_dir=top_dir+r'\sim'
            self.rtl_dir=top_dir+r'\rtl'
            self.tb_dir =top_dir+r'\tb'
            self.env_dir=top_dir+r'\tb\env'
            self.hdl_dir=top_dir+r'\tb\hdl'
            self.case_dir=top_dir+r'\tb\testcase'
            self.reg_dir=top_dir+r'\tb\reg_model'
            self.agt1_dir=top_dir+r'\tb\%s_agent'%agent1
            self.agt2_dir=top_dir+r'\tb\%s_agent'%agent2
    
        def top_dir_gen(self):
            print("------------------------------------------")
            print("change the dir to the 'top'")
            os.chdir(self.top_dir)
            su_file=open("build.setup","w")
            su_file.write("setenv  VER_PATH  `pwd`")
            su_file.close
            
            print("create the directory of tb")
            os.mkdir("tb")
            print("create the directory of sim")
            os.mkdir("sim")
            print("create the directory of rtl")
            os.mkdir("rtl")
        
        def env_dir_gen(self):
            print("------------------------------------------")
            print("change the dir to the 'tb'")
            os.chdir(self.tb_dir)
            print("create the directory of env")
            os.mkdir("env")
            print("create the directory of hdl")
            os.mkdir("hdl")
            print("create the directory of testcase")
            os.mkdir("testcase")
            print("create the directory of reg_model")
            os.mkdir("reg_model")
    
        def agent_dir_gen(self,agent):
            print("------------------------------------------")
            print("change the dir to the 'tb'")
            os.chdir(self.tb_dir)
            dir_agent_name=agent+"_agent"
            print("create the directory of %s"%dir_agent_name)
            os.mkdir(dir_agent_name)
    
        def sim_dec(self,mk_f):
            print("------------------------------------------")
            print("change the dir to the 'sim'")
            os.chdir(self.sim_dir)
            mk_s=mk_f((self.prefix,self.prefix.upper(),self.prefix,self.prefix))
    
            mk_file=open("makefile",'w')
            mk_file.write(mk_s)
            mk_file.close
            
            fl_file=open("filelist.f",'w')
            fl_file.write("$VER_PATH/tb/hdl/%s_package.sv\n"%self.prefix)
            fl_file.write("$VER_PATH/tb/hdl/%s_top_tb.sv"%self.prefix)
            fl_file.close
            
            dl_file=open("dut.f",'w')
            dl_file.write("$VER_PATH/rtl/%s.v"%self.prefix)
            dl_file.close
            
            ss_file=open("synopsys_sim.setup",'w')
            ss_file.write("%s : $VER_PATH/libs/%s\n"%(self.prefix,self.prefix))
            ss_file.write("tb  : $VER_PATH/libs/tb\n")
            ss_file.write("work > tb")
            ss_file.close
    
        #--------------------------------------------------------------
        #----generate the agent files----
        #--------------------------------------------------------------
        def agent_dec(self,agent,agent_bi,agent_dir,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f,cfg):
            #--IF--
            IF      ='if'
            IF_NAME =agent+"_"+IF
            IF_FILE =agent+"_"+IF+".sv"
            IF_MACRO=agent.upper()+"_"+IF.upper()+"_SV"
            IF_S=itf_f((IF_MACRO,IF_MACRO,IF_NAME))
            
            #--transaction--
            TR      ='transaction'
            TR_NAME =agent+"_"+TR
            TR_FILE =agent+"_"+TR+".sv"
            TR_MACRO=agent.upper()+"_"+TR.upper()+"_SV"
            TR_S=tr_f((TR_MACRO,TR_MACRO,TR_NAME,TR_NAME,TR_NAME))
            
            #--sequencer--
            SQR      ='sequencer'
            SQR_NAME =agent+"_"+SQR
            SQR_FILE =agent+"_"+SQR+".sv"
            SQR_MACRO=agent.upper()+"_"+SQR.upper()+"_SV"
            SQR_S=sqs_f((SQR_MACRO,SQR_MACRO,SQR_NAME,TR_NAME,TR_NAME,SQR_NAME))
            
            #--drv--
            DRV      ='driver'
            DRV_NAME =agent+"_"+DRV
            DRV_FILE =agent+"_"+DRV+".sv"
            DRV_MACRO=agent.upper()+"_"+DRV.upper()+"_SV"
            DRV_S=drv_f((DRV_MACRO,DRV_MACRO,DRV_NAME,TR_NAME,DRV_NAME,IF_NAME, \
                         agent+"_vif",DRV_NAME,IF_NAME,agent,agent,agent,TR_NAME,DRV_NAME,DRV_NAME,TR_NAME))
            
            #--mon--
            MON      ='monitor'
            MON_NAME =agent+"_"+MON
            MON_FILE =agent+"_"+MON+".sv"
            MON_MACRO=agent.upper()+"_"+MON.upper()+"_SV"
            MON_S=mon_f((MON_MACRO,MON_MACRO,MON_NAME,TR_NAME,MON_NAME,TR_NAME,IF_NAME,agent+"_vif", \
                         MON_NAME,IF_NAME,agent,agent,agent,TR_NAME,MON_NAME,TR_NAME,MON_NAME,TR_NAME))
            
            #--agent--
            AGENT      ='agent'
            AGENT_NAME =agent+"_"+AGENT
            AGENT_FILE =agent+"_"+AGENT+".sv"
            AGENT_MACRO=agent.upper()+"_"+AGENT.upper()+"_SV"
            AGENT_S=agent_f((AGENT_MACRO,AGENT_MACRO,AGENT_NAME,SQR_NAME,DRV_NAME,MON_NAME,AGENT_NAME,AGENT_NAME,agent,agent,MON_NAME,AGENT_NAME))
            
            print("------------------------------------------")
            print("change the dir to the '%s'"%agent_dir)
            os.chdir(agent_dir)
            print("create the file of %s"%IF_NAME+".sv")
            IF_file=open(IF_NAME+".sv",'w')
            IF_file.write(IF_S)
            IF_file.close
            
            print("create the file of %s"%TR_NAME+".sv")
            TR_file=open(TR_NAME+".sv",'w')
            TR_file.write(TR_S)
            TR_file.close
            
            print("create the file of %s"%SQR_NAME+".sv")
            SQR_file=open(SQR_NAME+".sv",'w')
            SQR_file.write(SQR_S)
            SQR_file.close
            
            print("create the file of %s"%DRV_NAME+".sv")
            DRV_file=open(DRV_NAME+".sv",'w')
            DRV_file.write(DRV_S)
            DRV_file.close
            
            if agent_bi=='BI' and cfg==0:
                print("create the file of %s"%MON_NAME+".sv")
                MON_file=open(MON_NAME+".sv",'w')
                MON_file.write(MON_S)
                MON_file.close
            
            print("create the file of %s"%AGENT_NAME+".sv")
            AGENT_file=open(AGENT_NAME+".sv",'w')
            AGENT_file.write(AGENT_S)
            AGENT_file.close
    
        #--------------------------------------------------------------
        #----generate the env files----
        #--------------------------------------------------------------
        def env_dec(self,vsqr_f,mdl_f,scb_f,env_f):
            prefix=self.prefix
            agent1=self.agent1
            agent2=self.agent2
            SQR       ='sequencer'
            SQR1_NAME =agent1+"_"+SQR
            SQR2_NAME =agent2+"_"+SQR
            RM_NAME   =prefix+"_reg_blk"
            #--virtual sequencer--
            VSQR      ='vsqr'
            VSQR_NAME =prefix+"_"+VSQR
            VSQR_FILE =prefix+"_"+VSQR+".sv"
            VSQR_MACRO=prefix.upper()+"_"+VSQR.upper()+"_SV"
            VSQR_S=vsqr_f((VSQR_MACRO,VSQR_MACRO,VSQR_NAME,SQR1_NAME,SQR2_NAME,RM_NAME,VSQR_NAME))
    
            #--model--
            MDL      ='model'
            MDL_NAME =prefix+"_"+MDL
            MDL_FILE =prefix+"_"+MDL+".sv"
            MDL_MACRO=prefix.upper()+"_"+MDL.upper()+"_SV"
            MDL_S=mdl_f((MDL_MACRO,MDL_MACRO,MDL_NAME,RM_NAME,agent1,agent1,MDL_NAME,MDL_NAME,MDL_NAME,MDL_NAME,agent1,agent1))
    
            #--scoreboard--
            SCB      ='scoreboard'
            SCB_NAME =prefix+"_"+SCB
            SCB_FILE =prefix+"_"+SCB+".sv"
            SCB_MACRO=prefix.upper()+"_"+SCB.upper()+"_SV"
            SCB_S=scb_f((SCB_MACRO,SCB_MACRO,SCB_NAME,agent1,agent1,agent1,SCB_NAME,SCB_NAME,SCB_NAME,SCB_NAME,agent1))
    
            #--env--
            ENV      ='env'
            ENV_NAME =prefix+"_"+ENV
            ENV_FILE =prefix+"_"+ENV+".sv"
            ENV_MACRO=prefix.upper()+"_"+ENV.upper()+"_SV"
            ENV_S=env_f((ENV_MACRO,ENV_MACRO,ENV_NAME, \
                VSQR_NAME,agent1+"_agent",agent1,agent2+"_agent",agent2, \
                prefix+"_reg_blk",prefix+"_adapter",prefix, \
                agent1,agent1,agent1,MDL_NAME,SCB_NAME, \
                ENV_NAME,agent1,agent2,ENV_NAME,prefix,agent1,agent1,agent1,agent2,agent2,agent2, \
                prefix,prefix,prefix,prefix,prefix,prefix, \
                MDL_NAME,SCB_NAME, \
                agent1,agent2,prefix,agent1,agent1))
    
            print("------------------------------------------")
            print("change the dir to the 'env'")
            os.chdir(self.env_dir)
            print("create the file of %s"%VSQR_NAME+".sv")
            VSQR_file=open(VSQR_NAME+".sv",'w')
            VSQR_file.write(VSQR_S)
            VSQR_file.close
            
            print("create the file of %s"%MDL_NAME+".sv")
            MDL_file=open(MDL_NAME+".sv",'w')
            MDL_file.write(MDL_S)
            MDL_file.close
            
            print("create the file of %s"%SCB_NAME+".sv")
            SCB_file=open(SCB_NAME+".sv",'w')
            SCB_file.write(SCB_S)
            SCB_file.close
    
            print("create the file of %s"%ENV_NAME+".sv")
            ENV_file=open(ENV_NAME+".sv",'w')
            ENV_file.write(ENV_S)
            ENV_file.close
    
        #--------------------------------------------------------------
        #----generate the hdl files----
        #--------------------------------------------------------------
        def hdl_dec(self,pkg_f,top_f):
            prefix=self.prefix
            agent1=self.agent1
            agent2=self.agent2
            hdl_dir=self.hdl_dir
            #--package--
            PKG      ='package'
            PKG_NAME =prefix+"_"+PKG
            PKG_FILE =prefix+"_"+PKG+".sv"
            PKG_MACRO=prefix.upper()+"_"+PKG.upper()+"_SV"
            PKG_S=pkg_f((PKG_NAME, \
                 agent1+"_agent",agent1+"_transaction", \
                 agent1+"_agent",agent1+"_sequencer", \
                 agent1+"_agent",agent1+"_driver", \
                 agent1+"_agent",agent1+"_monitor", \
                 agent1+"_agent",agent1+"_agent", \
                 agent2+"_agent",agent2+"_transaction", \
                 agent2+"_agent",agent2+"_sequencer", \
                 agent2+"_agent",agent2+"_driver", \
                 agent2+"_agent",agent2+"_agent", \
                 prefix+"_reg_blk",prefix+"_adapter", \
                 prefix+"_vsqr",prefix+"_model",prefix+"_scoreboard",prefix+"_env",prefix,prefix))
            
            #--top_tb--
            TOP      ='top_tb'
            TOP_NAME =prefix+"_"+TOP
            TOP_FILE =prefix+"_"+TOP+".sv"
            TOP_MACRO=prefix.upper()+"_"+TOP.upper()+"_SV"
            TOP_S=top_f((PKG_NAME,agent1,agent1,agent2,agent2,TOP_NAME, \
                 agent1+"_if",agent1+"_if",agent2+"_if",agent2+"_if", \
                 prefix,prefix,agent1+"_if",agent1+"_if",agent2+"_if",agent2+"_if", \
                 agent1+"_if",agent1,agent1,agent1, \
                 agent2+"_if",agent2,agent2,agent2, \
                 agent1+"_if",agent1,agent1,agent1))
            
            print("------------------------------------------")
            print("change the dir to the 'hdl'")
            os.chdir(hdl_dir)
            print("create the file of %s"%PKG_NAME+".sv")
            PKG_file=open(PKG_NAME+".sv",'w')
            PKG_file.write(PKG_S)
            PKG_file.close
            
            
            print("create the file of %s"%TOP_NAME+".sv")
            TOP_file=open(TOP_NAME+".sv",'w')
            TOP_file.write(TOP_S)
            TOP_file.close
    
        #--------------------------------------------------------------
        #----generate the testcase files----
        #--------------------------------------------------------------
        def case_dec(self,vsqs_f,case_f):
            prefix=self.prefix
            agent1=self.agent1
            case_dir=self.case_dir
            #--vsquence--
            VSQS      ='base_vsqs'
            VSQS_NAME =prefix+"_"+VSQS
            VSQS_FILE =prefix+"_"+VSQS+".sv"
            VSQS_MACRO=prefix.upper()+"_"+VSQS.upper()+"_SV"
            VSQS_S=vsqs_f((VSQS_MACRO,VSQS_MACRO,VSQS_NAME,VSQS_NAME,prefix+"_vsqr",agent1+"_transaction",VSQS_NAME,VSQS_NAME))
            
            #--testcase--
            CASE      ='base_case'
            CASE_NAME =prefix+"_"+CASE
            CASE_FILE =prefix+"_"+CASE+".sv"
            CASE_MACRO=prefix.upper()+"_"+CASE.upper()+"_SV"
            CASE_S=case_f((CASE_MACRO,CASE_MACRO,CASE_NAME,prefix+"_env",CASE_NAME,CASE_NAME,CASE_NAME,prefix+"_env",VSQS_NAME,CASE_NAME))
            
            VSQSLIB      ='seqlib'
            VSQSLIB_NAME =prefix+"_"+VSQSLIB
            VSQSLIB_FILE =prefix+"_"+VSQSLIB+".f"
            VSQSLIB_MACRO=prefix.upper()+"_"+VSQSLIB.upper()+"_SV"
            VSQSLIB_S ='''`include "%s"
            '''%VSQS_FILE
            
            CASELIB      ='caselib'
            CASELIB_NAME =prefix+"_"+CASELIB
            CASELIB_FILE =prefix+"_"+CASELIB+".f"
            CASELIB_MACRO=prefix.upper()+"_"+CASELIB.upper()+"_SV"
            CASELIB_S ='''`include "%s"
            '''%CASE_FILE
            
            print("------------------------------------------")
            print("change the dir to the 'testcase'")
            os.chdir(case_dir)
            print("create the file of %s"%VSQS_NAME+".sv")
            VSQS_file=open(VSQS_NAME+".sv",'w')
            VSQS_file.write(VSQS_S)
            VSQS_file.close
            
            print("create the file of %s"%CASE_NAME+".sv")
            CASE_file=open(CASE_NAME+".sv",'w')
            CASE_file.write(CASE_S)
            CASE_file.close
            
            print("create the file of %s"%VSQSLIB_NAME+".f")
            VSQSLIB_file=open(VSQSLIB_NAME+".f",'w')
            VSQSLIB_file.write(VSQSLIB_S)
            VSQSLIB_file.close
            
            print("create the file of %s"%CASELIB_NAME+".f")
            CASELIB_file=open(CASELIB_NAME+".f",'w')
            CASELIB_file.write(CASELIB_S)
            CASELIB_file.close
    
        #--------------------------------------------------------------
        #----generate the reg_model files----
        #--------------------------------------------------------------
        def rm_dec(self,adpt_f):
            prefix=self.prefix
            agent2=self.agent2
            reg_dir=self.reg_dir
            #--vsquence--
            ADPT      ='adapter'
            ADPT_NAME =prefix+"_"+ADPT
            ADPT_FILE =prefix+"_"+ADPT+".sv"
            ADPT_MACRO=prefix.upper()+"_"+ADPT.upper()+"_SV"
            ADPT_S=adpt_f((ADPT_MACRO,ADPT_MACRO,ADPT_NAME,ADPT_NAME,ADPT_NAME,agent2,agent2,agent2))
            
            #--adapter--
            print("------------------------------------------")
            print("change the dir to the 'testcase'")
            os.chdir(reg_dir)
            print("create the file of %s"%ADPT_NAME+".sv")
            ADPT_file=open(ADPT_NAME+".sv",'w')
            ADPT_file.write(ADPT_S)
            ADPT_file.close
            
            BLK      ='reg_blk'
            BLK_NAME =prefix+"_"+BLK
            BLK_FILE =prefix+"_"+BLK+".sv"
            print("create the file of %s"%BLK_NAME+".sv")
            BLK_file=open(BLK_NAME+".sv",'w')
            BLK_file.write("//generate the code in json2sv\n")
            BLK_file.write("//replace the file w/ this file\n")
            BLK_file.close
        def new_env(self,mk_f,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f,vsqr_f,mdl_f,scb_f,env_f,pkg_f,top_f,vsqs_f,case_f,adpt_f):
            print("------------------------------------------")
            print("-- Auto Env Begin                       --")
            print("------------------------------------------")
            self.top_dir_gen()
            self.env_dir_gen()
            self.agent_dir_gen(self.agent1)
            self.agent_dir_gen(self.agent2)
            self.sim_dec(mk_f)
            self.agent_dec(self.agent1,self.agent1_bi,self.agt1_dir,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f,0)
            self.agent_dec(self.agent2,self.agent2_bi,self.agt2_dir,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f,1)
            self.env_dec(vsqr_f,mdl_f,scb_f,env_f)
            self.hdl_dec(pkg_f,top_f)
            self.rm_dec(adpt_f)
            self.case_dec(vsqs_f,case_f)
            print("------------------------------------------")
            print("-- Auto Env End                         --")
            print("------------------------------------------")
        def new_agt(self,agent,agent_bi,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f):
            agent_dir=self.tb_dir+r'/'+agent+"_agent"
            self.agent_dir_gen(agent)
            self.agent_dec(agent,agent_bi,agent_dir,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f)
    
    

    3.2 使用方法

    建立新环境

    #! /usr/bin/python
    #version 1.0
    import os
    import sys
    import shutil
    
    prefix   ="gmac"
    
    agent1   ="rgmii"
    agent1_bi="BI"
    
    agent2   ="cfg"
    agent2_bi="BI"
    
    top_dir=r'E:/VERIFICATION/test'
    
    #define the strings function
    #define the auto_env class
    
    tmp=auto_env(prefix,agent1,agent2,agent1_bi,agent2_bi,top_dir)
    tmp.new_env(mk_f,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f,vsqr_f,mdl_f,scb_f,env_f,pkg_f,top_f,vsqs_f,case_f,adpt_f)
    

    添加新的agent

    #! /usr/bin/python
    #version 1.0
    import os
    import sys
    import shutil
    
    prefix   ="gmac"
    
    agent1   ="rgmii"
    agent1_bi="BI"
    
    agent2   ="cfg"
    agent2_bi="BI"
    
    top_dir=r'E:/VERIFICATION/test'
    
    #define the strings function
    #define the auto_env class
    
    agent_new="i2c"
    agent_new_bi="BI"
    tmp.new_agt(agent_new,agent_new_bi,itf_f,tr_f,sqs_f,drv_f,mon_f,agent_f,1)
    

    bugfix或其他改进后续继续更新;
    OVER

    相关文章

      网友评论

        本文标题:自动搭建UVM环境--Auto ENV(V1.0)

        本文链接:https://www.haomeiwen.com/subject/jtqjhktx.html