risc-v中文社区

 找回密码
 立即注册
查看: 1434|回复: 2

[原创] RegNext类型寄存器

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-19 09:10:00 | 显示全部楼层 |阅读模式
上一帖我们介绍了Reg寄存器,它就代表我们在verilog中常见到的reg,只不过在chisel中,
val reg =Reg(chisel类型)之后还需要用Data的:=方法进行连接操作,如果有可能还需要
用when将默认或withReset的复位信号用.toBool转为Bool判断是否复位之后再赋Reg初始值,
而RegNext则不需要再次:=操作,因为RegNext的两个apply方法中都有next:T参数,
这个next:T表示寄存器变量要连拉信号,所以这个next:T不能是chisel类型,只能是硬件类型,
其中有一个apply除了有next:T之外,还有init:T参数,表示复位时初始化的值,各种例子如下:
val foo = Reg(UInt(4.W)) //Reg类型的foo的宽度是4
val bar = RegNext(foo) //一定要注意:RegNext的宽度不是next参数的宽度,也不是后面init的宽度
//那bar的宽度怎么计算呢?总结来说:bar的宽度由chisel后面步骤的FIRRTL编译器来决定,
我们知道chisel写的scala代码会变成.fir,然后再由FIRRTL变成verilog的.v文件,这样大家应该能理解了。

如果确实需要明确的宽度,则不能用RegNext,要用Reg:
val foo =Reg(UInt(4.W)) //指定chisel类型且宽度 4
val bar = Reg(chiselType(foo)) //指定硬件类型且必须要用chiselType将硬件类型回退成原始的chisel类型,这样就能指定与foo一样的宽度 4
但指定宽度之后,如果连线必须要用Data的:=或<>指定:
bar := foo //一定要指定硬件连线到哪个Reg或Wire

如果RegNext硬件类型参数的原生chisel类型是Bundle类型,那么RegNext返回的寄存器的宽度是Bundle中指定的宽度:
class MyBundle extends Bundle {
  val x = UInt(4.W)
}
val foo = Wire(new MyBundle) //foo.x 宽度4
val bar = RegNext(foo) //bar.x的宽度也是4


回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-19 09:20:06 | 显示全部楼层
RegNext有一个时钟的延时,所以可以用来进行边沿检测,比如上升沿检测:
val risereg = RegNext(某个硬件类型,一般可能是Wire,如:Module中的io里面的某个val a = Input(UInt(1.W)))
上升沿检测:
val rising = io.a & !risereg
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-19 09:30:59 | 显示全部楼层
如果RegNext硬件类型参数的原生chisel类型是Bundle类型,那么RegNext返回的寄存器的宽度是Bundle中指定的宽度:
class MyBundle extends Bundle {
  val x = UInt(4.W)
}
如果Bundle中不指定则对应RegNext也不指定,由FIRRTL编译器自动推断:
class MyBunlde extends Bundle {
  val y = UInt()
  val x = UInt(4.W)
}
回复

使用道具 举报

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

本版积分规则



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

GMT+8, 2024-5-2 02:46 , Processed in 0.023242 second(s), 17 queries .

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

Copyright © 2018-2021, risc-v open source

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