<file>.v name appended to generated SV file when a blackbox is used
Type of issue: Bug Report
Please provide the steps to reproduce the problem:
I came across this issue when bumping a project from Chisel 5.0 -> 6.2, I've tried to narrow it down as much as possible:
I use a Blackbox feature to import a design in Verilog to Chisel via Blackbox with HasBlackBoxResource, I then interface it in another module and emitSystemVerilogFile.
The implemented classes:
package AIG
import chisel3._
import chisel3.util.HasBlackBoxResource
import circt.stage.ChiselStage
class AcceleratorBlackbox extends BlackBox with HasBlackBoxResource {
override val desiredName = "fpga_isp"
val io = IO(new Bundle {
val sys_clk = Input(Clock())
val sys_rst = Input(Reset())
val raw_payload_data = Input(UInt(32.W))
val raw_valid = Input(Bool())
val raw_ready = Output(Bool())
val raw_first = Input(Bool())
val raw_last = Input(Bool())
val rgb_payload_data = Output(UInt(32.W))
val rgb_valid = Output(Bool())
val rgb_ready = Input(Bool())
val rgb_first = Output(Bool())
val rgb_last = Output(Bool())
val bgr = Input(Bool())
val pattern = Input(UInt(2.W))
val busy = Output(Bool())
val algorithm = Input(UInt(3.W))
val rows = Input(UInt(13.W))
val cols = Input(UInt(13.W))
})
addResource("fpga_isp.sv")
}
class AcceleratorModule extends Module {
val accelerator = Module(new AcceleratorBlackbox)
val io = IO(new Bundle {
val raw_payload_data = Input(UInt(32.W))
val raw_valid = Input(Bool())
val raw_first = Input(Bool())
val raw_last = Input(Bool())
val rgb_ready = Input(Bool())
val bgr = Input(Bool())
val pattern = Input(UInt(2.W))
val algorithm = Input(UInt(3.W))
val rows = Input(UInt(13.W))
val cols = Input(UInt(13.W))
})
accelerator.io.sys_clk := clock
accelerator.io.sys_rst := reset
accelerator.io.raw_payload_data := io.raw_payload_data
accelerator.io.raw_valid := io.raw_valid
accelerator.io.raw_first := io.raw_first
accelerator.io.raw_last := io.raw_last
accelerator.io.rgb_ready := io.rgb_ready
accelerator.io.bgr := io.bgr
accelerator.io.pattern := io.pattern
accelerator.io.algorithm := io.algorithm
accelerator.io.rows := io.rows
accelerator.io.cols := io.cols
}
object Driver extends App {
ChiselStage.emitSystemVerilogFile(new AcceleratorModule)
}
I use the sbt and run with sbt "runMain AIG.Driver"
Here's a resource file I'm using: fpga_ispSV.log
And here's the output SystemVerilog file: AcceleratorModuleSV.log
What is the current behavior?
The ./fpga_isp.v line is appended at the end of AcceleratorModule.sv file.
What is the expected behavior?
The name of the included resource to not be appended to the end of the file as it causes an error with the later used SystemVerilog file. I've searched the specification but I didn't find it to be a legal expression.
Please tell us about your environment:
- chisel version: 6.2.0
- scala version: 2.13.12
- firtool version: 1.68.0
- sbt version: 1.6.2
- java-11-openjdk
- OS: Linux Terassen 6.4.7-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 27 Jul 2023 22:02:18 +0000 x86_64 GNU/Linux
The single-file output is not super well supported and is more intended for testing. What's happening is that this is outputting the contents of all files into one file. Can you try with:
ChiselStage.emitSystemVerilogFile(new AcceleratorModule, Array("--split-verilog"))
Thanks for the explanation.
The issue doesn't persist with "--split-verilog" option and the files are synthesisable.
I am having this issue as well when defining an inline BlackBox with Chisel 7.0.0-M1. My BlackBox is named MemuBlackBox, and the final single-file output as these lines appended:
// ----- 8< ----- FILE "./MemuBlackBox.sv" ----- 8< -----
// Generated by CIRCT firtool-1.66.0
module MemuBlackBox(
...
);
...
endmodule
// ----- 8< ----- FILE "firrtl_black_box_resource_files.f" ----- 8< -----
MemuBlackBox.sv
which is consistent with @wkkuna's observation.
However, after implementing @seldridge's solution (appending --split-verilog), Chisel no longer produces my top-level module. Suppose my top module is named Top, then the build artifact will contain an empty file named Top.sv.
Is there a way to fix this?
Since I have not come to a solution of this issue, I've written a script for manually stripping all .f files from generated output. The following script overwrites each files specified in cmdline with stripped content.
#!/usr/bin/env python3
import re
from argparse import ArgumentParser
RE_BANNER = re.compile(r"^// ----- 8< ----- FILE \"((?:.+)\.(?:.+))\" ----- 8< -----$")
RE_FILE_F = re.compile(r"^.+\.f$")
def match_banner(line: str) -> str | None:
match RE_BANNER.match(line):
case None:
return None
case m:
return m.group(1)
parser = ArgumentParser(
description="Remove .f content from SystemVerilog files generated by Chisel"
)
parser.add_argument(
"filenames",
metavar="FILE",
type=str,
nargs="+",
help="SystemVerilog files to process",
)
args = parser.parse_args()
for filename in args.filenames:
with open(filename, "rt") as f:
lines = f.readlines()
with open(filename, "wt") as f:
in_f_file = False
for banners in enumerate(map(match_banner, lines)):
if banners[1] is None:
pass
elif RE_FILE_F.match(banners[1]) is None:
in_f_file = False
else:
in_f_file = True
if not in_f_file:
print(lines[banners[0]], end="", file=f)
The single-file output is not super well supported and is more intended for testing. What's happening is that this is outputting the contents of all files into one file. Can you try with:
ChiselStage.emitSystemVerilogFile(new AcceleratorModule, Array("--split-verilog"))
I encountered the same problem... Especially when using HasBlackBoxInline and setInline, the "--split-verilog" seems not effectively split the blackbox to a seperated file, so I can only a script to delete it