Spinal-sim Verilator install on Windows

Verilator install on Windows

Step1 : install MSYS32

到官网https://www.msys2.org/ 下载最近安装文件 msys2-x86_64-20190524.exe

运行安装到d:/msys64,安装完毕后打开 mingw64.exe

在命令行输入 pacman -Suyy

如果遇到以下异常

1
2
3
4
5
# pacman -Syuu
错误:无法初始化事务处理 (无法锁定数据库)
错误:无法锁定数据库:File exists
如果你确认软件包管理器没有在运行,
你可以删除 /var/lib/pacman/db.lck。

解决办法,删掉之前的文件: /var/lib/pacman/db.lck
出现错误的原因是,之前同步的时候,由于异常中断,导致之前进程锁文件未被释放。

Step2 Change mirrors for China user

如果更新库很慢导致失败

1
2
3
4
5
6
7
# pacman -Syuu
:: 正在同步软件包数据库...
错误:无法从 repo.msys2.org : Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds 获取文件 'mingw32.db'] 49%
错误:无法从 sourceforge.net : Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds 获取文件 'mingw32.db' 3%
错误:无法从 www2.futureware.at : Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds 获取文件 'mingw32.db'7%
错误:无法从 mirror.yandex.ru : Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds 获取文件 'mingw32.db' 10%
错误:无法升级 mingw32 (下载数据库出错)

请更新 清华镜像

编辑 /etc/pacman.d/mirrorlist.mingw32 ,在文件开头添加:

1
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686

编辑 /etc/pacman.d/mirrorlist.mingw64 ,在文件开头添加:

1
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64

编辑 /etc/pacman.d/mirrorlist.msys ,在文件开头添加:

1
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch

然后执行 pacman -Sy 刷新软件包数据即可。

Step3: Install Verilator

1
2
3
4
5
6
pacman -Syuu
#Close the MSYS2 shell once you're asked to
pacman -Syuu
pacman -S --needed base-devel mingw-w64-x86_64-toolchain \
git flex\
mingw-w64-x86_64-cmake
1
pacman -S mingw-w64-x86_64-verilator

Step4: Add to ENV

Add D:\msys64\usr\bin;D:\msys64\mingw64\bin to you windows PATH

Step4: Spinal simulation by verialtor

1
2
3
4
5
6
7
8
9
10
11
12
[Progress] Verilator compilation started
VDFT2Cell.mk:67: /mingw64/share/verilator/include/verilated.mk: No such file or directory
make: *** No rule to make target '/mingw64/share/verilator/include/verilated.mk'. Stop.
Exception in thread "main" java.lang.AssertionError: assertion failed: Verilator C++ model compilation failed
at scala.Predef$.assert(Predef.scala:170)
at spinal.sim.VerilatorBackend.compileVerilator(VerilatorBackend.scala:376)
at spinal.sim.VerilatorBackend.<init>(VerilatorBackend.scala:429)
at spinal.core.sim.SpinalVerilatorBackend$.apply(SimBootstraps.scala:120)
at spinal.core.sim.SpinalSimConfig.compile(SimBootstraps.scala:400)
at spinal.core.sim.SpinalSimConfig.compile(SimBootstraps.scala:364)
at FFT.DFT2CellTest$.main(FFTsim.scala:27)
at FFT.DFT2CellTest.main(FFTsim.scala)

显示verilated.mk路径找不到,我忍为应该是VERILATOR_ROOT目录设置有误, 查找verilated.mk的目录所在地,
然后在windows Env 中添加系统变量 VERILATOR_ROOT= /d/msys64/mingw64/share/verilator

任然遇到问题

1
2
3
4
5
6
7
8
9
x86_64-w64-mingw32-g++.exe: error: /d/msys64/mingw64/share/verilator/include/verilated.cpp: No such file or directory
x86_64-w64-mingw32-g++.exe: fatal error: no input files
compilation terminated.
make: *** [/d/msys64/mingw64/share/verilator/include/verilated.mk:192: verilated.o] Error 1
make: *** Waiting for unfinished jobs....
x86_64-w64-mingw32-g++.exe: error: /d/msys64/mingw64/share/verilator/include/verilated_vcd_c.cpp: No such file or directory
x86_64-w64-mingw32-g++.exe: fatal error: no input files
compilation terminated.
Exception in thread "main" java.lang.AssertionError: assertion failed: Verilator C++ model compilation failed

