calyxir / calyx

Intermediate Language (IL) for Hardware Accelerator Generators
https://calyxir.org
MIT License
450 stars 44 forks source link

Use External Libraries To Generate A Single Verilog File #1985

Open jiahanxie353 opened 1 month ago

jiahanxie353 commented 1 month ago

Issue

When we have extern definitions, we link against the RTL program and copy paste the content specified by the path variable.

This works well with all existing primitives. With the integration of floating point primitives support to Calyx #1928 , we need a more versatile way to handle complicated file structure and includes in the Berkeley HardFloat project. In addition, since Berkeley HardFloat repo has some unconventional namings, such as *.vi for "Verilog interface", we are facing compilation issues when trying to pushing down the design for FPGA simulation. Therefore, we want to generate a single, big Verilog file that contains everything, including the primitive itself and all its dependencies.

A Potential Solution

To this end, I'd propose to use morty as our tool, thanks to @sampsyo @rachitnigam 's advice. Morty "reads SystemVerilog files and pickles them into a single file for easier handling." If we'd like to compile a Calyx program that imports the following externs:

import "primitives/core.futil";
import "primitives/memories/comb.futil";
import "primitives/float/mulFN.futil";

we can simply have an example.json file:

[
  {
    "include_dirs": [
      "primitives/float/HardFloat-1/source/",
      "primitives/float/HardFloat-1/source/RISCV/"
    ],
    "defines": {},
    "files": [
      "primitives/core.sv",
      "primitives/memories/comb.sv",
      "primitives/float/mulFN.sv",
    ]
  }
]

By running command morty -f example.json, morty will simply resolve the dependencies and generate a big, compile-able System Verilog program to stdout stream.

Implementation-wise, the following chunk of code was used to link and copy-paste external Verilog files: https://github.com/calyxir/calyx/blob/e89ed248bd131ca23ef09b55e76d254e1d9f23af/calyx-backend/src/verilog.rs#L109-L126

One possible solution is to replace it with a function that generates/manipulates a json file. It'll iterate over the paths in ctx.lib.extern_paths to append these paths to the files field of the json file. Then, we simply invoke morty command to generate that Verilog stdout to be piped.

@evanmwilliams and I will be working on this issue.