add #[hdl(cmp_eq)] to implement HdlPartialEq automatically
This commit is contained in:
parent
43797db36e
commit
3458c21f44
|
@ -83,6 +83,7 @@ impl ParsedBundle {
|
|||
custom_bounds,
|
||||
no_static: _,
|
||||
no_runtime_generics: _,
|
||||
cmp_eq: _,
|
||||
} = options.body;
|
||||
let mut fields = match fields {
|
||||
syn::Fields::Named(fields) => fields,
|
||||
|
@ -437,6 +438,7 @@ impl ToTokens for ParsedBundle {
|
|||
custom_bounds: _,
|
||||
no_static,
|
||||
no_runtime_generics,
|
||||
cmp_eq,
|
||||
} = &options.body;
|
||||
let target = get_target(target, ident);
|
||||
let mut item_attrs = attrs.clone();
|
||||
|
@ -765,6 +767,69 @@ impl ToTokens for ParsedBundle {
|
|||
}
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
if let Some((cmp_eq,)) = cmp_eq {
|
||||
let mut where_clause =
|
||||
Generics::from(generics)
|
||||
.where_clause
|
||||
.unwrap_or_else(|| syn::WhereClause {
|
||||
where_token: Token,
|
||||
predicates: Punctuated::new(),
|
||||
});
|
||||
let mut fields_cmp_eq = vec![];
|
||||
let mut fields_cmp_ne = vec![];
|
||||
for field in fields.named() {
|
||||
let field_ident = field.ident();
|
||||
let field_ty = field.ty();
|
||||
where_clause
|
||||
.predicates
|
||||
.push(parse_quote_spanned! {cmp_eq.span=>
|
||||
#field_ty: ::fayalite::expr::ops::ExprPartialEq<#field_ty>
|
||||
});
|
||||
fields_cmp_eq.push(quote_spanned! {span=>
|
||||
::fayalite::expr::ops::ExprPartialEq::cmp_eq(__lhs.#field_ident, __rhs.#field_ident)
|
||||
});
|
||||
fields_cmp_ne.push(quote_spanned! {span=>
|
||||
::fayalite::expr::ops::ExprPartialEq::cmp_ne(__lhs.#field_ident, __rhs.#field_ident)
|
||||
});
|
||||
}
|
||||
let cmp_eq_body;
|
||||
let cmp_ne_body;
|
||||
if fields_len == 0 {
|
||||
cmp_eq_body = quote_spanned! {span=>
|
||||
::fayalite::expr::ToExpr::to_expr(&true)
|
||||
};
|
||||
cmp_ne_body = quote_spanned! {span=>
|
||||
::fayalite::expr::ToExpr::to_expr(&false)
|
||||
};
|
||||
} else {
|
||||
cmp_eq_body = quote_spanned! {span=>
|
||||
#(#fields_cmp_eq)&*
|
||||
};
|
||||
cmp_ne_body = quote_spanned! {span=>
|
||||
#(#fields_cmp_ne)|*
|
||||
};
|
||||
};
|
||||
quote_spanned! {span=>
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::fayalite::expr::ops::ExprPartialEq<Self> for #target #type_generics
|
||||
#where_clause
|
||||
{
|
||||
fn cmp_eq(
|
||||
__lhs: ::fayalite::expr::Expr<Self>,
|
||||
__rhs: ::fayalite::expr::Expr<Self>,
|
||||
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
|
||||
#cmp_eq_body
|
||||
}
|
||||
fn cmp_ne(
|
||||
__lhs: ::fayalite::expr::Expr<Self>,
|
||||
__rhs: ::fayalite::expr::Expr<Self>,
|
||||
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
|
||||
#cmp_ne_body
|
||||
}
|
||||
}
|
||||
}
|
||||
.to_tokens(tokens);
|
||||
}
|
||||
if let (None, MaybeParsed::Parsed(generics)) = (no_static, &self.generics) {
|
||||
let static_generics = generics.clone().for_static_type();
|
||||
let (static_impl_generics, static_type_generics, static_where_clause) =
|
||||
|
|
|
@ -155,7 +155,11 @@ impl ParsedEnum {
|
|||
custom_bounds,
|
||||
no_static: _,
|
||||
no_runtime_generics: _,
|
||||
cmp_eq,
|
||||
} = options.body;
|
||||
if let Some((cmp_eq,)) = cmp_eq {
|
||||
errors.error(cmp_eq, "#[hdl(cmp_eq)] is not yet implemented for enums");
|
||||
}
|
||||
attrs.retain(|attr| {
|
||||
if attr.path().is_ident("repr") {
|
||||
errors.error(attr, "#[repr] is not supported on #[hdl] enums");
|
||||
|
@ -211,6 +215,7 @@ impl ToTokens for ParsedEnum {
|
|||
custom_bounds: _,
|
||||
no_static,
|
||||
no_runtime_generics,
|
||||
cmp_eq: _, // TODO: implement cmp_eq for enums
|
||||
} = &options.body;
|
||||
let target = get_target(target, ident);
|
||||
let mut struct_attrs = attrs.clone();
|
||||
|
|
|
@ -49,10 +49,14 @@ impl ParsedTypeAlias {
|
|||
custom_bounds,
|
||||
no_static,
|
||||
no_runtime_generics: _,
|
||||
cmp_eq,
|
||||
} = options.body;
|
||||
if let Some((no_static,)) = no_static {
|
||||
errors.error(no_static, "no_static is not valid on type aliases");
|
||||
}
|
||||
if let Some((cmp_eq,)) = cmp_eq {
|
||||
errors.error(cmp_eq, "cmp_eq is not valid on type aliases");
|
||||
}
|
||||
let generics = if custom_bounds.is_some() {
|
||||
MaybeParsed::Unrecognized(generics)
|
||||
} else if let Some(generics) = errors.ok(ParsedGenerics::parse(&mut generics)) {
|
||||
|
@ -95,6 +99,7 @@ impl ToTokens for ParsedTypeAlias {
|
|||
custom_bounds: _,
|
||||
no_static: _,
|
||||
no_runtime_generics,
|
||||
cmp_eq: _,
|
||||
} = &options.body;
|
||||
let target = get_target(target, ident);
|
||||
let mut type_attrs = attrs.clone();
|
||||
|
|
|
@ -26,6 +26,7 @@ crate::options! {
|
|||
CustomBounds(custom_bounds),
|
||||
NoStatic(no_static),
|
||||
NoRuntimeGenerics(no_runtime_generics),
|
||||
CmpEq(cmp_eq),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ mod kw {
|
|||
custom_keyword!(cfg);
|
||||
custom_keyword!(cfg_attr);
|
||||
custom_keyword!(clock_domain);
|
||||
custom_keyword!(cmp_eq);
|
||||
custom_keyword!(connect_inexact);
|
||||
custom_keyword!(custom_bounds);
|
||||
custom_keyword!(flip);
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
expr::{ops::ArrayIndex, Expr, ToExpr},
|
||||
int::{DynSize, KnownSize, Size, SizeType, DYN_SIZE},
|
||||
expr::{
|
||||
ops::{ArrayIndex, ArrayLiteral, ExprPartialEq},
|
||||
CastToBits, Expr, HdlPartialEq, ReduceBits, ToExpr,
|
||||
},
|
||||
int::{Bool, DynSize, KnownSize, Size, SizeType, DYN_SIZE},
|
||||
intern::{Intern, Interned, LazyInterned},
|
||||
module::transform::visit::{Fold, Folder, Visit, Visitor},
|
||||
source_location::SourceLocation,
|
||||
|
@ -218,3 +221,36 @@ impl<T: Type, L: SizeType> Index<L> for ArrayWithoutLen<T> {
|
|||
Interned::into_inner(Intern::intern_sized(ArrayType::new(self.element, len)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Lhs: Type, Rhs: Type, Len: Size> ExprPartialEq<ArrayType<Rhs, Len>> for ArrayType<Lhs, Len>
|
||||
where
|
||||
Lhs: ExprPartialEq<Rhs>,
|
||||
{
|
||||
fn cmp_eq(lhs: Expr<Self>, rhs: Expr<ArrayType<Rhs, Len>>) -> Expr<Bool> {
|
||||
let lhs_ty = Expr::ty(lhs);
|
||||
let rhs_ty = Expr::ty(rhs);
|
||||
assert_eq!(lhs_ty.len(), rhs_ty.len());
|
||||
ArrayLiteral::<Bool, DynSize>::new(
|
||||
Bool,
|
||||
(0..lhs_ty.len())
|
||||
.map(|i| Expr::canonical(lhs[i].cmp_eq(rhs[i])))
|
||||
.collect(),
|
||||
)
|
||||
.cast_to_bits()
|
||||
.all_one_bits()
|
||||
}
|
||||
|
||||
fn cmp_ne(lhs: Expr<Self>, rhs: Expr<ArrayType<Rhs, Len>>) -> Expr<Bool> {
|
||||
let lhs_ty = Expr::ty(lhs);
|
||||
let rhs_ty = Expr::ty(rhs);
|
||||
assert_eq!(lhs_ty.len(), rhs_ty.len());
|
||||
ArrayLiteral::<Bool, DynSize>::new(
|
||||
Bool,
|
||||
(0..lhs_ty.len())
|
||||
.map(|i| Expr::canonical(lhs[i].cmp_ne(rhs[i])))
|
||||
.collect(),
|
||||
)
|
||||
.cast_to_bits()
|
||||
.any_one_bits()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
expr::{ops::BundleLiteral, Expr, ToExpr},
|
||||
expr::{
|
||||
ops::{ArrayLiteral, BundleLiteral, ExprPartialEq},
|
||||
CastToBits, Expr, ReduceBits, ToExpr,
|
||||
},
|
||||
int::{Bool, DynSize},
|
||||
intern::{Intern, Interned},
|
||||
sim::{SimValue, ToSimValue},
|
||||
source_location::SourceLocation,
|
||||
|
@ -325,7 +329,19 @@ macro_rules! impl_tuple_builder_fields {
|
|||
}
|
||||
|
||||
macro_rules! impl_tuples {
|
||||
([$({#[num = $num:literal, field = $field:ident, ty = $ty_var:ident: $Ty:ident] $var:ident: $T:ident})*] []) => {
|
||||
(
|
||||
[$({
|
||||
#[
|
||||
num = $num:tt,
|
||||
field = $field:ident,
|
||||
ty = $ty_var:ident: $Ty:ident,
|
||||
lhs = $lhs_var:ident: $Lhs:ident,
|
||||
rhs = $rhs_var:ident: $Rhs:ident
|
||||
]
|
||||
$var:ident: $T:ident
|
||||
})*]
|
||||
[]
|
||||
) => {
|
||||
impl_tuple_builder_fields! {
|
||||
{}
|
||||
[$({
|
||||
|
@ -498,6 +514,29 @@ macro_rules! impl_tuples {
|
|||
Self::into_sim_value(*self, ty)
|
||||
}
|
||||
}
|
||||
impl<$($Lhs: Type + ExprPartialEq<$Rhs>, $Rhs: Type,)*> ExprPartialEq<($($Rhs,)*)> for ($($Lhs,)*) {
|
||||
fn cmp_eq(lhs: Expr<Self>, rhs: Expr<($($Rhs,)*)>) -> Expr<Bool> {
|
||||
let ($($lhs_var,)*) = *lhs;
|
||||
let ($($rhs_var,)*) = *rhs;
|
||||
ArrayLiteral::<Bool, DynSize>::new(
|
||||
Bool,
|
||||
FromIterator::from_iter([$(Expr::canonical(ExprPartialEq::cmp_eq($lhs_var, $rhs_var)),)*]),
|
||||
)
|
||||
.cast_to_bits()
|
||||
.all_one_bits()
|
||||
}
|
||||
|
||||
fn cmp_ne(lhs: Expr<Self>, rhs: Expr<($($Rhs,)*)>) -> Expr<Bool> {
|
||||
let ($($lhs_var,)*) = *lhs;
|
||||
let ($($rhs_var,)*) = *rhs;
|
||||
ArrayLiteral::<Bool, DynSize>::new(
|
||||
Bool,
|
||||
FromIterator::from_iter([$(Expr::canonical(ExprPartialEq::cmp_ne($lhs_var, $rhs_var)),)*]),
|
||||
)
|
||||
.cast_to_bits()
|
||||
.any_one_bits()
|
||||
}
|
||||
}
|
||||
};
|
||||
([$($lhs:tt)*] [$rhs_first:tt $($rhs:tt)*]) => {
|
||||
impl_tuples!([$($lhs)*] []);
|
||||
|
@ -507,18 +546,18 @@ macro_rules! impl_tuples {
|
|||
|
||||
impl_tuples! {
|
||||
[] [
|
||||
{#[num = 0, field = field_0, ty = ty0: Ty0] v0: T0}
|
||||
{#[num = 1, field = field_1, ty = ty1: Ty1] v1: T1}
|
||||
{#[num = 2, field = field_2, ty = ty2: Ty2] v2: T2}
|
||||
{#[num = 3, field = field_3, ty = ty3: Ty3] v3: T3}
|
||||
{#[num = 4, field = field_4, ty = ty4: Ty4] v4: T4}
|
||||
{#[num = 5, field = field_5, ty = ty5: Ty5] v5: T5}
|
||||
{#[num = 6, field = field_6, ty = ty6: Ty6] v6: T6}
|
||||
{#[num = 7, field = field_7, ty = ty7: Ty7] v7: T7}
|
||||
{#[num = 8, field = field_8, ty = ty8: Ty8] v8: T8}
|
||||
{#[num = 9, field = field_9, ty = ty9: Ty9] v9: T9}
|
||||
{#[num = 10, field = field_10, ty = ty10: Ty10] v10: T10}
|
||||
{#[num = 11, field = field_11, ty = ty11: Ty11] v11: T11}
|
||||
{#[num = 0, field = field_0, ty = ty0: Ty0, lhs = lhs0: Lhs0, rhs = rhs0: Rhs0] v0: T0}
|
||||
{#[num = 1, field = field_1, ty = ty1: Ty1, lhs = lhs1: Lhs1, rhs = rhs1: Rhs1] v1: T1}
|
||||
{#[num = 2, field = field_2, ty = ty2: Ty2, lhs = lhs2: Lhs2, rhs = rhs2: Rhs2] v2: T2}
|
||||
{#[num = 3, field = field_3, ty = ty3: Ty3, lhs = lhs3: Lhs3, rhs = rhs3: Rhs3] v3: T3}
|
||||
{#[num = 4, field = field_4, ty = ty4: Ty4, lhs = lhs4: Lhs4, rhs = rhs4: Rhs4] v4: T4}
|
||||
{#[num = 5, field = field_5, ty = ty5: Ty5, lhs = lhs5: Lhs5, rhs = rhs5: Rhs5] v5: T5}
|
||||
{#[num = 6, field = field_6, ty = ty6: Ty6, lhs = lhs6: Lhs6, rhs = rhs6: Rhs6] v6: T6}
|
||||
{#[num = 7, field = field_7, ty = ty7: Ty7, lhs = lhs7: Lhs7, rhs = rhs7: Rhs7] v7: T7}
|
||||
{#[num = 8, field = field_8, ty = ty8: Ty8, lhs = lhs8: Lhs8, rhs = rhs8: Rhs8] v8: T8}
|
||||
{#[num = 9, field = field_9, ty = ty9: Ty9, lhs = lhs9: Lhs9, rhs = rhs9: Rhs9] v9: T9}
|
||||
{#[num = 10, field = field_10, ty = ty10: Ty10, lhs = lhs10: Lhs10, rhs = rhs10: Rhs10] v10: T10}
|
||||
{#[num = 11, field = field_11, ty = ty11: Ty11, lhs = lhs11: Lhs11, rhs = rhs11: Rhs11] v11: T11}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
expr::{ops::VariantAccess, Expr, ToExpr},
|
||||
expr::{
|
||||
ops::{ExprPartialEq, VariantAccess},
|
||||
Expr, ToExpr,
|
||||
},
|
||||
hdl,
|
||||
int::Bool,
|
||||
intern::{Intern, Interned},
|
||||
|
@ -360,6 +363,60 @@ pub enum HdlOption<T: Type> {
|
|||
HdlSome(T),
|
||||
}
|
||||
|
||||
impl<Lhs: Type + ExprPartialEq<Rhs>, Rhs: Type> ExprPartialEq<HdlOption<Rhs>> for HdlOption<Lhs> {
|
||||
#[hdl]
|
||||
fn cmp_eq(lhs: Expr<Self>, rhs: Expr<HdlOption<Rhs>>) -> Expr<Bool> {
|
||||
#[hdl]
|
||||
let cmp_eq = wire();
|
||||
#[hdl]
|
||||
match lhs {
|
||||
HdlSome(lhs) =>
|
||||
{
|
||||
#[hdl]
|
||||
match rhs {
|
||||
HdlSome(rhs) => connect(cmp_eq, ExprPartialEq::cmp_eq(lhs, rhs)),
|
||||
HdlNone => connect(cmp_eq, false),
|
||||
}
|
||||
}
|
||||
HdlNone =>
|
||||
{
|
||||
#[hdl]
|
||||
match rhs {
|
||||
HdlSome(_) => connect(cmp_eq, false),
|
||||
HdlNone => connect(cmp_eq, true),
|
||||
}
|
||||
}
|
||||
}
|
||||
cmp_eq
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
fn cmp_ne(lhs: Expr<Self>, rhs: Expr<HdlOption<Rhs>>) -> Expr<Bool> {
|
||||
#[hdl]
|
||||
let cmp_ne = wire();
|
||||
#[hdl]
|
||||
match lhs {
|
||||
HdlSome(lhs) =>
|
||||
{
|
||||
#[hdl]
|
||||
match rhs {
|
||||
HdlSome(rhs) => connect(cmp_ne, ExprPartialEq::cmp_ne(lhs, rhs)),
|
||||
HdlNone => connect(cmp_ne, true),
|
||||
}
|
||||
}
|
||||
HdlNone =>
|
||||
{
|
||||
#[hdl]
|
||||
match rhs {
|
||||
HdlSome(_) => connect(cmp_ne, true),
|
||||
HdlNone => connect(cmp_ne, false),
|
||||
}
|
||||
}
|
||||
}
|
||||
cmp_ne
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn HdlNone<T: StaticType>() -> Expr<HdlOption<T>> {
|
||||
HdlOption[T::TYPE].HdlNone()
|
||||
|
|
|
@ -380,18 +380,18 @@ circuit check_written_inside_both_if_else:
|
|||
};
|
||||
}
|
||||
|
||||
#[hdl(outline_generated)]
|
||||
#[hdl(outline_generated, cmp_eq)]
|
||||
pub struct TestStruct<T> {
|
||||
pub a: T,
|
||||
pub b: UInt<8>,
|
||||
}
|
||||
|
||||
#[hdl(outline_generated)]
|
||||
#[hdl(outline_generated, cmp_eq)]
|
||||
pub struct TestStruct2 {
|
||||
pub v: UInt<8>,
|
||||
}
|
||||
|
||||
#[hdl(outline_generated)]
|
||||
#[hdl(outline_generated, cmp_eq)]
|
||||
pub struct TestStruct3 {}
|
||||
|
||||
#[hdl_module(outline_generated)]
|
||||
|
@ -4425,3 +4425,125 @@ circuit check_let_patterns:
|
|||
",
|
||||
};
|
||||
}
|
||||
|
||||
#[hdl_module(outline_generated)]
|
||||
pub fn check_struct_cmp_eq() {
|
||||
#[hdl]
|
||||
let tuple_lhs: (UInt<1>, SInt<1>, Bool) = m.input();
|
||||
#[hdl]
|
||||
let tuple_rhs: (UInt<1>, SInt<1>, Bool) = m.input();
|
||||
#[hdl]
|
||||
let tuple_cmp_eq: Bool = m.output();
|
||||
connect(tuple_cmp_eq, tuple_lhs.cmp_eq(tuple_rhs));
|
||||
#[hdl]
|
||||
let tuple_cmp_ne: Bool = m.output();
|
||||
connect(tuple_cmp_ne, tuple_lhs.cmp_ne(tuple_rhs));
|
||||
|
||||
#[hdl]
|
||||
let test_struct_lhs: TestStruct<SInt<8>> = m.input();
|
||||
#[hdl]
|
||||
let test_struct_rhs: TestStruct<SInt<8>> = m.input();
|
||||
#[hdl]
|
||||
let test_struct_cmp_eq: Bool = m.output();
|
||||
connect(test_struct_cmp_eq, test_struct_lhs.cmp_eq(test_struct_rhs));
|
||||
#[hdl]
|
||||
let test_struct_cmp_ne: Bool = m.output();
|
||||
connect(test_struct_cmp_ne, test_struct_lhs.cmp_ne(test_struct_rhs));
|
||||
|
||||
#[hdl]
|
||||
let test_struct_2_lhs: TestStruct2 = m.input();
|
||||
#[hdl]
|
||||
let test_struct_2_rhs: TestStruct2 = m.input();
|
||||
#[hdl]
|
||||
let test_struct_2_cmp_eq: Bool = m.output();
|
||||
connect(
|
||||
test_struct_2_cmp_eq,
|
||||
test_struct_2_lhs.cmp_eq(test_struct_2_rhs),
|
||||
);
|
||||
#[hdl]
|
||||
let test_struct_2_cmp_ne: Bool = m.output();
|
||||
connect(
|
||||
test_struct_2_cmp_ne,
|
||||
test_struct_2_lhs.cmp_ne(test_struct_2_rhs),
|
||||
);
|
||||
|
||||
#[hdl]
|
||||
let test_struct_3_lhs: TestStruct3 = m.input();
|
||||
#[hdl]
|
||||
let test_struct_3_rhs: TestStruct3 = m.input();
|
||||
#[hdl]
|
||||
let test_struct_3_cmp_eq: Bool = m.output();
|
||||
connect(
|
||||
test_struct_3_cmp_eq,
|
||||
test_struct_3_lhs.cmp_eq(test_struct_3_rhs),
|
||||
);
|
||||
#[hdl]
|
||||
let test_struct_3_cmp_ne: Bool = m.output();
|
||||
connect(
|
||||
test_struct_3_cmp_ne,
|
||||
test_struct_3_lhs.cmp_ne(test_struct_3_rhs),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_struct_cmp_eq() {
|
||||
let _n = SourceLocation::normalize_files_for_tests();
|
||||
let m = check_struct_cmp_eq();
|
||||
dbg!(m);
|
||||
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
|
||||
assert_export_firrtl! {
|
||||
m =>
|
||||
"/test/check_struct_cmp_eq.fir": r"FIRRTL version 3.2.0
|
||||
circuit check_struct_cmp_eq:
|
||||
type Ty0 = {`0`: UInt<1>, `1`: SInt<1>, `2`: UInt<1>}
|
||||
type Ty1 = {a: SInt<8>, b: UInt<8>}
|
||||
type Ty2 = {v: UInt<8>}
|
||||
type Ty3 = {}
|
||||
module check_struct_cmp_eq: @[module-XXXXXXXXXX.rs 1:1]
|
||||
input tuple_lhs: Ty0 @[module-XXXXXXXXXX.rs 2:1]
|
||||
input tuple_rhs: Ty0 @[module-XXXXXXXXXX.rs 3:1]
|
||||
output tuple_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1]
|
||||
output tuple_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 6:1]
|
||||
input test_struct_lhs: Ty1 @[module-XXXXXXXXXX.rs 8:1]
|
||||
input test_struct_rhs: Ty1 @[module-XXXXXXXXXX.rs 9:1]
|
||||
output test_struct_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 10:1]
|
||||
output test_struct_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 12:1]
|
||||
input test_struct_2_lhs: Ty2 @[module-XXXXXXXXXX.rs 14:1]
|
||||
input test_struct_2_rhs: Ty2 @[module-XXXXXXXXXX.rs 15:1]
|
||||
output test_struct_2_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 16:1]
|
||||
output test_struct_2_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 18:1]
|
||||
input test_struct_3_lhs: Ty3 @[module-XXXXXXXXXX.rs 20:1]
|
||||
input test_struct_3_rhs: Ty3 @[module-XXXXXXXXXX.rs 21:1]
|
||||
output test_struct_3_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 22:1]
|
||||
output test_struct_3_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 24:1]
|
||||
wire _array_literal_expr: UInt<1>[3]
|
||||
connect _array_literal_expr[0], eq(tuple_lhs.`0`, tuple_rhs.`0`)
|
||||
connect _array_literal_expr[1], eq(tuple_lhs.`1`, tuple_rhs.`1`)
|
||||
connect _array_literal_expr[2], eq(tuple_lhs.`2`, tuple_rhs.`2`)
|
||||
wire _cast_array_to_bits_expr: UInt<1>[3]
|
||||
connect _cast_array_to_bits_expr[0], _array_literal_expr[0]
|
||||
connect _cast_array_to_bits_expr[1], _array_literal_expr[1]
|
||||
connect _cast_array_to_bits_expr[2], _array_literal_expr[2]
|
||||
wire _cast_to_bits_expr: UInt<3>
|
||||
connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0]))
|
||||
connect tuple_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1]
|
||||
wire _array_literal_expr_1: UInt<1>[3]
|
||||
connect _array_literal_expr_1[0], neq(tuple_lhs.`0`, tuple_rhs.`0`)
|
||||
connect _array_literal_expr_1[1], neq(tuple_lhs.`1`, tuple_rhs.`1`)
|
||||
connect _array_literal_expr_1[2], neq(tuple_lhs.`2`, tuple_rhs.`2`)
|
||||
wire _cast_array_to_bits_expr_1: UInt<1>[3]
|
||||
connect _cast_array_to_bits_expr_1[0], _array_literal_expr_1[0]
|
||||
connect _cast_array_to_bits_expr_1[1], _array_literal_expr_1[1]
|
||||
connect _cast_array_to_bits_expr_1[2], _array_literal_expr_1[2]
|
||||
wire _cast_to_bits_expr_1: UInt<3>
|
||||
connect _cast_to_bits_expr_1, cat(_cast_array_to_bits_expr_1[2], cat(_cast_array_to_bits_expr_1[1], _cast_array_to_bits_expr_1[0]))
|
||||
connect tuple_cmp_ne, orr(_cast_to_bits_expr_1) @[module-XXXXXXXXXX.rs 7:1]
|
||||
connect test_struct_cmp_eq, and(eq(test_struct_lhs.a, test_struct_rhs.a), eq(test_struct_lhs.b, test_struct_rhs.b)) @[module-XXXXXXXXXX.rs 11:1]
|
||||
connect test_struct_cmp_ne, or(neq(test_struct_lhs.a, test_struct_rhs.a), neq(test_struct_lhs.b, test_struct_rhs.b)) @[module-XXXXXXXXXX.rs 13:1]
|
||||
connect test_struct_2_cmp_eq, eq(test_struct_2_lhs.v, test_struct_2_rhs.v) @[module-XXXXXXXXXX.rs 17:1]
|
||||
connect test_struct_2_cmp_ne, neq(test_struct_2_lhs.v, test_struct_2_rhs.v) @[module-XXXXXXXXXX.rs 19:1]
|
||||
connect test_struct_3_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 23:1]
|
||||
connect test_struct_3_cmp_ne, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 25:1]
|
||||
",
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue