ChiselからVerilogを生成すると、配列参照の記述は最終的に除去され、とんでもないVerilogが生成されることはよくある。例えば以下のようなFIRを書いたとすると、
circuit VecModules : module VecModules : input in: UInt<1>[16] input sel: UInt<4> output out : UInt<1> out <= in[sel]
module VecModules( input logic in_0, input logic in_1, input logic in_2, ... // あまりにも長いので省略 input logic in_13, input logic in_14, input logic in_15, input logic [3:0] sel, output logic out ); logic _GEN_1; logic _GEN_2; ... // あまりにも長いので省略 logic _GEN_13; logic _GEN_14; assign _GEN_1 = 4'h1 == sel ? in_1 : in_0; assign _GEN_2 = 4'h2 == sel ? in_2 : _GEN_1; assign _GEN_3 = 4'h3 == sel ? in_3 : _GEN_2; ... // ああまりにも長いので省略 assign _GEN_12 = 4'hc == sel ? in_12 : _GEN_11; assign _GEN_13 = 4'hd == sel ? in_13 : _GEN_12; assign _GEN_14 = 4'he == sel ? in_14 : _GEN_13; assign out = 4'hf == sel ? in_15 : _GEN_14; endmodule
これがどこで生成されているかというと、Passの中で変換されるルーチンを確認しなければならないのだが、このためには、firrtlの-ll trace
オプションを使用する。
./utils/bin/firrtl -td regress -i regress/VecModules.fir -X sverilog -ll trace 2>&1 | tee trace.log
======== Starting Transform ExpandConnects$ ======== ---------------------------------------------------- Time: 1.6 ms Form: UnknownForm Annotations: LogLevelAnnotation(Trace) EmitCircuitAnnotation(class firrtl.SystemVerilogEmitter) TargetDirAnnotation(regress) InfoModeAnnotation(use) targetDir regress DELETED by firrtl.stage.phases.AddCircuit FirrtlFileAnnotation(regress/VecModules.fir) OutputFileAnnotation(VecModules) Circuit: circuit VecModules : module VecModules : input in : UInt<1>[16] input sel : UInt<4> output out : UInt<1> out <= in[sel] ======== Finished Transform ExpandConnects$ ========
======== Starting Transform RemoveAccesses$ ======== ---------------------------------------------------- Time: 10.7 ms Form: UnknownForm Annotations: LogLevelAnnotation(Trace) EmitCircuitAnnotation(class firrtl.SystemVerilogEmitter) TargetDirAnnotation(regress) InfoModeAnnotation(use) targetDir regress DELETED by firrtl.stage.phases.AddCircuit FirrtlFileAnnotation(regress/VecModules.fir) OutputFileAnnotation(VecModules) Circuit: circuit VecModules : module VecModules : input in : UInt<1>[16] input sel : UInt<4> output out : UInt<1> wire _in_sel : UInt<1> _in_sel is invalid when eq(UInt<1>("h0"), sel) : _in_sel <= in[0] when eq(UInt<1>("h1"), sel) : _in_sel <= in[1] when eq(UInt<2>("h2"), sel) : ... // あまりにも長いので省略 _in_sel <= in[11] when eq(UInt<4>("hc"), sel) : _in_sel <= in[12] when eq(UInt<4>("hd"), sel) : _in_sel <= in[13] when eq(UInt<4>("he"), sel) : _in_sel <= in[14] when eq(UInt<4>("hf"), sel) : _in_sel <= in[15] out <= _in_sel ======== Finished Transform RemoveAccesses$ ========
とりあえずまずはRemoveAccesses
のPassを除去してみると何が起きるかな?
diff --git a/src/main/scala/firrtl/LoweringCompilers.scala b/src/main/scala/firrtl/LoweringCompilers.scala index 05cdbe96..d911f340 100644 --- a/src/main/scala/firrtl/LoweringCompilers.scala +++ b/src/main/scala/firrtl/LoweringCompilers.scala @@ -62,7 +62,6 @@ class HighFirrtlToMiddleFirrtl extends CoreTransform { passes.PullMuxes, passes.ReplaceAccesses, passes.ExpandConnects, - passes.RemoveAccesses, passes.Uniquify, passes.ExpandWhens, passes.CheckInitialization,
Internal Errorが発生してしまった。
Exception in thread "main" firrtl.FirrtlInternalException: Internal Error! Please file an issue at https://github.com/ucb-bar/firrtl/issues at firrtl.Utils$.error(Utils.scala:423) at firrtl.Utils$.throwInternalError(Utils.scala:164) ... at firrtl.options.Stage.transform(Stage.scala:46) at firrtl.options.Stage.execute(Stage.scala:57) at firrtl.options.StageMain.main(Stage.scala:70) at firrtl.stage.FirrtlMain.main(FirrtlStage.scala) Caused by: scala.MatchError: WSubAccess(WRef(in,VectorType(UIntType(IntWidth(1)),16),PortKind,SourceFlow),WRef(sel,UIntType(IntWidth(4)),PortKind,SourceFlow),UIntType(IntWidth(1)),Sourc eFlow) (of class firrtl.WSubAccess) at firrtl.passes.LowerTypes$.lowerTypesExp(LowerTypes.scala:140) at firrtl.passes.LowerTypes$.$anonfun$lowerTypesStmt$22(LowerTypes.scala:254) ... at firrtl.passes.LowerTypes$.lowerTypesStmt(LowerTypes.scala:254)
まだInternal Errorが発生する。
Exception in thread "main" firrtl.FirrtlInternalException: Internal Error! Please file an issue at https://github.com/ucb-bar/firrtl/issues ... at firrtl.options.StageMain.main(Stage.scala:70) at firrtl.stage.FirrtlMain.main(FirrtlStage.scala) Caused by: java.util.NoSuchElementException: key not found: in at scala.collection.MapLike.default(MapLike.scala:235) at scala.collection.MapLike.default$(MapLike.scala:234)
解析を続けよう。