尝试学习 Chisel 语言,“工欲善其事,必先利其器”, 因此先扫除环境问题。
基础环境
本笔记使用的基础环境是 ubuntu 16.04 , Idea 进行开发, 在 ubuntu 中安装如下工具
名称 | 描述 |
---|---|
verilator | RTL仿真平台, rocket-chip 默认仿真平台 |
iverilog | RTL仿真平台,执行编译,生成的文件通过vvp执行仿真 |
gtkwave | 图形化波形显示 |
通过如下命令进行安装:
$ sudo apt install -y verilator iverilog gtkwave git
iVerilog 使用方法
选项 | 说明 |
---|---|
-D macro[=def ] | 定义宏 |
-I incdir | 等同于-incdir |
-o filename | 指定输出的可执行文件名 |
-s topmodule | 等同于-top |
-y libdir | 等同于-y |
例如:
- 编写简单的模块 Adder.v
module Adder(
input [7:0] io_in0,
input [7:0] io_in1,
output [7:0] io_out
);
wire [8:0] _T_11;
assign _T_11 = io_in0 + io_in1;
assign io_out = _T_11[7:0];
endmodule
- 编写测试用例 AdderTester.v
module AdderTester;
reg[7:0] in0;
reg[7:0] in1;
wire[7:0] out;
initial begin
// 从这里开始是输入参数
// 第 1 组参数
in0 = 8'h35;
in1 = 8'h56;
// 第 2 组参数
#1 in0 = 8'h39;
in1 = 8'h28;
// 第 3 组参数
#1 in0 = 8'h10;
in1 = 8'h09;
// 第 4 组参数
#1 in0 = 8'h15;
in1 = 8'h20;
// 停止测试
#1 $stop;
end
// 配置 Adder 模块的引脚配置
Adder AdderInstance(
.io_in0(in0),
.io_in1(in1),
.io_out(out)
);
// 打印波形文件
initial begin
// 输出 vcd 文件,最后通过 gtkwave 文件进行显示
$dumpfile("AdderTester.vcd");
$dumpvars(0, AdderTester);
end
endmodule
- 进行仿真
$ iverilog -o test Adder.v AdderTester.v
$ vvp -n test
gtkwave 波形
通过如下命令查看 vcd 文件
$ gtkwave AdderTester.vcd
如下图所示:
开发环境
如本文初所述,使用采用 chisel 语言进行开发,使用 idea 做编辑器,使用 sbt 做依赖库管理,因此这里简单介绍下 sbt 环境安装即可。
$ wget https://dl.bintray.com/sbt/debian/sbt-0.13.11.deb
$ sudo dpkg -i sbt-0.13.11.deb
sbt 使用
- 创建模块 Adder.scala
import chisel3._
import chisel3.iotesters.{SteppedHWIOTester, ChiselFlatSpec}
import chisel3.testers.TesterDriver
class Adder(val w: Int) extends Module {
val io = IO(new Bundle {
val in0 = Input(UInt(w.W))
val in1 = Input(UInt(w.W))
val out = Output(UInt(w.W))
})
io.out := io.in0 + io.in1
}
class AdderTester extends SteppedHWIOTester {
val device_under_test = Module( new Adder(8) )
val c = device_under_test
enable_all_debug = true
rnd.setSeed(0L)
for (i <- 0 until 3) {
val in0 = rnd.nextInt(1 << c.w)
val in1 = rnd.nextInt(1 << c.w)
poke(c.io.in0, in0)
poke(c.io.in1, in1)
expect(c.io.out, (in0 + in1) & ((1 << c.w) - 1))
step(1)
}
}
object Adder {
def main(args: Array[String]): Unit = {
TesterDriver.execute { () => new AdderTester }
}
}
class AdderSpec extends ChiselFlatSpec {
"Adder" should "compile and run without incident" in {
assertTesterPasses { new AdderTester }
}
}
- 编写 build.sbt 文件
这里仿照 chisel-tutorial 项目编写即可:
version := "3.1.0"
name := "chisel-tutorial"
scalaVersion := "2.11.12"
crossScalaVersions := Seq("2.11.12", "2.12.4")
scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-language:reflectiveCalls")
// Provide a managed dependency on X if -DXVersion="" is supplied on the command line.
// The following are the current "release" versions.
val defaultVersions = Map(
"chisel3" -> "3.1.+",
"chisel-iotesters" -> "1.2.+",
"treadle" -> "1.0.1"
)
libraryDependencies ++= (Seq("chisel3","chisel-iotesters").map {
dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) })
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.0.1" % "test"
)
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Resolver.sonatypeRepo("releases")
)
// Recommendations from http://www.scalatest.org/user_guide/using_scalatest_with_sbt
logBuffered in Test := true
// Disable parallel execution when running tests.
// Running tests in parallel on Jenkins currently fails.
parallelExecution in Test := false
publishMavenStyle := true
publishArtifact in Test := true
pomIncludeRepository := { x => false }
pomExtra := (
<url>http://chisel.eecs.berkeley.edu/</url>
<licenses>
<license>
<name>BSD-style</name>
<url>http://www.opensource.org/licenses/bsd-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>https://github.com/ucb-bar/chisel-testers2.git</url>
<connection>scm:git:github.com/ucb-bar/chisel-testers2.git</connection>
</scm>
)
// Recommendations from http://www.scalatest.org/user_guide/using_scalatest_with_sbt
logBuffered in Test := true
// Disable parallel execution when running tests.
// Running tests in parallel on Jenkins currently fails.
parallelExecution in Test := false
publishMavenStyle := true
publishArtifact in Test := true
pomIncludeRepository := { x => false }
pomExtra := (
<url>http://chisel.eecs.berkeley.edu/</url>
<licenses>
<license>
<name>BSD-style</name>
<url>http://www.opensource.org/licenses/bsd-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>https://github.com/ucb-bar/chisel-testers2.git</url>
<connection>scm:git:github.com/ucb-bar/chisel-testers2.git</connection>
</scm>
)
publishTo := {
val v = version.value
val nexus = "https://oss.sonatype.org/"
if (v.trim.endsWith("SNAPSHOT")) {
Some("snapshots" at nexus + "content/repositories/snapshots")
}
else {
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
}
trapExit := false
- 编译执行
$ sbt run
如下是其日志:
uc : /srv/workspace/chisel$ sbt clean run
[info] Set current project to chisel-tutorial (in build file:/srv/workspace/chisel/)
[success] Total time: 0 s, completed Nov 14, 2018 7:51:19 PM
[info] Updating {file:/srv/workspace/chisel/}chisel...
[info] Resolving jline#jline;2.14.3 ...
[info] Done updating.
[info] Compiling 1 Scala source to /srv/workspace/chisel/target/scala-2.11/classes...
[info] Running Adder
[info] [0.001] Elaborating design...
================================================================================
Device under test: io bundle
# Dir D/V Used Name Parent
--------------------------------------------------------------------------------
0 I y in0
1 I y in1
2 O y out
================================================================================
================================================================================
UnitTester state table
step in1 in0 out
--------------------------------------------------------------------------------
0 851 748 575
1 620 246 866
2 316 652 968
3 - - -
================================================================================
[info] [0.453] Done elaborating.
Total FIRRTL Compile Time: 279.0 ms
verilator --cc /srv/workspace/chisel/test_run_dir/AdderTester/201811141951384238257037378005420/AdderTester.v --assert -Wno-fatal -Wno-WIDTH -Wno-STMTDLY --trace -O1 --top-module AdderTester +define+TOP_TYPE=VAdderTester +define+PRINTF_COND=!AdderTester.reset +define+STOP_COND=!AdderTester.reset -CFLAGS -Wno-undefined-bool-conversion -O1 -DTOP_TYPE=VAdderTester -DVL_USER_FINISH -include VAdderTester.h -Mdir /srv/workspace/chisel/test_run_dir/AdderTester/201811141951384238257037378005420 --exe /srv/workspace/chisel/test_run_dir/AdderTester/201811141951384238257037378005420/top.cpp
make: Entering directory '/srv/workspace/chisel/test_run_dir/AdderTester/201811141951384238257037378005420'
g++ -I. -MMD -I/usr/share/verilator/include -I/usr/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -faligned-new -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -Wno-undefined-bool-conversion -O1 -DTOP_TYPE=VAdderTester -DVL_USER_FINISH -include VAdderTester.h -c -o top.o /srv/workspace/chisel/test_run_dir/AdderTester/201811141951384238257037378005420/top.cpp
g++ -I. -MMD -I/usr/share/verilator/include -I/usr/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -faligned-new -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -Wno-undefined-bool-conversion -O1 -DTOP_TYPE=VAdderTester -DVL_USER_FINISH -include VAdderTester.h -c -o verilated.o /usr/share/verilator/include/verilated.cpp
g++ -I. -MMD -I/usr/share/verilator/include -I/usr/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -faligned-new -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -Wno-undefined-bool-conversion -O1 -DTOP_TYPE=VAdderTester -DVL_USER_FINISH -include VAdderTester.h -c -o verilated_vcd_c.o /usr/share/verilator/include/verilated_vcd_c.cpp
/usr/bin/perl /usr/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VAdderTester.cpp > VAdderTester__ALLcls.cpp
/usr/bin/perl /usr/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VAdderTester__Trace.cpp VAdderTester__Syms.cpp VAdderTester__Trace__Slow.cpp > VAdderTester__ALLsup.cpp
g++ -I. -MMD -I/usr/share/verilator/include -I/usr/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -faligned-new -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -Wno-undefined-bool-conversion -O1 -DTOP_TYPE=VAdderTester -DVL_USER_FINISH -include VAdderTester.h -c -o VAdderTester__ALLsup.o VAdderTester__ALLsup.cpp
g++ -I. -MMD -I/usr/share/verilator/include -I/usr/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -faligned-new -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -Wno-undefined-bool-conversion -O1 -DTOP_TYPE=VAdderTester -DVL_USER_FINISH -include VAdderTester.h -c -o VAdderTester__ALLcls.o VAdderTester__ALLcls.cpp
Archiving VAdderTester__ALL.a ...
ar r VAdderTester__ALL.a VAdderTester__ALLcls.o VAdderTester__ALLsup.o
ar: creating VAdderTester__ALL.a
ranlib VAdderTester__ALL.a
g++ top.o verilated.o verilated_vcd_c.o VAdderTester__ALL.a -o VAdderTester -lm -lstdc++ 2>&1 | c++filt
make: Leaving directory '/srv/workspace/chisel/test_run_dir/AdderTester/201811141951384238257037378005420'
Enabling waves...
passed step 0 -- out: 575
Starting simulation!
passed step 1 -- out: 866
passed step 2 -- out: 968
Stopping, end of tests, 4 steps
[success] Total time: 20 s, completed Nov 14, 2018 7:51:40 PM
这时,在 /srv/workspace/chisel/test_run_dir/AdderTester
文件夹中能找到相关的模块比如: *.v 以及 *.vcd 文件。