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,设置是不是非常杂乱,请删除不用的,尽量保持干净。

Chiel Keep变量名

how to keep chisel variable name when generate verilog

There are several reasons why a name may be disappearing.

Constant Propagation
For many reasons, including interoperability with existing CAD tools, performance, and Verilog debug-ability, Chisel (actually the FIRRTL compiler underneath Chisel) will propagate constants and direct wire connections. For example:

Chisel组合逻辑时序逻辑

时序逻辑的声明和写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
实例1
val tiRomStartAddr = RegInit(0.U(6.W)) //显示的声明Reg
when (io.swif.K<40.U ){tiRomStartAddr := 25.U }
.elsewhen (io.swif.K<159.U ){tiRomStartAddr := 21.U }
.elsewhen (io.swif.K<200.U ){tiRomStartAddr := 35.U }
.elsewhen (io.swif.K<481.U ){tiRomStartAddr := 15.U }
.elsewhen (io.swif.K<530.U ){tiRomStartAddr := 10.U }
.elsewhen (io.swif.K<2881.U){tiRomStartAddr := 5.U }
.otherwise {tiRomStartAddr := 25.U }
实例2
val RRomRdata = RegInit(0.U(log2Up(pm.MaxR).W)) //显示的声明Reg并初始化(switch语句不带default)
switch (io.RRomAddr) {
is (0.U) {RRomRdata := intraRowTi.RRomVal(0).U}
is (1.U) {RRomRdata := intraRowTi.RRomVal(1).U}
is (2.U) {RRomRdata := intraRowTi.RRomVal(2).U}
is (3.U) {RRomRdata := intraRowTi.RRomVal(3).U}
is (4.U) {RRomRdata := intraRowTi.RRomVal(4).U}
is (5.U) {RRomRdata := intraRowTi.RRomVal(5).U}
is (6.U) {RRomRdata := intraRowTi.RRomVal(6).U}
is (7.U) {RRomRdata := intraRowTi.RRomVal(7).U}
}

Chisel 实例问题汇总

chisel-example \ chisel-tutorial 同样代码,生成器输出不一致问题

同样的一份代码
src/main/scala/GCD.scala
src/test/scala/GCDTester.scala

其中生成vcd波形的代码

1
2
3
4
5
object GCDTester extends App {
iotesters.Driver.execute(Array("--target-dir", "generated", "--fint-write-vcd"), () => new GCD){
c => new GCDTests(c)
}
}

从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");

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

Chisel-Verilog查找表优先级问题讨论

Chisel 查找表电路优先级问题

verilog ROM的两种写法及区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
方法1
always @(posedge clk )
begin
case(addr0)
6'd0 : data0 <= 8'd214;
6'd1 : data0 <= 8'd213;
6'd2 : data0 <= 8'd212;
6'd3 : data0 <= 8'd211;
6'd4 : data0 <= 8'd210;
6'd5 : data0 <= 8'd209;
6'd6 : data0 <= 8'd208;
6'd7 : data0 <= 8'd207;
方法2
always @(posedge clk )
begin
if(addr1 == 6'd0 ) data1 <= 8'd150;
else if(addr1 == 6'd1 ) data1 <= 8'd149;
else if(addr1 == 6'd2 ) data1 <= 8'd148;
else if(addr1 == 6'd3 ) data1 <= 8'd147;
else if(addr1 == 6'd4 ) data1 <= 8'd146;
else if(addr1 == 6'd5 ) data1 <= 8'd145;
else if(addr1 == 6'd6 ) data1 <= 8'd144;
else if(addr1 == 6'd7 ) data1 <= 8'd143;

方法2是不是带优先级? 实际上是不带优先级
逻辑上if取的条件都是addr1的值,一定是互斥的,综合工具也能自动识别出这种if else
它有别于以下这种情况,这种情况下是真实带有优先级的电路,其中another_cond_A,another_cond_B
是独立的两个输入条件,和addr1的取值可能同时发生,所以不能被综合器当做查找表来对待。

Terminal配置常见问题

Teriminal 配置常见问题

    1. ls后文件名包含引号,例如 'Program file'

      在 ~/.zshrc 里面配置

    1. MACOS ls 目录后没有颜色显示,

      'alias ls =/bin/ls -G' , 一定要指到/bin/ls

    1. 其他

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