Skip to content

Commit

Permalink
[Calyx-FIRRTL] Primitive cell bug fix (#1838)
Browse files Browse the repository at this point in the history
* First commit of what I believe is the fix for primitive extmodule port bug. Need to fix the code clone

* fix code clone

* Update tests. Need to manually test whether this will compile in FIRRTL

* Fix formatting error

* recover panic message for an inout port

* Fixes from review comments
  • Loading branch information
ayakayorihiro authored and rachitnigam committed Feb 16, 2024
1 parent 2434c6a commit 02ebf99
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 27 deletions.
80 changes: 53 additions & 27 deletions calyx-backend/src/firrtl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use crate::{traits::Backend, VerilogBackend};
use calyx_ir::{self as ir, Binding, RRC};
use calyx_utils::{CalyxResult, Id, OutputFile};
use ir::Port;
use std::collections::HashSet;
use std::io;

Expand Down Expand Up @@ -50,6 +51,7 @@ impl Backend for FirrtlBackend {
get_primitive_module_name(name, param_binding);
if extmodule_set.insert(curr_module_name.clone()) {
emit_primitive_extmodule(
cell.borrow().ports(),
&curr_module_name,
name,
param_binding,
Expand Down Expand Up @@ -77,33 +79,7 @@ fn emit_component<F: io::Write>(
let sig = comp.signature.borrow();
for (_idx, port_ref) in sig.ports.iter().enumerate() {
let port = port_ref.borrow();
let direction_string =
// NOTE: The signature port definitions are reversed inside the component.
match port.direction {
ir::Direction::Input => {"output"}
ir::Direction::Output => {"input"}
ir::Direction::Inout => {
panic!("Unexpected Inout port on Component: {}", port.name)
}
};
if port.has_attribute(ir::BoolAttr::Clk) {
writeln!(
f,
"{}{} {}: Clock",
SPACING.repeat(2),
direction_string,
port.name
)?;
} else {
writeln!(
f,
"{}{} {}: UInt<{}>",
SPACING.repeat(2),
direction_string,
port.name,
port.width
)?;
}
emit_port(port, true, f)?;
}

// Add a COMPONENT START: <name> anchor before any code in the component
Expand Down Expand Up @@ -175,12 +151,17 @@ fn get_primitive_module_name(name: &Id, param_binding: &Binding) -> String {
}

fn emit_primitive_extmodule<F: io::Write>(
ports: &[RRC<Port>],
curr_module_name: &String,
name: &Id,
param_binding: &Binding,
f: &mut F,
) -> io::Result<()> {
writeln!(f, "{}extmodule {}:", SPACING, curr_module_name)?;
for port in ports {
let port_borrowed = port.borrow();
emit_port(port_borrowed, false, f)?;
}
writeln!(f, "{}defname = {}", SPACING.repeat(2), name)?;
for (id, size) in param_binding.as_ref().iter() {
writeln!(f, "{}parameter {} = {}", SPACING.repeat(2), id, size)?;
Expand All @@ -189,6 +170,51 @@ fn emit_primitive_extmodule<F: io::Write>(
Ok(())
}

fn emit_port<F: io::Write>(
port: std::cell::Ref<'_, Port>,
reverse_direction: bool,
f: &mut F,
) -> Result<(), io::Error> {
let direction_string = match port.direction {
calyx_frontend::Direction::Input => {
if reverse_direction {
"output"
} else {
"input"
}
}
calyx_frontend::Direction::Output => {
if reverse_direction {
"input"
} else {
"output"
}
}
calyx_frontend::Direction::Inout => {
panic!("Unexpected Inout port on Component: {}", port.name)
}
};
if port.has_attribute(ir::BoolAttr::Clk) {
writeln!(
f,
"{}{} {}: Clock",
SPACING.repeat(2),
direction_string,
port.name
)?;
} else {
writeln!(
f,
"{}{} {}: UInt<{}>",
SPACING.repeat(2),
direction_string,
port.name,
port.width
)?;
};
Ok(())
}

// fn create_primitive_extmodule() {}

// recursive function that writes the FIRRTL representation for a guard.
Expand Down
2 changes: 2 additions & 0 deletions tests/backend/firrtl/basic-cell.expect
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
circuit main:
extmodule std_wire_1:
input in: UInt<1>
output out: UInt<1>
defname = std_wire
parameter WIDTH = 1

Expand Down
5 changes: 5 additions & 0 deletions tests/backend/firrtl/primitive-cells.expect
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
circuit main:
extmodule std_add_32:
input left: UInt<32>
input right: UInt<32>
output out: UInt<32>
defname = std_add
parameter WIDTH = 32

extmodule std_wire_1:
input in: UInt<1>
output out: UInt<1>
defname = std_wire
parameter WIDTH = 1

Expand Down

0 comments on commit 02ebf99

Please sign in to comment.