FIRRTLの変換フローについて調査した。ソースコードを読みながら各Passが何を実行しているのかを確認していく。
実行方法としては、
./utils/bin/firrtl -td regress -i ./regress/simple_test.fir -X sverilog -ll trace 2>&1 | tee simple_test.log
として、出力されるログを見ながらPassを確認していく。
ChirrtlToHighFirrtl
CheckChirrtl
CheckHighFormLike
に実体が存在する。Circuit内のTopModuleを探す。
CInferTypes
src/main/scala/firrtl/passes/InferTypes.scala
- 上位から順に伝搬できる型を下位に伝搬させる。
CInferMDir$
src/main/scala/firrtl/passes/Resolves.scala
- ポートの方向を伝搬させる?
RemoveCHIRRTL
src/main/scala/firrtl/passes/RemoveCHIRRTL.scala
- CHIRRTL と呼ばれるChiselのHigh Level Immediate Representationを変換する。
IRToWorkingIR
ToWorkingIR
src/main/scala/firrtl/passes/Passes.scala
- IRのノードからFirrtlNodeの形式に変換する。
ResolveAndCheck
CheckHighForm$
src/main/scala/firrtl/passes/Checks.scala
- ルール違反の制約を探す?
ResolveKinds$
src/main/scala/firrtl/passes/Resolves.scala
- ポートの名前から型に対するテーブルを作っていく。
InferTypes
src/main/scala/firrtl/passes/InferTypes.scala
CInferType
と同様だが、FirrtlNodeに対して処理を実行する。
CheckTypes
src/main/scala/firrtl/passes/Checks.scala
- 各構文に対して、有効な型が使われているかをチェックする。例えば演算に対して有効な型のノードが適用されているか。
Uniquify
src/main/scala/firrtl/passes/Uniquify.scala
- 変数名の変換により別の変数と衝突してしまうことを防ぐ。例えば、
a[0]
をa_0
に変換すると元々a_0
だったものにぶつかってしまう。なのでこの場合はa__0
などに変換する?
ResolveKinds
src/main/scala/firrtl/passes/Resolves.scala
- ポートの名前から型に対するテーブルを作っていく。
InferTypes
ResolveFlows
src/main/scala/firrtl/passes/Resolves.scala
- 配線同士のフローを構築する。例えば
Flip
などは方向を逆転させて本来の方向へ戻す。
CheckFlows
src/main/scala/firrtl/passes/Checks.scala
ResolveFlows
の解決後のチェックを行う。
InferWidths
src/main/scala/firrtl/passes/InferWidths.scala
- トップ階層から順に、配線のビット幅の推論を行っていく。
CheckWidths
src/main/scala/firrtl/passes/CheckWidths.scala
- ビット幅の矛盾をチェックする。例えば、代入時のビット幅に矛盾がないか、など。
InferResets
src/main/scala/firrtl/transforms/InferResets.scala
- リセット信号を推論させる。
DedupModules
HighFirrtlToMiddleFirrtl
PullMuxes
src/main/scala/firrtl/passes/Passes.scala
SubField
やSubIndex
などの型に対して、MuxやValidIfが使用されていると、この順序を変える。
ReplaceAccesses
src/main/scala/firrtl/passes/ReplaceAccesses.scala
WSubAccess(index)
で、index
が定数の場合はWSubIndex
に変換する。
ExpandConnects
src/main/scala/firrtl/passes/Passes.scala
- 配列や構造体について、Connect文を各要素に展開する。
Uniquify
src/main/scala/firrtl/passes/Uniquify.scala
- 変数名の変換により別の変数と衝突してしまうことを防ぐ。例えば、
a[0]
をa_0
に変換すると元々a_0
だったものにぶつかってしまう。なのでこの場合はa__0
などに変換する?
ExpandWhens
src/main/scala/firrtl/passes/ExpandWhens.scala
- Whenを分解してMuxに変換する。
CheckInitialization
src/main/scala/firrtl/passes/CheckInitialization.scala
- 完全に初期化されていない変数を探してエラーを出力する。
ResolveKinds
InferTypes
CheckTypes
CheckResets
ResolveFlows
InferWidths
CheckWidths
ConvertFixedToSInt
src/main/scala/firrtl/passes/ConvertFixedToSInt.scala
FixedInt
型をSInt
型に変換する。
ZeroWidth
src/main/scala/firrtl/passes/ZeroWidth.scala
- ビット幅がゼロのメモリを除去する。なんでそんなものが生成されるのか謎だが...
InferTypes
MiddleFirrtlToLowFirrtl
LowerTypes
ResolveKinds
InferTypes
ResolveFlows
InferWidths
Legalize
src/main/scala/firrtl/passes/Passes.scala
- 演算に際し型のLegalizeなどを行う。
RemoveReset
src/main/scala/firrtl/transforms/RemoveReset.scala
- Registerの定義されていないモジュールに対してResetの除去を行う。
CheckCombLoops
src/main/scala/firrtl/transforms/CheckCombLoops.scala
- Combinational Loopの検出を行う。
RemoveWires
src/main/scala/firrtl/transforms/RemoveWires.scala
- 不要な信号を除去する。
LowFirrtlOptimization
RemoveValidIf
src/main/scala/firrtl/passes/RemoveValidIf.scala
ValidIf
を除去して分解する。
ConstantPropagation
src/main/scala/firrtl/transforms/ConstantPropagation.scala
- 定数の伝搬を行う。
PadWidths
src/main/scala/firrtl/passes/PadWidths.scala
- 自動的なビット拡張に対する処理を行う。
ConstantPropagation
Legalize
VerilogMemDelays
src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala
- メモリモジュールに対する遅延の挿入?
ConstantPropagation
SplitExpressions
src/main/scala/firrtl/passes/SplitExpressions.scala
- 複数の式などをそれぞれの式に分解する。
CombineCats
src/main/scala/firrtl/transforms/CombineCats.scala
- 複数のCatsをマージする。
CommonSubexpressionElimination
src/main/scala/firrtl/passes/CommonSubexpressionElimination.scala
- 共通の式を除去する?
SystemVerilogEmitter
BlackBoxSourceHelper
ReplaceTruncatingArithmetic
FlattenRegUpdate
VerilogModulusCleanup$
VerilogRename
VerilogPrep$
AddDescriptionNodes