diff --git a/calyx-opt/src/passes/clk_insertion.rs b/calyx-opt/src/passes/clk_insertion.rs index 8e4fb9e529..e0ca0dbea6 100644 --- a/calyx-opt/src/passes/clk_insertion.rs +++ b/calyx-opt/src/passes/clk_insertion.rs @@ -1,5 +1,6 @@ use crate::traversal::{Action, Named, VisResult, Visitor}; use calyx_ir::{self as ir, LibrarySignatures}; +use calyx_utils::Error; use std::rc::Rc; #[derive(Default)] @@ -25,22 +26,38 @@ impl Visitor for ClkInsertion { _comps: &[ir::Component], ) -> VisResult { let builder = ir::Builder::new(comp, sigs); + // Find @clk port in the component. If it doesn't exist, + // then we don't need to do anything. let clk = builder .component .signature .borrow() - .get_with_attr(ir::BoolAttr::Clk); + .find_with_attr(ir::BoolAttr::Clk); - for cell_ref in builder.component.cells.iter() { - let cell = cell_ref.borrow(); - if let Some(port) = cell.find_with_attr(ir::BoolAttr::Clk) { - builder.component.continuous_assignments.push( - builder.build_assignment( - port, - Rc::clone(&clk), - ir::Guard::True, - ), - ) + if let Some(clk) = clk { + for cell_ref in builder.component.cells.iter() { + let cell = cell_ref.borrow(); + if let Some(port) = cell.find_with_attr(ir::BoolAttr::Clk) { + builder.component.continuous_assignments.push( + builder.build_assignment( + port, + Rc::clone(&clk), + ir::Guard::True, + ), + ) + } + } + } else { + for cell_ref in builder.component.cells.iter() { + let cell = cell_ref.borrow(); + if cell.find_with_attr(ir::BoolAttr::Clk).is_some() { + return Err(Error::malformed_structure(format!( + "Cell `{}' in component `{}' has a clk port, \ + but the component does not have a clk port.", + cell.name(), + builder.component.name + ))); + } } } diff --git a/calyx-opt/src/passes/reset_insertion.rs b/calyx-opt/src/passes/reset_insertion.rs index b2040af3ab..ef105404dd 100644 --- a/calyx-opt/src/passes/reset_insertion.rs +++ b/calyx-opt/src/passes/reset_insertion.rs @@ -1,7 +1,7 @@ -use std::rc::Rc; - use crate::traversal::{Action, Named, VisResult, Visitor}; use calyx_ir::{self as ir, LibrarySignatures}; +use calyx_utils::Error; +use std::rc::Rc; #[derive(Default)] /// Adds assignments from a components `reset` port to every @@ -30,18 +30,32 @@ impl Visitor for ResetInsertion { .component .signature .borrow() - .get_with_attr(ir::BoolAttr::Reset); + .find_with_attr(ir::BoolAttr::Reset); - for cell_ref in builder.component.cells.iter() { - let cell = cell_ref.borrow(); - if let Some(port) = cell.find_with_attr(ir::BoolAttr::Reset) { - builder.component.continuous_assignments.push( - builder.build_assignment( - port, - Rc::clone(&reset), - ir::Guard::True, - ), - ) + if let Some(reset) = reset { + for cell_ref in builder.component.cells.iter() { + let cell = cell_ref.borrow(); + if let Some(port) = cell.find_with_attr(ir::BoolAttr::Reset) { + builder.component.continuous_assignments.push( + builder.build_assignment( + port, + Rc::clone(&reset), + ir::Guard::True, + ), + ) + } + } + } else { + for cell_ref in builder.component.cells.iter() { + let cell = cell_ref.borrow(); + if cell.find_with_attr(ir::BoolAttr::Reset).is_some() { + return Err(Error::malformed_structure(format!( + "Cell `{}' in component `{}' has a reset port, \ + but the component does not have a reset port.", + cell.name(), + builder.component.name + ))); + } } } diff --git a/tests/passes/clk-insertion.expect b/tests/passes/clk-insertion.expect new file mode 100644 index 0000000000..1bfaf0d00b --- /dev/null +++ b/tests/passes/clk-insertion.expect @@ -0,0 +1,21 @@ +import "primitives/core.futil"; +comb component layout_hw0() -> (flat_port_addr0: 4) { + cells { + add_0 = std_add(4); + } + wires { + flat_port_addr0 = add_0.out; + add_0.left = 4'd1; + add_0.right = 4'd2; + } +} +component main(@clk clk: 1, @go go: 1, @reset reset: 1) -> (out: 32, @done done: 1) { + cells { + r = std_reg(32); + } + wires { + out = r.out; + r.clk = clk; + } + control {} +} diff --git a/tests/passes/clk-insertion.futil b/tests/passes/clk-insertion.futil new file mode 100644 index 0000000000..ac71312483 --- /dev/null +++ b/tests/passes/clk-insertion.futil @@ -0,0 +1,22 @@ +// -p well-formed -p clk-insertion +import "primitives/core.futil"; +comb component layout_hw0() -> (flat_port_addr0: 4) { + cells { + add_0 = std_add(4); + } + wires { + flat_port_addr0 = add_0.out; + add_0.left = 4'd1; + add_0.right = 4'd2; + } +} + +component main(@clk clk: 1) -> (out: 32) { + cells { + r = std_reg(32); + } + wires { + out = r.out; + } + control {} +} \ No newline at end of file