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

一、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 <= 8'h0; // @[Reset.scala 17:61]
    end else begin
      resetAgnosticReg <= _T_1; // @[Reset.scala 18:20]
    end
  end
endmodule

这里展示的是生成的子模块的代码。reset.asBool()使得此时的隐式复位信号reset的类型为Bool,也即同步复位,所以此时的寄存器resetAgnosticReg也是同步复位的。之所以是同步复位,是因为生成的verilog代码中,复位信号rst没有出现在always的敏感列表中。


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

      // 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]
  assign out = resetAgnosticReg; // @[Reset.scala 19:7]
  always @(posedge clk or posedge rst) begin
    if (rst) begin
      resetAgnosticReg <= 8'h0;
    end else begin
      resetAgnosticReg <= resetAgnosticReg + 8'h1;
    end
  end
endmodule

这里展示的是生成的子模块的代码。asAsyncReset()使得此时的隐式复位信号reset的类型为AsyncReset,也即异步复位,所以此时的寄存器resetAgnosticReg也是异步复位的。之所以是异步复位,是因为生成的verilog代码中,复位信号rst出现在了always的敏感列表中。


参考链接https://www.chisel-lang.org/chisel3/docs/explanations/reset.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

耐心的小黑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值