如何的快速的搭建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
从最顶层讲起:
build.setup:环境变量设置,要进入这个路径下,然后source build.setup;
-
剩下有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或其他改进后续继续更新;