chisel icon indicating copy to clipboard operation
chisel copied to clipboard

<file>.v name appended to generated SV file when a blackbox is used

Open wkkuna opened this issue 1 year ago • 4 comments

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

wkkuna avatar Mar 15 '24 13:03 wkkuna

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"))

seldridge avatar Mar 15 '24 16:03 seldridge

Thanks for the explanation. The issue doesn't persist with "--split-verilog" option and the files are synthesisable.

wkkuna avatar Mar 15 '24 17:03 wkkuna

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)

CSharperMantle avatar May 26 '24 00:05 CSharperMantle

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

IveanEx avatar Aug 01 '24 22:08 IveanEx