https://mp.weixin.qq.com/s/Y26N5P4XOr5e3uyi5XQY-w
不同于Verilog,Chisel中Wire和Reg并不是数据类型,而是数据容器,作为数据的一个特征而存在。
Wire和Reg作为数据容器,只是标识了变量是否可以存值这一个特征。但这不是数据类型的主要特征,更多的时候,我们关注的是数据的组织形式(是否包含符号位、是否包含小数点、位宽及编码方式等),以及数据如何参与运算。
在Verilog中,直接把变量声明为wire类型和reg类型,也可以加上signed标识。但数据还是作为一堆比特位来处理的。Chisel中做了更高层次的抽象、更具体的划分(UInt/SInt/Bool等),提取出了各种类型的组织形式和运算方法。
本文只做简单介绍,不做具体展开。
1.Wire
可以看到,Wire和WireInit都是定义了apply方法的Object,相当于函数调用。接收一个Data子类型的参数,在内部记录一些信息,再返回出来一个同样的变量。
def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
使用方法如下:
val carry = Wire(Vec(n+1, UInt(1.W)))
val sum = Wire(Vec(n, Bool()))
val abc = Wire(Bool())
2. Reg
Reg跟Wire一样,只是记录Data子类型变量的信息,然后返回:
def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
其中:
a. Reg(arg) 返回一个存放于寄存器中的变量;
b. RegNext(arg) 返回一个存放在寄存器中的变量,输入信号的值经过一个时钟之后,传递给这个变量;
c. RegInit(arg) 返回一个存放在寄存器中的变量,这个变量在复位时会被赋予一个初始值;
使用方法如下:
val r0 = Reg(UInt())
val r1 = Reg(UInt())
val r0 = RegNext(io.in)
val r1 = RegNext(r0)
val r2 = RegNext(r1)
val r3 = RegNext(r2)
io.out := r3
val r0 = RegInit(0.U(4.W))
val r1 = RegInit(0.U(4.W))