calyx_ir/
control.rs

1use calyx_frontend::Attribute;
2
3use super::StaticGroup;
4use std::rc::Rc;
5
6use super::{Attributes, Cell, CombGroup, GetAttributes, Group, Id, Port, RRC};
7
8type StaticLatency = u64;
9
10/// Data for the `seq` control statement.
11#[derive(Debug)]
12#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
13pub struct Seq {
14    /// List of `Control` statements to run in sequence.
15    pub stmts: Vec<Control>,
16    /// Attributes attached to this control statement.
17    pub attributes: Attributes,
18}
19impl GetAttributes for Seq {
20    fn get_attributes(&self) -> &Attributes {
21        &self.attributes
22    }
23    fn get_mut_attributes(&mut self) -> &mut Attributes {
24        &mut self.attributes
25    }
26}
27
28/// Data for the `static seq` control statement.
29#[derive(Debug)]
30#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
31pub struct StaticSeq {
32    /// List of `StaticControl` statements to run in sequence.
33    pub stmts: Vec<StaticControl>,
34    /// Attributes attached to this control statement.
35    pub attributes: Attributes,
36    /// Latency, in cycles
37    pub latency: StaticLatency,
38}
39impl GetAttributes for StaticSeq {
40    fn get_attributes(&self) -> &Attributes {
41        &self.attributes
42    }
43    fn get_mut_attributes(&mut self) -> &mut Attributes {
44        &mut self.attributes
45    }
46}
47
48/// Data for the `par` control statement.
49#[derive(Debug)]
50#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
51pub struct Par {
52    /// List of `Control` statements to run in parallel.
53    pub stmts: Vec<Control>,
54    /// Attributes attached to this control statement.
55    pub attributes: Attributes,
56}
57impl GetAttributes for Par {
58    fn get_attributes(&self) -> &Attributes {
59        &self.attributes
60    }
61    fn get_mut_attributes(&mut self) -> &mut Attributes {
62        &mut self.attributes
63    }
64}
65
66// Data for the `static par` control statement.
67#[derive(Debug)]
68#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
69pub struct StaticPar {
70    /// List of `StaticControl` statements to run in parallel.
71    pub stmts: Vec<StaticControl>,
72    /// Attributes attached to this control statement.
73    pub attributes: Attributes,
74    /// Latency, in cycles
75    pub latency: StaticLatency,
76}
77impl GetAttributes for StaticPar {
78    fn get_attributes(&self) -> &Attributes {
79        &self.attributes
80    }
81    fn get_mut_attributes(&mut self) -> &mut Attributes {
82        &mut self.attributes
83    }
84}
85
86/// Data for the `if` control statement.
87#[derive(Debug)]
88#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
89pub struct If {
90    /// Port that connects the conditional check.
91    pub port: RRC<Port>,
92
93    /// Optional combinational group attached using `with`.
94    pub cond: Option<RRC<CombGroup>>,
95
96    /// Control for the true branch.
97    pub tbranch: Box<Control>,
98
99    /// Control for the false branch.
100    pub fbranch: Box<Control>,
101
102    /// Attributes attached to this control statement.
103    pub attributes: Attributes,
104}
105impl GetAttributes for If {
106    fn get_attributes(&self) -> &Attributes {
107        &self.attributes
108    }
109
110    fn get_mut_attributes(&mut self) -> &mut Attributes {
111        &mut self.attributes
112    }
113}
114
115/// Data for the `static if` control statement.
116#[derive(Debug)]
117#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
118pub struct StaticIf {
119    /// Port that connects the conditional check.
120    pub port: RRC<Port>,
121
122    /// latency field
123    /// currrently, if two if branches take different amounts of time,
124    /// the latency to the length of the longer branch
125    pub latency: StaticLatency,
126
127    /// Control for the true branch.
128    pub tbranch: Box<StaticControl>,
129
130    /// Control for the false branch.
131    pub fbranch: Box<StaticControl>,
132
133    /// Attributes attached to this control statement.
134    pub attributes: Attributes,
135}
136impl GetAttributes for StaticIf {
137    fn get_attributes(&self) -> &Attributes {
138        &self.attributes
139    }
140
141    fn get_mut_attributes(&mut self) -> &mut Attributes {
142        &mut self.attributes
143    }
144}
145
146/// Data for the `while` control statement.
147#[derive(Debug)]
148#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
149pub struct While {
150    /// Port that connects the conditional check.
151    pub port: RRC<Port>,
152    /// Group that makes the signal on the conditional port valid.
153    pub cond: Option<RRC<CombGroup>>,
154    /// Control for the loop body.
155    pub body: Box<Control>,
156    /// Attributes attached to this control statement.
157    pub attributes: Attributes,
158}
159impl GetAttributes for While {
160    fn get_attributes(&self) -> &Attributes {
161        &self.attributes
162    }
163
164    fn get_mut_attributes(&mut self) -> &mut Attributes {
165        &mut self.attributes
166    }
167}
168
169/// Data for the Dynamic `Repeat` control statement. Repeats the body of the loop
170/// a given number times.
171#[derive(Debug)]
172#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
173pub struct Repeat {
174    /// Attributes
175    pub attributes: Attributes,
176    /// Body to repeat
177    pub body: Box<Control>,
178    /// Number of times to repeat the body
179    pub num_repeats: u64,
180}
181impl GetAttributes for Repeat {
182    fn get_attributes(&self) -> &Attributes {
183        &self.attributes
184    }
185
186    fn get_mut_attributes(&mut self) -> &mut Attributes {
187        &mut self.attributes
188    }
189}
190
191/// Data for the `StaticRepeat` control statement. Essentially a static while loop.
192#[derive(Debug)]
193#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
194pub struct StaticRepeat {
195    /// Attributes
196    pub attributes: Attributes,
197    /// Body to repeat
198    pub body: Box<StaticControl>,
199    /// Number of times to repeat the body
200    pub num_repeats: u64,
201    /// latency = num_repeats * (body latency)
202    pub latency: StaticLatency,
203}
204impl GetAttributes for StaticRepeat {
205    fn get_attributes(&self) -> &Attributes {
206        &self.attributes
207    }
208
209    fn get_mut_attributes(&mut self) -> &mut Attributes {
210        &mut self.attributes
211    }
212}
213
214/// Data for the `enable` control statement.
215#[derive(Debug)]
216#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
217pub struct Enable {
218    /// List of components to run.
219    pub group: RRC<Group>,
220    /// Attributes attached to this control statement.
221    pub attributes: Attributes,
222}
223impl GetAttributes for Enable {
224    fn get_attributes(&self) -> &Attributes {
225        &self.attributes
226    }
227
228    fn get_mut_attributes(&mut self) -> &mut Attributes {
229        &mut self.attributes
230    }
231}
232
233/// Data for the `enable` control for a static group.
234#[derive(Debug)]
235#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
236pub struct StaticEnable {
237    /// List of components to run.
238    pub group: RRC<StaticGroup>,
239    /// Attributes attached to this control statement.
240    pub attributes: Attributes,
241}
242impl GetAttributes for StaticEnable {
243    fn get_attributes(&self) -> &Attributes {
244        &self.attributes
245    }
246
247    fn get_mut_attributes(&mut self) -> &mut Attributes {
248        &mut self.attributes
249    }
250}
251
252impl StaticEnable {
253    /// Returns the value of an attribute if present
254    pub fn get_attribute(&self, attr: Attribute) -> Option<u64> {
255        self.get_attributes().get(attr)
256    }
257}
258
259type PortMap = Vec<(Id, RRC<Port>)>;
260type CellMap = Vec<(Id, RRC<Cell>)>;
261
262/// Data for an `invoke` control statement.
263#[derive(Debug)]
264#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
265pub struct Invoke {
266    /// Cell that is being invoked.
267    pub comp: RRC<Cell>,
268    /// Mapping from name of input ports in `comp` to the port connected to it.
269    pub inputs: PortMap,
270    /// Mapping from name of output ports in `comp` to the port connected to it.
271    pub outputs: PortMap,
272    /// Attributes attached to this control statement.
273    pub attributes: Attributes,
274    /// Optional combinational group that is active when the invoke is active.
275    pub comb_group: Option<RRC<CombGroup>>,
276    /// Mapping from name of external cell in 'comp' to the cell connected to it.
277    pub ref_cells: CellMap,
278}
279impl GetAttributes for Invoke {
280    fn get_attributes(&self) -> &Attributes {
281        &self.attributes
282    }
283
284    fn get_mut_attributes(&mut self) -> &mut Attributes {
285        &mut self.attributes
286    }
287}
288
289/// Data for a `StaticInvoke` control statement
290#[derive(Debug)]
291#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
292pub struct StaticInvoke {
293    /// Cell that is being invoked.
294    pub comp: RRC<Cell>,
295    /// StaticLatency
296    pub latency: StaticLatency,
297    /// Mapping from name of input ports in `comp` to the port connected to it.
298    pub inputs: PortMap,
299    /// Mapping from name of output ports in `comp` to the port connected to it.
300    pub outputs: PortMap,
301    /// Attributes attached to this control statement.
302    pub attributes: Attributes,
303    /// Mapping from name of external cell in 'comp' to the cell connected to it.
304    pub ref_cells: CellMap,
305    /// Optional combinational group that is active when the invoke is active.
306    pub comb_group: Option<RRC<CombGroup>>,
307}
308impl GetAttributes for StaticInvoke {
309    fn get_attributes(&self) -> &Attributes {
310        &self.attributes
311    }
312
313    fn get_mut_attributes(&mut self) -> &mut Attributes {
314        &mut self.attributes
315    }
316}
317
318/// Data for the `empty` control statement.
319#[derive(Debug, Default)]
320#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
321pub struct Empty {
322    pub attributes: Attributes,
323}
324
325/// Control AST nodes.
326#[derive(Debug)]
327#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
328pub enum Control {
329    /// Represents sequential composition of control statements.
330    Seq(Seq),
331    /// Represents parallel composition of control statements.
332    Par(Par),
333    /// Standard imperative if statement
334    If(If),
335    /// Standard imperative while statement
336    While(While),
337    /// Standard repeat control statement
338    Repeat(Repeat),
339    /// Invoke a sub-component with the given port assignments
340    Invoke(Invoke),
341    /// Runs the control for a list of subcomponents.
342    Enable(Enable),
343    /// Control statement that does nothing.
344    Empty(Empty),
345    /// Static Control
346    Static(StaticControl),
347}
348
349/// Control AST nodes.
350#[derive(Debug)]
351#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
352pub enum StaticControl {
353    Repeat(StaticRepeat),
354    Enable(StaticEnable),
355    Par(StaticPar),
356    Seq(StaticSeq),
357    If(StaticIf),
358    Empty(Empty),
359    Invoke(StaticInvoke),
360}
361
362impl From<Invoke> for Control {
363    fn from(inv: Invoke) -> Self {
364        Control::Invoke(inv)
365    }
366}
367
368impl From<Enable> for Control {
369    fn from(en: Enable) -> Self {
370        Control::Enable(en)
371    }
372}
373
374impl From<StaticControl> for Control {
375    fn from(sc: StaticControl) -> Self {
376        Control::Static(sc)
377    }
378}
379
380impl From<StaticEnable> for StaticControl {
381    fn from(se: StaticEnable) -> Self {
382        StaticControl::Enable(se)
383    }
384}
385
386impl From<RRC<StaticGroup>> for StaticControl {
387    fn from(sgroup: RRC<StaticGroup>) -> Self {
388        StaticControl::Enable(StaticEnable {
389            group: sgroup,
390            attributes: Attributes::default(),
391        })
392    }
393}
394
395impl<'a> From<&'a Control> for GenericControl<'a> {
396    fn from(c: &'a Control) -> Self {
397        match c {
398            Control::Static(sc) => GenericControl::Static(sc),
399            _ => GenericControl::Dynamic(c),
400        }
401    }
402}
403
404impl<'a> From<&'a StaticControl> for GenericControl<'a> {
405    fn from(sc: &'a StaticControl) -> Self {
406        GenericControl::Static(sc)
407    }
408}
409
410impl GetAttributes for Control {
411    fn get_mut_attributes(&mut self) -> &mut Attributes {
412        match self {
413            Self::Seq(Seq { attributes, .. })
414            | Self::Par(Par { attributes, .. })
415            | Self::If(If { attributes, .. })
416            | Self::While(While { attributes, .. })
417            | Self::Repeat(Repeat { attributes, .. })
418            | Self::Invoke(Invoke { attributes, .. })
419            | Self::Enable(Enable { attributes, .. })
420            | Self::Empty(Empty { attributes }) => attributes,
421            Self::Static(s) => s.get_mut_attributes(),
422        }
423    }
424
425    fn get_attributes(&self) -> &Attributes {
426        match self {
427            Self::Seq(Seq { attributes, .. })
428            | Self::Par(Par { attributes, .. })
429            | Self::If(If { attributes, .. })
430            | Self::While(While { attributes, .. })
431            | Self::Repeat(Repeat { attributes, .. })
432            | Self::Invoke(Invoke { attributes, .. })
433            | Self::Enable(Enable { attributes, .. })
434            | Self::Empty(Empty { attributes }) => attributes,
435            Self::Static(s) => s.get_attributes(),
436        }
437    }
438}
439
440impl GetAttributes for StaticControl {
441    fn get_mut_attributes(&mut self) -> &mut Attributes {
442        match self {
443            Self::Enable(StaticEnable { attributes, .. }) => attributes,
444            Self::Repeat(StaticRepeat { attributes, .. }) => attributes,
445            Self::Par(StaticPar { attributes, .. }) => attributes,
446            Self::Seq(StaticSeq { attributes, .. }) => attributes,
447            Self::If(StaticIf { attributes, .. }) => attributes,
448            Self::Empty(Empty { attributes, .. }) => attributes,
449            Self::Invoke(StaticInvoke { attributes, .. }) => attributes,
450        }
451    }
452    fn get_attributes(&self) -> &Attributes {
453        match self {
454            Self::Enable(StaticEnable { attributes, .. }) => attributes,
455            Self::Repeat(StaticRepeat { attributes, .. }) => attributes,
456            Self::Par(StaticPar { attributes, .. }) => attributes,
457            Self::Seq(StaticSeq { attributes, .. }) => attributes,
458            Self::If(StaticIf { attributes, .. }) => attributes,
459            Self::Empty(Empty { attributes, .. }) => attributes,
460            Self::Invoke(StaticInvoke { attributes, .. }) => attributes,
461        }
462    }
463}
464
465impl calyx_utils::WithPos for Control {
466    fn copy_span(&self) -> calyx_utils::GPosIdx {
467        self.get_attributes().copy_span()
468    }
469}
470
471impl Control {
472    // ================ Constructor methods ================
473    /// Convience constructor for empty.
474    pub fn empty() -> Self {
475        Control::Empty(Empty::default())
476    }
477
478    /// Convience constructor for seq.
479    pub fn seq(stmts: Vec<Control>) -> Self {
480        Control::Seq(Seq {
481            stmts,
482            attributes: Attributes::default(),
483        })
484    }
485
486    /// Convience constructor for par.
487    pub fn par(stmts: Vec<Control>) -> Self {
488        Control::Par(Par {
489            stmts,
490            attributes: Attributes::default(),
491        })
492    }
493
494    /// Convience constructor for enable.
495    pub fn enable(group: RRC<Group>) -> Self {
496        Control::Enable(Enable {
497            group,
498            attributes: Attributes::default(),
499        })
500    }
501
502    /// Convience constructor for enable.
503    pub fn static_enable(group: RRC<StaticGroup>) -> Self {
504        Control::Static(StaticControl::Enable(StaticEnable {
505            group,
506            attributes: Attributes::default(),
507        }))
508    }
509
510    /// Convience constructor for invoke.
511    pub fn invoke(comp: RRC<Cell>, inputs: PortMap, outputs: PortMap) -> Self {
512        Control::Invoke(Invoke {
513            comp,
514            inputs,
515            outputs,
516            attributes: Attributes::default(),
517            comb_group: None,
518            ref_cells: Vec::new(),
519        })
520    }
521
522    /// Convience constructor for if
523    pub fn if_(
524        port: RRC<Port>,
525        cond: Option<RRC<CombGroup>>,
526        tbranch: Box<Control>,
527        fbranch: Box<Control>,
528    ) -> Self {
529        Control::If(If {
530            port,
531            cond,
532            tbranch,
533            fbranch,
534            attributes: Attributes::default(),
535        })
536    }
537
538    /// Convience constructor for while
539    pub fn while_(
540        port: RRC<Port>,
541        cond: Option<RRC<CombGroup>>,
542        body: Box<Control>,
543    ) -> Self {
544        Control::While(While {
545            port,
546            cond,
547            body,
548            attributes: Attributes::default(),
549        })
550    }
551
552    /// Convience constructor for dynamic repeat
553    pub fn repeat(num_repeats: u64, body: Box<Control>) -> Self {
554        Control::Repeat(Repeat {
555            body,
556            num_repeats,
557            attributes: Attributes::default(),
558        })
559    }
560
561    /// Returns the value of an attribute if present
562    pub fn get_attribute<A>(&self, attr: A) -> Option<u64>
563    where
564        A: Into<Attribute>,
565    {
566        self.get_attributes().get(attr)
567    }
568
569    /// Returns true if the node has a specific attribute
570    pub fn has_attribute<A>(&self, attr: A) -> bool
571    where
572        A: Into<Attribute>,
573    {
574        self.get_attributes().has(attr)
575    }
576
577    pub fn is_static(&self) -> bool {
578        matches!(self, Control::Static(_))
579    }
580
581    pub fn is_empty(&self) -> bool {
582        matches!(self, Control::Static(StaticControl::Empty(_)))
583            || matches!(self, Control::Empty(_))
584    }
585
586    pub fn get_latency(&self) -> Option<StaticLatency> {
587        match self {
588            Control::Static(sc) => Some(sc.get_latency()),
589            _ => None,
590        }
591    }
592
593    /// Replaces &mut self with an empty control statement, and returns self
594    pub fn take_control(&mut self) -> Control {
595        let empty = Control::empty();
596        std::mem::replace(self, empty)
597    }
598
599    /// Replaces &mut self with an empty control statement, and returns StaticControl
600    /// of self. Note that this only works on Control that is static
601    pub fn take_static_control(&mut self) -> StaticControl {
602        let empty = Control::empty();
603        let control = std::mem::replace(self, empty);
604        let Control::Static(static_control) = control else {
605            unreachable!("Called take_static_control on non-static control")
606        };
607        static_control
608    }
609}
610
611impl StaticControl {
612    /// Convience constructor for empty.
613    pub fn empty() -> Self {
614        StaticControl::Empty(Empty::default())
615    }
616
617    /// Convience constructor for static enable.
618    pub fn seq(stmts: Vec<StaticControl>, latency: u64) -> Self {
619        StaticControl::Seq(StaticSeq {
620            stmts,
621            attributes: Attributes::default(),
622            latency,
623        })
624    }
625
626    /// Convience constructor for static enable.
627    pub fn par(stmts: Vec<StaticControl>, latency: u64) -> Self {
628        StaticControl::Par(StaticPar {
629            stmts,
630            attributes: Attributes::default(),
631            latency,
632        })
633    }
634
635    /// Convience constructor for static if
636    pub fn static_if(
637        port: RRC<Port>,
638        tbranch: Box<StaticControl>,
639        fbranch: Box<StaticControl>,
640        latency: u64,
641    ) -> Self {
642        StaticControl::If(StaticIf {
643            port,
644            tbranch,
645            fbranch,
646            attributes: Attributes::default(),
647            latency,
648        })
649    }
650
651    /// Convience constructor for static if
652    pub fn repeat(
653        num_repeats: u64,
654        latency: u64,
655        body: Box<StaticControl>,
656    ) -> Self {
657        StaticControl::Repeat(StaticRepeat {
658            body,
659            num_repeats,
660            latency,
661            attributes: Attributes::default(),
662        })
663    }
664
665    /// Returns the value of an attribute if present
666    pub fn get_attribute(&self, attr: Attribute) -> Option<u64> {
667        self.get_attributes().get(attr)
668    }
669
670    /// Returns the value of an attribute if present
671    pub fn get_latency(&self) -> StaticLatency {
672        match self {
673            StaticControl::Enable(StaticEnable { group, .. }) => {
674                group.borrow().get_latency()
675            }
676            StaticControl::Seq(StaticSeq { latency, .. })
677            | StaticControl::Par(StaticPar { latency, .. })
678            | StaticControl::Repeat(StaticRepeat { latency, .. })
679            | StaticControl::If(StaticIf { latency, .. })
680            | StaticControl::Invoke(StaticInvoke { latency, .. }) => *latency,
681            &StaticControl::Empty(_) => 0,
682        }
683    }
684
685    /// Replaces &mut self with an empty static control statement, and returns self
686    pub fn take_static_control(&mut self) -> StaticControl {
687        let empty = StaticControl::empty();
688        std::mem::replace(self, empty)
689    }
690}
691
692#[derive(Debug)]
693/// Either holds a reference to a StaticControl, reference to a Control, or None
694/// Helpful when we want to be able get get any specific control statement within a
695/// control program. For example, suppose we assign an id to each enable (static or dynamic)
696/// in the control program. A function that takes in an id and returns the appropriate
697/// enable would have to return a GenericControl.
698/// Has the weird affect that GenericControl::Dynamic(Control::Static(_)) can be
699/// a bit redundant with GenericControl::Static(_) but the latter gives us more precise access
700/// to every enum in the static control, instead of just the big wrapper.
701pub enum GenericControl<'a> {
702    Static(&'a StaticControl),
703    Dynamic(&'a Control),
704}
705
706/// Implement cloning operations on control statements.
707/// We implement these separatily from the [Clone] trait because cloning trait
708/// is not very common and clones should be explicit.
709pub struct Cloner;
710
711impl Cloner {
712    pub fn enable(en: &Enable) -> Enable {
713        Enable {
714            group: Rc::clone(&en.group),
715            attributes: en.attributes.clone(),
716        }
717    }
718
719    pub fn static_enable(en: &StaticEnable) -> StaticEnable {
720        StaticEnable {
721            group: Rc::clone(&en.group),
722            attributes: en.attributes.clone(),
723        }
724    }
725
726    pub fn invoke(inv: &Invoke) -> Invoke {
727        Invoke {
728            comp: Rc::clone(&inv.comp),
729            inputs: inv.inputs.clone(),
730            outputs: inv.outputs.clone(),
731            attributes: inv.attributes.clone(),
732            comb_group: inv.comb_group.clone(),
733            ref_cells: inv.ref_cells.clone(),
734        }
735    }
736
737    pub fn empty(en: &Empty) -> Empty {
738        Empty {
739            attributes: en.attributes.clone(),
740        }
741    }
742
743    pub fn while_(wh: &While) -> While {
744        While {
745            port: Rc::clone(&wh.port),
746            cond: wh.cond.clone(),
747            body: Box::new(Self::control(&wh.body)),
748            attributes: wh.attributes.clone(),
749        }
750    }
751
752    pub fn static_repeat(rep: &StaticRepeat) -> StaticRepeat {
753        StaticRepeat {
754            attributes: rep.attributes.clone(),
755            body: Box::new(Self::static_control(&rep.body)),
756            num_repeats: rep.num_repeats,
757            latency: rep.latency,
758        }
759    }
760
761    pub fn repeat(rep: &Repeat) -> Repeat {
762        Repeat {
763            attributes: rep.attributes.clone(),
764            body: Box::new(Self::control(&rep.body)),
765            num_repeats: rep.num_repeats,
766        }
767    }
768
769    pub fn if_(if_: &If) -> If {
770        If {
771            port: Rc::clone(&if_.port),
772            cond: if_.cond.clone(),
773            tbranch: Box::new(Self::control(&if_.tbranch)),
774            fbranch: Box::new(Self::control(&if_.fbranch)),
775            attributes: if_.attributes.clone(),
776        }
777    }
778
779    pub fn static_if(sif: &StaticIf) -> StaticIf {
780        StaticIf {
781            port: Rc::clone(&sif.port),
782            latency: sif.latency,
783            tbranch: Box::new(Self::static_control(&sif.tbranch)),
784            fbranch: Box::new(Self::static_control(&sif.fbranch)),
785            attributes: sif.attributes.clone(),
786        }
787    }
788
789    pub fn par(par: &Par) -> Par {
790        Par {
791            stmts: par.stmts.iter().map(Self::control).collect(),
792            attributes: par.attributes.clone(),
793        }
794    }
795
796    pub fn static_par(par: &StaticPar) -> StaticPar {
797        StaticPar {
798            stmts: par.stmts.iter().map(Self::static_control).collect(),
799            attributes: par.attributes.clone(),
800            latency: par.latency,
801        }
802    }
803
804    pub fn seq(seq: &Seq) -> Seq {
805        Seq {
806            stmts: seq.stmts.iter().map(Self::control).collect(),
807            attributes: seq.attributes.clone(),
808        }
809    }
810
811    pub fn static_seq(seq: &StaticSeq) -> StaticSeq {
812        StaticSeq {
813            stmts: seq.stmts.iter().map(Self::static_control).collect(),
814            attributes: seq.attributes.clone(),
815            latency: seq.latency,
816        }
817    }
818
819    pub fn static_invoke(i: &StaticInvoke) -> StaticInvoke {
820        StaticInvoke {
821            comp: Rc::clone(&i.comp),
822            latency: i.latency,
823            inputs: i.inputs.clone(),
824            outputs: i.outputs.clone(),
825            attributes: i.attributes.clone(),
826            ref_cells: i.ref_cells.clone(),
827            comb_group: i.comb_group.clone(),
828        }
829    }
830
831    pub fn static_control(s: &StaticControl) -> StaticControl {
832        match s {
833            StaticControl::Enable(sen) => {
834                StaticControl::Enable(Cloner::static_enable(sen))
835            }
836            StaticControl::Repeat(rep) => {
837                StaticControl::Repeat(Cloner::static_repeat(rep))
838            }
839            StaticControl::Seq(sseq) => {
840                StaticControl::Seq(Cloner::static_seq(sseq))
841            }
842            StaticControl::Par(spar) => {
843                StaticControl::Par(Cloner::static_par(spar))
844            }
845            StaticControl::If(sif) => StaticControl::If(Cloner::static_if(sif)),
846            StaticControl::Empty(e) => StaticControl::Empty(Self::empty(e)),
847            StaticControl::Invoke(si) => {
848                StaticControl::Invoke(Self::static_invoke(si))
849            }
850        }
851    }
852
853    pub fn control(con: &Control) -> Control {
854        match con {
855            Control::Seq(seq) => Control::Seq(Cloner::seq(seq)),
856            Control::Par(par) => Control::Par(Cloner::par(par)),
857            Control::If(if_) => Control::If(Cloner::if_(if_)),
858            Control::While(wh) => Control::While(Cloner::while_(wh)),
859            Control::Repeat(repeat) => Control::Repeat(Cloner::repeat(repeat)),
860            Control::Invoke(inv) => Control::Invoke(Cloner::invoke(inv)),
861            Control::Enable(en) => Control::Enable(Cloner::enable(en)),
862            Control::Empty(en) => Control::Empty(Cloner::empty(en)),
863            Control::Static(s) => Control::Static(Cloner::static_control(s)),
864        }
865    }
866}