calyx_ir/
control.rs

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