Should "automatic logic" appear when firtool --verilog is specified?

Yosys complains about lines with “automatic logic” in them.

After a little bit of googling, it appears that “automatic logic” is SystemVerilog and not Verilog.

You can use disallowLocalVariables option to remove “automatic logic”. Please try

$ firtool --lowering-options=disallowLocalVariables foo.fir


However, this is just one thing that I ran into with yosys not understanding the .sv files.

I would have expected only .v files to be generated when I specify --verilog and there to be no SystemVerilog artifacts.

However, I see .sv files and SystemVerilog artifacts…

I would have expected only .v files to be generated when I specify --verilog and there to be no SystemVerilog artifacts.

Yeah, I agree that this is a bit confusing but --verilog option just indicates that the output format is (system) verilog (this option doesn’t say the output is pure verilog). CIRCT controls the output style by specifying “lowering-options”. This doc would be very informative about the design and philosophy of verilog emission in CIRCT:

As far as I know to make yosys happy, you might need disallowPackedArrays option as well, e.g:

$ firtool --lowering-options=disallowLocalVariables,disallowPackedArrays foo.fir

I see.

I’m starting with Chisel CIRCT and there’s no way to specify firtool options directly… This makes it awkward to test out firtool from my current context. Previously I was able to generate Verilog files directly from Chisel, until the issue below is addressed somehow, I can’t do that…

Yeah, I agree that it’s better for chisel-circt to have such a functionality.

I updated sifive/chisel-circt to add support for directly passing options to firtool in Add ability to pass options to firtool · sifive/chisel-circt@6bcb704 · GitHub. This will enable a user to set --lowering-options and get the behavior requested here.

For convenience, I cut a 0.4.0 release of chisel-circt just now which will show up on Maven within a day.


This works near as I can tell.

The only thing is that --split-verilog doesn’t work unless you also specify -o=folder/.

The problem in a ChiselStage scenario, the parsing of the command line’s --target-dir is done by ChiselStage, so the user has to add some hacks to figure out what the target dir is…

Another thing that would be useful is to log the actual firtool command, for information and debugging purposes.

Perhaps some sort of generic callback mechanism to ChiselStage.execute() where the user can log/inspect/make changes to the final command line?

This callback should have access to everything, including the parsed command line…

Or… Perhaps copy + paste from Chisel CIRCT is the solution?

I’ve copied and pasted code from Chisel CIRCT into my Scala code that generates .sv files.

Perhaps I should have copied and pasted more, the entire command line parsing too?

I ended up with the following changes:

+  val pos = remainingArgs.indexOf("--target-dir")
+  if (pos == -1) {
+    throw new RuntimeException("--target-dir required")
+  }
+  val targetFolder = remainingArgs(pos + 1)
+  println("Target folder: " + targetFolder)


-    new ChiselStage()
+    new circt.stage.ChiselStage()
-        Seq(ChiselGeneratorAnnotation(provider))
+        Seq(
+          ChiselGeneratorAnnotation(provider),
+          circt.stage.CIRCTTargetAnnotation(circt.stage.CIRCTTarget.Verilog),
+          circt.stage.CIRCTHandover(circt.stage.CIRCTHandover.CHIRRTL),
+          circt.stage.FirtoolOption("--lowering-options=disallowLocalVariables,disallowPackedArrays,verifLabels"),
+          circt.stage.FirtoolOption("--remove-unused-ports"),
+          circt.stage.FirtoolOption("--disable-name-preservation"),
+          circt.stage.FirtoolOption("--split-verilog"),
+          circt.stage.FirtoolOption("--dedup"),
+          circt.stage.FirtoolOption("-o=" + targetFolder)
+        )