diff --git a/crates/fayalite-proc-macros-impl/src/fold.rs b/crates/fayalite-proc-macros-impl/src/fold.rs index 22e7b82..50423b5 100644 --- a/crates/fayalite-proc-macros-impl/src/fold.rs +++ b/crates/fayalite-proc-macros-impl/src/fold.rs @@ -257,5 +257,6 @@ no_op_fold!(syn::Token![let]); no_op_fold!(syn::Token![mut]); no_op_fold!(syn::Token![static]); no_op_fold!(syn::Token![struct]); +no_op_fold!(syn::Token![type]); no_op_fold!(syn::Token![where]); no_op_fold!(usize); diff --git a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs index 97fa3ff..f7ad68d 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs @@ -3,8 +3,9 @@ use crate::{ Errors, HdlAttr, PairsIterExt, hdl_type_common::{ - ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedField, ParsedFieldsNamed, ParsedGenerics, - SplitForImpl, TypesParser, WrappedInConst, common_derives, get_target, + CustomDebugOptions, CustomDebugTrait, ItemOptions, MakeHdlTypeExpr, MaybeParsed, + ParsedField, ParsedFieldsNamed, ParsedGenerics, SplitForImpl, TypesParser, WrappedInConst, + common_derives, create_struct_debug_impl, get_target, }, kw, }; @@ -30,6 +31,7 @@ pub(crate) struct ParsedBundle { pub(crate) fields: MaybeParsed, pub(crate) field_flips: Vec>>, pub(crate) mask_type_ident: Ident, + pub(crate) mask_type_name: String, pub(crate) mask_type_match_variant_ident: Ident, pub(crate) mask_type_sim_value_ident: Ident, pub(crate) match_variant_ident: Ident, @@ -88,6 +90,8 @@ impl ParsedBundle { no_runtime_generics: _, cmp_eq: _, ref get, + custom_debug: _, + custom_sim_display: _, } = options.body; if let Some((get, ..)) = get { errors.error(get, "#[hdl(get(...))] is not allowed on structs"); @@ -131,6 +135,7 @@ impl ParsedBundle { fields, field_flips, mask_type_ident: format_ident!("__{}__MaskType", ident), + mask_type_name: format!("MaskType<{}>", ident), mask_type_match_variant_ident: format_ident!("__{}__MaskType__MatchVariant", ident), mask_type_sim_value_ident: format_ident!("__{}__MaskType__SimValue", ident), match_variant_ident: format_ident!("__{}__MatchVariant", ident), @@ -448,6 +453,7 @@ impl ToTokens for ParsedBundle { fields, field_flips, mask_type_ident, + mask_type_name, mask_type_match_variant_ident, mask_type_sim_value_ident, match_variant_ident, @@ -464,11 +470,20 @@ impl ToTokens for ParsedBundle { no_runtime_generics, cmp_eq, get: _, + custom_debug: _, + custom_sim_display, } = &options.body; + let CustomDebugOptions { + type_: custom_debug_type, + sim: custom_debug_sim, + mask_type: custom_debug_mask_type, + mask_sim: custom_debug_mask_sim, + } = options.body.custom_debug(); let target = get_target(target, ident); + let struct_name = ident.to_string(); let mut item_attrs = attrs.clone(); - item_attrs.push(common_derives(span)); - ItemStruct { + item_attrs.push(common_derives(span, false)); + let type_struct = ItemStruct { attrs: item_attrs, vis: vis.clone(), struct_token: *struct_token, @@ -476,8 +491,8 @@ impl ToTokens for ParsedBundle { generics: generics.into(), fields: Fields::Named(fields.clone().into()), semi_token: None, - } - .to_tokens(tokens); + }; + type_struct.to_tokens(tokens); let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); if let (MaybeParsed::Parsed(generics), MaybeParsed::Parsed(fields), None) = (generics, fields, no_runtime_generics) @@ -503,6 +518,9 @@ impl ToTokens for ParsedBundle { } let mut wrapped_in_const = WrappedInConst::new(tokens, span); let tokens = wrapped_in_const.inner(); + if custom_debug_type.is_none() { + create_struct_debug_impl(&type_struct, &struct_name, None).to_tokens(tokens); + } let builder = Builder { vis: vis.clone(), struct_token: *struct_token, @@ -530,9 +548,9 @@ impl ToTokens for ParsedBundle { mask_type_builder.to_tokens(tokens); let unfilled_mask_type_builder_ty = mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled); - ItemStruct { + let mask_type_struct = ItemStruct { attrs: vec![ - common_derives(span), + common_derives(span, false), parse_quote_spanned! {span=> #[allow(non_camel_case_types, dead_code)] }, @@ -543,17 +561,20 @@ impl ToTokens for ParsedBundle { generics: generics.into(), fields: Fields::Named(mask_type_fields.clone()), semi_token: None, + }; + mask_type_struct.to_tokens(tokens); + if custom_debug_mask_type.is_none() { + create_struct_debug_impl(&mask_type_struct, mask_type_name, None).to_tokens(tokens); } - .to_tokens(tokens); let mut mask_type_match_variant_fields = mask_type_fields.clone(); for Field { ty, .. } in &mut mask_type_match_variant_fields.named { *ty = parse_quote_spanned! {span=> ::fayalite::expr::Expr<#ty> }; } - ItemStruct { + let mask_type_match_variant_struct = ItemStruct { attrs: vec![ - common_derives(span), + common_derives(span, false), parse_quote_spanned! {span=> #[allow(non_camel_case_types, dead_code)] }, @@ -564,17 +585,19 @@ impl ToTokens for ParsedBundle { generics: generics.into(), fields: Fields::Named(mask_type_match_variant_fields), semi_token: None, - } - .to_tokens(tokens); + }; + mask_type_match_variant_struct.to_tokens(tokens); + create_struct_debug_impl(&mask_type_match_variant_struct, mask_type_name, None) + .to_tokens(tokens); let mut match_variant_fields = FieldsNamed::from(fields.clone()); for Field { ty, .. } in &mut match_variant_fields.named { *ty = parse_quote_spanned! {span=> ::fayalite::expr::Expr<#ty> }; } - ItemStruct { + let match_variant_struct = ItemStruct { attrs: vec![ - common_derives(span), + common_derives(span, false), parse_quote_spanned! {span=> #[allow(non_camel_case_types, dead_code)] }, @@ -585,19 +608,19 @@ impl ToTokens for ParsedBundle { generics: generics.into(), fields: Fields::Named(match_variant_fields), semi_token: None, - } - .to_tokens(tokens); + }; + match_variant_struct.to_tokens(tokens); + create_struct_debug_impl(&match_variant_struct, &struct_name, None).to_tokens(tokens); let mut mask_type_sim_value_fields = mask_type_fields; for Field { ty, .. } in &mut mask_type_sim_value_fields.named { *ty = parse_quote_spanned! {span=> ::fayalite::sim::value::SimValue<#ty> }; } - ItemStruct { + let mask_type_sim_value_struct = ItemStruct { attrs: vec![ parse_quote_spanned! {span=> #[::fayalite::__std::prelude::v1::derive( - ::fayalite::__std::fmt::Debug, ::fayalite::__std::clone::Clone, )] }, @@ -611,19 +634,34 @@ impl ToTokens for ParsedBundle { generics: generics.into(), fields: Fields::Named(mask_type_sim_value_fields), semi_token: None, + }; + mask_type_sim_value_struct.to_tokens(tokens); + if custom_debug_mask_sim.is_none() { + create_struct_debug_impl( + &mask_type_struct, + mask_type_name, + Some(CustomDebugTrait { + trait_path: &parse_quote_spanned! {span=> + ::fayalite::ty::SimValueDebug + }, + fn_name: &format_ident!("sim_value_debug", span = span), + this_arg: &parse_quote_spanned! {span=> + value: &::SimValue + }, + }), + ) + .to_tokens(tokens); } - .to_tokens(tokens); let mut sim_value_fields = FieldsNamed::from(fields.clone()); for Field { ty, .. } in &mut sim_value_fields.named { *ty = parse_quote_spanned! {span=> ::fayalite::sim::value::SimValue<#ty> }; } - ItemStruct { + let sim_value_struct = ItemStruct { attrs: vec![ parse_quote_spanned! {span=> #[::fayalite::__std::prelude::v1::derive( - ::fayalite::__std::fmt::Debug, ::fayalite::__std::clone::Clone, )] }, @@ -637,8 +675,36 @@ impl ToTokens for ParsedBundle { generics: generics.into(), fields: Fields::Named(sim_value_fields), semi_token: None, + }; + sim_value_struct.to_tokens(tokens); + if custom_debug_sim.is_none() { + create_struct_debug_impl( + &type_struct, + &struct_name, + Some(CustomDebugTrait { + trait_path: &parse_quote_spanned! {span=> + ::fayalite::ty::SimValueDebug + }, + fn_name: &format_ident!("sim_value_debug", span = span), + this_arg: &parse_quote_spanned! {span=> + value: &::SimValue + }, + }), + ) + .to_tokens(tokens); + } + if custom_sim_display.is_some() { + quote_spanned! {span=> + #[automatically_derived] + impl #impl_generics ::fayalite::__std::fmt::Display for #sim_value_ident #type_generics + #where_clause + { + fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + <#target #type_generics as ::fayalite::ty::SimValueDisplay>::sim_value_display(self, f) + } + } + }.to_tokens(tokens); } - .to_tokens(tokens); let this_token = Ident::new("__this", span); let fields_token = Ident::new("__fields", span); let self_token = Token![self](span); @@ -820,6 +886,14 @@ impl ToTokens for ParsedBundle { } } #[automatically_derived] + impl #impl_generics ::fayalite::__std::fmt::Debug for #mask_type_sim_value_ident #type_generics + #where_clause + { + fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + <#mask_type_ident #type_generics as ::fayalite::ty::SimValueDebug>::sim_value_debug(self, f) + } + } + #[automatically_derived] impl #impl_generics ::fayalite::expr::ValueType for #mask_type_sim_value_ident #type_generics #where_clause { @@ -980,6 +1054,14 @@ impl ToTokens for ParsedBundle { } } #[automatically_derived] + impl #impl_generics ::fayalite::__std::fmt::Debug for #sim_value_ident #type_generics + #where_clause + { + fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + <#target #type_generics as ::fayalite::ty::SimValueDebug>::sim_value_debug(self, f) + } + } + #[automatically_derived] impl #impl_generics ::fayalite::expr::ValueType for #sim_value_ident #type_generics #where_clause { @@ -1141,7 +1223,7 @@ impl ToTokens for ParsedBundle { valueless_eq_body = quote_spanned! {span=> let __lhs = ::fayalite::expr::ValueType::ty(&__lhs); let __rhs = ::fayalite::expr::ValueType::ty(&__rhs); - #(#fields_valueless_eq)|* + #(#fields_valueless_eq)&* }; valueless_ne_body = quote_spanned! {span=> let __lhs = ::fayalite::expr::ValueType::ty(&__lhs); diff --git a/crates/fayalite-proc-macros-impl/src/hdl_enum.rs b/crates/fayalite-proc-macros-impl/src/hdl_enum.rs index ae0f8f4..e9f013b 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_enum.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_enum.rs @@ -3,8 +3,9 @@ use crate::{ Errors, HdlAttr, PairsIterExt, hdl_type_common::{ - ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, SplitForImpl, - TypesParser, WrappedInConst, common_derives, get_target, + CustomDebugOptions, ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, + SplitForImpl, TypesParser, WrappedInConst, common_derives, create_struct_debug_impl, + get_target, }, kw, }; @@ -158,15 +159,32 @@ impl ParsedEnum { custom_bounds, no_static: _, no_runtime_generics: _, - cmp_eq, + cmp_eq: _, ref get, + custom_debug: _, + custom_sim_display: _, } = options.body; - if let Some((cmp_eq,)) = cmp_eq { - errors.error(cmp_eq, "#[hdl(cmp_eq)] is not yet implemented for enums"); - } if let Some((get, ..)) = get { errors.error(get, "#[hdl(get(...))] is not allowed on enums"); } + let CustomDebugOptions { + type_: _, + sim: _, + mask_type, + mask_sim, + } = options.body.custom_debug(); + if let Some((mask_type,)) = mask_type { + errors.error( + mask_type, + "#[hdl(custom_debug(mask_type)] is not allowed on enums", + ); + } + if let Some((mask_sim,)) = mask_sim { + errors.error( + mask_sim, + "#[hdl(custom_debug(mask_sim)] is not allowed on enums", + ); + } attrs.retain(|attr| { if attr.path().is_ident("repr") { errors.error(attr, "#[repr] is not supported on #[hdl] enums"); @@ -228,12 +246,21 @@ impl ToTokens for ParsedEnum { custom_bounds: _, no_static, no_runtime_generics, - cmp_eq: _, // TODO: implement cmp_eq for enums + cmp_eq, get: _, + custom_debug: _, + custom_sim_display, } = &options.body; + let CustomDebugOptions { + type_: custom_debug_type, + sim: custom_debug_sim, + mask_type: _, + mask_sim: _, + } = options.body.custom_debug(); let target = get_target(target, ident); + let enum_name = ident.to_string(); let mut struct_attrs = attrs.clone(); - struct_attrs.push(common_derives(span)); + struct_attrs.push(common_derives(span, false)); struct_attrs.push(parse_quote_spanned! {span=> #[allow(non_snake_case)] }); @@ -273,7 +300,7 @@ impl ToTokens for ParsedEnum { } }, )); - ItemStruct { + let type_struct = ItemStruct { attrs: struct_attrs, vis: vis.clone(), struct_token: Token![struct](enum_token.span), @@ -288,8 +315,8 @@ impl ToTokens for ParsedEnum { }) }, semi_token: None, - } - .to_tokens(tokens); + }; + type_struct.to_tokens(tokens); let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); if let (MaybeParsed::Parsed(generics), None) = (generics, no_runtime_generics) { generics.make_runtime_generics(tokens, vis, ident, &target, |context| { @@ -373,6 +400,9 @@ impl ToTokens for ParsedEnum { } .to_tokens(tokens); } + if custom_debug_type.is_none() { + create_struct_debug_impl(&type_struct, &enum_name, None).to_tokens(tokens); + } let mut enum_attrs = attrs.clone(); enum_attrs.push(parse_quote_spanned! {span=> #[allow(dead_code, non_camel_case_types)] @@ -453,7 +483,6 @@ impl ToTokens for ParsedEnum { let mut enum_attrs = attrs.clone(); enum_attrs.push(parse_quote_spanned! {span=> #[::fayalite::__std::prelude::v1::derive( - ::fayalite::__std::fmt::Debug, ::fayalite::__std::clone::Clone, )] }); @@ -838,6 +867,240 @@ impl ToTokens for ParsedEnum { }, )), ); + if custom_debug_sim.is_none() { + let debug_match_arms = Vec::from_iter( + variants + .iter() + .map( + |ParsedVariant { + attrs: _, + options: _, + ident, + field, + }| { + let variant_name = ident.to_string(); + if let Some(_) = field { + quote_spanned! {span=> + #sim_value_ident::#ident(field, _) => { + f.debug_tuple(#variant_name).field(field).finish() + } + } + } else { + quote_spanned! {span=> + #sim_value_ident::#ident(_) => { + f.write_str(#variant_name) + } + } + } + }, + ) + .chain(sim_value_unknown_variant_name.as_ref().map( + |sim_value_unknown_variant_name| { + let sim_value_unknown_variant_name_str = + sim_value_unknown_variant_name.to_string(); + quote_spanned! {span=> + #sim_value_ident::#sim_value_unknown_variant_name(_) => { + f.write_str(#sim_value_unknown_variant_name_str) + } + } + }, + )), + ); + quote_spanned! {span=> + #[automatically_derived] + impl #impl_generics ::fayalite::ty::SimValueDebug for #target #type_generics + #where_clause + { + fn sim_value_debug( + value: &::SimValue, + f: &mut ::fayalite::__std::fmt::Formatter<'_>, + ) -> ::fayalite::__std::fmt::Result { + match value { + #(#debug_match_arms)* + } + } + } + } + .to_tokens(tokens); + } + if custom_sim_display.is_some() { + quote_spanned! {span=> + #[automatically_derived] + impl #impl_generics ::fayalite::__std::fmt::Display for #sim_value_ident #type_generics + #where_clause + { + fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + <#target #type_generics as ::fayalite::ty::SimValueDisplay>::sim_value_display(self, f) + } + } + }.to_tokens(tokens); + } + if let Some((cmp_eq,)) = cmp_eq { + let mut cmp_eq_where_clause = + Generics::from(generics) + .where_clause + .unwrap_or_else(|| syn::WhereClause { + where_token: Token![where](span), + predicates: Punctuated::new(), + }); + let mut variants_value_eq = vec![]; + let mut variants_expr_eq = vec![]; + let mut fields_valueless_eq = vec![]; + for ( + variant_index, + ParsedVariant { + attrs: _, + options: variant_options, + ident: variant_ident, + field, + }, + ) in variants.iter().enumerate() + { + let VariantOptions {} = variant_options.body; + if let Some(ParsedVariantField { + paren_token: _, + attrs: _, + options: field_options, + ty: field_ty, + comma_token: _, + }) = field + { + let FieldOptions {} = field_options.body; + cmp_eq_where_clause + .predicates + .push(parse_quote_spanned! {cmp_eq.span=> + #field_ty: ::fayalite::expr::HdlPartialEqImpl<#field_ty> + }); + variants_value_eq.push(quote_spanned! {span=> + (#sim_value_ident::#variant_ident(__lhs_field, _), #sim_value_ident::#variant_ident(__rhs_field, _)) => { + ::fayalite::expr::HdlPartialEqImpl::cmp_value_eq( + __lhs.#variant_ident, + ::fayalite::__std::borrow::Cow::Borrowed(__lhs_field), + __rhs.#variant_ident, + ::fayalite::__std::borrow::Cow::Borrowed(__rhs_field), + ) + } + }); + variants_expr_eq.push(quote_spanned! {span=> + { + let (#match_variant_ident::#variant_ident(__lhs), __scope) = + ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( + ::fayalite::__std::iter::Iterator::next(&mut __lhs_match_variant_iter) + .expect("known to have enough variants"), + ) + else { + ::fayalite::__std::unreachable!(); + }; + let (#match_variant_ident::#variant_ident(__rhs), __scope) = + ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( + ::fayalite::__std::iter::Iterator::nth( + &mut ::fayalite::module::match_(__rhs), + #variant_index, + ) + .expect("known to have variant"), + ) + else { + ::fayalite::__std::unreachable!(); + }; + ::fayalite::module::connect(__retval, ::fayalite::expr::HdlPartialEqImpl::cmp_expr_eq(__lhs, __rhs)); + } + }); + fields_valueless_eq.push(quote_spanned! {span=> + ::fayalite::expr::HdlPartialEqImpl::cmp_valueless_eq( + ::fayalite::expr::Valueless::new(__lhs.#variant_ident), + ::fayalite::expr::Valueless::new(__rhs.#variant_ident), + ) + }); + } else { + variants_value_eq.push(quote_spanned! {span=> + (#sim_value_ident::#variant_ident(_), #sim_value_ident::#variant_ident(_)) => true, + }); + variants_expr_eq.push(quote_spanned! {span=> + { + let (#match_variant_ident::#variant_ident, __scope) = + ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( + ::fayalite::__std::iter::Iterator::next(&mut __lhs_match_variant_iter) + .expect("known to have enough variants"), + ) + else { + ::fayalite::__std::unreachable!(); + }; + let (#match_variant_ident::#variant_ident, __scope) = + ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( + ::fayalite::__std::iter::Iterator::nth( + &mut ::fayalite::module::match_(__rhs), + #variant_index, + ) + .expect("known to have variant"), + ) + else { + ::fayalite::__std::unreachable!(); + }; + ::fayalite::module::connect(__retval, true); + } + }); + } + } + if let Some(sim_value_unknown_variant_name) = &sim_value_unknown_variant_name { + variants_value_eq.push(quote_spanned! {span=> + (#sim_value_ident::#sim_value_unknown_variant_name(__lhs_unknown), #sim_value_ident::#sim_value_unknown_variant_name(__rhs_unknown)) => { + __lhs_unknown == __rhs_unknown + } + }); + } + let valueless_eq_body = if fields_valueless_eq.is_empty() { + quote_spanned! {span=> + ::fayalite::expr::Valueless::new(::fayalite::int::Bool) + } + } else { + quote_spanned! {span=> + let __lhs = ::fayalite::expr::ValueType::ty(&__lhs); + let __rhs = ::fayalite::expr::ValueType::ty(&__rhs); + #(#fields_valueless_eq)&* + } + }; + let cmp_expr_eq_wire_name = format!("{ident}_cmp_eq"); + quote_spanned! {span=> + #[automatically_derived] + impl #impl_generics ::fayalite::expr::HdlPartialEqImpl for #target #type_generics + #cmp_eq_where_clause + { + #[track_caller] + fn cmp_value_eq( + __lhs: Self, + __lhs_value: ::fayalite::__std::borrow::Cow<'_, ::SimValue>, + __rhs: Self, + __rhs_value: ::fayalite::__std::borrow::Cow<'_, ::SimValue>, + ) -> ::fayalite::__std::primitive::bool { + match (&*__lhs_value, &*__rhs_value) { + #(#variants_value_eq)* + _ => false, + } + } + + #[track_caller] + fn cmp_expr_eq( + __lhs: ::fayalite::expr::Expr, + __rhs: ::fayalite::expr::Expr, + ) -> ::fayalite::expr::Expr<::fayalite::int::Bool> { + let __retval = ::fayalite::module::wire(::fayalite::module::ImplicitName(#cmp_expr_eq_wire_name), ::fayalite::int::Bool); + ::fayalite::module::connect(__retval, false); + let mut __lhs_match_variant_iter = ::fayalite::module::match_(__lhs); + #(#variants_expr_eq)* + __retval + } + + #[track_caller] + fn cmp_valueless_eq( + __lhs: ::fayalite::expr::Valueless, + __rhs: ::fayalite::expr::Valueless, + ) -> ::fayalite::expr::Valueless<::fayalite::int::Bool> { + #valueless_eq_body + } + } + } + .to_tokens(tokens); + } let variants_len = variants.len(); quote_spanned! {span=> #[automatically_derived] @@ -934,6 +1197,14 @@ impl ToTokens for ParsedEnum { } } #[automatically_derived] + impl #impl_generics ::fayalite::__std::fmt::Debug for #sim_value_ident #type_generics + #where_clause + { + fn fmt(&self, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + <#target #type_generics as ::fayalite::ty::SimValueDebug>::sim_value_debug(self, f) + } + } + #[automatically_derived] impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#target #type_generics> for #sim_value_ident #type_generics #where_clause diff --git a/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs b/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs index 0fa2222..556c15b 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs @@ -215,6 +215,8 @@ impl ParsedTypeAlias { no_runtime_generics, cmp_eq, get: _, + ref custom_debug, + custom_sim_display, } = options.body; if let Some((no_static,)) = no_static { errors.error(no_static, "no_static is not valid on type aliases"); @@ -234,6 +236,15 @@ impl ParsedTypeAlias { if let Some((cmp_eq,)) = cmp_eq { errors.error(cmp_eq, "cmp_eq is not valid on type aliases"); } + if let Some((custom_debug, _, _)) = custom_debug { + errors.error(custom_debug, "custom_debug is not valid on type aliases"); + } + if let Some((custom_sim_display,)) = custom_sim_display { + errors.error( + custom_sim_display, + "custom_sim_display is not valid on type aliases", + ); + } if let Some((custom_bounds,)) = custom_bounds { errors.error( custom_bounds, @@ -287,6 +298,8 @@ impl ParsedTypeAlias { no_runtime_generics: _, cmp_eq, ref mut get, + ref custom_debug, + custom_sim_display, } = options.body; if let Some(get) = get.take() { return Self::parse_phantom_const_accessor( @@ -311,6 +324,15 @@ impl ParsedTypeAlias { if let Some((cmp_eq,)) = cmp_eq { errors.error(cmp_eq, "cmp_eq is not valid on type aliases"); } + if let Some((custom_debug, _, _)) = custom_debug { + errors.error(custom_debug, "custom_debug is not valid on type aliases"); + } + if let Some((custom_sim_display,)) = custom_sim_display { + errors.error( + custom_sim_display, + "custom_sim_display 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)) { @@ -356,6 +378,8 @@ impl ToTokens for ParsedTypeAlias { no_runtime_generics, cmp_eq: _, get: _, + custom_debug: _, + custom_sim_display: _, } = &options.body; let target = get_target(target, ident); let mut type_attrs = attrs.clone(); @@ -402,6 +426,8 @@ impl ToTokens for ParsedTypeAlias { no_runtime_generics: _, cmp_eq: _, get: _, + custom_debug: _, + custom_sim_display: _, } = &options.body; let span = ident.span(); let mut type_attrs = attrs.clone(); @@ -427,7 +453,7 @@ impl ToTokens for ParsedTypeAlias { format_ident!("__{}__GenericsAccumulation", ident); ItemStruct { attrs: vec![ - common_derives(span), + common_derives(span, true), parse_quote_spanned! {span=> #[allow(non_camel_case_types)] }, diff --git a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs index 3a0e5e9..18cffc6 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs @@ -7,10 +7,10 @@ use std::{collections::HashMap, fmt, mem}; use syn::{ AngleBracketedGenericArguments, Attribute, Block, ConstParam, Expr, ExprBlock, ExprGroup, ExprIndex, ExprParen, ExprPath, ExprTuple, Field, FieldMutability, Fields, FieldsNamed, - FieldsUnnamed, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index, ItemStruct, - Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, TraitBound, Turbofish, - Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath, TypeTuple, - Visibility, WhereClause, WherePredicate, + FieldsUnnamed, FnArg, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index, + ItemStruct, Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, TraitBound, + Turbofish, Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath, + TypeTuple, Visibility, WhereClause, WherePredicate, parse::{Parse, ParseStream}, parse_quote, parse_quote_spanned, punctuated::{Pair, Punctuated}, @@ -18,6 +18,17 @@ use syn::{ token::{Brace, Bracket, Paren}, }; +crate::options! { + #[options = CustomDebugOptions] + #[no_ident_fragment] + pub(crate) enum CustomDebugOption { + Type(type_), + Sim(sim), + MaskType(mask_type), + MaskSim(mask_sim), + } +} + crate::options! { #[options = ItemOptions] pub(crate) enum ItemOption { @@ -28,6 +39,8 @@ crate::options! { NoRuntimeGenerics(no_runtime_generics), CmpEq(cmp_eq), Get(get, Expr), + CustomDebug(custom_debug, CustomDebugOptions), + CustomSimDisplay(custom_sim_display), } } @@ -41,8 +54,36 @@ impl ItemOptions { { self.no_static = Some((kw::no_static(custom_bounds.span),)); } + if let Some((kw, _, custom_debug)) = &mut self.custom_debug { + if let CustomDebugOptions { + type_: None, + sim: None, + mask_type: None, + mask_sim: None, + } = custom_debug + { + *custom_debug = CustomDebugOptions { + type_: Some((kw::type_(kw.span),)), + sim: Some((kw::sim(kw.span),)), + mask_type: None, + mask_sim: None, + }; + } + } Ok(()) } + pub(crate) fn custom_debug(&self) -> &CustomDebugOptions { + self.custom_debug.as_ref().map(|v| &v.2).unwrap_or( + const { + &CustomDebugOptions { + type_: None, + sim: None, + mask_type: None, + mask_sim: None, + } + }, + ) + } } pub(crate) struct WrappedInConst<'a> { @@ -84,10 +125,17 @@ pub(crate) fn get_target(target: &Option<(kw::target, Paren, Path)>, item_ident: } } -pub(crate) fn common_derives(span: Span) -> Attribute { +pub(crate) fn common_derives(span: Span, include_debug: bool) -> Attribute { + let debug = include_debug + .then(|| { + quote_spanned! {span=> + ::fayalite::__std::fmt::Debug + } + }) + .into_iter(); parse_quote_spanned! {span=> #[::fayalite::__std::prelude::v1::derive( - ::fayalite::__std::fmt::Debug, + #(#debug,)* ::fayalite::__std::cmp::Eq, ::fayalite::__std::cmp::PartialEq, ::fayalite::__std::hash::Hash, @@ -2975,7 +3023,7 @@ impl ParsedGenerics { let span = ident.span(); ItemStruct { attrs: vec![ - common_derives(span), + common_derives(span, true), parse_quote_spanned! {span=> #[allow(non_camel_case_types)] }, @@ -4733,3 +4781,109 @@ impl ParsedVisibility { .map(|ord| if ord.is_lt() { self } else { other }) } } + +pub(crate) struct CustomDebugTrait<'a> { + pub(crate) trait_path: &'a Path, + pub(crate) fn_name: &'a Ident, + pub(crate) this_arg: &'a FnArg, +} + +#[must_use] +pub(crate) fn create_struct_debug_impl( + item_struct: &ItemStruct, + debug_struct_name: &str, + custom_debug_trait: Option>, +) -> TokenStream { + let ident = &item_struct.ident; + let span = ident.span(); + let (impl_generics, type_generics, where_clause) = item_struct.generics.split_for_impl(); + let trait_path; + let fn_name; + let this_arg; + let CustomDebugTrait { + trait_path, + fn_name, + this_arg, + } = match custom_debug_trait { + Some(v) => v, + None => { + trait_path = parse_quote_spanned! {span=> + ::fayalite::__std::fmt::Debug + }; + fn_name = parse_quote_spanned! {span=> + fmt + }; + this_arg = parse_quote_spanned! {span=> + &self + }; + CustomDebugTrait { + trait_path: &trait_path, + fn_name: &fn_name, + this_arg: &this_arg, + } + } + }; + let this_arg_name = match this_arg { + FnArg::Receiver(this_arg) => this_arg.self_token.to_token_stream(), + FnArg::Typed(this_arg) => match &*this_arg.pat { + syn::Pat::Ident(pat_ident) => pat_ident.ident.to_token_stream(), + _ => unreachable!(), + }, + }; + match &item_struct.fields { + Fields::Named(fields) => { + let field_idents = fields + .named + .iter() + .map(|v| v.ident.as_ref().expect("known to have field name")); + let field_names = field_idents.clone().map(|v| v.to_string()); + quote_spanned! {span=> + #[automatically_derived] + impl #impl_generics #trait_path for #ident #type_generics + #where_clause + { + fn #fn_name(#this_arg, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + let _ = #this_arg_name; + f.debug_struct(#debug_struct_name) + #(.field(#field_names, &#this_arg_name.#field_idents))* + .finish() + } + } + } + } + Fields::Unnamed(fields) => { + let field_members = fields + .unnamed + .iter() + .enumerate() + .map(|(index, _)| syn::Index { + index: index as _, + span, + }); + quote_spanned! {span=> + #[automatically_derived] + impl #impl_generics #trait_path for #ident #type_generics + #where_clause + { + fn #fn_name(#this_arg, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + let _ = #this_arg_name; + f.debug_tuple(#debug_struct_name) + #(.field(&#this_arg_name.#field_members))* + .finish() + } + } + } + } + Fields::Unit => quote_spanned! {ident.span()=> + #[automatically_derived] + impl #impl_generics #trait_path for #ident #type_generics + #where_clause + { + fn #fn_name(#this_arg, f: &mut ::fayalite::__std::fmt::Formatter<'_>) -> ::fayalite::__std::fmt::Result { + let _ = #this_arg_name; + f.write_str(#debug_struct_name) + } + } + }, + } +} diff --git a/crates/fayalite-proc-macros-impl/src/lib.rs b/crates/fayalite-proc-macros-impl/src/lib.rs index 152053c..905cb05 100644 --- a/crates/fayalite-proc-macros-impl/src/lib.rs +++ b/crates/fayalite-proc-macros-impl/src/lib.rs @@ -42,6 +42,7 @@ pub(crate) trait CustomToken: mod kw { pub(crate) use syn::token::Extern as extern_; + pub(crate) use syn::token::Type as type_; macro_rules! custom_keyword { ($kw:ident) => { @@ -75,6 +76,8 @@ mod kw { custom_keyword!(cmp_eq); custom_keyword!(connect_inexact); custom_keyword!(custom_bounds); + custom_keyword!(custom_debug); + custom_keyword!(custom_sim_display); custom_keyword!(flip); custom_keyword!(get); custom_keyword!(hdl); @@ -83,6 +86,8 @@ mod kw { custom_keyword!(input); custom_keyword!(instance); custom_keyword!(m); + custom_keyword!(mask_sim); + custom_keyword!(mask_type); custom_keyword!(memory); custom_keyword!(memory_array); custom_keyword!(memory_with_init); diff --git a/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_match.rs b/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_match.rs index ca06c0b..605f662 100644 --- a/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_match.rs +++ b/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_match.rs @@ -1096,11 +1096,9 @@ impl Visitor<'_> { let (#(#bindings,)*) = { type __MatchTy = ::SimValue; let __match_value = #expr; - let __match_value = { - use ::fayalite::sim::value::match_sim_value::*; - // use method syntax to deduce the correct trait to call - ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value).__fayalite_match_sim_value() - }; + // use method syntax to deduce what type to convert to + let __match_value = ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value) + .__fayalite_match_sim_value(); #let_token #pat #eq_token __match_value #semi_token (#(#bindings_idents,)*) }; @@ -1172,11 +1170,9 @@ impl Visitor<'_> { { type __MatchTy = ::SimValue; let __match_value = #expr; - let __match_value = { - use ::fayalite::sim::value::match_sim_value::*; - // use method syntax to deduce the correct trait to call - ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value).__fayalite_match_sim_value() - }; + // use method syntax to deduce what type to convert to + let __match_value = ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value) + .__fayalite_match_sim_value(); #match_token __match_value { #(#arms)* } diff --git a/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs b/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs index 8d70d21..065e5de 100644 --- a/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs +++ b/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs @@ -95,7 +95,23 @@ //! } //! //! #[hdl] -//! fn destructure_to_sim_value<'a, T: Type>(v: impl ToSimValue>) { +//! fn destructure_inner(v: as Type>::SimValue) { +//! #[hdl(sim)] +//! let MyStruct:: { +//! a, +//! mut b, +//! c, +//! } = v; +//! +//! // that gives these types: +//! let _: SimValue> = a; +//! let _: SimValue = b; +//! let _: SimValue = c; +//! *b = false; // can modify b since mut was used +//! } +//! +//! #[hdl] +//! fn destructure_inner_ref<'a, T: Type>(v: &'a as Type>::SimValue) { //! #[hdl(sim)] //! let MyStruct:: { //! a, @@ -104,8 +120,25 @@ //! } = v; //! //! // that gives these types: -//! let _: SimValue> = a; -//! let _: SimValue = b; -//! let _: SimValue = c; +//! let _: &'a SimValue> = a; +//! let _: &'a SimValue = b; +//! let _: &'a SimValue = c; +//! } +//! +//! #[hdl] +//! fn destructure_inner_mut<'a, T: Type>(v: &'a mut as Type>::SimValue) { +//! #[hdl(sim)] +//! let MyStruct:: { +//! a, +//! b, +//! c, +//! } = v; +//! +//! **b = true; // you can modify v by modifying b which borrows from it +//! +//! // that gives these types: +//! let _: &'a mut SimValue> = a; +//! let _: &'a mut SimValue = b; +//! let _: &'a mut SimValue = c; //! } //! ``` diff --git a/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs b/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs index accd3d7..9e2d41d 100644 --- a/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs +++ b/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs @@ -72,15 +72,47 @@ //! } //! //! #[hdl] -//! fn match_to_sim_value<'a, T: Type>(v: impl ToSimValue>) { +//! fn match_inner_move(v: as Type>::SimValue) -> String { //! #[hdl(sim)] //! match v { -//! MyEnum::::A => println!("got A"), -//! MyEnum::::B(b) => { +//! MyEnum::::A => String::from("got A"), +//! MyEnum::::B(mut b) => { //! let _: SimValue = b; // b has this type -//! println!("got B({b})"); +//! let text = format!("got B({b})"); +//! *b = true; // can modify b since mut was used +//! text //! } -//! _ => println!("something else"), +//! _ => String::from("something else"), +//! } +//! } +//! +//! #[hdl] +//! fn match_inner_ref<'a, T: Type>(v: &'a as Type>::SimValue) -> u32 { +//! #[hdl(sim)] +//! match v { +//! MyEnum::::A => 1, +//! MyEnum::::B(b) => { +//! let _: &'a SimValue = b; // b has this type +//! println!("got B({b})"); +//! 5 +//! } +//! _ => 42, +//! } +//! } +//! +//! #[hdl] +//! fn match_inner_mut<'a, T: Type>(v: &'a mut as Type>::SimValue) -> Option<&'a mut SimValue> { +//! #[hdl(sim)] +//! match v { +//! MyEnum::::A => None, +//! MyEnum::::B(b) => { +//! println!("got B({b})"); +//! **b = true; // you can modify v by modifying b which borrows from it +//! let _: &'a mut SimValue = b; // b has this type +//! None +//! } +//! MyEnum::::C(v) => Some(v), // you can return matched values +//! _ => None, // HDL enums can have invalid discriminants, so we need this extra match arm //! } //! } //! ``` diff --git a/crates/fayalite/src/array.rs b/crates/fayalite/src/array.rs index 6ca6809..fa754fd 100644 --- a/crates/fayalite/src/array.rs +++ b/crates/fayalite/src/array.rs @@ -13,13 +13,13 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, MatchVariantWithoutScope, OpaqueSimValueSlice, OpaqueSimValueWriter, - OpaqueSimValueWritten, StaticType, Type, TypeProperties, TypeWithDeref, + OpaqueSimValueWritten, SimValueDebug, StaticType, Type, TypeProperties, TypeWithDeref, serde_impls::SerdeCanonicalType, }, util::ConstUsize, }; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error}; -use std::{borrow::Cow, iter::FusedIterator, ops::Index}; +use std::{borrow::Cow, fmt, iter::FusedIterator, ops::Index}; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct ArrayType { @@ -28,8 +28,8 @@ pub struct ArrayType { type_properties: TypeProperties, } -impl std::fmt::Debug for ArrayType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Debug for ArrayType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Array<{:?}, {}>", self.element, self.len()) } } @@ -182,6 +182,15 @@ impl, Len: Size, State: Visitor + ?Sized> Visit } } +impl SimValueDebug for ArrayType { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl Type for ArrayType { type BaseType = Array; type MaskType = ArrayType; diff --git a/crates/fayalite/src/bundle.rs b/crates/fayalite/src/bundle.rs index 1471f3a..5fad35c 100644 --- a/crates/fayalite/src/bundle.rs +++ b/crates/fayalite/src/bundle.rs @@ -14,8 +14,8 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, MatchVariantWithoutScope, OpaqueSimValue, OpaqueSimValueSize, - OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type, - TypeProperties, TypeWithDeref, impl_match_variant_as_self, + OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, SimValueDebug, + StaticType, Type, TypeProperties, TypeWithDeref, impl_match_variant_as_self, }, util::HashMap, }; @@ -271,6 +271,15 @@ impl Type for Bundle { } } +impl SimValueDebug for Bundle { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + pub trait BundleType: Type { type Builder: Default; fn fields(&self) -> Interned<[BundleField]>; @@ -471,6 +480,14 @@ macro_rules! impl_tuples { #[var($var)] })*] } + impl<$($T: Type,)*> SimValueDebug for ($($T,)*) { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } + } impl<$($T: Type,)*> Type for ($($T,)*) { type BaseType = Bundle; type MaskType = ($($T::MaskType,)*); @@ -773,6 +790,15 @@ impl_tuples! { ] } +impl SimValueDebug for PhantomData { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl Type for PhantomData { type BaseType = Bundle; type MaskType = (); diff --git a/crates/fayalite/src/clock.rs b/crates/fayalite/src/clock.rs index 168142b..0e6d145 100644 --- a/crates/fayalite/src/clock.rs +++ b/crates/fayalite/src/clock.rs @@ -1,5 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information + use crate::{ expr::{Expr, ValueType}, hdl, @@ -9,10 +10,12 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter, - OpaqueSimValueWritten, StaticType, Type, TypeProperties, impl_match_variant_as_self, + OpaqueSimValueWritten, SimValueDebug, StaticType, Type, TypeProperties, + impl_match_variant_as_self, }, }; use bitvec::{bits, order::Lsb0}; +use std::fmt; #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)] pub struct Clock; @@ -69,6 +72,15 @@ impl Type for Clock { } } +impl SimValueDebug for Clock { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl Clock { pub fn type_properties(self) -> TypeProperties { Self::TYPE_PROPERTIES diff --git a/crates/fayalite/src/enum_.rs b/crates/fayalite/src/enum_.rs index a04f67a..f6af578 100644 --- a/crates/fayalite/src/enum_.rs +++ b/crates/fayalite/src/enum_.rs @@ -2,7 +2,7 @@ // See Notices.txt for copyright information use crate::{ - expr::{Expr, HdlPartialEq, HdlPartialEqImpl, ToExpr, ValueType, ops::VariantAccess}, + expr::{Expr, ToExpr, ValueType, ops::VariantAccess}, hdl, int::{Bool, UIntValue}, intern::{Intern, Interned}, @@ -10,18 +10,18 @@ use crate::{ EnumMatchVariantAndInactiveScopeImpl, EnumMatchVariantsIterImpl, Scope, connect, enum_match_variants_helper, incomplete_wire, wire, }, - sim::value::SimValue, + sim::value::{SimValue, ToSimValue, ToSimValueWithType}, source_location::SourceLocation, ty::{ CanonicalType, MatchVariantAndInactiveScope, OpaqueSimValue, OpaqueSimValueSize, - OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type, - TypeProperties, + OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, SimValueDebug, + StaticType, Type, TypeProperties, }, util::HashMap, }; use bitvec::{order::Lsb0, slice::BitSlice, view::BitView}; use serde::{Deserialize, Serialize}; -use std::{borrow::Cow, convert::Infallible, fmt, iter::FusedIterator, sync::Arc}; +use std::{convert::Infallible, fmt, iter::FusedIterator, sync::Arc}; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] pub struct EnumVariant { @@ -410,6 +410,15 @@ impl Type for Enum { } } +impl SimValueDebug for Enum { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + #[derive(Clone, PartialEq, Eq, Hash, Debug, Default)] pub struct EnumPaddingSimValue { bits: Option, @@ -723,95 +732,12 @@ pub fn enum_type_to_sim_builder(v: T) -> T::SimBuilder { v.into() } -#[hdl] +#[hdl(cmp_eq)] pub enum HdlOption { HdlNone, HdlSome(T), } -impl, Rhs: Type> HdlPartialEqImpl> - for HdlOption -{ - fn cmp_value_eq( - lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - rhs: HdlOption, - rhs_value: Cow<'_, as Type>::SimValue>, - ) -> bool { - type SimValueMatch = ::SimValue; - match (&*lhs_value, &*rhs_value) { - (SimValueMatch::::HdlNone(_), SimValueMatch::>::HdlNone(_)) => { - true - } - (SimValueMatch::::HdlSome(..), SimValueMatch::>::HdlNone(_)) - | (SimValueMatch::::HdlNone(_), SimValueMatch::>::HdlSome(..)) => { - false - } - ( - SimValueMatch::::HdlSome(l, _), - SimValueMatch::>::HdlSome(r, _), - ) => HdlPartialEqImpl::cmp_value_eq( - lhs.HdlSome, - Cow::Borrowed(&**l), - rhs.HdlSome, - Cow::Borrowed(&**r), - ), - } - } - - #[hdl] - fn cmp_expr_eq(lhs: Expr, rhs: Expr>) -> Expr { - #[hdl] - let cmp_eq = wire(); - #[hdl] - match lhs { - HdlSome(lhs) => - { - #[hdl] - match rhs { - HdlSome(rhs) => connect(cmp_eq, lhs.cmp_eq(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_expr_ne(lhs: Expr, rhs: Expr>) -> Expr { - #[hdl] - let cmp_ne = wire(); - #[hdl] - match lhs { - HdlSome(lhs) => - { - #[hdl] - match rhs { - HdlSome(rhs) => connect(cmp_ne, lhs.cmp_ne(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() -> Expr> { HdlOption[T::TYPE].HdlNone() @@ -823,6 +749,123 @@ pub fn HdlSome(value: impl ToExpr) -> Expr> { HdlOption[value.ty()].HdlSome(value) } +impl From>> for Option> { + #[hdl] + fn from(value: SimValue>) -> Self { + #[hdl(sim)] + match value { + HdlSome(v) => Some(v), + HdlNone => None, + } + } +} + +impl<'a, T: Type> From<&'a SimValue>> for Option<&'a SimValue> { + #[hdl] + fn from(value: &'a SimValue>) -> Self { + #[hdl(sim)] + match value { + HdlSome(v) => Some(v), + HdlNone => None, + } + } +} + +impl<'a, T: Type> From<&'a mut SimValue>> for Option<&'a mut SimValue> { + #[hdl] + fn from(value: &'a mut SimValue>) -> Self { + #[hdl(sim)] + match value { + HdlSome(v) => Some(v), + HdlNone => None, + } + } +} + +impl>> ValueType for Option { + type Type = HdlOption; + type ValueCategory = T::ValueCategory; + + fn ty(&self) -> Self::Type { + StaticType::TYPE + } +} + +impl> ToSimValueWithType> for Option { + #[hdl] + fn to_sim_value_with_type(&self, ty: HdlOption) -> SimValue> { + match self { + Some(v) => + { + #[hdl(sim)] + ty.HdlSome(v) + } + None => + { + #[hdl(sim)] + ty.HdlNone() + } + } + } + #[hdl] + fn into_sim_value_with_type(self, ty: HdlOption) -> SimValue> { + match self { + Some(v) => + { + #[hdl(sim)] + ty.HdlSome(v) + } + None => + { + #[hdl(sim)] + ty.HdlNone() + } + } + } +} + +impl>> ToSimValue for Option { + #[hdl] + fn to_sim_value(&self) -> SimValue { + match self { + Some(v) => + { + #[hdl(sim)] + HdlSome(v) + } + None => + { + #[hdl(sim)] + HdlNone() + } + } + } + #[hdl] + fn into_sim_value(self) -> SimValue { + match self { + Some(v) => + { + #[hdl(sim)] + HdlSome(v) + } + None => + { + #[hdl(sim)] + HdlNone() + } + } + } +} + +impl>> ToExpr for Option { + fn to_expr(&self) -> Expr { + match self { + Some(v) => HdlSome(v), + None => HdlNone(), + } + } +} + impl HdlOption { #[track_caller] pub fn try_map( diff --git a/crates/fayalite/src/expr.rs b/crates/fayalite/src/expr.rs index 00a0cee..e235cd7 100644 --- a/crates/fayalite/src/expr.rs +++ b/crates/fayalite/src/expr.rs @@ -17,7 +17,7 @@ use crate::{ reg::Reg, reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset}, sim::value::{SimValue, ToSimValue, ToSimValueWithType}, - ty::{CanonicalType, OpaqueSimValue, StaticType, Type, TypeWithDeref}, + ty::{CanonicalType, OpaqueSimValue, StaticType, TraceAsString, Type, TypeWithDeref}, util::{ConstBool, ConstUsize}, wire::Wire, }; @@ -218,6 +218,8 @@ expr_enum! { SliceSInt(ops::SliceSInt), CastToBits(ops::CastToBits), CastBitsTo(ops::CastBitsTo), + ToTraceAsString(ops::ToTraceAsString), + TraceAsStringAsInner(ops::TraceAsStringAsInner), ModuleIO(ModuleIO), Instance(Instance), Wire(Wire), @@ -389,6 +391,35 @@ impl Expr { __flow: this.__flow, } } + #[track_caller] + pub fn as_trace_as_string(this: Self, ty: TraceAsString) -> Expr> { + assert_eq!(this.ty(), ty.inner_ty()); + ops::ToTraceAsString::new(Expr::canonical(this), ty).to_expr() + } +} + +impl Expr { + pub fn unwrap_transparent_types(mut this: Self) -> Expr { + loop { + match this.ty() { + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Bool(_) + | CanonicalType::Array(_) + | CanonicalType::Enum(_) + | CanonicalType::Bundle(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) + | CanonicalType::PhantomConst(_) + | CanonicalType::DynSimOnly(_) => return this, + CanonicalType::TraceAsString(_) => { + this = *Expr::::from_canonical(this); + } + } + } + } } impl ToLiteralBits for Expr { @@ -1692,3 +1723,188 @@ impl<'a, T: Type> ToSimValueInner<'a> for &'a SimValue { Cow::Borrowed(&**this) } } + +pub trait ToTraceAsString: ValueType { + type Output: ValueType, ValueCategory = Self::ValueCategory>; + fn to_trace_as_string_with_ty(&self, ty: TraceAsString) -> Self::Output; + fn into_trace_as_string_with_ty(self, ty: TraceAsString) -> Self::Output + where + Self: Sized; + fn to_trace_as_string(&self) -> Self::Output; + fn into_trace_as_string(self) -> Self::Output + where + Self: Sized; +} + +impl< + T: ?Sized + + ValueType + + ToTraceAsStringImpl<::Type, ::ValueCategory>, +> ToTraceAsString for T +{ + type Output = T::ImplOutput; + fn to_trace_as_string_with_ty(&self, ty: TraceAsString) -> Self::Output { + Self::to_trace_as_string_with_ty_impl(self, ty) + } + fn into_trace_as_string_with_ty(self, ty: TraceAsString) -> Self::Output + where + Self: Sized, + { + Self::into_trace_as_string_with_ty_impl(self, ty) + } + fn to_trace_as_string(&self) -> Self::Output { + Self::to_trace_as_string_impl(self) + } + fn into_trace_as_string(self) -> Self::Output + where + Self: Sized, + { + Self::into_trace_as_string_impl(self) + } +} + +pub trait ToTraceAsStringImpl { + type ImplOutput: ValueType, ValueCategory = C>; + fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput; + fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput + where + Self: Sized; + fn to_trace_as_string_with_ty_impl(this: &Self, ty: TraceAsString) -> Self::ImplOutput; + fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString) -> Self::ImplOutput + where + Self: Sized; +} + +impl + ToTraceAsStringImpl for T +{ + type ImplOutput = crate::ty::TraceAsStringSimValue; + + fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput { + crate::ty::TraceAsStringSimValue::new(this) + } + + fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput + where + Self: Sized, + { + crate::ty::TraceAsStringSimValue::new(this) + } + + fn to_trace_as_string_with_ty_impl( + this: &Self, + ty: TraceAsString, + ) -> Self::ImplOutput { + crate::ty::TraceAsStringSimValue::new_with_ty(this, ty) + } + + fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString) -> Self::ImplOutput + where + Self: Sized, + { + crate::ty::TraceAsStringSimValue::new_with_ty(this, ty) + } +} + +impl + ToTraceAsStringImpl for T +{ + type ImplOutput = SimValue>; + + fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput { + crate::ty::TraceAsStringSimValue::new(this).into_sim_value() + } + + fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput + where + Self: Sized, + { + crate::ty::TraceAsStringSimValue::new(this).into_sim_value() + } + + fn to_trace_as_string_with_ty_impl( + this: &Self, + ty: TraceAsString, + ) -> Self::ImplOutput { + crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value() + } + + fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString) -> Self::ImplOutput + where + Self: Sized, + { + crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value() + } +} + +impl ToTraceAsStringImpl for T { + type ImplOutput = Expr>; + + fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput { + let this = this.to_expr(); + ops::ToTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr() + } + + fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput + where + Self: Sized, + { + let this = this.to_expr(); + ops::ToTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr() + } + + fn to_trace_as_string_with_ty_impl( + this: &Self, + ty: TraceAsString, + ) -> Self::ImplOutput { + let this = this.to_expr(); + ops::ToTraceAsString::new( + Expr::canonical(this), + ty.with_new_inner_ty(this.ty().intern_sized()), + ) + .to_expr() + } + + fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString) -> Self::ImplOutput + where + Self: Sized, + { + let this = this.to_expr(); + ops::ToTraceAsString::new( + Expr::canonical(this), + ty.with_new_inner_ty(this.ty().intern_sized()), + ) + .to_expr() + } +} + +impl ToTraceAsStringImpl + for T +{ + type ImplOutput = Valueless>; + + fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput { + Valueless::new(TraceAsString::new(this.ty())) + } + + fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput + where + Self: Sized, + { + Valueless::new(TraceAsString::new(this.ty())) + } + + fn to_trace_as_string_with_ty_impl( + this: &Self, + ty: TraceAsString, + ) -> Self::ImplOutput { + Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized())) + } + + fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString) -> Self::ImplOutput + where + Self: Sized, + { + Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized())) + } +} diff --git a/crates/fayalite/src/expr/ops.rs b/crates/fayalite/src/expr/ops.rs index f4cfebd..b2e20ad 100644 --- a/crates/fayalite/src/expr/ops.rs +++ b/crates/fayalite/src/expr/ops.rs @@ -12,7 +12,8 @@ use crate::{ ToExpr, ToLiteralBits, ToSimValueInner, ToValueless, ValueType, Valueless, target::{ GetTarget, Target, TargetPathArrayElement, TargetPathBundleField, - TargetPathDynArrayElement, TargetPathElement, + TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString, + TargetPathTraceAsStringInner, }, value_category::ValueCategoryExpr, }, @@ -27,7 +28,7 @@ use crate::{ ToSyncReset, }, sim::value::{SimValue, ToSimValue}, - ty::{CanonicalType, StaticType, Type}, + ty::{CanonicalType, StaticType, TraceAsString, Type}, util::ConstUsize, }; use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView}; @@ -44,6 +45,9 @@ use std::{ }, }; +#[cfg(test)] +mod test_ops_impls; + macro_rules! make_impls { ( $([$($args:tt)*])? @@ -583,9 +587,6 @@ macro_rules! make_impls { #[cfg(test)] pub(crate) use make_impls; -#[cfg(test)] -mod test_ops_impls; - macro_rules! impl_simple_binary_op_trait { ( [$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), @@ -4694,3 +4695,189 @@ impl, A> FromIterator for Expr { This::expr_from_iter(iter) } } + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct ToTraceAsString { + inner: Expr, + ty: TraceAsString, + literal_bits: Result, NotALiteralExpr>, + target: Option>, +} + +impl fmt::Debug for ToTraceAsString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + inner, + ty: _, + literal_bits: _, + target: _, + } = self; + f.debug_struct("ToTraceAsString") + .field("inner", inner) + .finish_non_exhaustive() + } +} + +impl ToTraceAsString { + pub fn new(inner: Expr, ty: TraceAsString) -> Self { + assert_eq!(inner.ty(), ty.inner_ty().canonical()); + let literal_bits = inner.to_literal_bits(); + let target = inner.target().map(|base| { + Intern::intern_sized( + base.join(TargetPathElement::intern_sized( + TargetPathToTraceAsString { + ty: ty.canonical_trace_as_string(), + } + .into(), + )) + .canonicalized(), + ) + }); + Self { + inner, + ty, + literal_bits, + target, + } + } + pub fn inner(self) -> Expr { + self.inner + } +} + +impl GetTarget for ToTraceAsString { + fn target(&self) -> Option> { + self.target + } +} + +impl ToLiteralBits for ToTraceAsString { + fn to_literal_bits(&self) -> Result, NotALiteralExpr> { + self.literal_bits + } +} + +impl ValueType for ToTraceAsString { + type Type = TraceAsString; + type ValueCategory = ValueCategoryExpr; + + fn ty(&self) -> Self::Type { + self.ty + } +} + +impl ToExpr for ToTraceAsString { + fn to_expr(&self) -> Expr { + Expr { + __enum: ExprEnum::ToTraceAsString(ToTraceAsString { + inner: self.inner, + ty: self.ty.canonical_trace_as_string(), + literal_bits: self.literal_bits, + target: self.target, + }) + .intern(), + __ty: self.ty, + __flow: Expr::flow(self.inner), + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct TraceAsStringAsInner { + arg: Expr>, + ty: T, + literal_bits: Result, NotALiteralExpr>, + target: Option>, +} + +impl fmt::Debug for TraceAsStringAsInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + arg, + ty: _, + literal_bits: _, + target: _, + } = self; + f.debug_struct("TraceAsStringAsInner") + .field("arg", arg) + .finish_non_exhaustive() + } +} + +impl TraceAsStringAsInner { + pub fn from_arg_and_ty(arg: Expr>, ty: T) -> Self { + assert_eq!(arg.ty().inner_ty(), ty.canonical()); + let literal_bits = arg.to_literal_bits(); + let target = arg.target().map(|base| { + Intern::intern_sized( + base.join(TargetPathElement::intern_sized( + TargetPathTraceAsStringInner {}.into(), + )) + .canonicalized(), + ) + }); + Self { + arg, + ty, + literal_bits, + target, + } + } + pub fn new(arg: Expr>) -> Self { + Self::from_arg_and_ty( + Expr { + __enum: arg.__enum, + __ty: arg.__ty.canonical_trace_as_string(), + __flow: arg.__flow, + }, + arg.ty().inner_ty(), + ) + } + pub fn arg(self) -> Expr> { + self.arg + } + pub fn arg_typed(self) -> Expr> { + Expr { + __enum: self.arg.__enum, + __ty: TraceAsString::from_canonical_trace_as_string(self.arg.__ty), + __flow: self.arg.__flow, + } + } +} + +impl GetTarget for TraceAsStringAsInner { + fn target(&self) -> Option> { + self.target + } +} + +impl ToLiteralBits for TraceAsStringAsInner { + fn to_literal_bits(&self) -> Result, NotALiteralExpr> { + self.literal_bits + } +} + +impl ValueType for TraceAsStringAsInner { + type Type = T; + type ValueCategory = ValueCategoryExpr; + + fn ty(&self) -> Self::Type { + self.ty + } +} + +impl ToExpr for TraceAsStringAsInner { + fn to_expr(&self) -> Expr { + Expr { + __enum: ExprEnum::TraceAsStringAsInner(TraceAsStringAsInner { + arg: self.arg, + ty: self.ty.canonical(), + literal_bits: self.literal_bits, + target: self.target, + }) + .intern(), + __ty: self.ty, + __flow: Expr::flow(self.arg), + } + } +} diff --git a/crates/fayalite/src/expr/target.rs b/crates/fayalite/src/expr/target.rs index 95d8e0f..9016111 100644 --- a/crates/fayalite/src/expr/target.rs +++ b/crates/fayalite/src/expr/target.rs @@ -10,7 +10,7 @@ use crate::{ reg::Reg, reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset}, source_location::SourceLocation, - ty::{CanonicalType, Type}, + ty::{CanonicalType, TraceAsString, Type}, wire::Wire, }; use std::fmt; @@ -46,11 +46,33 @@ impl fmt::Display for TargetPathDynArrayElement { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct TargetPathTraceAsStringInner {} + +impl fmt::Display for TargetPathTraceAsStringInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, ".") + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct TargetPathToTraceAsString { + pub ty: TraceAsString, +} + +impl fmt::Display for TargetPathToTraceAsString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, ".to_trace_as_string(...)") + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum TargetPathElement { BundleField(TargetPathBundleField), ArrayElement(TargetPathArrayElement), DynArrayElement(TargetPathDynArrayElement), + TraceAsStringInner(TargetPathTraceAsStringInner), + ToTraceAsString(TargetPathToTraceAsString), } impl From for TargetPathElement { @@ -71,12 +93,26 @@ impl From for TargetPathElement { } } +impl From for TargetPathElement { + fn from(value: TargetPathTraceAsStringInner) -> Self { + Self::TraceAsStringInner(value) + } +} + +impl From for TargetPathElement { + fn from(value: TargetPathToTraceAsString) -> Self { + Self::ToTraceAsString(value) + } +} + impl fmt::Display for TargetPathElement { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::BundleField(v) => v.fmt(f), Self::ArrayElement(v) => v.fmt(f), Self::DynArrayElement(v) => v.fmt(f), + Self::TraceAsStringInner(v) => v.fmt(f), + Self::ToTraceAsString(v) => v.fmt(f), } } } @@ -100,6 +136,15 @@ impl TargetPathElement { let parent_ty = Array::::from_canonical(parent.canonical_ty()); parent_ty.element() } + Self::TraceAsStringInner(_) => { + let parent_ty = + TraceAsString::::from_canonical(parent.canonical_ty()); + parent_ty.inner_ty() + } + &Self::ToTraceAsString(TargetPathToTraceAsString { ty }) => { + assert_eq!(parent.canonical_ty(), ty.inner_ty()); + ty.canonical() + } } } pub fn flow(&self, parent: Interned) -> Flow { @@ -111,13 +156,18 @@ impl TargetPathElement { .expect("field name is known to be a valid field of parent type"); parent.flow().flip_if(field.flipped) } - Self::ArrayElement(_) => parent.flow(), - Self::DynArrayElement(_) => parent.flow(), + Self::ArrayElement(_) + | Self::DynArrayElement(_) + | Self::TraceAsStringInner(_) + | Self::ToTraceAsString(_) => parent.flow(), } } pub fn is_static(&self) -> bool { match self { - Self::BundleField(_) | Self::ArrayElement(_) => true, + Self::BundleField(_) + | Self::ArrayElement(_) + | Self::TraceAsStringInner(_) + | Self::ToTraceAsString(_) => true, Self::DynArrayElement(_) => false, } } @@ -314,6 +364,7 @@ pub struct TargetChild { path_element: Interned, canonical_ty: CanonicalType, flow: Flow, + canonicalized_if_different: Option>, } impl fmt::Debug for TargetChild { @@ -323,6 +374,7 @@ impl fmt::Debug for TargetChild { path_element, canonical_ty: _, flow: _, + canonicalized_if_different: _, } = self; parent.fmt(f)?; fmt::Display::fmt(path_element, f) @@ -336,6 +388,7 @@ impl fmt::Display for TargetChild { path_element, canonical_ty: _, flow: _, + canonicalized_if_different: _, } = self; parent.fmt(f)?; path_element.fmt(f) @@ -343,14 +396,69 @@ impl fmt::Display for TargetChild { } impl TargetChild { - pub fn new(parent: Interned, path_element: Interned) -> Self { + fn new_helper( + parent: Interned, + path_element: Interned, + canonicalized_if_different: Option>, + ) -> Self { Self { parent, path_element, canonical_ty: path_element.canonical_ty(parent), flow: path_element.flow(parent), + canonicalized_if_different, } } + fn make_canonicalized_if_different( + parent: Interned, + path_element: Interned, + ) -> Option> { + use TargetPathElement::*; + match *path_element { + BundleField(_) => {} + ArrayElement(_) => {} + DynArrayElement(_) => {} + TraceAsStringInner(_) => { + if let Some(child) = parent.canonicalized().child() { + match *child.path_element() { + BundleField(_) + | ArrayElement(_) + | DynArrayElement(_) + | TraceAsStringInner(_) => {} + ToTraceAsString(_) => return Some(child.parent()), + } + } + } + ToTraceAsString(TargetPathToTraceAsString { ty }) => { + if let Some(child) = parent.canonicalized().child() { + match *child.path_element() { + BundleField(_) | ArrayElement(_) | DynArrayElement(_) + | ToTraceAsString(_) => {} + TraceAsStringInner(_) => { + if ty.canonical() == child.parent().canonical_ty() { + return Some(child.parent()); + } + } + } + } + } + } + Some( + Target::Child(Self::new_helper( + parent.canonicalized_if_different()?, + path_element, + None, + )) + .intern_sized(), + ) + } + pub fn new(parent: Interned, path_element: Interned) -> Self { + Self::new_helper( + parent, + path_element, + Self::make_canonicalized_if_different(parent, path_element), + ) + } pub fn parent(self) -> Interned { self.parent } @@ -363,6 +471,19 @@ impl TargetChild { pub fn flow(self) -> Flow { self.flow } + pub fn is_canonicalized(self) -> bool { + self.canonicalized_if_different.is_none() + } + pub fn canonicalized_if_different(self) -> Option> { + self.canonicalized_if_different + } + #[must_use] + pub fn canonicalized(self) -> Target { + match self.canonicalized_if_different { + Some(v) => *v, + None => Target::Child(self), + } + } pub fn bundle_field(self) -> Option { if let TargetPathElement::BundleField(TargetPathBundleField { name }) = *self.path_element { let parent_ty = Bundle::from_canonical(self.parent.canonical_ty()); @@ -443,6 +564,82 @@ impl Target { Target::Child(v) => v.canonical_ty(), } } + pub fn is_canonicalized(self) -> bool { + match self { + Self::Base(_) => true, + Self::Child(child) => child.is_canonicalized(), + } + } + pub fn canonicalized_if_different(self) -> Option> { + match self { + Self::Base(_) => None, + Self::Child(child) => child.canonicalized_if_different(), + } + } + #[must_use] + pub fn canonicalized(self) -> Target { + match self.canonicalized_if_different() { + Some(v) => *v, + None => self, + } + } + #[must_use] + pub fn canonicalized_interned(this: Interned) -> Interned { + this.canonicalized_if_different().unwrap_or(this) + } + #[must_use] + pub fn unwrap_transparent_types(mut self) -> Target { + loop { + self = self.canonicalized(); + match self.canonical_ty() { + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Bool(_) + | CanonicalType::Array(_) + | CanonicalType::Enum(_) + | CanonicalType::Bundle(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) + | CanonicalType::PhantomConst(_) + | CanonicalType::DynSimOnly(_) => return self, + CanonicalType::TraceAsString(_) => { + if let Self::Child(child) = self + && let TargetPathElement::ToTraceAsString(_) = *child.path_element() + { + self = *child.parent(); + } else { + self = self.join(TargetPathElement::intern_sized( + TargetPathTraceAsStringInner {}.into(), + )); + } + } + } + } + } + #[must_use] + pub fn unwrap_transparent_types_interned(this: Interned) -> Interned { + let retval = this.unwrap_transparent_types(); + if retval != *this { + retval.intern_sized() + } else { + this + } + } + #[must_use] + pub fn without_trailing_transparent_path_elements(mut self) -> Target { + use TargetPathElement::*; + loop { + match self { + Self::Base(_) => return self, + Self::Child(child) => match *child.path_element() { + BundleField(_) | ArrayElement(_) | DynArrayElement(_) => return self, + TraceAsStringInner(_) | ToTraceAsString(_) => self = *child.parent(), + }, + } + } + } } impl fmt::Display for Target { diff --git a/crates/fayalite/src/firrtl.rs b/crates/fayalite/src/firrtl.rs index 383bd95..51aa040 100644 --- a/crates/fayalite/src/firrtl.rs +++ b/crates/fayalite/src/firrtl.rs @@ -16,6 +16,7 @@ use crate::{ ops::{self, VariantAccess}, target::{ Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, + TargetPathTraceAsStringInner, }, }, formal::FormalKind, @@ -471,7 +472,7 @@ impl TypeState { Ok(self.enum_def(ty)?.1.variants.borrow_mut().get(name)) } fn ty(&self, ty: T) -> Result { - Ok(match ty.canonical() { + Ok(match ty.canonical().unwrap_transparent_types() { CanonicalType::Bundle(ty) => self.bundle_ty(ty)?.to_string(), CanonicalType::Enum(ty) => self.enum_ty(ty)?.to_string(), CanonicalType::Array(ty) => { @@ -490,6 +491,7 @@ impl TypeState { CanonicalType::DynSimOnly(_) => { return Err(FirrtlError::SimOnlyValuesAreNotPermitted); } + CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"), }) } } @@ -1191,7 +1193,7 @@ impl<'a> Exporter<'a> { definitions: &RcDefinitions, extra_indent: Indent<'_>, ) -> Result { - match ty { + match ty.unwrap_transparent_types() { CanonicalType::Bundle(ty) => { self.expr_cast_bundle_to_bits(value_str, ty, definitions, extra_indent) } @@ -1210,6 +1212,7 @@ impl<'a> Exporter<'a> { | CanonicalType::Reset(_) => Ok(format!("asUInt({value_str})")), CanonicalType::PhantomConst(_) => Ok("UInt<0>(0)".into()), CanonicalType::DynSimOnly(_) => Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()), + CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"), } } fn expr_cast_bits_to_bundle( @@ -1407,7 +1410,7 @@ impl<'a> Exporter<'a> { definitions: &RcDefinitions, extra_indent: Indent<'_>, ) -> Result { - match ty { + match ty.unwrap_transparent_types() { CanonicalType::Bundle(ty) => { self.expr_cast_bits_to_bundle(value_str, ty, definitions, extra_indent) } @@ -1431,6 +1434,7 @@ impl<'a> Exporter<'a> { return Ok(retval.to_string()); } CanonicalType::DynSimOnly(_) => Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()), + CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"), } } fn expr_unary( @@ -1798,6 +1802,10 @@ impl<'a> Exporter<'a> { write!(out, "[{index}]").unwrap(); Ok(out) } + ExprEnum::ToTraceAsString(expr) => self.expr(expr.inner(), definitions, const_ty), + ExprEnum::TraceAsStringAsInner(expr) => { + self.expr(Expr::canonical(expr.arg()), definitions, const_ty) + } ExprEnum::ModuleIO(expr) => Ok(self.module.ns.get(expr.name_id()).to_string()), ExprEnum::Instance(expr) => { assert!(!const_ty, "not a constant"); @@ -1957,6 +1965,10 @@ impl<'a> Exporter<'a> { .segments .push(AnnotationTargetRefSegment::Index { index }), TargetPathElement::DynArrayElement(_) => unreachable!(), + TargetPathElement::ToTraceAsString(_) + | TargetPathElement::TraceAsStringInner(_) => { + // ignored + } } Ok(retval) } @@ -3211,6 +3223,8 @@ impl ScalarizeTreeNode { TargetPathElement::DynArrayElement(_) => { unreachable!("annotations are only on static targets"); } + TargetPathElement::ToTraceAsString(_) + | TargetPathElement::TraceAsStringInner(_) => parent, } } } @@ -3337,6 +3351,13 @@ impl ScalarizeTreeBuilder { CanonicalType::DynSimOnly(_) => { return Err(ScalarizedModuleABIError::SimOnlyValuesAreNotPermitted); } + CanonicalType::TraceAsString(_) => self.build( + target + .join(TargetPathElement::intern_sized( + TargetPathTraceAsStringInner {}.into(), + )) + .intern_sized(), + )?, }) } } diff --git a/crates/fayalite/src/int.rs b/crates/fayalite/src/int.rs index c461306..15f8ed1 100644 --- a/crates/fayalite/src/int.rs +++ b/crates/fayalite/src/int.rs @@ -15,8 +15,8 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, FillInDefaultedGenerics, OpaqueSimValueSize, OpaqueSimValueSlice, - OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type, TypeProperties, - impl_match_variant_as_self, + OpaqueSimValueWriter, OpaqueSimValueWritten, SimValueDebug, SimValueDisplay, StaticType, + Type, TypeProperties, impl_match_variant_as_self, }, util::{ConstBool, ConstUsize, GenericConstBool, GenericConstUsize, interned_bit, slice_range}, }; @@ -1019,6 +1019,24 @@ macro_rules! impl_int { } } + impl SimValueDebug for $name { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } + } + + impl SimValueDisplay for $name { + fn sim_value_display( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Display::fmt(value, f) + } + } + impl Default for $name { fn default() -> Self { Self::TYPE @@ -1259,6 +1277,9 @@ macro_rules! impl_int { pub fn bitvec_mut(&mut self) -> &mut BitVec { Arc::make_mut(&mut self.bits) } + pub fn arc_bitvec_mut(&mut self) -> &mut Arc { + &mut self.bits + } } }; } @@ -1899,6 +1920,15 @@ impl Type for Bool { } } +impl SimValueDebug for Bool { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl StaticType for Bool { const TYPE: Self = Bool; const MASK_TYPE: Self::MaskType = Bool; diff --git a/crates/fayalite/src/int/uint_in_range.rs b/crates/fayalite/src/int/uint_in_range.rs index acf2fec..edf2e25 100644 --- a/crates/fayalite/src/int/uint_in_range.rs +++ b/crates/fayalite/src/int/uint_in_range.rs @@ -14,7 +14,7 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, - StaticType, Type, TypeProperties, impl_match_variant_as_self, + SimValueDebug, StaticType, Type, TypeProperties, impl_match_variant_as_self, }, }; use bitvec::{order::Lsb0, view::BitView}; @@ -94,6 +94,15 @@ impl Type for UIntInRangeMaskType { } } +impl SimValueDebug for UIntInRangeMaskType { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl BundleType for UIntInRangeMaskType { type Builder = NoBuilder; @@ -339,6 +348,15 @@ macro_rules! define_uint_in_range_type { } } + impl SimValueDebug for $UIntInRangeType { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } + } + impl fmt::Debug for $UIntInRangeType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { value, range } = self; diff --git a/crates/fayalite/src/memory.rs b/crates/fayalite/src/memory.rs index 83e7437..b3af13c 100644 --- a/crates/fayalite/src/memory.rs +++ b/crates/fayalite/src/memory.rs @@ -1093,6 +1093,7 @@ pub fn splat_mask(ty: T, value: Expr) -> Expr> { .to_expr(), )), CanonicalType::PhantomConst(_) => Expr::from_canonical(Expr::canonical(().to_expr())), + CanonicalType::TraceAsString(ty) => Expr::from_canonical(splat_mask(ty.inner_ty(), value)), } } diff --git a/crates/fayalite/src/module.rs b/crates/fayalite/src/module.rs index d959182..816a286 100644 --- a/crates/fayalite/src/module.rs +++ b/crates/fayalite/src/module.rs @@ -1111,7 +1111,10 @@ fn validate_clock_for_past( let mut target = clock_for_past; while let Target::Child(child) = target { match *child.path_element() { - TargetPathElement::BundleField(_) | TargetPathElement::ArrayElement(_) => {} + TargetPathElement::BundleField(_) + | TargetPathElement::ArrayElement(_) + | TargetPathElement::ToTraceAsString(_) + | TargetPathElement::TraceAsStringInner(_) => {} TargetPathElement::DynArrayElement(_) => { panic!( "clock_for_past: clock must be a static target (you can't use `Expr` array indexes):\n{clock_for_past:?}" @@ -1535,6 +1538,7 @@ impl TargetState { } } fn new(target: Interned, declared_in_block: usize) -> Self { + let target = Target::unwrap_transparent_types_interned(target); Self { target, inner: match target.canonical_ty() { @@ -1586,6 +1590,9 @@ impl TargetState { declared_in_block, written_in_blocks: RefCell::default(), }, + CanonicalType::TraceAsString(_) => { + unreachable!("handled by Target::unwrap_transparent_types_interned") + } }, } } @@ -1605,44 +1612,59 @@ impl AssertValidityState { } fn get_target_states<'a>( &'a self, - target: &Target, + target: Target, process_target_state: &dyn Fn(&'a TargetState, bool), ) -> Result<(), ()> { - match target { - Target::Base(target_base) => { - let target_state = self.get_base_state(*target_base)?; - process_target_state(target_state, false); - Ok(()) - } - Target::Child(target_child) => self.get_target_states( - &target_child.parent(), - &|target_state, exact_target_unknown| { - let TargetStateInner::Decomposed { subtargets } = &target_state.inner else { - unreachable!( - "TargetState::new makes TargetState tree match the Target type" - ); - }; - match *target_child.path_element() { - TargetPathElement::BundleField(_) => process_target_state( - subtargets - .get(&target_child.path_element()) - .expect("bundle fields filled in by TargetState::new"), - exact_target_unknown, - ), - TargetPathElement::ArrayElement(_) => process_target_state( - subtargets - .get(&target_child.path_element()) - .expect("array elements filled in by TargetState::new"), - exact_target_unknown, - ), - TargetPathElement::DynArrayElement(_) => { - for target_state in subtargets.values() { - process_target_state(target_state, true); + let mut target = target.unwrap_transparent_types(); + loop { + break match target { + Target::Base(target_base) => { + let target_state = self.get_base_state(target_base)?; + process_target_state(target_state, false); + Ok(()) + } + Target::Child(target_child) => match *target_child.path_element() { + TargetPathElement::BundleField(_) + | TargetPathElement::ArrayElement(_) + | TargetPathElement::DynArrayElement(_) => self.get_target_states( + *target_child.parent(), + &|target_state, exact_target_unknown| { + let TargetStateInner::Decomposed { subtargets } = &target_state.inner + else { + unreachable!( + "TargetState::new makes TargetState tree match the Target type" + ); + }; + match *target_child.path_element() { + TargetPathElement::BundleField(_) => process_target_state( + subtargets + .get(&target_child.path_element()) + .expect("bundle fields filled in by TargetState::new"), + exact_target_unknown, + ), + TargetPathElement::ArrayElement(_) => process_target_state( + subtargets + .get(&target_child.path_element()) + .expect("array elements filled in by TargetState::new"), + exact_target_unknown, + ), + TargetPathElement::DynArrayElement(_) => { + for target_state in subtargets.values() { + process_target_state(target_state, true); + } + } + TargetPathElement::TraceAsStringInner(_) + | TargetPathElement::ToTraceAsString(_) => unreachable!(), } - } + }, + ), + TargetPathElement::TraceAsStringInner(_) + | TargetPathElement::ToTraceAsString(_) => { + target = *target_child.parent(); + continue; } }, - ), + }; } } fn get_base_state(&self, target_base: Interned) -> Result<&TargetState, ()> { @@ -1693,6 +1715,7 @@ impl AssertValidityState { &TargetPathElement::BundleField(_) => { let field = sub_target_state .target + .without_trailing_transparent_path_elements() .child() .expect("known to be a child") .bundle_field() @@ -1716,6 +1739,8 @@ impl AssertValidityState { TargetPathElement::DynArrayElement { .. } => { Self::set_connect_target_written(sub_target_state, is_lhs, block, true); } + TargetPathElement::TraceAsStringInner(_) + | TargetPathElement::ToTraceAsString(_) => unreachable!("never added"), } } } @@ -1733,7 +1758,7 @@ impl AssertValidityState { debug_assert!(!is_lhs, "the ModuleBuilder asserts lhs.target().is_some()"); return; }; - let result = self.get_target_states(&target, &|target_state, exact_target_unknown| { + let result = self.get_target_states(*target, &|target_state, exact_target_unknown| { Self::set_connect_target_written(target_state, is_lhs, block, exact_target_unknown); }); if result.is_err() { diff --git a/crates/fayalite/src/module/transform/deduce_resets.rs b/crates/fayalite/src/module/transform/deduce_resets.rs index 61167fd..4595e84 100644 --- a/crates/fayalite/src/module/transform/deduce_resets.rs +++ b/crates/fayalite/src/module/transform/deduce_resets.rs @@ -10,7 +10,8 @@ use crate::{ ops::{self, ArrayLiteral}, target::{ Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField, - TargetPathDynArrayElement, TargetPathElement, + TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString, + TargetPathTraceAsStringInner, }, }, formal::FormalKind, @@ -26,6 +27,7 @@ use crate::{ prelude::*, reset::{ResetType, ResetTypeDispatch}, sim::ExternModuleSimulation, + ty::TraceAsString, util::{HashMap, HashSet}, }; use hashbrown::hash_map::Entry; @@ -103,6 +105,10 @@ enum ResetsLayout { element: Interned, reset_count: usize, }, + Transparent { + inner: Interned, + reset_count: usize, + }, } impl ResetsLayout { @@ -112,7 +118,8 @@ impl ResetsLayout { ResetsLayout::Reset | ResetsLayout::SyncReset | ResetsLayout::AsyncReset => 1, ResetsLayout::Bundle { reset_count, .. } | ResetsLayout::Enum { reset_count, .. } - | ResetsLayout::Array { reset_count, .. } => reset_count, + | ResetsLayout::Array { reset_count, .. } + | ResetsLayout::Transparent { reset_count, .. } => reset_count, } } fn new(ty: CanonicalType) -> Self { @@ -166,6 +173,13 @@ impl ResetsLayout { CanonicalType::Clock(_) => ResetsLayout::NoResets, CanonicalType::PhantomConst(_) => ResetsLayout::NoResets, CanonicalType::DynSimOnly(_) => ResetsLayout::NoResets, + CanonicalType::TraceAsString(ty) => { + let inner = ResetsLayout::new(ty.inner_ty()).intern_sized(); + ResetsLayout::Transparent { + inner, + reset_count: inner.reset_count(), + } + } } } } @@ -315,6 +329,12 @@ impl ResetGraph { } => { self.append_new_nodes_for_layout(*element, node_indexes, source_location); } + ResetsLayout::Transparent { + inner, + reset_count: _, + } => { + self.append_new_nodes_for_layout(*inner, node_indexes, source_location); + } } } } @@ -357,6 +377,21 @@ impl Resets { node_indexes: self.node_indexes, } } + fn trace_as_string_inner(self) -> Self { + let trace_as_string = TraceAsString::from_canonical(self.ty); + let ResetsLayout::Transparent { + inner, + reset_count: _, + } = self.layout + else { + unreachable!(); + }; + Self { + ty: trace_as_string.inner_ty(), + layout: *inner, + node_indexes: self.node_indexes, + } + } fn bundle_fields(self) -> impl Iterator { let bundle = Bundle::from_canonical(self.ty); let ResetsLayout::Bundle { @@ -480,6 +515,17 @@ impl Resets { CanonicalType::SyncReset(SyncReset) }, ), + CanonicalType::TraceAsString(ty) => Ok(CanonicalType::TraceAsString( + ty.with_new_inner_ty( + self.array_elements() + .substituted_type( + reset_graph, + fallback_to_sync_reset, + fallback_error_source_location, + )? + .intern_sized(), + ), + )), } } } @@ -1013,7 +1059,8 @@ fn cast_bit_op( | CanonicalType::Bundle(_) | CanonicalType::Reset(_) | CanonicalType::PhantomConst(_) - | CanonicalType::DynSimOnly(_) => unreachable!(), + | CanonicalType::DynSimOnly(_) + | CanonicalType::TraceAsString(_) => unreachable!(), $(CanonicalType::$Variant(ty) => Expr::expr_enum($arg.cast_to(ty)),)* } }; @@ -1024,7 +1071,8 @@ fn cast_bit_op( CanonicalType::Array(_) | CanonicalType::Enum(_) | CanonicalType::Bundle(_) - | CanonicalType::Reset(_) => unreachable!(), + | CanonicalType::Reset(_) + | CanonicalType::TraceAsString(_) => unreachable!(), CanonicalType::PhantomConst(_) | CanonicalType::DynSimOnly(_) => Expr::expr_enum(arg), $(CanonicalType::$Variant(_) => { @@ -1156,6 +1204,10 @@ impl RunPass

for ExprEnum { ExprEnum::SliceSInt(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::CastToBits(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::CastBitsTo(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), + ExprEnum::TraceAsStringAsInner(expr) => { + Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)) + } + ExprEnum::ToTraceAsString(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::ModuleIO(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::Instance(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::Wire(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), @@ -1536,6 +1588,67 @@ impl RunPassExpr for ops::CastBitsTo { } } +impl RunPassExpr for ops::TraceAsStringAsInner { + type Args<'a> = [Expr; 1]; + + fn args<'a>(&'a self) -> Self::Args<'a> { + [Expr::canonical(self.arg())] + } + + fn source_location(&self) -> Option { + None + } + + fn union_parts( + &self, + resets: Resets, + args_resets: Vec, + mut pass_args: PassArgs<'_, BuildResetGraph>, + ) -> Result<(), DeduceResetsError> { + pass_args.union(resets, args_resets[0].trace_as_string_inner(), None) + } + + fn new( + &self, + _ty: CanonicalType, + new_args: Vec>, + ) -> Result { + Ok(Self::new(Expr::from_canonical(new_args[0]))) + } +} + +impl RunPassExpr for ops::ToTraceAsString { + type Args<'a> = [Expr; 1]; + + fn args<'a>(&'a self) -> Self::Args<'a> { + [Expr::canonical(self.inner())] + } + + fn source_location(&self) -> Option { + None + } + + fn union_parts( + &self, + resets: Resets, + args_resets: Vec, + mut pass_args: PassArgs<'_, BuildResetGraph>, + ) -> Result<(), DeduceResetsError> { + pass_args.union(resets.trace_as_string_inner(), args_resets[0], None) + } + + fn new( + &self, + _ty: CanonicalType, + new_args: Vec>, + ) -> Result { + Ok(Self::new( + new_args[0], + self.ty().with_new_inner_ty(new_args[0].ty().intern_sized()), + )) + } +} + impl RunPassExpr for ModuleIO { type Args<'a> = [Expr; 0]; @@ -1691,7 +1804,8 @@ impl RunPassDispatch for AnyReg { | CanonicalType::Reset(_) | CanonicalType::Clock(_) | CanonicalType::PhantomConst(_) - | CanonicalType::DynSimOnly(_) => unreachable!(), + | CanonicalType::DynSimOnly(_) + | CanonicalType::TraceAsString(_) => unreachable!(), } }) } @@ -2173,30 +2287,6 @@ impl RunPass

for StmtDeclaration { } } -impl_run_pass_for_struct! { - impl[] RunPass for TargetPathBundleField { - name: _, - } -} - -impl_run_pass_for_struct! { - impl[] RunPass for TargetPathArrayElement { - index: _, - } -} - -impl_run_pass_for_struct! { - impl[] RunPass for TargetPathDynArrayElement {} -} - -impl_run_pass_for_enum! { - impl[] RunPass for TargetPathElement { - BundleField(v), - ArrayElement(v), - DynArrayElement(v), - } -} - impl_run_pass_for_enum! { impl[] RunPass for Target { Base(v), @@ -2204,11 +2294,28 @@ impl_run_pass_for_enum! { } } -impl_run_pass_for_struct! { - #[constructor = TargetChild::new(parent, path_element)] - impl[] RunPass for TargetChild { - parent(): _, - path_element(): _, +impl RunPass

for TargetChild { + fn run_pass( + &self, + mut pass_args: PassArgs<'_, P>, + ) -> Result, DeduceResetsError> { + Ok(self.parent().run_pass(pass_args.as_mut())?.map(|parent| { + let path_element = match *self.path_element() { + TargetPathElement::BundleField(TargetPathBundleField { name: _ }) + | TargetPathElement::ArrayElement(TargetPathArrayElement { index: _ }) + | TargetPathElement::DynArrayElement(TargetPathDynArrayElement {}) + | TargetPathElement::TraceAsStringInner(TargetPathTraceAsStringInner {}) => { + self.path_element() + } + TargetPathElement::ToTraceAsString(TargetPathToTraceAsString { ty }) => { + TargetPathElement::from(TargetPathToTraceAsString { + ty: ty.with_new_inner_ty(parent.canonical_ty().intern_sized()), + }) + .intern_sized() + } + }; + TargetChild::new(parent, path_element) + })) } } diff --git a/crates/fayalite/src/module/transform/simplify_enums.rs b/crates/fayalite/src/module/transform/simplify_enums.rs index 8902921..5f136f2 100644 --- a/crates/fayalite/src/module/transform/simplify_enums.rs +++ b/crates/fayalite/src/module/transform/simplify_enums.rs @@ -17,7 +17,7 @@ use crate::{ transform::visit::{Fold, Folder}, }, source_location::SourceLocation, - ty::{CanonicalType, Type}, + ty::{CanonicalType, TraceAsString, Type}, util::HashMap, wire::Wire, }; @@ -64,6 +64,7 @@ fn contains_any_enum_types(ty: CanonicalType) -> bool { .fields() .iter() .any(|field| contains_any_enum_types(field.ty)), + CanonicalType::TraceAsString(ty) => contains_any_enum_types(ty.inner_ty()), CanonicalType::UInt(_) | CanonicalType::SInt(_) | CanonicalType::Bool(_) @@ -313,6 +314,24 @@ impl State { } Ok(()) } + fn handle_stmt_connect_trace_as_string( + &mut self, + unfolded_lhs_ty: TraceAsString, + unfolded_rhs_ty: TraceAsString, + folded_lhs: Expr, + folded_rhs: Expr, + source_location: SourceLocation, + output_stmts: &mut Vec, + ) -> Result<(), SimplifyEnumsError> { + self.handle_stmt_connect( + unfolded_lhs_ty.inner_ty(), + unfolded_rhs_ty.inner_ty(), + ops::TraceAsStringAsInner::new(folded_lhs).to_expr(), + ops::TraceAsStringAsInner::new(folded_rhs).to_expr(), + source_location, + output_stmts, + ) + } fn handle_stmt_connect_bundle( &mut self, unfolded_lhs_ty: Bundle, @@ -509,6 +528,15 @@ impl State { source_location, output_stmts, ), + CanonicalType::TraceAsString(unfolded_lhs_ty) => self + .handle_stmt_connect_trace_as_string( + unfolded_lhs_ty, + TraceAsString::from_canonical(unfolded_rhs_ty), + Expr::from_canonical(folded_lhs), + Expr::from_canonical(folded_rhs), + source_location, + output_stmts, + ), CanonicalType::UInt(_) | CanonicalType::SInt(_) | CanonicalType::Bool(_) @@ -528,6 +556,8 @@ fn connect_port( rhs: Expr, source_location: SourceLocation, ) { + let lhs = Expr::unwrap_transparent_types(lhs); + let rhs = Expr::unwrap_transparent_types(rhs); if lhs.ty() == rhs.ty() { stmts.push( StmtConnect { @@ -573,6 +603,9 @@ fn connect_port( connect_port(stmts, lhs[index], rhs[index], source_location); } } + (CanonicalType::TraceAsString(_), CanonicalType::TraceAsString(_)) => { + unreachable!("handled by unwrap_transparent_types") + } (CanonicalType::Bundle(_), _) | (CanonicalType::Enum(_), _) | (CanonicalType::Array(_), _) @@ -584,7 +617,8 @@ fn connect_port( | (CanonicalType::SyncReset(_), _) | (CanonicalType::Reset(_), _) | (CanonicalType::PhantomConst(_), _) - | (CanonicalType::DynSimOnly(_), _) => unreachable!( + | (CanonicalType::DynSimOnly(_), _) + | (CanonicalType::TraceAsString(_), _) => unreachable!( "trying to connect memory ports:\n{:?}\n{:?}", lhs.ty(), rhs.ty(), @@ -772,6 +806,8 @@ impl Folder for State { | ExprEnum::SliceSInt(_) | ExprEnum::CastToBits(_) | ExprEnum::CastBitsTo(_) + | ExprEnum::TraceAsStringAsInner(_) + | ExprEnum::ToTraceAsString(_) | ExprEnum::ModuleIO(_) | ExprEnum::Instance(_) | ExprEnum::Wire(_) @@ -936,7 +972,8 @@ impl Folder for State { | CanonicalType::SyncReset(_) | CanonicalType::Reset(_) | CanonicalType::PhantomConst(_) - | CanonicalType::DynSimOnly(_) => canonical_type.default_fold(self), + | CanonicalType::DynSimOnly(_) + | CanonicalType::TraceAsString(_) => canonical_type.default_fold(self), } } diff --git a/crates/fayalite/src/module/transform/simplify_memories.rs b/crates/fayalite/src/module/transform/simplify_memories.rs index d741836..4a97353 100644 --- a/crates/fayalite/src/module/transform/simplify_memories.rs +++ b/crates/fayalite/src/module/transform/simplify_memories.rs @@ -90,7 +90,7 @@ impl MemSplit { } } fn new(element_type: CanonicalType) -> Self { - match element_type { + match element_type.unwrap_transparent_types() { CanonicalType::Bundle(bundle_ty) => MemSplit::Bundle { fields: bundle_ty .fields() @@ -195,6 +195,7 @@ impl MemSplit { | CanonicalType::SyncReset(_) | CanonicalType::Reset(_) => unreachable!("memory element type is a storable type"), CanonicalType::DynSimOnly(_) => todo!("memory containing sim-only values"), + CanonicalType::TraceAsString(_) => unreachable!("handled by unwrap_transparent_types"), } } } @@ -306,7 +307,9 @@ impl SplitMemState<'_, '_> { let outer_mem_name_path_len = self.mem_name_path.len(); match self.split { MemSplit::Bundle { fields } => { - let CanonicalType::Bundle(bundle_type) = self.element_type else { + let CanonicalType::Bundle(bundle_type) = + self.element_type.unwrap_transparent_types() + else { unreachable!(); }; for ((field, field_offset), split) in bundle_type @@ -321,7 +324,10 @@ impl SplitMemState<'_, '_> { let field_ty_bit_width = field.ty.bit_width(); self.split_state_stack.push_map( |e: Expr| { - Expr::field(Expr::::from_canonical(e), &field.name) + Expr::field( + Expr::::from_canonical(Expr::unwrap_transparent_types(e)), + &field.name, + ) }, |initial_value_element| { let Some(field_offset) = field_offset.only_bit_width() else { @@ -377,8 +383,8 @@ impl SplitMemState<'_, '_> { }; self.output_stmts.push( StmtConnect { - lhs: Expr::field(port_expr, name), - rhs: Expr::field(wire_expr, name), + lhs: Expr::unwrap_transparent_types(Expr::field(port_expr, name)), + rhs: Expr::unwrap_transparent_types(Expr::field(wire_expr, name)), source_location: port.source_location(), } .into(), @@ -389,7 +395,8 @@ impl SplitMemState<'_, '_> { self.output_mems.push(new_mem); } MemSplit::Array { elements } => { - let CanonicalType::Array(array_type) = self.element_type else { + let CanonicalType::Array(array_type) = self.element_type.unwrap_transparent_types() + else { unreachable!(); }; let element_type = array_type.element(); @@ -398,7 +405,7 @@ impl SplitMemState<'_, '_> { self.mem_name_path.truncate(outer_mem_name_path_len); write!(self.mem_name_path, "_{index}").unwrap(); self.split_state_stack.push_map( - |e| Expr::::from_canonical(e)[index], + |e| Expr::::from_canonical(Expr::unwrap_transparent_types(e))[index], |initial_value_element| { &initial_value_element[index * element_bit_width..][..element_bit_width] }, @@ -464,7 +471,7 @@ impl ModuleState { assert_eq!(memory_element_array_range_len % input_array_type.len(), 0); let chunk_size = memory_element_array_range_len / input_array_type.len(); for index in 0..input_array_type.len() { - let map = |e| Expr::::from_canonical(e)[index]; + let map = |e| Expr::::from_canonical(Expr::unwrap_transparent_types(e))[index]; let wire_rdata = wire_rdata.map(map); let wire_wdata = wire_wdata.map(map); let wire_wmask = wire_wmask.map(map); @@ -505,8 +512,8 @@ impl ModuleState { port_read: Expr| { output_stmts.push( StmtConnect { - lhs: wire_read, - rhs: port_read, + lhs: Expr::unwrap_transparent_types(wire_read), + rhs: Expr::unwrap_transparent_types(port_read), source_location, } .into(), @@ -517,8 +524,8 @@ impl ModuleState { port_write: Expr| { output_stmts.push( StmtConnect { - lhs: port_write, - rhs: wire_write, + lhs: Expr::unwrap_transparent_types(port_write), + rhs: Expr::unwrap_transparent_types(wire_write), source_location, } .into(), @@ -530,7 +537,8 @@ impl ModuleState { connect_read( output_stmts, wire_read, - Expr::::from_canonical(port_read).cast_bits_to(wire_read.ty()), + Expr::::from_canonical(Expr::unwrap_transparent_types(port_read)) + .cast_bits_to(wire_read.ty()), ); }; let connect_write_enum = @@ -544,7 +552,7 @@ impl ModuleState { ); }; loop { - match input_element_type { + match input_element_type.unwrap_transparent_types() { CanonicalType::Bundle(_) => { unreachable!("bundle types are always split") } @@ -625,6 +633,9 @@ impl ModuleState { | CanonicalType::SyncReset(_) | CanonicalType::Reset(_) => unreachable!("memory element type is a storable type"), CanonicalType::DynSimOnly(_) => todo!("memory containing sim-only values"), + CanonicalType::TraceAsString(_) => { + unreachable!("handled by unwrap_transparent_types") + } } break; } diff --git a/crates/fayalite/src/module/transform/visit.rs b/crates/fayalite/src/module/transform/visit.rs index 2869a49..7b4cd2a 100644 --- a/crates/fayalite/src/module/transform/visit.rs +++ b/crates/fayalite/src/module/transform/visit.rs @@ -14,7 +14,8 @@ use crate::{ Expr, ExprEnum, ValueType, ops, target::{ Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField, - TargetPathDynArrayElement, TargetPathElement, + TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString, + TargetPathTraceAsStringInner, }, }, formal::FormalKind, @@ -32,7 +33,7 @@ use crate::{ reset::{AsyncReset, Reset, ResetType, SyncReset}, sim::{ExternModuleSimulation, value::DynSimOnly}, source_location::SourceLocation, - ty::{CanonicalType, Type}, + ty::{CanonicalType, TraceAsString, Type}, vendor::xilinx::{ XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation, }, diff --git a/crates/fayalite/src/phantom_const.rs b/crates/fayalite/src/phantom_const.rs index fb7be6f..ba85817 100644 --- a/crates/fayalite/src/phantom_const.rs +++ b/crates/fayalite/src/phantom_const.rs @@ -9,7 +9,7 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, - StaticType, Type, TypeProperties, impl_match_variant_as_self, + SimValueDebug, StaticType, Type, TypeProperties, impl_match_variant_as_self, serde_impls::{SerdeCanonicalType, SerdePhantomConst}, }, }; @@ -327,6 +327,15 @@ impl Type for PhantomConst { } } +impl SimValueDebug for PhantomConst { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl Default for PhantomConst where Interned: Default, diff --git a/crates/fayalite/src/prelude.rs b/crates/fayalite/src/prelude.rs index 4c5bfdf..42038ca 100644 --- a/crates/fayalite/src/prelude.rs +++ b/crates/fayalite/src/prelude.rs @@ -13,7 +13,7 @@ pub use crate::{ enum_::{Enum, HdlNone, HdlOption, HdlSome}, expr::{ CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr, - ReduceBits, ToExpr, ValueType, repeat, + ReduceBits, ToExpr, ToTraceAsString, ValueType, repeat, }, formal::{ MakeFormalExpr, all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset, @@ -38,7 +38,7 @@ pub use crate::{ }, source_location::SourceLocation, testing::{FormalMode, assert_formal}, - ty::{AsMask, CanonicalType, Type}, + ty::{AsMask, CanonicalType, TraceAsString, Type}, util::{ConstUsize, GenericConstUsize}, wire::Wire, }; diff --git a/crates/fayalite/src/reset.rs b/crates/fayalite/src/reset.rs index 13273ac..ddc3651 100644 --- a/crates/fayalite/src/reset.rs +++ b/crates/fayalite/src/reset.rs @@ -1,5 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information + use crate::{ clock::Clock, expr::{CastToImpl, Expr, ValueType}, @@ -8,11 +9,13 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter, - OpaqueSimValueWritten, StaticType, Type, TypeProperties, impl_match_variant_as_self, + OpaqueSimValueWritten, SimValueDebug, StaticType, Type, TypeProperties, + impl_match_variant_as_self, }, util::ConstUsize, }; use bitvec::{bits, order::Lsb0}; +use std::fmt; mod sealed { pub trait ResetTypeSealed {} @@ -100,6 +103,15 @@ macro_rules! reset_type { } } + impl SimValueDebug for $name { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } + } + impl $name { pub fn type_properties(self) -> TypeProperties { Self::TYPE_PROPERTIES diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 45691ea..1247fd8 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -9,6 +9,7 @@ use crate::{ Flow, target::{ GetTarget, Target, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, + TargetPathTraceAsStringInner, }, }, int::BoolOrIntType, @@ -38,7 +39,7 @@ use crate::{ }, ty::{ OpaqueSimValue, OpaqueSimValueSize, OpaqueSimValueSizeRange, OpaqueSimValueSlice, - OpaqueSimValueWriter, + OpaqueSimValueWriter, TraceAsString, }, util::{BitSliceWriteWithBase, DebugAsDisplay, HashMap, HashSet, copy_le_bytes_to_bitslice}, }; @@ -432,6 +433,15 @@ impl_trace_decl! { ty: DynSimOnly, flow: Flow, }), + TraceAsString(TraceTraceAsString { + fn location(self) -> _ { + self.location + } + location: TraceLocation, + name: Interned, + ty: TraceAsString, + flow: Flow, + }), }), } @@ -543,6 +553,7 @@ pub trait TraceWriter: fmt::Debug + 'static { id: TraceScalarId, value: &DynSimOnlyValue, ) -> Result<(), Self::Error>; + fn set_signal_string(&mut self, id: TraceScalarId, value: &str) -> Result<(), Self::Error>; } pub struct DynTraceWriterDecls(Box); @@ -607,6 +618,7 @@ trait TraceWriterDynTrait: fmt::Debug + 'static { id: TraceScalarId, value: &DynSimOnlyValue, ) -> std::io::Result<()>; + fn set_signal_string_dyn(&mut self, id: TraceScalarId, value: &str) -> std::io::Result<()>; } impl TraceWriterDynTrait for T { @@ -680,6 +692,9 @@ impl TraceWriterDynTrait for T { ) -> std::io::Result<()> { Ok(TraceWriter::set_signal_sim_only_value(self, id, value).map_err(err_into_io)?) } + fn set_signal_string_dyn(&mut self, id: TraceScalarId, value: &str) -> std::io::Result<()> { + Ok(TraceWriter::set_signal_string(self, id, value).map_err(err_into_io)?) + } } pub struct DynTraceWriter(Box); @@ -758,6 +773,9 @@ impl TraceWriter for DynTraceWriter { ) -> Result<(), Self::Error> { self.0.set_signal_sim_only_value_dyn(id, value) } + fn set_signal_string(&mut self, id: TraceScalarId, value: &str) -> Result<(), Self::Error> { + self.0.set_signal_string_dyn(id, value) + } } #[derive(Debug)] @@ -828,6 +846,7 @@ where #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub(crate) struct SimTrace { kind: K, + maybe_changed: bool, state: S, last_state: S, } @@ -848,12 +867,14 @@ impl SimTraceDebug for SimTrace { fn fmt(&self, id: TraceScalarId, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { kind, + maybe_changed, state, last_state, } = self; f.debug_struct("SimTrace") .field("id", &id) .field("kind", kind) + .field("maybe_changed", maybe_changed) .field("state", state) .field("last_state", last_state) .finish() @@ -864,12 +885,14 @@ impl SimTraceDebug for SimTrace fn fmt(&self, id: TraceScalarId, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { kind, + maybe_changed, state, last_state, } = self; f.debug_struct("SimTrace") .field("id", &id) .field("kind", kind) + .field("maybe_changed", maybe_changed) .field("state", state) .field("last_state", last_state) .finish() @@ -929,6 +952,10 @@ pub(crate) enum SimTraceKind { PhantomConst { ty: PhantomConst, }, + TraceAsString { + layout: compiler::CompiledTypeLayout, + range: TypeIndexRange, + }, } #[derive(PartialEq, Eq)] @@ -936,6 +963,7 @@ pub(crate) enum SimTraceState { Bits(BitVec), SimOnly(DynSimOnlyValue), PhantomConst, + OpaqueSimValue(OpaqueSimValue), } impl Clone for SimTraceState { @@ -944,6 +972,7 @@ impl Clone for SimTraceState { Self::Bits(v) => Self::Bits(v.clone()), Self::SimOnly(v) => Self::SimOnly(v.clone()), Self::PhantomConst => Self::PhantomConst, + Self::OpaqueSimValue(v) => Self::OpaqueSimValue(v.clone()), } } fn clone_from(&mut self, source: &Self) { @@ -951,6 +980,9 @@ impl Clone for SimTraceState { (SimTraceState::Bits(dest), SimTraceState::Bits(source)) => { dest.clone_from_bitslice(source); } + (SimTraceState::OpaqueSimValue(dest), SimTraceState::OpaqueSimValue(source)) => { + dest.clone_from(source); + } _ => *self = source.clone(), } } @@ -985,6 +1017,20 @@ impl SimTraceState { unreachable!() } } + fn unwrap_opaque_sim_value_ref(&self) -> &OpaqueSimValue { + if let SimTraceState::OpaqueSimValue(v) = self { + v + } else { + unreachable!() + } + } + fn unwrap_opaque_sim_value_mut(&mut self) -> &mut OpaqueSimValue { + if let SimTraceState::OpaqueSimValue(v) = self { + v + } else { + unreachable!() + } + } } impl fmt::Debug for SimTraceState { @@ -993,6 +1039,7 @@ impl fmt::Debug for SimTraceState { SimTraceState::Bits(v) => BitSliceWriteWithBase(v).fmt(f), SimTraceState::SimOnly(v) => v.fmt(f), SimTraceState::PhantomConst => f.debug_tuple("PhantomConst").finish(), + SimTraceState::OpaqueSimValue(v) => v.fmt(f), } } } @@ -1021,6 +1068,13 @@ impl SimTraceKind { } SimTraceKind::PhantomConst { .. } => SimTraceState::PhantomConst, SimTraceKind::SimOnly { index: _, ty } => SimTraceState::SimOnly(ty.default_value()), + SimTraceKind::TraceAsString { layout, range: _ } => { + let type_properties = layout.ty.type_properties(); + SimTraceState::OpaqueSimValue(OpaqueSimValue::from_bits_and_sim_only_values( + UIntValue::new_dyn(Arc::new(BitVec::repeat(false, type_properties.bit_width))), + Vec::with_capacity(type_properties.sim_only_values_len), + )) + } } } } @@ -1175,6 +1229,31 @@ impl SimulationModuleState { true } } + CompiledTypeLayoutBody::Transparent { .. } => { + let value = value.map_ty(|ty| match ty { + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Bool(_) + | CanonicalType::Array(_) + | CanonicalType::Enum(_) + | CanonicalType::Bundle(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) + | CanonicalType::PhantomConst(_) + | CanonicalType::DynSimOnly(_) => unreachable!(), + CanonicalType::TraceAsString(ty) => ty, + }); + let sub_target = target + .join(TargetPathElement::from(TargetPathTraceAsStringInner {}).intern_sized()); + if self.parse_io(sub_target, value.inner()) { + self.uninitialized_ios.insert(target, vec![sub_target]); + true + } else { + false + } + } } } fn mark_target_as_initialized(&mut self, mut target: Target) { @@ -1225,7 +1304,10 @@ impl SimulationModuleState { Target::Base(_) => break, Target::Child(child) => { match *child.path_element() { - TargetPathElement::BundleField(_) | TargetPathElement::ArrayElement(_) => {} + TargetPathElement::BundleField(_) + | TargetPathElement::ArrayElement(_) + | TargetPathElement::TraceAsStringInner(_) + | TargetPathElement::ToTraceAsString(_) => {} TargetPathElement::DynArrayElement(_) => panic!( "simulator read/write expression must not have dynamic array indexes" ), @@ -1268,7 +1350,8 @@ impl SimulationModuleState { | CanonicalType::Reset(_) | CanonicalType::Clock(_) | CanonicalType::PhantomConst(_) - | CanonicalType::DynSimOnly(_) => unreachable!(), + | CanonicalType::DynSimOnly(_) + | CanonicalType::TraceAsString(_) => unreachable!(), CanonicalType::AsyncReset(_) => true, CanonicalType::SyncReset(_) => false, } @@ -1433,6 +1516,26 @@ impl SimulationExternModuleClockForPast { ); } } + CompiledTypeLayoutBody::Transparent { .. } => { + let map_ty_fn = |ty| match ty { + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Bool(_) + | CanonicalType::Array(_) + | CanonicalType::Enum(_) + | CanonicalType::Bundle(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) + | CanonicalType::PhantomConst(_) + | CanonicalType::DynSimOnly(_) => unreachable!(), + CanonicalType::TraceAsString(ty) => ty, + }; + let current = current.map_ty(map_ty_fn); + let past = past.map_ty(map_ty_fn); + self.add_current_to_past_mapping(current.inner(), past.inner()); + } } } } @@ -1901,6 +2004,7 @@ struct SimulationImpl { ), >, waiting_sensitivity_sets_by_address: HashMap<*const SensitivitySet, Rc>, + trace_as_string_buf: String, } impl fmt::Debug for SimulationImpl { @@ -1990,6 +2094,7 @@ impl SimulationImpl { next_sensitivity_set_debug_id: _, waiting_sensitivity_sets_by_compiled_value, waiting_sensitivity_sets_by_address, + trace_as_string_buf: _, } = self; f.debug_struct("Simulation") .field("state", state) @@ -2078,10 +2183,12 @@ impl SimulationImpl { traces: SimTraces(Box::from_iter(compiled.traces.0.iter().map( |&SimTrace { kind, + maybe_changed: _, state: _, last_state: _, }| SimTrace { kind, + maybe_changed: true, state: kind.make_state(), last_state: kind.make_state(), }, @@ -2094,6 +2201,7 @@ impl SimulationImpl { next_sensitivity_set_debug_id: 0, waiting_sensitivity_sets_by_compiled_value: HashMap::default(), waiting_sensitivity_sets_by_address: HashMap::default(), + trace_as_string_buf: String::with_capacity(256), } } fn write_traces( @@ -2126,13 +2234,16 @@ impl SimulationImpl { id, &SimTrace { kind, + maybe_changed, ref state, ref last_state, }, ) in self.traces.0.iter().enumerate() { - if ONLY_IF_CHANGED && state == last_state { - continue; + if ONLY_IF_CHANGED { + if !(maybe_changed && state != last_state) { + continue; + } } let id = TraceScalarId(id); match kind { @@ -2171,6 +2282,15 @@ impl SimulationImpl { SimTraceKind::SimOnly { .. } => { trace_writer.set_signal_sim_only_value(id, state.unwrap_sim_only_ref())? } + SimTraceKind::TraceAsString { layout, .. } => { + self.trace_as_string_buf.clear(); + layout.ty.trace_fmt_append_to_string( + &mut self.trace_as_string_buf, + state.unwrap_opaque_sim_value_ref().as_slice(), + ); + trace_writer.set_signal_string(id, &self.trace_as_string_buf)?; + self.trace_as_string_buf.clear(); + } } } Ok(trace_writer) @@ -2193,10 +2313,48 @@ impl SimulationImpl { fn read_traces(&mut self) { for &mut SimTrace { kind, + ref mut maybe_changed, ref mut state, ref mut last_state, } in &mut self.traces.0 { + let new_maybe_changed = match kind { + SimTraceKind::BigUInt { index, ty: _ } + | SimTraceKind::BigSInt { index, ty: _ } + | SimTraceKind::BigBool { index } + | SimTraceKind::BigAsyncReset { index } + | SimTraceKind::BigSyncReset { index } + | SimTraceKind::BigClock { index } => self + .state + .big_slots + .state_index_fetch_maybe_modified_flag(index), + SimTraceKind::SmallUInt { index, ty: _ } + | SimTraceKind::SmallSInt { index, ty: _ } + | SimTraceKind::SmallBool { index } + | SimTraceKind::SmallAsyncReset { index } + | SimTraceKind::SmallSyncReset { index } + | SimTraceKind::SmallClock { index } + | SimTraceKind::EnumDiscriminant { index, ty: _ } => self + .state + .small_slots + .state_index_fetch_maybe_modified_flag(index), + SimTraceKind::SimOnly { index, ty: _ } => self + .state + .sim_only_slots + .state_index_fetch_maybe_modified_flag(index), + SimTraceKind::PhantomConst { ty: _ } => IS_INITIAL_STEP, + SimTraceKind::TraceAsString { layout: _, range } => self + .state + .type_index_range_fetch_maybe_modified_flags(range), + }; + if !new_maybe_changed && !IS_INITIAL_STEP { + if *maybe_changed { + last_state.clone_from(state); + } + *maybe_changed = false; + continue; + } + *maybe_changed = new_maybe_changed; if !IS_INITIAL_STEP { mem::swap(state, last_state); } @@ -2241,11 +2399,26 @@ impl SimulationImpl { .unwrap_sim_only_mut() .clone_from(&self.state.sim_only_slots[index]); } + SimTraceKind::TraceAsString { layout, range } => { + let CompiledTypeLayoutBody::Transparent { inner } = layout.body else { + unreachable!() + }; + Self::read_opaque_no_settle( + &mut self.state, + CompiledValue { + layout: *inner, + range, + write: None, + }, + state.unwrap_opaque_sim_value_mut(), + ); + } } if IS_INITIAL_STEP { last_state.clone_from(state); } } + self.state.clear_all_maybe_modified_flags(); } #[track_caller] fn advance_time(this_ref: &Rc>, duration: SimDuration) { @@ -2772,6 +2945,7 @@ impl SimulationImpl { + Copy, read_write_sim_only_scalar: impl Fn(usize, &mut Opaque, &mut DynSimOnlyValue) + Copy, ) { + let compiled_value = compiled_value.unwrap_transparent_types(); match compiled_value.layout.body { CompiledTypeLayoutBody::Scalar => { let signed = match compiled_value.layout.ty { @@ -2787,6 +2961,7 @@ impl SimulationImpl { CanonicalType::Clock(_) => false, CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::DynSimOnly(_) => false, + CanonicalType::TraceAsString(_) => unreachable!(), }; let indexes = OpaqueSimValueSizeRange::from( start_index..start_index + compiled_value.layout.ty.size(), @@ -2863,14 +3038,17 @@ impl SimulationImpl { ); } } + CompiledTypeLayoutBody::Transparent { .. } => { + unreachable!("handled by unwrap_transparent_types") + } } } #[track_caller] - fn read_no_settle_helper( + fn read_opaque_no_settle( state: &mut interpreter::State, - io: Expr, compiled_value: CompiledValue, - ) -> SimValue { + opaque: &mut OpaqueSimValue, + ) { #[track_caller] fn read_write_sim_only_scalar( index: usize, @@ -2891,8 +3069,7 @@ impl SimulationImpl { }, ); } - let size = io.ty().size(); - let mut opaque = OpaqueSimValue::with_capacity(size); + let size = compiled_value.layout.ty.size(); opaque.rewrite_with(size, |mut writer| { SimulationImpl::read_write_sim_value_helper( state, @@ -2924,6 +3101,16 @@ impl SimulationImpl { ); writer.fill_cloned_from_slice(OpaqueSimValueSlice::empty()) }); + } + #[track_caller] + fn read_no_settle_helper( + state: &mut interpreter::State, + io: Expr, + compiled_value: CompiledValue, + ) -> SimValue { + let size = io.ty().size(); + let mut opaque = OpaqueSimValue::with_capacity(size); + Self::read_opaque_no_settle(state, compiled_value, &mut opaque); SimValue::from_opaque(io.ty(), opaque) } /// doesn't modify `opaque` diff --git a/crates/fayalite/src/sim/compiler.rs b/crates/fayalite/src/sim/compiler.rs index e85ff0f..4d6d9bc 100644 --- a/crates/fayalite/src/sim/compiler.rs +++ b/crates/fayalite/src/sim/compiler.rs @@ -10,7 +10,7 @@ use crate::{ ExprEnum, Flow, ValueType, ops, target::{ GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, - TargetPathElement, + TargetPathElement, TargetPathToTraceAsString, TargetPathTraceAsStringInner, }, }, int::BoolOrIntType, @@ -29,7 +29,8 @@ use crate::{ TraceBool, TraceBundle, TraceClock, TraceDecl, TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule, TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt, - TraceScalarId, TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, + TraceScalarId, TraceScope, TraceSimOnly, TraceSyncReset, TraceTraceAsString, TraceUInt, + TraceWire, interpreter::{ self, Insn, InsnField, InsnFieldKind, InsnFieldType, InsnOrLabel, Insns, InsnsBuilding, InsnsBuildingDone, InsnsBuildingKind, Label, PrefixLinesWrapper, SmallUInt, @@ -42,7 +43,7 @@ use crate::{ }, }, }, - ty::{OpaqueSimValueSize, StaticType}, + ty::{OpaqueSimValueSize, StaticType, TraceAsString}, util::{HashMap, chain}, }; use bitvec::vec::BitVec; @@ -110,6 +111,9 @@ pub(crate) enum CompiledTypeLayoutBody { Bundle { fields: Interned<[CompiledBundleField]>, }, + Transparent { + inner: Interned>, + }, } impl CompiledTypeLayoutBody { @@ -128,6 +132,9 @@ impl CompiledTypeLayoutBody { .map(|field| field.with_prefixed_debug_names(prefix)) .collect(), }, + CompiledTypeLayoutBody::Transparent { inner } => CompiledTypeLayoutBody::Transparent { + inner: inner.with_prefixed_debug_names(prefix).intern_sized(), + }, } } fn with_anonymized_debug_info(self) -> Self { @@ -145,6 +152,9 @@ impl CompiledTypeLayoutBody { .map(|field| field.with_anonymized_debug_info()) .collect(), }, + CompiledTypeLayoutBody::Transparent { inner } => CompiledTypeLayoutBody::Transparent { + inner: inner.with_anonymized_debug_info().intern_sized(), + }, } } } @@ -179,7 +189,7 @@ impl CompiledTypeLayout { impl Memoize for MyMemoize { type Input = CanonicalType; type InputOwned = CanonicalType; - type Output = CompiledTypeLayout; + type Output = (TypeLayout, CompiledTypeLayoutBody); fn inner(self, input: &Self::Input) -> Self::Output { match input { @@ -197,11 +207,7 @@ impl CompiledTypeLayout { ty: *input, }; layout.big_slots = StatePartLayout::scalar(debug_data, ()); - CompiledTypeLayout { - ty: *input, - layout: layout.into(), - body: CompiledTypeLayoutBody::Scalar, - } + (layout.into(), CompiledTypeLayoutBody::Scalar) } CanonicalType::Array(array) => { let mut layout = TypeLayout::empty(); @@ -215,19 +221,16 @@ impl CompiledTypeLayout { if array.is_empty() { elements_non_empty.push(element.with_prefixed_debug_names("[]")); } - CompiledTypeLayout { - ty: *input, - layout: layout.into(), - body: CompiledTypeLayoutBody::Array { + ( + layout.into(), + CompiledTypeLayoutBody::Array { elements_non_empty: elements_non_empty.intern_deref(), }, - } + ) + } + CanonicalType::PhantomConst(_) => { + (TypeLayout::empty(), CompiledTypeLayoutBody::PhantomConst) } - CanonicalType::PhantomConst(_) => CompiledTypeLayout { - ty: *input, - layout: TypeLayout::empty(), - body: CompiledTypeLayoutBody::PhantomConst, - }, CanonicalType::Bundle(bundle) => { let mut layout = TypeLayout::empty(); let fields = bundle @@ -246,11 +249,7 @@ impl CompiledTypeLayout { }, ) .collect(); - CompiledTypeLayout { - ty: *input, - layout: layout.into(), - body: CompiledTypeLayoutBody::Bundle { fields }, - } + (layout.into(), CompiledTypeLayoutBody::Bundle { fields }) } CanonicalType::DynSimOnly(ty) => { let mut layout = TypeLayout::empty(); @@ -259,24 +258,30 @@ impl CompiledTypeLayout { ty: *input, }; layout.sim_only_slots = StatePartLayout::scalar(debug_data, *ty); - CompiledTypeLayout { - ty: *input, - layout: layout.into(), - body: CompiledTypeLayoutBody::Scalar, - } + (layout.into(), CompiledTypeLayoutBody::Scalar) + } + CanonicalType::TraceAsString(ty) => { + let inner = CompiledTypeLayout::get(ty.inner_ty()).intern_sized(); + (inner.layout, CompiledTypeLayoutBody::Transparent { inner }) } } } } - let CompiledTypeLayout { - ty: _, - layout, - body, - } = MyMemoize.get_owned(ty.canonical()); + let (layout, body) = MyMemoize.get_owned(ty.canonical()); Self { ty, layout, body } } } +impl CompiledTypeLayout { + #[must_use] + fn unwrap_transparent_types(mut self) -> Self { + while let CompiledTypeLayoutBody::Transparent { inner } = self.body { + self = *inner; + } + self + } +} + #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] pub(crate) struct CompiledValue { pub(crate) layout: CompiledTypeLayout, @@ -324,6 +329,29 @@ impl CompiledValue { } } +impl CompiledValue { + #[must_use] + pub(crate) fn unwrap_transparent_types(self) -> Self { + let Self { + layout, + range, + write, + } = self; + Self { + layout: layout.unwrap_transparent_types(), + range, + write: write.map(|(layout, range)| (layout.unwrap_transparent_types(), range)), + } + } + #[must_use] + pub(crate) fn wrap_in_trace_as_string(self, ty: TraceAsString) -> CompiledValue { + self.map(|layout, range| { + assert_eq!(layout.ty, ty.inner_ty()); + (CompiledTypeLayout::get(ty), range) + }) + } +} + pub(crate) struct DebugCompiledValueStateAsMap<'a> { pub(crate) compiled_value: CompiledValue, pub(crate) state_layout: &'a interpreter::parts::StateLayout, @@ -402,6 +430,17 @@ impl CompiledValue { } } +impl CompiledValue { + pub(crate) fn inner(self) -> CompiledValue { + self.map(|layout, range| { + let CompiledTypeLayoutBody::Transparent { inner } = layout.body else { + unreachable!(); + }; + (*inner, range) + }) + } +} + macro_rules! make_type_array_indexes { ( type_plural_fields = [$($type_plural_field:ident,)*]; @@ -618,6 +657,16 @@ impl CompiledExpr { } } +impl CompiledExpr { + #[must_use] + pub(crate) fn wrap_in_trace_as_string(self, ty: TraceAsString) -> CompiledExpr { + CompiledExpr { + static_part: self.static_part.wrap_in_trace_as_string(ty), + indexes: self.indexes, + } + } +} + impl CompiledExpr { fn field_by_index(self, field_index: usize) -> CompiledExpr { CompiledExpr { @@ -666,6 +715,15 @@ impl CompiledExpr { } } +impl CompiledExpr { + pub(crate) fn inner(self) -> CompiledExpr { + CompiledExpr { + static_part: self.static_part.inner(), + indexes: self.indexes, + } + } +} + macro_rules! make_assignment_graph { ( type_plural_fields = [$($type_plural_field:ident,)*]; @@ -1977,6 +2035,39 @@ macro_rules! impl_compiler { flow, } .into(), + CanonicalType::TraceAsString(ty) => { + let location = match target { + MakeTraceDeclTarget::Expr(target) => { + let compiled_value = self.compile_expr(instantiated_module, target); + let CompiledValue { layout, range, write: _ } = + self.compiled_expr_to_value(compiled_value, source_location).map_ty(Type::from_canonical); + TraceLocation::Scalar(self.new_sim_trace(SimTraceKind::TraceAsString { + layout, + range, + })) + } + MakeTraceDeclTarget::Memory { + id, + depth, + stride, + start, + ty: _, + } => TraceLocation::Memory(TraceMemoryLocation { + id, + depth, + stride, + start, + len: ty.type_properties().bit_width, + }), + }; + TraceTraceAsString { + location, + name, + ty, + flow, + } + .into() + } } } fn compiled_expr_to_value( @@ -2234,6 +2325,7 @@ impl Compiler { let id = TraceScalarId(self.traces.0.len()); self.traces.0.push(SimTrace { kind, + maybe_changed: true, state: (), last_state: (), }); @@ -2420,7 +2512,8 @@ impl Compiler { | CanonicalType::Reset(_) | CanonicalType::Clock(_) | CanonicalType::DynSimOnly(_) - | CanonicalType::PhantomConst(_) => { + | CanonicalType::PhantomConst(_) + | CanonicalType::TraceAsString(_) => { self.make_trace_scalar(instantiated_module, target, name, source_location) } } @@ -2590,6 +2683,12 @@ impl Compiler { parent.map_ty(Array::from_canonical).element(index) } TargetPathElement::DynArrayElement(_) => unreachable!(), + TargetPathElement::TraceAsStringInner(TargetPathTraceAsStringInner {}) => { + parent.map_ty(TraceAsString::from_canonical).inner() + } + TargetPathElement::ToTraceAsString(TargetPathToTraceAsString { ty }) => parent + .wrap_in_trace_as_string(ty) + .map_ty(|ty| ty.canonical()), } } }; @@ -2822,6 +2921,12 @@ impl Compiler { CanonicalType::PhantomConst(_) | CanonicalType::DynSimOnly(_) => { self.compile_cast_aggregate_to_bits(instantiated_module, []) } + CanonicalType::TraceAsString(_) => self.compile_cast_to_bits( + instantiated_module, + ops::CastToBits::new( + ops::TraceAsStringAsInner::new(Expr::from_canonical(expr.arg())).to_expr(), + ), + ), } } fn compile_cast_bits_to_or_uninit( @@ -2911,6 +3016,16 @@ impl Compiler { vec![] }); } + CanonicalType::TraceAsString(ty) => Expr::canonical( + ops::ToTraceAsString::new( + match arg { + Some(arg) => arg.cast_bits_to(ty.inner_ty()), + None => ty.inner_ty().uninit(), + }, + ty, + ) + .to_expr(), + ), }; let retval = self.compile_expr(instantiated_module, Expr::canonical(retval)); self.compiled_expr_to_value(retval, instantiated_module.leaf_module().source_location()) @@ -2962,6 +3077,7 @@ impl Compiler { CanonicalType::Clock(_) => false, CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::DynSimOnly(_) => unreachable!(), + CanonicalType::TraceAsString(_) => unreachable!(), }; let dest_signed = match expr.ty() { CanonicalType::UInt(_) => false, @@ -2976,6 +3092,7 @@ impl Compiler { CanonicalType::Clock(_) => false, CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::DynSimOnly(_) => unreachable!(), + CanonicalType::TraceAsString(_) => unreachable!(), }; self.simple_nary_big_expr(instantiated_module, expr.ty(), [arg], |dest, [src]| match ( src_signed, @@ -3721,6 +3838,14 @@ impl Compiler { ExprEnum::CastBitsTo(expr) => self .compile_cast_bits_to_or_uninit(instantiated_module, Some(expr.arg()), expr.ty()) .into(), + ExprEnum::ToTraceAsString(expr) => self + .compile_expr(instantiated_module, expr.inner()) + .wrap_in_trace_as_string(expr.ty()) + .map_ty(|ty| ty.canonical()), + ExprEnum::TraceAsStringAsInner(expr) => self + .compile_expr(instantiated_module, Expr::canonical(expr.arg())) + .map_ty(TraceAsString::from_canonical) + .inner(), ExprEnum::ModuleIO(expr) => self .compile_value(TargetInInstantiatedModule { instantiated_module, @@ -3868,6 +3993,21 @@ impl Compiler { CanonicalType::DynSimOnly(_) => { unreachable!("DynSimOnly mismatch"); } + CanonicalType::TraceAsString(_) => { + let lhs = Expr::::from_canonical(lhs); + let rhs = Expr::::from_canonical(rhs); + let lhs_expr = ops::TraceAsStringAsInner::new(lhs).to_expr(); + let rhs_expr = ops::TraceAsStringAsInner::new(rhs).to_expr(); + return self.compile_connect( + lhs_instantiated_module, + lhs_conditions, + lhs_expr, + rhs_instantiated_module, + rhs_conditions, + rhs_expr, + source_location, + ); + } } } let Some(target) = lhs.target() else { @@ -4243,6 +4383,8 @@ impl Compiler { mut read: Option>, mut write: Option>, ) { + let data_layout = data_layout.unwrap_transparent_types(); + let mask_layout = mask_layout.unwrap_transparent_types(); match data_layout.body { CompiledTypeLayoutBody::Scalar => { let CompiledTypeLayoutBody::Scalar = mask_layout.body else { @@ -4261,6 +4403,7 @@ impl Compiler { CanonicalType::Clock(_) => false, CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::DynSimOnly(_) => false, + CanonicalType::TraceAsString(_) => unreachable!(), }; let width = data_layout.ty.bit_width(); if let Some(MemoryPortReadInsns { @@ -4483,6 +4626,9 @@ impl Compiler { start = start + field.ty.ty.bit_width(); } } + CompiledTypeLayoutBody::Transparent { .. } => { + unreachable!("handled by unwrap_transparent_types") + } } } fn compile_memory_port_rw( diff --git a/crates/fayalite/src/sim/interpreter.rs b/crates/fayalite/src/sim/interpreter.rs index 2b121b5..6b3eced 100644 --- a/crates/fayalite/src/sim/interpreter.rs +++ b/crates/fayalite/src/sim/interpreter.rs @@ -6,9 +6,9 @@ use crate::{ int::{BoolOrIntType, SInt, UInt}, intern::{Intern, Interned, Memoize}, sim::interpreter::parts::{ - StateLayout, StatePartIndex, StatePartKind, StatePartKindBigSlots, StatePartKindMemories, - StatePartKindSimOnlySlots, StatePartKindSmallSlots, StatePartLen, TypeIndexRange, - TypeLayout, get_state_part_kinds, + StateLayout, StatePartIndex, StatePartIndexRange, StatePartKind, StatePartKindBigSlots, + StatePartKindMemories, StatePartKindSimOnlySlots, StatePartKindSmallSlots, StatePartLen, + TypeIndexRange, TypeLayout, get_state_part_kinds, }, source_location::SourceLocation, util::{HashMap, HashSet}, @@ -17,12 +17,11 @@ use bitvec::slice::BitSlice; use num_bigint::BigInt; use num_traits::{One, Signed, ToPrimitive, Zero}; use std::{ - borrow::BorrowMut, convert::Infallible, fmt::{self, Write}, hash::Hash, marker::PhantomData, - ops::{ControlFlow, Deref, DerefMut, Index, IndexMut}, + ops::{ControlFlow, Deref, Index, IndexMut}, }; use vec_map::VecMap; @@ -915,6 +914,21 @@ impl StatePart { value: K::borrow_state(&mut self.value), } } + pub(crate) fn state_index_fetch_maybe_modified_flag( + &self, + part_index: StatePartIndex, + ) -> bool { + K::state_index_fetch_maybe_modified_flag(&self.value, part_index) + } + pub(crate) fn state_index_range_fetch_maybe_modified_flags( + &self, + part_index_range: StatePartIndexRange, + ) -> bool { + K::state_index_range_fetch_maybe_modified_flags(&self.value, part_index_range) + } + pub(crate) fn clear_all_maybe_modified_flags(&mut self) { + K::clear_all_maybe_modified_flags(&mut self.value) + } } #[derive(Clone, PartialEq, Eq, Hash, Debug)] @@ -922,56 +936,38 @@ pub(crate) struct BorrowedStatePart<'a, K: StatePartKind> { pub(crate) value: K::BorrowedState<'a>, } -impl< - 'a, - K: StatePartKind< - BorrowedState<'a>: DerefMut + BorrowMut<[T]>>, - >, - T, -> BorrowedStatePart<'a, K> -{ +impl BorrowedStatePart<'_, K> { pub(crate) fn get_disjoint_mut( &mut self, indexes: [StatePartIndex; N], - ) -> [&mut T; N] { - (*self.value) - .borrow_mut() - .get_disjoint_mut(indexes.map(|v| v.value as usize)) - .expect("indexes are disjoint") + ) -> [&mut K::StateElement; N] { + K::borrowed_state_get_disjoint_mut(&mut self.value, indexes) } } -impl>>, T> Index> - for StatePart -{ - type Output = T; +impl Index> for StatePart { + type Output = K::StateElement; fn index(&self, index: StatePartIndex) -> &Self::Output { - &self.value[index.value as usize] + K::state_index(&self.value, index) } } -impl>>, T> - IndexMut> for StatePart -{ +impl IndexMut> for StatePart { fn index_mut(&mut self, index: StatePartIndex) -> &mut Self::Output { - &mut self.value[index.value as usize] + K::state_index_mut(&mut self.value, index) } } -impl<'a, K: StatePartKind: Deref>>, T> - Index> for BorrowedStatePart<'a, K> -{ - type Output = T; +impl Index> for BorrowedStatePart<'_, K> { + type Output = K::StateElement; fn index(&self, index: StatePartIndex) -> &Self::Output { - &self.value[index.value as usize] + K::borrowed_state_index(&self.value, index) } } -impl<'a, K: StatePartKind: DerefMut>>, T> - IndexMut> for BorrowedStatePart<'a, K> -{ +impl IndexMut> for BorrowedStatePart<'_, K> { fn index_mut(&mut self, index: StatePartIndex) -> &mut Self::Output { - &mut self.value[index.value as usize] + K::borrowed_state_index_mut(&mut self.value, index) } } @@ -1028,6 +1024,15 @@ macro_rules! make_state { $($type_plural_field: self.$type_plural_field.borrow(),)* } } + pub(crate) fn type_index_range_fetch_maybe_modified_flags(&self, range: TypeIndexRange) -> bool { + $(self.$type_plural_field.state_index_range_fetch_maybe_modified_flags( + range.$type_plural_field, + ))||* + } + pub(crate) fn clear_all_maybe_modified_flags(&mut self) { + $(self.$state_plural_field.clear_all_maybe_modified_flags();)* + $(self.$type_plural_field.clear_all_maybe_modified_flags();)* + } } #[derive(Debug)] diff --git a/crates/fayalite/src/sim/interpreter/parts.rs b/crates/fayalite/src/sim/interpreter/parts.rs index 75427c9..0d98c06 100644 --- a/crates/fayalite/src/sim/interpreter/parts.rs +++ b/crates/fayalite/src/sim/interpreter/parts.rs @@ -236,6 +236,7 @@ pub(crate) trait StatePartKind: type LayoutData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy; type State: fmt::Debug + 'static + Clone; type BorrowedState<'a>: 'a; + type StateElement; fn new_state(layout_data: &[Self::LayoutData]) -> Self::State; fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a>; fn part_debug_data( @@ -247,6 +248,35 @@ pub(crate) trait StatePartKind: index: StatePartIndex, f: &mut impl fmt::Write, ) -> fmt::Result; + fn state_index<'a>( + state: &'a Self::State, + part_index: StatePartIndex, + ) -> &'a Self::StateElement; + fn state_index_mut<'a>( + state: &'a mut Self::State, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement; + fn state_index_fetch_maybe_modified_flag( + state: &Self::State, + part_index: StatePartIndex, + ) -> bool; + fn state_index_range_fetch_maybe_modified_flags( + state: &Self::State, + part_index_range: StatePartIndexRange, + ) -> bool; + fn clear_all_maybe_modified_flags(state: &mut Self::State); + fn borrowed_state_index<'a, 'b>( + state: &'a Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a Self::StateElement; + fn borrowed_state_index_mut<'a, 'b>( + state: &'a mut Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement; + fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>( + state: &'a mut Self::BorrowedState<'b>, + part_indexes: [StatePartIndex; N], + ) -> [&'a mut Self::StateElement; N]; } macro_rules! make_state_part_kinds { @@ -272,6 +302,7 @@ impl StatePartKind for StatePartKindMemories { type LayoutData = MemoryData>; type State = Box<[MemoryData]>; type BorrowedState<'a> = &'a mut [MemoryData]; + type StateElement = MemoryData; fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { layout_data .iter() @@ -297,19 +328,95 @@ impl StatePartKind for StatePartKindMemories { ) -> fmt::Result { write!(f, "{:#?}", &state.memories[index]) } + fn state_index<'a>( + state: &'a Self::State, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state[part_index.as_usize()] + } + fn state_index_mut<'a>( + state: &'a mut Self::State, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + &mut state[part_index.as_usize()] + } + fn state_index_fetch_maybe_modified_flag( + _state: &Self::State, + _part_index: StatePartIndex, + ) -> bool { + true + } + fn state_index_range_fetch_maybe_modified_flags( + _state: &Self::State, + part_index_range: StatePartIndexRange, + ) -> bool { + part_index_range.len.value > 0 + } + fn clear_all_maybe_modified_flags(_state: &mut Self::State) {} + fn borrowed_state_index<'a, 'b>( + state: &'a Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state[part_index.as_usize()] + } + fn borrowed_state_index_mut<'a, 'b>( + state: &'a mut Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + &mut state[part_index.as_usize()] + } + fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>( + state: &'a mut Self::BorrowedState<'b>, + part_indexes: [StatePartIndex; N], + ) -> [&'a mut Self::StateElement; N] { + state + .get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize)) + .expect("indexes are disjoint") + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Default)] +pub(crate) struct StateAndModified { + pub(crate) state: T, + pub(crate) modified: M, +} + +impl, M: Deref, E: fmt::Debug> fmt::Debug + for StateAndModified +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_list() + .entries(self.state.iter().zip(self.modified.iter().copied()).map( + |(state, modified)| { + fmt::from_fn(move |f| { + state.fmt(f)?; + if modified { + f.write_str(" (modified)")?; + } + Ok(()) + }) + }, + )) + .finish() + } } impl StatePartKind for StatePartKindSmallSlots { const NAME: &'static str = "SmallSlots"; type DebugData = SlotDebugData; type LayoutData = (); - type State = Box<[SmallUInt]>; - type BorrowedState<'a> = &'a mut [SmallUInt]; + type State = StateAndModified, Box<[bool]>>; + type BorrowedState<'a> = StateAndModified<&'a mut [Self::StateElement], &'a mut [bool]>; + type StateElement = SmallUInt; fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { - vec![0; layout_data.len()].into_boxed_slice() + StateAndModified { + state: vec![0; layout_data.len()].into_boxed_slice(), + modified: vec![false; layout_data.len()].into_boxed_slice(), + } } fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { - state + let StateAndModified { state, modified } = state; + StateAndModified { state, modified } } fn part_debug_data( state_layout: &StateLayout, @@ -330,19 +437,80 @@ impl StatePartKind for StatePartKindSmallSlots { write!(f, "{value:#x} {}", value as SmallSInt)?; Ok(()) } + fn state_index<'a>( + state: &'a Self::State, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state.state[part_index.as_usize()] + } + fn state_index_mut<'a>( + state: &'a mut Self::State, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + state.modified[part_index.as_usize()] = true; + &mut state.state[part_index.as_usize()] + } + fn state_index_fetch_maybe_modified_flag( + state: &Self::State, + part_index: StatePartIndex, + ) -> bool { + state.modified[part_index.as_usize()] + } + fn state_index_range_fetch_maybe_modified_flags( + state: &Self::State, + part_index_range: StatePartIndexRange, + ) -> bool { + state.modified[part_index_range.start.as_usize()..] + [..part_index_range.len.as_index().as_usize()] + .contains(&true) + } + fn clear_all_maybe_modified_flags(state: &mut Self::State) { + state.modified.fill(false); + } + fn borrowed_state_index<'a, 'b>( + state: &'a Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state.state[part_index.as_usize()] + } + fn borrowed_state_index_mut<'a, 'b>( + state: &'a mut Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + state.modified[part_index.as_usize()] = true; + &mut state.state[part_index.as_usize()] + } + fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>( + state: &'a mut Self::BorrowedState<'b>, + part_indexes: [StatePartIndex; N], + ) -> [&'a mut Self::StateElement; N] { + for part_index in part_indexes { + state.modified[part_index.as_usize()] = true; + } + state + .state + .get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize)) + .expect("indexes are disjoint") + } } impl StatePartKind for StatePartKindBigSlots { const NAME: &'static str = "BigSlots"; type DebugData = SlotDebugData; type LayoutData = (); - type State = Box<[BigInt]>; - type BorrowedState<'a> = &'a mut [BigInt]; + type State = StateAndModified, Box<[bool]>>; + type BorrowedState<'a> = StateAndModified<&'a mut [Self::StateElement], &'a mut [bool]>; + type StateElement = BigInt; fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { - layout_data.iter().map(|_| BigInt::default()).collect() + let state: Box<[_]> = layout_data.iter().map(|_| BigInt::default()).collect(); + StateAndModified { + modified: vec![false; state.len()].into_boxed_slice(), + state, + } } fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { - state + let StateAndModified { state, modified } = state; + StateAndModified { state, modified } } fn part_debug_data( state_layout: &StateLayout, @@ -361,19 +529,80 @@ impl StatePartKind for StatePartKindBigSlots { ) -> fmt::Result { write!(f, "{:#x}", state.big_slots[index]) } + fn state_index<'a>( + state: &'a Self::State, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state.state[part_index.as_usize()] + } + fn state_index_mut<'a>( + state: &'a mut Self::State, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + state.modified[part_index.as_usize()] = true; + &mut state.state[part_index.as_usize()] + } + fn state_index_fetch_maybe_modified_flag( + state: &Self::State, + part_index: StatePartIndex, + ) -> bool { + state.modified[part_index.as_usize()] + } + fn state_index_range_fetch_maybe_modified_flags( + state: &Self::State, + part_index_range: StatePartIndexRange, + ) -> bool { + state.modified[part_index_range.start.as_usize()..] + [..part_index_range.len.as_index().as_usize()] + .contains(&true) + } + fn clear_all_maybe_modified_flags(state: &mut Self::State) { + state.modified.fill(false); + } + fn borrowed_state_index<'a, 'b>( + state: &'a Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state.state[part_index.as_usize()] + } + fn borrowed_state_index_mut<'a, 'b>( + state: &'a mut Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + state.modified[part_index.as_usize()] = true; + &mut state.state[part_index.as_usize()] + } + fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>( + state: &'a mut Self::BorrowedState<'b>, + part_indexes: [StatePartIndex; N], + ) -> [&'a mut Self::StateElement; N] { + for part_index in part_indexes { + state.modified[part_index.as_usize()] = true; + } + state + .state + .get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize)) + .expect("indexes are disjoint") + } } impl StatePartKind for StatePartKindSimOnlySlots { const NAME: &'static str = "SimOnlySlots"; type DebugData = SlotDebugData; type LayoutData = DynSimOnly; - type State = Box<[DynSimOnlyValue]>; - type BorrowedState<'a> = &'a mut [DynSimOnlyValue]; + type State = StateAndModified, Box<[bool]>>; + type BorrowedState<'a> = StateAndModified<&'a mut [Self::StateElement], &'a mut [bool]>; + type StateElement = DynSimOnlyValue; fn new_state(layout_data: &[Self::LayoutData]) -> Self::State { - layout_data.iter().map(|ty| ty.default_value()).collect() + let state: Box<[_]> = layout_data.iter().map(|ty| ty.default_value()).collect(); + StateAndModified { + modified: vec![false; state.len()].into_boxed_slice(), + state, + } } fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> { - state + let StateAndModified { state, modified } = state; + StateAndModified { state, modified } } fn part_debug_data( state_layout: &StateLayout, @@ -392,6 +621,61 @@ impl StatePartKind for StatePartKindSimOnlySlots { ) -> fmt::Result { write!(f, "{:?}", state.sim_only_slots[index]) } + fn state_index<'a>( + state: &'a Self::State, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state.state[part_index.as_usize()] + } + fn state_index_mut<'a>( + state: &'a mut Self::State, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + state.modified[part_index.as_usize()] = true; + &mut state.state[part_index.as_usize()] + } + fn state_index_fetch_maybe_modified_flag( + state: &Self::State, + part_index: StatePartIndex, + ) -> bool { + state.modified[part_index.as_usize()] + } + fn state_index_range_fetch_maybe_modified_flags( + state: &Self::State, + part_index_range: StatePartIndexRange, + ) -> bool { + state.modified[part_index_range.start.as_usize()..] + [..part_index_range.len.as_index().as_usize()] + .contains(&true) + } + fn clear_all_maybe_modified_flags(state: &mut Self::State) { + state.modified.fill(false); + } + fn borrowed_state_index<'a, 'b>( + state: &'a Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a Self::StateElement { + &state.state[part_index.as_usize()] + } + fn borrowed_state_index_mut<'a, 'b>( + state: &'a mut Self::BorrowedState<'b>, + part_index: StatePartIndex, + ) -> &'a mut Self::StateElement { + state.modified[part_index.as_usize()] = true; + &mut state.state[part_index.as_usize()] + } + fn borrowed_state_get_disjoint_mut<'a, 'b, const N: usize>( + state: &'a mut Self::BorrowedState<'b>, + part_indexes: [StatePartIndex; N], + ) -> [&'a mut Self::StateElement; N] { + for part_index in part_indexes { + state.modified[part_index.as_usize()] = true; + } + state + .state + .get_disjoint_mut(part_indexes.map(StatePartIndex::as_usize)) + .expect("indexes are disjoint") + } } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/crates/fayalite/src/sim/value.rs b/crates/fayalite/src/sim/value.rs index b6a4e4b..24bc1ef 100644 --- a/crates/fayalite/src/sim/value.rs +++ b/crates/fayalite/src/sim/value.rs @@ -15,23 +15,23 @@ use crate::{ source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValue, OpaqueSimValueSize, OpaqueSimValueSlice, - OpaqueSimValueWriter, StaticType, Type, TypeProperties, impl_match_variant_as_self, + OpaqueSimValueWriter, SimValueDebug, StaticType, Type, TypeProperties, + impl_match_variant_as_self, }, util::{ - ConstUsize, HashMap, + ConstUsize, alternating_cell::{AlternatingCell, AlternatingCellMethods}, + serde_by_id::{SerdeById, SerdeByIdProperties, SerdeByIdTable, SerdeByIdTrait}, }, }; use bitvec::{slice::BitSlice, vec::BitVec}; -use hashbrown::hash_map::Entry; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _}; use std::{ borrow::{Borrow, BorrowMut, Cow}, - fmt::{self, Write}, - hash::{BuildHasher, Hash, Hasher, RandomState}, + fmt, num::NonZero, ops::{Deref, DerefMut, Index, IndexMut}, - sync::{Arc, Mutex}, + sync::Arc, }; pub(crate) mod sim_only_value_unsafe; @@ -551,113 +551,119 @@ impl_sim_value_cmp_as_bool!(AsyncReset); #[doc(hidden)] pub mod match_sim_value { - use crate::{ - sim::value::{SimValue, ToSimValue}, - ty::Type, - }; + use crate::{sim::value::SimValue, ty::Type}; + use std::ops::{Deref, DerefMut}; + + macro_rules! wrapper { + ( + $(pub struct $wrapper:ident<$T:ident>($inner:ty);)* + ) => { + $(#[doc(hidden)] + pub struct $wrapper<$T>($inner); + + impl<$T> $wrapper<$T> { + #[inline(always)] + pub fn new(value: $T) -> Self { + Self(<$inner>::new(value)) + } + } + + impl<$T> Deref for $wrapper<$T> { + type Target = $inner; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl<$T> DerefMut for $wrapper<$T> { + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + })* + }; + } + + wrapper! { + pub struct MatchSimValueHelperCheckSimValue(MatchSimValueHelperCheckMutSimValue); + pub struct MatchSimValueHelperCheckMutSimValue(MatchSimValueHelperCheckRefSimValue); + pub struct MatchSimValueHelperCheckRefSimValue(MatchSimValueHelperCheckRefRefSimValue); + pub struct MatchSimValueHelperCheckRefRefSimValue(MatchSimValueHelperCheckRefMutSimValue); + pub struct MatchSimValueHelperCheckRefMutSimValue(MatchSimValueHelperCheckMutRefSimValue); + pub struct MatchSimValueHelperCheckMutRefSimValue(MatchSimValueHelperCheckMutMutSimValue); + pub struct MatchSimValueHelperCheckMutMutSimValue(MatchSimValueHelperIdentity); + } + + impl MatchSimValueHelperCheckSimValue> { + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> T::SimValue { + SimValue::into_value(self.take()) + } + } + + impl<'a, T: Type> MatchSimValueHelperCheckMutSimValue<&'a mut SimValue> { + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> &'a mut T::SimValue { + self.take() + } + } + + impl<'a, T: Type> MatchSimValueHelperCheckRefSimValue<&'a SimValue> { + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> &'a T::SimValue { + self.take() + } + } + + impl<'a, 'b, T: Type> MatchSimValueHelperCheckRefRefSimValue<&'a &'b SimValue> { + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> &'b T::SimValue { + self.take() + } + } + + impl<'a, 'b, T: Type> MatchSimValueHelperCheckRefMutSimValue<&'a &'b mut SimValue> { + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> &'a T::SimValue { + self.take() + } + } + + impl<'a, 'b, T: Type> MatchSimValueHelperCheckMutRefSimValue<&'a mut &'b SimValue> { + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> &'b T::SimValue { + self.take() + } + } + + impl<'a, 'b, T: Type> MatchSimValueHelperCheckMutMutSimValue<&'a mut &'b mut SimValue> { + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> &'a mut T::SimValue { + self.take() + } + } #[doc(hidden)] - pub struct MatchSimValueHelper(Option); + pub struct MatchSimValueHelperIdentity(Option); - impl MatchSimValueHelper { - pub fn new(v: T) -> Self { + impl MatchSimValueHelperIdentity { + fn new(v: T) -> Self { Self(Some(v)) } - } - - #[doc(hidden)] - pub trait MatchSimValue { - type MatchValue; - - /// use `self` so it comes first in the method resolution order - fn __fayalite_match_sim_value(self) -> Self::MatchValue - where - Self: Sized; - } - - impl MatchSimValue for MatchSimValueHelper> { - type MatchValue = T::SimValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - SimValue::into_value(self.0.expect("should be Some")) + #[inline(always)] + fn take(&mut self) -> T { + self.0.take().expect("known to be Some") } - } - - impl<'a, T: Type> MatchSimValue for MatchSimValueHelper<&'a SimValue> { - type MatchValue = &'a T::SimValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - SimValue::value(self.0.expect("should be Some")) - } - } - - impl<'a, T: Type> MatchSimValue for MatchSimValueHelper<&'a mut SimValue> { - type MatchValue = &'a mut T::SimValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - SimValue::value_mut(self.0.expect("should be Some")) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'_ &'a T> - where - MatchSimValueHelper<&'a T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| *v))) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'_ mut &'a T> - where - MatchSimValueHelper<&'a T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| *v))) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'a &'_ mut T> - where - MatchSimValueHelper<&'a T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| &**v))) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'a mut &'_ mut T> - where - MatchSimValueHelper<&'a mut T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| &mut **v))) + #[inline(always)] + pub fn __fayalite_match_sim_value(&mut self) -> T { + self.take() } } #[doc(hidden)] - pub trait MatchSimValueFallback { - type MatchValue; - - /// use `&mut self` so it comes later in the method resolution order than MatchSimValue - fn __fayalite_match_sim_value(&mut self) -> Self::MatchValue; - } - - impl MatchSimValueFallback for MatchSimValueHelper { - type MatchValue = ::SimValue; - - fn __fayalite_match_sim_value(&mut self) -> Self::MatchValue { - SimValue::into_value(self.0.take().expect("should be Some").into_sim_value()) - } - } + pub type MatchSimValueHelper = MatchSimValueHelperCheckSimValue; } pub trait ToSimValue: ToSimValueWithType<::Type> + ValueType { @@ -1091,7 +1097,8 @@ impl ToSimValueWithType for bool { | CanonicalType::Enum(_) | CanonicalType::Bundle(_) | CanonicalType::PhantomConst(_) - | CanonicalType::DynSimOnly(_) => { + | CanonicalType::DynSimOnly(_) + | CanonicalType::TraceAsString(_) => { panic!("can't create SimValue from bool: expected value of type: {ty:?}"); } CanonicalType::Bool(_) @@ -1220,80 +1227,17 @@ macro_rules! impl_to_sim_value_for_int_value { impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType); impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType); -#[derive(Default)] -struct DynSimOnlySerdeTableRest { - from_serde: HashMap, - serde_id_random_state: RandomState, - buffer: String, -} - -impl DynSimOnlySerdeTableRest { - #[cold] - fn add_new(&mut self, ty: DynSimOnly) -> DynSimOnlySerdeId { - let mut try_number = 0u64; - let mut hasher = self.serde_id_random_state.build_hasher(); - // extract more bits of randomness from TypeId -- its Hash impl only hashes 64-bits - write!(self.buffer, "{:?}", ty.type_id()).expect("shouldn't ever fail"); - self.buffer.hash(&mut hasher); - loop { - let mut hasher = hasher.clone(); - try_number.hash(&mut hasher); - try_number += 1; - let retval = DynSimOnlySerdeId(std::array::from_fn(|i| { - let mut hasher = hasher.clone(); - i.hash(&mut hasher); - hasher.finish() as u32 - })); - match self.from_serde.entry(retval) { - Entry::Occupied(_) => continue, - Entry::Vacant(e) => { - e.insert(ty); - return retval; - } - } - } +impl SerdeByIdTrait for DynSimOnly { + fn serde_by_id_properties(&self) -> SerdeByIdProperties { + self.serde_by_id_properties_inner() } -} -#[derive(Default)] -struct DynSimOnlySerdeTable { - to_serde: HashMap, - rest: DynSimOnlySerdeTableRest, -} - -static DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE: Mutex> = Mutex::new(None); - -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] -#[serde(transparent)] -struct DynSimOnlySerdeId([u32; 4]); - -impl From for DynSimOnlySerdeId { - fn from(ty: DynSimOnly) -> Self { - let mut locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE - .lock() - .expect("shouldn't be poison"); - let DynSimOnlySerdeTable { to_serde, rest } = locked.get_or_insert_default(); - match to_serde.entry(ty) { - Entry::Occupied(occupied_entry) => *occupied_entry.get(), - Entry::Vacant(vacant_entry) => *vacant_entry.insert(rest.add_new(ty)), - } + fn static_table() -> &'static SerdeByIdTable { + static TABLE: SerdeByIdTable = SerdeByIdTable::new(); + &TABLE } -} -impl DynSimOnlySerdeId { - fn ty(self) -> Option { - let locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE - .lock() - .expect("shouldn't be poison"); - Some(*locked.as_ref()?.rest.from_serde.get(&self)?) - } -} - -#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] -struct DynSimOnlySerde<'a> { - random_id: DynSimOnlySerdeId, - #[serde(borrow)] - type_name: Cow<'a, str>, + const NAME: &'static str = "DynSimOnly"; } impl Serialize for DynSimOnly { @@ -1301,11 +1245,7 @@ impl Serialize for DynSimOnly { where S: Serializer, { - DynSimOnlySerde { - random_id: (*self).into(), - type_name: Cow::Borrowed(self.type_name()), - } - .serialize(serializer) + SerdeById { inner: *self }.serialize(serializer) } } @@ -1314,16 +1254,7 @@ impl<'de> Deserialize<'de> for DynSimOnly { where D: Deserializer<'de>, { - let deserialized = DynSimOnlySerde::deserialize(deserializer)?; - let retval = deserialized - .random_id - .ty() - .filter(|ty| ty.type_name() == deserialized.type_name); - retval.ok_or_else(|| { - D::Error::custom( - "doesn't match any DynSimOnly that was serialized this time this program was run", - ) - }) + Ok(SerdeById::deserialize(deserializer)?.inner) } } @@ -1394,6 +1325,15 @@ impl Type for DynSimOnly { } } +impl SimValueDebug for DynSimOnly { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl Type for SimOnly { type BaseType = DynSimOnly; type MaskType = Bool; @@ -1459,6 +1399,15 @@ impl Type for SimOnly { } } +impl SimValueDebug for SimOnly { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + impl StaticType for SimOnly { const TYPE: Self = Self::new(); diff --git a/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs b/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs index 2424c03..bcbcdc6 100644 --- a/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs +++ b/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs @@ -3,7 +3,10 @@ //! `unsafe` parts of [`DynSimOnlyValue`] -use crate::expr::{ValueType, value_category::ValueCategoryValue}; +use crate::{ + expr::{ValueType, value_category::ValueCategoryValue}, + util::serde_by_id::SerdeByIdProperties, +}; use serde::{Serialize, de::DeserializeOwned}; use std::{ any::{self, TypeId}, @@ -33,6 +36,7 @@ unsafe trait DynSimOnlyTrait: 'static + Send + Sync { &self, json_str: &str, ) -> serde_json::Result>; + fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties; } /// Safety: `type_id_dyn` is implemented correctly @@ -55,6 +59,9 @@ unsafe impl DynSimOnlyTrait for SimOnly { ) -> serde_json::Result> { Ok(Rc::::new(serde_json::from_str(json_str)?)) } + fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties { + SerdeByIdProperties::of::() + } } /// Safety: @@ -151,6 +158,9 @@ impl DynSimOnly { pub fn default_value(self) -> DynSimOnlyValue { DynSimOnlyValue(self.ty.default_value()) } + pub(super) fn serde_by_id_properties_inner(self) -> SerdeByIdProperties { + self.ty.serde_by_id_properties_inner() + } } impl PartialEq for DynSimOnly { diff --git a/crates/fayalite/src/sim/vcd.rs b/crates/fayalite/src/sim/vcd.rs index ad3e974..09e7d66 100644 --- a/crates/fayalite/src/sim/vcd.rs +++ b/crates/fayalite/src/sim/vcd.rs @@ -12,11 +12,12 @@ use crate::{ TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule, TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt, TraceScalar, TraceScalarId, - TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, TraceWriter, - TraceWriterDecls, + TraceScope, TraceSimOnly, TraceSyncReset, TraceTraceAsString, TraceUInt, TraceWire, + TraceWriter, TraceWriterDecls, time::{SimDuration, SimInstant}, value::DynSimOnlyValue, }, + ty::{OpaqueSimValueSlice, TraceAsString}, util::HashMap, }; use bitvec::{order::Lsb0, slice::BitSlice}; @@ -331,6 +332,7 @@ impl WriteTrace for TraceScalar { Self::AsyncReset(v) => v.write_trace(writer, arg), Self::PhantomConst(v) => v.write_trace(writer, arg), Self::SimOnly(v) => v.write_trace(writer, arg), + Self::TraceAsString(v) => v.write_trace(writer, arg), } } } @@ -726,6 +728,34 @@ impl WriteTrace for TraceSimOnly { } } +impl WriteTrace for TraceTraceAsString { + fn write_trace(self, writer: &mut W, mut arg: A) -> io::Result<()> { + let ArgInType { + source_var_type: _, + sink_var_type: _, + duplex_var_type: _, + properties, + scope, + } = arg.in_type(); + let Self { + location, + name, + ty, + flow: _, + } = self; + write_vcd_var( + properties, + scope, + MemoryElementPartBody::TraceAsString { ty }, + writer, + "string", + 1, + location, + name, + ) + } +} + impl WriteTrace for TraceScope { fn write_trace(self, writer: &mut W, arg: A) -> io::Result<()> { match self { @@ -1093,6 +1123,7 @@ impl TraceWriterDecls for VcdWriterDecls { finished_init: false, timescale, properties, + trace_as_string_buf: String::with_capacity(256), }) } } @@ -1100,6 +1131,7 @@ impl TraceWriterDecls for VcdWriterDecls { enum MemoryElementPartBody { Scalar, EnumDiscriminant { ty: Enum }, + TraceAsString { ty: TraceAsString }, } struct MemoryElementPart { @@ -1217,6 +1249,7 @@ pub struct VcdWriter { finished_init: bool, timescale: SimDuration, properties: VcdWriterProperties, + trace_as_string_buf: String, } impl VcdWriter { @@ -1326,6 +1359,21 @@ impl TraceWriter for VcdWriter { .built_scalar_id_to_vcd_id(first_id + element_index), )? } + MemoryElementPartBody::TraceAsString { ty } => { + self.trace_as_string_buf.clear(); + ty.trace_fmt_append_to_string( + &mut self.trace_as_string_buf, + OpaqueSimValueSlice::from_bitslice(&element_data[start..start + len]), + ); + write_string_value_change( + &mut self.writer, + &self.trace_as_string_buf, + self.properties + .scalar_id_to_vcd_id_map + .built_scalar_id_to_vcd_id(first_id + element_index), + )?; + self.trace_as_string_buf.clear(); + } } } Ok(()) @@ -1419,6 +1467,16 @@ impl TraceWriter for VcdWriter { .built_scalar_id_to_vcd_id(id.as_usize()), ) } + + fn set_signal_string(&mut self, id: TraceScalarId, value: &str) -> Result<(), Self::Error> { + write_string_value_change( + &mut self.writer, + value, + self.properties + .scalar_id_to_vcd_id_map + .built_scalar_id_to_vcd_id(id.as_usize()), + ) + } } impl fmt::Debug for VcdWriter { @@ -1428,6 +1486,7 @@ impl fmt::Debug for VcdWriter { finished_init, timescale, properties: _, + trace_as_string_buf: _, } = self; f.debug_struct("VcdWriter") .field("finished_init", finished_init) diff --git a/crates/fayalite/src/ty.rs b/crates/fayalite/src/ty.rs index 76c0955..ab69532 100644 --- a/crates/fayalite/src/ty.rs +++ b/crates/fayalite/src/ty.rs @@ -3,22 +3,28 @@ use crate::{ array::Array, - bundle::Bundle, + bundle::{Bundle, BundleField, BundleType}, clock::Clock, - enum_::Enum, - expr::Expr, + enum_::{Enum, EnumType, EnumVariant}, + expr::{Expr, HdlPartialEqImpl, HdlPartialOrdImpl, ToExpr, ValueType, Valueless, ops}, int::{Bool, SInt, UInt, UIntValue}, - intern::{Intern, Interned}, + intern::{Intern, Interned, LazyInterned, Memoize, SupportsPtrEqWithTypeId}, + module::transform::visit::{Fold, Folder, Visit, Visitor}, phantom_const::PhantomConst, reset::{AsyncReset, Reset, SyncReset}, - sim::value::{DynSimOnly, DynSimOnlyValue, SimValue, ToSimValueWithType}, + sim::value::{DynSimOnly, DynSimOnlyValue, SimValue, ToSimValue, ToSimValueWithType}, source_location::SourceLocation, - util::{ConstUsize, slice_range, try_slice_range}, + util::{ + ConstUsize, iter_eq_by, + serde_by_id::{SerdeByIdProperties, SerdeByIdTable, SerdeByIdTrait}, + slice_range, try_slice_range, + }, }; use bitvec::{slice::BitSlice, vec::BitVec}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::DeserializeOwned}; use std::{ - fmt, + borrow::Cow, + fmt::{self, Write}, hash::Hash, iter::{FusedIterator, Sum}, marker::PhantomData, @@ -69,6 +75,7 @@ pub enum CanonicalType { Clock(Clock), PhantomConst(PhantomConst), DynSimOnly(DynSimOnly), + TraceAsString(TraceAsString), } impl fmt::Debug for CanonicalType { @@ -86,6 +93,7 @@ impl fmt::Debug for CanonicalType { Self::Clock(v) => v.fmt(f), Self::PhantomConst(v) => v.fmt(f), Self::DynSimOnly(v) => v.fmt(f), + Self::TraceAsString(v) => v.fmt(f), } } } @@ -123,6 +131,7 @@ impl CanonicalType { CanonicalType::Clock(v) => v.type_properties(), CanonicalType::PhantomConst(v) => v.type_properties(), CanonicalType::DynSimOnly(v) => v.type_properties(), + CanonicalType::TraceAsString(v) => v.type_properties(), } } pub fn is_passive(self) -> bool { @@ -217,11 +226,134 @@ impl CanonicalType { }; lhs.can_connect(rhs) } + CanonicalType::TraceAsString(lhs) => { + let CanonicalType::TraceAsString(rhs) = rhs else { + return false; + }; + lhs.can_connect(rhs) + } } } pub(crate) fn as_serde_unexpected_str(self) -> &'static str { serde_impls::SerdeCanonicalType::from(self).as_serde_unexpected_str() } + /// Unwrap transparent types until reaching a non-transparent type. Currently [`TraceAsString`] is the only transparent type. + /// + /// [`TraceAsString`]: struct@TraceAsString + pub fn unwrap_transparent_types(mut self) -> Self { + loop { + self = match self { + Self::UInt(_) + | Self::SInt(_) + | Self::Bool(_) + | Self::Array(_) + | Self::Enum(_) + | Self::Bundle(_) + | Self::AsyncReset(_) + | Self::SyncReset(_) + | Self::Reset(_) + | Self::Clock(_) + | Self::PhantomConst(_) + | Self::DynSimOnly(_) => return self, + Self::TraceAsString(ty) => ty.inner_ty(), + }; + } + } + pub fn is_layout_equivalent(self, other: Self) -> bool { + fn is_bit(ty: CanonicalType) -> bool { + match ty { + CanonicalType::UInt(ty) => ty.width() == 1, + CanonicalType::SInt(_) => false, // SInt<1> doesn't count since it would be -1/0 instead of 1/0 + CanonicalType::Bool(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) => true, + CanonicalType::Array(_) + | CanonicalType::Enum(_) + | CanonicalType::Bundle(_) + | CanonicalType::PhantomConst(_) + | CanonicalType::DynSimOnly(_) => false, + CanonicalType::TraceAsString(_) => { + unreachable!("handled by unwrap_transparent_types") + } + } + } + #[derive(Copy, Clone, PartialEq, Eq, Hash)] + struct MyMemoize; + impl Memoize for MyMemoize { + type Input = (CanonicalType, CanonicalType); + type InputOwned = (CanonicalType, CanonicalType); + type Output = bool; + + fn inner(self, input: &Self::Input) -> Self::Output { + let (this, other) = *input; + let this = this.unwrap_transparent_types(); + let other = other.unwrap_transparent_types(); + let this_is_bit = is_bit(this); + let other_is_bit = is_bit(other); + if this_is_bit || other_is_bit { + return this_is_bit && other_is_bit; + } + let this_is_empty = this.size().is_empty(); + let other_is_empty = other.size().is_empty(); + if this_is_empty || other_is_empty { + return this_is_empty && other_is_empty; + } + match this { + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::DynSimOnly(_) => this == other, + CanonicalType::Array(this) => { + let CanonicalType::Array(other) = other else { + return false; + }; + this.len() == other.len() + && this.element().is_layout_equivalent(other.element()) + } + CanonicalType::Enum(this) => { + let CanonicalType::Enum(other) = other else { + return false; + }; + iter_eq_by( + this.variants(), + other.variants(), + |EnumVariant { name, ty }, other_variant| { + name == other_variant.name + && ty.unwrap_or_else(|| ().canonical()).is_layout_equivalent( + other_variant.ty.unwrap_or_else(|| ().canonical()), + ) + }, + ) + } + CanonicalType::Bundle(this) => { + let CanonicalType::Bundle(other) = other else { + return false; + }; + iter_eq_by( + this.fields().iter().filter(|f| !f.ty.size().is_empty()), + other.fields().iter().filter(|f| !f.ty.size().is_empty()), + |&BundleField { name, flipped, ty }, other_field| { + name == other_field.name + && flipped == other_field.flipped + && ty.is_layout_equivalent(other_field.ty) + }, + ) + } + CanonicalType::Bool(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) => unreachable!("handled by is_bit"), + CanonicalType::PhantomConst(_) => unreachable!("handled by is_empty"), + CanonicalType::TraceAsString(_) => { + unreachable!("handled by unwrap_transparent_types") + } + } + } + } + MyMemoize.get_owned((self, other)) + } } pub trait MatchVariantAndInactiveScope: Sized { @@ -328,6 +460,7 @@ impl_base_type!(Reset); impl_base_type!(Clock); impl_base_type!(PhantomConst); impl_base_type!(DynSimOnly); +impl_base_type!(TraceAsString); impl_base_type_serde!(Bool, "a Bool"); impl_base_type_serde!(Enum, "an Enum"); @@ -336,6 +469,7 @@ impl_base_type_serde!(AsyncReset, "an AsyncReset"); impl_base_type_serde!(SyncReset, "a SyncReset"); impl_base_type_serde!(Reset, "a Reset"); impl_base_type_serde!(Clock, "a Clock"); +impl_base_type_serde!(TraceAsString, "a TraceAsString"); impl sealed::BaseTypeSealed for CanonicalType {} @@ -367,7 +501,15 @@ impl TypeOrDefault for crate::__ { } pub trait Type: - Copy + Hash + Eq + fmt::Debug + Send + Sync + 'static + FillInDefaultedGenerics + Copy + + Hash + + Eq + + fmt::Debug + + Send + + Sync + + 'static + + FillInDefaultedGenerics + + SimValueDebug { type BaseType: BaseType; type MaskType: Type; @@ -402,6 +544,16 @@ pub trait Type: ) -> OpaqueSimValueWritten<'w>; } +pub trait SimValueDebug { + fn sim_value_debug(value: &::SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result + where + Self: Type; +} + +pub trait SimValueDisplay: Type { + fn sim_value_display(value: &Self::SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result; +} + pub trait BaseType: Type< BaseType = Self, @@ -455,6 +607,7 @@ impl Type for CanonicalType { CanonicalType::Clock(v) => v.mask_type().canonical(), CanonicalType::PhantomConst(v) => v.mask_type().canonical(), CanonicalType::DynSimOnly(v) => v.mask_type().canonical(), + CanonicalType::TraceAsString(v) => v.mask_type().canonical(), } } fn canonical(&self) -> CanonicalType { @@ -490,6 +643,15 @@ impl Type for CanonicalType { } } +impl SimValueDebug for CanonicalType { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(value, f) + } +} + #[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Default)] #[non_exhaustive] pub struct OpaqueSimValueSizeRange { @@ -730,13 +892,34 @@ impl Sum for OpaqueSimValueSize { } } -#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] +#[derive(PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] pub struct OpaqueSimValue { bits: UIntValue, #[serde(skip_serializing_if = "Vec::is_empty", default)] sim_only_values: Vec, } +impl Clone for OpaqueSimValue { + fn clone(&self) -> Self { + Self { + bits: self.bits.clone(), + sim_only_values: self.sim_only_values.clone(), + } + } + fn clone_from(&mut self, source: &Self) { + let Self { + bits, + sim_only_values, + } = self; + if let Some(bits) = Arc::get_mut(bits.arc_bitvec_mut()) { + bits.clone_from(source.bits.bits()); + } else { + *bits = source.bits.clone(); + } + sim_only_values.clone_from(&source.sim_only_values); + } +} + impl OpaqueSimValue { pub fn empty() -> Self { Self { @@ -1116,3 +1299,786 @@ impl Index for AsMaskWithoutGenerics { Interned::into_inner(Intern::intern_sized(ty.mask_type())) } } + +trait TraceAsStringTrait: fmt::Debug + 'static + Send + Sync + SupportsPtrEqWithTypeId { + fn trace_fmt(&self, opaque: OpaqueSimValueSlice<'_>, f: &mut fmt::Formatter<'_>) + -> fmt::Result; + fn serde_by_id_properties(&self) -> SerdeByIdProperties> { + SerdeByIdProperties::of::() + } + fn can_substitute_type(&self, new_type: CanonicalType) -> bool; +} + +impl TraceAsStringTrait for T { + fn trace_fmt( + &self, + opaque: OpaqueSimValueSlice<'_>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(&Type::sim_value_from_opaque(self, opaque), f) + } + fn can_substitute_type(&self, new_type: CanonicalType) -> bool { + self.canonical().is_layout_equivalent(new_type) + } +} + +impl crate::intern::InternedCompare for dyn TraceAsStringTrait { + type InternedCompareKey = crate::intern::PtrEqWithTypeId; + + fn interned_compare_key_ref(this: &Self) -> Self::InternedCompareKey { + this.get_ptr_eq_with_type_id() + } +} + +impl SerdeByIdTrait for Interned { + fn serde_by_id_properties(&self) -> SerdeByIdProperties { + TraceAsStringTrait::serde_by_id_properties(&**self) + } + + fn static_table() -> &'static SerdeByIdTable { + static TABLE: SerdeByIdTable> = SerdeByIdTable::new(); + &TABLE + } + + const NAME: &'static str = "dyn TraceAsStringTrait"; +} + +/// When running the fayalite simulator, outputs a single string signal containing a formatted version of the inner value (uses [`fmt::Debug`] by default). +/// This is a transparent type, meaning [`CanonicalType::unwrap_transparent_types`] will unwrap this type. +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct TraceAsString { + inner_ty: LazyInterned, + trace_as_string: LazyInterned, +} + +#[expect(non_upper_case_globals)] +pub const TraceAsString: TraceAsStringWithoutGenerics = TraceAsStringWithoutGenerics; + +impl fmt::Debug for TraceAsString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + inner_ty, + trace_as_string: _, + } = self; + f.debug_struct("TraceAsString") + .field("inner_ty", &inner_ty.interned()) + .finish_non_exhaustive() + } +} + +impl TraceAsString { + pub fn new(inner_ty: T) -> Self { + Self::new_interned(inner_ty.intern_sized()) + } + pub fn new_interned(inner_ty: Interned) -> Self { + Self { + inner_ty: LazyInterned::Interned(inner_ty), + trace_as_string: LazyInterned::Interned(Interned::cast_unchecked( + inner_ty, + |v| -> &dyn TraceAsStringTrait { v }, + )), + } + } + pub fn interned_inner_ty(self) -> Interned { + self.inner_ty.interned() + } + pub fn inner_ty(self) -> T { + *self.interned_inner_ty() + } + /// create a new `TraceAsString` but try to keep the old formatting method + pub fn with_new_inner_ty(self, inner_ty: Interned) -> TraceAsString { + if self + .trace_as_string + .can_substitute_type(inner_ty.canonical()) + { + TraceAsString { + inner_ty: LazyInterned::Interned(inner_ty), + trace_as_string: self.trace_as_string, + } + } else { + TraceAsString::new_interned(inner_ty) + } + } + pub fn canonical_trace_as_string(self) -> TraceAsString { + let Self { + inner_ty, + trace_as_string, + } = self; + TraceAsString { + inner_ty: LazyInterned::Interned(inner_ty.interned().canonical().intern_sized()), + trace_as_string, + } + } + pub fn from_canonical_trace_as_string(canonical: TraceAsString) -> Self { + let TraceAsString { + inner_ty, + trace_as_string, + } = canonical; + Self { + inner_ty: LazyInterned::Interned( + T::from_canonical(*inner_ty.interned()).intern_sized(), + ), + trace_as_string, + } + } + pub fn type_properties(self) -> TypeProperties { + self.interned_inner_ty().canonical().type_properties() + } + pub fn can_connect(self, rhs: TraceAsString) -> bool { + self.interned_inner_ty() + .canonical() + .can_connect(rhs.interned_inner_ty().canonical()) + } + pub fn trace_fmt( + self, + opaque: OpaqueSimValueSlice<'_>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + self.trace_as_string.interned().trace_fmt(opaque, f) + } + pub fn trace_fmt_append_to_string(self, output: &mut String, opaque: OpaqueSimValueSlice<'_>) { + fn impl_fn( + trace_as_string: Interned, + output: &mut String, + opaque: OpaqueSimValueSlice<'_>, + ) { + let initial_len = output.len(); + if let Err(fmt::Error {}) = write!( + output, + "{}", + fmt::from_fn(|f| trace_as_string.trace_fmt(opaque, f)) + ) { + output.truncate(initial_len); + output.push_str(""); + } + } + impl_fn(self.trace_as_string.interned(), output, opaque) + } +} + +impl SimValueDebug for TraceAsString { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + T::sim_value_debug(value.inner(), f) + } +} + +impl Type for TraceAsString { + type BaseType = TraceAsString; + type MaskType = T::MaskType; + type SimValue = TraceAsStringSimValue; + type MatchVariant = Expr; + type MatchActiveScope = (); + type MatchVariantAndInactiveScope = MatchVariantWithoutScope; + type MatchVariantsIter = std::iter::Once; + + fn match_variants( + this: Expr, + source_location: SourceLocation, + ) -> Self::MatchVariantsIter { + let _ = source_location; + std::iter::once(MatchVariantWithoutScope( + ops::TraceAsStringAsInner::new(this).to_expr(), + )) + } + + fn mask_type(&self) -> Self::MaskType { + self.inner_ty.mask_type() + } + + fn canonical(&self) -> CanonicalType { + CanonicalType::TraceAsString(self.canonical_trace_as_string()) + } + + fn from_canonical(canonical_type: CanonicalType) -> Self { + let CanonicalType::TraceAsString(canonical) = canonical_type else { + panic!("expected TraceAsString"); + }; + Self::from_canonical_trace_as_string(canonical) + } + + fn source_location() -> SourceLocation { + SourceLocation::builtin() + } + + fn sim_value_from_opaque(&self, opaque: OpaqueSimValueSlice<'_>) -> Self::SimValue { + TraceAsStringSimValue { + inner: SimValue::from_opaque(self.inner_ty(), opaque.to_owned()), + trace_as_string: self.trace_as_string.interned(), + } + } + + fn sim_value_clone_from_opaque( + &self, + value: &mut Self::SimValue, + opaque: OpaqueSimValueSlice<'_>, + ) { + self.inner_ty + .sim_value_clone_from_opaque(&mut value.inner, opaque); + } + + fn sim_value_to_opaque<'w>( + &self, + value: &Self::SimValue, + writer: OpaqueSimValueWriter<'w>, + ) -> OpaqueSimValueWritten<'w> { + self.inner_ty.sim_value_to_opaque(&value.inner, writer) + } +} + +impl TypeWithDeref for TraceAsString { + fn expr_deref(this: &Expr) -> &Self::MatchVariant { + Interned::into_inner( + ops::TraceAsStringAsInner::new(*this) + .to_expr() + .intern_sized(), + ) + } +} + +struct TraceAsStringStaticTypeHelper(PhantomData); + +impl Default for TraceAsStringStaticTypeHelper { + fn default() -> Self { + Self(PhantomData) + } +} + +impl From> for Interned { + fn from(_value: TraceAsStringStaticTypeHelper) -> Self { + Interned::cast_unchecked(T::TYPE.intern_sized(), |v| -> &dyn TraceAsStringTrait { v }) + } +} + +impl Default for TraceAsString { + fn default() -> Self { + Self::TYPE + } +} + +struct MakeType(Interned); + +impl From> for Interned { + fn from(value: MakeType) -> Self { + value.0 + } +} + +impl Default for MakeType { + fn default() -> Self { + Self(T::TYPE.intern_sized()) + } +} + +impl StaticType for TraceAsString { + const TYPE: Self = Self { + inner_ty: LazyInterned::new_const::>(), + trace_as_string: LazyInterned::new_const::>(), + }; + const MASK_TYPE: Self::MaskType = T::MASK_TYPE; + const TYPE_PROPERTIES: TypeProperties = T::TYPE_PROPERTIES; + const MASK_TYPE_PROPERTIES: TypeProperties = T::MASK_TYPE_PROPERTIES; +} + +#[doc(hidden)] +pub struct TraceAsStringWithoutGenerics; + +impl Index for TraceAsStringWithoutGenerics { + type Output = TraceAsString; + + fn index(&self, inner_ty: T) -> &Self::Output { + Interned::into_inner(TraceAsString::new(inner_ty).intern_sized()) + } +} + +#[derive(Clone)] +pub struct TraceAsStringSimValue { + inner: SimValue, + trace_as_string: Interned, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename = "TraceAsStringSimValue")] +struct TraceAsStringSimValueSerde { + inner: T, + trace_as_string: crate::util::serde_by_id::SerdeById>, +} + +impl + Serialize> Serialize for TraceAsStringSimValue { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let Self { + inner, + trace_as_string, + } = self; + TraceAsStringSimValueSerde { + inner, + trace_as_string: crate::util::serde_by_id::SerdeById { + inner: *trace_as_string, + }, + } + .serialize(serializer) + } +} + +impl<'de, T: Type> + Deserialize<'de>> Deserialize<'de> + for TraceAsStringSimValue +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let TraceAsStringSimValueSerde { + inner, + trace_as_string: + crate::util::serde_by_id::SerdeById { + inner: trace_as_string, + }, + } = Deserialize::deserialize(deserializer)?; + Ok(Self { + inner, + trace_as_string, + }) + } +} + +impl TraceAsStringSimValue { + pub fn new_with_ty(inner: impl ToSimValueWithType, ty: TraceAsString) -> Self { + Self { + inner: inner.into_sim_value_with_type(ty.inner_ty()), + trace_as_string: ty.trace_as_string.interned(), + } + } + pub fn new(inner: impl ToSimValue) -> Self { + let inner = inner.into_sim_value(); + Self { + trace_as_string: TraceAsString::new(inner.ty()).trace_as_string.interned(), + inner, + } + } + pub fn into_inner(self) -> SimValue { + self.inner + } + pub fn inner(&self) -> &SimValue { + &self.inner + } + pub fn inner_mut(&mut self) -> &mut SimValue { + &mut self.inner + } +} + +impl ValueType for TraceAsStringSimValue { + type Type = TraceAsString; + type ValueCategory = crate::expr::value_category::ValueCategoryValue; + + fn ty(&self) -> Self::Type { + let inner_ty = self.inner.ty().intern_sized(); + if self + .trace_as_string + .can_substitute_type(inner_ty.canonical()) + { + TraceAsString { + inner_ty: LazyInterned::Interned(inner_ty), + trace_as_string: LazyInterned::Interned(self.trace_as_string), + } + } else { + TraceAsString::new_interned(inner_ty) + } + } +} + +impl ToExpr for TraceAsStringSimValue { + #[track_caller] + fn to_expr(&self) -> Expr { + let inner = self.inner.to_expr(); + let inner_canonical = Expr::canonical(inner); + let inner_ty = inner.ty().intern_sized(); + let ty = if self + .trace_as_string + .can_substitute_type(inner_canonical.ty()) + { + TraceAsString { + inner_ty: LazyInterned::Interned(inner_ty), + trace_as_string: LazyInterned::Interned(self.trace_as_string), + } + } else { + TraceAsString::new_interned(inner_ty) + }; + ops::ToTraceAsString::new(inner_canonical, ty).to_expr() + } +} + +impl ToSimValueWithType> for TraceAsStringSimValue { + fn to_sim_value_with_type(&self, ty: TraceAsString) -> SimValue> { + let inner = self.inner.to_sim_value_with_type(ty.inner_ty()); + SimValue::from_value( + ty, + TraceAsStringSimValue { + inner, + trace_as_string: ty.trace_as_string.interned(), + }, + ) + } + fn into_sim_value_with_type(self, ty: TraceAsString) -> SimValue> { + let inner = self.inner.into_sim_value_with_type(ty.inner_ty()); + SimValue::from_value( + ty, + TraceAsStringSimValue { + inner, + trace_as_string: ty.trace_as_string.interned(), + }, + ) + } +} + +impl ToSimValue for TraceAsStringSimValue { + fn to_sim_value(&self) -> SimValue { + SimValue::from_value(self.ty(), self.clone()) + } + fn into_sim_value(self) -> SimValue { + SimValue::from_value(self.ty(), self) + } +} + +impl fmt::Debug for TraceAsStringSimValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.inner, f) + } +} + +impl> fmt::Display for TraceAsStringSimValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.inner, f) + } +} + +impl Ord for TraceAsStringSimValue +where + SimValue: Ord, +{ + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.inner.cmp(&other.inner) + } +} + +impl PartialOrd> for TraceAsStringSimValue +where + SimValue: PartialOrd>, +{ + fn partial_cmp(&self, other: &TraceAsStringSimValue) -> Option { + self.inner.partial_cmp(&other.inner) + } +} + +impl Eq for TraceAsStringSimValue where SimValue: Eq {} + +impl Hash for TraceAsStringSimValue +where + SimValue: Hash, +{ + fn hash(&self, state: &mut H) { + self.inner.hash(state); + } +} + +impl Default for TraceAsStringSimValue +where + SimValue: Default, +{ + fn default() -> Self { + let inner = SimValue::default(); + Self { + trace_as_string: TraceAsString::new(inner.ty()).trace_as_string.interned(), + inner, + } + } +} + +impl PartialEq> for TraceAsStringSimValue +where + SimValue: PartialEq>, +{ + fn eq(&self, other: &TraceAsStringSimValue) -> bool { + self.inner == other.inner + } +} + +impl, State: ?Sized + Folder> Fold for TraceAsString { + fn fold(self, state: &mut State) -> Result { + state.fold_trace_as_string(self) + } + + fn default_fold(self, state: &mut State) -> Result { + Ok(self.with_new_inner_ty(self.interned_inner_ty().fold(state)?)) + } +} + +impl, State: ?Sized + Visitor> Visit for TraceAsString { + fn visit(&self, state: &mut State) -> Result<(), ::Error> { + state.visit_trace_as_string(self) + } + + fn default_visit(&self, state: &mut State) -> Result<(), ::Error> { + self.interned_inner_ty().visit(state) + } +} + +fn trace_as_string_cow_into_inner( + this: Cow<'_, SimValue>>, +) -> Cow<'_, SimValue> { + match this { + Cow::Borrowed(v) => Cow::Borrowed(&v.inner), + Cow::Owned(v) => Cow::Owned(SimValue::into_value(v).inner), + } +} + +fn trace_as_string_cow_into_inner_value( + this: Cow<'_, TraceAsStringSimValue>, +) -> Cow<'_, T::SimValue> { + match this { + Cow::Borrowed(v) => Cow::Borrowed(&v.inner), + Cow::Owned(v) => Cow::Owned(SimValue::into_value(v.inner)), + } +} + +impl, U: Type> HdlPartialEqImpl> for TraceAsString { + #[track_caller] + fn cmp_value_eq( + lhs: Self, + lhs_value: Cow<'_, Self::SimValue>, + rhs: TraceAsString, + rhs_value: Cow<'_, as Type>::SimValue>, + ) -> bool { + HdlPartialEqImpl::cmp_value_eq( + lhs.inner_ty(), + trace_as_string_cow_into_inner_value(lhs_value), + rhs.inner_ty(), + trace_as_string_cow_into_inner_value(rhs_value), + ) + } + + #[track_caller] + fn cmp_value_ne( + lhs: Self, + lhs_value: Cow<'_, Self::SimValue>, + rhs: TraceAsString, + rhs_value: Cow<'_, as Type>::SimValue>, + ) -> bool { + HdlPartialEqImpl::cmp_value_ne( + lhs.inner_ty(), + trace_as_string_cow_into_inner_value(lhs_value), + rhs.inner_ty(), + trace_as_string_cow_into_inner_value(rhs_value), + ) + } + + #[track_caller] + fn cmp_sim_value_eq( + lhs: Cow<'_, SimValue>, + rhs: Cow<'_, SimValue>>, + ) -> SimValue { + HdlPartialEqImpl::cmp_sim_value_eq( + trace_as_string_cow_into_inner(lhs), + trace_as_string_cow_into_inner(rhs), + ) + } + + #[track_caller] + fn cmp_sim_value_ne( + lhs: Cow<'_, SimValue>, + rhs: Cow<'_, SimValue>>, + ) -> SimValue { + HdlPartialEqImpl::cmp_sim_value_ne( + trace_as_string_cow_into_inner(lhs), + trace_as_string_cow_into_inner(rhs), + ) + } + + #[track_caller] + fn cmp_expr_eq(lhs: Expr, rhs: Expr>) -> Expr { + HdlPartialEqImpl::cmp_expr_eq(*lhs, *rhs) + } + + #[track_caller] + fn cmp_expr_ne(lhs: Expr, rhs: Expr>) -> Expr { + HdlPartialEqImpl::cmp_expr_ne(*lhs, *rhs) + } + + #[track_caller] + fn cmp_valueless_eq(lhs: Valueless, rhs: Valueless>) -> Valueless { + HdlPartialEqImpl::cmp_valueless_eq( + Valueless::new(lhs.ty().inner_ty()), + Valueless::new(rhs.ty().inner_ty()), + ) + } + + #[track_caller] + fn cmp_valueless_ne(lhs: Valueless, rhs: Valueless>) -> Valueless { + HdlPartialEqImpl::cmp_valueless_ne( + Valueless::new(lhs.ty().inner_ty()), + Valueless::new(rhs.ty().inner_ty()), + ) + } +} + +impl, U: Type> HdlPartialOrdImpl> for TraceAsString { + #[track_caller] + fn cmp_value_lt( + lhs: Self, + lhs_value: Cow<'_, Self::SimValue>, + rhs: TraceAsString, + rhs_value: Cow<'_, as Type>::SimValue>, + ) -> bool { + HdlPartialOrdImpl::cmp_value_lt( + lhs.inner_ty(), + trace_as_string_cow_into_inner_value(lhs_value), + rhs.inner_ty(), + trace_as_string_cow_into_inner_value(rhs_value), + ) + } + + #[track_caller] + fn cmp_value_le( + lhs: Self, + lhs_value: Cow<'_, Self::SimValue>, + rhs: TraceAsString, + rhs_value: Cow<'_, as Type>::SimValue>, + ) -> bool { + HdlPartialOrdImpl::cmp_value_le( + lhs.inner_ty(), + trace_as_string_cow_into_inner_value(lhs_value), + rhs.inner_ty(), + trace_as_string_cow_into_inner_value(rhs_value), + ) + } + + #[track_caller] + fn cmp_value_gt( + lhs: Self, + lhs_value: Cow<'_, Self::SimValue>, + rhs: TraceAsString, + rhs_value: Cow<'_, as Type>::SimValue>, + ) -> bool { + HdlPartialOrdImpl::cmp_value_gt( + lhs.inner_ty(), + trace_as_string_cow_into_inner_value(lhs_value), + rhs.inner_ty(), + trace_as_string_cow_into_inner_value(rhs_value), + ) + } + + #[track_caller] + fn cmp_value_ge( + lhs: Self, + lhs_value: Cow<'_, Self::SimValue>, + rhs: TraceAsString, + rhs_value: Cow<'_, as Type>::SimValue>, + ) -> bool { + HdlPartialOrdImpl::cmp_value_ge( + lhs.inner_ty(), + trace_as_string_cow_into_inner_value(lhs_value), + rhs.inner_ty(), + trace_as_string_cow_into_inner_value(rhs_value), + ) + } + + #[track_caller] + fn cmp_sim_value_lt( + lhs: Cow<'_, SimValue>, + rhs: Cow<'_, SimValue>>, + ) -> SimValue { + HdlPartialOrdImpl::cmp_sim_value_lt( + trace_as_string_cow_into_inner(lhs), + trace_as_string_cow_into_inner(rhs), + ) + } + + #[track_caller] + fn cmp_sim_value_le( + lhs: Cow<'_, SimValue>, + rhs: Cow<'_, SimValue>>, + ) -> SimValue { + HdlPartialOrdImpl::cmp_sim_value_le( + trace_as_string_cow_into_inner(lhs), + trace_as_string_cow_into_inner(rhs), + ) + } + + #[track_caller] + fn cmp_sim_value_gt( + lhs: Cow<'_, SimValue>, + rhs: Cow<'_, SimValue>>, + ) -> SimValue { + HdlPartialOrdImpl::cmp_sim_value_gt( + trace_as_string_cow_into_inner(lhs), + trace_as_string_cow_into_inner(rhs), + ) + } + + #[track_caller] + fn cmp_sim_value_ge( + lhs: Cow<'_, SimValue>, + rhs: Cow<'_, SimValue>>, + ) -> SimValue { + HdlPartialOrdImpl::cmp_sim_value_ge( + trace_as_string_cow_into_inner(lhs), + trace_as_string_cow_into_inner(rhs), + ) + } + + #[track_caller] + fn cmp_expr_lt(lhs: Expr, rhs: Expr>) -> Expr { + HdlPartialOrdImpl::cmp_expr_lt(*lhs, *rhs) + } + + #[track_caller] + fn cmp_expr_le(lhs: Expr, rhs: Expr>) -> Expr { + HdlPartialOrdImpl::cmp_expr_le(*lhs, *rhs) + } + + #[track_caller] + fn cmp_expr_gt(lhs: Expr, rhs: Expr>) -> Expr { + HdlPartialOrdImpl::cmp_expr_gt(*lhs, *rhs) + } + + #[track_caller] + fn cmp_expr_ge(lhs: Expr, rhs: Expr>) -> Expr { + HdlPartialOrdImpl::cmp_expr_ge(*lhs, *rhs) + } + + #[track_caller] + fn cmp_valueless_lt(lhs: Valueless, rhs: Valueless>) -> Valueless { + HdlPartialOrdImpl::cmp_valueless_lt( + Valueless::new(lhs.ty().inner_ty()), + Valueless::new(rhs.ty().inner_ty()), + ) + } + + #[track_caller] + fn cmp_valueless_le(lhs: Valueless, rhs: Valueless>) -> Valueless { + HdlPartialOrdImpl::cmp_valueless_le( + Valueless::new(lhs.ty().inner_ty()), + Valueless::new(rhs.ty().inner_ty()), + ) + } + + #[track_caller] + fn cmp_valueless_gt(lhs: Valueless, rhs: Valueless>) -> Valueless { + HdlPartialOrdImpl::cmp_valueless_gt( + Valueless::new(lhs.ty().inner_ty()), + Valueless::new(rhs.ty().inner_ty()), + ) + } + + #[track_caller] + fn cmp_valueless_ge(lhs: Valueless, rhs: Valueless>) -> Valueless { + HdlPartialOrdImpl::cmp_valueless_ge( + Valueless::new(lhs.ty().inner_ty()), + Valueless::new(rhs.ty().inner_ty()), + ) + } +} diff --git a/crates/fayalite/src/ty/serde_impls.rs b/crates/fayalite/src/ty/serde_impls.rs index af324f9..d5b5551 100644 --- a/crates/fayalite/src/ty/serde_impls.rs +++ b/crates/fayalite/src/ty/serde_impls.rs @@ -12,7 +12,8 @@ use crate::{ prelude::PhantomConst, reset::{AsyncReset, Reset, SyncReset}, sim::value::DynSimOnly, - ty::{BaseType, CanonicalType}, + ty::{BaseType, CanonicalType, TraceAsString, TraceAsStringTrait}, + util::serde_by_id::SerdeById, }; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -38,6 +39,7 @@ impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for SerdePhantomConst< #[derive(Serialize, Deserialize)] #[serde(rename = "CanonicalType")] +#[expect(private_interfaces)] pub(crate) enum SerdeCanonicalType< ArrayElement = CanonicalType, ThePhantomConst = SerdePhantomConst>, @@ -65,6 +67,10 @@ pub(crate) enum SerdeCanonicalType< Clock, PhantomConst(ThePhantomConst), DynSimOnly(DynSimOnly), + TraceAsString { + inner_ty: Interned, + trace_as_string: SerdeById>, + }, } impl SerdeCanonicalType { @@ -82,6 +88,7 @@ impl SerdeCanonicalType "a Clock", Self::PhantomConst(_) => "a PhantomConst", Self::DynSimOnly(_) => "a SimOnlyValue", + Self::TraceAsString { .. } => "a TraceAsString", } } } @@ -109,6 +116,15 @@ impl From for SerdeCanonicalType { CanonicalType::Clock(Clock {}) => Self::Clock, CanonicalType::PhantomConst(ty) => Self::PhantomConst(SerdePhantomConst(ty.get())), CanonicalType::DynSimOnly(ty) => Self::DynSimOnly(ty), + CanonicalType::TraceAsString(TraceAsString { + inner_ty, + trace_as_string, + }) => Self::TraceAsString { + inner_ty: inner_ty.interned(), + trace_as_string: SerdeById { + inner: trace_as_string.interned(), + }, + }, } } } @@ -130,6 +146,13 @@ impl From for CanonicalType { Self::PhantomConst(PhantomConst::new_interned(value.0)) } SerdeCanonicalType::DynSimOnly(value) => Self::DynSimOnly(value), + SerdeCanonicalType::TraceAsString { + inner_ty, + trace_as_string, + } => Self::TraceAsString(TraceAsString { + inner_ty: crate::intern::LazyInterned::Interned(inner_ty), + trace_as_string: crate::intern::LazyInterned::Interned(trace_as_string.inner), + }), } } } diff --git a/crates/fayalite/src/util.rs b/crates/fayalite/src/util.rs index f1457de..6845d3c 100644 --- a/crates/fayalite/src/util.rs +++ b/crates/fayalite/src/util.rs @@ -46,3 +46,4 @@ pub(crate) use misc::{InternedStrCompareAsStr, chain, copy_le_bytes_to_bitslice} pub mod job_server; pub mod prefix_sum; pub mod ready_valid; +pub(crate) mod serde_by_id; diff --git a/crates/fayalite/src/util/serde_by_id.rs b/crates/fayalite/src/util/serde_by_id.rs new file mode 100644 index 0000000..3db4ab6 --- /dev/null +++ b/crates/fayalite/src/util/serde_by_id.rs @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +use crate::util::HashMap; +use hashbrown::hash_map::Entry; +use serde::{Deserialize, Serialize, de::Error}; +use std::{ + any::TypeId, + borrow::Cow, + fmt::Write, + hash::{BuildHasher, Hash, Hasher}, + marker::PhantomData, + sync::Mutex, +}; + +pub(crate) struct SerdeByIdProperties { + type_id: TypeId, + type_name: &'static str, + _phantom: PhantomData T>, +} + +impl Clone for SerdeByIdProperties { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SerdeByIdProperties {} + +impl SerdeByIdProperties { + pub fn of() -> Self { + Self { + type_id: TypeId::of::(), + type_name: std::any::type_name::(), + _phantom: PhantomData, + } + } +} + +pub(crate) trait SerdeByIdTrait: Hash + Eq + Clone + 'static + Send { + fn serde_by_id_properties(&self) -> SerdeByIdProperties; + fn static_table() -> &'static SerdeByIdTable; + const NAME: &'static str; +} + +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] +#[serde(transparent)] +struct SerdeRandomId([u32; 4]); + +#[derive(Serialize, Deserialize)] +pub(crate) struct SerdeId<'a, T: SerdeByIdTrait> { + random_id: SerdeRandomId, + #[serde(borrow)] + type_name: Cow<'a, str>, + #[serde(skip)] + _phantom: PhantomData T>, +} + +impl<'a, T: SerdeByIdTrait> Clone for SerdeId<'a, T> { + fn clone(&self) -> Self { + Self { + random_id: self.random_id, + type_name: self.type_name.clone(), + _phantom: PhantomData, + } + } +} + +impl<'a, T: SerdeByIdTrait> Eq for SerdeId<'a, T> {} + +impl<'a, 'b, T: SerdeByIdTrait> PartialEq> for SerdeId<'a, T> { + fn eq(&self, other: &SerdeId<'b, T>) -> bool { + let Self { + random_id, + type_name, + _phantom: _, + } = self; + *random_id == other.random_id && *type_name == other.type_name + } +} + +impl<'a, T: SerdeByIdTrait> Hash for SerdeId<'a, T> { + fn hash(&self, state: &mut H) { + let Self { + random_id, + type_name: _, + _phantom: _, + } = self; + random_id.hash(state); + } +} + +struct SerdeByIdTableRest { + from_serde: HashMap, T>, + serde_id_random_state: std::hash::RandomState, + buffer: String, +} + +impl Default for SerdeByIdTableRest { + fn default() -> Self { + Self { + from_serde: Default::default(), + serde_id_random_state: Default::default(), + buffer: Default::default(), + } + } +} + +impl SerdeByIdTableRest { + fn add_new(&mut self, value: T) -> SerdeId<'static, T> { + let properties = value.serde_by_id_properties(); + let mut try_number = 0u64; + let mut hasher = self.serde_id_random_state.build_hasher(); + // extract more bits of randomness from TypeId -- its Hash impl only hashes 64-bits + write!(self.buffer, "{:?}", properties.type_id).expect("shouldn't ever fail"); + self.buffer.hash(&mut hasher); + loop { + let mut hasher = hasher.clone(); + try_number.hash(&mut hasher); + try_number += 1; + let key = SerdeId { + random_id: SerdeRandomId(std::array::from_fn(|i| { + let mut hasher = hasher.clone(); + i.hash(&mut hasher); + hasher.finish() as u32 + })), + type_name: Cow::Borrowed(properties.type_name), + _phantom: PhantomData, + }; + match self.from_serde.entry(key) { + Entry::Occupied(_) => continue, + Entry::Vacant(e) => { + let key = e.key().clone(); + e.insert(value); + return key; + } + } + } + } +} + +pub(crate) struct SerdeByIdTableMut { + to_serde: HashMap>, + rest: SerdeByIdTableRest, +} + +impl Default for SerdeByIdTableMut { + fn default() -> Self { + Self { + to_serde: Default::default(), + rest: Default::default(), + } + } +} + +impl SerdeByIdTableMut { + pub(crate) fn to_serde(&mut self, value: &T) -> SerdeId<'static, T> { + if let Some(retval) = self.to_serde.get(value) { + return retval.clone(); + } + self.to_serde_insert(value) + } + #[cold] + fn to_serde_insert(&mut self, value: &T) -> SerdeId<'static, T> { + let value = value.clone(); + let retval = self.rest.add_new(value.clone()); + self.to_serde.insert(value, retval.clone()); + retval + } + pub(crate) fn from_serde(&self, id: &SerdeId<'_, T>) -> Option { + self.rest.from_serde.get(id).cloned() + } +} + +pub(crate) struct SerdeByIdTable(Mutex>>); + +impl SerdeByIdTable { + pub(crate) const fn new() -> Self { + Self(Mutex::new(None)) + } + pub(crate) fn to_serde(&self, value: &T) -> SerdeId<'static, T> { + self.0 + .lock() + .expect("shouldn't be poison") + .get_or_insert_with( + #[cold] + || Default::default(), + ) + .to_serde(value) + } + pub(crate) fn from_serde(&self, id: &SerdeId<'_, T>) -> Option { + self.0 + .lock() + .expect("shouldn't be poison") + .get_or_insert_with( + #[cold] + || Default::default(), + ) + .from_serde(id) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default, Ord, PartialOrd)] +pub(crate) struct SerdeById { + pub(crate) inner: T, +} + +impl<'de, T: SerdeByIdTrait> Deserialize<'de> for SerdeById { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let id = SerdeId::deserialize(deserializer)?; + let inner = T::static_table().from_serde(&id).ok_or_else(|| { + D::Error::custom(format_args!( + "doesn't match any {} that was serialized this time this program was run: type_name={:?}", + T::NAME, + id.type_name, + )) + })?; + Ok(Self { inner }) + } +} + +impl Serialize for SerdeById { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + T::static_table() + .to_serde(&self.inner) + .serialize(serializer) + } +} diff --git a/crates/fayalite/src/vendor/xilinx/yosys_nextpnr_prjxray.rs b/crates/fayalite/src/vendor/xilinx/yosys_nextpnr_prjxray.rs index 3e1ac0c..2d498e7 100644 --- a/crates/fayalite/src/vendor/xilinx/yosys_nextpnr_prjxray.rs +++ b/crates/fayalite/src/vendor/xilinx/yosys_nextpnr_prjxray.rs @@ -546,7 +546,7 @@ impl Visitor for XdcFileWriter { base.source_location(), )? {}, } - match base.canonical_ty() { + match base.canonical_ty().unwrap_transparent_types() { CanonicalType::UInt(_) | CanonicalType::SInt(_) | CanonicalType::Bool(_) @@ -563,6 +563,9 @@ impl Visitor for XdcFileWriter { v, base.source_location(), )? {}, + CanonicalType::TraceAsString(_) => { + unreachable!("handled by unwrap_transparent_types") + } } self.required_dont_touch_targets.insert(target); match v { diff --git a/crates/fayalite/tests/hdl_types_fmt.rs b/crates/fayalite/tests/hdl_types_fmt.rs new file mode 100644 index 0000000..382f64d --- /dev/null +++ b/crates/fayalite/tests/hdl_types_fmt.rs @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information +use fayalite::{prelude::*, ty::SimValueDebug}; +use std::fmt; + +#[hdl(outline_generated)] +struct MyStruct0 { + v: T, + a: ArrayType, S>, +} + +#[hdl] +#[test] +fn check_my_struct0() { + let ty = MyStruct0[UInt[8]][3]; + assert_eq!( + format!("{ty:?}"), + "MyStruct0 { v: UInt<8>, a: Array, 3> }", + ); + assert_eq!( + format!("{:?}", ty.mask_type()), + "MaskType { v: Bool, a: Array }", + ); + let v = #[hdl(sim)] + MyStruct0::<_, _> { + v: 0x23u8, + a: [1u8, 2, 3], + }; + assert_eq!( + format!("{v:?}"), + "MyStruct0 { v: 0x23_u8, a: [0x1_u8, 0x2_u8, 0x3_u8] }", + ); +} + +#[hdl(outline_generated, custom_debug())] +struct MyStruct1 { + v: T, + a: ArrayType, S>, +} + +impl fmt::Debug for MyStruct1 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { v, a } = self; + f.debug_struct("Custom") + .field("v", v) + .field("a", a) + .finish() + } +} + +impl SimValueDebug for MyStruct1 { + #[hdl] + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + #[hdl(sim)] + let Self { v, a } = value; + f.debug_struct("Custom") + .field("v", &v) + .field("a", &a) + .finish() + } +} + +#[hdl] +#[test] +fn check_my_struct1() { + let ty = MyStruct1[UInt[8]][3]; + assert_eq!( + format!("{ty:?}"), + "Custom { v: UInt<8>, a: Array, 3> }", + ); + assert_eq!( + format!("{:?}", ty.mask_type()), + "MaskType { v: Bool, a: Array }", + ); + let v = #[hdl(sim)] + MyStruct1::<_, _> { + v: 0x23u8, + a: [1u8, 2, 3], + }; + assert_eq!( + format!("{v:?}"), + "Custom { v: 0x23_u8, a: [0x1_u8, 0x2_u8, 0x3_u8] }", + ); +} + +#[hdl(outline_generated)] +enum MyEnum0 { + Unit, + V(T), + A(ArrayType, S>), +} + +#[hdl] +#[test] +fn check_my_enum0() { + let ty = MyEnum0[UInt[8]][3]; + assert_eq!( + format!("{ty:?}"), + "MyEnum0 { Unit: (), V: UInt<8>, A: Array, 3> }", + ); + let v = #[hdl(sim)] + ty.Unit(); + assert_eq!(format!("{v:?}"), "Unit"); + let v = #[hdl(sim)] + ty.V(0x23u8); + assert_eq!(format!("{v:?}"), "V(0x23_u8)"); + let v = #[hdl(sim)] + ty.A([1u8, 2, 3]); + assert_eq!(format!("{v:?}"), "A([0x1_u8, 0x2_u8, 0x3_u8])"); +} + +#[hdl(outline_generated, custom_debug())] +enum MyEnum1 { + Unit, + V(T), + A(ArrayType, S>), +} + +impl fmt::Debug for MyEnum1 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { Unit, V, A } = self; + f.debug_struct("Custom") + .field("Unit", Unit) + .field("V", V) + .field("A", A) + .finish() + } +} + +impl SimValueDebug for MyEnum1 { + #[hdl] + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + type SimValueT = ::SimValue; + match value { + SimValueT::::Unit(_) => f.write_str("MyEnum1::Unit"), + SimValueT::::V(v, _) => f.debug_tuple("MyEnum1::V").field(v).finish(), + SimValueT::::A(a, _) => f.debug_tuple("MyEnum1::A").field(a).finish(), + SimValueT::::Unknown(_) => f.write_str("MyEnum1::Unknown"), + } + } +} + +#[hdl] +#[test] +fn check_my_enum1() { + let ty = MyEnum1[UInt[8]][3]; + assert_eq!( + format!("{ty:?}"), + "Custom { Unit: (), V: UInt<8>, A: Array, 3> }", + ); + let v = #[hdl(sim)] + ty.Unit(); + assert_eq!(format!("{v:?}"), "MyEnum1::Unit"); + let v = #[hdl(sim)] + ty.V(0x23u8); + assert_eq!(format!("{v:?}"), "MyEnum1::V(0x23_u8)"); + let v = #[hdl(sim)] + ty.A([1u8, 2, 3]); + assert_eq!(format!("{v:?}"), "MyEnum1::A([0x1_u8, 0x2_u8, 0x3_u8])"); +} diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index 2761cba..9dc0107 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -13,7 +13,7 @@ use fayalite::{ }; use serde_json::json; -#[hdl(outline_generated)] +#[hdl(outline_generated, cmp_eq)] pub enum TestEnum { A, B(UInt<8>), @@ -679,6 +679,366 @@ circuit check_enum_literals: }; } +#[hdl_module(outline_generated)] +pub fn check_enum_cmp_eq() { + #[hdl] + let lhs: TestEnum = m.input(); + #[hdl] + let rhs: TestEnum = m.input(); + #[hdl] + let eq: Bool = m.output(); + connect(eq, lhs.cmp_eq(rhs)); +} + +#[test] +fn test_enum_cmp_eq() { + let _n = SourceLocation::normalize_files_for_tests(); + let m = check_enum_cmp_eq(); + dbg!(m); + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_enums: None, + ..ExportOptions::default() + }, + "/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0 +circuit check_enum_cmp_eq: + type Ty0 = {|A, B: UInt<8>, C: UInt<1>[3]|} + module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1] + input lhs: Ty0 @[module-XXXXXXXXXX.rs 2:1] + input rhs: Ty0 @[module-XXXXXXXXXX.rs 3:1] + output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1] + wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1] + match lhs: @[module-XXXXXXXXXX.rs 5:1] + A: + match rhs: @[module-XXXXXXXXXX.rs 5:1] + A: + connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1] + B(_match_arm_value): + skip + C(_match_arm_value_1): + skip + B(_match_arm_value_2): + match rhs: @[module-XXXXXXXXXX.rs 5:1] + A: + skip + B(_match_arm_value_3): + connect TestEnum_cmp_eq, eq(_match_arm_value_2, _match_arm_value_3) @[module-XXXXXXXXXX.rs 5:1] + C(_match_arm_value_4): + skip + C(_match_arm_value_5): + match rhs: @[module-XXXXXXXXXX.rs 5:1] + A: + skip + B(_match_arm_value_6): + skip + C(_match_arm_value_7): + wire _array_literal_expr: UInt<1>[3] + connect _array_literal_expr[0], eq(_match_arm_value_5[0], _match_arm_value_7[0]) + connect _array_literal_expr[1], eq(_match_arm_value_5[1], _match_arm_value_7[1]) + connect _array_literal_expr[2], eq(_match_arm_value_5[2], _match_arm_value_7[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 TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1] + connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1] +", + }; + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody), + ..ExportOptions::default() + }, + "/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0 +circuit check_enum_cmp_eq: + type Ty0 = {|A, B, C|} + type Ty1 = {tag: Ty0, body: UInt<8>} + module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1] + input lhs: Ty1 @[module-XXXXXXXXXX.rs 2:1] + input rhs: Ty1 @[module-XXXXXXXXXX.rs 3:1] + output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1] + wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1] + match lhs.tag: @[module-XXXXXXXXXX.rs 5:1] + A: + match rhs.tag: @[module-XXXXXXXXXX.rs 5:1] + A: + connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1] + B: + skip + C: + skip + B: + match rhs.tag: @[module-XXXXXXXXXX.rs 5:1] + A: + skip + B: + connect TestEnum_cmp_eq, eq(bits(lhs.body, 7, 0), bits(rhs.body, 7, 0)) @[module-XXXXXXXXXX.rs 5:1] + C: + skip + C: + match rhs.tag: @[module-XXXXXXXXXX.rs 5:1] + A: + skip + B: + skip + C: + wire _array_literal_expr: UInt<1>[3] + wire _cast_bits_to_array_expr: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened[0], bits(bits(lhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] + connect _cast_bits_to_array_expr_flattened[1], bits(bits(lhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] + connect _cast_bits_to_array_expr_flattened[2], bits(bits(lhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] + wire _cast_bits_to_array_expr_1: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(rhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0] + connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(rhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1] + connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(rhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2] + connect _array_literal_expr[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0]) + wire _cast_bits_to_array_expr_2: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_2[0], bits(bits(lhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_2[0], _cast_bits_to_array_expr_flattened_2[0] + connect _cast_bits_to_array_expr_flattened_2[1], bits(bits(lhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_flattened_2[1] + connect _cast_bits_to_array_expr_flattened_2[2], bits(bits(lhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_2[2], _cast_bits_to_array_expr_flattened_2[2] + wire _cast_bits_to_array_expr_3: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_3: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_3[0], bits(bits(rhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_3[0], _cast_bits_to_array_expr_flattened_3[0] + connect _cast_bits_to_array_expr_flattened_3[1], bits(bits(rhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_3[1], _cast_bits_to_array_expr_flattened_3[1] + connect _cast_bits_to_array_expr_flattened_3[2], bits(bits(rhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_3[2], _cast_bits_to_array_expr_flattened_3[2] + connect _array_literal_expr[1], eq(_cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_3[1]) + wire _cast_bits_to_array_expr_4: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_4: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_4[0], bits(bits(lhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_4[0], _cast_bits_to_array_expr_flattened_4[0] + connect _cast_bits_to_array_expr_flattened_4[1], bits(bits(lhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_4[1], _cast_bits_to_array_expr_flattened_4[1] + connect _cast_bits_to_array_expr_flattened_4[2], bits(bits(lhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_flattened_4[2] + wire _cast_bits_to_array_expr_5: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_5: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_5[0], bits(bits(rhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_5[0], _cast_bits_to_array_expr_flattened_5[0] + connect _cast_bits_to_array_expr_flattened_5[1], bits(bits(rhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_5[1], _cast_bits_to_array_expr_flattened_5[1] + connect _cast_bits_to_array_expr_flattened_5[2], bits(bits(rhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_5[2], _cast_bits_to_array_expr_flattened_5[2] + connect _array_literal_expr[2], eq(_cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_5[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 TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1] + connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1] +", + }; + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts), + ..ExportOptions::default() + }, + "/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0 +circuit check_enum_cmp_eq: + type Ty0 = {tag: UInt<2>, body: UInt<8>} + module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1] + input lhs: Ty0 @[module-XXXXXXXXXX.rs 2:1] + input rhs: Ty0 @[module-XXXXXXXXXX.rs 3:1] + output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1] + wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1] + when eq(lhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + when eq(rhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1] + else when eq(rhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + skip + else when eq(lhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + when eq(rhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + skip + else when eq(rhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, eq(bits(lhs.body, 7, 0), bits(rhs.body, 7, 0)) @[module-XXXXXXXXXX.rs 5:1] + else when eq(rhs.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + skip + else when eq(rhs.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + skip + else: + wire _array_literal_expr: UInt<1>[3] + wire _cast_bits_to_array_expr: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened[0], bits(bits(lhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] + connect _cast_bits_to_array_expr_flattened[1], bits(bits(lhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] + connect _cast_bits_to_array_expr_flattened[2], bits(bits(lhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] + wire _cast_bits_to_array_expr_1: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(rhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0] + connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(rhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1] + connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(rhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2] + connect _array_literal_expr[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0]) + wire _cast_bits_to_array_expr_2: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_2[0], bits(bits(lhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_2[0], _cast_bits_to_array_expr_flattened_2[0] + connect _cast_bits_to_array_expr_flattened_2[1], bits(bits(lhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_flattened_2[1] + connect _cast_bits_to_array_expr_flattened_2[2], bits(bits(lhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_2[2], _cast_bits_to_array_expr_flattened_2[2] + wire _cast_bits_to_array_expr_3: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_3: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_3[0], bits(bits(rhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_3[0], _cast_bits_to_array_expr_flattened_3[0] + connect _cast_bits_to_array_expr_flattened_3[1], bits(bits(rhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_3[1], _cast_bits_to_array_expr_flattened_3[1] + connect _cast_bits_to_array_expr_flattened_3[2], bits(bits(rhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_3[2], _cast_bits_to_array_expr_flattened_3[2] + connect _array_literal_expr[1], eq(_cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_3[1]) + wire _cast_bits_to_array_expr_4: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_4: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_4[0], bits(bits(lhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_4[0], _cast_bits_to_array_expr_flattened_4[0] + connect _cast_bits_to_array_expr_flattened_4[1], bits(bits(lhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_4[1], _cast_bits_to_array_expr_flattened_4[1] + connect _cast_bits_to_array_expr_flattened_4[2], bits(bits(lhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_flattened_4[2] + wire _cast_bits_to_array_expr_5: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_5: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_5[0], bits(bits(rhs.body, 2, 0), 0, 0) + connect _cast_bits_to_array_expr_5[0], _cast_bits_to_array_expr_flattened_5[0] + connect _cast_bits_to_array_expr_flattened_5[1], bits(bits(rhs.body, 2, 0), 1, 1) + connect _cast_bits_to_array_expr_5[1], _cast_bits_to_array_expr_flattened_5[1] + connect _cast_bits_to_array_expr_flattened_5[2], bits(bits(rhs.body, 2, 0), 2, 2) + connect _cast_bits_to_array_expr_5[2], _cast_bits_to_array_expr_flattened_5[2] + connect _array_literal_expr[2], eq(_cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_5[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 TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1] + connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1] +", + }; + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_enums: Some(SimplifyEnumsKind::ReplaceWithUInt), + ..ExportOptions::default() + }, + "/test/check_enum_cmp_eq.fir": r"FIRRTL version 3.2.0 +circuit check_enum_cmp_eq: + module check_enum_cmp_eq: @[module-XXXXXXXXXX.rs 1:1] + input lhs: UInt<10> @[module-XXXXXXXXXX.rs 2:1] + input rhs: UInt<10> @[module-XXXXXXXXXX.rs 3:1] + output eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1] + wire TestEnum_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 5:1] + when eq(bits(lhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + when eq(bits(rhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 5:1] + else when eq(bits(rhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + skip + else when eq(bits(lhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + when eq(bits(rhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + skip + else when eq(bits(rhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + connect TestEnum_cmp_eq, eq(bits(bits(lhs, 9, 2), 7, 0), bits(bits(rhs, 9, 2), 7, 0)) @[module-XXXXXXXXXX.rs 5:1] + else when eq(bits(rhs, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 5:1] + skip + else when eq(bits(rhs, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 5:1] + skip + else: + wire _array_literal_expr: UInt<1>[3] + wire _cast_bits_to_array_expr: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened[0], bits(bits(bits(lhs, 9, 2), 2, 0), 0, 0) + connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] + connect _cast_bits_to_array_expr_flattened[1], bits(bits(bits(lhs, 9, 2), 2, 0), 1, 1) + connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] + connect _cast_bits_to_array_expr_flattened[2], bits(bits(bits(lhs, 9, 2), 2, 0), 2, 2) + connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] + wire _cast_bits_to_array_expr_1: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(bits(rhs, 9, 2), 2, 0), 0, 0) + connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0] + connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(bits(rhs, 9, 2), 2, 0), 1, 1) + connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1] + connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(bits(rhs, 9, 2), 2, 0), 2, 2) + connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2] + connect _array_literal_expr[0], eq(_cast_bits_to_array_expr[0], _cast_bits_to_array_expr_1[0]) + wire _cast_bits_to_array_expr_2: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_2: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_2[0], bits(bits(bits(lhs, 9, 2), 2, 0), 0, 0) + connect _cast_bits_to_array_expr_2[0], _cast_bits_to_array_expr_flattened_2[0] + connect _cast_bits_to_array_expr_flattened_2[1], bits(bits(bits(lhs, 9, 2), 2, 0), 1, 1) + connect _cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_flattened_2[1] + connect _cast_bits_to_array_expr_flattened_2[2], bits(bits(bits(lhs, 9, 2), 2, 0), 2, 2) + connect _cast_bits_to_array_expr_2[2], _cast_bits_to_array_expr_flattened_2[2] + wire _cast_bits_to_array_expr_3: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_3: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_3[0], bits(bits(bits(rhs, 9, 2), 2, 0), 0, 0) + connect _cast_bits_to_array_expr_3[0], _cast_bits_to_array_expr_flattened_3[0] + connect _cast_bits_to_array_expr_flattened_3[1], bits(bits(bits(rhs, 9, 2), 2, 0), 1, 1) + connect _cast_bits_to_array_expr_3[1], _cast_bits_to_array_expr_flattened_3[1] + connect _cast_bits_to_array_expr_flattened_3[2], bits(bits(bits(rhs, 9, 2), 2, 0), 2, 2) + connect _cast_bits_to_array_expr_3[2], _cast_bits_to_array_expr_flattened_3[2] + connect _array_literal_expr[1], eq(_cast_bits_to_array_expr_2[1], _cast_bits_to_array_expr_3[1]) + wire _cast_bits_to_array_expr_4: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_4: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_4[0], bits(bits(bits(lhs, 9, 2), 2, 0), 0, 0) + connect _cast_bits_to_array_expr_4[0], _cast_bits_to_array_expr_flattened_4[0] + connect _cast_bits_to_array_expr_flattened_4[1], bits(bits(bits(lhs, 9, 2), 2, 0), 1, 1) + connect _cast_bits_to_array_expr_4[1], _cast_bits_to_array_expr_flattened_4[1] + connect _cast_bits_to_array_expr_flattened_4[2], bits(bits(bits(lhs, 9, 2), 2, 0), 2, 2) + connect _cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_flattened_4[2] + wire _cast_bits_to_array_expr_5: UInt<1>[3] + wire _cast_bits_to_array_expr_flattened_5: UInt<1>[3] + connect _cast_bits_to_array_expr_flattened_5[0], bits(bits(bits(rhs, 9, 2), 2, 0), 0, 0) + connect _cast_bits_to_array_expr_5[0], _cast_bits_to_array_expr_flattened_5[0] + connect _cast_bits_to_array_expr_flattened_5[1], bits(bits(bits(rhs, 9, 2), 2, 0), 1, 1) + connect _cast_bits_to_array_expr_5[1], _cast_bits_to_array_expr_flattened_5[1] + connect _cast_bits_to_array_expr_flattened_5[2], bits(bits(bits(rhs, 9, 2), 2, 0), 2, 2) + connect _cast_bits_to_array_expr_5[2], _cast_bits_to_array_expr_flattened_5[2] + connect _array_literal_expr[2], eq(_cast_bits_to_array_expr_4[2], _cast_bits_to_array_expr_5[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 TestEnum_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1] + connect eq, TestEnum_cmp_eq @[module-XXXXXXXXXX.rs 6:1] +", + }; +} + #[hdl_module(outline_generated)] pub fn check_struct_enum_match() { #[hdl] diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index e57c064..80ae4c2 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -1,12 +1,19 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information +use bitvec::{order::Lsb0, view::BitView}; use fayalite::{ - memory::{ReadStruct, ReadWriteStruct, WriteStruct}, - module::{instance_with_loc, memory_with_init_and_loc, reg_builder_with_loc}, + assert_export_firrtl, + firrtl::ExportOptions, + memory::{ReadStruct, ReadWriteStruct, WriteStruct, splat_mask}, + module::{ + instance_with_loc, memory_with_init_and_loc, reg_builder_with_loc, + transform::simplify_enums::SimplifyEnumsKind, + }, prelude::*, reset::ResetType, sim::vcd::VcdWriterDecls, + ty::SimValueDebug, util::{RcWriter, ready_valid::queue}, }; use std::{collections::BTreeMap, num::NonZeroUsize, rc::Rc}; @@ -550,6 +557,150 @@ fn test_enums() { } } +#[hdl] +pub enum EnumWithSimpleBody { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), +} + +#[hdl_module(outline_generated)] +pub fn enum_with_simple_body() { + #[hdl] + let which_in: UInt<8> = m.input(); + #[hdl] + let data_in: UInt<8> = m.input(); + #[hdl] + let which_out: UInt<8> = m.output(); + #[hdl] + let data_out: UInt<8> = m.output(); + #[hdl] + let enum_out: EnumWithSimpleBody = m.output(); + + #[hdl] + if which_in.cmp_eq(0u8) { + connect(enum_out, EnumWithSimpleBody.A(data_in)); + } else if which_in.cmp_eq(1u8) { + connect(enum_out, EnumWithSimpleBody.B(data_in)); + } else { + connect(enum_out, EnumWithSimpleBody.C(data_in)); + } + + #[hdl] + match enum_out { + EnumWithSimpleBody::A(v) => { + connect(which_out, 0u8); + connect(data_out, v); + } + EnumWithSimpleBody::B(v) => { + connect(which_out, 1u8); + connect(data_out, v); + } + EnumWithSimpleBody::C(v) => { + connect(which_out, 2u8); + connect(data_out, v); + } + } +} + +#[hdl] +#[test] +fn test_enum_with_simple_body() { + let _n = SourceLocation::normalize_files_for_tests(); + let mut sim = Simulation::new(enum_with_simple_body()); + let mut writer = RcWriter::default(); + sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); + for which in 0u8..=2 { + for data in (0..u8::MAX).step_by(45) { + sim.write(sim.io().which_in, which); + sim.write(sim.io().data_in, data); + sim.advance_time(SimDuration::from_micros(1)); + assert_eq!(sim.read(sim.io().which_out).as_int(), which); + assert_eq!(sim.read(sim.io().data_out).as_int(), data); + } + } + sim.flush_traces().unwrap(); + let vcd = String::from_utf8(writer.take()).unwrap(); + println!("####### VCD:\n{vcd}\n#######"); + #[derive(Debug)] + struct WireState<'a> { + name: &'a str, + space_then_id: Option<&'a str>, + value: Option<&'a str>, + } + impl<'a> WireState<'a> { + fn new(name: &'a str) -> Self { + Self { + name, + space_then_id: None, + value: None, + } + } + } + let mut variant_wires = [ + WireState::new("A"), + WireState::new("B"), + WireState::new("C"), + ]; + // check that output .vcd has the proper values for all variants' wires + for (is_last, line) in vcd.lines().map(|line| (false, line)).chain([(true, "")]) { + if let Some(line) = line.strip_prefix("$var wire 8") + && let Some(line) = line.strip_suffix(" $end") + && let Some((space_then_id, state)) = variant_wires + .iter_mut() + .find_map(|state| Some((line.strip_suffix(state.name)?.strip_suffix(" ")?, state))) + { + assert_eq!(space_then_id.chars().next(), Some(' ')); + assert!( + space_then_id + .chars() + .skip(1) + .all(|ch| matches!(ch, '!'..='~')) + ); + assert_eq!(state.space_then_id.replace(space_then_id), None); + } else if line.starts_with("#") || is_last { + let Some(expected_value) = variant_wires[0].value else { + panic!( + "variant {} hasn't been initialized before a timestamp or EOF: {variant_wires:#?}\n\ + line={line:?}", + variant_wires[0].name, + ); + }; + for state in &variant_wires { + assert_eq!( + state.value, + Some(expected_value), + "at a timestamp or EOF: variant value for {} doesn't match expected value.\n\ + {variant_wires:#?}\nline={line:?}", + state.name, + ); + } + } else if line.starts_with("b") { + for state in &mut variant_wires { + let Some(space_then_id) = state.space_then_id else { + let name = state.name; + panic!( + "variant {name} hasn't had an id assigned yet: {variant_wires:#?}\n\ + line={line:?}", + ); + }; + if let Some(value) = line.strip_suffix(space_then_id) { + state.value = Some(value); + break; + } + } + } + } + if vcd != include_str!("sim/expected/enum_with_simple_body.vcd") { + panic!(); + } + let sim_debug = format!("{sim:#?}"); + println!("#######\n{sim_debug}\n#######"); + if sim_debug != include_str!("sim/expected/enum_with_simple_body.txt") { + panic!(); + } +} + #[hdl_module(outline_generated)] pub fn memories() { #[hdl] @@ -2841,3 +2992,621 @@ fn test_queue_4_true_true() { include_str!("sim/expected/queue_4_true_true.txt"), ); } + +#[hdl(outline_generated, custom_debug(sim), cmp_eq)] +pub enum HasCustomDebug { + Text(UInt<512>), + FmtError, +} + +impl HasCustomDebug { + #[hdl] + pub fn new_sim(text: Result<&str, std::fmt::Error>) -> SimValue { + match text { + Ok(text) => { + let mut retval = HasCustomDebug.Text.zero(); + let src = text.as_bytes().view_bits::(); + let dest = retval.bits_mut(); + let len = src.len().min(dest.len()); + dest[..len].clone_from_bitslice(&src[..len]); + #[hdl(sim)] + HasCustomDebug.Text(retval) + } + Err(std::fmt::Error) => + { + #[hdl(sim)] + HasCustomDebug.FmtError() + } + } + } + pub fn new(text: Result<&str, std::fmt::Error>) -> Expr { + Self::new_sim(text).to_expr() + } +} + +impl SimValueDebug for HasCustomDebug { + #[hdl] + fn sim_value_debug( + value: &::SimValue, + f: &mut std::fmt::Formatter<'_>, + ) -> std::fmt::Result { + if f.alternate() { + return #[hdl(sim)] + match value { + Self::FmtError => f.write_str("FmtError"), + Self::Text(text) => f.debug_tuple("Text").field(text).finish(), + }; + } + #[hdl(sim)] + match value { + Self::FmtError => Err(std::fmt::Error), + Self::Text(text) => { + assert_eq!(text.ty().width() % u8::BITS as usize, 0); + let mut bytes = vec![0u8; text.ty().width() / u8::BITS as usize]; + bytes + .view_bits_mut::() + .clone_from_bitslice(text.bits()); + if let Some(len) = bytes.iter().position(|b| *b == 0) { + bytes.truncate(len); + } + f.write_str(&String::from_utf8_lossy(&bytes)) + } + } + } +} + +#[hdl_module(outline_generated)] +pub fn sim_trace_as_string() { + #[hdl] + let clk: Clock = m.input(); + #[hdl] + let read: ReadStruct>, ConstUsize<8>> = m.input(); + #[hdl] + let write: WriteStruct, 2>, ConstUsize<8>> = m.input(); + #[hdl] + let mut mem = memory_with_init([[HasCustomDebug::new(Ok("")).to_trace_as_string(); 2]; 4]); + let read_port = mem.new_read_port(); + connect(read_port.clk, clk); + connect_any(read_port.addr, read.addr); + connect(read_port.en, read.en); + for (l, r) in read.data.iter().zip(read_port.data.iter()) { + connect(l, &**r); + } + let write_port = mem.new_write_port(); + connect(write_port.clk, clk); + connect_any(write_port.addr, write.addr); + connect(write_port.data, write.data); + connect(write_port.en, write.en); + connect(write_port.mask, write.mask); +} + +#[hdl] +#[test] +fn test_sim_trace_as_string() { + let _n = SourceLocation::normalize_files_for_tests(); + let m = sim_trace_as_string(); + let mut sim = Simulation::new(m); + // sim.set_breakpoints_unstable(Default::default(), true); + let mut writer = RcWriter::default(); + sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); + sim.write(sim.io().clk, false); + sim.write(sim.io().read.clk, false); + sim.write(sim.io().write.clk, false); + #[derive(Debug)] + struct TestCase { + read: Option<(u8, [Result<&'static str, std::fmt::Error>; 2])>, + write_addr: Option, + write_data: [Result<&'static str, std::fmt::Error>; 2], + write_mask: [bool; 2], + } + const TEST_CASES: &[TestCase] = &[ + TestCase { + read: None, + write_addr: None, + write_data: [Ok(""); 2], + write_mask: [false; 2], + }, + TestCase { + read: None, + write_addr: Some(0), + write_data: [Ok("mem[0][0]"), Ok("mem[0][1]")], + write_mask: [true; 2], + }, + TestCase { + read: None, + write_addr: Some(1), + write_data: [Ok("mem[1][0]"), Ok("mem[1][1]")], + write_mask: [true; 2], + }, + TestCase { + read: None, + write_addr: Some(2), + write_data: [Ok("mem[2][0]"), Ok("mem[2][1]")], + write_mask: [true; 2], + }, + TestCase { + read: None, + write_addr: Some(3), + write_data: [Ok("mem[3][0]"), Ok("mem[3][1]")], + write_mask: [true; 2], + }, + TestCase { + read: Some((1, [Ok("mem[1][0]"), Ok("mem[1][1]")])), + write_addr: None, + write_data: [Err(std::fmt::Error), Err(std::fmt::Error)], + write_mask: [true; 2], + }, + TestCase { + read: Some((1, [Err(std::fmt::Error), Err(std::fmt::Error)])), + write_addr: Some(1), + write_data: [Err(std::fmt::Error), Err(std::fmt::Error)], + write_mask: [true; 2], + }, + ]; + for test_case in TEST_CASES { + let TestCase { + read, + write_addr, + write_data, + write_mask, + } = test_case; + sim.write(sim.io().read.addr, read.map(|v| v.0).unwrap_or(0)); + sim.write(sim.io().read.en, read.is_some()); + sim.write(sim.io().write.addr, write_addr.unwrap_or(0)); + sim.write(sim.io().write.en, write_addr.is_some()); + sim.write( + sim.io().write.data, + write_data.map(|v| HasCustomDebug::new_sim(v).to_trace_as_string()), + ); + sim.write( + sim.io().write.mask, + write_mask.map(|v| splat_mask(TraceAsString[HasCustomDebug], v.to_expr())), + ); + sim.write(sim.io().clk, false); + sim.advance_time(SimDuration::from_nanos(500)); + sim.write(sim.io().clk, true); + sim.advance_time(SimDuration::from_nanos(500)); + if let Some((_, expected_read_data)) = read { + let read_data = sim.read(sim.io().read.data); + let expected_read_data = expected_read_data + .map(HasCustomDebug::new_sim) + .into_sim_value(); + assert!( + *read_data.inner() == expected_read_data, + "{read_data:#?}\n!= {expected_read_data:#?}", + ); + } + } + sim.flush_traces().unwrap(); + let vcd = String::from_utf8(writer.take()).unwrap(); + println!("####### VCD:\n{vcd}\n#######"); + if vcd != include_str!("sim/expected/sim_trace_as_string.vcd") { + panic!(); + } + let sim_debug = format!("{sim:#?}"); + println!("#######\n{sim_debug}\n#######"); + if sim_debug != include_str!("sim/expected/sim_trace_as_string.txt") { + panic!(); + } +} + +#[test] +fn test_firrtl_trace_as_string() { + let _n = SourceLocation::normalize_files_for_tests(); + let m = sim_trace_as_string(); + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_memories: false, + simplify_enums: None, + ..ExportOptions::default() + }, + "/test/sim_trace_as_string.fir": r#"FIRRTL version 3.2.0 +circuit sim_trace_as_string: %[[ + { + "class": "firrtl.annotations.MemoryFileInlineAnnotation", + "filename": "/test/sim_trace_as_string/mem.mem", + "hexOrBinary": "b", + "target": "~sim_trace_as_string|sim_trace_as_string>mem" + } +]] + type Ty0 = {|Text: UInt<512>, FmtError|} + type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: Ty0[2]} + type Ty2 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: Ty0[2], mask: UInt<1>[2]} + type Ty3 = {addr: UInt<2>, en: UInt<1>, clk: Clock, flip data: Ty0[2]} + type Ty4 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: Ty0[2], mask: UInt<1>[2]} + module sim_trace_as_string: @[module-XXXXXXXXXX.rs 1:1] + input clk: Clock @[module-XXXXXXXXXX.rs 2:1] + input `read`: Ty1 @[module-XXXXXXXXXX.rs 3:1] + input `write`: Ty2 @[module-XXXXXXXXXX.rs 4:1] + mem `mem`: @[module-XXXXXXXXXX.rs 5:1] + data-type => Ty0[2] + depth => 4 + read-latency => 0 + write-latency => 1 + read-under-write => old + reader => r0 + writer => w1 + connect `mem`.r0.clk, clk @[module-XXXXXXXXXX.rs 7:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect `mem`.r0.addr, `read`.addr @[module-XXXXXXXXXX.rs 8:1] + connect `mem`.r0.en, `read`.en @[module-XXXXXXXXXX.rs 9:1] + connect `read`.data[0], `mem`.r0.data[0] @[module-XXXXXXXXXX.rs 10:1] + connect `read`.data[1], `mem`.r0.data[1] @[module-XXXXXXXXXX.rs 10:1] + connect `mem`.w1.clk, clk @[module-XXXXXXXXXX.rs 12:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect `mem`.w1.addr, `write`.addr @[module-XXXXXXXXXX.rs 13:1] + connect `mem`.w1.data, `write`.data @[module-XXXXXXXXXX.rs 14:1] + connect `mem`.w1.en, `write`.en @[module-XXXXXXXXXX.rs 15:1] + connect `mem`.w1.mask, `write`.mask @[module-XXXXXXXXXX.rs 16:1] +"#, + "/test/sim_trace_as_string/mem.mem": r"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +", + }; + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_memories: true, + simplify_enums: None, + ..ExportOptions::default() + }, + "/test/sim_trace_as_string.fir": r#"FIRRTL version 3.2.0 +circuit sim_trace_as_string: %[[ + { + "class": "firrtl.annotations.MemoryFileInlineAnnotation", + "filename": "/test/sim_trace_as_string/mem.mem", + "hexOrBinary": "b", + "target": "~sim_trace_as_string|sim_trace_as_string>mem" + } +]] + type Ty0 = {|Text: UInt<512>, FmtError|} + type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: Ty0[2]} + type Ty2 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: Ty0[2], mask: UInt<1>[2]} + type Ty3 = {addr: UInt<2>, en: UInt<1>, clk: Clock, flip data: Ty0[2]} + type Ty4 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: Ty0[2], mask: UInt<1>[2]} + type Ty5 = {addr: UInt<2>, en: UInt<1>, clk: Clock, flip data: UInt<513>[2]} + type Ty6 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: UInt<513>[2], mask: UInt<1>[2]} + module sim_trace_as_string: @[module-XXXXXXXXXX.rs 1:1] + input clk: Clock @[module-XXXXXXXXXX.rs 2:1] + input `read`: Ty1 @[module-XXXXXXXXXX.rs 3:1] + input `write`: Ty2 @[module-XXXXXXXXXX.rs 4:1] + mem `mem`: @[module-XXXXXXXXXX.rs 5:1] + data-type => UInt<513>[2] + depth => 4 + read-latency => 0 + write-latency => 1 + read-under-write => old + reader => r0 + writer => w1 + wire mem_r0: Ty3 @[module-XXXXXXXXXX.rs 6:1] + wire mem_w1: Ty4 @[module-XXXXXXXXXX.rs 11:1] + wire _cast_bits_to_enum_expr: Ty0 + wire _cast_bits_to_enum_expr_body: UInt<512> + connect _cast_bits_to_enum_expr_body, head(`mem`.r0.data[0], 512) + when eq(UInt<1>(0), tail(`mem`.r0.data[0], 512)): + connect _cast_bits_to_enum_expr, {|Text: UInt<512>, FmtError|}(Text, _cast_bits_to_enum_expr_body) + else: + connect _cast_bits_to_enum_expr, {|Text: UInt<512>, FmtError|}(FmtError) + connect mem_r0.data[0], _cast_bits_to_enum_expr @[module-XXXXXXXXXX.rs 6:1] + wire _cast_bits_to_enum_expr_1: Ty0 + wire _cast_bits_to_enum_expr_body_1: UInt<512> + connect _cast_bits_to_enum_expr_body_1, head(`mem`.r0.data[1], 512) + when eq(UInt<1>(0), tail(`mem`.r0.data[1], 512)): + connect _cast_bits_to_enum_expr_1, {|Text: UInt<512>, FmtError|}(Text, _cast_bits_to_enum_expr_body_1) + else: + connect _cast_bits_to_enum_expr_1, {|Text: UInt<512>, FmtError|}(FmtError) + connect mem_r0.data[1], _cast_bits_to_enum_expr_1 @[module-XXXXXXXXXX.rs 6:1] + wire _cast_enum_to_bits_expr: UInt<513> + match mem_w1.data[0]: + Text(_cast_enum_to_bits_expr_Text): + connect _cast_enum_to_bits_expr, pad(cat(_cast_enum_to_bits_expr_Text, UInt<1>(0)), 513) + FmtError: + connect _cast_enum_to_bits_expr, UInt<513>(1) + connect `mem`.w1.data[0], _cast_enum_to_bits_expr @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.mask[0], mem_w1.mask[0] @[module-XXXXXXXXXX.rs 11:1] + wire _cast_enum_to_bits_expr_1: UInt<513> + match mem_w1.data[1]: + Text(_cast_enum_to_bits_expr_Text_1): + connect _cast_enum_to_bits_expr_1, pad(cat(_cast_enum_to_bits_expr_Text_1, UInt<1>(0)), 513) + FmtError: + connect _cast_enum_to_bits_expr_1, UInt<513>(1) + connect `mem`.w1.data[1], _cast_enum_to_bits_expr_1 @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.mask[1], mem_w1.mask[1] @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 6:1] + connect `mem`.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 6:1] + connect `mem`.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 6:1] + connect `mem`.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 11:1] + connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 7:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect mem_r0.addr, `read`.addr @[module-XXXXXXXXXX.rs 8:1] + connect mem_r0.en, `read`.en @[module-XXXXXXXXXX.rs 9:1] + connect `read`.data[0], mem_r0.data[0] @[module-XXXXXXXXXX.rs 10:1] + connect `read`.data[1], mem_r0.data[1] @[module-XXXXXXXXXX.rs 10:1] + connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 12:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect mem_w1.addr, `write`.addr @[module-XXXXXXXXXX.rs 13:1] + connect mem_w1.data, `write`.data @[module-XXXXXXXXXX.rs 14:1] + connect mem_w1.en, `write`.en @[module-XXXXXXXXXX.rs 15:1] + connect mem_w1.mask, `write`.mask @[module-XXXXXXXXXX.rs 16:1] +"#, + "/test/sim_trace_as_string/mem.mem": r"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +", + }; + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_memories: false, + simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody), + ..ExportOptions::default() + }, + "/test/sim_trace_as_string.fir": r#"FIRRTL version 3.2.0 +circuit sim_trace_as_string: %[[ + { + "class": "firrtl.annotations.MemoryFileInlineAnnotation", + "filename": "/test/sim_trace_as_string/mem.mem", + "hexOrBinary": "b", + "target": "~sim_trace_as_string|sim_trace_as_string>mem" + } +]] + type Ty0 = {|Text, FmtError|} + type Ty1 = {tag: Ty0, body: UInt<512>} + type Ty2 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: Ty1[2]} + type Ty3 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: Ty1[2], mask: UInt<1>[2]} + type Ty4 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: Ty1[2], mask: UInt<1>[2]} + type Ty5 = {tag: UInt<1>, body: UInt<1>} + type Ty6 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: Ty1[2], mask: Ty5[2]} + type Ty7 = {addr: UInt<2>, en: UInt<1>, clk: Clock, flip data: Ty1[2]} + module sim_trace_as_string: @[module-XXXXXXXXXX.rs 1:1] + input clk: Clock @[module-XXXXXXXXXX.rs 2:1] + input `read`: Ty2 @[module-XXXXXXXXXX.rs 3:1] + input `write`: Ty3 @[module-XXXXXXXXXX.rs 4:1] + mem `mem`: @[module-XXXXXXXXXX.rs 5:1] + data-type => Ty1[2] + depth => 4 + read-latency => 0 + write-latency => 1 + read-under-write => old + reader => r0 + writer => w1 + wire mem_w1: Ty4 @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.data, mem_w1.data @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.mask[0].tag, mem_w1.mask[0] @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.mask[0].body, mem_w1.mask[0] @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.mask[1].tag, mem_w1.mask[1] @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.w1.mask[1].body, mem_w1.mask[1] @[module-XXXXXXXXXX.rs 11:1] + connect `mem`.r0.clk, clk @[module-XXXXXXXXXX.rs 7:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect `mem`.r0.addr, `read`.addr @[module-XXXXXXXXXX.rs 8:1] + connect `mem`.r0.en, `read`.en @[module-XXXXXXXXXX.rs 9:1] + connect `read`.data[0], `mem`.r0.data[0] @[module-XXXXXXXXXX.rs 10:1] + connect `read`.data[1], `mem`.r0.data[1] @[module-XXXXXXXXXX.rs 10:1] + connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 12:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect mem_w1.addr, `write`.addr @[module-XXXXXXXXXX.rs 13:1] + connect mem_w1.data, `write`.data @[module-XXXXXXXXXX.rs 14:1] + connect mem_w1.en, `write`.en @[module-XXXXXXXXXX.rs 15:1] + connect mem_w1.mask, `write`.mask @[module-XXXXXXXXXX.rs 16:1] +"#, + "/test/sim_trace_as_string/mem.mem": r"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +", + }; + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + options: ExportOptions { + simplify_memories: true, + simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody), + ..ExportOptions::default() + }, + "/test/sim_trace_as_string.fir": r#"FIRRTL version 3.2.0 +circuit sim_trace_as_string: %[[ + { + "class": "firrtl.annotations.MemoryFileInlineAnnotation", + "filename": "/test/sim_trace_as_string/mem_0_tag.mem", + "hexOrBinary": "b", + "target": "~sim_trace_as_string|sim_trace_as_string>mem_0_tag" + }, + { + "class": "firrtl.annotations.MemoryFileInlineAnnotation", + "filename": "/test/sim_trace_as_string/mem_0_body.mem", + "hexOrBinary": "h", + "target": "~sim_trace_as_string|sim_trace_as_string>mem_0_body" + }, + { + "class": "firrtl.annotations.MemoryFileInlineAnnotation", + "filename": "/test/sim_trace_as_string/mem_1_tag.mem", + "hexOrBinary": "b", + "target": "~sim_trace_as_string|sim_trace_as_string>mem_1_tag" + }, + { + "class": "firrtl.annotations.MemoryFileInlineAnnotation", + "filename": "/test/sim_trace_as_string/mem_1_body.mem", + "hexOrBinary": "h", + "target": "~sim_trace_as_string|sim_trace_as_string>mem_1_body" + } +]] + type Ty0 = {|Text, FmtError|} + type Ty1 = {tag: Ty0, body: UInt<512>} + type Ty2 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: Ty1[2]} + type Ty3 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: Ty1[2], mask: UInt<1>[2]} + type Ty4 = {addr: UInt<2>, en: UInt<1>, clk: Clock, flip data: Ty1[2]} + type Ty5 = {tag: UInt<1>, body: UInt<1>} + type Ty6 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: Ty1[2], mask: Ty5[2]} + type Ty7 = {addr: UInt<2>, en: UInt<1>, clk: Clock, flip data: UInt<1>} + type Ty8 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: UInt<1>, mask: UInt<1>} + type Ty9 = {addr: UInt<2>, en: UInt<1>, clk: Clock, flip data: UInt<512>} + type Ty10 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: UInt<512>, mask: UInt<1>} + type Ty11 = {addr: UInt<2>, en: UInt<1>, clk: Clock, data: Ty1[2], mask: UInt<1>[2]} + module sim_trace_as_string: @[module-XXXXXXXXXX.rs 1:1] + input clk: Clock @[module-XXXXXXXXXX.rs 2:1] + input `read`: Ty2 @[module-XXXXXXXXXX.rs 3:1] + input `write`: Ty3 @[module-XXXXXXXXXX.rs 4:1] + mem mem_0_tag: @[module-XXXXXXXXXX.rs 5:1] + data-type => UInt<1> + depth => 4 + read-latency => 0 + write-latency => 1 + read-under-write => old + reader => r0 + writer => w1 + mem mem_0_body: @[module-XXXXXXXXXX.rs 5:1] + data-type => UInt<512> + depth => 4 + read-latency => 0 + write-latency => 1 + read-under-write => old + reader => r0 + writer => w1 + mem mem_1_tag: @[module-XXXXXXXXXX.rs 5:1] + data-type => UInt<1> + depth => 4 + read-latency => 0 + write-latency => 1 + read-under-write => old + reader => r0 + writer => w1 + mem mem_1_body: @[module-XXXXXXXXXX.rs 5:1] + data-type => UInt<512> + depth => 4 + read-latency => 0 + write-latency => 1 + read-under-write => old + reader => r0 + writer => w1 + wire mem_r0: Ty4 @[module-XXXXXXXXXX.rs 6:1] + wire mem_w1: Ty6 @[module-XXXXXXXXXX.rs 11:1] + wire _cast_bits_to_enum_expr: Ty0 + when eq(UInt<1>(0), tail(mem_0_tag.r0.data, 0)): + connect _cast_bits_to_enum_expr, {|Text, FmtError|}(Text) + else: + connect _cast_bits_to_enum_expr, {|Text, FmtError|}(FmtError) + connect mem_r0.data[0].tag, _cast_bits_to_enum_expr @[module-XXXXXXXXXX.rs 6:1] + wire _cast_enum_to_bits_expr: UInt<1> + match mem_w1.data[0].tag: + Text: + connect _cast_enum_to_bits_expr, UInt<1>(0) + FmtError: + connect _cast_enum_to_bits_expr, UInt<1>(1) + connect mem_0_tag.w1.data, _cast_enum_to_bits_expr @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_tag.w1.mask, mem_w1.mask[0].tag @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_tag.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 6:1] + connect mem_0_tag.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 6:1] + connect mem_0_tag.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 6:1] + connect mem_0_tag.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_tag.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_tag.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 11:1] + connect mem_r0.data[0].body, mem_0_body.r0.data @[module-XXXXXXXXXX.rs 6:1] + connect mem_0_body.w1.data, mem_w1.data[0].body @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_body.w1.mask, mem_w1.mask[0].body @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_body.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 6:1] + connect mem_0_body.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 6:1] + connect mem_0_body.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 6:1] + connect mem_0_body.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_body.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 11:1] + connect mem_0_body.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 11:1] + wire _cast_bits_to_enum_expr_1: Ty0 + when eq(UInt<1>(0), tail(mem_1_tag.r0.data, 0)): + connect _cast_bits_to_enum_expr_1, {|Text, FmtError|}(Text) + else: + connect _cast_bits_to_enum_expr_1, {|Text, FmtError|}(FmtError) + connect mem_r0.data[1].tag, _cast_bits_to_enum_expr_1 @[module-XXXXXXXXXX.rs 6:1] + wire _cast_enum_to_bits_expr_1: UInt<1> + match mem_w1.data[1].tag: + Text: + connect _cast_enum_to_bits_expr_1, UInt<1>(0) + FmtError: + connect _cast_enum_to_bits_expr_1, UInt<1>(1) + connect mem_1_tag.w1.data, _cast_enum_to_bits_expr_1 @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_tag.w1.mask, mem_w1.mask[1].tag @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_tag.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 6:1] + connect mem_1_tag.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 6:1] + connect mem_1_tag.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 6:1] + connect mem_1_tag.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_tag.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_tag.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 11:1] + connect mem_r0.data[1].body, mem_1_body.r0.data @[module-XXXXXXXXXX.rs 6:1] + connect mem_1_body.w1.data, mem_w1.data[1].body @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_body.w1.mask, mem_w1.mask[1].body @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_body.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 6:1] + connect mem_1_body.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 6:1] + connect mem_1_body.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 6:1] + connect mem_1_body.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_body.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 11:1] + connect mem_1_body.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 11:1] + wire mem_w1_1: Ty11 @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.addr, mem_w1_1.addr @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.en, mem_w1_1.en @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.clk, mem_w1_1.clk @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.data, mem_w1_1.data @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.mask[0].tag, mem_w1_1.mask[0] @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.mask[0].body, mem_w1_1.mask[0] @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.mask[1].tag, mem_w1_1.mask[1] @[module-XXXXXXXXXX.rs 11:1] + connect mem_w1.mask[1].body, mem_w1_1.mask[1] @[module-XXXXXXXXXX.rs 11:1] + connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 7:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect mem_r0.addr, `read`.addr @[module-XXXXXXXXXX.rs 8:1] + connect mem_r0.en, `read`.en @[module-XXXXXXXXXX.rs 9:1] + connect `read`.data[0], mem_r0.data[0] @[module-XXXXXXXXXX.rs 10:1] + connect `read`.data[1], mem_r0.data[1] @[module-XXXXXXXXXX.rs 10:1] + connect mem_w1_1.clk, clk @[module-XXXXXXXXXX.rs 12:1] + ; connect different types: + ; lhs: UInt<2> + ; rhs: UInt<8> + connect mem_w1_1.addr, `write`.addr @[module-XXXXXXXXXX.rs 13:1] + connect mem_w1_1.data, `write`.data @[module-XXXXXXXXXX.rs 14:1] + connect mem_w1_1.en, `write`.en @[module-XXXXXXXXXX.rs 15:1] + connect mem_w1_1.mask, `write`.mask @[module-XXXXXXXXXX.rs 16:1] +"#, + "/test/sim_trace_as_string/mem_0_body.mem": r"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +", + "/test/sim_trace_as_string/mem_0_tag.mem": r"0 +0 +0 +0 +", + "/test/sim_trace_as_string/mem_1_body.mem": r"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +", + "/test/sim_trace_as_string/mem_1_tag.mem": r"0 +0 +0 +0 +", + }; +} diff --git a/crates/fayalite/tests/sim/expected/array_rw.txt b/crates/fayalite/tests/sim/expected/array_rw.txt index 27b040d..271ec3c 100644 --- a/crates/fayalite/tests/sim/expected/array_rw.txt +++ b/crates/fayalite/tests/sim/expected/array_rw.txt @@ -1218,6 +1218,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<8>, }, + maybe_changed: true, state: 0xff, last_state: 0xff, }, @@ -1227,6 +1228,7 @@ Simulation { index: StatePartIndex(1), ty: UInt<8>, }, + maybe_changed: true, state: 0x7f, last_state: 0x7f, }, @@ -1236,6 +1238,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<8>, }, + maybe_changed: true, state: 0x3f, last_state: 0x3f, }, @@ -1245,6 +1248,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1254,6 +1258,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<8>, }, + maybe_changed: true, state: 0x0f, last_state: 0x0f, }, @@ -1263,6 +1268,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x07, last_state: 0x07, }, @@ -1272,6 +1278,7 @@ Simulation { index: StatePartIndex(6), ty: UInt<8>, }, + maybe_changed: true, state: 0x03, last_state: 0x03, }, @@ -1281,6 +1288,7 @@ Simulation { index: StatePartIndex(7), ty: UInt<8>, }, + maybe_changed: true, state: 0x01, last_state: 0x01, }, @@ -1290,6 +1298,7 @@ Simulation { index: StatePartIndex(8), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -1299,6 +1308,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x80, last_state: 0x80, }, @@ -1308,6 +1318,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<8>, }, + maybe_changed: true, state: 0xc0, last_state: 0xc0, }, @@ -1317,6 +1328,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<8>, }, + maybe_changed: true, state: 0xe0, last_state: 0xe0, }, @@ -1326,6 +1338,7 @@ Simulation { index: StatePartIndex(12), ty: UInt<8>, }, + maybe_changed: true, state: 0xf0, last_state: 0xf0, }, @@ -1335,6 +1348,7 @@ Simulation { index: StatePartIndex(13), ty: UInt<8>, }, + maybe_changed: true, state: 0xf8, last_state: 0xf8, }, @@ -1344,6 +1358,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0xfc, last_state: 0xfc, }, @@ -1353,6 +1368,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<8>, }, + maybe_changed: true, state: 0xfe, last_state: 0xfe, }, @@ -1362,6 +1378,7 @@ Simulation { index: StatePartIndex(16), ty: UInt<8>, }, + maybe_changed: true, state: 0xff, last_state: 0xff, }, @@ -1371,6 +1388,7 @@ Simulation { index: StatePartIndex(17), ty: UInt<8>, }, + maybe_changed: true, state: 0x7f, last_state: 0x7f, }, @@ -1380,6 +1398,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x3f, last_state: 0x3f, }, @@ -1389,6 +1408,7 @@ Simulation { index: StatePartIndex(19), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1398,6 +1418,7 @@ Simulation { index: StatePartIndex(20), ty: UInt<8>, }, + maybe_changed: true, state: 0x0f, last_state: 0x0f, }, @@ -1407,6 +1428,7 @@ Simulation { index: StatePartIndex(21), ty: UInt<8>, }, + maybe_changed: true, state: 0x07, last_state: 0x07, }, @@ -1416,6 +1438,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<8>, }, + maybe_changed: true, state: 0x03, last_state: 0x03, }, @@ -1425,6 +1448,7 @@ Simulation { index: StatePartIndex(23), ty: UInt<8>, }, + maybe_changed: true, state: 0x01, last_state: 0x01, }, @@ -1434,6 +1458,7 @@ Simulation { index: StatePartIndex(24), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -1443,6 +1468,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<8>, }, + maybe_changed: true, state: 0x80, last_state: 0x80, }, @@ -1452,6 +1478,7 @@ Simulation { index: StatePartIndex(26), ty: UInt<8>, }, + maybe_changed: true, state: 0xc0, last_state: 0xc0, }, @@ -1461,6 +1488,7 @@ Simulation { index: StatePartIndex(27), ty: UInt<8>, }, + maybe_changed: true, state: 0xe0, last_state: 0xe0, }, @@ -1470,6 +1498,7 @@ Simulation { index: StatePartIndex(28), ty: UInt<8>, }, + maybe_changed: true, state: 0xf0, last_state: 0xf0, }, @@ -1479,6 +1508,7 @@ Simulation { index: StatePartIndex(29), ty: UInt<8>, }, + maybe_changed: true, state: 0xf8, last_state: 0xf8, }, @@ -1488,6 +1518,7 @@ Simulation { index: StatePartIndex(30), ty: UInt<8>, }, + maybe_changed: true, state: 0xfc, last_state: 0xfc, }, @@ -1497,6 +1528,7 @@ Simulation { index: StatePartIndex(31), ty: UInt<8>, }, + maybe_changed: true, state: 0xfe, last_state: 0xe1, }, @@ -1506,6 +1538,7 @@ Simulation { index: StatePartIndex(32), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -1515,6 +1548,7 @@ Simulation { index: StatePartIndex(33), ty: UInt<8>, }, + maybe_changed: true, state: 0xff, last_state: 0xff, }, @@ -1524,6 +1558,7 @@ Simulation { index: StatePartIndex(34), ty: UInt<8>, }, + maybe_changed: true, state: 0x10, last_state: 0x0f, }, @@ -1533,6 +1568,7 @@ Simulation { index: StatePartIndex(35), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0xe1, }, @@ -1541,6 +1577,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1550,6 +1587,7 @@ Simulation { index: StatePartIndex(37), ty: UInt<8>, }, + maybe_changed: true, state: 0xff, last_state: 0xff, }, @@ -1559,6 +1597,7 @@ Simulation { index: StatePartIndex(38), ty: UInt<8>, }, + maybe_changed: true, state: 0x7f, last_state: 0x7f, }, @@ -1568,6 +1607,7 @@ Simulation { index: StatePartIndex(39), ty: UInt<8>, }, + maybe_changed: true, state: 0x3f, last_state: 0x3f, }, @@ -1577,6 +1617,7 @@ Simulation { index: StatePartIndex(40), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1586,6 +1627,7 @@ Simulation { index: StatePartIndex(41), ty: UInt<8>, }, + maybe_changed: true, state: 0x0f, last_state: 0x0f, }, @@ -1595,6 +1637,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x07, last_state: 0x07, }, @@ -1604,6 +1647,7 @@ Simulation { index: StatePartIndex(43), ty: UInt<8>, }, + maybe_changed: true, state: 0x03, last_state: 0x03, }, @@ -1613,6 +1657,7 @@ Simulation { index: StatePartIndex(44), ty: UInt<8>, }, + maybe_changed: true, state: 0x01, last_state: 0x01, }, @@ -1622,6 +1667,7 @@ Simulation { index: StatePartIndex(45), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -1631,6 +1677,7 @@ Simulation { index: StatePartIndex(46), ty: UInt<8>, }, + maybe_changed: true, state: 0x80, last_state: 0x80, }, @@ -1640,6 +1687,7 @@ Simulation { index: StatePartIndex(47), ty: UInt<8>, }, + maybe_changed: true, state: 0xc0, last_state: 0xc0, }, @@ -1649,6 +1697,7 @@ Simulation { index: StatePartIndex(48), ty: UInt<8>, }, + maybe_changed: true, state: 0xe0, last_state: 0xe0, }, @@ -1658,6 +1707,7 @@ Simulation { index: StatePartIndex(49), ty: UInt<8>, }, + maybe_changed: true, state: 0xf0, last_state: 0xf0, }, @@ -1667,6 +1717,7 @@ Simulation { index: StatePartIndex(50), ty: UInt<8>, }, + maybe_changed: true, state: 0xf8, last_state: 0xf8, }, @@ -1676,6 +1727,7 @@ Simulation { index: StatePartIndex(51), ty: UInt<8>, }, + maybe_changed: true, state: 0xfc, last_state: 0xfc, }, @@ -1685,6 +1737,7 @@ Simulation { index: StatePartIndex(52), ty: UInt<8>, }, + maybe_changed: true, state: 0xfe, last_state: 0xe1, }, diff --git a/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt b/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt index d470792..74c03a4 100644 --- a/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt +++ b/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt @@ -155,6 +155,7 @@ Simulation { kind: BigBool { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x1, last_state: 0x0, }, @@ -163,6 +164,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, diff --git a/crates/fayalite/tests/sim/expected/connect_const.txt b/crates/fayalite/tests/sim/expected/connect_const.txt index 56ea4ad..8193fc5 100644 --- a/crates/fayalite/tests/sim/expected/connect_const.txt +++ b/crates/fayalite/tests/sim/expected/connect_const.txt @@ -124,6 +124,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<8>, }, + maybe_changed: true, state: 0x05, last_state: 0x05, }, diff --git a/crates/fayalite/tests/sim/expected/connect_const_reset.txt b/crates/fayalite/tests/sim/expected/connect_const_reset.txt index 6b5814a..5a64923 100644 --- a/crates/fayalite/tests/sim/expected/connect_const_reset.txt +++ b/crates/fayalite/tests/sim/expected/connect_const_reset.txt @@ -175,6 +175,7 @@ Simulation { kind: BigAsyncReset { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -183,6 +184,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, diff --git a/crates/fayalite/tests/sim/expected/counter_async.txt b/crates/fayalite/tests/sim/expected/counter_async.txt index 2bdd665..20d27ac 100644 --- a/crates/fayalite/tests/sim/expected/counter_async.txt +++ b/crates/fayalite/tests/sim/expected/counter_async.txt @@ -332,6 +332,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x1, last_state: 0x0, }, @@ -340,6 +341,7 @@ Simulation { kind: BigAsyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -349,6 +351,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<4>, }, + maybe_changed: true, state: 0x3, last_state: 0x2, }, @@ -358,6 +361,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<4>, }, + maybe_changed: true, state: 0x3, last_state: 0x2, }, diff --git a/crates/fayalite/tests/sim/expected/counter_sync.txt b/crates/fayalite/tests/sim/expected/counter_sync.txt index 87c2098..baa08e7 100644 --- a/crates/fayalite/tests/sim/expected/counter_sync.txt +++ b/crates/fayalite/tests/sim/expected/counter_sync.txt @@ -313,6 +313,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x1, last_state: 0x0, }, @@ -321,6 +322,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -330,6 +332,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<4>, }, + maybe_changed: true, state: 0x3, last_state: 0x2, }, @@ -339,6 +342,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<4>, }, + maybe_changed: true, state: 0x3, last_state: 0x2, }, diff --git a/crates/fayalite/tests/sim/expected/duplicate_names.txt b/crates/fayalite/tests/sim/expected/duplicate_names.txt index 64bbbe6..76338e8 100644 --- a/crates/fayalite/tests/sim/expected/duplicate_names.txt +++ b/crates/fayalite/tests/sim/expected/duplicate_names.txt @@ -137,6 +137,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<8>, }, + maybe_changed: true, state: 0x05, last_state: 0x05, }, @@ -146,6 +147,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<8>, }, + maybe_changed: true, state: 0x06, last_state: 0x06, }, diff --git a/crates/fayalite/tests/sim/expected/enum_with_simple_body.txt b/crates/fayalite/tests/sim/expected/enum_with_simple_body.txt new file mode 100644 index 0000000..6b5af1c --- /dev/null +++ b/crates/fayalite/tests/sim/expected/enum_with_simple_body.txt @@ -0,0 +1,749 @@ +Simulation { + state: State { + insns: Insns { + state_layout: StateLayout { + ty: TypeLayout { + small_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Enum { + A, + B, + C, + }, + }, + ], + .. + }, + big_slots: StatePartLayout { + len: 33, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_in", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: UInt<8>, + }, + SlotDebugData { + name: "", + ty: UInt<8>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: ".0", + ty: UInt<2>, + }, + SlotDebugData { + name: ".1", + ty: UInt<8>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + }, + SlotDebugData { + name: "", + ty: UInt<8>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: ".0", + ty: UInt<2>, + }, + SlotDebugData { + name: ".1", + ty: UInt<8>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + }, + SlotDebugData { + name: ".0", + ty: UInt<2>, + }, + SlotDebugData { + name: ".1", + ty: UInt<8>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: UInt<10>, + }, + SlotDebugData { + name: "", + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + }, + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + memories: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + insns: [ + // at: module-XXXXXXXXXX.rs:1:1 + 0: Const { + dest: StatePartIndex(32), // (0x2) SlotDebugData { name: "", ty: UInt<8> }, + value: 0x2, + }, + 1: Const { + dest: StatePartIndex(27), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + value: 0x2, + }, + 2: Copy { + dest: StatePartIndex(25), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, + src: StatePartIndex(27), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + }, + 3: Copy { + dest: StatePartIndex(26), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> }, + src: StatePartIndex(1), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in", ty: UInt<8> }, + }, + 4: Shl { + dest: StatePartIndex(28), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + lhs: StatePartIndex(26), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> }, + rhs: 2, + }, + 5: Or { + dest: StatePartIndex(29), // (0x386) SlotDebugData { name: "", ty: UInt<10> }, + lhs: StatePartIndex(25), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, + rhs: StatePartIndex(28), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + }, + 6: CastToUInt { + dest: StatePartIndex(30), // (0x386) SlotDebugData { name: "", ty: UInt<10> }, + src: StatePartIndex(29), // (0x386) SlotDebugData { name: "", ty: UInt<10> }, + dest_width: 10, + }, + 7: Copy { + dest: StatePartIndex(31), // (0x386) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + src: StatePartIndex(30), // (0x386) SlotDebugData { name: "", ty: UInt<10> }, + }, + 8: Const { + dest: StatePartIndex(20), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + value: 0x1, + }, + 9: Copy { + dest: StatePartIndex(18), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, + src: StatePartIndex(20), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + }, + 10: Copy { + dest: StatePartIndex(19), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> }, + src: StatePartIndex(1), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in", ty: UInt<8> }, + }, + 11: Shl { + dest: StatePartIndex(21), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + lhs: StatePartIndex(19), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> }, + rhs: 2, + }, + 12: Or { + dest: StatePartIndex(22), // (0x385) SlotDebugData { name: "", ty: UInt<10> }, + lhs: StatePartIndex(18), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, + rhs: StatePartIndex(21), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + }, + 13: CastToUInt { + dest: StatePartIndex(23), // (0x385) SlotDebugData { name: "", ty: UInt<10> }, + src: StatePartIndex(22), // (0x385) SlotDebugData { name: "", ty: UInt<10> }, + dest_width: 10, + }, + 14: Copy { + dest: StatePartIndex(24), // (0x385) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + src: StatePartIndex(23), // (0x385) SlotDebugData { name: "", ty: UInt<10> }, + }, + 15: Const { + dest: StatePartIndex(16), // (0x1) SlotDebugData { name: "", ty: UInt<8> }, + value: 0x1, + }, + 16: CmpEq { + dest: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(0), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_in", ty: UInt<8> }, + rhs: StatePartIndex(16), // (0x1) SlotDebugData { name: "", ty: UInt<8> }, + }, + 17: Const { + dest: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + value: 0x0, + }, + 18: Copy { + dest: StatePartIndex(9), // (0x0) SlotDebugData { name: ".0", ty: UInt<2> }, + src: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + }, + 19: Copy { + dest: StatePartIndex(10), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> }, + src: StatePartIndex(1), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_in", ty: UInt<8> }, + }, + 20: Shl { + dest: StatePartIndex(12), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + lhs: StatePartIndex(10), // (0xe1) SlotDebugData { name: ".1", ty: UInt<8> }, + rhs: 2, + }, + 21: Or { + dest: StatePartIndex(13), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + lhs: StatePartIndex(9), // (0x0) SlotDebugData { name: ".0", ty: UInt<2> }, + rhs: StatePartIndex(12), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + }, + 22: CastToUInt { + dest: StatePartIndex(14), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + src: StatePartIndex(13), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + dest_width: 10, + }, + 23: Copy { + dest: StatePartIndex(15), // (0x384) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + src: StatePartIndex(14), // (0x384) SlotDebugData { name: "", ty: UInt<10> }, + }, + 24: Const { + dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "", ty: UInt<8> }, + value: 0x0, + }, + 25: CmpEq { + dest: StatePartIndex(8), // (0x0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(0), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_in", ty: UInt<8> }, + rhs: StatePartIndex(7), // (0x0) SlotDebugData { name: "", ty: UInt<8> }, + }, + // at: module-XXXXXXXXXX.rs:7:1 + 26: BranchIfZero { + target: 28, + value: StatePartIndex(8), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:8:1 + 27: Copy { + dest: StatePartIndex(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + src: StatePartIndex(15), // (0x384) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + }, + // at: module-XXXXXXXXXX.rs:7:1 + 28: BranchIfNonZero { + target: 33, + value: StatePartIndex(8), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:9:1 + 29: BranchIfZero { + target: 31, + value: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:10:1 + 30: Copy { + dest: StatePartIndex(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + src: StatePartIndex(24), // (0x385) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + }, + // at: module-XXXXXXXXXX.rs:9:1 + 31: BranchIfNonZero { + target: 33, + value: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:11:1 + 32: Copy { + dest: StatePartIndex(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + src: StatePartIndex(31), // (0x386) SlotDebugData { name: "", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 33: Copy { + dest: StatePartIndex(5), // (0x386) SlotDebugData { name: "", ty: UInt<10> }, + src: StatePartIndex(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + }, + 34: SliceInt { + dest: StatePartIndex(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> }, + src: StatePartIndex(5), // (0x386) SlotDebugData { name: "", ty: UInt<10> }, + start: 2, + len: 8, + }, + // at: module-XXXXXXXXXX.rs:6:1 + 35: AndBigWithSmallImmediate { + dest: StatePartIndex(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + lhs: StatePartIndex(4), // (0x386) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::enum_out", ty: Enum {A(UInt<8>), B(UInt<8>), C(UInt<8>)} }, + rhs: 0x3, + }, + // at: module-XXXXXXXXXX.rs:12:1 + 36: BranchIfSmallNeImmediate { + target: 39, + lhs: StatePartIndex(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + rhs: 0x0, + }, + // at: module-XXXXXXXXXX.rs:13:1 + 37: Copy { + dest: StatePartIndex(2), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out", ty: UInt<8> }, + src: StatePartIndex(7), // (0x0) SlotDebugData { name: "", ty: UInt<8> }, + }, + // at: module-XXXXXXXXXX.rs:14:1 + 38: Copy { + dest: StatePartIndex(3), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out", ty: UInt<8> }, + src: StatePartIndex(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> }, + }, + // at: module-XXXXXXXXXX.rs:12:1 + 39: BranchIfSmallNeImmediate { + target: 42, + lhs: StatePartIndex(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + rhs: 0x1, + }, + // at: module-XXXXXXXXXX.rs:15:1 + 40: Copy { + dest: StatePartIndex(2), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out", ty: UInt<8> }, + src: StatePartIndex(16), // (0x1) SlotDebugData { name: "", ty: UInt<8> }, + }, + // at: module-XXXXXXXXXX.rs:16:1 + 41: Copy { + dest: StatePartIndex(3), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out", ty: UInt<8> }, + src: StatePartIndex(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> }, + }, + // at: module-XXXXXXXXXX.rs:12:1 + 42: BranchIfSmallNeImmediate { + target: 45, + lhs: StatePartIndex(0), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + rhs: 0x2, + }, + // at: module-XXXXXXXXXX.rs:17:1 + 43: Copy { + dest: StatePartIndex(2), // (0x2) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::which_out", ty: UInt<8> }, + src: StatePartIndex(32), // (0x2) SlotDebugData { name: "", ty: UInt<8> }, + }, + // at: module-XXXXXXXXXX.rs:18:1 + 44: Copy { + dest: StatePartIndex(3), // (0xe1) SlotDebugData { name: "InstantiatedModule(enum_with_simple_body: enum_with_simple_body).enum_with_simple_body::data_out", ty: UInt<8> }, + src: StatePartIndex(6), // (0xe1) SlotDebugData { name: "", ty: UInt<8> }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 45: Return, + ], + .. + }, + pc: 45, + memory_write_log: [], + memories: StatePart { + value: [], + }, + small_slots: StatePart { + value: [ + 2, + ], + }, + big_slots: StatePart { + value: [ + 2, + 225, + 2 (modified), + 225 (modified), + 902, + 902, + 225, + 0, + 0, + 0, + 225, + 0, + 900, + 900, + 900, + 900, + 1, + 0, + 1, + 225, + 1, + 900, + 901, + 901, + 901, + 2, + 225, + 2, + 900, + 902, + 902, + 902, + 2, + ], + }, + sim_only_slots: StatePart { + value: [], + }, + }, + io: Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }, + main_module: SimulationModuleState { + base_targets: [ + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.which_in, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.data_in, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.which_out, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.data_out, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.enum_out, + ], + uninitialized_ios: {}, + io_targets: { + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.data_in, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.data_out, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.enum_out, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.which_in, + Instance { + name: ::enum_with_simple_body, + instantiated: Module { + name: enum_with_simple_body, + .. + }, + }.which_out, + }, + did_initial_settle: true, + clocks_for_past: {}, + }, + extern_modules: [], + trace_decls: TraceModule { + name: "enum_with_simple_body", + children: [ + TraceModuleIO { + name: "which_in", + child: TraceUInt { + location: TraceScalarId(0), + name: "which_in", + ty: UInt<8>, + flow: Source, + }, + ty: UInt<8>, + flow: Source, + }, + TraceModuleIO { + name: "data_in", + child: TraceUInt { + location: TraceScalarId(1), + name: "data_in", + ty: UInt<8>, + flow: Source, + }, + ty: UInt<8>, + flow: Source, + }, + TraceModuleIO { + name: "which_out", + child: TraceUInt { + location: TraceScalarId(2), + name: "which_out", + ty: UInt<8>, + flow: Sink, + }, + ty: UInt<8>, + flow: Sink, + }, + TraceModuleIO { + name: "data_out", + child: TraceUInt { + location: TraceScalarId(3), + name: "data_out", + ty: UInt<8>, + flow: Sink, + }, + ty: UInt<8>, + flow: Sink, + }, + TraceModuleIO { + name: "enum_out", + child: TraceEnumWithFields { + name: "enum_out", + discriminant: TraceEnumDiscriminant { + location: TraceScalarId(4), + name: "$tag", + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + flow: Sink, + }, + non_empty_fields: [ + TraceUInt { + location: TraceScalarId(5), + name: "A", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(6), + name: "B", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(7), + name: "C", + ty: UInt<8>, + flow: Source, + }, + ], + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + flow: Sink, + }, + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + flow: Sink, + }, + ], + }, + traces: [ + SimTrace { + id: TraceScalarId(0), + kind: BigUInt { + index: StatePartIndex(0), + ty: UInt<8>, + }, + maybe_changed: true, + state: 0x02, + last_state: 0x02, + }, + SimTrace { + id: TraceScalarId(1), + kind: BigUInt { + index: StatePartIndex(1), + ty: UInt<8>, + }, + maybe_changed: true, + state: 0xe1, + last_state: 0xb4, + }, + SimTrace { + id: TraceScalarId(2), + kind: BigUInt { + index: StatePartIndex(2), + ty: UInt<8>, + }, + maybe_changed: true, + state: 0x02, + last_state: 0x02, + }, + SimTrace { + id: TraceScalarId(3), + kind: BigUInt { + index: StatePartIndex(3), + ty: UInt<8>, + }, + maybe_changed: true, + state: 0xe1, + last_state: 0xb4, + }, + SimTrace { + id: TraceScalarId(4), + kind: EnumDiscriminant { + index: StatePartIndex(0), + ty: Enum { + A(UInt<8>), + B(UInt<8>), + C(UInt<8>), + }, + }, + maybe_changed: true, + state: 0x2, + last_state: 0x2, + }, + SimTrace { + id: TraceScalarId(5), + kind: BigUInt { + index: StatePartIndex(6), + ty: UInt<8>, + }, + maybe_changed: true, + state: 0xe1, + last_state: 0xb4, + }, + SimTrace { + id: TraceScalarId(6), + kind: BigUInt { + index: StatePartIndex(6), + ty: UInt<8>, + }, + maybe_changed: true, + state: 0xe1, + last_state: 0xb4, + }, + SimTrace { + id: TraceScalarId(7), + kind: BigUInt { + index: StatePartIndex(6), + ty: UInt<8>, + }, + maybe_changed: true, + state: 0xe1, + last_state: 0xb4, + }, + ], + trace_memories: {}, + trace_writers: [ + Running( + VcdWriter { + finished_init: true, + timescale: 1 ps, + .. + }, + ), + ], + clocks_triggered: [], + event_queue: EventQueue(EventQueueData { + instant: 18 μs, + events: {}, + }), + waiting_sensitivity_sets_by_address: {}, + waiting_sensitivity_sets_by_compiled_value: {}, + .. +} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/enum_with_simple_body.vcd b/crates/fayalite/tests/sim/expected/enum_with_simple_body.vcd new file mode 100644 index 0000000..dfe0dc1 --- /dev/null +++ b/crates/fayalite/tests/sim/expected/enum_with_simple_body.vcd @@ -0,0 +1,133 @@ +$timescale 1 ps $end +$scope module enum_with_simple_body $end +$var wire 8 J&-ne which_in $end +$var wire 8 \7mo/ data_in $end +$var wire 8 ,`>ir which_out $end +$var wire 8 0_gMP data_out $end +$scope struct enum_out $end +$var string 1 kFH/w \$tag $end +$var wire 8 |EI_= A $end +$var wire 8 !pRd4 B $end +$var wire 8 &RAbd C $end +$upscope $end +$upscope $end +$enddefinitions $end +$dumpvars +b0 J&-ne +b0 \7mo/ +b0 ,`>ir +b0 0_gMP +sA\x20(0) kFH/w +b0 |EI_= +b0 !pRd4 +b0 &RAbd +$end +#1000000 +b101101 \7mo/ +b101101 0_gMP +b101101 |EI_= +b101101 !pRd4 +b101101 &RAbd +#2000000 +b1011010 \7mo/ +b1011010 0_gMP +b1011010 |EI_= +b1011010 !pRd4 +b1011010 &RAbd +#3000000 +b10000111 \7mo/ +b10000111 0_gMP +b10000111 |EI_= +b10000111 !pRd4 +b10000111 &RAbd +#4000000 +b10110100 \7mo/ +b10110100 0_gMP +b10110100 |EI_= +b10110100 !pRd4 +b10110100 &RAbd +#5000000 +b11100001 \7mo/ +b11100001 0_gMP +b11100001 |EI_= +b11100001 !pRd4 +b11100001 &RAbd +#6000000 +b1 J&-ne +b0 \7mo/ +b1 ,`>ir +b0 0_gMP +sB\x20(1) kFH/w +b0 |EI_= +b0 !pRd4 +b0 &RAbd +#7000000 +b101101 \7mo/ +b101101 0_gMP +b101101 |EI_= +b101101 !pRd4 +b101101 &RAbd +#8000000 +b1011010 \7mo/ +b1011010 0_gMP +b1011010 |EI_= +b1011010 !pRd4 +b1011010 &RAbd +#9000000 +b10000111 \7mo/ +b10000111 0_gMP +b10000111 |EI_= +b10000111 !pRd4 +b10000111 &RAbd +#10000000 +b10110100 \7mo/ +b10110100 0_gMP +b10110100 |EI_= +b10110100 !pRd4 +b10110100 &RAbd +#11000000 +b11100001 \7mo/ +b11100001 0_gMP +b11100001 |EI_= +b11100001 !pRd4 +b11100001 &RAbd +#12000000 +b10 J&-ne +b0 \7mo/ +b10 ,`>ir +b0 0_gMP +sC\x20(2) kFH/w +b0 |EI_= +b0 !pRd4 +b0 &RAbd +#13000000 +b101101 \7mo/ +b101101 0_gMP +b101101 |EI_= +b101101 !pRd4 +b101101 &RAbd +#14000000 +b1011010 \7mo/ +b1011010 0_gMP +b1011010 |EI_= +b1011010 !pRd4 +b1011010 &RAbd +#15000000 +b10000111 \7mo/ +b10000111 0_gMP +b10000111 |EI_= +b10000111 !pRd4 +b10000111 &RAbd +#16000000 +b10110100 \7mo/ +b10110100 0_gMP +b10110100 |EI_= +b10110100 !pRd4 +b10110100 &RAbd +#17000000 +b11100001 \7mo/ +b11100001 0_gMP +b11100001 |EI_= +b11100001 !pRd4 +b11100001 &RAbd +#18000000 diff --git a/crates/fayalite/tests/sim/expected/enums.txt b/crates/fayalite/tests/sim/expected/enums.txt index a3a52cb..d2da2d9 100644 --- a/crates/fayalite/tests/sim/expected/enums.txt +++ b/crates/fayalite/tests/sim/expected/enums.txt @@ -1746,6 +1746,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x1, last_state: 0x0, }, @@ -1754,6 +1755,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1762,6 +1764,7 @@ Simulation { kind: BigBool { index: StatePartIndex(2), }, + maybe_changed: false, state: 0x1, last_state: 0x1, }, @@ -1771,6 +1774,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<2>, }, + maybe_changed: false, state: 0x2, last_state: 0x2, }, @@ -1780,6 +1784,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<4>, }, + maybe_changed: false, state: 0xf, last_state: 0xf, }, @@ -1789,6 +1794,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1798,6 +1804,7 @@ Simulation { index: StatePartIndex(6), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -1810,6 +1817,7 @@ Simulation { HdlSome(Bundle {0: UInt<1>, 1: Bool}), }, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1819,6 +1827,7 @@ Simulation { index: StatePartIndex(8), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1827,6 +1836,7 @@ Simulation { kind: BigBool { index: StatePartIndex(9), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1839,6 +1849,7 @@ Simulation { HdlSome(Bundle {0: UInt<1>, 1: Bool}), }, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1848,6 +1859,7 @@ Simulation { index: StatePartIndex(16), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1856,6 +1868,7 @@ Simulation { kind: BigBool { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1869,6 +1882,7 @@ Simulation { C(Bundle {a: Array, 2>, b: SInt<2>}), }, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1878,6 +1892,7 @@ Simulation { index: StatePartIndex(27), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1886,6 +1901,7 @@ Simulation { kind: BigBool { index: StatePartIndex(28), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1895,6 +1911,7 @@ Simulation { index: StatePartIndex(34), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1904,6 +1921,7 @@ Simulation { index: StatePartIndex(35), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1913,6 +1931,7 @@ Simulation { index: StatePartIndex(36), ty: SInt<2>, }, + maybe_changed: true, state: 0x3, last_state: 0x3, }, diff --git a/crates/fayalite/tests/sim/expected/extern_module.txt b/crates/fayalite/tests/sim/expected/extern_module.txt index f49106f..48a3af5 100644 --- a/crates/fayalite/tests/sim/expected/extern_module.txt +++ b/crates/fayalite/tests/sim/expected/extern_module.txt @@ -221,6 +221,7 @@ Simulation { kind: BigBool { index: StatePartIndex(0), }, + maybe_changed: false, state: 0x1, last_state: 0x1, }, @@ -229,6 +230,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x1, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/extern_module2.txt b/crates/fayalite/tests/sim/expected/extern_module2.txt index 365830f..d488666 100644 --- a/crates/fayalite/tests/sim/expected/extern_module2.txt +++ b/crates/fayalite/tests/sim/expected/extern_module2.txt @@ -57,7 +57,7 @@ Simulation { big_slots: StatePart { value: [ 0, - 1, + 1 (modified), 101, ], }, @@ -280,6 +280,7 @@ Simulation { kind: BigBool { index: StatePartIndex(0), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -288,6 +289,7 @@ Simulation { kind: BigClock { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -297,6 +299,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<8>, }, + maybe_changed: false, state: 0x65, last_state: 0x65, }, diff --git a/crates/fayalite/tests/sim/expected/last_connect.txt b/crates/fayalite/tests/sim/expected/last_connect.txt index 6a43497..c5d1341 100644 --- a/crates/fayalite/tests/sim/expected/last_connect.txt +++ b/crates/fayalite/tests/sim/expected/last_connect.txt @@ -433,7 +433,7 @@ Simulation { 1, 1, 1, - 7, + 7 (modified), 7, 3, 0, @@ -614,6 +614,7 @@ Simulation { HdlSome(Array), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -622,6 +623,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -630,6 +632,7 @@ Simulation { kind: BigBool { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -638,6 +641,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -646,6 +650,7 @@ Simulation { kind: BigBool { index: StatePartIndex(4), }, + maybe_changed: true, state: 0x1, last_state: 0x0, }, @@ -658,6 +663,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -667,6 +673,7 @@ Simulation { index: StatePartIndex(17), ty: UInt<8>, }, + maybe_changed: true, state: 0x03, last_state: 0x02, }, @@ -676,6 +683,7 @@ Simulation { index: StatePartIndex(20), ty: UInt<8>, }, + maybe_changed: true, state: 0x03, last_state: 0x02, }, diff --git a/crates/fayalite/tests/sim/expected/many_memories.txt b/crates/fayalite/tests/sim/expected/many_memories.txt index c521d72..0d1a6db 100644 --- a/crates/fayalite/tests/sim/expected/many_memories.txt +++ b/crates/fayalite/tests/sim/expected/many_memories.txt @@ -5545,6 +5545,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5553,6 +5554,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5561,6 +5563,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5569,6 +5572,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5578,6 +5582,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5586,6 +5591,7 @@ Simulation { kind: BigBool { index: StatePartIndex(5), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5594,6 +5600,7 @@ Simulation { kind: BigClock { index: StatePartIndex(6), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5602,6 +5609,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5611,6 +5619,7 @@ Simulation { index: StatePartIndex(8), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5619,6 +5628,7 @@ Simulation { kind: BigBool { index: StatePartIndex(9), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5627,6 +5637,7 @@ Simulation { kind: BigClock { index: StatePartIndex(10), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5635,6 +5646,7 @@ Simulation { kind: BigBool { index: StatePartIndex(11), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5644,6 +5656,7 @@ Simulation { index: StatePartIndex(12), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5652,6 +5665,7 @@ Simulation { kind: BigBool { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5660,6 +5674,7 @@ Simulation { kind: BigClock { index: StatePartIndex(14), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5668,6 +5683,7 @@ Simulation { kind: BigBool { index: StatePartIndex(15), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5677,6 +5693,7 @@ Simulation { index: StatePartIndex(16), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5685,6 +5702,7 @@ Simulation { kind: BigBool { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5693,6 +5711,7 @@ Simulation { kind: BigClock { index: StatePartIndex(18), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5701,6 +5720,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5710,6 +5730,7 @@ Simulation { index: StatePartIndex(20), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5718,6 +5739,7 @@ Simulation { kind: BigBool { index: StatePartIndex(21), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5726,6 +5748,7 @@ Simulation { kind: BigClock { index: StatePartIndex(22), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5734,6 +5757,7 @@ Simulation { kind: BigBool { index: StatePartIndex(23), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5743,6 +5767,7 @@ Simulation { index: StatePartIndex(24), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5751,6 +5776,7 @@ Simulation { kind: BigBool { index: StatePartIndex(25), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5759,6 +5785,7 @@ Simulation { kind: BigClock { index: StatePartIndex(26), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5767,6 +5794,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5776,6 +5804,7 @@ Simulation { index: StatePartIndex(28), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -5784,6 +5813,7 @@ Simulation { kind: BigBool { index: StatePartIndex(29), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5792,6 +5822,7 @@ Simulation { kind: BigClock { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5800,6 +5831,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5809,6 +5841,7 @@ Simulation { index: StatePartIndex(32), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5817,6 +5850,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5825,6 +5859,7 @@ Simulation { kind: BigClock { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5833,6 +5868,7 @@ Simulation { kind: BigBool { index: StatePartIndex(35), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5841,6 +5877,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5850,6 +5887,7 @@ Simulation { index: StatePartIndex(37), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5858,6 +5896,7 @@ Simulation { kind: BigBool { index: StatePartIndex(38), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5866,6 +5905,7 @@ Simulation { kind: BigClock { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5874,6 +5914,7 @@ Simulation { kind: BigBool { index: StatePartIndex(40), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5882,6 +5923,7 @@ Simulation { kind: BigBool { index: StatePartIndex(41), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5891,6 +5933,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5899,6 +5942,7 @@ Simulation { kind: BigBool { index: StatePartIndex(43), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5907,6 +5951,7 @@ Simulation { kind: BigClock { index: StatePartIndex(44), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5915,6 +5960,7 @@ Simulation { kind: BigBool { index: StatePartIndex(45), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5923,6 +5969,7 @@ Simulation { kind: BigBool { index: StatePartIndex(46), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5932,6 +5979,7 @@ Simulation { index: StatePartIndex(47), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5940,6 +5988,7 @@ Simulation { kind: BigBool { index: StatePartIndex(48), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5948,6 +5997,7 @@ Simulation { kind: BigClock { index: StatePartIndex(49), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5956,6 +6006,7 @@ Simulation { kind: BigBool { index: StatePartIndex(50), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5964,6 +6015,7 @@ Simulation { kind: BigBool { index: StatePartIndex(51), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -5973,6 +6025,7 @@ Simulation { index: StatePartIndex(52), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5981,6 +6034,7 @@ Simulation { kind: BigBool { index: StatePartIndex(53), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -5989,6 +6043,7 @@ Simulation { kind: BigClock { index: StatePartIndex(54), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -5997,6 +6052,7 @@ Simulation { kind: BigBool { index: StatePartIndex(55), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6005,6 +6061,7 @@ Simulation { kind: BigBool { index: StatePartIndex(56), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6014,6 +6071,7 @@ Simulation { index: StatePartIndex(57), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6022,6 +6080,7 @@ Simulation { kind: BigBool { index: StatePartIndex(58), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6030,6 +6089,7 @@ Simulation { kind: BigClock { index: StatePartIndex(59), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6038,6 +6098,7 @@ Simulation { kind: BigBool { index: StatePartIndex(60), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6046,6 +6107,7 @@ Simulation { kind: BigBool { index: StatePartIndex(61), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6055,6 +6117,7 @@ Simulation { index: StatePartIndex(62), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6063,6 +6126,7 @@ Simulation { kind: BigBool { index: StatePartIndex(63), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6071,6 +6135,7 @@ Simulation { kind: BigClock { index: StatePartIndex(64), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6079,6 +6144,7 @@ Simulation { kind: BigBool { index: StatePartIndex(65), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6087,6 +6153,7 @@ Simulation { kind: BigBool { index: StatePartIndex(66), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6096,6 +6163,7 @@ Simulation { index: StatePartIndex(67), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6104,6 +6172,7 @@ Simulation { kind: BigBool { index: StatePartIndex(68), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6112,6 +6181,7 @@ Simulation { kind: BigClock { index: StatePartIndex(69), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6120,6 +6190,7 @@ Simulation { kind: BigBool { index: StatePartIndex(70), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6128,6 +6199,7 @@ Simulation { kind: BigBool { index: StatePartIndex(71), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6137,6 +6209,7 @@ Simulation { index: StatePartIndex(72), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6145,6 +6218,7 @@ Simulation { kind: BigBool { index: StatePartIndex(73), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6153,6 +6227,7 @@ Simulation { kind: BigClock { index: StatePartIndex(74), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6161,6 +6236,7 @@ Simulation { kind: BigBool { index: StatePartIndex(75), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6170,6 +6246,7 @@ Simulation { index: StatePartIndex(76), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6178,6 +6255,7 @@ Simulation { kind: BigBool { index: StatePartIndex(77), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6186,6 +6264,7 @@ Simulation { kind: BigClock { index: StatePartIndex(78), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6194,6 +6273,7 @@ Simulation { kind: BigBool { index: StatePartIndex(79), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6202,6 +6282,7 @@ Simulation { kind: BigBool { index: StatePartIndex(80), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6211,6 +6292,7 @@ Simulation { index: StatePartIndex(83), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6219,6 +6301,7 @@ Simulation { kind: BigBool { index: StatePartIndex(84), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6227,6 +6310,7 @@ Simulation { kind: BigClock { index: StatePartIndex(85), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6235,6 +6319,7 @@ Simulation { kind: BigBool { index: StatePartIndex(86), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6244,6 +6329,7 @@ Simulation { index: StatePartIndex(87), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6252,6 +6338,7 @@ Simulation { kind: BigBool { index: StatePartIndex(88), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6260,6 +6347,7 @@ Simulation { kind: BigClock { index: StatePartIndex(89), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6268,6 +6356,7 @@ Simulation { kind: BigBool { index: StatePartIndex(90), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6276,6 +6365,7 @@ Simulation { kind: BigBool { index: StatePartIndex(91), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6285,6 +6375,7 @@ Simulation { index: StatePartIndex(94), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6293,6 +6384,7 @@ Simulation { kind: BigBool { index: StatePartIndex(95), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6301,6 +6393,7 @@ Simulation { kind: BigClock { index: StatePartIndex(96), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6309,6 +6402,7 @@ Simulation { kind: BigBool { index: StatePartIndex(97), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6318,6 +6412,7 @@ Simulation { index: StatePartIndex(98), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6326,6 +6421,7 @@ Simulation { kind: BigBool { index: StatePartIndex(99), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6334,6 +6430,7 @@ Simulation { kind: BigClock { index: StatePartIndex(100), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6342,6 +6439,7 @@ Simulation { kind: BigBool { index: StatePartIndex(101), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6350,6 +6448,7 @@ Simulation { kind: BigBool { index: StatePartIndex(102), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6359,6 +6458,7 @@ Simulation { index: StatePartIndex(105), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6367,6 +6467,7 @@ Simulation { kind: BigBool { index: StatePartIndex(106), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6375,6 +6476,7 @@ Simulation { kind: BigClock { index: StatePartIndex(107), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6383,6 +6485,7 @@ Simulation { kind: BigBool { index: StatePartIndex(108), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6392,6 +6495,7 @@ Simulation { index: StatePartIndex(109), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6400,6 +6504,7 @@ Simulation { kind: BigBool { index: StatePartIndex(110), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6408,6 +6513,7 @@ Simulation { kind: BigClock { index: StatePartIndex(111), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6416,6 +6522,7 @@ Simulation { kind: BigBool { index: StatePartIndex(112), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6424,6 +6531,7 @@ Simulation { kind: BigBool { index: StatePartIndex(113), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6433,6 +6541,7 @@ Simulation { index: StatePartIndex(116), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6441,6 +6550,7 @@ Simulation { kind: BigBool { index: StatePartIndex(117), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6449,6 +6559,7 @@ Simulation { kind: BigClock { index: StatePartIndex(118), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6457,6 +6568,7 @@ Simulation { kind: BigBool { index: StatePartIndex(119), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6466,6 +6578,7 @@ Simulation { index: StatePartIndex(120), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6474,6 +6587,7 @@ Simulation { kind: BigBool { index: StatePartIndex(121), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6482,6 +6596,7 @@ Simulation { kind: BigClock { index: StatePartIndex(122), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6490,6 +6605,7 @@ Simulation { kind: BigBool { index: StatePartIndex(123), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6498,6 +6614,7 @@ Simulation { kind: BigBool { index: StatePartIndex(124), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6507,6 +6624,7 @@ Simulation { index: StatePartIndex(127), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6515,6 +6633,7 @@ Simulation { kind: BigBool { index: StatePartIndex(128), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6523,6 +6642,7 @@ Simulation { kind: BigClock { index: StatePartIndex(129), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6531,6 +6651,7 @@ Simulation { kind: BigBool { index: StatePartIndex(130), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6540,6 +6661,7 @@ Simulation { index: StatePartIndex(131), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6548,6 +6670,7 @@ Simulation { kind: BigBool { index: StatePartIndex(132), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6556,6 +6679,7 @@ Simulation { kind: BigClock { index: StatePartIndex(133), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6564,6 +6688,7 @@ Simulation { kind: BigBool { index: StatePartIndex(134), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6572,6 +6697,7 @@ Simulation { kind: BigBool { index: StatePartIndex(135), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6581,6 +6707,7 @@ Simulation { index: StatePartIndex(138), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6589,6 +6716,7 @@ Simulation { kind: BigBool { index: StatePartIndex(139), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6597,6 +6725,7 @@ Simulation { kind: BigClock { index: StatePartIndex(140), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6605,6 +6734,7 @@ Simulation { kind: BigBool { index: StatePartIndex(141), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6614,6 +6744,7 @@ Simulation { index: StatePartIndex(142), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6622,6 +6753,7 @@ Simulation { kind: BigBool { index: StatePartIndex(143), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6630,6 +6762,7 @@ Simulation { kind: BigClock { index: StatePartIndex(144), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6638,6 +6771,7 @@ Simulation { kind: BigBool { index: StatePartIndex(145), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6646,6 +6780,7 @@ Simulation { kind: BigBool { index: StatePartIndex(146), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6655,6 +6790,7 @@ Simulation { index: StatePartIndex(149), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xf, }, @@ -6663,6 +6799,7 @@ Simulation { kind: BigBool { index: StatePartIndex(150), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -6671,6 +6808,7 @@ Simulation { kind: BigClock { index: StatePartIndex(151), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6679,6 +6817,7 @@ Simulation { kind: BigBool { index: StatePartIndex(152), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6688,6 +6827,7 @@ Simulation { index: StatePartIndex(153), ty: UInt<4>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6696,6 +6836,7 @@ Simulation { kind: BigBool { index: StatePartIndex(154), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6704,6 +6845,7 @@ Simulation { kind: BigClock { index: StatePartIndex(155), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -6712,6 +6854,7 @@ Simulation { kind: BigBool { index: StatePartIndex(156), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -6720,6 +6863,7 @@ Simulation { kind: BigBool { index: StatePartIndex(157), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, diff --git a/crates/fayalite/tests/sim/expected/memories.txt b/crates/fayalite/tests/sim/expected/memories.txt index 0358bb3..c96da4f 100644 --- a/crates/fayalite/tests/sim/expected/memories.txt +++ b/crates/fayalite/tests/sim/expected/memories.txt @@ -1168,6 +1168,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<4>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1176,6 +1177,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1184,6 +1186,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1193,6 +1196,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<8>, }, + maybe_changed: true, state: 0xb0, last_state: 0xb0, }, @@ -1202,6 +1206,7 @@ Simulation { index: StatePartIndex(4), ty: SInt<8>, }, + maybe_changed: true, state: 0xc0, last_state: 0xc0, }, @@ -1211,6 +1216,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<4>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1219,6 +1225,7 @@ Simulation { kind: BigBool { index: StatePartIndex(6), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1227,6 +1234,7 @@ Simulation { kind: BigClock { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1236,6 +1244,7 @@ Simulation { index: StatePartIndex(8), ty: UInt<8>, }, + maybe_changed: true, state: 0xd0, last_state: 0xd0, }, @@ -1245,6 +1254,7 @@ Simulation { index: StatePartIndex(9), ty: SInt<8>, }, + maybe_changed: true, state: 0xe0, last_state: 0xe0, }, @@ -1253,6 +1263,7 @@ Simulation { kind: BigBool { index: StatePartIndex(10), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1261,6 +1272,7 @@ Simulation { kind: BigBool { index: StatePartIndex(11), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1270,6 +1282,7 @@ Simulation { index: StatePartIndex(12), ty: UInt<4>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1278,6 +1291,7 @@ Simulation { kind: BigBool { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1286,6 +1300,7 @@ Simulation { kind: BigClock { index: StatePartIndex(14), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1295,6 +1310,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<8>, }, + maybe_changed: true, state: 0xb0, last_state: 0xb0, }, @@ -1304,6 +1320,7 @@ Simulation { index: StatePartIndex(16), ty: SInt<8>, }, + maybe_changed: true, state: 0xc0, last_state: 0xc0, }, @@ -1313,6 +1330,7 @@ Simulation { index: StatePartIndex(17), ty: UInt<4>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1321,6 +1339,7 @@ Simulation { kind: BigBool { index: StatePartIndex(18), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1329,6 +1348,7 @@ Simulation { kind: BigClock { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1338,6 +1358,7 @@ Simulation { index: StatePartIndex(20), ty: UInt<8>, }, + maybe_changed: true, state: 0xd0, last_state: 0xd0, }, @@ -1347,6 +1368,7 @@ Simulation { index: StatePartIndex(21), ty: SInt<8>, }, + maybe_changed: true, state: 0xe0, last_state: 0xe0, }, @@ -1355,6 +1377,7 @@ Simulation { kind: BigBool { index: StatePartIndex(22), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1363,6 +1386,7 @@ Simulation { kind: BigBool { index: StatePartIndex(23), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, diff --git a/crates/fayalite/tests/sim/expected/memories2.txt b/crates/fayalite/tests/sim/expected/memories2.txt index b4041ba..1f78fcf 100644 --- a/crates/fayalite/tests/sim/expected/memories2.txt +++ b/crates/fayalite/tests/sim/expected/memories2.txt @@ -943,6 +943,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<3>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -951,6 +952,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -959,6 +961,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -968,6 +971,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -976,6 +980,7 @@ Simulation { kind: BigBool { index: StatePartIndex(4), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -985,6 +990,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<2>, }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -993,6 +999,7 @@ Simulation { kind: BigBool { index: StatePartIndex(6), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1002,6 +1009,7 @@ Simulation { index: StatePartIndex(7), ty: UInt<3>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1010,6 +1018,7 @@ Simulation { kind: BigBool { index: StatePartIndex(8), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1018,6 +1027,7 @@ Simulation { kind: BigClock { index: StatePartIndex(9), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1030,6 +1040,7 @@ Simulation { HdlSome(Bool), }, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1038,6 +1049,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1046,6 +1058,7 @@ Simulation { kind: BigBool { index: StatePartIndex(11), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1058,6 +1071,7 @@ Simulation { HdlSome(Bool), }, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1066,6 +1080,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1074,6 +1089,7 @@ Simulation { kind: BigBool { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/memories3.txt b/crates/fayalite/tests/sim/expected/memories3.txt index 2213912..75720a8 100644 --- a/crates/fayalite/tests/sim/expected/memories3.txt +++ b/crates/fayalite/tests/sim/expected/memories3.txt @@ -2391,6 +2391,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<3>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2399,6 +2400,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2407,6 +2409,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -2416,6 +2419,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2425,6 +2429,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2434,6 +2439,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2443,6 +2449,7 @@ Simulation { index: StatePartIndex(6), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2452,6 +2459,7 @@ Simulation { index: StatePartIndex(7), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2461,6 +2469,7 @@ Simulation { index: StatePartIndex(8), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2470,6 +2479,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2479,6 +2489,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2488,6 +2499,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<3>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2496,6 +2508,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2504,6 +2517,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -2513,6 +2527,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2522,6 +2537,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2531,6 +2547,7 @@ Simulation { index: StatePartIndex(16), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2540,6 +2557,7 @@ Simulation { index: StatePartIndex(17), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2549,6 +2567,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2558,6 +2577,7 @@ Simulation { index: StatePartIndex(19), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2567,6 +2587,7 @@ Simulation { index: StatePartIndex(20), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2576,6 +2597,7 @@ Simulation { index: StatePartIndex(21), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2584,6 +2606,7 @@ Simulation { kind: BigBool { index: StatePartIndex(22), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2592,6 +2615,7 @@ Simulation { kind: BigBool { index: StatePartIndex(23), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2600,6 +2624,7 @@ Simulation { kind: BigBool { index: StatePartIndex(24), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2608,6 +2633,7 @@ Simulation { kind: BigBool { index: StatePartIndex(25), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2616,6 +2642,7 @@ Simulation { kind: BigBool { index: StatePartIndex(26), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2624,6 +2651,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2632,6 +2660,7 @@ Simulation { kind: BigBool { index: StatePartIndex(28), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2640,6 +2669,7 @@ Simulation { kind: BigBool { index: StatePartIndex(29), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2649,6 +2679,7 @@ Simulation { index: StatePartIndex(30), ty: UInt<3>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2657,6 +2688,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2665,6 +2697,7 @@ Simulation { kind: BigClock { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -2674,6 +2707,7 @@ Simulation { index: StatePartIndex(33), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2683,6 +2717,7 @@ Simulation { index: StatePartIndex(34), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2692,6 +2727,7 @@ Simulation { index: StatePartIndex(35), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2701,6 +2737,7 @@ Simulation { index: StatePartIndex(36), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2710,6 +2747,7 @@ Simulation { index: StatePartIndex(37), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2719,6 +2757,7 @@ Simulation { index: StatePartIndex(38), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2728,6 +2767,7 @@ Simulation { index: StatePartIndex(39), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2737,6 +2777,7 @@ Simulation { index: StatePartIndex(40), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2746,6 +2787,7 @@ Simulation { index: StatePartIndex(57), ty: UInt<3>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2754,6 +2796,7 @@ Simulation { kind: BigBool { index: StatePartIndex(58), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2762,6 +2805,7 @@ Simulation { kind: BigClock { index: StatePartIndex(59), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -2771,6 +2815,7 @@ Simulation { index: StatePartIndex(60), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2780,6 +2825,7 @@ Simulation { index: StatePartIndex(61), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2789,6 +2835,7 @@ Simulation { index: StatePartIndex(62), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2798,6 +2845,7 @@ Simulation { index: StatePartIndex(63), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2807,6 +2855,7 @@ Simulation { index: StatePartIndex(64), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2816,6 +2865,7 @@ Simulation { index: StatePartIndex(65), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2825,6 +2875,7 @@ Simulation { index: StatePartIndex(66), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2834,6 +2885,7 @@ Simulation { index: StatePartIndex(67), ty: UInt<8>, }, + maybe_changed: true, state: 0x00, last_state: 0x00, }, @@ -2842,6 +2894,7 @@ Simulation { kind: BigBool { index: StatePartIndex(68), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2850,6 +2903,7 @@ Simulation { kind: BigBool { index: StatePartIndex(69), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2858,6 +2912,7 @@ Simulation { kind: BigBool { index: StatePartIndex(70), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2866,6 +2921,7 @@ Simulation { kind: BigBool { index: StatePartIndex(71), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2874,6 +2930,7 @@ Simulation { kind: BigBool { index: StatePartIndex(72), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2882,6 +2939,7 @@ Simulation { kind: BigBool { index: StatePartIndex(73), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2890,6 +2948,7 @@ Simulation { kind: BigBool { index: StatePartIndex(74), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2898,6 +2957,7 @@ Simulation { kind: BigBool { index: StatePartIndex(75), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/mod1.txt b/crates/fayalite/tests/sim/expected/mod1.txt index 3f7a55e..a1de89a 100644 --- a/crates/fayalite/tests/sim/expected/mod1.txt +++ b/crates/fayalite/tests/sim/expected/mod1.txt @@ -445,6 +445,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<4>, }, + maybe_changed: true, state: 0xa, last_state: 0x3, }, @@ -454,6 +455,7 @@ Simulation { index: StatePartIndex(1), ty: SInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x3, }, @@ -463,6 +465,7 @@ Simulation { index: StatePartIndex(2), ty: SInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -472,6 +475,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xe, }, @@ -481,6 +485,7 @@ Simulation { index: StatePartIndex(8), ty: UInt<4>, }, + maybe_changed: true, state: 0xa, last_state: 0x3, }, @@ -490,6 +495,7 @@ Simulation { index: StatePartIndex(9), ty: SInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x3, }, @@ -499,6 +505,7 @@ Simulation { index: StatePartIndex(10), ty: SInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -508,6 +515,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xe, }, @@ -517,6 +525,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<4>, }, + maybe_changed: true, state: 0xa, last_state: 0x3, }, @@ -526,6 +535,7 @@ Simulation { index: StatePartIndex(5), ty: SInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x3, }, @@ -535,6 +545,7 @@ Simulation { index: StatePartIndex(6), ty: SInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -544,6 +555,7 @@ Simulation { index: StatePartIndex(7), ty: UInt<4>, }, + maybe_changed: true, state: 0xf, last_state: 0xe, }, diff --git a/crates/fayalite/tests/sim/expected/phantom_const.txt b/crates/fayalite/tests/sim/expected/phantom_const.txt index 94072ac..c9adae4 100644 --- a/crates/fayalite/tests/sim/expected/phantom_const.txt +++ b/crates/fayalite/tests/sim/expected/phantom_const.txt @@ -373,6 +373,7 @@ Simulation { ["a","b"], ), }, + maybe_changed: true, state: PhantomConst, last_state: PhantomConst, }, @@ -383,6 +384,7 @@ Simulation { ["a","b"], ), }, + maybe_changed: true, state: PhantomConst, last_state: PhantomConst, }, @@ -392,6 +394,7 @@ Simulation { index: StatePartIndex(0), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -400,6 +403,7 @@ Simulation { kind: BigBool { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -408,6 +412,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -418,6 +423,7 @@ Simulation { "mem_element", ), }, + maybe_changed: true, state: PhantomConst, last_state: PhantomConst, }, diff --git a/crates/fayalite/tests/sim/expected/queue_1_false_false.txt b/crates/fayalite/tests/sim/expected/queue_1_false_false.txt index 570c08d..e349bbd 100644 --- a/crates/fayalite/tests/sim/expected/queue_1_false_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_1_false_false.txt @@ -1722,6 +1722,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1730,6 +1731,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1742,6 +1744,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1751,6 +1754,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x19, last_state: 0x19, }, @@ -1759,6 +1763,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1771,6 +1776,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1780,6 +1786,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x19, last_state: 0x19, }, @@ -1788,6 +1795,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1797,6 +1805,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1806,6 +1815,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1814,6 +1824,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1822,6 +1833,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1831,6 +1843,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x19, last_state: 0x19, }, @@ -1840,6 +1853,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1848,6 +1862,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1856,6 +1871,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1865,6 +1881,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x19, last_state: 0x19, }, @@ -1873,6 +1890,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1882,6 +1900,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1891,6 +1910,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1899,6 +1919,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1907,6 +1928,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1915,6 +1937,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1923,6 +1946,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1931,6 +1955,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1939,6 +1964,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1947,6 +1973,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1955,6 +1982,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1964,6 +1992,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x19, last_state: 0x19, }, @@ -1973,6 +2002,7 @@ Simulation { index: StatePartIndex(66), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/queue_1_false_true.txt b/crates/fayalite/tests/sim/expected/queue_1_false_true.txt index 5bff275..3a31636 100644 --- a/crates/fayalite/tests/sim/expected/queue_1_false_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_1_false_true.txt @@ -1701,6 +1701,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1709,6 +1710,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1721,6 +1723,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1730,6 +1733,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1738,6 +1742,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1750,6 +1755,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1759,6 +1765,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1767,6 +1774,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1776,6 +1784,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1785,6 +1794,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1793,6 +1803,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1801,6 +1812,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1810,6 +1822,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1819,6 +1832,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1827,6 +1841,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1835,6 +1850,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1844,6 +1860,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1852,6 +1869,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1861,6 +1879,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1870,6 +1889,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1878,6 +1898,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1886,6 +1907,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1894,6 +1916,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1902,6 +1925,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1910,6 +1934,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1918,6 +1943,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1926,6 +1952,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1934,6 +1961,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1943,6 +1971,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1952,6 +1981,7 @@ Simulation { index: StatePartIndex(64), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/queue_1_true_false.txt b/crates/fayalite/tests/sim/expected/queue_1_true_false.txt index d9771dc..9dd3851 100644 --- a/crates/fayalite/tests/sim/expected/queue_1_true_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_1_true_false.txt @@ -1732,6 +1732,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1740,6 +1741,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1752,6 +1754,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1761,6 +1764,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1769,6 +1773,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1781,6 +1786,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1790,6 +1796,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1798,6 +1805,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1807,6 +1815,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1816,6 +1825,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1824,6 +1834,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1832,6 +1843,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1841,6 +1853,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1850,6 +1863,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1858,6 +1872,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1866,6 +1881,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1875,6 +1891,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1883,6 +1900,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1892,6 +1910,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1901,6 +1920,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1909,6 +1929,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1917,6 +1938,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1925,6 +1947,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1933,6 +1956,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1941,6 +1965,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1949,6 +1974,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1957,6 +1983,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1965,6 +1992,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1974,6 +2002,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x1f, last_state: 0x1f, }, @@ -1983,6 +2012,7 @@ Simulation { index: StatePartIndex(66), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/queue_1_true_true.txt b/crates/fayalite/tests/sim/expected/queue_1_true_true.txt index 0e16d2d..5762f24 100644 --- a/crates/fayalite/tests/sim/expected/queue_1_true_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_1_true_true.txt @@ -1711,6 +1711,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1719,6 +1720,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1731,6 +1733,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1740,6 +1743,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1748,6 +1752,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1760,6 +1765,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1769,6 +1775,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1777,6 +1784,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1786,6 +1794,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1795,6 +1804,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1803,6 +1813,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1811,6 +1822,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1820,6 +1832,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1829,6 +1842,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1837,6 +1851,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1845,6 +1860,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1854,6 +1870,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1862,6 +1879,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1871,6 +1889,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1880,6 +1899,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1888,6 +1908,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1896,6 +1917,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1904,6 +1926,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1912,6 +1935,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1920,6 +1944,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1928,6 +1953,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1936,6 +1962,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1944,6 +1971,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1953,6 +1981,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1962,6 +1991,7 @@ Simulation { index: StatePartIndex(64), ty: UInt<0>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/queue_2_false_false.txt b/crates/fayalite/tests/sim/expected/queue_2_false_false.txt index 23b0a7b..c2cb51a 100644 --- a/crates/fayalite/tests/sim/expected/queue_2_false_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_2_false_false.txt @@ -1740,6 +1740,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1748,6 +1749,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1760,6 +1762,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1769,6 +1772,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1777,6 +1781,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1789,6 +1794,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1798,6 +1804,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1806,6 +1813,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1815,6 +1823,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1824,6 +1833,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1832,6 +1842,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1840,6 +1851,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1849,6 +1861,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1858,6 +1871,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1866,6 +1880,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1874,6 +1889,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1883,6 +1899,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1891,6 +1908,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1900,6 +1918,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1909,6 +1928,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1917,6 +1937,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1925,6 +1946,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1933,6 +1955,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1941,6 +1964,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1949,6 +1973,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1957,6 +1982,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1965,6 +1991,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1973,6 +2000,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1982,6 +2010,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x23, last_state: 0x23, }, @@ -1991,6 +2020,7 @@ Simulation { index: StatePartIndex(68), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, diff --git a/crates/fayalite/tests/sim/expected/queue_2_false_true.txt b/crates/fayalite/tests/sim/expected/queue_2_false_true.txt index a057fa7..f229451 100644 --- a/crates/fayalite/tests/sim/expected/queue_2_false_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_2_false_true.txt @@ -1719,6 +1719,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1727,6 +1728,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1739,6 +1741,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1748,6 +1751,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x26, last_state: 0x26, }, @@ -1756,6 +1760,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1768,6 +1773,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1777,6 +1783,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x26, last_state: 0x26, }, @@ -1785,6 +1792,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1794,6 +1802,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1803,6 +1812,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1811,6 +1821,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1819,6 +1830,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1828,6 +1840,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x26, last_state: 0x26, }, @@ -1837,6 +1850,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1845,6 +1859,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1853,6 +1868,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1862,6 +1878,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x26, last_state: 0x26, }, @@ -1870,6 +1887,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1879,6 +1897,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1888,6 +1907,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1896,6 +1916,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1904,6 +1925,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1912,6 +1934,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1920,6 +1943,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1928,6 +1952,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1936,6 +1961,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1944,6 +1970,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1952,6 +1979,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1961,6 +1989,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x26, last_state: 0x26, }, @@ -1970,6 +1999,7 @@ Simulation { index: StatePartIndex(66), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, diff --git a/crates/fayalite/tests/sim/expected/queue_2_true_false.txt b/crates/fayalite/tests/sim/expected/queue_2_true_false.txt index 1f6d8ec..e137316 100644 --- a/crates/fayalite/tests/sim/expected/queue_2_true_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_2_true_false.txt @@ -1750,6 +1750,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1758,6 +1759,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1770,6 +1772,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1779,6 +1782,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x27, last_state: 0x27, }, @@ -1787,6 +1791,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1799,6 +1804,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1808,6 +1814,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x26, last_state: 0x26, }, @@ -1816,6 +1823,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1825,6 +1833,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1834,6 +1843,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1842,6 +1852,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1850,6 +1861,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1859,6 +1871,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x26, last_state: 0x26, }, @@ -1868,6 +1881,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1876,6 +1890,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1884,6 +1899,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1893,6 +1909,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x27, last_state: 0x27, }, @@ -1901,6 +1918,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1910,6 +1928,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1919,6 +1938,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1927,6 +1947,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1935,6 +1956,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1943,6 +1965,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1951,6 +1974,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1959,6 +1983,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1967,6 +1992,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1975,6 +2001,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1983,6 +2010,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1992,6 +2020,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x27, last_state: 0x27, }, @@ -2001,6 +2030,7 @@ Simulation { index: StatePartIndex(68), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/queue_2_true_true.txt b/crates/fayalite/tests/sim/expected/queue_2_true_true.txt index 25b08a1..5203027 100644 --- a/crates/fayalite/tests/sim/expected/queue_2_true_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_2_true_true.txt @@ -1729,6 +1729,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1737,6 +1738,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1749,6 +1751,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1758,6 +1761,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2a, last_state: 0x2a, }, @@ -1766,6 +1770,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1778,6 +1783,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1787,6 +1793,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1795,6 +1802,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1804,6 +1812,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1813,6 +1822,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1821,6 +1831,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1829,6 +1840,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1838,6 +1850,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1847,6 +1860,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1855,6 +1869,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1863,6 +1878,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1872,6 +1888,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2a, last_state: 0x2a, }, @@ -1880,6 +1897,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1889,6 +1907,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1898,6 +1917,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<1>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1906,6 +1926,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1914,6 +1935,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1922,6 +1944,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1930,6 +1953,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1938,6 +1962,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1946,6 +1971,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1954,6 +1980,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1962,6 +1989,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1971,6 +1999,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2a, last_state: 0x2a, }, @@ -1980,6 +2009,7 @@ Simulation { index: StatePartIndex(66), ty: UInt<1>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/queue_3_false_false.txt b/crates/fayalite/tests/sim/expected/queue_3_false_false.txt index 6f65006..f5641ce 100644 --- a/crates/fayalite/tests/sim/expected/queue_3_false_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_3_false_false.txt @@ -1759,6 +1759,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1767,6 +1768,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1779,6 +1781,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1788,6 +1791,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x28, last_state: 0x28, }, @@ -1796,6 +1800,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1808,6 +1813,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1817,6 +1823,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x27, last_state: 0x27, }, @@ -1825,6 +1832,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1834,6 +1842,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1843,6 +1852,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1851,6 +1861,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1859,6 +1870,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1868,6 +1880,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x27, last_state: 0x27, }, @@ -1877,6 +1890,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1885,6 +1899,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1893,6 +1908,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1902,6 +1918,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x28, last_state: 0x28, }, @@ -1910,6 +1927,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1919,6 +1937,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1928,6 +1947,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1936,6 +1956,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1944,6 +1965,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1952,6 +1974,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1960,6 +1983,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1968,6 +1992,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1976,6 +2001,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1984,6 +2010,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1992,6 +2019,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2001,6 +2029,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x28, last_state: 0x28, }, diff --git a/crates/fayalite/tests/sim/expected/queue_3_false_true.txt b/crates/fayalite/tests/sim/expected/queue_3_false_true.txt index 4cffcd6..cde5489 100644 --- a/crates/fayalite/tests/sim/expected/queue_3_false_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_3_false_true.txt @@ -1738,6 +1738,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1746,6 +1747,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1758,6 +1760,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1767,6 +1770,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2a, last_state: 0x2a, }, @@ -1775,6 +1779,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1787,6 +1792,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1796,6 +1802,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1804,6 +1811,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1813,6 +1821,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1822,6 +1831,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1830,6 +1840,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1838,6 +1849,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1847,6 +1859,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1856,6 +1869,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1864,6 +1878,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1872,6 +1887,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1881,6 +1897,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2a, last_state: 0x2a, }, @@ -1889,6 +1906,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1898,6 +1916,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1907,6 +1926,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1915,6 +1935,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1923,6 +1944,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1931,6 +1953,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1939,6 +1962,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1947,6 +1971,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1955,6 +1980,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1963,6 +1989,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1971,6 +1998,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1980,6 +2008,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2a, last_state: 0x2a, }, diff --git a/crates/fayalite/tests/sim/expected/queue_3_true_false.txt b/crates/fayalite/tests/sim/expected/queue_3_true_false.txt index 03d3aba..d943150 100644 --- a/crates/fayalite/tests/sim/expected/queue_3_true_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_3_true_false.txt @@ -1769,6 +1769,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1777,6 +1778,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1789,6 +1791,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1798,6 +1801,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1806,6 +1810,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1818,6 +1823,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1827,6 +1833,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1835,6 +1842,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1844,6 +1852,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x3, last_state: 0x3, }, @@ -1853,6 +1862,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1861,6 +1871,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1869,6 +1880,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1878,6 +1890,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1887,6 +1900,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1895,6 +1909,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1903,6 +1918,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1912,6 +1928,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1920,6 +1937,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1929,6 +1947,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1938,6 +1957,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1946,6 +1966,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1954,6 +1975,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1962,6 +1984,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1970,6 +1993,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1978,6 +2002,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1986,6 +2011,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1994,6 +2020,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -2002,6 +2029,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -2011,6 +2039,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, diff --git a/crates/fayalite/tests/sim/expected/queue_3_true_true.txt b/crates/fayalite/tests/sim/expected/queue_3_true_true.txt index a663e23..4a0f664 100644 --- a/crates/fayalite/tests/sim/expected/queue_3_true_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_3_true_true.txt @@ -1748,6 +1748,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1756,6 +1757,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1768,6 +1770,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1777,6 +1780,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1785,6 +1789,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1797,6 +1802,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1806,6 +1812,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1814,6 +1821,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1823,6 +1831,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<2>, }, + maybe_changed: true, state: 0x3, last_state: 0x3, }, @@ -1832,6 +1841,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1840,6 +1850,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1848,6 +1859,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1857,6 +1869,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1866,6 +1879,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1874,6 +1888,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1882,6 +1897,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1891,6 +1907,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1899,6 +1916,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1908,6 +1926,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1917,6 +1936,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x2, last_state: 0x2, }, @@ -1925,6 +1945,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1933,6 +1954,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1941,6 +1963,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1949,6 +1972,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1957,6 +1981,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1965,6 +1990,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1973,6 +1999,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1981,6 +2008,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1990,6 +2018,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, diff --git a/crates/fayalite/tests/sim/expected/queue_4_false_false.txt b/crates/fayalite/tests/sim/expected/queue_4_false_false.txt index 445d9d0..4e0a067 100644 --- a/crates/fayalite/tests/sim/expected/queue_4_false_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_4_false_false.txt @@ -1748,6 +1748,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1756,6 +1757,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1768,6 +1770,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1777,6 +1780,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1785,6 +1789,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1797,6 +1802,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1806,6 +1812,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1814,6 +1821,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1823,6 +1831,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<3>, }, + maybe_changed: true, state: 0x3, last_state: 0x3, }, @@ -1832,6 +1841,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1840,6 +1850,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1848,6 +1859,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1857,6 +1869,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1866,6 +1879,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1874,6 +1888,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1882,6 +1897,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1891,6 +1907,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1899,6 +1916,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1908,6 +1926,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1917,6 +1936,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1925,6 +1945,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1933,6 +1954,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1941,6 +1963,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1949,6 +1972,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1957,6 +1981,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1965,6 +1990,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1973,6 +1999,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1981,6 +2008,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1990,6 +2018,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1999,6 +2028,7 @@ Simulation { index: StatePartIndex(68), ty: UInt<2>, }, + maybe_changed: true, state: 0x3, last_state: 0x3, }, diff --git a/crates/fayalite/tests/sim/expected/queue_4_false_true.txt b/crates/fayalite/tests/sim/expected/queue_4_false_true.txt index 5e7ada2..a374f44 100644 --- a/crates/fayalite/tests/sim/expected/queue_4_false_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_4_false_true.txt @@ -1727,6 +1727,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1735,6 +1736,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1747,6 +1749,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1756,6 +1759,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1764,6 +1768,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1776,6 +1781,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1785,6 +1791,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1793,6 +1800,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1802,6 +1810,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<3>, }, + maybe_changed: true, state: 0x3, last_state: 0x3, }, @@ -1811,6 +1820,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1819,6 +1829,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1827,6 +1838,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1836,6 +1848,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1845,6 +1858,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1853,6 +1867,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1861,6 +1876,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1870,6 +1886,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1878,6 +1895,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1887,6 +1905,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1896,6 +1915,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1904,6 +1924,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1912,6 +1933,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1920,6 +1942,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1928,6 +1951,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1936,6 +1960,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1944,6 +1969,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1952,6 +1978,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1960,6 +1987,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1969,6 +1997,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2b, last_state: 0x2b, }, @@ -1978,6 +2007,7 @@ Simulation { index: StatePartIndex(66), ty: UInt<2>, }, + maybe_changed: true, state: 0x3, last_state: 0x3, }, diff --git a/crates/fayalite/tests/sim/expected/queue_4_true_false.txt b/crates/fayalite/tests/sim/expected/queue_4_true_false.txt index 2701c1d..7d20f26 100644 --- a/crates/fayalite/tests/sim/expected/queue_4_true_false.txt +++ b/crates/fayalite/tests/sim/expected/queue_4_true_false.txt @@ -1758,6 +1758,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1766,6 +1767,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1778,6 +1780,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1787,6 +1790,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2c, last_state: 0x2c, }, @@ -1795,6 +1799,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1807,6 +1812,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1816,6 +1822,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1824,6 +1831,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1833,6 +1841,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<3>, }, + maybe_changed: true, state: 0x4, last_state: 0x4, }, @@ -1842,6 +1851,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1850,6 +1860,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1858,6 +1869,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1867,6 +1879,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1876,6 +1889,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1884,6 +1898,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1892,6 +1907,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1901,6 +1917,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2c, last_state: 0x2c, }, @@ -1909,6 +1926,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1918,6 +1936,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1927,6 +1946,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1935,6 +1955,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1943,6 +1964,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1951,6 +1973,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1959,6 +1982,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1967,6 +1991,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1975,6 +2000,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1983,6 +2009,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1991,6 +2018,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -2000,6 +2028,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2c, last_state: 0x2c, }, @@ -2009,6 +2038,7 @@ Simulation { index: StatePartIndex(68), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/queue_4_true_true.txt b/crates/fayalite/tests/sim/expected/queue_4_true_true.txt index a52069d..a0ee509 100644 --- a/crates/fayalite/tests/sim/expected/queue_4_true_true.txt +++ b/crates/fayalite/tests/sim/expected/queue_4_true_true.txt @@ -1737,6 +1737,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1745,6 +1746,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1757,6 +1759,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1766,6 +1769,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: true, state: 0x2c, last_state: 0x2c, }, @@ -1774,6 +1778,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1786,6 +1791,7 @@ Simulation { HdlSome(UInt<8>), }, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1795,6 +1801,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1803,6 +1810,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1812,6 +1820,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<3>, }, + maybe_changed: true, state: 0x4, last_state: 0x4, }, @@ -1821,6 +1830,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1829,6 +1839,7 @@ Simulation { kind: BigBool { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1837,6 +1848,7 @@ Simulation { kind: BigClock { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1846,6 +1858,7 @@ Simulation { index: StatePartIndex(14), ty: UInt<8>, }, + maybe_changed: true, state: 0x29, last_state: 0x29, }, @@ -1855,6 +1868,7 @@ Simulation { index: StatePartIndex(15), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1863,6 +1877,7 @@ Simulation { kind: BigBool { index: StatePartIndex(16), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1871,6 +1886,7 @@ Simulation { kind: BigClock { index: StatePartIndex(17), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -1880,6 +1896,7 @@ Simulation { index: StatePartIndex(18), ty: UInt<8>, }, + maybe_changed: true, state: 0x2c, last_state: 0x2c, }, @@ -1888,6 +1905,7 @@ Simulation { kind: BigBool { index: StatePartIndex(19), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1897,6 +1915,7 @@ Simulation { index: StatePartIndex(22), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1906,6 +1925,7 @@ Simulation { index: StatePartIndex(25), ty: UInt<2>, }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1914,6 +1934,7 @@ Simulation { kind: BigBool { index: StatePartIndex(27), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1922,6 +1943,7 @@ Simulation { kind: BigBool { index: StatePartIndex(30), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1930,6 +1952,7 @@ Simulation { kind: BigBool { index: StatePartIndex(31), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1938,6 +1961,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1946,6 +1970,7 @@ Simulation { kind: BigBool { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1954,6 +1979,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1962,6 +1988,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1970,6 +1997,7 @@ Simulation { kind: BigBool { index: StatePartIndex(39), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1979,6 +2007,7 @@ Simulation { index: StatePartIndex(42), ty: UInt<8>, }, + maybe_changed: true, state: 0x2c, last_state: 0x2c, }, @@ -1988,6 +2017,7 @@ Simulation { index: StatePartIndex(66), ty: UInt<2>, }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/ripple_counter.txt b/crates/fayalite/tests/sim/expected/ripple_counter.txt index 1fb5fee..6562d4d 100644 --- a/crates/fayalite/tests/sim/expected/ripple_counter.txt +++ b/crates/fayalite/tests/sim/expected/ripple_counter.txt @@ -687,18 +687,7 @@ Simulation { 1, 0, 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, + 0 (modified), 0, 0, 0, @@ -709,9 +698,20 @@ Simulation { 1, 0, 0, + 0 (modified), 0, 0, 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0 (modified), + 0, + 0, ], }, sim_only_slots: StatePart { @@ -1284,6 +1284,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: false, state: 0x1, last_state: 0x1, }, @@ -1293,6 +1294,7 @@ Simulation { index: StatePartIndex(1), ty: UInt<6>, }, + maybe_changed: false, state: 0x00, last_state: 0x00, }, @@ -1301,6 +1303,7 @@ Simulation { kind: BigBool { index: StatePartIndex(2), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1309,6 +1312,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1317,6 +1321,7 @@ Simulation { kind: BigBool { index: StatePartIndex(4), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1325,6 +1330,7 @@ Simulation { kind: BigBool { index: StatePartIndex(5), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1333,6 +1339,7 @@ Simulation { kind: BigBool { index: StatePartIndex(6), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1341,6 +1348,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1349,6 +1357,7 @@ Simulation { kind: BigBool { index: StatePartIndex(24), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1357,6 +1366,7 @@ Simulation { kind: BigClock { index: StatePartIndex(33), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1365,6 +1375,7 @@ Simulation { kind: BigBool { index: StatePartIndex(34), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1373,6 +1384,7 @@ Simulation { kind: BigClock { index: StatePartIndex(31), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1381,6 +1393,7 @@ Simulation { kind: BigBool { index: StatePartIndex(32), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1389,6 +1402,7 @@ Simulation { kind: BigBool { index: StatePartIndex(36), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1397,6 +1411,7 @@ Simulation { kind: BigClock { index: StatePartIndex(44), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1405,6 +1420,7 @@ Simulation { kind: BigBool { index: StatePartIndex(45), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1413,6 +1429,7 @@ Simulation { kind: BigClock { index: StatePartIndex(42), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1421,6 +1438,7 @@ Simulation { kind: BigBool { index: StatePartIndex(43), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1429,6 +1447,7 @@ Simulation { kind: BigBool { index: StatePartIndex(47), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1437,6 +1456,7 @@ Simulation { kind: BigClock { index: StatePartIndex(55), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1445,6 +1465,7 @@ Simulation { kind: BigBool { index: StatePartIndex(56), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1453,6 +1474,7 @@ Simulation { kind: BigClock { index: StatePartIndex(53), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -1461,6 +1483,7 @@ Simulation { kind: BigBool { index: StatePartIndex(54), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/shift_register.txt b/crates/fayalite/tests/sim/expected/shift_register.txt index 2e1b176..1eaa378 100644 --- a/crates/fayalite/tests/sim/expected/shift_register.txt +++ b/crates/fayalite/tests/sim/expected/shift_register.txt @@ -458,6 +458,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x1, last_state: 0x0, }, @@ -466,6 +467,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -474,6 +476,7 @@ Simulation { kind: BigBool { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -482,6 +485,7 @@ Simulation { kind: BigBool { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -490,6 +494,7 @@ Simulation { kind: BigBool { index: StatePartIndex(4), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -498,6 +503,7 @@ Simulation { kind: BigBool { index: StatePartIndex(7), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -506,6 +512,7 @@ Simulation { kind: BigBool { index: StatePartIndex(9), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -514,6 +521,7 @@ Simulation { kind: BigBool { index: StatePartIndex(11), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, diff --git a/crates/fayalite/tests/sim/expected/sim_fork_join.txt b/crates/fayalite/tests/sim/expected/sim_fork_join.txt index df9c092..c66e77e 100644 --- a/crates/fayalite/tests/sim/expected/sim_fork_join.txt +++ b/crates/fayalite/tests/sim/expected/sim_fork_join.txt @@ -68,12 +68,12 @@ Simulation { }, big_slots: StatePart { value: [ + 0 (modified), 0, 0, - 0, - 49, - 50, - 50, + 49 (modified), + 50 (modified), + 50 (modified), ], }, sim_only_slots: StatePart { @@ -356,6 +356,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -364,6 +365,7 @@ Simulation { kind: BigClock { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -372,6 +374,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -381,6 +384,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<8>, }, + maybe_changed: false, state: 0x31, last_state: 0x31, }, @@ -390,6 +394,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<8>, }, + maybe_changed: false, state: 0x32, last_state: 0x32, }, @@ -399,6 +404,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: false, state: 0x32, last_state: 0x32, }, diff --git a/crates/fayalite/tests/sim/expected/sim_fork_join_scope.txt b/crates/fayalite/tests/sim/expected/sim_fork_join_scope.txt index 917dd5d..ae88960 100644 --- a/crates/fayalite/tests/sim/expected/sim_fork_join_scope.txt +++ b/crates/fayalite/tests/sim/expected/sim_fork_join_scope.txt @@ -68,12 +68,12 @@ Simulation { }, big_slots: StatePart { value: [ + 0 (modified), 0, 0, - 0, - 49, - 50, - 50, + 49 (modified), + 50 (modified), + 50 (modified), ], }, sim_only_slots: StatePart { @@ -356,6 +356,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -364,6 +365,7 @@ Simulation { kind: BigClock { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -372,6 +374,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -381,6 +384,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<8>, }, + maybe_changed: false, state: 0x31, last_state: 0x31, }, @@ -390,6 +394,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<8>, }, + maybe_changed: false, state: 0x32, last_state: 0x32, }, @@ -399,6 +404,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: false, state: 0x32, last_state: 0x32, }, diff --git a/crates/fayalite/tests/sim/expected/sim_only_connects.txt b/crates/fayalite/tests/sim/expected/sim_only_connects.txt index 827f3cc..2ae2fbe 100644 --- a/crates/fayalite/tests/sim/expected/sim_only_connects.txt +++ b/crates/fayalite/tests/sim/expected/sim_only_connects.txt @@ -392,7 +392,7 @@ Simulation { 0, 1, 0, - 1, + 1 (modified), 0, 0, 0, @@ -400,7 +400,7 @@ Simulation { 0, 1, 0, - 1, + 1 (modified), 0, ], }, @@ -1252,6 +1252,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1260,6 +1261,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1269,6 +1271,7 @@ Simulation { index: StatePartIndex(0), ty: SimOnly>>, }, + maybe_changed: true, state: { "extra": "value", }, @@ -1282,6 +1285,7 @@ Simulation { index: StatePartIndex(1), ty: SimOnly>>, }, + maybe_changed: true, state: { "extra": "value", }, @@ -1295,6 +1299,7 @@ Simulation { index: StatePartIndex(2), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "", "extra": "value", @@ -1312,6 +1317,7 @@ Simulation { index: StatePartIndex(3), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "baz", "extra": "value", @@ -1328,6 +1334,7 @@ Simulation { kind: BigClock { index: StatePartIndex(4), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1336,6 +1343,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(5), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1345,6 +1353,7 @@ Simulation { index: StatePartIndex(6), ty: SimOnly>>, }, + maybe_changed: true, state: { "extra": "value", }, @@ -1358,6 +1367,7 @@ Simulation { index: StatePartIndex(7), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "", "extra": "value", @@ -1374,6 +1384,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1382,6 +1393,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(3), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1391,6 +1403,7 @@ Simulation { index: StatePartIndex(4), ty: SimOnly>>, }, + maybe_changed: true, state: { "extra": "value", }, @@ -1404,6 +1417,7 @@ Simulation { index: StatePartIndex(5), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "", "extra": "value", @@ -1421,6 +1435,7 @@ Simulation { index: StatePartIndex(8), ty: SimOnly>>, }, + maybe_changed: true, state: { "extra": "value", }, @@ -1433,6 +1448,7 @@ Simulation { kind: BigBool { index: StatePartIndex(6), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1441,6 +1457,7 @@ Simulation { kind: BigClock { index: StatePartIndex(12), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1449,6 +1466,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(13), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1458,6 +1476,7 @@ Simulation { index: StatePartIndex(13), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "", "extra": "value", @@ -1475,6 +1494,7 @@ Simulation { index: StatePartIndex(14), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "baz", "extra": "value", @@ -1491,6 +1511,7 @@ Simulation { kind: BigClock { index: StatePartIndex(10), }, + maybe_changed: true, state: 0x1, last_state: 0x1, }, @@ -1499,6 +1520,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(11), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -1508,6 +1530,7 @@ Simulation { index: StatePartIndex(11), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "", "extra": "value", @@ -1525,6 +1548,7 @@ Simulation { index: StatePartIndex(12), ty: SimOnly>>, }, + maybe_changed: true, state: { "bar": "baz", "extra": "value", diff --git a/crates/fayalite/tests/sim/expected/sim_read_past.txt b/crates/fayalite/tests/sim/expected/sim_read_past.txt index 6df4571..f771434 100644 --- a/crates/fayalite/tests/sim/expected/sim_read_past.txt +++ b/crates/fayalite/tests/sim/expected/sim_read_past.txt @@ -530,18 +530,18 @@ Simulation { }, big_slots: StatePart { value: [ + 0 (modified), 0, 0, - 0, - 49, - 50, - 50, - 0, - 1, - 0, - 49, - 49, - 50, + 49 (modified), + 50 (modified), + 50 (modified), + 0 (modified), + 1 (modified), + 0 (modified), + 49 (modified), + 49 (modified), + 50 (modified), 1, 0, 0, @@ -9500,6 +9500,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -9508,6 +9509,7 @@ Simulation { kind: BigClock { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -9516,6 +9518,7 @@ Simulation { kind: BigClock { index: StatePartIndex(2), }, + maybe_changed: true, state: 0x0, last_state: 0x1, }, @@ -9525,6 +9528,7 @@ Simulation { index: StatePartIndex(3), ty: UInt<8>, }, + maybe_changed: false, state: 0x31, last_state: 0x31, }, @@ -9534,6 +9538,7 @@ Simulation { index: StatePartIndex(4), ty: UInt<8>, }, + maybe_changed: false, state: 0x32, last_state: 0x32, }, @@ -9543,6 +9548,7 @@ Simulation { index: StatePartIndex(5), ty: UInt<8>, }, + maybe_changed: false, state: 0x32, last_state: 0x32, }, @@ -9551,6 +9557,7 @@ Simulation { kind: BigClock { index: StatePartIndex(6), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -9559,6 +9566,7 @@ Simulation { kind: BigClock { index: StatePartIndex(7), }, + maybe_changed: false, state: 0x1, last_state: 0x1, }, @@ -9567,6 +9575,7 @@ Simulation { kind: BigClock { index: StatePartIndex(8), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -9576,6 +9585,7 @@ Simulation { index: StatePartIndex(9), ty: UInt<8>, }, + maybe_changed: false, state: 0x31, last_state: 0x31, }, @@ -9585,6 +9595,7 @@ Simulation { index: StatePartIndex(10), ty: UInt<8>, }, + maybe_changed: false, state: 0x31, last_state: 0x31, }, @@ -9594,6 +9605,7 @@ Simulation { index: StatePartIndex(11), ty: UInt<8>, }, + maybe_changed: false, state: 0x32, last_state: 0x32, }, diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.txt index 3fea928..5584b73 100644 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.txt +++ b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.txt @@ -56,8 +56,8 @@ Simulation { }, big_slots: StatePart { value: [ - 0, - 0, + 0 (modified), + 0 (modified), 3, ], }, @@ -310,6 +310,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -318,6 +319,7 @@ Simulation { kind: BigAsyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -327,6 +329,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<8>, }, + maybe_changed: false, state: 0x03, last_state: 0x03, }, diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.txt index 2283ce5..f03c25a 100644 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.txt +++ b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.txt @@ -56,8 +56,8 @@ Simulation { }, big_slots: StatePart { value: [ - 0, - 0, + 0 (modified), + 0 (modified), 3, ], }, @@ -310,6 +310,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -318,6 +319,7 @@ Simulation { kind: BigAsyncReset { index: StatePartIndex(1), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -327,6 +329,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<8>, }, + maybe_changed: false, state: 0x03, last_state: 0x03, }, diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.txt index c77046f..c93d6c1 100644 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.txt +++ b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.txt @@ -56,7 +56,7 @@ Simulation { }, big_slots: StatePart { value: [ - 0, + 0 (modified), 0, 3, ], @@ -310,6 +310,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -318,6 +319,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -327,6 +329,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<8>, }, + maybe_changed: false, state: 0x03, last_state: 0x03, }, diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.txt index e1c565a..f13af84 100644 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.txt +++ b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.txt @@ -56,7 +56,7 @@ Simulation { }, big_slots: StatePart { value: [ - 0, + 0 (modified), 0, 3, ], @@ -310,6 +310,7 @@ Simulation { kind: BigClock { index: StatePartIndex(0), }, + maybe_changed: true, state: 0x0, last_state: 0x0, }, @@ -318,6 +319,7 @@ Simulation { kind: BigSyncReset { index: StatePartIndex(1), }, + maybe_changed: false, state: 0x0, last_state: 0x0, }, @@ -327,6 +329,7 @@ Simulation { index: StatePartIndex(2), ty: UInt<8>, }, + maybe_changed: false, state: 0x03, last_state: 0x03, }, diff --git a/crates/fayalite/tests/sim/expected/sim_trace_as_string.txt b/crates/fayalite/tests/sim/expected/sim_trace_as_string.txt new file mode 100644 index 0000000..0dd374c --- /dev/null +++ b/crates/fayalite/tests/sim/expected/sim_trace_as_string.txt @@ -0,0 +1,2254 @@ +Simulation { + state: State { + insns: Insns { + state_layout: StateLayout { + ty: TypeLayout { + small_slots: StatePartLayout { + len: 12, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + big_slots: StatePartLayout { + len: 31, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.addr", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.addr", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.mask[0]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.mask[1]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.addr", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.addr", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.mask[0]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.mask[1]", + ty: Bool, + }, + SlotDebugData { + name: "[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "[0]", + ty: Bool, + }, + SlotDebugData { + name: "[1]", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + memories: StatePartLayout { + len: 1, + debug_data: [ + (), + ], + layout_data: [ + MemoryData { + array_type: Array), FmtError}, .. }, 2>, 4>, + data: [ + // len = 0x4 + [0x0]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, + [0x1]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, + [0x2]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, + [0x3]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, + ], + }, + ], + .. + }, + }, + insns: [ + // at: module-XXXXXXXXXX.rs:16:1 + 0: Copy { + dest: StatePartIndex(23), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.mask[0]", ty: Bool }, + src: StatePartIndex(11), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.mask[0]", ty: Bool }, + }, + 1: Copy { + dest: StatePartIndex(24), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.mask[1]", ty: Bool }, + src: StatePartIndex(12), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.mask[1]", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:15:1 + 2: Copy { + dest: StatePartIndex(19), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.en", ty: Bool }, + src: StatePartIndex(7), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.en", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:14:1 + 3: Copy { + dest: StatePartIndex(21), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[0]", ty: Enum {Text(UInt<512>), FmtError} }, + src: StatePartIndex(9), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[0]", ty: Enum {Text(UInt<512>), FmtError} }, + }, + 4: Copy { + dest: StatePartIndex(22), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[1]", ty: Enum {Text(UInt<512>), FmtError} }, + src: StatePartIndex(10), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[1]", ty: Enum {Text(UInt<512>), FmtError} }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 5: CastToUInt { + dest: StatePartIndex(30), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(6), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.addr", ty: UInt<8> }, + dest_width: 2, + }, + // at: module-XXXXXXXXXX.rs:13:1 + 6: Copy { + dest: StatePartIndex(18), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.addr", ty: UInt<2> }, + src: StatePartIndex(30), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + }, + // at: module-XXXXXXXXXX.rs:12:1 + 7: Copy { + dest: StatePartIndex(20), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.clk", ty: Clock }, + src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::clk", ty: Clock }, + }, + // at: module-XXXXXXXXXX.rs:9:1 + 8: Copy { + dest: StatePartIndex(14), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.en", ty: Bool }, + src: StatePartIndex(2), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.en", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 9: CastToUInt { + dest: StatePartIndex(29), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(1), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.addr", ty: UInt<8> }, + dest_width: 2, + }, + // at: module-XXXXXXXXXX.rs:8:1 + 10: Copy { + dest: StatePartIndex(13), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.addr", ty: UInt<2> }, + src: StatePartIndex(29), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + }, + // at: module-XXXXXXXXXX.rs:7:1 + 11: Copy { + dest: StatePartIndex(15), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.clk", ty: Clock }, + src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::clk", ty: Clock }, + }, + // at: module-XXXXXXXXXX.rs:5:1 + 12: CastBigToArrayIndex { + dest: StatePartIndex(9), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(18), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.addr", ty: UInt<2> }, + }, + 13: IsNonZeroDestIsSmall { + dest: StatePartIndex(8), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(19), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.en", ty: Bool }, + }, + 14: IsNonZeroDestIsSmall { + dest: StatePartIndex(7), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(20), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.clk", ty: Clock }, + }, + 15: AndSmall { + dest: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(7), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + rhs: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 16: CastBigToArrayIndex { + dest: StatePartIndex(4), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(13), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.addr", ty: UInt<2> }, + }, + 17: IsNonZeroDestIsSmall { + dest: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(14), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.en", ty: Bool }, + }, + 18: BranchIfSmallZero { + target: 22, + value: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + }, + 19: MemoryReadUInt { + dest: StatePartIndex(16), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[0]", ty: Enum {Text(UInt<512>), FmtError} }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array), FmtError}, .. }, 2>, 4>, + // data: [ + // // len = 0x4 + // [0x0]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c16db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba60b6dacada, + // [0x1]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + // [0x2]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c96db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba64b6dacada, + // [0x3]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74cd6db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba66b6dacada, + // ], + // }) (), + addr: StatePartIndex(4), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + stride: 1026, + start: 0, + width: 513, + }, + 20: MemoryReadUInt { + dest: StatePartIndex(17), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[1]", ty: Enum {Text(UInt<512>), FmtError} }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array), FmtError}, .. }, 2>, 4>, + // data: [ + // // len = 0x4 + // [0x0]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c16db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba60b6dacada, + // [0x1]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + // [0x2]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c96db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba64b6dacada, + // [0x3]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74cd6db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba66b6dacada, + // ], + // }) (), + addr: StatePartIndex(4), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + stride: 1026, + start: 513, + width: 513, + }, + 21: Branch { + target: 24, + }, + 22: Const { + dest: StatePartIndex(16), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[0]", ty: Enum {Text(UInt<512>), FmtError} }, + value: 0x0, + }, + 23: Const { + dest: StatePartIndex(17), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[1]", ty: Enum {Text(UInt<512>), FmtError} }, + value: 0x0, + }, + // at: module-XXXXXXXXXX.rs:10:1 + 24: Copy { + dest: StatePartIndex(4), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[0]", ty: Enum {Text(UInt<512>), FmtError} }, + src: StatePartIndex(16), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[0]", ty: Enum {Text(UInt<512>), FmtError} }, + }, + 25: Copy { + dest: StatePartIndex(5), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[1]", ty: Enum {Text(UInt<512>), FmtError} }, + src: StatePartIndex(17), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[1]", ty: Enum {Text(UInt<512>), FmtError} }, + }, + // at: module-XXXXXXXXXX.rs:5:1 + 26: IsNonZeroDestIsSmall { + dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(15), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.clk", ty: Clock }, + }, + 27: AndSmall { + dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + rhs: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 28: BranchIfSmallZero { + target: 29, + value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 29: BranchIfSmallZero { + target: 41, + value: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 30: CopySmall { + dest: StatePartIndex(10), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(9), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + }, + 31: CopySmall { + dest: StatePartIndex(11), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(8), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + }, + 32: Copy { + dest: StatePartIndex(25), // (0x1) SlotDebugData { name: "[0]", ty: Enum {Text(UInt<512>), FmtError} }, + src: StatePartIndex(21), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[0]", ty: Enum {Text(UInt<512>), FmtError} }, + }, + 33: Copy { + dest: StatePartIndex(26), // (0x1) SlotDebugData { name: "[1]", ty: Enum {Text(UInt<512>), FmtError} }, + src: StatePartIndex(22), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[1]", ty: Enum {Text(UInt<512>), FmtError} }, + }, + 34: Copy { + dest: StatePartIndex(27), // (0x1) SlotDebugData { name: "[0]", ty: Bool }, + src: StatePartIndex(23), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.mask[0]", ty: Bool }, + }, + 35: Copy { + dest: StatePartIndex(28), // (0x1) SlotDebugData { name: "[1]", ty: Bool }, + src: StatePartIndex(24), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.mask[1]", ty: Bool }, + }, + 36: BranchIfSmallZero { + target: 41, + value: StatePartIndex(11), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + }, + 37: BranchIfZero { + target: 39, + value: StatePartIndex(27), // (0x1) SlotDebugData { name: "[0]", ty: Bool }, + }, + 38: MemoryWriteUInt { + value: StatePartIndex(25), // (0x1) SlotDebugData { name: "[0]", ty: Enum {Text(UInt<512>), FmtError} }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array), FmtError}, .. }, 2>, 4>, + // data: [ + // // len = 0x4 + // [0x0]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c16db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba60b6dacada, + // [0x1]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + // [0x2]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c96db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba64b6dacada, + // [0x3]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74cd6db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba66b6dacada, + // ], + // }) (), + addr: StatePartIndex(10), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + stride: 1026, + start: 0, + width: 513, + }, + 39: BranchIfZero { + target: 41, + value: StatePartIndex(28), // (0x1) SlotDebugData { name: "[1]", ty: Bool }, + }, + 40: MemoryWriteUInt { + value: StatePartIndex(26), // (0x1) SlotDebugData { name: "[1]", ty: Enum {Text(UInt<512>), FmtError} }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array), FmtError}, .. }, 2>, 4>, + // data: [ + // // len = 0x4 + // [0x0]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c16db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba60b6dacada, + // [0x1]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + // [0x2]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c96db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba64b6dacada, + // [0x3]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74cd6db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba66b6dacada, + // ], + // }) (), + addr: StatePartIndex(10), // (0x1 1) SlotDebugData { name: "", ty: UInt<2> }, + stride: 1026, + start: 513, + width: 513, + }, + 41: XorSmallImmediate { + dest: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + rhs: 0x1, + }, + 42: XorSmallImmediate { + dest: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(7), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + rhs: 0x1, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 43: Return, + ], + .. + }, + pc: 43, + memory_write_log: [], + memories: StatePart { + value: [ + MemoryData { + array_type: Array), FmtError}, .. }, 2>, 4>, + data: [ + // len = 0x4 + [0x0]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c16db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba60b6dacada, + [0x1]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, + [0x2]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74c96db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba64b6dacada, + [0x3]: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000174c56d74cd6db595b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba60b6ba66b6dacada, + ], + }, + ], + }, + small_slots: StatePart { + value: [ + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + ], + }, + big_slots: StatePart { + value: [ + 1, + 1, + 1, + 0, + 1 (modified), + 1 (modified), + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + }, + sim_only_slots: StatePart { + value: [], + }, + }, + io: Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }, + main_module: SimulationModuleState { + base_targets: [ + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.clk, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write, + ], + uninitialized_ios: {}, + io_targets: { + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.clk, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read.addr, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read.clk, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read.data, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read.data., + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read.data.[0], + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read.data.[1], + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.read.en, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.addr, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.clk, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.data, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.data[0], + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.data[0]., + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.data[1], + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.data[1]., + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.en, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.mask, + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.mask[0], + Instance { + name: ::sim_trace_as_string, + instantiated: Module { + name: sim_trace_as_string, + .. + }, + }.write.mask[1], + }, + did_initial_settle: true, + clocks_for_past: {}, + }, + extern_modules: [], + trace_decls: TraceModule { + name: "sim_trace_as_string", + children: [ + TraceModuleIO { + name: "clk", + child: TraceClock { + location: TraceScalarId(0), + name: "clk", + flow: Source, + }, + ty: Clock, + flow: Source, + }, + TraceModuleIO { + name: "read", + child: TraceBundle { + name: "read", + fields: [ + TraceUInt { + location: TraceScalarId(1), + name: "addr", + ty: UInt<8>, + flow: Source, + }, + TraceBool { + location: TraceScalarId(2), + name: "en", + flow: Source, + }, + TraceClock { + location: TraceScalarId(3), + name: "clk", + flow: Source, + }, + TraceTraceAsString { + location: TraceScalarId(4), + name: "data", + ty: TraceAsString { + inner_ty: Array), FmtError}, 2>, + .. + }, + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<8>, + /* offset = 8 */ + en: Bool, + /* offset = 9 */ + clk: Clock, + #[hdl(flip)] /* offset = 10 */ + data: TraceAsString { + inner_ty: Array), FmtError}, 2>, + .. + }, + }, + flow: Source, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<8>, + /* offset = 8 */ + en: Bool, + /* offset = 9 */ + clk: Clock, + #[hdl(flip)] /* offset = 10 */ + data: TraceAsString { + inner_ty: Array), FmtError}, 2>, + .. + }, + }, + flow: Source, + }, + TraceModuleIO { + name: "write", + child: TraceBundle { + name: "write", + fields: [ + TraceUInt { + location: TraceScalarId(5), + name: "addr", + ty: UInt<8>, + flow: Source, + }, + TraceBool { + location: TraceScalarId(6), + name: "en", + flow: Source, + }, + TraceClock { + location: TraceScalarId(7), + name: "clk", + flow: Source, + }, + TraceArray { + name: "data", + elements: [ + TraceTraceAsString { + location: TraceScalarId(8), + name: "[0]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Source, + }, + TraceTraceAsString { + location: TraceScalarId(9), + name: "[1]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Source, + }, + ], + ty: Array), FmtError}, .. }, 2>, + flow: Source, + }, + TraceArray { + name: "mask", + elements: [ + TraceBool { + location: TraceScalarId(10), + name: "[0]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(11), + name: "[1]", + flow: Source, + }, + ], + ty: Array, + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<8>, + /* offset = 8 */ + en: Bool, + /* offset = 9 */ + clk: Clock, + /* offset = 10 */ + data: Array), FmtError}, .. }, 2>, + /* offset = 1036 */ + mask: Array, + }, + flow: Source, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<8>, + /* offset = 8 */ + en: Bool, + /* offset = 9 */ + clk: Clock, + /* offset = 10 */ + data: Array), FmtError}, .. }, 2>, + /* offset = 1036 */ + mask: Array, + }, + flow: Source, + }, + TraceMem { + id: TraceMemoryId(0), + name: "mem", + stride: 1026, + element_type: TraceArray { + name: "mem", + elements: [ + TraceTraceAsString { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 4, + stride: 1026, + start: 0, + len: 513, + }, + name: "[0]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Duplex, + }, + TraceTraceAsString { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 4, + stride: 1026, + start: 513, + len: 513, + }, + name: "[1]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Duplex, + }, + ], + ty: Array), FmtError}, .. }, 2>, + flow: Duplex, + }, + ports: [ + TraceMemPort { + name: "r0", + bundle: TraceBundle { + name: "r0", + fields: [ + TraceUInt { + location: TraceScalarId(12), + name: "addr", + ty: UInt<2>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(13), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(14), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceTraceAsString { + location: TraceScalarId(15), + name: "[0]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Source, + }, + TraceTraceAsString { + location: TraceScalarId(16), + name: "[1]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Source, + }, + ], + ty: Array), FmtError}, .. }, 2>, + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + #[hdl(flip)] /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + #[hdl(flip)] /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + }, + }, + TraceMemPort { + name: "w1", + bundle: TraceBundle { + name: "w1", + fields: [ + TraceUInt { + location: TraceScalarId(17), + name: "addr", + ty: UInt<2>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(18), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(19), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceTraceAsString { + location: TraceScalarId(20), + name: "[0]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Sink, + }, + TraceTraceAsString { + location: TraceScalarId(21), + name: "[1]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Sink, + }, + ], + ty: Array), FmtError}, .. }, 2>, + flow: Sink, + }, + TraceArray { + name: "mask", + elements: [ + TraceBool { + location: TraceScalarId(22), + name: "[0]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(23), + name: "[1]", + flow: Sink, + }, + ], + ty: Array, + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + /* offset = 1030 */ + mask: Array, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + /* offset = 1030 */ + mask: Array, + }, + }, + ], + array_type: Array), FmtError}, .. }, 2>, 4>, + }, + ], + }, + traces: [ + SimTrace { + id: TraceScalarId(0), + kind: BigClock { + index: StatePartIndex(0), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(1), + kind: BigUInt { + index: StatePartIndex(1), + ty: UInt<8>, + }, + maybe_changed: false, + state: 0x01, + last_state: 0x01, + }, + SimTrace { + id: TraceScalarId(2), + kind: BigBool { + index: StatePartIndex(2), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(3), + kind: BigClock { + index: StatePartIndex(3), + }, + maybe_changed: false, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(4), + kind: TraceAsString { + layout: CompiledTypeLayout { + ty: TraceAsString { + inner_ty: Array), FmtError}, 2>, + .. + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Transparent { + inner: CompiledTypeLayout { + ty: Array), FmtError}, 2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Array { + elements_non_empty: [ + CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::read.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + ], + }, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 2 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + }, + maybe_changed: true, + state: OpaqueSimValue { + bits: 0x200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001_u1026, + sim_only_values: [], + }, + last_state: OpaqueSimValue { + bits: 0x174C56D74C56DB595B400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BA60B6BA62B6DACADA_u1026, + sim_only_values: [], + }, + }, + SimTrace { + id: TraceScalarId(5), + kind: BigUInt { + index: StatePartIndex(6), + ty: UInt<8>, + }, + maybe_changed: false, + state: 0x01, + last_state: 0x01, + }, + SimTrace { + id: TraceScalarId(6), + kind: BigBool { + index: StatePartIndex(7), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(7), + kind: BigClock { + index: StatePartIndex(8), + }, + maybe_changed: false, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(8), + kind: TraceAsString { + layout: CompiledTypeLayout { + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Transparent { + inner: CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 9, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + }, + maybe_changed: true, + state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + last_state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + }, + SimTrace { + id: TraceScalarId(9), + kind: TraceAsString { + layout: CompiledTypeLayout { + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Transparent { + inner: CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::write.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 10, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + }, + maybe_changed: true, + state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + last_state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + }, + SimTrace { + id: TraceScalarId(10), + kind: BigBool { + index: StatePartIndex(11), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(11), + kind: BigBool { + index: StatePartIndex(12), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(12), + kind: BigUInt { + index: StatePartIndex(13), + ty: UInt<2>, + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(13), + kind: BigBool { + index: StatePartIndex(14), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(14), + kind: BigClock { + index: StatePartIndex(15), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(15), + kind: TraceAsString { + layout: CompiledTypeLayout { + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Transparent { + inner: CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 16, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + }, + maybe_changed: true, + state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + last_state: OpaqueSimValue { + bits: 0xBA60B6BA62B6DACADA_u513, + sim_only_values: [], + }, + }, + SimTrace { + id: TraceScalarId(16), + kind: TraceAsString { + layout: CompiledTypeLayout { + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Transparent { + inner: CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::r0.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 17, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + }, + maybe_changed: true, + state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + last_state: OpaqueSimValue { + bits: 0xBA62B6BA62B6DACADA_u513, + sim_only_values: [], + }, + }, + SimTrace { + id: TraceScalarId(17), + kind: BigUInt { + index: StatePartIndex(18), + ty: UInt<2>, + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(18), + kind: BigBool { + index: StatePartIndex(19), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(19), + kind: BigClock { + index: StatePartIndex(20), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(20), + kind: TraceAsString { + layout: CompiledTypeLayout { + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Transparent { + inner: CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[0]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 5, len: 0 }, + big_slots: StatePartIndexRange { start: 21, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + }, + maybe_changed: true, + state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + last_state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + }, + SimTrace { + id: TraceScalarId(21), + kind: TraceAsString { + layout: CompiledTypeLayout { + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Transparent { + inner: CompiledTypeLayout { + ty: Enum { + Text(UInt<512>), + FmtError, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(sim_trace_as_string: sim_trace_as_string).sim_trace_as_string::mem::w1.data[1]", + ty: Enum { + Text(UInt<512>), + FmtError, + }, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 5, len: 0 }, + big_slots: StatePartIndexRange { start: 22, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + }, + maybe_changed: true, + state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + last_state: OpaqueSimValue { + bits: 0x1_u513, + sim_only_values: [], + }, + }, + SimTrace { + id: TraceScalarId(22), + kind: BigBool { + index: StatePartIndex(23), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(23), + kind: BigBool { + index: StatePartIndex(24), + }, + maybe_changed: true, + state: 0x1, + last_state: 0x1, + }, + ], + trace_memories: { + StatePartIndex(0): TraceMem { + id: TraceMemoryId(0), + name: "mem", + stride: 1026, + element_type: TraceArray { + name: "mem", + elements: [ + TraceTraceAsString { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 4, + stride: 1026, + start: 0, + len: 513, + }, + name: "[0]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Duplex, + }, + TraceTraceAsString { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 4, + stride: 1026, + start: 513, + len: 513, + }, + name: "[1]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Duplex, + }, + ], + ty: Array), FmtError}, .. }, 2>, + flow: Duplex, + }, + ports: [ + TraceMemPort { + name: "r0", + bundle: TraceBundle { + name: "r0", + fields: [ + TraceUInt { + location: TraceScalarId(12), + name: "addr", + ty: UInt<2>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(13), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(14), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceTraceAsString { + location: TraceScalarId(15), + name: "[0]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Source, + }, + TraceTraceAsString { + location: TraceScalarId(16), + name: "[1]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Source, + }, + ], + ty: Array), FmtError}, .. }, 2>, + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + #[hdl(flip)] /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + #[hdl(flip)] /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + }, + }, + TraceMemPort { + name: "w1", + bundle: TraceBundle { + name: "w1", + fields: [ + TraceUInt { + location: TraceScalarId(17), + name: "addr", + ty: UInt<2>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(18), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(19), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceTraceAsString { + location: TraceScalarId(20), + name: "[0]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Sink, + }, + TraceTraceAsString { + location: TraceScalarId(21), + name: "[1]", + ty: TraceAsString { + inner_ty: Enum { + Text(UInt<512>), + FmtError, + }, + .. + }, + flow: Sink, + }, + ], + ty: Array), FmtError}, .. }, 2>, + flow: Sink, + }, + TraceArray { + name: "mask", + elements: [ + TraceBool { + location: TraceScalarId(22), + name: "[0]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(23), + name: "[1]", + flow: Sink, + }, + ], + ty: Array, + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + /* offset = 1030 */ + mask: Array, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<2>, + /* offset = 2 */ + en: Bool, + /* offset = 3 */ + clk: Clock, + /* offset = 4 */ + data: Array), FmtError}, .. }, 2>, + /* offset = 1030 */ + mask: Array, + }, + }, + ], + array_type: Array), FmtError}, .. }, 2>, 4>, + }, + }, + trace_writers: [ + Running( + VcdWriter { + finished_init: true, + timescale: 1 ps, + .. + }, + ), + ], + clocks_triggered: [ + StatePartIndex(1), + StatePartIndex(6), + ], + event_queue: EventQueue(EventQueueData { + instant: 7 μs, + events: {}, + }), + waiting_sensitivity_sets_by_address: {}, + waiting_sensitivity_sets_by_compiled_value: {}, + .. +} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_trace_as_string.vcd b/crates/fayalite/tests/sim/expected/sim_trace_as_string.vcd new file mode 100644 index 0000000..3338905 --- /dev/null +++ b/crates/fayalite/tests/sim/expected/sim_trace_as_string.vcd @@ -0,0 +1,221 @@ +$timescale 1 ps $end +$scope module sim_trace_as_string $end +$var wire 1 J(7*b clk $end +$scope struct read $end +$var wire 8 @t0}\ addr $end +$var wire 1 78"T5 en $end +$var wire 1 G7v@m clk $end +$var string 1 F&^FN data $end +$upscope $end +$scope struct write $end +$var wire 8 "fUdW addr $end +$var wire 1 r1OK) en $end +$var wire 1 ,ADvU clk $end +$scope struct data $end +$var string 1 pD.mP \[0] $end +$var string 1 !V!em \[1] $end +$upscope $end +$scope struct mask $end +$var wire 1 l8dgD \[0] $end +$var wire 1 1/sDs \[1] $end +$upscope $end +$upscope $end +$scope struct mem $end +$scope struct contents $end +$scope struct \[0] $end +$scope struct mem $end +$var string 1 sz>#| \[0] $end +$var string 1 G._83 \[1] $end +$upscope $end +$upscope $end +$scope struct \[1] $end +$scope struct mem $end +$var string 1 2r3#W \[0] $end +$var string 1 AbGF% \[1] $end +$upscope $end +$upscope $end +$scope struct \[2] $end +$scope struct mem $end +$var string 1 .^<$p \[0] $end +$var string 1 ?s@Dc \[1] $end +$upscope $end +$upscope $end +$scope struct \[3] $end +$scope struct mem $end +$var string 1 {*||o \[0] $end +$var string 1 Bg,vB \[1] $end +$upscope $end +$upscope $end +$upscope $end +$scope struct r0 $end +$var wire 2 .0()- addr $end +$var wire 1 GEbRA en $end +$var wire 1 ;`9BK clk $end +$scope struct data $end +$var string 1 _Xe"P \[0] $end +$var string 1 jXrsx \[1] $end +$upscope $end +$upscope $end +$scope struct w1 $end +$var wire 2 '8u?z addr $end +$var wire 1 ~o=`& en $end +$var wire 1 *q>M1 clk $end +$scope struct data $end +$var string 1 N\zBe \[0] $end +$var string 1 c3h8{ \[1] $end +$upscope $end +$scope struct mask $end +$var wire 1 .SYGD \[0] $end +$var wire 1 />wYd \[1] $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +$dumpvars +s sz>#| +s G._83 +s 2r3#W +s AbGF% +s .^<$p +s ?s@Dc +s {*||o +s Bg,vB +0J(7*b +b0 @t0}\ +078"T5 +0G7v@m +s[,\x20] F&^FN +b0 "fUdW +0r1OK) +0,ADvU +s pD.mP +s !V!em +0l8dgD +01/sDs +b0 .0()- +0GEbRA +0;`9BK +s _Xe"P +s jXrsx +b0 '8u?z +0~o=`& +0*q>M1 +s N\zBe +s c3h8{ +0.SYGD +0/>wYd +$end +#500000 +1J(7*b +1;`9BK +1*q>M1 +#1000000 +0J(7*b +1r1OK) +smem[0][0] pD.mP +smem[0][1] !V!em +1l8dgD +11/sDs +0;`9BK +1~o=`& +0*q>M1 +smem[0][0] N\zBe +smem[0][1] c3h8{ +1.SYGD +1/>wYd +#1500000 +smem[0][0] sz>#| +smem[0][1] G._83 +1J(7*b +1;`9BK +1*q>M1 +#2000000 +0J(7*b +b1 "fUdW +smem[1][0] pD.mP +smem[1][1] !V!em +0;`9BK +b1 '8u?z +0*q>M1 +smem[1][0] N\zBe +smem[1][1] c3h8{ +#2500000 +smem[1][0] 2r3#W +smem[1][1] AbGF% +1J(7*b +1;`9BK +1*q>M1 +#3000000 +0J(7*b +b10 "fUdW +smem[2][0] pD.mP +smem[2][1] !V!em +0;`9BK +b10 '8u?z +0*q>M1 +smem[2][0] N\zBe +smem[2][1] c3h8{ +#3500000 +smem[2][0] .^<$p +smem[2][1] ?s@Dc +1J(7*b +1;`9BK +1*q>M1 +#4000000 +0J(7*b +b11 "fUdW +smem[3][0] pD.mP +smem[3][1] !V!em +0;`9BK +b11 '8u?z +0*q>M1 +smem[3][0] N\zBe +smem[3][1] c3h8{ +#4500000 +smem[3][0] {*||o +smem[3][1] Bg,vB +1J(7*b +1;`9BK +1*q>M1 +#5000000 +0J(7*b +b1 @t0}\ +178"T5 +s[mem[1][0],\x20mem[1][1]] F&^FN +b0 "fUdW +0r1OK) +s pD.mP +s !V!em +b1 .0()- +1GEbRA +0;`9BK +smem[1][0] _Xe"P +smem[1][1] jXrsx +b0 '8u?z +0~o=`& +0*q>M1 +s N\zBe +s c3h8{ +#5500000 +1J(7*b +1;`9BK +1*q>M1 +#6000000 +0J(7*b +b1 "fUdW +1r1OK) +0;`9BK +b1 '8u?z +1~o=`& +0*q>M1 +#6500000 +s 2r3#W +s AbGF% +1J(7*b +s F&^FN +1;`9BK +s _Xe"P +s jXrsx +1*q>M1 +#7000000 diff --git a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr index 6c78637..8eff725 100644 --- a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr +++ b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr @@ -55,7 +55,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta note: required because it appears within the type `DynSimOnlyValue` --> src/sim/value/sim_only_value_unsafe.rs | - 271 | pub struct DynSimOnlyValue(Rc); + 281 | pub struct DynSimOnlyValue(Rc); | ^^^^^^^^^^^^^^^ note: required because it appears within the type `PhantomData` --> $RUST/core/src/marker.rs @@ -75,7 +75,7 @@ note: required because it appears within the type `Vec` note: required because it appears within the type `OpaqueSimValue` --> src/ty.rs | - 734 | pub struct OpaqueSimValue { + 896 | pub struct OpaqueSimValue { | ^^^^^^^^^^^^^^ note: required because it appears within the type `value::SimValueInner<()>` --> src/sim/value.rs @@ -194,7 +194,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta note: required because it appears within the type `DynSimOnlyValue` --> src/sim/value/sim_only_value_unsafe.rs | - 271 | pub struct DynSimOnlyValue(Rc); + 281 | pub struct DynSimOnlyValue(Rc); | ^^^^^^^^^^^^^^^ note: required because it appears within the type `PhantomData` --> $RUST/core/src/marker.rs @@ -214,7 +214,7 @@ note: required because it appears within the type `Vec` note: required because it appears within the type `OpaqueSimValue` --> src/ty.rs | - 734 | pub struct OpaqueSimValue { + 896 | pub struct OpaqueSimValue { | ^^^^^^^^^^^^^^ note: required because it appears within the type `value::SimValueInner<()>` --> src/sim/value.rs @@ -306,7 +306,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta note: required because it appears within the type `DynSimOnlyValue` --> src/sim/value/sim_only_value_unsafe.rs | - 271 | pub struct DynSimOnlyValue(Rc); + 281 | pub struct DynSimOnlyValue(Rc); | ^^^^^^^^^^^^^^^ note: required because it appears within the type `PhantomData` --> $RUST/core/src/marker.rs @@ -326,7 +326,7 @@ note: required because it appears within the type `Vec` note: required because it appears within the type `OpaqueSimValue` --> src/ty.rs | - 734 | pub struct OpaqueSimValue { + 896 | pub struct OpaqueSimValue { | ^^^^^^^^^^^^^^ note: required because it appears within the type `value::SimValueInner<()>` --> src/sim/value.rs diff --git a/crates/fayalite/visit_types.json b/crates/fayalite/visit_types.json index a74cef9..f3af962 100644 --- a/crates/fayalite/visit_types.json +++ b/crates/fayalite/visit_types.json @@ -51,7 +51,8 @@ "Reset": "Visible", "Clock": "Visible", "PhantomConst": "Visible", - "DynSimOnly": "Visible" + "DynSimOnly": "Visible", + "TraceAsString": "Visible" } }, "Bundle": { @@ -1021,6 +1022,27 @@ "fold_where": "T: Fold", "visit_where": "T: Visit" }, + "ops::ToTraceAsString": { + "data": { + "$kind": "Struct", + "$constructor": "ops::ToTraceAsString::new", + "inner()": "Visible", + "ty()": "Visible" + }, + "generics": "", + "fold_where": "T: Fold", + "visit_where": "T: Visit" + }, + "ops::TraceAsStringAsInner": { + "data": { + "$kind": "Struct", + "$constructor": "ops::TraceAsStringAsInner::new", + "arg_typed()": "Visible" + }, + "generics": "", + "fold_where": "T: Fold", + "visit_where": "T: Visit" + }, "BlockId": { "data": { "$kind": "Opaque" @@ -1283,12 +1305,25 @@ "$kind": "Struct" } }, + "TargetPathTraceAsStringInner": { + "data": { + "$kind": "Struct" + } + }, + "TargetPathToTraceAsString": { + "data": { + "$kind": "Struct", + "ty": "Visible" + } + }, "TargetPathElement": { "data": { "$kind": "Enum", "BundleField": "Visible", "ArrayElement": "Visible", - "DynArrayElement": "Visible" + "DynArrayElement": "Visible", + "TraceAsStringInner": "Visible", + "ToTraceAsString": "Visible" } }, "PhantomConst": { @@ -1306,6 +1341,14 @@ "data": { "$kind": "ManualImpl" } + }, + "TraceAsString": { + "data": { + "$kind": "ManualImpl" + }, + "generics": "", + "fold_where": "T: Fold", + "visit_where": "T: Visit" } } } \ No newline at end of file