x86_64-w64-mingw32-g++.exe 不能访问/d/myss64/….,后来重新安装MSYS2到 C盘,并且将系统变量删除 VERILATOR_ROOT

任然遇到问题:
检查环境变量Paht的值为C:\Users\Administrator\.babun\cygwin\bin;D:\Program\emacs-26.2\bin;C:\Users\Administrator\.babun;C:\Users\Administrator\AppData\Roaming\npm;%IntelliJ IDEA Community Edition%;C:\Users\Administrator\AppData\Local\Pandoc\;c:\msys64\usr\bin\;c:\msys64\mingw64\bin\ 发现很乱 ,删除一些不用的
D:\Program\emacs-26.2\bin;C:\Users\Administrator\.babun;C:\Users\Administrator\AppData\Local\Pandoc\;c:\msys64\usr\bin\;c:\msys64\mingw64\bin\;
更新PATH

重新开启Project , 运行Spinal-sim ,Wow 居然成了, 非常痛苦, 饶了一大圈,居然是PATH变量的问题。总算是解决了

最后:

特别注意:

尽量把MSYS2安装到C盘 在环境变量Path末尾追加C:\msys64\usr\bin;C:\msys64\mingw64\bin

不要多此一举设置VERILATOR_ROOT, Spinal会默认识别到 /mingw64/share/verilator

如果运行不成功,请检查你的PATH,设置是不是非常杂乱,请删除不用的,尽量保持干净。

