calyx_opt/passes/
clk_insertion.rs

1use crate::traversal::{Action, Named, VisResult, Visitor};
2use calyx_ir::{self as ir, LibrarySignatures};
3use calyx_utils::Error;
4use std::rc::Rc;
5
6#[derive(Default)]
7/// Adds assignments from a components `clk` port to every
8/// component that contains an input `clk` port.
9pub struct ClkInsertion;
10
11impl Named for ClkInsertion {
12    fn name() -> &'static str {
13        "clk-insertion"
14    }
15
16    fn description() -> &'static str {
17        "inserts assignments from component clk to sub-component clk"
18    }
19}
20
21impl Visitor for ClkInsertion {
22    fn start(
23        &mut self,
24        comp: &mut ir::Component,
25        sigs: &LibrarySignatures,
26        _comps: &[ir::Component],
27    ) -> VisResult {
28        let builder = ir::Builder::new(comp, sigs);
29        // Find @clk port in the component. If it doesn't exist,
30        // then we don't need to do anything.
31        let clk = builder
32            .component
33            .signature
34            .borrow()
35            .find_unique_with_attr(ir::BoolAttr::Clk)?;
36
37        if let Some(clk) = clk {
38            for cell_ref in builder.component.cells.iter() {
39                let cell = cell_ref.borrow();
40                if let Some(port) =
41                    cell.find_unique_with_attr(ir::BoolAttr::Clk)?
42                {
43                    builder.component.continuous_assignments.push(
44                        builder.build_assignment(
45                            port,
46                            Rc::clone(&clk),
47                            ir::Guard::True,
48                        ),
49                    )
50                }
51            }
52        } else {
53            for cell_ref in builder.component.cells.iter() {
54                let cell = cell_ref.borrow();
55                if cell.find_unique_with_attr(ir::BoolAttr::Clk)?.is_some() {
56                    return Err(Error::malformed_structure(format!(
57                        "Cell `{}' in component `{}' has a clk port, \
58                        but the component does not have a clk port.",
59                        cell.name(),
60                        builder.component.name
61                    )));
62                }
63            }
64        }
65
66        // we don't need to traverse control
67        Ok(Action::Stop)
68    }
69}