您当前的位置: 首页 > 

耐心的小黑

暂无认证

  • 1浏览

    0关注

    323博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

chisel Reset的三种类型和同步异步寄存器

耐心的小黑 发布时间:2021-07-10 22:32:03 ,浏览量:1

一、Reset三种类型

Chisel3.2.0开始,Chisel 3支持同步和异步复位,这意味着我们可以生成同步复位和异步复位寄存器。寄存器的类型取决于与其相关的复位信号的类型。

  • Bool - constructed with Bool(). 同步复位信号
  • AsyncReset - constructed with AsyncReset(). 异步复位信号
  • Reset - constructed with Reset(). 自动推断类型的抽象reset
二、Reset类型推断

这里的英文还不太理解,就不翻译了,直接贴出原文。 在这里插入图片描述

三、隐式的Reset

具有隐式复位信号的ModuleMultiIOModule的隐式reset是抽象的Reset类型,并且默认推断为Bool类型的,也就是同步信号。

但是我们可以在定义模块时通过混入以下特质,覆盖掉自动推断的模式,将reset的类型设置成我们想要的类型。如下所示:

  • RequireSyncReset - sets the type of reset to Bool
  • RequireAsyncReset - sets the type of reset to AsyncReset
class MyAlwaysSyncResetModule extends MultiIOModule with RequireSyncReset {
  val mySyncResetReg = RegInit(false.B) // reset is of type Bool
}
class MyAlwaysAsyncResetModule extends MultiIOModule with RequireAsyncReset {
  val myAsyncResetReg = RegInit(false.B) // reset is of type AsyncReset
}
四、类型不确定的Reset举例
class ResetAgnosticRawModule extends RawModule {
  val clk = IO(Input(Clock()))
  val rst = IO(Input(Reset()))
  val out = IO(Output(UInt(8.W)))

  val resetAgnosticReg = withClockAndReset(clk, rst)(RegInit(0.U(8.W)))
  resetAgnosticReg := resetAgnosticReg + 1.U
  out := resetAgnosticReg
}

在上述代码中,rst的定义使用的是Reset(),此时的复位信号的类型需要自动推断,所以寄存器resetAgnosticReg是同步还是异步我们并不知道。

我觉得这样做的好处是,当我们给上述模块分别提供同步复位信号和异步复位信号时,可以使其生成不同的电路,也即产生不同类型的寄存器。接下来会结合强制类型转换举一个具体的例子。

五、Reset类型强制转换

在三中我们已经说过,我们可以手动设置隐式复位信号的类型,这里再介绍另一种方式:

  • .asBool ,将Reset类型强制转换成Bool
class ForcedSyncReset extends MultiIOModule {
    val out = IO(Output(UInt(8.W)))
    // withReset's argument becomes the implicit reset in its scope
    withReset (reset.asBool()) {

      // RawModules do not have implicit resets so withReset has no effect
      val myRawModule = Module(new ResetAgnosticRawModule)
      // We must drive the reset port manually
      myRawModule.clk := Module.clock
      // Module.reset grabs the current implicit reset
      myRawModule.rst := Module.reset 

      out := myRawModule.out
  }
}
module ResetAgnosticRawModule(
  input        clk,
  input        rst,
  output [7:0] out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [7:0] resetAgnosticReg; // @[Reset.scala 17:61]
  wire [7:0] _T_1 = resetAgnosticReg + 8'h1; // @[Reset.scala 18:40]
  assign out = resetAgnosticReg; // @[Reset.scala 19:7]
  always @(posedge clk) begin
    if (rst) begin // @[Reset.scala 17:61]
      resetAgnosticReg             
关注
打赏
1640088279
查看更多评论
0.0430s