risc-v中文社区

 找回密码
 立即注册
查看: 1194|回复: 0

[原创] Reg类型寄存器

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-18 20:21:55 | 显示全部楼层 |阅读模式
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宽度也是4  Bundle类型作为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[T],硬件类型主要有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[T])而不是硬件类型(Wire,Reg,IO,Input,Output,Flipped),
  上面代码中如果val reg = Reg(UInt(1.W))则将会语法错误,只能用chiselTypeOf(io.a)将硬件类型转为chisel类型
object chiselTypeOf {
  def apply[T <: Data](target: T): T = {
    requireIsHardware(target)
    target.cloneTypeFull.asInstanceOf[T]
  }
}
Data类中:
  def cloneType: this.type  
  private[chisel3] def cloneTypeFull: this.type = {
    val clone = this.cloneType.asInstanceOf[this.type]  // 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语法糖去掉才能接收。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-5-4 23:41 , Processed in 0.013781 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表