Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use External Libraries To Generate A Single Verilog File #1985

Open
jiahanxie353 opened this issue Mar 20, 2024 · 0 comments
Open

Use External Libraries To Generate A Single Verilog File #1985

jiahanxie353 opened this issue Mar 20, 2024 · 0 comments
Labels
C: Verilog Status: In progress Issue is being worked on Type: Tracker Track various tasks

Comments

@jiahanxie353
Copy link
Collaborator

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:

fn link_externs(
ctx: &ir::Context,
file: &mut OutputFile,
) -> CalyxResult<()> {
let fw = &mut file.get_write();
for extern_path in &ctx.lib.extern_paths() {
// The extern file is guaranteed to exist by the frontend.
let mut ext = File::open(extern_path).unwrap();
io::copy(&mut ext, fw).map_err(|err| {
let std::io::Error { .. } = err;
Error::write_error(format!(
"File not found: {}",
file.as_path_string()
))
})?;
// Add a newline after appending a library file
writeln!(fw)?;
}

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: Verilog Status: In progress Issue is being worked on Type: Tracker Track various tasks
Projects
None yet
Development

No branches or pull requests

2 participants