working on deduce_resets
This commit is contained in:
parent
358cdd10c8
commit
d744d85c66
|
@ -8,6 +8,7 @@ use crate::{
|
|||
bundle::{BundleField, BundleType},
|
||||
enum_::{EnumType, EnumVariant},
|
||||
expr::{
|
||||
ops,
|
||||
target::{
|
||||
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField,
|
||||
TargetPathDynArrayElement, TargetPathElement,
|
||||
|
@ -25,14 +26,8 @@ use crate::{
|
|||
reset::{ResetType, ResetTypeDispatch},
|
||||
};
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
use num_bigint::BigInt;
|
||||
use num_bigint::BigInt;
|
||||
use petgraph::unionfind::UnionFind;
|
||||
use petgraph::{
|
||||
graph::{NodeIndex, UnGraph},
|
||||
unionfind::UnionFind,
|
||||
};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
fmt,
|
||||
|
@ -921,6 +916,94 @@ fn reg_expr_run_pass<P: Pass, R: ResetType>(
|
|||
.map(|reg| match_any_reg!(reg, ExprEnum::from)))
|
||||
}
|
||||
|
||||
fn cast_bit_op<P: Pass, T: Type, A: Type>(
|
||||
expr: impl ToExpr<Type = T>,
|
||||
arg: Expr<A>,
|
||||
pass_args: PassArgs<'_, P>,
|
||||
) -> Result<PassOutput<ExprEnum, P>, DeduceResetsError> {
|
||||
struct Dispatch<'a, T: Type, A: Type> {
|
||||
expr: Expr<T>,
|
||||
arg: Expr<A>,
|
||||
_phantom: PhantomData<&'a mut ()>,
|
||||
}
|
||||
impl<'a, T: Type, A: Type> PassDispatch for Dispatch<'a, T, A> {
|
||||
type Input<P: Pass> = PassArgs<'a, P>;
|
||||
type Output<P: Pass> = Result<PassOutput<ExprEnum, P>, DeduceResetsError>;
|
||||
|
||||
fn build_reset_graph(
|
||||
self,
|
||||
mut pass_args: Self::Input<BuildResetGraph>,
|
||||
) -> Self::Output<BuildResetGraph> {
|
||||
Expr::canonical(self.arg).run_pass(pass_args.as_mut())?;
|
||||
let (expr_resets, _) = pass_args.get_or_make_resets(self.expr, None);
|
||||
let (arg_resets, _) = pass_args.get_or_make_resets(self.arg, None);
|
||||
for (expr_node_index, arg_node_index) in expr_resets
|
||||
.node_indexes
|
||||
.into_iter()
|
||||
.zip(arg_resets.node_indexes)
|
||||
{
|
||||
pass_args.state.reset_graph.union(
|
||||
expr_node_index,
|
||||
arg_node_index,
|
||||
pass_args.fallback_error_source_location,
|
||||
)?;
|
||||
}
|
||||
Ok(PassOutput(()))
|
||||
}
|
||||
|
||||
fn substitute_resets(
|
||||
self,
|
||||
mut pass_args: Self::Input<SubstituteResets>,
|
||||
) -> Self::Output<SubstituteResets> {
|
||||
let resets = pass_args
|
||||
.get_resets(self.expr)
|
||||
.expect("added resets in build_reset_graph");
|
||||
let arg = Expr::canonical(self.arg).run_pass(pass_args.as_mut())?;
|
||||
let ty = resets.substituted_type(
|
||||
&mut pass_args.state.reset_graph,
|
||||
pass_args.state.fallback_to_sync_reset,
|
||||
pass_args.fallback_error_source_location,
|
||||
)?;
|
||||
Ok(arg.map(|arg| {
|
||||
macro_rules! match_expr_ty {
|
||||
($arg:ident, $($Variant:ident),*) => {
|
||||
match ty {
|
||||
CanonicalType::Array(_)
|
||||
| CanonicalType::Enum(_)
|
||||
| CanonicalType::Bundle(_)
|
||||
| CanonicalType::Reset(_) => unreachable!(),
|
||||
$(CanonicalType::$Variant(ty) => Expr::expr_enum($arg.cast_to(ty)),)*
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! match_arg_ty {
|
||||
($($Variant:ident),*) => {
|
||||
*match Expr::ty(arg) {
|
||||
CanonicalType::Array(_)
|
||||
| CanonicalType::Enum(_)
|
||||
| CanonicalType::Bundle(_)
|
||||
| CanonicalType::Reset(_) => unreachable!(),
|
||||
$(CanonicalType::$Variant(_) => {
|
||||
let arg = Expr::<$Variant>::from_canonical(arg);
|
||||
match_expr_ty!(arg, UInt, SInt, Bool, AsyncReset, SyncReset, Clock)
|
||||
})*
|
||||
}
|
||||
};
|
||||
}
|
||||
match_arg_ty!(UInt, SInt, Bool, AsyncReset, SyncReset, Clock)
|
||||
}))
|
||||
}
|
||||
}
|
||||
P::dispatch(
|
||||
Dispatch {
|
||||
expr: expr.to_expr(),
|
||||
arg,
|
||||
_phantom: PhantomData,
|
||||
},
|
||||
pass_args,
|
||||
)
|
||||
}
|
||||
|
||||
impl<P: Pass> RunPass<P> for ExprEnum {
|
||||
fn run_pass(
|
||||
&self,
|
||||
|
@ -991,51 +1074,23 @@ impl<P: Pass> RunPass<P> for ExprEnum {
|
|||
ExprEnum::CastBoolToSInt(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastUIntToBool(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastSIntToBool(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastBoolToSyncReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastUIntToSyncReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastSIntToSyncReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastBoolToAsyncReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastUIntToAsyncReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastSIntToAsyncReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastSyncResetToBool(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastSyncResetToUInt(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastSyncResetToSInt(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastSyncResetToReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastAsyncResetToBool(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastAsyncResetToUInt(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastAsyncResetToSInt(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastAsyncResetToReset(expr) => {
|
||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||
}
|
||||
ExprEnum::CastResetToBool(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastResetToUInt(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastResetToSInt(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastBoolToSyncReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastUIntToSyncReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastSIntToSyncReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastBoolToAsyncReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastUIntToAsyncReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastSIntToAsyncReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastSyncResetToBool(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastSyncResetToUInt(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastSyncResetToSInt(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastSyncResetToReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastAsyncResetToBool(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastAsyncResetToUInt(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastAsyncResetToSInt(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastAsyncResetToReset(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastResetToBool(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastResetToUInt(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastResetToSInt(expr) => cast_bit_op(expr, expr.arg(), pass_args),
|
||||
ExprEnum::CastBoolToClock(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastUIntToClock(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
ExprEnum::CastSIntToClock(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||
|
@ -1078,6 +1133,50 @@ impl<P: Pass> RunPass<P> for Expr<CanonicalType> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<P: Pass, Width: Size> RunPass<P> for Expr<UIntType<Width>> {
|
||||
fn run_pass(
|
||||
&self,
|
||||
pass_args: PassArgs<'_, P>,
|
||||
) -> Result<PassOutput<Self, P>, DeduceResetsError> {
|
||||
Ok(Expr::canonical(*self)
|
||||
.run_pass(pass_args)?
|
||||
.map(Expr::from_canonical))
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Pass, Width: Size> RunPass<P> for Expr<SIntType<Width>> {
|
||||
fn run_pass(
|
||||
&self,
|
||||
pass_args: PassArgs<'_, P>,
|
||||
) -> Result<PassOutput<Self, P>, DeduceResetsError> {
|
||||
Ok(Expr::canonical(*self)
|
||||
.run_pass(pass_args)?
|
||||
.map(Expr::from_canonical))
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Pass> RunPass<P> for Expr<Bool> {
|
||||
fn run_pass(
|
||||
&self,
|
||||
pass_args: PassArgs<'_, P>,
|
||||
) -> Result<PassOutput<Self, P>, DeduceResetsError> {
|
||||
Ok(Expr::canonical(*self)
|
||||
.run_pass(pass_args)?
|
||||
.map(Expr::from_canonical))
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Pass> RunPass<P> for Expr<Clock> {
|
||||
fn run_pass(
|
||||
&self,
|
||||
pass_args: PassArgs<'_, P>,
|
||||
) -> Result<PassOutput<Self, P>, DeduceResetsError> {
|
||||
Ok(Expr::canonical(*self)
|
||||
.run_pass(pass_args)?
|
||||
.map(Expr::from_canonical))
|
||||
}
|
||||
}
|
||||
|
||||
impl RunPassDispatch for ModuleIO<CanonicalType> {
|
||||
fn build_reset_graph(
|
||||
&self,
|
||||
|
@ -1324,6 +1423,113 @@ macro_rules! impl_run_pass_for_enum {
|
|||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_run_pass_for_unary_op {
|
||||
($path:path) => {
|
||||
impl_run_pass_for_struct! {
|
||||
#[constructor = <$path>::new(arg)]
|
||||
impl[] RunPass for $path {
|
||||
arg(): _,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_run_pass_for_unary_op!(ops::NotU);
|
||||
impl_run_pass_for_unary_op!(ops::NotS);
|
||||
impl_run_pass_for_unary_op!(ops::NotB);
|
||||
impl_run_pass_for_unary_op!(ops::Neg);
|
||||
impl_run_pass_for_unary_op!(ops::CastBoolToUInt);
|
||||
impl_run_pass_for_unary_op!(ops::CastBoolToSInt);
|
||||
impl_run_pass_for_unary_op!(ops::CastUIntToBool);
|
||||
impl_run_pass_for_unary_op!(ops::CastSIntToBool);
|
||||
impl_run_pass_for_unary_op!(ops::CastBoolToClock);
|
||||
impl_run_pass_for_unary_op!(ops::CastUIntToClock);
|
||||
impl_run_pass_for_unary_op!(ops::CastSIntToClock);
|
||||
impl_run_pass_for_unary_op!(ops::CastClockToBool);
|
||||
impl_run_pass_for_unary_op!(ops::CastClockToUInt);
|
||||
impl_run_pass_for_unary_op!(ops::CastClockToSInt);
|
||||
impl_run_pass_for_unary_op!(ops::ReduceBitAndU);
|
||||
impl_run_pass_for_unary_op!(ops::ReduceBitAndS);
|
||||
impl_run_pass_for_unary_op!(ops::ReduceBitOrU);
|
||||
impl_run_pass_for_unary_op!(ops::ReduceBitOrS);
|
||||
impl_run_pass_for_unary_op!(ops::ReduceBitXorU);
|
||||
impl_run_pass_for_unary_op!(ops::ReduceBitXorS);
|
||||
|
||||
macro_rules! impl_run_pass_for_binary_op {
|
||||
($path:path) => {
|
||||
impl_run_pass_for_struct! {
|
||||
#[constructor = <$path>::new(lhs, rhs)]
|
||||
impl[] RunPass for $path {
|
||||
lhs(): _,
|
||||
rhs(): _,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_run_pass_for_binary_op!(ops::BitAndU);
|
||||
impl_run_pass_for_binary_op!(ops::BitAndS);
|
||||
impl_run_pass_for_binary_op!(ops::BitAndB);
|
||||
impl_run_pass_for_binary_op!(ops::BitOrU);
|
||||
impl_run_pass_for_binary_op!(ops::BitOrS);
|
||||
impl_run_pass_for_binary_op!(ops::BitOrB);
|
||||
impl_run_pass_for_binary_op!(ops::BitXorU);
|
||||
impl_run_pass_for_binary_op!(ops::BitXorS);
|
||||
impl_run_pass_for_binary_op!(ops::BitXorB);
|
||||
impl_run_pass_for_binary_op!(ops::AddU);
|
||||
impl_run_pass_for_binary_op!(ops::AddS);
|
||||
impl_run_pass_for_binary_op!(ops::SubU);
|
||||
impl_run_pass_for_binary_op!(ops::SubS);
|
||||
impl_run_pass_for_binary_op!(ops::MulU);
|
||||
impl_run_pass_for_binary_op!(ops::MulS);
|
||||
impl_run_pass_for_binary_op!(ops::DivU);
|
||||
impl_run_pass_for_binary_op!(ops::DivS);
|
||||
impl_run_pass_for_binary_op!(ops::RemU);
|
||||
impl_run_pass_for_binary_op!(ops::RemS);
|
||||
impl_run_pass_for_binary_op!(ops::DynShlU);
|
||||
impl_run_pass_for_binary_op!(ops::DynShlS);
|
||||
impl_run_pass_for_binary_op!(ops::DynShrU);
|
||||
impl_run_pass_for_binary_op!(ops::DynShrS);
|
||||
impl_run_pass_for_binary_op!(ops::FixedShlU);
|
||||
impl_run_pass_for_binary_op!(ops::FixedShlS);
|
||||
impl_run_pass_for_binary_op!(ops::FixedShrU);
|
||||
impl_run_pass_for_binary_op!(ops::FixedShrS);
|
||||
impl_run_pass_for_binary_op!(ops::CmpLtB);
|
||||
impl_run_pass_for_binary_op!(ops::CmpLeB);
|
||||
impl_run_pass_for_binary_op!(ops::CmpGtB);
|
||||
impl_run_pass_for_binary_op!(ops::CmpGeB);
|
||||
impl_run_pass_for_binary_op!(ops::CmpEqB);
|
||||
impl_run_pass_for_binary_op!(ops::CmpNeB);
|
||||
impl_run_pass_for_binary_op!(ops::CmpLtU);
|
||||
impl_run_pass_for_binary_op!(ops::CmpLeU);
|
||||
impl_run_pass_for_binary_op!(ops::CmpGtU);
|
||||
impl_run_pass_for_binary_op!(ops::CmpGeU);
|
||||
impl_run_pass_for_binary_op!(ops::CmpEqU);
|
||||
impl_run_pass_for_binary_op!(ops::CmpNeU);
|
||||
impl_run_pass_for_binary_op!(ops::CmpLtS);
|
||||
impl_run_pass_for_binary_op!(ops::CmpLeS);
|
||||
impl_run_pass_for_binary_op!(ops::CmpGtS);
|
||||
impl_run_pass_for_binary_op!(ops::CmpGeS);
|
||||
impl_run_pass_for_binary_op!(ops::CmpEqS);
|
||||
impl_run_pass_for_binary_op!(ops::CmpNeS);
|
||||
|
||||
macro_rules! impl_run_pass_for_int_cast_op {
|
||||
($path:path) => {
|
||||
impl_run_pass_for_struct! {
|
||||
#[constructor = <$path>::new(arg, ty)]
|
||||
impl[] RunPass for $path {
|
||||
arg(): _,
|
||||
ty(): _,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_run_pass_for_int_cast_op!(ops::CastUIntToUInt);
|
||||
impl_run_pass_for_int_cast_op!(ops::CastUIntToSInt);
|
||||
impl_run_pass_for_int_cast_op!(ops::CastSIntToUInt);
|
||||
impl_run_pass_for_int_cast_op!(ops::CastSIntToSInt);
|
||||
|
||||
impl_run_pass_for_struct! {
|
||||
impl[] RunPass for Block {
|
||||
memories: _,
|
||||
|
|
Loading…
Reference in a new issue