Skip to content

Commit

Permalink
Started function and implemented printer for fsm
Browse files Browse the repository at this point in the history
- started indexing states from 1 (because of transition from 0 -> 1)
- need to enable fsms and register transitions within fsm
- need to replace control node with fsm in each  function
  • Loading branch information
parthsarkar17 committed Nov 4, 2024
1 parent a92d45b commit 9bd2b6e
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 29 deletions.
2 changes: 1 addition & 1 deletion calyx-ir/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<'a> Builder<'a> {
let fsm = ir::rrc(ir::FSM::new(name));

// Fill in the ports of the FSM with default wires
for (name, width) in &[("go", 1), ("done", 1)] {
for (name, width) in &[("go", 1), ("done", 1), ("state", 1)] {
let hole = ir::rrc(ir::Port {
name: ir::Id::from(*name),
width: *width,
Expand Down
5 changes: 5 additions & 0 deletions calyx-ir/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ impl Component {
&self.groups
}

/// get the component's fsms
pub fn get_fsms(&self) -> &IdList<FSM> {
&self.fsms
}

/// gets the component's static groups
pub fn get_static_groups(&self) -> &IdList<StaticGroup> {
&self.static_groups
Expand Down
56 changes: 56 additions & 0 deletions calyx-ir/src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ impl Printer {
Self::write_static_group(&group.borrow(), 4, f)?;
writeln!(f)?;
}
for fsm in comp.get_fsms().iter() {}

Check failure on line 242 in calyx-ir/src/printer.rs

View workflow job for this annotation

GitHub Actions / Validate playground config

unused variable: `fsm`
for comb_group in comp.comb_groups.iter() {
Self::write_comb_group(&comb_group.borrow(), 4, f)?;
writeln!(f)?;
Expand Down Expand Up @@ -426,6 +427,61 @@ impl Printer {
write!(f, "{}}}", " ".repeat(indent_level))
}

/// Formt and write an FSM
pub fn write_fsm<F: io::Write>(
fsm: &ir::FSM,
indent_level: usize,
f: &mut F,
) -> io::Result<()> {
write!(f, "{}", " ".repeat(indent_level))?;
write!(f, "fsm {}", fsm.name().id)?;
if !fsm.attributes.is_empty() {
write!(f, "{}", Self::format_attributes(&fsm.attributes))?;
}
writeln!(f, " {{")?;
for (i, (assigns, trans)) in
fsm.assignments.iter().zip(&fsm.transitions).enumerate()
{
// WRITE ASSIGNMENTS
write!(f, "{}", " ".repeat(indent_level + 2))?;
write!(f, "{} : ", i + 1)?;
match assigns.is_empty() {
true => {
// skip directly to transitions section
write!(f, "{{")?;
write!(f, "}} ")?;
write!(f, "=> ")?;
}
false => {
writeln!(f, "{{")?;
for assign in assigns {
Self::write_assignment(assign, indent_level + 4, f)?;
writeln!(f)?;
}
write!(f, "{}", " ".repeat(indent_level + 2))?;
write!(f, "}} => ")?;
}
}

// WRITE TRANSITIONS
match trans {
ir::Transition::Unconditional(s) => {
writeln!(f, "{},", s)?;
}
ir::Transition::Conditional(cond_dsts) => {
writeln!(f, "{{")?;
for (g, dst) in cond_dsts.iter() {
write!(f, "{}", " ".repeat(indent_level + 4))?;
writeln!(f, "{} ? {} :", Self::guard_str(g), dst)?;
}
write!(f, "{}", " ".repeat(indent_level + 2))?;
writeln!(f, "}},")?;
}
}
}
write!(f, "{}}}", " ".repeat(indent_level))
}

/// Format and write a static group.
pub fn write_static_group<F: io::Write>(
group: &ir::StaticGroup,
Expand Down
29 changes: 6 additions & 23 deletions calyx-ir/src/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,34 +601,14 @@ pub enum State {
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub enum Transition {
Unconditional(State),
Conditional(Vec<(Guard<Nothing>, State)>),
Unconditional(u64),
Conditional(Vec<(Guard<Nothing>, u64)>),
}

impl Transition {
pub fn new_uncond(s: State) -> Self {
pub fn new_uncond(s: u64) -> Self {
Self::Unconditional(s)
}

pub fn new_cond(conds: Vec<(Guard<Nothing>, State)>) -> Self {
Self::Conditional(conds)
}
}

#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Branch {
/// Originating state of the FSM transition
src: State,

/// Optionally conditional destination states of the transition
dsts: Transition,
}

impl Branch {
pub fn new(src: State, dsts: Transition) -> Self {
Branch { src, dsts }
}
}

/// A Group of assignments that perform a logical action.
Expand Down Expand Up @@ -833,6 +813,8 @@ impl CombGroup {
pub struct FSM {
/// Name of this construct
pub(super) name: Id,
/// Number of states in this FSM
pub num_states: u64,
/// Attributes for this FSM
pub attributes: Attributes,
/// State indexes into assignments that are supposed to be enabled at that state
Expand All @@ -853,6 +835,7 @@ impl FSM {
pub fn new(name: Id) -> Self {
Self {
name,
num_states: 0,
assignments: vec![],
transitions: vec![],
wires: SmallVec::new(),
Expand Down
41 changes: 36 additions & 5 deletions calyx-opt/src/passes/dyn_fsm_allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,38 @@ impl<'b, 'a> Schedule<'b, 'a> {
}

fn realize_fsm(self, dump_fsm: bool) -> RRC<ir::FSM> {
ir::rrc(ir::FSM::new(Id::new("fsm")))
// STATES ARE NOW INDEXED FROM 1
// ensure schedule is valid
self.validate();

// compute final state and fsm_size, and register initial fsm
let last_state = self.last_state();
let fsm_size = get_bit_width_from(last_state + 1);
let fsm = self.builder.add_fsm("fsm");

// register group enables that are dependent on fsm state as continuous assignments
let continuous_enables = self
.enables
.into_iter()
.sorted_by(|(k1, _), (k2, _)| k1.cmp(k2))
.flat_map(|(state, mut assigns_to_enable)| {
let state_const = self.builder.add_constant(state, fsm_size);
let state_guard = guard!(fsm["state"] == state_const["out"]);
assigns_to_enable.iter_mut().for_each(|assign| {
assign.guard.update(|g| g.and(state_guard.clone()))
});
assigns_to_enable
})
.collect_vec();

self.builder
.component
.continuous_assignments
.extend(continuous_enables);

// add

fsm
}
}

Expand Down Expand Up @@ -669,7 +700,7 @@ impl Schedule<'_, '_> {
seq: &ir::Seq,
early_transitions: bool,
) -> CalyxResult<()> {
let first_state = (0, ir::Guard::True);
let first_state = (1, ir::Guard::True);
// We create an empty first state in case the control program starts with
// a branch (if, while).
// If the program doesn't branch, then the initial state is merged into
Expand All @@ -686,7 +717,7 @@ impl Schedule<'_, '_> {
if_stmt: &ir::If,
early_transitions: bool,
) -> CalyxResult<()> {
let first_state = (0, ir::Guard::True);
let first_state = (1, ir::Guard::True);
// We create an empty first state in case the control program starts with
// a branch (if, while).
// If the program doesn't branch, then the initial state is merged into
Expand All @@ -703,7 +734,7 @@ impl Schedule<'_, '_> {
while_stmt: &ir::While,
early_transitions: bool,
) -> CalyxResult<()> {
let first_state = (0, ir::Guard::True);
let first_state = (1, ir::Guard::True);
// We create an empty first state in case the control program starts with
// a branch (if, while).
// If the program doesn't branch, then the initial state is merged into
Expand Down Expand Up @@ -743,7 +774,7 @@ impl Schedule<'_, '_> {
con: &ir::Control,
early_transitions: bool,
) -> CalyxResult<()> {
let first_state = (0, ir::Guard::True);
let first_state = (1, ir::Guard::True);
// We create an empty first state in case the control program starts with
// a branch (if, while).
// If the program doesn't branch, then the initial state is merged into
Expand Down

0 comments on commit 9bd2b6e

Please sign in to comment.