use calyx_frontend::Attribute;
use super::StaticGroup;
use std::rc::Rc;
use super::{Attributes, Cell, CombGroup, GetAttributes, Group, Id, Port, RRC};
type StaticLatency = u64;
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Seq {
pub stmts: Vec<Control>,
pub attributes: Attributes,
}
impl GetAttributes for Seq {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct StaticSeq {
pub stmts: Vec<StaticControl>,
pub attributes: Attributes,
pub latency: StaticLatency,
}
impl GetAttributes for StaticSeq {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Par {
pub stmts: Vec<Control>,
pub attributes: Attributes,
}
impl GetAttributes for Par {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct StaticPar {
pub stmts: Vec<StaticControl>,
pub attributes: Attributes,
pub latency: StaticLatency,
}
impl GetAttributes for StaticPar {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct If {
pub port: RRC<Port>,
pub cond: Option<RRC<CombGroup>>,
pub tbranch: Box<Control>,
pub fbranch: Box<Control>,
pub attributes: Attributes,
}
impl GetAttributes for If {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct StaticIf {
pub port: RRC<Port>,
pub latency: StaticLatency,
pub tbranch: Box<StaticControl>,
pub fbranch: Box<StaticControl>,
pub attributes: Attributes,
}
impl GetAttributes for StaticIf {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct While {
pub port: RRC<Port>,
pub cond: Option<RRC<CombGroup>>,
pub body: Box<Control>,
pub attributes: Attributes,
}
impl GetAttributes for While {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Repeat {
pub attributes: Attributes,
pub body: Box<Control>,
pub num_repeats: u64,
}
impl GetAttributes for Repeat {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct StaticRepeat {
pub attributes: Attributes,
pub body: Box<StaticControl>,
pub num_repeats: u64,
pub latency: StaticLatency,
}
impl GetAttributes for StaticRepeat {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Enable {
pub group: RRC<Group>,
pub attributes: Attributes,
}
impl GetAttributes for Enable {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct StaticEnable {
pub group: RRC<StaticGroup>,
pub attributes: Attributes,
}
impl GetAttributes for StaticEnable {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
impl StaticEnable {
pub fn get_attribute(&self, attr: Attribute) -> Option<u64> {
self.get_attributes().get(attr)
}
}
type PortMap = Vec<(Id, RRC<Port>)>;
type CellMap = Vec<(Id, RRC<Cell>)>;
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Invoke {
pub comp: RRC<Cell>,
pub inputs: PortMap,
pub outputs: PortMap,
pub attributes: Attributes,
pub comb_group: Option<RRC<CombGroup>>,
pub ref_cells: CellMap,
}
impl GetAttributes for Invoke {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct StaticInvoke {
pub comp: RRC<Cell>,
pub latency: StaticLatency,
pub inputs: PortMap,
pub outputs: PortMap,
pub attributes: Attributes,
pub ref_cells: CellMap,
pub comb_group: Option<RRC<CombGroup>>,
}
impl GetAttributes for StaticInvoke {
fn get_attributes(&self) -> &Attributes {
&self.attributes
}
fn get_mut_attributes(&mut self) -> &mut Attributes {
&mut self.attributes
}
}
#[derive(Debug, Default)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Empty {
pub attributes: Attributes,
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub enum Control {
Seq(Seq),
Par(Par),
If(If),
While(While),
Repeat(Repeat),
Invoke(Invoke),
Enable(Enable),
Empty(Empty),
Static(StaticControl),
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub enum StaticControl {
Repeat(StaticRepeat),
Enable(StaticEnable),
Par(StaticPar),
Seq(StaticSeq),
If(StaticIf),
Empty(Empty),
Invoke(StaticInvoke),
}
impl From<Invoke> for Control {
fn from(inv: Invoke) -> Self {
Control::Invoke(inv)
}
}
impl From<Enable> for Control {
fn from(en: Enable) -> Self {
Control::Enable(en)
}
}
impl From<StaticControl> for Control {
fn from(sc: StaticControl) -> Self {
Control::Static(sc)
}
}
impl From<StaticEnable> for StaticControl {
fn from(se: StaticEnable) -> Self {
StaticControl::Enable(se)
}
}
impl From<RRC<StaticGroup>> for StaticControl {
fn from(sgroup: RRC<StaticGroup>) -> Self {
StaticControl::Enable(StaticEnable {
group: sgroup,
attributes: Attributes::default(),
})
}
}
impl<'a> From<&'a Control> for GenericControl<'a> {
fn from(c: &'a Control) -> Self {
match c {
Control::Static(sc) => GenericControl::Static(sc),
_ => GenericControl::Dynamic(c),
}
}
}
impl<'a> From<&'a StaticControl> for GenericControl<'a> {
fn from(sc: &'a StaticControl) -> Self {
GenericControl::Static(sc)
}
}
impl GetAttributes for Control {
fn get_mut_attributes(&mut self) -> &mut Attributes {
match self {
Self::Seq(Seq { attributes, .. })
| Self::Par(Par { attributes, .. })
| Self::If(If { attributes, .. })
| Self::While(While { attributes, .. })
| Self::Repeat(Repeat { attributes, .. })
| Self::Invoke(Invoke { attributes, .. })
| Self::Enable(Enable { attributes, .. })
| Self::Empty(Empty { attributes }) => attributes,
Self::Static(s) => s.get_mut_attributes(),
}
}
fn get_attributes(&self) -> &Attributes {
match self {
Self::Seq(Seq { attributes, .. })
| Self::Par(Par { attributes, .. })
| Self::If(If { attributes, .. })
| Self::While(While { attributes, .. })
| Self::Repeat(Repeat { attributes, .. })
| Self::Invoke(Invoke { attributes, .. })
| Self::Enable(Enable { attributes, .. })
| Self::Empty(Empty { attributes }) => attributes,
Self::Static(s) => s.get_attributes(),
}
}
}
impl GetAttributes for StaticControl {
fn get_mut_attributes(&mut self) -> &mut Attributes {
match self {
Self::Enable(StaticEnable { attributes, .. }) => attributes,
Self::Repeat(StaticRepeat { attributes, .. }) => attributes,
Self::Par(StaticPar { attributes, .. }) => attributes,
Self::Seq(StaticSeq { attributes, .. }) => attributes,
Self::If(StaticIf { attributes, .. }) => attributes,
Self::Empty(Empty { attributes, .. }) => attributes,
Self::Invoke(StaticInvoke { attributes, .. }) => attributes,
}
}
fn get_attributes(&self) -> &Attributes {
match self {
Self::Enable(StaticEnable { attributes, .. }) => attributes,
Self::Repeat(StaticRepeat { attributes, .. }) => attributes,
Self::Par(StaticPar { attributes, .. }) => attributes,
Self::Seq(StaticSeq { attributes, .. }) => attributes,
Self::If(StaticIf { attributes, .. }) => attributes,
Self::Empty(Empty { attributes, .. }) => attributes,
Self::Invoke(StaticInvoke { attributes, .. }) => attributes,
}
}
}
impl calyx_utils::WithPos for Control {
fn copy_span(&self) -> calyx_utils::GPosIdx {
self.get_attributes().copy_span()
}
}
impl Control {
pub fn empty() -> Self {
Control::Empty(Empty::default())
}
pub fn seq(stmts: Vec<Control>) -> Self {
Control::Seq(Seq {
stmts,
attributes: Attributes::default(),
})
}
pub fn par(stmts: Vec<Control>) -> Self {
Control::Par(Par {
stmts,
attributes: Attributes::default(),
})
}
pub fn enable(group: RRC<Group>) -> Self {
Control::Enable(Enable {
group,
attributes: Attributes::default(),
})
}
pub fn static_enable(group: RRC<StaticGroup>) -> Self {
Control::Static(StaticControl::Enable(StaticEnable {
group,
attributes: Attributes::default(),
}))
}
pub fn invoke(comp: RRC<Cell>, inputs: PortMap, outputs: PortMap) -> Self {
Control::Invoke(Invoke {
comp,
inputs,
outputs,
attributes: Attributes::default(),
comb_group: None,
ref_cells: Vec::new(),
})
}
pub fn if_(
port: RRC<Port>,
cond: Option<RRC<CombGroup>>,
tbranch: Box<Control>,
fbranch: Box<Control>,
) -> Self {
Control::If(If {
port,
cond,
tbranch,
fbranch,
attributes: Attributes::default(),
})
}
pub fn while_(
port: RRC<Port>,
cond: Option<RRC<CombGroup>>,
body: Box<Control>,
) -> Self {
Control::While(While {
port,
cond,
body,
attributes: Attributes::default(),
})
}
pub fn repeat(num_repeats: u64, body: Box<Control>) -> Self {
Control::Repeat(Repeat {
body,
num_repeats,
attributes: Attributes::default(),
})
}
pub fn get_attribute<A>(&self, attr: A) -> Option<u64>
where
A: Into<Attribute>,
{
self.get_attributes().get(attr)
}
pub fn has_attribute<A>(&self, attr: A) -> bool
where
A: Into<Attribute>,
{
self.get_attributes().has(attr)
}
pub fn is_static(&self) -> bool {
matches!(self, Control::Static(_))
}
pub fn is_empty(&self) -> bool {
matches!(self, Control::Static(StaticControl::Empty(_)))
|| matches!(self, Control::Empty(_))
}
pub fn get_latency(&self) -> Option<StaticLatency> {
match self {
Control::Static(sc) => Some(sc.get_latency()),
_ => None,
}
}
pub fn take_control(&mut self) -> Control {
let empty = Control::empty();
std::mem::replace(self, empty)
}
pub fn take_static_control(&mut self) -> StaticControl {
let empty = Control::empty();
let control = std::mem::replace(self, empty);
let Control::Static(static_control) = control else {
unreachable!("Called take_static_control on non-static control")
};
static_control
}
}
impl StaticControl {
pub fn empty() -> Self {
StaticControl::Empty(Empty::default())
}
pub fn seq(stmts: Vec<StaticControl>, latency: u64) -> Self {
StaticControl::Seq(StaticSeq {
stmts,
attributes: Attributes::default(),
latency,
})
}
pub fn par(stmts: Vec<StaticControl>, latency: u64) -> Self {
StaticControl::Par(StaticPar {
stmts,
attributes: Attributes::default(),
latency,
})
}
pub fn static_if(
port: RRC<Port>,
tbranch: Box<StaticControl>,
fbranch: Box<StaticControl>,
latency: u64,
) -> Self {
StaticControl::If(StaticIf {
port,
tbranch,
fbranch,
attributes: Attributes::default(),
latency,
})
}
pub fn repeat(
num_repeats: u64,
latency: u64,
body: Box<StaticControl>,
) -> Self {
StaticControl::Repeat(StaticRepeat {
body,
num_repeats,
latency,
attributes: Attributes::default(),
})
}
pub fn get_attribute(&self, attr: Attribute) -> Option<u64> {
self.get_attributes().get(attr)
}
pub fn get_latency(&self) -> StaticLatency {
match self {
StaticControl::Enable(StaticEnable { group, .. }) => {
group.borrow().get_latency()
}
StaticControl::Seq(StaticSeq { latency, .. })
| StaticControl::Par(StaticPar { latency, .. })
| StaticControl::Repeat(StaticRepeat { latency, .. })
| StaticControl::If(StaticIf { latency, .. })
| StaticControl::Invoke(StaticInvoke { latency, .. }) => *latency,
&StaticControl::Empty(_) => 0,
}
}
pub fn take_static_control(&mut self) -> StaticControl {
let empty = StaticControl::empty();
std::mem::replace(self, empty)
}
}
#[derive(Debug)]
pub enum GenericControl<'a> {
Static(&'a StaticControl),
Dynamic(&'a Control),
}
pub struct Cloner;
impl Cloner {
pub fn enable(en: &Enable) -> Enable {
Enable {
group: Rc::clone(&en.group),
attributes: en.attributes.clone(),
}
}
pub fn static_enable(en: &StaticEnable) -> StaticEnable {
StaticEnable {
group: Rc::clone(&en.group),
attributes: en.attributes.clone(),
}
}
pub fn invoke(inv: &Invoke) -> Invoke {
Invoke {
comp: Rc::clone(&inv.comp),
inputs: inv.inputs.clone(),
outputs: inv.outputs.clone(),
attributes: inv.attributes.clone(),
comb_group: inv.comb_group.clone(),
ref_cells: inv.ref_cells.clone(),
}
}
pub fn empty(en: &Empty) -> Empty {
Empty {
attributes: en.attributes.clone(),
}
}
pub fn while_(wh: &While) -> While {
While {
port: Rc::clone(&wh.port),
cond: wh.cond.clone(),
body: Box::new(Self::control(&wh.body)),
attributes: wh.attributes.clone(),
}
}
pub fn static_repeat(rep: &StaticRepeat) -> StaticRepeat {
StaticRepeat {
attributes: rep.attributes.clone(),
body: Box::new(Self::static_control(&rep.body)),
num_repeats: rep.num_repeats,
latency: rep.latency,
}
}
pub fn repeat(rep: &Repeat) -> Repeat {
Repeat {
attributes: rep.attributes.clone(),
body: Box::new(Self::control(&rep.body)),
num_repeats: rep.num_repeats,
}
}
pub fn if_(if_: &If) -> If {
If {
port: Rc::clone(&if_.port),
cond: if_.cond.clone(),
tbranch: Box::new(Self::control(&if_.tbranch)),
fbranch: Box::new(Self::control(&if_.fbranch)),
attributes: if_.attributes.clone(),
}
}
pub fn static_if(sif: &StaticIf) -> StaticIf {
StaticIf {
port: Rc::clone(&sif.port),
latency: sif.latency,
tbranch: Box::new(Self::static_control(&sif.tbranch)),
fbranch: Box::new(Self::static_control(&sif.fbranch)),
attributes: sif.attributes.clone(),
}
}
pub fn par(par: &Par) -> Par {
Par {
stmts: par.stmts.iter().map(Self::control).collect(),
attributes: par.attributes.clone(),
}
}
pub fn static_par(par: &StaticPar) -> StaticPar {
StaticPar {
stmts: par.stmts.iter().map(Self::static_control).collect(),
attributes: par.attributes.clone(),
latency: par.latency,
}
}
pub fn seq(seq: &Seq) -> Seq {
Seq {
stmts: seq.stmts.iter().map(Self::control).collect(),
attributes: seq.attributes.clone(),
}
}
pub fn static_seq(seq: &StaticSeq) -> StaticSeq {
StaticSeq {
stmts: seq.stmts.iter().map(Self::static_control).collect(),
attributes: seq.attributes.clone(),
latency: seq.latency,
}
}
pub fn static_invoke(i: &StaticInvoke) -> StaticInvoke {
StaticInvoke {
comp: Rc::clone(&i.comp),
latency: i.latency,
inputs: i.inputs.clone(),
outputs: i.outputs.clone(),
attributes: i.attributes.clone(),
ref_cells: i.ref_cells.clone(),
comb_group: i.comb_group.clone(),
}
}
pub fn static_control(s: &StaticControl) -> StaticControl {
match s {
StaticControl::Enable(sen) => {
StaticControl::Enable(Cloner::static_enable(sen))
}
StaticControl::Repeat(rep) => {
StaticControl::Repeat(Cloner::static_repeat(rep))
}
StaticControl::Seq(sseq) => {
StaticControl::Seq(Cloner::static_seq(sseq))
}
StaticControl::Par(spar) => {
StaticControl::Par(Cloner::static_par(spar))
}
StaticControl::If(sif) => StaticControl::If(Cloner::static_if(sif)),
StaticControl::Empty(e) => StaticControl::Empty(Self::empty(e)),
StaticControl::Invoke(si) => {
StaticControl::Invoke(Self::static_invoke(si))
}
}
}
pub fn control(con: &Control) -> Control {
match con {
Control::Seq(seq) => Control::Seq(Cloner::seq(seq)),
Control::Par(par) => Control::Par(Cloner::par(par)),
Control::If(if_) => Control::If(Cloner::if_(if_)),
Control::While(wh) => Control::While(Cloner::while_(wh)),
Control::Repeat(repeat) => Control::Repeat(Cloner::repeat(repeat)),
Control::Invoke(inv) => Control::Invoke(Cloner::invoke(inv)),
Control::Enable(en) => Control::Enable(Cloner::enable(en)),
Control::Empty(en) => Control::Empty(Cloner::empty(en)),
Control::Static(s) => Control::Static(Cloner::static_control(s)),
}
}
}