关于Reg的几种常见形式:
一、最基本形式:可用于类型声明Reg:
val clock = Node(x._parent.get.clock)
时钟跟复位信号在Chisel中是隐藏的。
Reg(t,next,init)
如果没有显示式声明,那这三个的默认值都是null
t: 是寄存器的数据类型
next:是数据的输入端,也就是要延迟一拍输出的数据
init:复位时候赋给输出的值
val B = Reg(UInt(width=3)) //指明类型和位宽
B := C //赋值
val D = Reg(init=false.B) // 声明、赋初值
二、几种特别的Reg
1.RegNext
这个寄存器的功能正如他的名字一样好理解,把输入延迟一个周期也就是在Next周期输出。
具体的用法有两种:
1.1 RegNext(next)
这里的next就是你想延迟的输入信号,例如 B := RegNext(A),这里把A的信号延迟了一个周期送给了B。这种形式的用法没有显式的指出初始值。
1.2 RegNext(next,init= initial_value)
这种形式显式指出了初始值,也就是复位后的值initial_value, B := RegNext(A,init=C),这个也好理解,如果复位的时候,延迟一个时钟周期将C输出给B,否则,将A延迟一周期输出给B,可能有人会问,这样做只能是同步复位,那如果想异步复位该怎么办呢?这确是是个问题,但是Chisel语言到目前为止只支持同步电路,至于以后是否会把异步加入语言特性,那就让时间来说吧,或者解决的办法就是用其他语言写出你的异步电路。
同样可能有人注意到了,在这个寄存器里根本就没有复位信号,为什么要有init这个复位值呢?因为Chisel将时钟信号和复位信号已经连接到需要连接的地方,所以也就在用法上隐藏了。
2、RegInit
这个只有一种用法,就是指明他的初始化或者是复位时候的值。
val r = RegInit(resetData)
3、RegEnable
这就是带有使能端的Reg,有两种用法:
3.1 RegNext(updateData,enable)
这种形式有两个参量,一个是需要控制的数据,一个控制信号,当enable=1的时候,将updateData在下个时钟上升沿输出。
val r = Reg(clonedUpdateData)
when (enable)
{ r := updateData }
3.2 RegNext(updateData,resetData,enable)
这个相比于上边的也就多了一个复位时候的值。
val r = RegInit(resetData)
when (enable) { r := updateData }
4、ShiftRegister
4.1 ShiftRegister(in , n , en )
in:需要移位的数据
n:需要移位的时钟周期数
en:使能信号,为true的时候移位
if (n != 0) {
RegEnable(apply(in, n-1, en), en)
} else {
in
}
4.2 ShiftRegister(in ,n ,resetData,en)
resetData :复位的时候为每个寄存器赋初值
if (n != 0) {
RegEnable(apply(in, n-1, resetData, en), resetData, en)
} else {
in
}