Is there better way to compile firrtl code?

70 views
Skip to first unread message

Soya OHNISHI

unread,
Jul 28, 2020, 11:05:32 PM7/28/20
to chisel...@googlegroups.com
Hi,

I'm writing compiler and will use firrtl as backend,
so I use firrtl API(?) instead of using CLI command.

I already write some code like below to use firrtl and generate verilog
code, and it seems to works in expect.

def compile(input: String): EmittedCircuit = {
val initAnnons = Seq(EmitCircuitAnnotation(classOf[VerilogEmitter]))
val init = CircuitState(Parser.parse(input), initAnnons)
val compiler = new Compiler(Forms.VerilogOptimized)
val state = compiler.execute(init)
val emitter = new VerilogEmitter
val result = emitter.execute(state)
result.getEmittedCircuit
}

However, because I write above code with firrtl test codes in firrtl
project as reference, I don't know whether this is correct usage or not.

Please tell me correct usage if above usage is wrong.

Thanks,
Soya

Schuyler Eldridge

unread,
Jul 30, 2020, 11:24:23 PM7/30/20
to chisel...@googlegroups.com
I'd suggest to instead use 'firrtl.stage.FirrtlStage'. This is a more
user-friendly API and is exactly the same as what you get on the
command line. The following is how I'd do it:

def emitVerilog(firrtlString: String, args: Array[String] = Array.empty, annotations: AnnotationSeq = Seq.empty): String =
(new FirrtlStage)
.execute(Array("-X", "verilog") ++ args, FirrtlSourceAnnotation(firrtlString) +: annotations)
.collectFirst {
case DeletedAnnotation(_, EmittedVerilogCircuitAnnotation(a)) => a
}.get
.value

Note that the 'emitVerilog' method is nearly the same construction as
how 'ChiselStage.emitVerilog' works. See:

- https://github.com/freechipsproject/chisel3/blob/v3.3.2/src/main/scala/chisel3/stage/ChiselStage.scala#L92

It probably makes sense to add helper methods to 'FirrtlStage' like
'emitLowFirrtl' and 'emitVerilog' so that you don't have to write this
yourself, though.

If you don't want to write any output files, then you would currently
have to use a construction like what you wrote. The following is the
same, just cleaned up a bit:

def emitVerilog2(firrtlString: String, annotations: AnnotationSeq = Seq.empty): String =
new Compiler(targets = Seq(Dependency[VerilogEmitter]))
.transform(CircuitState(Parser.parse(firrtlString),
EmitCircuitAnnotation(classOf[VerilogEmitter]) +: annotations))
.annotations
.collectFirst {
case EmittedVerilogCircuitAnnotation(a) => a
}.get
.value

If you want to play around with these, I wrote up a Scastie snippet:

- https://scastie.scala-lang.org/seldridge/oW6yhhKQTQS2vwCAk39cKA/23

SoyaOhnishi

unread,
Jul 31, 2020, 6:24:17 AM7/31/20
to chisel...@googlegroups.com
Thanks for your reply and suggestions!

For now, I tried to use one you suggested at first and it works in expect!

Thanks,
Soya
Reply all
Reply to author
Forward
0 new messages