-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add attributes for components and implement
counter_fsm
attribute (#…
…453) * add attributes to frontend * add invalid test * add attributes to IR * move fsm type decision to a pass * add pass to main pass set * add better error message * fix syntax for multiple attributes * disable fsm attrs for externals * restructure attributes to work with * transfer attribute changes * remove unused attributes and replace with dummy * re-add doc comments * small doc prettying
- Loading branch information
1 parent
bb771f1
commit c5e18c3
Showing
23 changed files
with
320 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use enum_map::{Enum, EnumMap}; | ||
use fil_utils::GPosIdx; | ||
use strum_macros::EnumString; | ||
|
||
/// An attribute that accepts a numeric value | ||
#[derive(Enum, Clone, Copy, PartialEq, EnumString)] | ||
pub enum NumAttr {} | ||
|
||
/// An flag attribute | ||
#[derive(Enum, Clone, Copy, PartialEq, EnumString)] | ||
pub enum BoolAttr { | ||
/// Use a counter based FSM design | ||
#[strum(serialize = "counter_fsm")] | ||
CounterFSM, | ||
/// Dummy attribute because the [Enum] trait derivation throws errors if there is only one varianat | ||
#[strum(disabled)] | ||
Dummy, | ||
} | ||
|
||
/// Represents a single attribute. This is a private enum that is used during | ||
/// parsing to collect all attributes before creating the [Attributes] struct. | ||
#[derive(Enum, Clone, Copy)] | ||
pub enum Attr { | ||
Bool(BoolAttr), | ||
Num(NumAttr), | ||
} | ||
|
||
impl From<BoolAttr> for Attr { | ||
fn from(attr: BoolAttr) -> Self { | ||
Attr::Bool(attr) | ||
} | ||
} | ||
|
||
impl From<NumAttr> for Attr { | ||
fn from(attr: NumAttr) -> Self { | ||
Attr::Num(attr) | ||
} | ||
} | ||
|
||
/// A set of attributes attached to a component | ||
#[derive(Default, Clone)] | ||
pub struct Attributes { | ||
attrs: EnumMap<Attr, Option<(u64, GPosIdx)>>, | ||
} | ||
|
||
impl Attributes { | ||
pub fn new(attrs: impl Iterator<Item = (Attr, GPosIdx, u64)>) -> Self { | ||
Self { | ||
attrs: attrs.map(|(attr, l, v)| (attr, Some((v, l)))).collect(), | ||
} | ||
} | ||
|
||
/// Get the value of an attribute. | ||
pub fn get(&self, attr: impl Into<Attr>) -> Option<u64> { | ||
self.attrs[attr.into()].map(|(v, _)| v) | ||
} | ||
|
||
/// Get the location of an attribute. | ||
pub fn get_loc(&self, attr: impl Into<Attr>) -> Option<GPosIdx> { | ||
self.attrs[attr.into()].map(|(_, l)| l) | ||
} | ||
|
||
/// Set the value of an attribute | ||
pub fn set(&mut self, attr: impl Into<Attr>, value: u64) { | ||
self.attrs[attr.into()] = Some((value, GPosIdx::UNKNOWN)); | ||
} | ||
|
||
/// Remove an attribute | ||
pub fn remove(&mut self, attr: impl Into<Attr>) { | ||
self.attrs[attr.into()] = None; | ||
} | ||
|
||
/// Check if the attribute set is empty | ||
pub fn is_empty(&self) -> bool { | ||
self.attrs.iter().all(|(_, v)| v.is_none()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use crate::ir_visitor::{Visitor, VisitorData}; | ||
use fil_ast as ast; | ||
use fil_ir::TimeSub; | ||
|
||
/// Sets the proper FSM Attributes for every component | ||
#[derive(Default)] | ||
pub struct FSMAttributes; | ||
|
||
impl Visitor for FSMAttributes { | ||
fn name() -> &'static str { | ||
"fsm-attributes" | ||
} | ||
|
||
fn visit(&mut self, mut data: VisitorData) { | ||
let attrs = &data.comp.attrs; | ||
|
||
// Check if the component already has FSM attributes | ||
if attrs.get(ast::BoolAttr::CounterFSM).is_some() { | ||
return; | ||
} | ||
|
||
// If the component is external or generated, do not add any slow FSM attributes | ||
if data.comp.is_ext() || data.comp.is_gen() { | ||
return; | ||
} | ||
|
||
// Get the delay of the component if it is a single event component | ||
if !data.opts.no_counter_fsms && data.comp.events().len() == 1 { | ||
let delay = &data.comp.events().iter().next().unwrap().1.delay; | ||
let TimeSub::Unit(delay) = delay else { | ||
data.comp.internal_error( | ||
"Non-unit delays should have been compiled away.", | ||
); | ||
}; | ||
let delay = delay.concrete(&data.comp); | ||
|
||
// If the delay is > 1, add a slow FSM attribute | ||
// TODO(UnsignedByte): Find a better heuristic for slow FSMs | ||
if delay > 1 { | ||
data.comp.attrs.set(ast::BoolAttr::CounterFSM, 1); | ||
return; | ||
} | ||
} | ||
|
||
data.comp.attrs.set(ast::BoolAttr::CounterFSM, 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.