calyx_opt/passes/
reset_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 `reset` port to every
8/// component that contains an input `reset` port.
9pub struct ResetInsertion;
10
11impl Named for ResetInsertion {
12    fn name() -> &'static str {
13        "reset-insertion"
14    }
15
16    fn description() -> &'static str {
17        "connect component reset to sub-component reset for applicable components"
18    }
19}
20
21impl Visitor for ResetInsertion {
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        let reset = builder
30            .component
31            .signature
32            .borrow()
33            .find_unique_with_attr(ir::BoolAttr::Reset)?;
34
35        if let Some(reset) = reset {
36            for cell_ref in builder.component.cells.iter() {
37                let cell = cell_ref.borrow();
38                if let Some(port) =
39                    cell.find_unique_with_attr(ir::BoolAttr::Reset)?
40                {
41                    builder.component.continuous_assignments.push(
42                        builder.build_assignment(
43                            port,
44                            Rc::clone(&reset),
45                            ir::Guard::True,
46                        ),
47                    )
48                }
49            }
50        } else {
51            for cell_ref in builder.component.cells.iter() {
52                let cell = cell_ref.borrow();
53                if cell.find_unique_with_attr(ir::BoolAttr::Reset)?.is_some() {
54                    return Err(Error::malformed_structure(format!(
55                        "Cell `{}' in component `{}' has a reset port, \
56                        but the component does not have a reset port.",
57                        cell.name(),
58                        builder.component.name
59                    )));
60                }
61            }
62        }
63
64        // we don't need to traverse control
65        Ok(Action::Stop)
66    }
67}