WIP adding deduce_resets pass
This commit is contained in:
parent
11ddbc43c7
commit
913baa37e9
|
@ -2641,3 +2641,50 @@ impl<T: Type> ModuleIO<T> {
|
|||
self.ty
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub enum InstantiatedModule {
|
||||
Base(Interned<Module<Bundle>>),
|
||||
Child {
|
||||
parent: Interned<InstantiatedModule>,
|
||||
instance: Interned<Instance<Bundle>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl InstantiatedModule {
|
||||
pub fn leaf_module(self) -> Interned<Module<Bundle>> {
|
||||
match self {
|
||||
InstantiatedModule::Base(base) => base,
|
||||
InstantiatedModule::Child { instance, .. } => instance.instantiated(),
|
||||
}
|
||||
}
|
||||
fn write_path(self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
InstantiatedModule::Base(base) => fmt::Debug::fmt(&base.name_id(), f),
|
||||
InstantiatedModule::Child { parent, instance } => {
|
||||
parent.write_path(f)?;
|
||||
write!(f, ".{}", instance.name_id())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for InstantiatedModule {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "InstantiatedModule(")?;
|
||||
self.write_path(f)?;
|
||||
write!(f, ": {})", self.leaf_module().name_id())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub struct TargetInInstantiatedModule {
|
||||
pub instantiated_module: InstantiatedModule,
|
||||
pub target: Target,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub struct ExprInInstantiatedModule<T: Type> {
|
||||
pub instantiated_module: InstantiatedModule,
|
||||
pub target: Expr<T>,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
pub mod deduce_resets;
|
||||
pub mod simplify_enums;
|
||||
pub mod simplify_memories;
|
||||
pub mod visit;
|
||||
|
|
191
crates/fayalite/src/module/transform/deduce_resets.rs
Normal file
191
crates/fayalite/src/module/transform/deduce_resets.rs
Normal file
|
@ -0,0 +1,191 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
use petgraph::graph::{NodeIndex, UnGraph};
|
||||
|
||||
use crate::{
|
||||
bundle::{BundleField, BundleType},
|
||||
enum_::{EnumType, EnumVariant},
|
||||
expr::target::{TargetPathArrayElement, TargetPathBundleField, TargetPathElement},
|
||||
intern::{Intern, Interned, Memoize},
|
||||
module::{
|
||||
AnnotatedModuleIO, ExprInInstantiatedModule, ExternModuleBody, InstantiatedModule,
|
||||
ModuleBody, NormalModuleBody, TargetInInstantiatedModule,
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DeduceResetsError {
|
||||
ResetIsNotDrivenByAsyncOrSync { target: TargetInInstantiatedModule },
|
||||
}
|
||||
|
||||
impl fmt::Display for DeduceResetsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
DeduceResetsError::ResetIsNotDrivenByAsyncOrSync { target } => {
|
||||
write!(f, "deduce_reset failed: Reset signal is not driven by any AsyncReset or SyncReset signals: {target:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for DeduceResetsError {}
|
||||
|
||||
impl From<DeduceResetsError> for std::io::Error {
|
||||
fn from(value: DeduceResetsError) -> Self {
|
||||
std::io::Error::new(std::io::ErrorKind::Other, value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Node {
|
||||
target: TargetInInstantiatedModule,
|
||||
deduced_type: Option<CanonicalType>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct State {
|
||||
base_module: Interned<Module<Bundle>>,
|
||||
transformed_exprs:
|
||||
HashMap<ExprInInstantiatedModule<CanonicalType>, ExprInInstantiatedModule<CanonicalType>>,
|
||||
node_ids: HashMap<TargetInInstantiatedModule, NodeIndex<u32>>,
|
||||
graph: UnGraph<Node, ()>,
|
||||
fallback_to_sync_reset: bool,
|
||||
}
|
||||
|
||||
fn type_contains_any_undeduced_resets(ty: CanonicalType) -> bool {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
struct MyMemoize;
|
||||
impl Memoize for MyMemoize {
|
||||
type Input = CanonicalType;
|
||||
type InputOwned = CanonicalType;
|
||||
type Output = bool;
|
||||
|
||||
fn inner(self, input: &Self::Input) -> Self::Output {
|
||||
match input {
|
||||
CanonicalType::UInt(_) => false,
|
||||
CanonicalType::SInt(_) => false,
|
||||
CanonicalType::Bool(_) => false,
|
||||
CanonicalType::Array(ty) => type_contains_any_undeduced_resets(ty.element()),
|
||||
CanonicalType::Enum(ty) => {
|
||||
ty.variants().iter().any(|EnumVariant { ty, .. }| {
|
||||
ty.is_some_and(|ty| type_contains_any_undeduced_resets(ty))
|
||||
})
|
||||
}
|
||||
CanonicalType::Bundle(ty) => ty
|
||||
.fields()
|
||||
.iter()
|
||||
.any(|&BundleField { ty, .. }| type_contains_any_undeduced_resets(ty)),
|
||||
CanonicalType::AsyncReset(_) => false,
|
||||
CanonicalType::SyncReset(_) => false,
|
||||
CanonicalType::Reset(_) => true,
|
||||
CanonicalType::Clock(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
MyMemoize.get_owned(ty)
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn add_target_to_graph_recursive(
|
||||
&mut self,
|
||||
target: TargetInInstantiatedModule,
|
||||
) -> NodeIndex<u32> {
|
||||
let entry = match self.node_ids.entry(target) {
|
||||
Entry::Vacant(entry) => entry,
|
||||
Entry::Occupied(entry) => {
|
||||
return *entry.get();
|
||||
}
|
||||
};
|
||||
let ty = target.target.canonical_ty();
|
||||
let node_id = self.graph.add_node(Node {
|
||||
target,
|
||||
deduced_type: type_contains_any_undeduced_resets(ty).then_some(ty),
|
||||
});
|
||||
entry.insert(node_id);
|
||||
match target.target.canonical_ty() {
|
||||
CanonicalType::UInt(_)
|
||||
| CanonicalType::SInt(_)
|
||||
| CanonicalType::Bool(_)
|
||||
| CanonicalType::AsyncReset(_)
|
||||
| CanonicalType::SyncReset(_)
|
||||
| CanonicalType::Clock(_) => {}
|
||||
CanonicalType::Array(ty) => {
|
||||
for index in 0..ty.len() {
|
||||
self.add_target_to_graph_recursive(TargetInInstantiatedModule {
|
||||
instantiated_module: target.instantiated_module,
|
||||
target: target.target.join(
|
||||
TargetPathElement::from(TargetPathArrayElement { index })
|
||||
.intern_sized(),
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
CanonicalType::Enum(_) => {}
|
||||
CanonicalType::Bundle(ty) => {
|
||||
for BundleField { name, .. } in ty.fields() {
|
||||
self.add_target_to_graph_recursive(TargetInInstantiatedModule {
|
||||
instantiated_module: target.instantiated_module,
|
||||
target: target.target.join(
|
||||
TargetPathElement::from(TargetPathBundleField { name }).intern_sized(),
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
CanonicalType::Reset(_) => {}
|
||||
}
|
||||
node_id
|
||||
}
|
||||
fn build_graph_for_module(&mut self, instantiated_module: Interned<InstantiatedModule>) {
|
||||
let Module {
|
||||
name: _,
|
||||
source_location: _,
|
||||
body,
|
||||
io_ty: _,
|
||||
module_io,
|
||||
module_annotations: _,
|
||||
} = *instantiated_module.leaf_module();
|
||||
for AnnotatedModuleIO {
|
||||
annotations: _,
|
||||
module_io,
|
||||
} in module_io
|
||||
{
|
||||
self.add_target_to_graph_recursive(TargetInInstantiatedModule {
|
||||
instantiated_module: *instantiated_module,
|
||||
target: module_io.into(),
|
||||
});
|
||||
}
|
||||
match body {
|
||||
ModuleBody::Normal(NormalModuleBody { body }) => todo!(),
|
||||
ModuleBody::Extern(ExternModuleBody {
|
||||
verilog_name: _,
|
||||
parameters: _,
|
||||
}) => {}
|
||||
}
|
||||
}
|
||||
fn deduce_types(&mut self) -> Result<(), DeduceResetsError> {
|
||||
todo!()
|
||||
}
|
||||
fn transform_module(&mut self, module: Interned<Module<Bundle>>) -> Interned<Module<Bundle>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deduce_resets(
|
||||
module: Interned<Module<Bundle>>,
|
||||
fallback_to_sync_reset: bool,
|
||||
) -> Result<Interned<Module<Bundle>>, DeduceResetsError> {
|
||||
let mut state = State {
|
||||
base_module: module,
|
||||
transformed_exprs: HashMap::new(),
|
||||
node_ids: HashMap::new(),
|
||||
graph: UnGraph::new_undirected(),
|
||||
fallback_to_sync_reset,
|
||||
};
|
||||
state.build_graph_for_module(InstantiatedModule::Base(module).intern_sized());
|
||||
state.deduce_types()?;
|
||||
Ok(state.transform_module(module))
|
||||
}
|
|
@ -16,9 +16,9 @@ use crate::{
|
|||
int::BoolOrIntType,
|
||||
intern::{Intern, Interned, Memoize},
|
||||
module::{
|
||||
AnnotatedModuleIO, Block, Id, ModuleBody, NameId, NormalModuleBody, ScopedNameId, Stmt,
|
||||
StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg,
|
||||
StmtWire,
|
||||
AnnotatedModuleIO, Block, Id, InstantiatedModule, ModuleBody, NameId, NormalModuleBody,
|
||||
ScopedNameId, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance,
|
||||
StmtMatch, StmtReg, StmtWire, TargetInInstantiatedModule,
|
||||
},
|
||||
prelude::*,
|
||||
sim::{
|
||||
|
@ -68,47 +68,6 @@ struct Cond {
|
|||
source_location: SourceLocation,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||
enum InstantiatedModule {
|
||||
Base(Interned<Module<Bundle>>),
|
||||
Child {
|
||||
parent: Interned<InstantiatedModule>,
|
||||
instance: Interned<Instance<Bundle>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl InstantiatedModule {
|
||||
fn leaf_module(self) -> Interned<Module<Bundle>> {
|
||||
match self {
|
||||
InstantiatedModule::Base(base) => base,
|
||||
InstantiatedModule::Child { instance, .. } => instance.instantiated(),
|
||||
}
|
||||
}
|
||||
fn write_path(self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
InstantiatedModule::Base(base) => fmt::Debug::fmt(&base.name_id(), f),
|
||||
InstantiatedModule::Child { parent, instance } => {
|
||||
parent.write_path(f)?;
|
||||
write!(f, ".{}", instance.name_id())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for InstantiatedModule {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "InstantiatedModule(")?;
|
||||
self.write_path(f)?;
|
||||
write!(f, ": {})", self.leaf_module().name_id())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
struct TargetInInstantiatedModule {
|
||||
instantiated_module: InstantiatedModule,
|
||||
target: Target,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
struct CompiledBundleField {
|
||||
offset: TypeIndex,
|
||||
|
|
Loading…
Reference in a new issue