joe 发表于 2021-8-18 20:21:55

Reg类型寄存器

val r0 = Reg(UInt()) //宽度将由推断而决定
val r1 = Reg(UInt(8.W)) //宽度被设置为8
val r2 = Reg(Vec(4,UInt())) //宽度由推断而决定
val r3 = Reg(Vec(4,UInt(8.W))) //每个元素的宽度是8
class MyBundle extends Bundle{
val unknown = UInt()
val known = UInt(8.W)
}
val r4 = Reg(new MyBundle)
//r4.unknown位宽推断而定,r4.known位宽产8
下面代码表示一个具有使能端口的寄存器:
val enableReg = Reg(UInt(4.W))
when(enable) {
enableReg := inputValue
}
具有使能端口的寄存器也可以被重置:
val resetEnableReg = RegInit(0.U(4.W))
when(enable){
resetEnableReg := inputValue
}
寄存器还可以是表达式的一部分,比如下面电路是上升沿检测电路:
val risingEdge = din & !RegNext(din)
//din数据位宽假设为8位,那么RegNext(din)寄存器的位宽将也是8位吗?
//在Reg.scala源码中有说明:
val foo = Reg(UInt(4.W)) //宽度是4
val bar = RegNext(foo) //bar的宽度将由FIRRTL编译器推断

val foo = Reg(UInt(4.W)) //宽度是4
val bar = Reg(chiselTypeOf(foo)) //宽度是4
bar := foo

class MyBundle extends Bundle {
val x = UInt(4.W)
}
val foo = Wire(new MyBundle) //foo.x宽度是4
val bar = RegNext(foo) //bar.x宽度也是4Bundle类型作为RegNext的参数,则
因为Bundle来自Aggregate,Aggregate中width决定了Bundle的宽度,
所以上面代码中同样是RegNext(foo),但Bundle类型的RegNext(foo)的宽度是4,
而前一个RegNext(foo)

https://blog.csdn.net/qq_39507748/article/details/118218180
Reg的参数只能是chisel数据类型,不能是硬件类型,chisel数据类型主要有
UInt,SInt,Bool,Bundle,Vec,硬件类型主要有Wire,Reg,IO以及指明端口
方向的Input,Output和Flipped
如果想将一个硬件类型参数传给Reg,则必须要用chiselTypeOf,
val io = IO(new Bundle{
    val a = Input(UInt(1.W))
    val b = Output(UInt(1.W))
    val c = Output(UInt(1.W))
})
val reg = Reg(chiselTypeOf(io.a)) //Reg接收的参数是chisel类型(UInt,SInt,Bool,Bundle,Vec)而不是硬件类型(Wire,Reg,IO,Input,Output,Flipped),
上面代码中如果val reg = Reg(UInt(1.W))则将会语法错误,只能用chiselTypeOf(io.a)将硬件类型转为chisel类型
object chiselTypeOf {
def apply(target: T): T = {
    requireIsHardware(target)
    target.cloneTypeFull.asInstanceOf
}
}
Data类中:
def cloneType: this.type
private def cloneTypeFull: this.type = {
    val clone = this.cloneType.asInstanceOf// get a fresh object, without bindings
    // Only the top-level direction needs to be fixed up, cloneType should do the rest
    clone.specifiedDirection = specifiedDirection
    clone
}
val a = Input(UInt(1.W))虽然是UInt类型,但它是硬件类型,也就是说在UInt之上还包裹了一层语法糖,从编译器角度来说其实是不同的类型,
所以要想将硬件类型的参数传给只接收chisel类型的Reg的apply,只能用chiselTypeOf将外层Input语法糖去掉才能接收。

页: [1]
查看完整版本: Reg类型寄存器