还是下决心学chisel了,我跟着riscv-mini的核来进行学习,这篇博客主要记录一些过程中遇到的问题和解决或者心得
Type
第一个搞清楚的概念就是chisel的type了,也是这个促使我写的博客
chisel的type不像其他编程语言的type那么直观,因为他是“二维”的
chisel的type包括硬件结构和硬件类型
- 硬件类型包括UInt,SInt
- 硬件结构包括Wire,Reg,Mem甚至Module等等
用English就是chisel type和chisel component
我一开始没有分清楚所以很迷惑,For example:
val a = 3.U + 4.U
这里的a的硬件结构或者节点是Wire或者Output…a的硬件类型是UInt,可以看出,表达式本身帮助我们推断出了他的硬件结构
之后还有两个常用type:Bundle和Vec
Bundle是类似c语言的struct一样的作用,将不同的硬件类型结合起来形成一个“新的硬件类型”,但是Bundle本身并没有映射到具体的硬件结构上面,所以,我们需要这样初始化Bundle:
val a = IO(new Mybundle)
才能将其映射到一个具体的硬件结构
Vec我还不太了解,但是初步了解是一个类似数组的东西,是将一系列的硬件结构组合起来,并且可以索引
BlackBox
由于我需要使用Dpi-C功能,我需要使用sv来编写一些代码,所以需要使用chisel的blackbox功能
这个简单来说就是extends BlackBox而不是Module,这样它例化的时候就不会带上一些奇怪的东西(比如io),至于addPath,addResource这些方法我感觉没什么用,他是把verilog文件复制到目标文件夹,其实只要把所有目录里面所有的verilog文件找出来传给verilator就行,只要确保生成的verilog例化时的语法正确就行
Mux
这个也是一个经常会使用的东西,chisel提供了很多类似的“函数”,具体见Muxes and Input Selection | Chisel (chisel-lang.org),但是还有一个叫做ListLookup不知道为什么文档没有写,但是API是可以看到的chisel 6.3.0 – chisel3.util.ListLookup (chisel-lang.org)
基本上ysyx讲义上提供的模版就是MuxLookup,基本上就使用mux就可以避免所有行为建模了吧
Reg
如果说Mux是组合逻辑的神器,那reg就是时序逻辑不可缺少的一部分,chisel提供了很多实现触发器的模版,随便找一个文章学习一下Chisel Registers Tutorial – Learn FPGA Easily,不过最好还是看官网比较好点
寄存器文件一般使用Mem来例化
Connect operator
似乎官网并不建议使用<>(至于两者的区别,似乎:<>=检查的更严格)
主要就是五种
- :=
- :>=
- :<=
- :<>=
- :#=
具体见官网,我暂时还没搞太清楚(上面那个wordpress会自动给我整成大于等于,实际上是分开的)
Connectable Operators | Chisel (chisel-lang.org)
今天忽然发现一个问题,<>这个运算符(也就是:<>=运算符),在连接同一级别的模块的时候似乎是连接input到output,output到input,但是,在连接父模块与子模块时,似乎是连接input到input,output到output,如图所示
并且连线的时候会有一个比较绕但是不复杂的东西,你连接到外部模块是要连接到本模块的output,再在更上层模块连接到外部模块的input,并从本模块的input获取数据,连接到内部模块要连接到内部模块的input,并从内部模块的output获取数据,其实就是上图