从Shell传递变量给verilog的两种方法

  • 通过define宏传递

    首先在命令行中定义define

    1
    2
    3
    4
    5
    6
    7
    vcs -sverilog -debug_all +define%s+CASENAME=\"%s\" 
    -timescale=1ns/100ps
    +notimingcheck
    +nospecify +v2k +memcbk
    -fsdb
    -l com.log
    -f top.f

    尤其要注意CASENAME=\"%s\"的转义“\”的应用,比如命令行被包含在python脚本内部,需要两次转义, 而shell可能只要一次

    1
    2
    3
    def run(case,defines=""):
    os.system('vcs -sverilog -debug_all +define%s+CASENAME=\\"%s\\" -timescale=1ns/100ps +notimingcheck +nospecify +v2k +memcbk -fsdb -l com.log -f top.f'%(defines,case))
    os.system('./simv -l sim.log +notimingcheck +nospecify +loopreport +memcbk +novopt')

    否则verilog文件是无法获取CASENAM的意思

    然后在verilog中通过宏取出

    1
    fp_reg = $fopen({"./case/",`CASENAME,"/source_dpp.txt"},"r");

    这种方式比较繁琐,而且转义嵌套难以理解,另外一种方便的方法如下

SBT 版本问题

QA

    1. sbt 指向 “java -Dsbt.ivy.home=/nishome/jijing/ivy2 -jar /DATA/jijing/rocket-chip/sbt-launch.jar”

现象
ivy2 也是最新的,包含 org.scala-lang#scala-library;2.11.12 正确的版本号

依然会报错!!

1
2
3
4
5
[warn] 	::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.scala-lang#scala-library;2.11.12: public: unable to get resource for org/scala-lang#scala-library;2.11.12: res=https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.11.12/scala-library-2.11.12.pom: java.net.UnknownHostException: repo1.maven.org: Temporary failure in name resolution
[warn] ::::::::::::::::::::::::::::::::::::::::::::::

原因

~/.sbt 目录可能存在旧的版本,导致问题,

解决

删除 ~/.sbt 目录,如果联网,直接重新sbt run ,会自动下载更新,否则copy 别的机子上正确的 .sbt 到home 目录下。

    1. IDEA,rochi-chip:sync failed ,但在terminal下正常编译 ,也是~/.sbt导致的
    1. C 程序编译好的.out文件不能再 rocket-chip/emulator 目录下运行,而 run-asm-isa-test 则会没有问题

这是由于直接用rvgcc 编译的文件,并没有按照处理器的格式做link,因此想要正确的在处理器上运行,需要正确的link

可以参见 bootrom/link.lds 文件 :

1
2
3
4
5
6
7
8
9
10
11
 1 SECTIONS 
2 {
3 ROM_BASE = 0x10000; /* ... but actually position independent */
4
5 . = ROM_BASE;
6 .text.start : { *(.text.start) }
7 . = ROM_BASE + 0x40;
8 .text.hang : { *(.text.hang) }
9 . = ROM_BASE + 0x80;
10 .rodata.dtb : { *(.rodata.dtb) }
11 }

rvgcc -T link.ld bootrom.S -nostdlib -static -wl,--no-gc-section -o bootrom.img

同理C代码编译的时候也需要使用正确的linkfile 文件 。

如何编译指定CPU的可执行文件

必要信息:

  • $(CC) 需要默认的target (例如intel x86, AMD64, MIPS 等等, 如果RISCV, 需要支持的指定指令集 (例如 rv32imc rv64g,rv32imdfc 等等)
  • link 脚本,如果不指定,会有导入默认的脚本,否则需要显示指定,尤其是自己设计的处理器,需要显式的指定堆栈起始地址,程序默认存放地址,这些信息响应的也会体现在CPU硬件设计当中。需要正确match
1
2


综合时序分析回顾

时序分析

静态时序分析工具STA,在分析时序的时候会统一从一个点出发开始计算分析(这样才有可行性),往往是从时钟PLL出来以后开始计算

一般情况下都会设一个clock network delay 表示从PLL 到寄存器段clk的群延迟 ,理想情况下,到每个寄存器的群延迟都是一样的(时钟balance)
寄存器

路径计算

看一个timing报告:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
****************************************

Startpoint: U_xx/_ram_sp1024x8/srsp_1024x8
(rising edge-triggered flip-flop clocked by clk)
Endpoint: U_xx/nS_bit_reg_1_
(rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max

Des/Clust/Port Wire Load Model Library
------------------------------------------------
xx_top ZeroWireload tef40ulp128x8hd_ph_ssg0p99v2p25vm40c

Point Incr Path
--------------------------------------------------------------------------
clock clk (rise edge) 0.0000 0.0000
clock network delay (ideal) 2.0000 2.0000 #时钟群延迟设为2ns
xx/srsp_1024x8/CLK (sadr41p1024x8m4b1) 0.0000 2.0000 r #arrival + 2ns
xx/srsp_1024x8/Q[0] (sadr41p1024x8m4b) 2.2361 4.2361 f
xx/U37/X (SVN_ND2_T_2) 0.0290 4.2651 r
xx/U47/X (SVN_ND2_2) 0.0323 4.2974 f
....
..
xx/U188/X (SVN_EN2_F_1) 0.0956 4.8690 f
xx/nS_bit_reg_1_/D (SVN_FSDPRBQ_D_4) 0.0000 4.8690 f
data arrival time 4.8690


clock clk (rise edge) 3.3300 3.3300 #300Mhz = 3.33ns
clock network delay (ideal) 2.0000 5.3300 #required + 2 =5.33ns
clock uncertainty 0.3000 5.0300 #恶化抖动
xxx/nS_bit_reg_1_/CK (SVN_FSDPRBQ_D_4) 0.0000 5.0300 r
library setup time 0.3303 4.6997 #- setup time
data required time 4.6997
--------------------------------------------------------------------------
data required time 4.6997 # = clk_arvl_time - Setuptime - skew
data arrival time -4.8690 #
--------------------------------------------------------------------------
slack (VIOLATED) -0.1693

****************************************

Clock Setup Slack = Data Required Time – Data Arrival Time

Clock Arrival Time = Latch Edge + Clock Network Delay to Destination Register

Data Required = Clock Arrival Time – μtSU – Setup Uncertainty

Data Arrival Time = Launch Edge + Clock Network Delay Source Register + μtCO + Register-to-Register Delay

VCS仿真option

VCS、verdi的命令的配置

该Makefile可作为仿真工作脚本,参考了开源处理器蜂鸟e200的仿真环境

https://github.com/SI-RISCV/e200_opensource/blob/master/vsim/bin/run.makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
RUN_DIR      := ${PWD}

TESTCASE := 00
DUMPWAVE := 1

VSRC_DIR := ${RUN_DIR}/../rtl
VTB_DIR := ${RUN_DIR}/../tb
INC_DIR := ${RUN_DIR}/../rtl/dir_inc_defines1
INC_DIR += ${RUN_DIR}/../rtl/dir_inc_defines2
# TESTNAME := $(notdir $(patsubst %.dump,%,${TESTCASE}.dump))
TESTNAME := case${TESTNAME}
TEST_RUNDIR := ${TESTNAME}

RTL_V_FILES := $(wildcard ${VSRC_DIR}/*/*.v)
TB_V_FILES := $(wildcard ${VTB_DIR}/*.v)

# The following portion is depending on the EDA tools you are using, Please add them by yourself according to your EDA vendors
SIM_TOOL := vcs # this is a free solution here to use iverilog to compile the code
SIM_OPTIONS := -sverilog -debug_all +incdir+${INC_DIR} -timescale=1ns/100ps +notimingcheck +nospecify +v2k +memcbk -fsdb -l com.log
SIM_EXEC := ${RUN_DIR}/simv -l sim.log +notimingcheck +nospecify +loopreport +memcbk +novopt

WAV_TOOL := verdi #To-ADD: to add the waveform tool
WAV_OPTIONS := -timescale=1ns/100ps +notimingcheck +nospecify #To-ADD: to add the waveform tool options
WAV_PFIX := #To-ADD: to add the waveform file postfix

all: run

compile.flg: ${RTL_V_FILES} ${TB_V_FILES}
@-rm -rf compile.flg
${SIM_TOOL} ${SIM_OPTIONS} ${RTL_V_FILES} ${TB_V_FILES} ;
touch compile.flg

compile: compile.flg

wave:
# gvim -p ${TESTCASE}.spike.log ${TESTCASE}.dump &
${WAV_TOOL} ${WAV_OPTIONS} ${RTL_V_FILES} ${TB_V_FILES} &

run: compile
rm -rf ${TEST_RUNDIR}
mkdir ${TEST_RUNDIR}
cd ${TEST_RUNDIR}; ${SIM_EXEC} +DUMPWAVE=${DUMPWAVE} +TESTCASE=${TESTCASE} |& tee ${TESTNAME}.log; cd ${RUN_DIR};

.PHONY: run clean all

Verilog仿真不打拍分析

现象

例如:
1
出现:
2

原因

这是由于采样的时钟tx_gen_symbol_clk 和数据信号subframe_start之间存在竞争关系导致的。
我们的设计意图是时钟tx_gen_symbol_clk应该采到subframe_start信号的后沿
3
有人可能会说在代码中加入延迟#1来解决,实际上不推荐这样做,还会存在两个#1的信号同样还会存在竞争。

仿真模型原理分析

要搞清楚产生这种问题的原因首先要了解仿真器对于时序仿真的模型。
4
第4级的时钟不能正常采到第3级输出的数据,但是第2级的时钟能采到第二级时钟打出来的数据(D3),
原因就是,仿真器会在寄存器输出的时候添加一个虚拟的延迟δ,虽然这个虚拟延迟我们是看不到的,
在仿真器上都是0,但是对于仿真器工作的时候,到遇到always采样事件时先要判断这个δ延迟,决定触发器的采样输出。
(当延迟相等时,clk延迟的优先级会比data延迟的优先级高,即clk1能采到D1的前沿, 也就是我们看到的数据不打拍,这跟我们的预期是不一致的,
而clk1能采不到D2的前沿,但能采到D2的后沿,这跟我们的预期一样的。这些讨论仅限于前仿,
实际器件上我们必须有时序约束来保证建立保持时间,也不会存在这样的问题。
但是硬件设计就是要保证仿真和物理器件一致。因此我们要注意这个现象。
5

如何解决

在你的TB里时钟都由一个单独的模块产生送给DUT,不管产生多少个时钟,这些时钟保证都经历了n级分频下来的然后送入DUT,这样数据就不会出现不delay的现象。