diff options
| author | sinofp | 2022-01-06 04:17:52 +0000 |
|---|---|---|
| committer | GitHub | 2022-01-06 04:17:52 +0000 |
| commit | 3e494b5cceda14a73f288a293dd007a82be18bb8 (patch) | |
| tree | a7a7692b4561509689b8ada5a4a755b1b923ff6a /src/main/scala | |
| parent | ebad877af9d9fe43a92f64f8b63ca8904834cc4d (diff) | |
Add FileInfo to asyncResetAlwaysBlocks (#2451)
* Add FileInfo to asyncResetAlwaysBlocks
Always blocks need three FileInfo (if, true, false) to show line numbers,
but initially, every always blocks only have one FileInfo (false).
RemoveReset adds the extra two FileInfo to sync always blocks,
so sync always blocks can have line numbers.
Async always blocks don't provide their only FileInfo, so there are no line numbers.
This commit gives async always block the extra FileInfo to show line numbers for them.
This code:
```scala
import chisel3._
import chisel3.stage._
import firrtl.CustomDefaultRegisterEmission
class Test extends Module with RequireAsyncReset {
val io = IO(new Bundle {
val in = Input(Bool())
val out = Output(Bool())
})
val valid = RegInit(false.B)
valid := io.in
io.out := valid
}
object Test extends App {
new ChiselStage().execute(Array(), Seq(
ChiselGeneratorAnnotation(() => new Test()),
CustomDefaultRegisterEmission(useInitAsPreset = false, disableRandomization = true)
))
}
```
will generate this Verilog:
```verilog
module Test(
input clock,
input reset,
input io_in,
output io_out
);
reg valid; // @[Playground.scala 10:22]
assign io_out = valid; // @[Playground.scala 12:10]
always @(posedge clock or posedge reset) begin
if (reset) begin // @[Playground.scala 10:22]
valid <= 1'h0; // @[Playground.scala 10:22]
end else begin
valid <= io_in; // @[Playground.scala 11:9]
end
end
endmodule
```
they have correct line numbers (10, 10, 11).
* Add test for async always block line numbers
* Add comment for review
Diffstat (limited to 'src/main/scala')
| -rw-r--r-- | src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala | 5 | ||||
| -rw-r--r-- | src/main/scala/firrtl/transforms/RemoveReset.scala | 10 |
2 files changed, 12 insertions, 3 deletions
diff --git a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala index af8996eb..f48e4846 100644 --- a/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala +++ b/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala @@ -787,13 +787,12 @@ class VerilogEmitter extends SeqTransform with Emitter { } else { // Asynchronous Reset assert(reset.tpe == AsyncResetType, "Error! Synchronous reset should have been removed!") val tv = init - val InfoExpr(finfo, fv) = netlist(r) - // TODO add register info argument and build a MultiInfo to pass + val InfoExpr(info, fv) = netlist(r) asyncResetAlwaysBlocks += ( ( clk, reset, - addUpdate(NoInfo, Mux(reset, tv, fv, mux_type_and_widths(tv, fv)), Seq.empty) + addUpdate(info, Mux(reset, tv, fv, mux_type_and_widths(tv, fv)), Seq.empty) ) ) } diff --git a/src/main/scala/firrtl/transforms/RemoveReset.scala b/src/main/scala/firrtl/transforms/RemoveReset.scala index 62b341cd..f1434ad2 100644 --- a/src/main/scala/firrtl/transforms/RemoveReset.scala +++ b/src/main/scala/firrtl/transforms/RemoveReset.scala @@ -50,6 +50,7 @@ object RemoveReset extends Transform with DependencyAPIMigration { private def onModule(m: DefModule, isPreset: String => Boolean): DefModule = { val resets = mutable.HashMap.empty[String, Reset] + val asyncResets = mutable.HashMap.empty[String, Reset] val invalids = computeInvalids(m) def onStmt(stmt: Statement): Statement = { stmt match { @@ -77,12 +78,21 @@ object RemoveReset extends Transform with DependencyAPIMigration { // Add register reset to map resets(rname) = Reset(reset, init, info) reg.copy(reset = Utils.zero, init = WRef(reg)) + case reg @ DefRegister(info, rname, _, _, reset, init) if reset.tpe == AsyncResetType => + asyncResets(rname) = Reset(reset, init, info) + reg case Connect(info, ref @ WRef(rname, _, RegKind, _), expr) if resets.contains(rname) => val reset = resets(rname) val muxType = Utils.mux_type_and_widths(reset.value, expr) // Use reg source locator for mux enable and true value since that's where they're defined val infox = MultiInfo(reset.info, reset.info, info) Connect(infox, ref, Mux(reset.cond, reset.value, expr, muxType)) + case Connect(info, ref @ WRef(rname, _, RegKind, _), expr) if asyncResets.contains(rname) => + val reset = asyncResets(rname) + // The `muxType` for async always blocks is located in [[VerilogEmitter.VerilogRender.regUpdate]]: + // addUpdate(info, Mux(reset, tv, fv, mux_type_and_widths(tv, fv)), Seq.empty) + val infox = MultiInfo(reset.info, reset.info, info) + Connect(infox, ref, expr) case other => other.map(onStmt) } } |
