まずはfirrtlに取り込まれる引数を確認した。以下のようにprintlnを挿入した。
firrtl/options/Stage.scala
final def execute(args: Array[String], annotations: AnnotationSeq): AnnotationSeq = { println("execute : args") for (i <- 0 until args.size) { println(args(i)) } transform(shell.parse(args, annotations)) }
実行すると以下のようになる。まあこれは想定通り。
execute : args -td regress -i regress/simple_test.fir -o regress/simple_test.v -X sverilog
つぎに、以下のようにしてすべての処理にprintlnを挟んでみる。
diff --git a/src/main/scala/firrtl/options/Stage.scala b/src/main/scala/firrtl/options/Stage.scala index 3752b846..ee3bf80b 100644 --- a/src/main/scala/firrtl/options/Stage.scala +++ b/src/main/scala/firrtl/options/Stage.scala @@ -35,7 +35,7 @@ abstract class Stage extends Phase { Seq( new phases.GetIncludes, new phases.ConvertLegacyAnnotations ) .map(phases.DeletedWrapper(_)) - .foldLeft(annotations)((a, p) => p.transform(a)) + .foldLeft(annotations)((a, p) => { println(s"Annotation = ${p}"); p.transform(a)}) Logger.makeScope(annotationsx) { Seq( new phases.AddDefaults, @@ -43,7 +43,7 @@ abstract class Stage extends Phase { new Phase { def transform(a: AnnotationSeq) = run(a) }, new phases.WriteOutputAnnotations ) .map(phases.DeletedWrapper(_)) - .foldLeft(annotationsx)((a, p) => p.transform(a)) + .foldLeft(annotationsx)((a, p) => { println(s"Annotation2 = ${p}"); p.transform(a)}) } }
以下のようになった。とりあえずPassが進んでいるようだ。
execute = DeletedAnnotation(firrtl.options.Stage$$anon$1,FirrtlFileAnnotation(regress/simple_test.fir)) execute = DeletedAnnotation(firrtl.options.Stage$$anon$1,CompilerAnnotation(firrtl.SystemVerilogCompiler@78aab498)) execute = DeletedAnnotation(firrtl.stage.phases.WriteEmitted,EmittedVerilogCircuitAnnotation(EmittedVerilogCircuit(SimpleCircuit,module SimpleCircuit( input [31:0] io_in, output [31:0] io_out ); assign io_out = io_in; endmodule ,.sv))) execute = DeletedAnnotation(firrtl.stage.phases.Compiler,FirrtlCircuitAnnotation(Circuit(,ArrayBuffer(Module(,SimpleCircuit,ArrayBuffer(Port(,io,Output,BundleType(ArrayBuffer(Field(in,Flip,UIntType(IntWidth(32))), Field(out,Default,UIntType(IntWidth(32))))))),Block(ArrayBuffer(Connect(,SubField(Reference(io,UnknownType),out,UnknownType),SubField(Reference(io,UnknownType),in,UnknownType)))))),SimpleCircuit))) execute = DeletedAnnotation(firrtl.stage.phases.Compiler,CompilerAnnotation(firrtl.SystemVerilogCompiler@78aab498)) execute = DeletedAnnotation(firrtl.stage.phases.Compiler,RunFirrtlTransformAnnotation(firrtl.SystemVerilogEmitter@7e0b85f9)) execute = FirrtlCircuitAnnotation(Circuit(,ArrayBuffer(Module(,SimpleCircuit,ArrayBuffer(Port(,io_in,Input,UIntType(IntWidth(32))), Port(,io_out,Output,UIntType(IntWidth(32)))),Block(ArrayBuffer(Block(ArrayBuffer(Connect(,WRef(io_out,UIntType(IntWidth(32)),PortKind,SinkFlow),WRef(io_in,UIntType(IntWidth(32)),PortKind,SourceFlow)))))))),SimpleCircuit)) execute = CombinationalPath(ReferenceTarget(SimpleCircuit,SimpleCircuit,List(),io_out,List()),ArrayBuffer(ReferenceTarget(SimpleCircuit,SimpleCircuit,List(),io_in,List()))) execute = EmitCircuitAnnotation(class firrtl.SystemVerilogEmitter) execute = OutputFileAnnotation(regress/simple_test.v) execute = TargetDirAnnotation(regress) execute = InfoModeAnnotation(use) execute = BlackBoxTargetDirAnno(regress) execute = DeletedAnnotation(firrtl.stage.phases.AddCircuit,FirrtlFileAnnotation(regress/simple_test.fir))
例えば、EmitCircuitAnnotation
を見てみる。ここでは、firrtl.SystemVerilogEmitter
を引数として渡しているようだが、実体はVerilogEmitter
と同一である。
firrtl/Emitter.scala
object EmitCircuitAnnotation extends HasShellOptions { val options = Seq( new ShellOption[String]( longOption = "emit-circuit", toAnnotationSeq = (a: String) => a match { case "chirrtl" => Seq(RunFirrtlTransformAnnotation(new ChirrtlEmitter), EmitCircuitAnnotation(classOf[ChirrtlEmitter])) case "high" => Seq(RunFirrtlTransformAnnotation(new HighFirrtlEmitter), EmitCircuitAnnotation(classOf[HighFirrtlEmitter])) case "middle" => Seq(RunFirrtlTransformAnnotation(new MiddleFirrtlEmitter), EmitCircuitAnnotation(classOf[MiddleFirrtlEmitter])) case "low" => Seq(RunFirrtlTransformAnnotation(new LowFirrtlEmitter), EmitCircuitAnnotation(classOf[LowFirrtlEmitter])) case "verilog" | "mverilog" => Seq(RunFirrtlTransformAnnotation(new VerilogEmitter), EmitCircuitAnnotation(classOf[VerilogEmitter])) case "sverilog" => Seq(RunFirrtlTransformAnnotation(new SystemVerilogEmitter), EmitCircuitAnnotation(classOf[SystemVerilogEmitter])) case _ => throw new PhaseException(s"Unknown emitter '$a'! (Did you misspell it?)") }, ...
firrtl/Emitter.scala
class SystemVerilogEmitter extends VerilogEmitter { StageUtils.dramaticWarning("SystemVerilog Emitter is the same as the Verilog Emitter!") ...
やはりEmitterのあたりがみそな気がするなあ。ここですべての構文に対するVerilogの対応が行われてる様子。
そもそも、Verilogに一対一対応で変換する前に、ファイルとして取り込んだFIRファイルをどこかで構文木に経関していると思うのだけれど、それはどこで行われているのだろう?