0%

UVM+Emulator硬件加速联合仿真


1. 环境结构

基于西门子Veloce的UVM硬件加速验证平台,其主要覆盖IP仿真加速,SOC系统验证,应用场景功耗分析等几个方面。验证环境采用的目录结构与pioneer #1保持一致。

采用硬件加速之后,DUT运行的时间极大的缩短,相比较与VCS仿真,可提高运行速度120倍左右。

Veloce硬件平台的结构如图所示。

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的寄存器模型。如图所示:

宏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
    4
    task xxx(input xxx ,output xxx)//pragma tbx xtf
    @(posedge/negedge clk)
    .......
    endtask
  • task或function中的参数类型只能是input或output

  • 默认编译内存大小为32GB,在veloce.config中添加rtlc -inc_vle_mem_limit可解除编译内存大小限制

  • interface中支持文件操作,$fopen,$fread,$fwrite,$fscanf,$fclose。文件操作会编译成硬件资源,有一定的限制(可查阅veloce ug查看详细信息)

  1. $fscanf,$fread的文件句柄不能使用数组表示
  2. $fscanf只能扫描出32bit的数据,超过32的高位无法扫描
  3. 对同一个文件句柄,仅支持一个$fread操作
  4. 无论采用二进制写还是文本写,$fwrite格式化%h到文件中的都是ASCII类型,格式化%c输出到文件中的是二进制数据
  5. 推荐使用二进制的$fwrite和$fread操作,如下所示
1
2
3
4
5
6
7
fp0 = $fopen("xxx","wb");
$fwrite(fp0,"%c",data_ceil8);
.......
fp1 = $fopen("xxx","rb");
$fread(data_ceil8_big_endian,fp1);// big endian
// swap endian
data_ceil8_little_endian = {<<8{data_ceil8_big_endian}};
  • 声明为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
    2
    wait(sig_name);
    @(posedge clk);
  • 对于特殊情况而言,即wait后可以跟foerever语句或repeat语句后再跟一个clk

    1
    2
    3
    wait(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

    1. 在hdl top里面例化axi master module,并且在hdl top将axi master module连接到dut。
    2. 在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));
    3. 在cfg里面定义axi_master_config,并且创建。
    4. env里面定义axi_agent,并且创建。将cfg里面的axi_master_config赋值给axi_master_agent.cfg。调用veloce_do_axi_master_config函数配置master cfg。
    5. 从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

    1. 在hdl top里面例化memory model module,并且在hdl top里面将dut 连接到memory model module。此时,dut就能正常使用memory model。
    2. 在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
    2
    apb3_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
    2
    axi_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>
  1. clock_name:clk 的整个hierarchy 路径。
  2. frequency:clk 频率,必须是正整数,单位为 kHz, MHz, 或者 GHz。
  3. positive_integer:分频因子,如CLOCK top.clock1 100 MHz -divide_by 3
  4. phase_degree:相位 (0-360) 。不支持小数,只允许使用整数或者分数,如相位为22.5,语法为”45/2”。
  5. base_clock_name:对齐的clk名称
  6. 精度可以是任意值,单位为us、ns、或者ps
  • rst 通过hdl top里面clk_reset module 产生。

3. Veloce仿真

完成环境的修改后,需要先配置环境变量进行调试。

3.1 配置环境变量

source 系统环境变量,为支持分布式编译,脚本会自动执行ssh免密登录操作,在终端根据命令行操作,默认选择yes。

1
2
cd sim_vel
source sourceme

配置UVM 相关的环境变量

1
2
3
setenv QUESA_MVC_HOME /home/emu/Veloce_Transactors_Library/Veloce_Transactors_Library_v21.2/questa_xvip_uvm
setenv UVM_HOME /home/emu/veloce_sw/questasim/verilog_src/uvm-1.2
setenv UVM_LIB /home/emu/veloce_sw/questasim/uvm-1.2/src

配置QVIP相关的环境变量

1
2
3
setenv VTL_AXI3_VERSION axi3_v2
setenv VTL_APB_V2_VERSION apb3_v2
setenv VTL_AXI_V2_VERSION axi_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
2
3
4
5
6
7
setenv LIB_PLATFORM linux64_el30_gnu74
setenv GCC_VER 7.4.0
setenv gcc_ver 740
setenv GNUHOME /home/emu/Veloce_Transactors_Library/Veloce_Transactors_Library_v21.2/questa_xvip_uvm/bin/med-tools/linuxRH7/gcc-7.4.0/bin/gcc
setenv GCC_EXE /home/emu/Veloce_Transactors_Library/Veloce_Transactors_Library_v21.2/questa_xvip_uvm/bin/med-tools/linuxRH7/gcc-7.4.0/bin/gcc
setenv PATH "/home/emu/Veloce_Transactors_Library/Veloce_Transactors_Library_v21.2/questa_xvip_uvm/bin/med-tools/linuxRH7/gcc-7.4.0/bin:$PATH"
setenv VELCE_GCC_PATH /home/emu/Veloce_Transactors_Library/Veloce_Transactors_Library_v21.2/questa_xvip_uvm/bin/med-tools/linuxRH7/gcc-7.4.0/bin/gcc

配置验证环境使用的HDL_TOP 和HVL_TOP

1
2
setenv HDL_TOP hdl_top_tb
setenv HVL_TOP hv1_top_tb

3.2 编译

编译之前先确保veloce.config、clk_file、run.do、run.tcl在编译目录下, 并且修改modelsim.ini文件,去掉里面的mtiUVm库(不使用questa 默认UVM库,自己编译UVM库)。

编译hdl,建立work库

1
2
vlib work
vmap work work

如果需要编译网表,使用velanalyze编译网表

1
velanalyze -f sim_vel_netlist.f -gate

编译UVM1.2

1
2
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
gcc -m64 -fPIC -DQUESTA -g -W -shared -x c -I/home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvm-1.2/src/dpi -I/home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvm-1.2/src/../../../include /home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvm-2.2/src/dpi/uvm_dpi.cc -o uvm_dpi.so

编译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
2
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
gcc -m64 -fPIC -DQUESTA -g -W -shared -x c -I/home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvm-1.2/src/dpi -I/home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvm-1.2/src/../../../include /home/emu/veloce_sw/questa_21_1/questasim/verilog_src/uvm-2.2/src/dpi/uvm_dpi.cc -o uvm_dpi.so

编译验证环境代码(包括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
2
velocecmd "do run.do"
quit -f

run.do: 脚本为veloce cmd,包含关闭hwtrace dump波形方法,打开xwave dump波形方法,初始化xwave,选择需要dump 的波形的group,运行case,等待case运行完成关闭xwave,退出。

1
2
3
4
5
6
7
8
9
hwtrace off
xwave on
xwave deselct_all_groups
xwave -init axi_vip_tbx
xwave -select_group clk_and_rst
run
wait runcomplete
xwave off
quit

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为通信而挂起等待的时间。