diff --git a/crates/fayalite/src/expr.rs b/crates/fayalite/src/expr.rs index 5ba6dbf..644d058 100644 --- a/crates/fayalite/src/expr.rs +++ b/crates/fayalite/src/expr.rs @@ -641,6 +641,18 @@ impl GetTarget for MemPort { } } +pub trait HdlPartialEq { + fn cmp_eq(self, rhs: Rhs) -> Expr; + fn cmp_ne(self, rhs: Rhs) -> Expr; +} + +pub trait HdlPartialOrd: HdlPartialEq { + fn cmp_lt(self, rhs: Rhs) -> Expr; + fn cmp_le(self, rhs: Rhs) -> Expr; + fn cmp_gt(self, rhs: Rhs) -> Expr; + fn cmp_ge(self, rhs: Rhs) -> Expr; +} + pub trait ReduceBits { type UIntOutput; type BoolOutput; diff --git a/crates/fayalite/src/expr/ops.rs b/crates/fayalite/src/expr/ops.rs index 144a56f..6069f20 100644 --- a/crates/fayalite/src/expr/ops.rs +++ b/crates/fayalite/src/expr/ops.rs @@ -11,11 +11,12 @@ use crate::{ GetTarget, Target, TargetPathArrayElement, TargetPathBundleField, TargetPathDynArrayElement, TargetPathElement, }, - CastTo, Expr, ExprEnum, Flow, NotALiteralExpr, ReduceBits, ToExpr, ToLiteralBits, + CastTo, Expr, ExprEnum, Flow, HdlPartialEq, HdlPartialOrd, NotALiteralExpr, ReduceBits, + ToExpr, ToLiteralBits, }, int::{ - Bool, BoolOrIntType, DynSize, IntCmp, IntType, KnownSize, SInt, SIntType, SIntValue, Size, - UInt, UIntType, UIntValue, + Bool, BoolOrIntType, DynSize, IntType, KnownSize, SInt, SIntType, SIntValue, Size, UInt, + UIntType, UIntValue, }, intern::{Intern, Interned}, reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset}, @@ -1422,36 +1423,45 @@ forward_value_to_expr_binary_op_trait! { Shr::shr } -pub trait IntCmpExpr: Type { +pub trait ExprPartialEq: Type { fn cmp_eq(lhs: Expr, rhs: Expr) -> Expr; fn cmp_ne(lhs: Expr, rhs: Expr) -> Expr; +} + +pub trait ExprPartialOrd: ExprPartialEq { fn cmp_lt(lhs: Expr, rhs: Expr) -> Expr; fn cmp_le(lhs: Expr, rhs: Expr) -> Expr; fn cmp_gt(lhs: Expr, rhs: Expr) -> Expr; fn cmp_ge(lhs: Expr, rhs: Expr) -> Expr; } -impl IntCmp for Lhs +impl HdlPartialEq for Lhs where - Lhs::Type: IntCmpExpr, + Lhs::Type: ExprPartialEq, { fn cmp_eq(self, rhs: Rhs) -> Expr { - IntCmpExpr::cmp_eq(self.to_expr(), rhs.to_expr()) + ExprPartialEq::cmp_eq(self.to_expr(), rhs.to_expr()) } fn cmp_ne(self, rhs: Rhs) -> Expr { - IntCmpExpr::cmp_ne(self.to_expr(), rhs.to_expr()) + ExprPartialEq::cmp_ne(self.to_expr(), rhs.to_expr()) } +} + +impl HdlPartialOrd for Lhs +where + Lhs::Type: ExprPartialOrd, +{ fn cmp_lt(self, rhs: Rhs) -> Expr { - IntCmpExpr::cmp_lt(self.to_expr(), rhs.to_expr()) + ExprPartialOrd::cmp_lt(self.to_expr(), rhs.to_expr()) } fn cmp_le(self, rhs: Rhs) -> Expr { - IntCmpExpr::cmp_le(self.to_expr(), rhs.to_expr()) + ExprPartialOrd::cmp_le(self.to_expr(), rhs.to_expr()) } fn cmp_gt(self, rhs: Rhs) -> Expr { - IntCmpExpr::cmp_gt(self.to_expr(), rhs.to_expr()) + ExprPartialOrd::cmp_gt(self.to_expr(), rhs.to_expr()) } fn cmp_ge(self, rhs: Rhs) -> Expr { - IntCmpExpr::cmp_ge(self.to_expr(), rhs.to_expr()) + ExprPartialOrd::cmp_ge(self.to_expr(), rhs.to_expr()) } } @@ -1461,6 +1471,7 @@ macro_rules! impl_compare_op { #[dyn_type($DynTy:ident)] #[to_dyn_type($lhs:ident => $dyn_lhs:expr, $rhs:ident => $dyn_rhs:expr)] #[type($Lhs:ty, $Rhs:ty)] + #[trait($Trait:ident)] $( struct $name:ident; fn $method:ident(); @@ -1512,7 +1523,7 @@ macro_rules! impl_compare_op { } })* - impl$(<$LhsWidth: Size, $RhsWidth: Size>)? IntCmpExpr<$Rhs> for $Lhs { + impl$(<$LhsWidth: Size, $RhsWidth: Size>)? $Trait<$Rhs> for $Lhs { $(fn $method($lhs: Expr, $rhs: Expr<$Rhs>) -> Expr { $name::new($dyn_lhs, $dyn_rhs).to_expr() })* @@ -1524,8 +1535,16 @@ impl_compare_op! { #[dyn_type(Bool)] #[to_dyn_type(lhs => lhs, rhs => rhs)] #[type(Bool, Bool)] + #[trait(ExprPartialEq)] struct CmpEqB; fn cmp_eq(); PartialEq::eq(); struct CmpNeB; fn cmp_ne(); PartialEq::ne(); +} + +impl_compare_op! { + #[dyn_type(Bool)] + #[to_dyn_type(lhs => lhs, rhs => rhs)] + #[type(Bool, Bool)] + #[trait(ExprPartialOrd)] struct CmpLtB; fn cmp_lt(); PartialOrd::lt(); struct CmpLeB; fn cmp_le(); PartialOrd::le(); struct CmpGtB; fn cmp_gt(); PartialOrd::gt(); @@ -1537,8 +1556,17 @@ impl_compare_op! { #[dyn_type(UInt)] #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] #[type(UIntType, UIntType)] + #[trait(ExprPartialEq)] struct CmpEqU; fn cmp_eq(); PartialEq::eq(); struct CmpNeU; fn cmp_ne(); PartialEq::ne(); +} + +impl_compare_op! { + #[width(LhsWidth, RhsWidth)] + #[dyn_type(UInt)] + #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] + #[type(UIntType, UIntType)] + #[trait(ExprPartialOrd)] struct CmpLtU; fn cmp_lt(); PartialOrd::lt(); struct CmpLeU; fn cmp_le(); PartialOrd::le(); struct CmpGtU; fn cmp_gt(); PartialOrd::gt(); @@ -1550,8 +1578,17 @@ impl_compare_op! { #[dyn_type(SInt)] #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] #[type(SIntType, SIntType)] + #[trait(ExprPartialEq)] struct CmpEqS; fn cmp_eq(); PartialEq::eq(); struct CmpNeS; fn cmp_ne(); PartialEq::ne(); +} + +impl_compare_op! { + #[width(LhsWidth, RhsWidth)] + #[dyn_type(SInt)] + #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] + #[type(SIntType, SIntType)] + #[trait(ExprPartialOrd)] struct CmpLtS; fn cmp_lt(); PartialOrd::lt(); struct CmpLeS; fn cmp_le(); PartialOrd::le(); struct CmpGtS; fn cmp_gt(); PartialOrd::gt(); diff --git a/crates/fayalite/src/int.rs b/crates/fayalite/src/int.rs index b48f617..e0d258a 100644 --- a/crates/fayalite/src/int.rs +++ b/crates/fayalite/src/int.rs @@ -679,15 +679,6 @@ impl StaticType for Bool { const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES; } -pub trait IntCmp { - fn cmp_eq(self, rhs: Rhs) -> Expr; - fn cmp_ne(self, rhs: Rhs) -> Expr; - fn cmp_lt(self, rhs: Rhs) -> Expr; - fn cmp_le(self, rhs: Rhs) -> Expr; - fn cmp_gt(self, rhs: Rhs) -> Expr; - fn cmp_ge(self, rhs: Rhs) -> Expr; -} - impl ToLiteralBits for bool { fn to_literal_bits(&self) -> Result, NotALiteralExpr> { Ok(interned_bit(*self)) diff --git a/crates/fayalite/src/module/transform/simplify_enums.rs b/crates/fayalite/src/module/transform/simplify_enums.rs index d6a9c02..9e1e552 100644 --- a/crates/fayalite/src/module/transform/simplify_enums.rs +++ b/crates/fayalite/src/module/transform/simplify_enums.rs @@ -6,10 +6,10 @@ use crate::{ enum_::{Enum, EnumType, EnumVariant}, expr::{ ops::{self, EnumLiteral}, - CastBitsTo, CastToBits, Expr, ExprEnum, ToExpr, + CastBitsTo, CastToBits, Expr, ExprEnum, HdlPartialEq, ToExpr, }, hdl, - int::{DynSize, IntCmp, Size, UInt, UIntType}, + int::{DynSize, Size, UInt, UIntType}, intern::{Intern, Interned}, memory::{DynPortType, Mem, MemPort}, module::{ diff --git a/crates/fayalite/src/prelude.rs b/crates/fayalite/src/prelude.rs index b376093..5dc503e 100644 --- a/crates/fayalite/src/prelude.rs +++ b/crates/fayalite/src/prelude.rs @@ -6,9 +6,12 @@ pub use crate::{ cli::Cli, clock::{Clock, ClockDomain, ToClock}, enum_::{HdlNone, HdlOption, HdlSome}, - expr::{CastBitsTo, CastTo, CastToBits, Expr, MakeUninitExpr, ReduceBits, ToExpr}, + expr::{ + CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr, + ReduceBits, ToExpr, + }, hdl, hdl_module, - int::{Bool, DynSize, IntCmp, KnownSize, SInt, SIntType, Size, UInt, UIntType}, + int::{Bool, DynSize, KnownSize, SInt, SIntType, Size, UInt, UIntType}, memory::{Mem, MemBuilder, ReadUnderWrite}, module::{ annotate, connect, connect_any, incomplete_wire, instance, memory, memory_array,