1. 环境结构
基于西门子Veloce的UVM硬件加速验证平台,其主要覆盖IP仿真加速,SOC系统验证,应用场景功耗分析等几个方面。验证环境采用的目录结构与pioneer #1保持一致。
采用硬件加速之后,DUT运行的时间极大的缩短,相比较与VCS仿真,可提高运行速度120倍左右。
Veloce硬件平台的结构如图所示。
![](/images/dv-emulator-env/0.png)
1.1 设计思想
硬件加速验证就是将DUT代码完全在veloce平台上运行起来,针对UVM环境做一些特定的修改,实现流程如下:
修改ASIC设计(时钟,复位,memory,PHY,PAD)
将UVM环境分割成HVL和HDL两个部分
使用Transaction Library进行HVL和HDL的通信
采用veloce综合,加速仿真
1.2 时钟树和复位
Veloce可以完全实现ASIC的时钟网络,只要去除Analog PLL模块,PLL输出的时钟由veloce直接force即可(采用clock file机制指定时钟),时钟树上的的clock mux, clock divider和clock buffer都可以全部保留。
Veloce可以完全实现ASIC的复位网络,无需任何修改。
1.3 Memory
所有ASIC的memory都要替换成基于flip-flop的寄存器模型。如图所示:
![](/images/dv-emulator-env/1.png)
宏DFF_MASK_BW用来指定memory的mask bit基本粒度。不同的mask_bit粒度占用的block ram资源不同。ASIC生成的memory库都是1 bit mask,对于DFF模型,需要根据实际使用的mask bit设定相应的DFF_MASK_BW值,尽量能做到以byte为单位mask。
1.4 Analog & PHY & IO
ASIC设计中所有的模拟部分和物理PHY部分均不能在Veloce上综合,需要全部去掉。
芯片设计中还存在很多物理PHY,在硬件加速平台中,这些PHY需要全部去除,使用Veloce的Virtual Lab来实现。
Veloce平台可以实现ASIC的PAD库,并保留PIN_MUX逻辑。
DDR PHY和内存颗粒需要使用veloce的机制实现, controller则可以保留ASIC设计一致。
2. UVM环境修改
Veloce硬件加速仿真平台使用与pioneer #1相同的环境结构,但是针对跨平台的验证,需要将interface, agent和env做特定的修改,相关的VIP替换成Siemens的VIP。
Veloce环境分为HDL和HVL两部分,所有的时间消耗任务都发生在HDL部分,在HVL部分仅存在没有时间消耗的任务。
2.1 Interface修改
Interface作为HVL和HDL之间的沟通桥梁,需要使用Siemens特定的XRTL语言来编写(XRTL语言继承自RTL,并做了一些限制)。使用XRTL语言编写的interface在综合后会自动构建HVL和HDL之间的通信机制,对于用户是透明的。将interface修改成veloce所需要的结构需要注意以下几点:
在interface声明后添加如下原语,编译器会识别为XRTL类型
1
//pragma attribute xxx(module name) partition_interface_xif
在task声明后添加如下原语,编译器会允许HVL调用这个任务
1
//pragma tbx xtf
task中要么不使用任何时钟,要么task内部第一个语句必须在时钟边沿等待,且task语句块内部必须使用相同时钟的相同边沿触发
1
2
3
4task xxx(input xxx ,output xxx)//pragma tbx xtf
@(posedge/negedge clk)
.......
endtasktask或function中的参数类型只能是input或output
默认编译内存大小为32GB,在veloce.config中添加rtlc -inc_vle_mem_limit可解除编译内存大小限制
interface中支持文件操作,$fopen,$fread,$fwrite,$fscanf,$fclose。文件操作会编译成硬件资源,有一定的限制(可查阅veloce ug查看详细信息)
- $fscanf,$fread的文件句柄不能使用数组表示
- $fscanf只能扫描出32bit的数据,超过32的高位无法扫描
- 对同一个文件句柄,仅支持一个$fread操作
- 无论采用二进制写还是文本写,$fwrite格式化%h到文件中的都是ASCII类型,格式化%c输出到文件中的是二进制数据
- 推荐使用二进制的$fwrite和$fread操作,如下所示
1 | fp0 = $fopen("xxx","wb"); |
声明为xtf的task不支持并行同时调用(因为HVL调用interface中的task时会占用veloce的co-model channel做数据传输)。
可以对task或function添加传输方向定义。one_way_call 是单向调用,two_way_call为有返回值或输出值。采用one_way_call可以提高performance,声明方法如下图所示:
在veloce模式下,vif中无法使用clock_blocking
在veloce中使用$fscanf时需要注意的是不能直接将驱动信号直接传给第三个参数,会发生报错。解决的办法是:另外声明一个不和dut相连的非驱动信号,打一拍后将该非驱动信号赋值给驱动信号,打一拍的作用是防止赋值语句被veloce优化。
wait语句与event一样必须紧跟一个clk
1
2wait(sig_name);
@(posedge clk);对于特殊情况而言,即wait后可以跟foerever语句或repeat语句后再跟一个clk
1
2
3wait(sig_name);
forever/repeat(N) begin
@(posedge clk);
2.2 Agent修改
Agent中主要修改基本都在interface中,主要体现在以下两个方面:
- 将hvl中的延时语句移除,通过调用vif中的task来实现延时
- 将hvl中的使用vif的语句移除,通过调用vif中的task或者function来实现
2.3 Env修改
Env主要修改interface,vip,memory,主要体现在以下几个方面:
添加questa axi master vip
- 在hdl top里面例化axi master module,并且在hdl top将axi master module连接到dut。
- 在hvl top 定义axi_masrer_if,bind到hdl 里面axi master module对应的hierarchy。如:axi_master_if[0].m_init($sformatf(“isp_top_tb.axi_intf_master_if[%0d]”,0));
- 在cfg里面定义axi_master_config,并且创建。
- env里面定义axi_agent,并且创建。将cfg里面的axi_master_config赋值给axi_master_agent.cfg。调用veloce_do_axi_master_config函数配置master cfg。
- 从test_top 通过config_db::get 获取axi_master_if,赋值给axi_master_agent.cfg,m_bfm。
添加questa apb master vip,方法同questa axi vip一致。
添加memory model 作为axi slave mem
- 在hdl top里面例化memory model module,并且在hdl top里面将dut 连接到memory model module。此时,dut就能正常使用memory model。
- 在base_test以memory model module里面mem的hierarchy初始化memory model的handle,以方便hvl从后门操作memory model。至此,hvl 可以通过hanlde里面的方法后门操作memory model。
active_system_shared_mem = new(”isp_top_tb.axi_intf_slave_if[0].axiSlave.memoryTransactor.memArray”);
无论对于vcs questa还是veloce,验证代码都是调用vip_mem_write_byte、vip_mem_read_byte、vip_mem_write_128bits、vip_mem_read_128bits后门操作memory。
对于veloce,使用scemi_mem_put_block_of_bytes和scemi_mem_get_block_of_bytes后门操作mem。对于questa,使用backdoor_read 和backdoor_write后门操作axi slave。
2.4 Testbench修改
将环境中top_tb拆分成两个top,分别为hdl_top和hvl_top。
2.4.1 hdl_top
hdl_top包括DUT,amba vip,memory model的例化与连接。
- 例化apb master module(vtl_apb_master_module),并且连接到dut apb slave interface。
- 例化axi_master module(mgc_xrtl_axi3_master),并且连接到dut axi slave interface。
- 例化axi memory model(axi_slave_intf_for_mem_model),并且将dut axi master interface 连接到memory model。
2.4.2 hvl_top
hvl_top包括对应amba vip与interace初始化。
例化apb interface(mgc_apb3),bind到hdl 侧apb master module对应的hierarchy,并且config到验证环境,供验证环境发送apb激励使用。
1
2apb3_master_if.m_init("isp_top_tb.apb_intf");
uvm_config_db#(apb3_if_t)::set(null, "uvm_test_top.env", "APB3_MASTER_IF", apb3_master_if);例化axi master interface(mgc_axi),bind到hdl侧 axi master module对应的hierarchy,并且config到验证环境,供验证环境发送axi激励使用。
1
2axi_master_if[0].m_init($sformatf("isp_top_tb.axi_intf_master_if[%0d]", 0));
uvm_config_db#(axi_if_t)::set(null, "uvm_test_top.env", $sformatf("AXI_MASTER_IF_0"), axi_master_if[0]);
2.4.3 clk_rst
- clk产生:clk 通过clk file 配置产生,文件路径为sim_vel/clk_file。
1
2
3
4
5
6#clk_file语法
CLOCK <clock_name> -base_clk <base_clock_name> -divide_by <positive_integer>
CLOCK <clock_name> <frequency> [inactive_negedge | both_edge] [-divide_by <positive integer>] -phase <phase_degree>
CLOCK <clock_name> -alias <base_clock_name>
#指定精度
PRECISION <value><us|ns|ps>
- clock_name:clk 的整个hierarchy 路径。
- frequency:clk 频率,必须是正整数,单位为 kHz, MHz, 或者 GHz。
- positive_integer:分频因子,如CLOCK top.clock1 100 MHz -divide_by 3
- phase_degree:相位 (0-360) 。不支持小数,只允许使用整数或者分数,如相位为22.5,语法为”45/2”。
- base_clock_name:对齐的clk名称
- 精度可以是任意值,单位为us、ns、或者ps
- rst 通过hdl top里面clk_reset module 产生。
3. Veloce仿真
完成环境的修改后,需要先配置环境变量进行调试。
3.1 配置环境变量
source 系统环境变量,为支持分布式编译,脚本会自动执行ssh免密登录操作,在终端根据命令行操作,默认选择yes。
1 | cd sim_vel |
配置UVM 相关的环境变量
1 | setenv QUESA_MVC_HOME /home/emu/Veloce_Transactors_Library/Veloce_Transactors_Library_v21.2/questa_xvip_uvm |
配置QVIP相关的环境变量
1 | setenv VTL_AXI3_VERSION axi3_v2 |
配置memory model相关环境变量
1 | setenv AXI_SLAVE_MODEL_PATH /home/emu/VirtualLAB/VirtualLAB_v2.2.0/devices/SoftModelMemories/AMBA_AXI_SlaveSoftmodelMemory_4.0.0.0 |
配置GCC相关环境变量
1 | setenv LIB_PLATFORM linux64_el30_gnu74 |
配置验证环境使用的HDL_TOP 和HVL_TOP
1 | setenv HDL_TOP hdl_top_tb |
3.2 编译
编译之前先确保veloce.config、clk_file、run.do、run.tcl在编译目录下, 并且修改modelsim.ini文件,去掉里面的mtiUVm库(不使用questa 默认UVM库,自己编译UVM库)。
编译hdl,建立work库
1 | vlib work |
如果需要编译网表,使用velanalyze编译网表
1 | velanalyze -f sim_vel_netlist.f -gate |
编译UVM1.2
1 | velanalyze -extract_hvl_info +incdir+home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvvm-1.2/src +home/emu/veloce_sw/questa_21_1/questasim/verilog_src/srvuvvm-1.2/src/srvuvvm_pkg.sv /home/emu/velocesw/questa_21_1/questasim/verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv -F /project/polestar/worktree/wgan/Kuiper/trunk/dv_new/ip_env/isp/sim_vl/hv1.f +define+UVM_NO_DEPRECATED +define+UVM_PACKER_MAX_BYTES=1500000 +define+UVM_DISABLE_AUTOITEM_RECORDING |
编译scemi_dmi,用于后门访问memory model
1 | vlog -f veloce/v2102/Veloce_v21.0.2/tbx/questa/hdl/scemi_dmi_sy_file_files.f |
编译axi memory model
1 | velanalyze +define+XL_FLEX_SLAVE_XACTOR -f /home/emu/VirtuaLAB/VirtuaLAB_v21.2/devices/SoftModelMemories/AMBA_AXI_SlaveSoftmodelMemory_4.0.0/hdl/axi_slave_core.f |
编译hdl 文件(包括QVIP,DUT RTL代码,验证环境XRTL代码)。
1 | velanalyze -f hdl_veloce.f |
指定top
1 | velcomp -top top_tb |
编译hvl,hvl也需要编译UVM1.2
1 | vlog +incdir+home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvvm-1.2/src +home/emu/veloce_sw/questa_21_1/questasim/verilog_src/srvuvvm-1.2/src/srvuvvm_pkg.sv /home/emu/velocesw/questa_21_1/questasim/verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv -F /project/polestar/worktree/wgan/Kuiper/trunk/dv_new/ip_env/isp/sim_vl/hv1.f +define+UVM_NO_DEPRECATED +define+UVM_PACKER_MAX_BYTES=1500000 +define+UVM_DISABLE_AUTOITEM_RECORDING |
编译验证环境代码(包括QVIP代码,testbench,scoreboard,env,agents,testcases等)
1 | vlog -f hvl.f -l hvl_comp.log |
编译hvl和hdl交互使用的tbx库
1 | velhvl -g -sim veloce -64bit runtime -ldflag "-Wl,--whole-archive /home/emu/Veloece_Transactors_Library/Veloece_Transactors_Library_v21.2/common/lib/linux64_e130_gnu74/libcommontbx.a /home/emu/Veloece_Transactors_Library/Veloece_Transactors_Library_v21.2/apb_v2/lib/linux64_e130_gnu74/libapb_v2tbx.a /home/emu/Veloece_Transactors_Library/Veloece_Transactors_Library_v21.2/axi_v2/lib/linux64_e130_gnu74/libaxi_v2tbx.a -Wl,--no-whole-archive" -cppinstall 7.4.0 |
指定top,优化成opt_design,在运行时不必再次执行vopt(三步法编译)
1 | vopt hvl_top_tb hdl_top_tb TbxSvManager -o opt_design |
3.3 运行
运行指令如下所示,opt_design是经过vopt之后的库文件:
- -c opt_design:在command line中运行opt_design
- -cppinstall 7.4.0:指定gcc版本
- -sv_lib uvm_dpi:指定uvm_dpi 库
- -do “run.tcl”:运行run.tcl 脚本
- -mvchome:指定QVIP UVM路径
- -t 1ns:强制指定hvl 时间单位为1ns,否则hvl的时间精度是clk_file中指定的时间精度的千分之一
1 | vsim -c opt_design -cppinstall 7.4.0 -sv_lib uvm_dpi -do "run.tcl" -mvchome /home/emu/Veloece_Transactors_Library/Veloece_Transactors_Library_v21.2/guesta_xvip_uvm "+UVM_VERBOSITY=UVM_LOW" "+define+UVM_NO_DEPRECATED" -t lns "+UVM_TESTNAME=wo_frame" "+dump_en=0" "+nb_random_seed=778574" "+test_timeout_ns=0" "+max_quit_count=1000" "+ddr2dvp_enable=1" "+snrl_sc_en=1" "+raw_crop_snrl_en=1" "+isp_dis2isp_reg0=0" "+isp_dis2isp_reg0=0" "+snr_width_in=1916" "+snr_height_in=1076" "+yam1_test_name=v2_ddr mode case_4_size_1916_1076" |
run.tcl:使用vsim 执行veloce 命令时用velocecmd调用run.do
1 | velocecmd "do run.do" |
run.do: 脚本为veloce cmd,包含关闭hwtrace dump波形方法,打开xwave dump波形方法,初始化xwave,选择需要dump 的波形的group,运行case,等待case运行完成关闭xwave,退出。
1 | hwtrace off |
3.4 Log分析
veloce.log/compile_rtlc_0.log: hdl编译log
veloce.log/compile_hvl_0.log: hvl编译log
veloce.log/compile_velsyn_0.log: 查看使用多少块板子和Luts、Flip-flops使用情况。
veloce.log/compile_velgs_0.log: 查看实际跑到的频率
veloce.log/simulation_profile.log:记录case运行时间,各个模块消耗时间,用户可以通过分析此文件,针对性优化case运行速度
veloce.log/transacript:运行log路径。这个文件会记录case运行的log,包括veloce系统log和测试代码log。通过分析此文件可以确定case运行结果。
4. 加速性能
在相同的随机种子下,VCS上运行需要花费3天时间的任务,经过veloce加速之后仅需30分钟。时间统计结果如下图所示:其中Hardware Time为DUT运行时间,Software Time为UVM环境运行时间,Communication Time为HDL与HVL交互时间,Hardware Stall Time为DUT为通信而挂起等待的时间。
![](/images/dv-emulator-env/2.png)