Chisel 项目环境配置
以 [1] 参考, Chisel 版本 6.0。Chisel 使用 mill 或 sbt 作为项目构建工具,我们这里使用 mill 为例
版本
mill 工具构建时对版本有强依赖关系,版本号不一致就会自动下载,创建环境需要检查 Chisel / Scala / Mill 的版本,mill 构建工具更新频繁且向前兼容比较差,有时候语法不兼容只有官网文档有信息,建议固定某个版本。
项目 | 配置文件位置 | 版本说明 |
---|---|---|
Chisel | 构建文件 build.sc 或 build.mill |
Chisel 5.0 更换了 FIRRTL 的后端流程,舍弃了 ChiselTest,测试和编译语法变化 |
Scala | 构建文件 build.sc 或 build.mill |
|
Mill | .mill-version |
Chisel 项目仓库组成
Chisel 仓库分为三个层次
- Project
- Package
- Main Class
项目层次
build.sc
里定义了一个代表项目的对象 $NAME$
后文以 <project_name>
指代 ,项目所有的依赖和配置文件都在这个对象的定义里。如果想在同一个目录下定义多个项目,每个项目有不同的方法和依赖,只需要依次类推定义多个 SbtModule
即可。mill 是按项目管理环境的,每个项目环境独立。这也是为什么 mill 称作项目构建工具而非 conda 的环境管理工具。
对象
object
可以看作只实例一次的class
或者说 static class
这是我们运行的入口 mill <project_name>.xxx
即可直接调用对应方法,可以使用 mil resolve <project_name>._
查看支持的接口
依赖包配置
Scala 三种方式添加依赖包
- 直接从远程 maven 仓库导入
- 编译到本地 ivy2 仓库导入
- 直接将代码 merge 进项目
SbtModule
中定义了很多项目配置相关属性 [2],使用 override def
重定义
ivyDeps
依赖的包scalacPluginIvyDeps
编译器扩展包
mill 使用 coursier 解析管理依赖 [3]。所有下载的依赖包都会放在 coursier 的缓存目录中,Linux 下是 ~/.cache/coursier/v1
。比如 org.chipsalliance::chisel:6.2.0
包位置在 ~/.cache/coursier/v1/https/repo1.maven.org/maven2/org/chipsalliance
。mill 同样读取 coursier 的镜像源配置,在 ~/.config/coursier/mirror.properties
设置镜像源配置 [4]
包路径的间隔符有 ::
或 :
俩种,前者会自动将 scala 版本作为字符串添加进路径中,这与 sbt 中的 %%
和 %
是一样的。
但我设置了国内镜像解析还是很慢 ...
很多包并没有托管到 maven 云仓库,需要编译到本地的 local ivy 仓库,注意 mill 编译项目要继承 PublishModule
[5],编译完成文件在 ~/.ivy2/local
如果不想编译直接 copy 代码,在object <project_name>
以下语法添加源文件解析路径
override def sources = T.sources {
super.sources() ++ Seq(
PathRef("<your_path>")
)
}
使用 ScalaTest 作为测试环境
// build.sc 中定义的 test object
object test extends SbtModuleTests with TestModule.ScalaTest {
override def ivyDeps = m.ivyDeps() ++ Agg(
ivy"org.scalatest::scalatest::3.2.16"
)
}
test
对象继承了 SbtModuleTests
和 TestModule.ScalaTest
SbtModuleTests
用 sbt 的路径管理项目,即源码和测试代码在src/main
和src/test
中TestModule.ScalaTest
使用 ScalaTest 作为测试框架
以上俩个继承让我们当运行 mill <project_name>.test
时,会自动搜索运行所有的 scalatest[6]
MainClass
主函数一般是 object 继承 App
trait 创建。
mill <project_name>.run
自动调用项目主函数(继承了 App
的 object),若项目内定义了多个主函数会报错,比如多人维护的项目,想要单独编译某个模块就会重新定义主函数,此时需要用 mill <project_name>.runMain <package_path>.<main_class>
指定主函数,或者一个仓库定义多个 project,每个 project 中在配置文件中定义 def mainClass=Some("<package>/<mainClass>")
mill <project_name>.test
自动搜索所有 scalatest 调用,build.sc
中定义mill <project_name>.testOnly <package_path>.<test_class>
单独调用某个 scalatest