Chisel blackbox generating syntax error in generated verilog
HakamAtassi opened this issue · comments
Hello!
I was about to post this on stack overflow but saw that another user has demonstrated the same exact issue but has no answers. See here.
I have the following chisel black box defined:
class nReadmWrite extends BlackBox with HasBlackBoxResource {
val io = IO(new Bundle {
val clock = Input(Clock())
val reset = Input(Bool())
val raddr_0 = Input(UInt(6.W))
val raddr_1 = Input(UInt(6.W))
val raddr_2 = Input(UInt(6.W))
val raddr_3 = Input(UInt(6.W))
val raddr_4 = Input(UInt(6.W))
val raddr_5 = Input(UInt(6.W))
val raddr_6 = Input(UInt(6.W))
val raddr_7 = Input(UInt(6.W))
val rdata_0 = Output(UInt(32.W))
val rdata_1 = Output(UInt(32.W))
val rdata_2 = Output(UInt(32.W))
val rdata_3 = Output(UInt(32.W))
val rdata_4 = Output(UInt(32.W))
val rdata_5 = Output(UInt(32.W))
val rdata_6 = Output(UInt(32.W))
val rdata_7 = Output(UInt(32.W))
val waddr_0 = Input(UInt(6.W))
val waddr_1 = Input(UInt(6.W))
val waddr_2 = Input(UInt(6.W))
val waddr_3 = Input(UInt(6.W))
val wen_0 = Input(Bool())
val wen_1 = Input(Bool())
val wen_2 = Input(Bool())
val wen_3 = Input(Bool())
val wdata_0 = Input(UInt(32.W))
val wdata_1 = Input(UInt(32.W))
val wdata_2 = Input(UInt(32.W))
val wdata_3 = Input(UInt(32.W))
})
// Reference the external Verilog file
addResource("/nReadmWrite.v")
}
which generates to the expected verilog but leaves behind an artifact that causes a syntax error. Namely, at the very end of my file, directly after the endmodule
of my blackbox, I see the following:
// rest of the module...
endmodule // Blackbox endmodule
// ----- 8< ----- FILE "firrtl_black_box_resource_files.f" ----- 8< ----- // not sure what this is, but its fine, I guess
nReadmWrite.v // Syntax error
No idea why this artifact is left behind. When I delete the line, the generated verilog is synthesized fine.
I'm Generating the verilog using the following command:
ChiselStage.emitSystemVerilogFile(new backend(parameters), firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info"))
My build file is
// See README.md for license details.
ThisBuild / scalaVersion := "2.13.12"
ThisBuild / version := "0.1.0"
ThisBuild / organization := "%ORGANIZATION%"
val chiselVersion = "6.2.0"
lazy val root = (project in file("."))
.settings(
name := "ChaosCore",
libraryDependencies ++= Seq(
"org.chipsalliance" %% "chisel" % chiselVersion,
"org.scalatest" %% "scalatest" % "3.2.16" % "test",
),
scalacOptions ++= Seq(
"-language:reflectiveCalls",
"-deprecation",
"-feature",
"-Xcheckinit",
"-Ymacro-annotations",
),
addCompilerPlugin("org.chipsalliance" % "chisel-plugin" % chiselVersion cross CrossVersion.full),
)
How do I get chisel to stop generating this artifact?
bumping. Several folks have complained about this issue on stack overflow with no real solution or responses anywhere.
Could you try split-verilog emission suggested in #3933 (comment)?
Hey,
Thanks for the response. That does seem to prevent the "moduleName.v" from being generated in the verilog file, but does generate all the verilog files separately, meaning one can no longer simply copy paste a single generated file into a synthesis tool for debugging and so on.
Is there an approach that maintains a single output file? Thanks in advance.
The underlying problem is that Chisel has this implicit ABI contract that a filelist will be produced listing all the blackboxes. This is fundamentally incompatible with single-file emission mode as the file is not a Verilog file. For the purposes of testing, in single-file emission mode CIRCT will use those comments as "file separators" to indicate what would go into each file.
What is missing on the CIRCT side is a more reasonable third file emission mode that will write all Verilog files to the same file, but create other files if they are supposed to exist. I don't expect that this is that complicated to add to CIRCT. However, most industrial users of Chisel are only using multi-file emission mode.
Ah okay that is good to know. Thanks @seldridge. Take care.