diff --git a/.forgejo/workflows/deps.yml b/.forgejo/workflows/deps.yml index b29723c..ffaca53 100644 --- a/.forgejo/workflows/deps.yml +++ b/.forgejo/workflows/deps.yml @@ -12,10 +12,10 @@ jobs: outputs: cache-primary-key: ${{ steps.restore-deps.outputs.cache-primary-key }} steps: - - uses: https://git.libre-chip.org/mirrors/checkout@v3 + - uses: https://code.forgejo.org/actions/checkout@v3 with: fetch-depth: 0 - - uses: https://git.libre-chip.org/mirrors/cache/restore@v3 + - uses: https://code.forgejo.org/actions/cache/restore@v3 id: restore-deps with: path: deps @@ -58,19 +58,19 @@ jobs: - name: Get SymbiYosys if: steps.restore-deps.outputs.cache-hit != 'true' run: | - git clone --depth=1 --branch=yosys-0.45 https://git.libre-chip.org/mirrors/sby deps/sby + git clone --depth=1 --branch=yosys-0.45 https://github.com/YosysHQ/sby.git deps/sby - name: Build Z3 if: steps.restore-deps.outputs.cache-hit != 'true' run: | - git clone --depth=1 --recursive --branch=z3-4.13.3 https://git.libre-chip.org/mirrors/z3 deps/z3 + git clone --depth=1 --recursive --branch=z3-4.13.3 https://github.com/Z3Prover/z3.git deps/z3 (cd deps/z3; PYTHON=python3 ./configure --prefix=/usr/local) make -C deps/z3/build -j"$(nproc)" - name: Build Yosys if: steps.restore-deps.outputs.cache-hit != 'true' run: | - git clone --depth=1 --recursive --branch=0.45 https://git.libre-chip.org/mirrors/yosys deps/yosys + git clone --depth=1 --recursive --branch=0.45 https://github.com/YosysHQ/yosys.git deps/yosys make -C deps/yosys -j"$(nproc)" - - uses: https://git.libre-chip.org/mirrors/cache/save@v3 + - uses: https://code.forgejo.org/actions/cache/save@v3 if: steps.restore-deps.outputs.cache-hit != 'true' with: path: deps diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index b2d03ba..e83c668 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -9,7 +9,7 @@ jobs: runs-on: debian-12 needs: deps steps: - - uses: https://git.libre-chip.org/mirrors/checkout@v3 + - uses: https://code.forgejo.org/actions/checkout@v3 with: fetch-depth: 0 - run: | @@ -41,7 +41,7 @@ jobs: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.82.0 source "$HOME/.cargo/env" echo "$PATH" >> "$GITHUB_PATH" - - uses: https://git.libre-chip.org/mirrors/cache/restore@v3 + - uses: https://code.forgejo.org/actions/cache/restore@v3 with: path: deps key: ${{ needs.deps.outputs.cache-primary-key }} @@ -52,11 +52,10 @@ jobs: make -C deps/yosys install export PATH="$(realpath deps/firtool/bin):$PATH" echo "$PATH" >> "$GITHUB_PATH" - - uses: https://git.libre-chip.org/mirrors/rust-cache@v2 + - uses: https://github.com/Swatinem/rust-cache@v2 with: save-if: ${{ github.ref == 'refs/heads/master' }} - run: cargo test - run: cargo build --tests --features=unstable-doc - run: cargo test --doc --features=unstable-doc - run: cargo doc --features=unstable-doc - - run: FAYALITE_TEST_HASHER=always_zero cargo test --test=module --features=unstable-doc,unstable-test-hasher diff --git a/Cargo.lock b/Cargo.lock index e0c32e9..23cdc34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "allocator-api2" version = "0.2.16" @@ -353,12 +365,6 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "funty" version = "2.0.0" @@ -394,13 +400,12 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ + "ahash", "allocator-api2", - "equivalent", - "foldhash", ] [[package]] @@ -426,9 +431,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.9.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", @@ -519,14 +524,11 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a98c6720655620a521dcc722d0ad66cd8afd5d86e34a89ef691c50b7b24de06" +version = "0.6.5" +source = "git+https://github.com/programmerjake/petgraph.git?rev=258ea8071209a924b73fe96f9f87a3b7b45cbc9f#258ea8071209a924b73fe96f9f87a3b7b45cbc9f" dependencies = [ "fixedbitset", - "hashbrown", "indexmap", - "serde", ] [[package]] @@ -891,3 +893,23 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index d681425..54de3a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,13 +23,14 @@ blake3 = { version = "1.5.4", features = ["serde"] } clap = { version = "4.5.9", features = ["derive", "env", "string"] } ctor = "0.2.8" eyre = "0.6.12" -hashbrown = "0.15.2" +hashbrown = "0.14.3" indexmap = { version = "2.5.0", features = ["serde"] } jobslot = "0.2.19" num-bigint = "0.4.6" num-traits = "0.2.16" os_pipe = "1.2.1" -petgraph = "0.8.1" +# TODO: switch back to crates.io once petgraph accepts PR #684 and releases a new version +petgraph = { git = "https://github.com/programmerjake/petgraph.git", rev = "258ea8071209a924b73fe96f9f87a3b7b45cbc9f" } prettyplease = "0.2.20" proc-macro2 = "1.0.83" quote = "1.0.36" diff --git a/crates/fayalite-proc-macros-impl/src/fold.rs b/crates/fayalite-proc-macros-impl/src/fold.rs index 22e7b82..49cc8c1 100644 --- a/crates/fayalite-proc-macros-impl/src/fold.rs +++ b/crates/fayalite-proc-macros-impl/src/fold.rs @@ -220,7 +220,6 @@ forward_fold!(syn::ExprArray => fold_expr_array); forward_fold!(syn::ExprCall => fold_expr_call); forward_fold!(syn::ExprIf => fold_expr_if); forward_fold!(syn::ExprMatch => fold_expr_match); -forward_fold!(syn::ExprMethodCall => fold_expr_method_call); forward_fold!(syn::ExprPath => fold_expr_path); forward_fold!(syn::ExprRepeat => fold_expr_repeat); forward_fold!(syn::ExprStruct => fold_expr_struct); diff --git a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs index 7441cb3..79326e2 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs @@ -30,9 +30,7 @@ pub(crate) struct ParsedBundle { pub(crate) field_flips: Vec>>, pub(crate) mask_type_ident: Ident, pub(crate) mask_type_match_variant_ident: Ident, - pub(crate) mask_type_sim_value_ident: Ident, pub(crate) match_variant_ident: Ident, - pub(crate) sim_value_ident: Ident, pub(crate) builder_ident: Ident, pub(crate) mask_type_builder_ident: Ident, } @@ -85,7 +83,6 @@ impl ParsedBundle { custom_bounds, no_static: _, no_runtime_generics: _, - cmp_eq: _, } = options.body; let mut fields = match fields { syn::Fields::Named(fields) => fields, @@ -127,9 +124,7 @@ impl ParsedBundle { field_flips, mask_type_ident: format_ident!("__{}__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), - sim_value_ident: format_ident!("__{}__SimValue", ident), mask_type_builder_ident: format_ident!("__{}__MaskType__Builder", ident), builder_ident: format_ident!("__{}__Builder", ident), ident, @@ -431,9 +426,7 @@ impl ToTokens for ParsedBundle { field_flips, mask_type_ident, mask_type_match_variant_ident, - mask_type_sim_value_ident, match_variant_ident, - sim_value_ident, builder_ident, mask_type_builder_ident, } = self; @@ -444,7 +437,6 @@ impl ToTokens for ParsedBundle { custom_bounds: _, no_static, no_runtime_generics, - cmp_eq, } = &options.body; let target = get_target(target, ident); let mut item_attrs = attrs.clone(); @@ -529,7 +521,7 @@ impl ToTokens for ParsedBundle { semi_token: None, } .to_tokens(tokens); - let mut mask_type_match_variant_fields = mask_type_fields.clone(); + let mut mask_type_match_variant_fields = mask_type_fields; for Field { ty, .. } in &mut mask_type_match_variant_fields.named { *ty = parse_quote_spanned! {span=> ::fayalite::expr::Expr<#ty> @@ -571,58 +563,6 @@ impl ToTokens for ParsedBundle { semi_token: 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 { - attrs: vec![ - parse_quote_spanned! {span=> - #[::fayalite::__std::prelude::v1::derive( - ::fayalite::__std::fmt::Debug, - ::fayalite::__std::clone::Clone, - )] - }, - parse_quote_spanned! {span=> - #[allow(non_camel_case_types, dead_code)] - }, - ], - vis: vis.clone(), - struct_token: *struct_token, - ident: mask_type_sim_value_ident.clone(), - generics: generics.into(), - fields: Fields::Named(mask_type_sim_value_fields), - semi_token: None, - } - .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 { - attrs: vec![ - parse_quote_spanned! {span=> - #[::fayalite::__std::prelude::v1::derive( - ::fayalite::__std::fmt::Debug, - ::fayalite::__std::clone::Clone, - )] - }, - parse_quote_spanned! {span=> - #[allow(non_camel_case_types, dead_code)] - }, - ], - vis: vis.clone(), - struct_token: *struct_token, - ident: sim_value_ident.clone(), - generics: generics.into(), - fields: Fields::Named(sim_value_fields), - semi_token: None, - } - .to_tokens(tokens); let this_token = Ident::new("__this", span); let fields_token = Ident::new("__fields", span); let self_token = Token![self](span); @@ -673,31 +613,6 @@ impl ToTokens for ParsedBundle { } }, )); - let sim_value_from_bits_fields = Vec::from_iter(fields.named().into_iter().map(|field| { - let ident: &Ident = field.ident().as_ref().unwrap(); - quote_spanned! {span=> - #ident: v.field_from_bits(), - } - })); - let sim_value_clone_from_bits_fields = - Vec::from_iter(fields.named().into_iter().map(|field| { - let ident: &Ident = field.ident().as_ref().unwrap(); - quote_spanned! {span=> - v.field_clone_from_bits(&mut value.#ident); - } - })); - let sim_value_to_bits_fields = Vec::from_iter(fields.named().into_iter().map(|field| { - let ident: &Ident = field.ident().as_ref().unwrap(); - quote_spanned! {span=> - v.field_to_bits(&value.#ident); - } - })); - let to_sim_value_fields = Vec::from_iter(fields.named().into_iter().map(|field| { - let ident: &Ident = field.ident().as_ref().unwrap(); - quote_spanned! {span=> - #ident: ::fayalite::sim::value::SimValue::ty(&self.#ident), - } - })); let fields_len = fields.named().into_iter().len(); quote_spanned! {span=> #[automatically_derived] @@ -706,7 +621,6 @@ impl ToTokens for ParsedBundle { { type BaseType = ::fayalite::bundle::Bundle; type MaskType = #mask_type_ident #type_generics; - type SimValue = #mask_type_sim_value_ident #type_generics; type MatchVariant = #mask_type_match_variant_ident #type_generics; type MatchActiveScope = (); type MatchVariantAndInactiveScope = ::fayalite::ty::MatchVariantWithoutScope< @@ -744,34 +658,6 @@ impl ToTokens for ParsedBundle { fn source_location() -> ::fayalite::source_location::SourceLocation { ::fayalite::source_location::SourceLocation::caller() } - fn sim_value_from_bits( - &self, - bits: &::fayalite::bitvec::slice::BitSlice, - ) -> ::SimValue { - #![allow(unused_mut, unused_variables)] - let mut v = ::fayalite::bundle::BundleSimValueFromBits::new(*self, bits); - #mask_type_sim_value_ident { - #(#sim_value_from_bits_fields)* - } - } - fn sim_value_clone_from_bits( - &self, - value: &mut ::SimValue, - bits: &::fayalite::bitvec::slice::BitSlice, - ) { - #![allow(unused_mut, unused_variables)] - let mut v = ::fayalite::bundle::BundleSimValueFromBits::new(*self, bits); - #(#sim_value_clone_from_bits_fields)* - } - fn sim_value_to_bits( - &self, - value: &::SimValue, - bits: &mut ::fayalite::bitvec::slice::BitSlice, - ) { - #![allow(unused_mut, unused_variables)] - let mut v = ::fayalite::bundle::BundleSimValueToBits::new(*self, bits); - #(#sim_value_to_bits_fields)* - } } #[automatically_derived] impl #impl_generics ::fayalite::bundle::BundleType for #mask_type_ident #type_generics @@ -803,57 +689,11 @@ impl ToTokens for ParsedBundle { } } #[automatically_derived] - impl #impl_generics ::fayalite::sim::value::ToSimValue for #mask_type_sim_value_ident #type_generics - #where_clause - { - type Type = #mask_type_ident #type_generics; - - fn to_sim_value( - &self, - ) -> ::fayalite::sim::value::SimValue< - ::Type, - > { - let ty = #mask_type_ident { - #(#to_sim_value_fields)* - }; - ::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self)) - } - fn into_sim_value( - self, - ) -> ::fayalite::sim::value::SimValue< - ::Type, - > { - let ty = #mask_type_ident { - #(#to_sim_value_fields)* - }; - ::fayalite::sim::value::SimValue::from_value(ty, self) - } - } - #[automatically_derived] - impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#mask_type_ident #type_generics> - for #mask_type_sim_value_ident #type_generics - #where_clause - { - fn to_sim_value_with_type( - &self, - ty: #mask_type_ident #type_generics, - ) -> ::fayalite::sim::value::SimValue<#mask_type_ident #type_generics> { - ::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self)) - } - fn into_sim_value_with_type( - self, - ty: #mask_type_ident #type_generics, - ) -> ::fayalite::sim::value::SimValue<#mask_type_ident #type_generics> { - ::fayalite::sim::value::SimValue::from_value(ty, self) - } - } - #[automatically_derived] impl #impl_generics ::fayalite::ty::Type for #target #type_generics #where_clause { type BaseType = ::fayalite::bundle::Bundle; type MaskType = #mask_type_ident #type_generics; - type SimValue = #sim_value_ident #type_generics; type MatchVariant = #match_variant_ident #type_generics; type MatchActiveScope = (); type MatchVariantAndInactiveScope = ::fayalite::ty::MatchVariantWithoutScope< @@ -893,34 +733,6 @@ impl ToTokens for ParsedBundle { fn source_location() -> ::fayalite::source_location::SourceLocation { ::fayalite::source_location::SourceLocation::caller() } - fn sim_value_from_bits( - &self, - bits: &::fayalite::bitvec::slice::BitSlice, - ) -> ::SimValue { - #![allow(unused_mut, unused_variables)] - let mut v = ::fayalite::bundle::BundleSimValueFromBits::new(*self, bits); - #sim_value_ident { - #(#sim_value_from_bits_fields)* - } - } - fn sim_value_clone_from_bits( - &self, - value: &mut ::SimValue, - bits: &::fayalite::bitvec::slice::BitSlice, - ) { - #![allow(unused_mut, unused_variables)] - let mut v = ::fayalite::bundle::BundleSimValueFromBits::new(*self, bits); - #(#sim_value_clone_from_bits_fields)* - } - fn sim_value_to_bits( - &self, - value: &::SimValue, - bits: &mut ::fayalite::bitvec::slice::BitSlice, - ) { - #![allow(unused_mut, unused_variables)] - let mut v = ::fayalite::bundle::BundleSimValueToBits::new(*self, bits); - #(#sim_value_to_bits_fields)* - } } #[automatically_derived] impl #impl_generics ::fayalite::bundle::BundleType for #target #type_generics @@ -951,144 +763,8 @@ impl ToTokens for ParsedBundle { ::fayalite::intern::Interned::into_inner(::fayalite::intern::Intern::intern_sized(__retval)) } } - #[automatically_derived] - impl #impl_generics ::fayalite::sim::value::ToSimValue for #sim_value_ident #type_generics - #where_clause - { - type Type = #target #type_generics; - - fn to_sim_value( - &self, - ) -> ::fayalite::sim::value::SimValue< - ::Type, - > { - let ty = #target { - #(#to_sim_value_fields)* - }; - ::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self)) - } - fn into_sim_value( - self, - ) -> ::fayalite::sim::value::SimValue< - ::Type, - > { - let ty = #target { - #(#to_sim_value_fields)* - }; - ::fayalite::sim::value::SimValue::from_value(ty, self) - } - } - #[automatically_derived] - impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#target #type_generics> - for #sim_value_ident #type_generics - #where_clause - { - fn to_sim_value_with_type( - &self, - ty: #target #type_generics, - ) -> ::fayalite::sim::value::SimValue<#target #type_generics> { - ::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self)) - } - fn into_sim_value_with_type( - self, - ty: #target #type_generics, - ) -> ::fayalite::sim::value::SimValue<#target #type_generics> { - ::fayalite::sim::value::SimValue::from_value(ty, self) - } - } } .to_tokens(tokens); - if let Some((cmp_eq,)) = cmp_eq { - let mut expr_where_clause = - Generics::from(generics) - .where_clause - .unwrap_or_else(|| syn::WhereClause { - where_token: Token![where](span), - predicates: Punctuated::new(), - }); - let mut sim_value_where_clause = expr_where_clause.clone(); - let mut fields_sim_value_eq = vec![]; - let mut fields_cmp_eq = vec![]; - let mut fields_cmp_ne = vec![]; - for field in fields.named() { - let field_ident = field.ident(); - let field_ty = field.ty(); - expr_where_clause - .predicates - .push(parse_quote_spanned! {cmp_eq.span=> - #field_ty: ::fayalite::expr::ops::ExprPartialEq<#field_ty> - }); - sim_value_where_clause - .predicates - .push(parse_quote_spanned! {cmp_eq.span=> - #field_ty: ::fayalite::sim::value::SimValuePartialEq<#field_ty> - }); - fields_sim_value_eq.push(quote_spanned! {span=> - ::fayalite::sim::value::SimValuePartialEq::sim_value_eq(&__lhs.#field_ident, &__rhs.#field_ident) - }); - fields_cmp_eq.push(quote_spanned! {span=> - ::fayalite::expr::ops::ExprPartialEq::cmp_eq(__lhs.#field_ident, __rhs.#field_ident) - }); - fields_cmp_ne.push(quote_spanned! {span=> - ::fayalite::expr::ops::ExprPartialEq::cmp_ne(__lhs.#field_ident, __rhs.#field_ident) - }); - } - let sim_value_eq_body; - let cmp_eq_body; - let cmp_ne_body; - if fields_len == 0 { - sim_value_eq_body = quote_spanned! {span=> - true - }; - cmp_eq_body = quote_spanned! {span=> - ::fayalite::expr::ToExpr::to_expr(&true) - }; - cmp_ne_body = quote_spanned! {span=> - ::fayalite::expr::ToExpr::to_expr(&false) - }; - } else { - sim_value_eq_body = quote_spanned! {span=> - #(#fields_sim_value_eq)&&* - }; - cmp_eq_body = quote_spanned! {span=> - #(#fields_cmp_eq)&* - }; - cmp_ne_body = quote_spanned! {span=> - #(#fields_cmp_ne)|* - }; - }; - quote_spanned! {span=> - #[automatically_derived] - impl #impl_generics ::fayalite::expr::ops::ExprPartialEq for #target #type_generics - #expr_where_clause - { - fn cmp_eq( - __lhs: ::fayalite::expr::Expr, - __rhs: ::fayalite::expr::Expr, - ) -> ::fayalite::expr::Expr<::fayalite::int::Bool> { - #cmp_eq_body - } - fn cmp_ne( - __lhs: ::fayalite::expr::Expr, - __rhs: ::fayalite::expr::Expr, - ) -> ::fayalite::expr::Expr<::fayalite::int::Bool> { - #cmp_ne_body - } - } - #[automatically_derived] - impl #impl_generics ::fayalite::sim::value::SimValuePartialEq for #target #type_generics - #sim_value_where_clause - { - fn sim_value_eq( - __lhs: &::fayalite::sim::value::SimValue, - __rhs: &::fayalite::sim::value::SimValue, - ) -> bool { - #sim_value_eq_body - } - } - } - .to_tokens(tokens); - } if let (None, MaybeParsed::Parsed(generics)) = (no_static, &self.generics) { let static_generics = generics.clone().for_static_type(); let (static_impl_generics, static_type_generics, static_where_clause) = @@ -1124,14 +800,6 @@ impl ToTokens for ParsedBundle { } })); quote_spanned! {span=> - #[automatically_derived] - impl #static_impl_generics ::fayalite::__std::default::Default for #mask_type_ident #static_type_generics - #static_where_clause - { - fn default() -> Self { - ::TYPE - } - } #[automatically_derived] impl #static_impl_generics ::fayalite::ty::StaticType for #mask_type_ident #static_type_generics #static_where_clause @@ -1154,15 +822,6 @@ impl ToTokens for ParsedBundle { }; } #[automatically_derived] - impl #static_impl_generics ::fayalite::__std::default::Default - for #target #static_type_generics - #static_where_clause - { - fn default() -> Self { - ::TYPE - } - } - #[automatically_derived] impl #static_impl_generics ::fayalite::ty::StaticType for #target #static_type_generics #static_where_clause { diff --git a/crates/fayalite-proc-macros-impl/src/hdl_enum.rs b/crates/fayalite-proc-macros-impl/src/hdl_enum.rs index e072135..1d16177 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_enum.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_enum.rs @@ -129,9 +129,6 @@ pub(crate) struct ParsedEnum { pub(crate) brace_token: Brace, pub(crate) variants: Punctuated, pub(crate) match_variant_ident: Ident, - pub(crate) sim_value_ident: Ident, - pub(crate) sim_builder_ident: Ident, - pub(crate) sim_builder_ty_field_ident: Ident, } impl ParsedEnum { @@ -158,11 +155,7 @@ impl ParsedEnum { custom_bounds, no_static: _, no_runtime_generics: _, - cmp_eq, } = options.body; - if let Some((cmp_eq,)) = cmp_eq { - errors.error(cmp_eq, "#[hdl(cmp_eq)] is not yet implemented for enums"); - } attrs.retain(|attr| { if attr.path().is_ident("repr") { errors.error(attr, "#[repr] is not supported on #[hdl] enums"); @@ -193,9 +186,6 @@ impl ParsedEnum { brace_token, variants, match_variant_ident: format_ident!("__{}__MatchVariant", ident), - sim_value_ident: format_ident!("__{}__SimValue", ident), - sim_builder_ident: format_ident!("__{}__SimBuilder", ident), - sim_builder_ty_field_ident: format_ident!("__ty", span = ident.span()), ident, }) } @@ -213,9 +203,6 @@ impl ToTokens for ParsedEnum { brace_token, variants, match_variant_ident, - sim_value_ident, - sim_builder_ident, - sim_builder_ty_field_ident, } = self; let span = ident.span(); let ItemOptions { @@ -224,7 +211,6 @@ impl ToTokens for ParsedEnum { custom_bounds: _, no_static, no_runtime_generics, - cmp_eq: _, // TODO: implement cmp_eq for enums } = &options.body; let target = get_target(target, ident); let mut struct_attrs = attrs.clone(); @@ -418,133 +404,6 @@ impl ToTokens for ParsedEnum { )), } .to_tokens(tokens); - let mut struct_attrs = attrs.clone(); - struct_attrs.push(parse_quote_spanned! {span=> - #[allow(dead_code, non_camel_case_types)] - }); - ItemStruct { - attrs: struct_attrs, - vis: vis.clone(), - struct_token: Token![struct](enum_token.span), - ident: sim_builder_ident.clone(), - generics: generics.into(), - fields: FieldsNamed { - brace_token: *brace_token, - named: Punctuated::from_iter([Field { - attrs: vec![], - vis: Visibility::Inherited, - mutability: FieldMutability::None, - ident: Some(sim_builder_ty_field_ident.clone()), - colon_token: Some(Token![:](span)), - ty: parse_quote_spanned! {span=> - #target #type_generics - }, - }]), - } - .into(), - semi_token: None, - } - .to_tokens(tokens); - 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, - )] - }); - enum_attrs.push(parse_quote_spanned! {span=> - #[allow(dead_code, non_camel_case_types)] - }); - let sim_value_has_unknown_variant = !variants.len().is_power_of_two(); - let sim_value_unknown_variant_name = sim_value_has_unknown_variant.then(|| { - let mut name = String::new(); - let unknown = "Unknown"; - loop { - let orig_len = name.len(); - name.push_str(unknown); - if variants.iter().all(|v| v.ident != name) { - break Ident::new(&name, span); - } - name.truncate(orig_len); - name.push('_'); - } - }); - let sim_value_unknown_variant = - sim_value_unknown_variant_name - .as_ref() - .map(|unknown_variant_name| { - Pair::End(parse_quote_spanned! {span=> - #unknown_variant_name(::fayalite::enum_::UnknownVariantSimValue) - }) - }); - ItemEnum { - attrs: enum_attrs, - vis: vis.clone(), - enum_token: *enum_token, - ident: sim_value_ident.clone(), - generics: generics.into(), - brace_token: *brace_token, - variants: Punctuated::from_iter( - variants - .pairs() - .map_pair_value_ref( - |ParsedVariant { - attrs, - options: _, - ident, - field, - }| Variant { - attrs: attrs.clone(), - ident: ident.clone(), - fields: match field { - Some(ParsedVariantField { - paren_token, - attrs, - options: _, - ty, - comma_token, - }) => Fields::Unnamed(FieldsUnnamed { - paren_token: *paren_token, - unnamed: Punctuated::from_iter([ - Pair::new( - Field { - attrs: attrs.clone(), - vis: Visibility::Inherited, - mutability: FieldMutability::None, - ident: None, - colon_token: None, - ty: parse_quote_spanned! {span=> - ::fayalite::sim::value::SimValue<#ty> - }, - }, - Some(comma_token.unwrap_or(Token![,](ident.span()))), - ), - Pair::new( - Field { - attrs: vec![], - vis: Visibility::Inherited, - mutability: FieldMutability::None, - ident: None, - colon_token: None, - ty: parse_quote_spanned! {span=> - ::fayalite::enum_::EnumPaddingSimValue - }, - }, - None, - ), - ]), - }), - None => Fields::Unnamed(parse_quote_spanned! {span=> - (::fayalite::enum_::EnumPaddingSimValue) - }), - }, - discriminant: None, - }, - ) - .chain(sim_value_unknown_variant), - ), - } - .to_tokens(tokens); let self_token = Token![self](span); for (index, ParsedVariant { ident, field, .. }) in variants.iter().enumerate() { if let Some(ParsedVariantField { ty, .. }) = field { @@ -571,25 +430,6 @@ impl ToTokens for ParsedEnum { ) } } - #[automatically_derived] - impl #impl_generics #sim_builder_ident #type_generics - #where_clause - { - #[allow(non_snake_case, dead_code)] - #vis fn #ident<__V: ::fayalite::sim::value::ToSimValueWithType<#ty>>( - #self_token, - v: __V, - ) -> ::fayalite::sim::value::SimValue<#target #type_generics> { - let v = ::fayalite::sim::value::ToSimValueWithType::into_sim_value_with_type( - v, - #self_token.#sim_builder_ty_field_ident.#ident, - ); - ::fayalite::sim::value::SimValue::from_value( - #self_token.#sim_builder_ty_field_ident, - #sim_value_ident::#ident(v, ::fayalite::enum_::EnumPaddingSimValue::new()), - ) - } - } } } else { quote_spanned! {span=> @@ -608,18 +448,6 @@ impl ToTokens for ParsedEnum { ) } } - #[automatically_derived] - impl #impl_generics #sim_builder_ident #type_generics - #where_clause - { - #[allow(non_snake_case, dead_code)] - #vis fn #ident(#self_token) -> ::fayalite::sim::value::SimValue<#target #type_generics> { - ::fayalite::sim::value::SimValue::from_value( - #self_token.#sim_builder_ty_field_ident, - #sim_value_ident::#ident(::fayalite::enum_::EnumPaddingSimValue::new()), - ) - } - } } } .to_tokens(tokens); @@ -701,142 +529,6 @@ impl ToTokens for ParsedEnum { } }, )); - let sim_value_from_bits_unknown_match_arm = if let Some(sim_value_unknown_variant_name) = - &sim_value_unknown_variant_name - { - quote_spanned! {span=> - _ => #sim_value_ident::#sim_value_unknown_variant_name(v.unknown_variant_from_bits()), - } - } else { - quote_spanned! {span=> - _ => ::fayalite::__std::unreachable!(), - } - }; - let sim_value_from_bits_match_arms = Vec::from_iter( - variants - .iter() - .enumerate() - .map( - |( - index, - ParsedVariant { - attrs: _, - options: _, - ident, - field, - }, - )| { - if let Some(_) = field { - quote_spanned! {span=> - #index => { - let (field, padding) = v.variant_with_field_from_bits(); - #sim_value_ident::#ident(field, padding) - } - } - } else { - quote_spanned! {span=> - #index => #sim_value_ident::#ident( - v.variant_no_field_from_bits(), - ), - } - } - }, - ) - .chain([sim_value_from_bits_unknown_match_arm]), - ); - let sim_value_clone_from_bits_unknown_match_arm = - if let Some(sim_value_unknown_variant_name) = &sim_value_unknown_variant_name { - quote_spanned! {span=> - _ => if let #sim_value_ident::#sim_value_unknown_variant_name(value) = value { - v.unknown_variant_clone_from_bits(value); - } else { - *value = #sim_value_ident::#sim_value_unknown_variant_name( - v.unknown_variant_from_bits(), - ); - }, - } - } else { - quote_spanned! {span=> - _ => ::fayalite::__std::unreachable!(), - } - }; - let sim_value_clone_from_bits_match_arms = Vec::from_iter( - variants - .iter() - .enumerate() - .map( - |( - index, - ParsedVariant { - attrs: _, - options: _, - ident, - field, - }, - )| { - if let Some(_) = field { - quote_spanned! {span=> - #index => if let #sim_value_ident::#ident(field, padding) = value { - v.variant_with_field_clone_from_bits(field, padding); - } else { - let (field, padding) = v.variant_with_field_from_bits(); - *value = #sim_value_ident::#ident(field, padding); - }, - } - } else { - quote_spanned! {span=> - #index => if let #sim_value_ident::#ident(padding) = value { - v.variant_no_field_clone_from_bits(padding); - } else { - *value = #sim_value_ident::#ident( - v.variant_no_field_from_bits(), - ); - }, - } - } - }, - ) - .chain([sim_value_clone_from_bits_unknown_match_arm]), - ); - let sim_value_to_bits_match_arms = Vec::from_iter( - variants - .iter() - .enumerate() - .map( - |( - index, - ParsedVariant { - attrs: _, - options: _, - ident, - field, - }, - )| { - if let Some(_) = field { - quote_spanned! {span=> - #sim_value_ident::#ident(field, padding) => { - v.variant_with_field_to_bits(#index, field, padding); - } - } - } else { - quote_spanned! {span=> - #sim_value_ident::#ident(padding) => { - v.variant_no_field_to_bits(#index, padding); - } - } - } - }, - ) - .chain(sim_value_unknown_variant_name.as_ref().map( - |sim_value_unknown_variant_name| { - quote_spanned! {span=> - #sim_value_ident::#sim_value_unknown_variant_name(value) => { - v.unknown_variant_to_bits(value); - } - } - }, - )), - ); let variants_len = variants.len(); quote_spanned! {span=> #[automatically_derived] @@ -845,7 +537,6 @@ impl ToTokens for ParsedEnum { { type BaseType = ::fayalite::enum_::Enum; type MaskType = ::fayalite::int::Bool; - type SimValue = #sim_value_ident #type_generics; type MatchVariant = #match_variant_ident #type_generics; type MatchActiveScope = ::fayalite::module::Scope; type MatchVariantAndInactiveScope = ::fayalite::enum_::EnumMatchVariantAndInactiveScope; @@ -878,41 +569,11 @@ impl ToTokens for ParsedEnum { fn source_location() -> ::fayalite::source_location::SourceLocation { ::fayalite::source_location::SourceLocation::caller() } - fn sim_value_from_bits( - &self, - bits: &::fayalite::bitvec::slice::BitSlice, - ) -> ::SimValue { - let v = ::fayalite::enum_::EnumSimValueFromBits::new(*self, bits); - match v.discriminant() { - #(#sim_value_from_bits_match_arms)* - } - } - fn sim_value_clone_from_bits( - &self, - value: &mut ::SimValue, - bits: &::fayalite::bitvec::slice::BitSlice, - ) { - let v = ::fayalite::enum_::EnumSimValueFromBits::new(*self, bits); - match v.discriminant() { - #(#sim_value_clone_from_bits_match_arms)* - } - } - fn sim_value_to_bits( - &self, - value: &::SimValue, - bits: &mut ::fayalite::bitvec::slice::BitSlice, - ) { - let v = ::fayalite::enum_::EnumSimValueToBits::new(*self, bits); - match value { - #(#sim_value_to_bits_match_arms)* - } - } } #[automatically_derived] impl #impl_generics ::fayalite::enum_::EnumType for #target #type_generics #where_clause { - type SimBuilder = #sim_builder_ident #type_generics; fn match_activate_scope( v: ::MatchVariantAndInactiveScope, ) -> (::MatchVariant, ::MatchActiveScope) { @@ -931,33 +592,6 @@ impl ToTokens for ParsedEnum { ][..]) } } - #[automatically_derived] - impl #impl_generics ::fayalite::sim::value::ToSimValueWithType<#target #type_generics> - for #sim_value_ident #type_generics - #where_clause - { - fn to_sim_value_with_type( - &self, - ty: #target #type_generics, - ) -> ::fayalite::sim::value::SimValue<#target #type_generics> { - ::fayalite::sim::value::SimValue::from_value(ty, ::fayalite::__std::clone::Clone::clone(self)) - } - fn into_sim_value_with_type( - self, - ty: #target #type_generics, - ) -> ::fayalite::sim::value::SimValue<#target #type_generics> { - ::fayalite::sim::value::SimValue::from_value(ty, self) - } - } - #[automatically_derived] - impl #impl_generics ::fayalite::__std::convert::From<#target #type_generics> - for #sim_builder_ident #type_generics - #where_clause - { - fn from(#sim_builder_ty_field_ident: #target #type_generics) -> Self { - Self { #sim_builder_ty_field_ident } - } - } } .to_tokens(tokens); if let (None, MaybeParsed::Parsed(generics)) = (no_static, &self.generics) { @@ -995,15 +629,6 @@ impl ToTokens for ParsedEnum { } })); quote_spanned! {span=> - #[automatically_derived] - impl #static_impl_generics ::fayalite::__std::default::Default - for #target #static_type_generics - #static_where_clause - { - fn default() -> Self { - ::TYPE - } - } #[automatically_derived] impl #static_impl_generics ::fayalite::ty::StaticType for #target #static_type_generics @@ -1022,34 +647,6 @@ impl ToTokens for ParsedEnum { const MASK_TYPE_PROPERTIES: ::fayalite::ty::TypeProperties = <::fayalite::int::Bool as ::fayalite::ty::StaticType>::TYPE_PROPERTIES; } - #[automatically_derived] - impl #static_impl_generics ::fayalite::sim::value::ToSimValue - for #sim_value_ident #static_type_generics - #static_where_clause - { - type Type = #target #static_type_generics; - - fn to_sim_value( - &self, - ) -> ::fayalite::sim::value::SimValue< - ::Type, - > { - ::fayalite::sim::value::SimValue::from_value( - ::fayalite::ty::StaticType::TYPE, - ::fayalite::__std::clone::Clone::clone(self), - ) - } - fn into_sim_value( - self, - ) -> ::fayalite::sim::value::SimValue< - ::Type, - > { - ::fayalite::sim::value::SimValue::from_value( - ::fayalite::ty::StaticType::TYPE, - self, - ) - } - } } .to_tokens(tokens); } 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 97501e7..e5d5f7b 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs @@ -49,14 +49,10 @@ impl ParsedTypeAlias { custom_bounds, no_static, no_runtime_generics: _, - cmp_eq, } = options.body; if let Some((no_static,)) = no_static { errors.error(no_static, "no_static is not valid on type aliases"); } - if let Some((cmp_eq,)) = cmp_eq { - errors.error(cmp_eq, "cmp_eq is not valid on type aliases"); - } let generics = if custom_bounds.is_some() { MaybeParsed::Unrecognized(generics) } else if let Some(generics) = errors.ok(ParsedGenerics::parse(&mut generics)) { @@ -99,7 +95,6 @@ impl ToTokens for ParsedTypeAlias { custom_bounds: _, no_static: _, no_runtime_generics, - cmp_eq: _, } = &options.body; let target = get_target(target, ident); let mut type_attrs = attrs.clone(); 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 2da0915..6193dc3 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs @@ -26,7 +26,6 @@ crate::options! { CustomBounds(custom_bounds), NoStatic(no_static), NoRuntimeGenerics(no_runtime_generics), - CmpEq(cmp_eq), } } @@ -2070,16 +2069,11 @@ macro_rules! impl_bounds { $( $Variant:ident, )* - $( - #[unknown] - $Unknown:ident, - )? } ) => { #[derive(Clone, Debug)] $vis enum $enum_type { $($Variant(known_items::$Variant),)* - $($Unknown(syn::TypeParamBound),)? } $(impl From for $enum_type { @@ -2092,54 +2086,28 @@ macro_rules! impl_bounds { fn to_tokens(&self, tokens: &mut TokenStream) { match self { $(Self::$Variant(v) => v.to_tokens(tokens),)* - $(Self::$Unknown(v) => v.to_tokens(tokens),)? } } } impl $enum_type { $vis fn parse_path(path: Path) -> Result { - #![allow(unreachable_code)] $(let path = match known_items::$Variant::parse_path(path) { Ok(v) => return Ok(Self::$Variant(v)), Err(path) => path, };)* - $(return Ok(Self::$Unknown(syn::TraitBound { - paren_token: None, - modifier: syn::TraitBoundModifier::None, - lifetimes: None, - path, - }.into()));)? Err(path) } - $vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> Result { - #![allow(unreachable_code)] - if let syn::TypeParamBound::Trait(mut trait_bound) = type_param_bound { - if let syn::TraitBound { - paren_token: _, - modifier: syn::TraitBoundModifier::None, - lifetimes: None, - path: _, - } = trait_bound { - match Self::parse_path(trait_bound.path) { - Ok(retval) => return Ok(retval), - Err(path) => trait_bound.path = path, - } - } - type_param_bound = trait_bound.into(); - } - $(return Ok(Self::$Unknown(type_param_bound));)? - Err(type_param_bound) - } } impl Parse for $enum_type { fn parse(input: ParseStream) -> syn::Result { - Self::parse_type_param_bound(input.parse()?) - .map_err(|type_param_bound| syn::Error::new_spanned( - type_param_bound, + Self::parse_path(Path::parse_mod_style(input)?).map_err(|path| { + syn::Error::new_spanned( + path, format_args!("expected one of: {}", [$(stringify!($Variant)),*].join(", ")), - )) + ) + }) } } @@ -2147,7 +2115,6 @@ macro_rules! impl_bounds { #[allow(non_snake_case)] $vis struct $struct_type { $($vis $Variant: Option,)* - $($vis $Unknown: Vec,)? } impl ToTokens for $struct_type { @@ -2159,63 +2126,42 @@ macro_rules! impl_bounds { separator = Some(::default()); v.to_tokens(tokens); })* - $(for v in &self.$Unknown { - separator.to_tokens(tokens); - separator = Some(::default()); - v.to_tokens(tokens); - })* } } const _: () = { #[derive(Clone, Debug)] - #[allow(non_snake_case)] - $vis struct Iter { - $($Variant: Option,)* - $($Unknown: std::vec::IntoIter,)? - } + $vis struct Iter($vis $struct_type); impl IntoIterator for $struct_type { type Item = $enum_type; type IntoIter = Iter; fn into_iter(self) -> Self::IntoIter { - Iter { - $($Variant: self.$Variant,)* - $($Unknown: self.$Unknown.into_iter(),)? - } + Iter(self) } } impl Iterator for Iter { type Item = $enum_type; + fn next(&mut self) -> Option { $( - if let Some(value) = self.$Variant.take() { + if let Some(value) = self.0.$Variant.take() { return Some($enum_type::$Variant(value)); } )* - $( - if let Some(value) = self.$Unknown.next() { - return Some($enum_type::$Unknown(value)); - } - )? None } #[allow(unused_mut, unused_variables)] fn fold B>(mut self, mut init: B, mut f: F) -> B { $( - if let Some(value) = self.$Variant.take() { + if let Some(value) = self.0.$Variant.take() { init = f(init, $enum_type::$Variant(value)); } )* - $( - if let Some(value) = self.$Unknown.next() { - init = f(init, $enum_type::$Unknown(value)); - } - )? init } } @@ -2227,9 +2173,6 @@ macro_rules! impl_bounds { $($enum_type::$Variant(v) => { self.$Variant = Some(v); })* - $($enum_type::$Unknown(v) => { - self.$Unknown.push(v); - })? }); } } @@ -2248,7 +2191,6 @@ macro_rules! impl_bounds { $(if let Some(v) = v.$Variant { self.$Variant = Some(v); })* - $(self.$Unknown.extend(v.$Unknown);)* }); } } @@ -2302,8 +2244,6 @@ impl_bounds! { Size, StaticType, Type, - #[unknown] - Unknown, } } @@ -2317,8 +2257,6 @@ impl_bounds! { ResetType, StaticType, Type, - #[unknown] - Unknown, } } @@ -2332,7 +2270,6 @@ impl From for ParsedBound { ParsedTypeBound::ResetType(v) => ParsedBound::ResetType(v), ParsedTypeBound::StaticType(v) => ParsedBound::StaticType(v), ParsedTypeBound::Type(v) => ParsedBound::Type(v), - ParsedTypeBound::Unknown(v) => ParsedBound::Unknown(v), } } } @@ -2347,7 +2284,6 @@ impl From for ParsedBounds { ResetType, StaticType, Type, - Unknown, } = value; Self { BoolOrIntType, @@ -2359,7 +2295,6 @@ impl From for ParsedBounds { Size: None, StaticType, Type, - Unknown, } } } @@ -2395,7 +2330,6 @@ impl ParsedTypeBound { ParsedTypeBound::Type(known_items::Type(span)), ]), Self::Type(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::from(v)]), - Self::Unknown(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::Unknown(v)]), } } } @@ -2430,7 +2364,6 @@ impl From for ParsedBounds { Size, StaticType: None, Type: None, - Unknown: vec![], } } } @@ -2458,7 +2391,6 @@ impl ParsedBounds { fn categorize(self, errors: &mut Errors, span: Span) -> ParsedBoundsCategory { let mut type_bounds = None; let mut size_type_bounds = None; - let mut unknown_bounds = vec![]; self.into_iter().for_each(|bound| match bound.categorize() { ParsedBoundCategory::Type(bound) => { type_bounds @@ -2470,37 +2402,15 @@ impl ParsedBounds { .get_or_insert_with(ParsedSizeTypeBounds::default) .extend([bound]); } - ParsedBoundCategory::Unknown(bound) => unknown_bounds.push(bound), }); - match (type_bounds, size_type_bounds, unknown_bounds.is_empty()) { - (None, None, true) => ParsedBoundsCategory::Type(ParsedTypeBounds { + match (type_bounds, size_type_bounds) { + (None, None) => ParsedBoundsCategory::Type(ParsedTypeBounds { Type: Some(known_items::Type(span)), ..Default::default() }), - (None, None, false) => { - errors.error( - unknown_bounds.remove(0), - "unknown bounds: must use at least one known bound (such as `Type`) with any unknown bounds", - ); - ParsedBoundsCategory::Type(ParsedTypeBounds { - Unknown: unknown_bounds, - ..Default::default() - }) - } - (None, Some(bounds), true) => ParsedBoundsCategory::SizeType(bounds), - (None, Some(bounds), false) => { - // TODO: implement - errors.error( - unknown_bounds.remove(0), - "unknown bounds with `Size` bounds are not implemented", - ); - ParsedBoundsCategory::SizeType(bounds) - } - (Some(bounds), None, _) => ParsedBoundsCategory::Type(ParsedTypeBounds { - Unknown: unknown_bounds, - ..bounds - }), - (Some(type_bounds), Some(size_type_bounds), _) => { + (None, Some(bounds)) => ParsedBoundsCategory::SizeType(bounds), + (Some(bounds), None) => ParsedBoundsCategory::Type(bounds), + (Some(type_bounds), Some(size_type_bounds)) => { errors.error( size_type_bounds .Size @@ -2517,7 +2427,6 @@ impl ParsedBounds { pub(crate) enum ParsedBoundCategory { Type(ParsedTypeBound), SizeType(ParsedSizeTypeBound), - Unknown(syn::TypeParamBound), } impl ParsedBound { @@ -2532,14 +2441,12 @@ impl ParsedBound { Self::Size(v) => ParsedBoundCategory::SizeType(ParsedSizeTypeBound::Size(v)), Self::StaticType(v) => ParsedBoundCategory::Type(ParsedTypeBound::StaticType(v)), Self::Type(v) => ParsedBoundCategory::Type(ParsedTypeBound::Type(v)), - Self::Unknown(v) => ParsedBoundCategory::Unknown(v), } } fn implied_bounds(self) -> ParsedBounds { match self.categorize() { ParsedBoundCategory::Type(v) => v.implied_bounds().into(), ParsedBoundCategory::SizeType(v) => v.implied_bounds().into(), - ParsedBoundCategory::Unknown(v) => ParsedBounds::from_iter([ParsedBound::Unknown(v)]), } } } @@ -3418,7 +3325,7 @@ impl ParsedGenerics { | ParsedTypeBound::EnumType(_) | ParsedTypeBound::IntType(_) | ParsedTypeBound::ResetType(_) => { - errors.error(bound, "bounds on mask types are not implemented"); + errors.error(bound, "bound on mask type not implemented"); } ParsedTypeBound::StaticType(bound) => { if bounds.StaticType.is_none() { @@ -3430,12 +3337,6 @@ impl ParsedGenerics { } } ParsedTypeBound::Type(_) => {} - ParsedTypeBound::Unknown(_) => { - errors.error( - bound, - "unknown bounds on mask types are not implemented", - ); - } } } bounds.add_implied_bounds(); diff --git a/crates/fayalite-proc-macros-impl/src/lib.rs b/crates/fayalite-proc-macros-impl/src/lib.rs index 4f7c4f0..6ba177b 100644 --- a/crates/fayalite-proc-macros-impl/src/lib.rs +++ b/crates/fayalite-proc-macros-impl/src/lib.rs @@ -72,14 +72,13 @@ mod kw { custom_keyword!(cfg); custom_keyword!(cfg_attr); custom_keyword!(clock_domain); - custom_keyword!(cmp_eq); custom_keyword!(connect_inexact); custom_keyword!(custom_bounds); custom_keyword!(flip); custom_keyword!(hdl); custom_keyword!(hdl_module); - custom_keyword!(incomplete_wire); custom_keyword!(input); + custom_keyword!(incomplete_wire); custom_keyword!(instance); custom_keyword!(m); custom_keyword!(memory); @@ -93,7 +92,6 @@ mod kw { custom_keyword!(output); custom_keyword!(reg_builder); custom_keyword!(reset); - custom_keyword!(sim); custom_keyword!(skip); custom_keyword!(target); custom_keyword!(wire); diff --git a/crates/fayalite-proc-macros-impl/src/module.rs b/crates/fayalite-proc-macros-impl/src/module.rs index 62b7837..0852f58 100644 --- a/crates/fayalite-proc-macros-impl/src/module.rs +++ b/crates/fayalite-proc-macros-impl/src/module.rs @@ -377,7 +377,7 @@ impl ModuleFn { module_kind, vis, sig, - mut block, + block, struct_generics, the_struct, } = match self.0 { @@ -439,12 +439,6 @@ impl ModuleFn { body_sig .inputs .insert(0, parse_quote! { m: &::fayalite::module::ModuleBuilder }); - block.stmts.insert( - 0, - parse_quote! { - let _ = m; - }, - ); let body_fn = ItemFn { attrs: vec![], vis: Visibility::Inherited, diff --git a/crates/fayalite-proc-macros-impl/src/module/transform_body.rs b/crates/fayalite-proc-macros-impl/src/module/transform_body.rs index a0f8eb0..c67f8dc 100644 --- a/crates/fayalite-proc-macros-impl/src/module/transform_body.rs +++ b/crates/fayalite-proc-macros-impl/src/module/transform_body.rs @@ -16,7 +16,7 @@ use std::{borrow::Borrow, convert::Infallible}; use syn::{ fold::{fold_expr, fold_expr_lit, fold_expr_unary, fold_local, fold_stmt, Fold}, parenthesized, - parse::{Parse, ParseStream}, + parse::{Nothing, Parse, ParseStream}, parse_quote, parse_quote_spanned, spanned::Spanned, token::Paren, @@ -27,13 +27,6 @@ use syn::{ mod expand_aggregate_literals; mod expand_match; -options! { - #[options = ExprOptions] - pub(crate) enum ExprOption { - Sim(sim), - } -} - options! { pub(crate) enum LetFnKind { Input(input), @@ -959,7 +952,7 @@ with_debug_clone_and_fold! { #[allow(dead_code)] pub(crate) struct HdlLet { pub(crate) attrs: Vec, - pub(crate) hdl_attr: HdlAttr, + pub(crate) hdl_attr: HdlAttr, pub(crate) let_token: Token![let], pub(crate) mut_token: Option, pub(crate) name: Ident, @@ -1180,7 +1173,7 @@ impl Visitor<'_> { Some(_) => {} } } - fn process_hdl_if(&mut self, hdl_attr: HdlAttr, expr_if: ExprIf) -> Expr { + fn process_hdl_if(&mut self, hdl_attr: HdlAttr, expr_if: ExprIf) -> Expr { let ExprIf { attrs, if_token, @@ -1188,10 +1181,10 @@ impl Visitor<'_> { then_branch, else_branch, } = expr_if; - let (else_token, else_expr) = else_branch.unzip(); - let else_expr = else_expr.map(|else_expr| match *else_expr { - Expr::If(expr_if) => Box::new(self.process_hdl_if(hdl_attr.clone(), expr_if)), - _ => else_expr, + self.require_normal_module_or_fn(if_token); + let else_expr = else_branch.unzip().1.map(|else_expr| match *else_expr { + Expr::If(expr_if) => self.process_hdl_if(hdl_attr.clone(), expr_if), + expr => expr, }); if let Expr::Let(ExprLet { attrs: let_attrs, @@ -1213,19 +1206,7 @@ impl Visitor<'_> { }, ); } - let ExprOptions { sim } = hdl_attr.body; - if sim.is_some() { - ExprIf { - attrs, - if_token, - cond: parse_quote_spanned! {if_token.span=> - *::fayalite::sim::value::SimValue::<::fayalite::int::Bool>::value(&::fayalite::sim::value::ToSimValue::into_sim_value(#cond)) - }, - then_branch, - else_branch: else_token.zip(else_expr), - } - .into() - } else if let Some(else_expr) = else_expr { + if let Some(else_expr) = else_expr { parse_quote_spanned! {if_token.span=> #(#attrs)* { @@ -1687,8 +1668,6 @@ impl Fold for Visitor<'_> { Repeat => process_hdl_repeat, Struct => process_hdl_struct, Tuple => process_hdl_tuple, - MethodCall => process_hdl_method_call, - Call => process_hdl_call, } } } @@ -1696,7 +1675,7 @@ impl Fold for Visitor<'_> { fn fold_local(&mut self, mut let_stmt: Local) -> Local { match self .errors - .ok(HdlAttr::::parse_and_leave_attr( + .ok(HdlAttr::::parse_and_leave_attr( &let_stmt.attrs, )) { None => return empty_let(), @@ -1715,11 +1694,10 @@ impl Fold for Visitor<'_> { subpat: None, }) = pat else { - let hdl_attr = - HdlAttr::::parse_and_take_attr(&mut let_stmt.attrs) - .ok() - .flatten() - .expect("already checked above"); + let hdl_attr = HdlAttr::::parse_and_take_attr(&mut let_stmt.attrs) + .ok() + .flatten() + .expect("already checked above"); let let_stmt = fold_local(self, let_stmt); return self.process_hdl_let_pat(hdl_attr, let_stmt); }; diff --git a/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_aggregate_literals.rs b/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_aggregate_literals.rs index 61f6c75..b5a0ad3 100644 --- a/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_aggregate_literals.rs +++ b/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_aggregate_literals.rs @@ -1,103 +1,45 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information - -use crate::{ - kw, - module::transform_body::{ - expand_match::{parse_enum_path, EnumPath}, - ExprOptions, Visitor, - }, - HdlAttr, -}; +use crate::{kw, module::transform_body::Visitor, HdlAttr}; use quote::{format_ident, quote_spanned}; -use std::mem; use syn::{ - parse_quote_spanned, punctuated::Punctuated, spanned::Spanned, token::Paren, Expr, ExprArray, - ExprCall, ExprGroup, ExprMethodCall, ExprParen, ExprPath, ExprRepeat, ExprStruct, ExprTuple, - FieldValue, Token, TypePath, + parse::Nothing, parse_quote, parse_quote_spanned, spanned::Spanned, Expr, ExprArray, ExprPath, + ExprRepeat, ExprStruct, ExprTuple, FieldValue, TypePath, }; impl Visitor<'_> { pub(crate) fn process_hdl_array( &mut self, - hdl_attr: HdlAttr, + hdl_attr: HdlAttr, mut expr_array: ExprArray, ) -> Expr { - let ExprOptions { sim } = hdl_attr.body; - let span = hdl_attr.kw.span; - if sim.is_some() { - for elem in &mut expr_array.elems { - *elem = parse_quote_spanned! {elem.span()=> - ::fayalite::sim::value::ToSimValue::to_sim_value(&(#elem)) - }; - } - parse_quote_spanned! {span=> - ::fayalite::sim::value::ToSimValue::into_sim_value(#expr_array) - } - } else { - for elem in &mut expr_array.elems { - *elem = parse_quote_spanned! {elem.span()=> - ::fayalite::expr::ToExpr::to_expr(&(#elem)) - }; - } - parse_quote_spanned! {span=> - ::fayalite::expr::ToExpr::to_expr(&#expr_array) - } + self.require_normal_module_or_fn(hdl_attr); + for elem in &mut expr_array.elems { + *elem = parse_quote_spanned! {elem.span()=> + ::fayalite::expr::ToExpr::to_expr(&(#elem)) + }; } + parse_quote! {::fayalite::expr::ToExpr::to_expr(&#expr_array)} } pub(crate) fn process_hdl_repeat( &mut self, - hdl_attr: HdlAttr, + hdl_attr: HdlAttr, mut expr_repeat: ExprRepeat, ) -> Expr { + self.require_normal_module_or_fn(hdl_attr); let repeated_value = &expr_repeat.expr; - let ExprOptions { sim } = hdl_attr.body; - let span = hdl_attr.kw.span; - if sim.is_some() { - *expr_repeat.expr = parse_quote_spanned! {repeated_value.span()=> - ::fayalite::sim::value::ToSimValue::to_sim_value(&(#repeated_value)) - }; - parse_quote_spanned! {span=> - ::fayalite::sim::value::ToSimValue::into_sim_value(#expr_repeat) - } - } else { - *expr_repeat.expr = parse_quote_spanned! {repeated_value.span()=> - ::fayalite::expr::ToExpr::to_expr(&(#repeated_value)) - }; - parse_quote_spanned! {span=> - ::fayalite::expr::ToExpr::to_expr(&#expr_repeat) - } - } + *expr_repeat.expr = parse_quote_spanned! {repeated_value.span()=> + ::fayalite::expr::ToExpr::to_expr(&(#repeated_value)) + }; + parse_quote! {::fayalite::expr::ToExpr::to_expr(&#expr_repeat)} } pub(crate) fn process_hdl_struct( &mut self, - hdl_attr: HdlAttr, - mut expr_struct: ExprStruct, + hdl_attr: HdlAttr, + expr_struct: ExprStruct, ) -> Expr { + self.require_normal_module_or_fn(&hdl_attr); let name_span = expr_struct.path.segments.last().unwrap().ident.span(); - let ExprOptions { sim } = hdl_attr.body; - if sim.is_some() { - let ty_path = TypePath { - qself: expr_struct.qself.take(), - path: expr_struct.path, - }; - expr_struct.path = parse_quote_spanned! {name_span=> - __SimValue::<#ty_path> - }; - for field in &mut expr_struct.fields { - let expr = &field.expr; - field.expr = parse_quote_spanned! {field.member.span()=> - ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr)) - }; - } - return parse_quote_spanned! {name_span=> - { - type __SimValue = ::SimValue; - let value: ::fayalite::sim::value::SimValue<#ty_path> = ::fayalite::sim::value::ToSimValue::into_sim_value(#expr_struct); - value - } - }; - } let builder_ident = format_ident!("__builder", span = name_span); let empty_builder = if expr_struct.qself.is_some() || expr_struct @@ -149,126 +91,12 @@ impl Visitor<'_> { } pub(crate) fn process_hdl_tuple( &mut self, - hdl_attr: HdlAttr, - mut expr_tuple: ExprTuple, + hdl_attr: HdlAttr, + expr_tuple: ExprTuple, ) -> Expr { - let ExprOptions { sim } = hdl_attr.body; - if sim.is_some() { - for element in &mut expr_tuple.elems { - *element = parse_quote_spanned! {element.span()=> - &(#element) - }; - } - parse_quote_spanned! {expr_tuple.span()=> - ::fayalite::sim::value::ToSimValue::into_sim_value(#expr_tuple) - } - } else { - parse_quote_spanned! {expr_tuple.span()=> - ::fayalite::expr::ToExpr::to_expr(&#expr_tuple) - } + self.require_normal_module_or_fn(hdl_attr); + parse_quote_spanned! {expr_tuple.span()=> + ::fayalite::expr::ToExpr::to_expr(&#expr_tuple) } } - pub(crate) fn process_hdl_call( - &mut self, - hdl_attr: HdlAttr, - mut expr_call: ExprCall, - ) -> Expr { - let span = hdl_attr.kw.span; - let mut func = &mut *expr_call.func; - let EnumPath { - variant_path: _, - enum_path, - variant_name, - } = loop { - match func { - Expr::Group(ExprGroup { expr, .. }) | Expr::Paren(ExprParen { expr, .. }) => { - func = &mut **expr; - } - Expr::Path(_) => { - let Expr::Path(ExprPath { attrs, qself, path }) = - mem::replace(func, Expr::PLACEHOLDER) - else { - unreachable!(); - }; - match parse_enum_path(TypePath { qself, path }) { - Ok(path) => break path, - Err(path) => { - self.errors.error(&path, "unsupported enum variant path"); - let TypePath { qself, path } = path; - *func = ExprPath { attrs, qself, path }.into(); - return expr_call.into(); - } - } - } - _ => { - self.errors.error( - &expr_call.func, - "#[hdl] function call -- function must be a possibly-parenthesized path", - ); - return expr_call.into(); - } - } - }; - self.process_hdl_method_call( - hdl_attr, - ExprMethodCall { - attrs: expr_call.attrs, - receiver: parse_quote_spanned! {span=> - <#enum_path as ::fayalite::ty::StaticType>::TYPE - }, - dot_token: Token![.](span), - method: variant_name, - turbofish: None, - paren_token: expr_call.paren_token, - args: expr_call.args, - }, - ) - } - pub(crate) fn process_hdl_method_call( - &mut self, - hdl_attr: HdlAttr, - mut expr_method_call: ExprMethodCall, - ) -> Expr { - let ExprOptions { sim } = hdl_attr.body; - let span = hdl_attr.kw.span; - // remove any number of groups and up to one paren - let mut receiver = &mut *expr_method_call.receiver; - let mut has_group = false; - let receiver = loop { - match receiver { - Expr::Group(ExprGroup { expr, .. }) => { - has_group = true; - receiver = expr; - } - Expr::Paren(ExprParen { expr, .. }) => break &mut **expr, - receiver @ Expr::Path(_) => break receiver, - _ => { - if !has_group { - self.errors.error( - &expr_method_call.receiver, - "#[hdl] on a method call needs parenthesized receiver", - ); - } - break &mut *expr_method_call.receiver; - } - } - }; - let func = if sim.is_some() { - parse_quote_spanned! {span=> - ::fayalite::enum_::enum_type_to_sim_builder - } - } else { - parse_quote_spanned! {span=> - ::fayalite::enum_::assert_is_enum_type - } - }; - *expr_method_call.receiver = ExprCall { - attrs: vec![], - func, - paren_token: Paren(span), - args: Punctuated::from_iter([mem::replace(receiver, Expr::PLACEHOLDER)]), - } - .into(); - expr_method_call.into() - } } 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 68218c1..f1ff2c2 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 @@ -3,9 +3,7 @@ use crate::{ fold::{impl_fold, DoFold}, kw, - module::transform_body::{ - empty_let, with_debug_clone_and_fold, wrap_ty_with_expr, ExprOptions, Visitor, - }, + module::transform_body::{empty_let, with_debug_clone_and_fold, wrap_ty_with_expr, Visitor}, Errors, HdlAttr, PairsIterExt, }; use proc_macro2::{Span, TokenStream}; @@ -13,6 +11,7 @@ use quote::{format_ident, quote_spanned, ToTokens, TokenStreamExt}; use std::collections::BTreeSet; use syn::{ fold::{fold_arm, fold_expr_match, fold_local, fold_pat, Fold}, + parse::Nothing, parse_quote_spanned, punctuated::Punctuated, spanned::Spanned, @@ -83,14 +82,7 @@ visit_trait! { } } fn visit_match_pat_enum_variant(state: _, v: &MatchPatEnumVariant) { - let MatchPatEnumVariant { - match_span:_, - sim:_, - variant_path: _, - enum_path: _, - variant_name: _, - field, - } = v; + let MatchPatEnumVariant {match_span:_, variant_path: _, enum_path: _, variant_name: _, field } = v; if let Some((_, v)) = field { state.visit_match_pat_simple(v); } @@ -300,7 +292,6 @@ impl ToTokens for MatchPatTuple { with_debug_clone_and_fold! { struct MatchPatEnumVariant<> { match_span: Span, - sim: Option<(kw::sim,)>, variant_path: Path, enum_path: Path, variant_name: Ident, @@ -312,7 +303,6 @@ impl ToTokens for MatchPatEnumVariant { fn to_tokens(&self, tokens: &mut TokenStream) { let Self { match_span, - sim, variant_path: _, enum_path, variant_name, @@ -322,28 +312,7 @@ impl ToTokens for MatchPatEnumVariant { __MatchTy::<#enum_path>::#variant_name } .to_tokens(tokens); - if sim.is_some() { - if let Some((paren_token, field)) = field { - paren_token.surround(tokens, |tokens| { - field.to_tokens(tokens); - match field { - MatchPatSimple::Paren(_) - | MatchPatSimple::Or(_) - | MatchPatSimple::Binding(_) - | MatchPatSimple::Wild(_) => quote_spanned! {*match_span=> - , _ - } - .to_tokens(tokens), - MatchPatSimple::Rest(_) => {} - } - }); - } else { - quote_spanned! {*match_span=> - (_) - } - .to_tokens(tokens); - } - } else if let Some((paren_token, field)) = field { + if let Some((paren_token, field)) = field { paren_token.surround(tokens, |tokens| field.to_tokens(tokens)); } } @@ -380,13 +349,13 @@ impl ToTokens for MatchPatSimple { } } -pub(crate) struct EnumPath { - pub(crate) variant_path: Path, - pub(crate) enum_path: Path, - pub(crate) variant_name: Ident, +struct EnumPath { + variant_path: Path, + enum_path: Path, + variant_name: Ident, } -pub(crate) fn parse_enum_path(variant_path: TypePath) -> Result { +fn parse_enum_path(variant_path: TypePath) -> Result { let TypePath { qself: None, path: variant_path, @@ -478,7 +447,6 @@ trait ParseMatchPat: Sized { state, MatchPatEnumVariant { match_span: state.match_span, - sim: state.sim, variant_path, enum_path, variant_name, @@ -525,7 +493,6 @@ trait ParseMatchPat: Sized { state, MatchPatEnumVariant { match_span: state.match_span, - sim: state.sim, variant_path, enum_path, variant_name, @@ -610,7 +577,6 @@ trait ParseMatchPat: Sized { state, MatchPatEnumVariant { match_span: state.match_span, - sim: state.sim, variant_path, enum_path, variant_name, @@ -973,7 +939,6 @@ impl Fold for RewriteAsCheckMatch { } struct HdlMatchParseState<'a> { - sim: Option<(kw::sim,)>, match_span: Span, errors: &'a mut Errors, } @@ -1016,11 +981,10 @@ impl<'a> VisitMatchPat<'a> for HdlLetPatVisitState<'a> { impl Visitor<'_> { pub(crate) fn process_hdl_let_pat( &mut self, - hdl_attr: HdlAttr, + _hdl_attr: HdlAttr, mut let_stmt: Local, ) -> Local { let span = let_stmt.let_token.span(); - let ExprOptions { sim } = hdl_attr.body; if let Pat::Type(pat) = &mut let_stmt.pat { *pat.ty = wrap_ty_with_expr((*pat.ty).clone()); } @@ -1032,6 +996,7 @@ impl Visitor<'_> { init, semi_token, } = let_stmt; + self.require_normal_module_or_fn(let_token); let Some(syn::LocalInit { eq_token, expr, @@ -1050,7 +1015,6 @@ impl Visitor<'_> { } let Ok(pat) = MatchPat::parse( &mut HdlMatchParseState { - sim, match_span: span, errors: &mut self.errors, }, @@ -1067,47 +1031,29 @@ impl Visitor<'_> { errors: _, bindings, } = state; - let retval = if sim.is_some() { - parse_quote_spanned! {span=> - let (#(#bindings,)*) = { - type __MatchTy = ::SimValue; - let __match_value = ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr)); - #let_token #pat #eq_token ::fayalite::sim::value::SimValue::into_value(__match_value) #semi_token - (#(#bindings,)*) + let retval = parse_quote_spanned! {span=> + let (#(#bindings,)* __scope,) = { + type __MatchTy = ::MatchVariant; + let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr)); + ::fayalite::expr::check_match_expr(__match_expr, |__match_value, __infallible| { + #[allow(unused_variables)] + #check_let_stmt + match __infallible {} + }); + let mut __match_iter = ::fayalite::module::match_(__match_expr); + let ::fayalite::__std::option::Option::Some(__match_variant) = ::fayalite::__std::iter::Iterator::next(&mut __match_iter) else { + ::fayalite::__std::unreachable!("#[hdl] let with uninhabited type"); }; - } - } else { - parse_quote_spanned! {span=> - let (#(#bindings,)* __scope,) = { - type __MatchTy = ::MatchVariant; - let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr)); - ::fayalite::expr::check_match_expr( - __match_expr, - |__match_value, __infallible| { - #[allow(unused_variables)] - #check_let_stmt - match __infallible {} - }, + let ::fayalite::__std::option::Option::None = ::fayalite::__std::iter::Iterator::next(&mut __match_iter) else { + ::fayalite::__std::unreachable!("#[hdl] let with refutable pattern"); + }; + let (__match_variant, __scope) = + ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( + __match_variant, ); - let mut __match_iter = ::fayalite::module::match_(__match_expr); - let ::fayalite::__std::option::Option::Some(__match_variant) = - ::fayalite::__std::iter::Iterator::next(&mut __match_iter) - else { - ::fayalite::__std::unreachable!("#[hdl] let with uninhabited type"); - }; - let ::fayalite::__std::option::Option::None = - ::fayalite::__std::iter::Iterator::next(&mut __match_iter) - else { - ::fayalite::__std::unreachable!("#[hdl] let with refutable pattern"); - }; - let (__match_variant, __scope) = - ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( - __match_variant, - ); - #let_token #pat #eq_token __match_variant #semi_token - (#(#bindings,)* __scope,) - }; - } + #let_token #pat #eq_token __match_variant #semi_token + (#(#bindings,)* __scope,) + }; }; match retval { syn::Stmt::Local(retval) => retval, @@ -1116,7 +1062,7 @@ impl Visitor<'_> { } pub(crate) fn process_hdl_match( &mut self, - hdl_attr: HdlAttr, + _hdl_attr: HdlAttr, expr_match: ExprMatch, ) -> Expr { let span = expr_match.match_token.span(); @@ -1128,9 +1074,8 @@ impl Visitor<'_> { brace_token: _, arms, } = expr_match; - let ExprOptions { sim } = hdl_attr.body; + self.require_normal_module_or_fn(match_token); let mut state = HdlMatchParseState { - sim, match_span: span, errors: &mut self.errors, }; @@ -1138,36 +1083,24 @@ impl Visitor<'_> { arms.into_iter() .filter_map(|arm| MatchArm::parse(&mut state, arm).ok()), ); - let expr = if sim.is_some() { - quote_spanned! {span=> - { - type __MatchTy = ::SimValue; - let __match_expr = ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr)); - #match_token ::fayalite::sim::value::SimValue::into_value(__match_expr) { + let expr = quote_spanned! {span=> + { + type __MatchTy = ::MatchVariant; + let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr)); + ::fayalite::expr::check_match_expr(__match_expr, |__match_value, __infallible| { + #[allow(unused_variables)] + #check_match + }); + for __match_variant in ::fayalite::module::match_(__match_expr) { + let (__match_variant, __scope) = + ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( + __match_variant, + ); + #match_token __match_variant { #(#arms)* } } } - } else { - quote_spanned! {span=> - { - type __MatchTy = ::MatchVariant; - let __match_expr = ::fayalite::expr::ToExpr::to_expr(&(#expr)); - ::fayalite::expr::check_match_expr(__match_expr, |__match_value, __infallible| { - #[allow(unused_variables)] - #check_match - }); - for __match_variant in ::fayalite::module::match_(__match_expr) { - let (__match_variant, __scope) = - ::fayalite::ty::MatchVariantAndInactiveScope::match_activate_scope( - __match_variant, - ); - #match_token __match_variant { - #(#arms)* - } - } - } - } }; syn::parse2(expr).unwrap() } diff --git a/crates/fayalite/Cargo.toml b/crates/fayalite/Cargo.toml index f176698..2652792 100644 --- a/crates/fayalite/Cargo.toml +++ b/crates/fayalite/Cargo.toml @@ -40,7 +40,6 @@ fayalite-visit-gen.workspace = true [features] unstable-doc = [] -unstable-test-hasher = [] [package.metadata.docs.rs] features = ["unstable-doc"] diff --git a/crates/fayalite/src/annotations.rs b/crates/fayalite/src/annotations.rs index 1c517ae..8eff4a0 100644 --- a/crates/fayalite/src/annotations.rs +++ b/crates/fayalite/src/annotations.rs @@ -12,7 +12,7 @@ use std::{ ops::Deref, }; -#[derive(Clone, Debug)] +#[derive(Clone)] struct CustomFirrtlAnnotationFieldsImpl { value: serde_json::Map, serialized: Interned, diff --git a/crates/fayalite/src/array.rs b/crates/fayalite/src/array.rs index 6d9b043..f617f91 100644 --- a/crates/fayalite/src/array.rs +++ b/crates/fayalite/src/array.rs @@ -2,24 +2,17 @@ // See Notices.txt for copyright information use crate::{ - expr::{ - ops::{ArrayLiteral, ExprFromIterator, ExprIntoIterator, ExprPartialEq}, - CastToBits, Expr, HdlPartialEq, ReduceBits, ToExpr, - }, - int::{Bool, DynSize, KnownSize, Size, SizeType, DYN_SIZE}, + expr::{ops::ArrayIndex, Expr, ToExpr}, + int::{DynSize, KnownSize, Size, SizeType, DYN_SIZE}, intern::{Intern, Interned, LazyInterned}, module::transform::visit::{Fold, Folder, Visit, Visitor}, - sim::value::{SimValue, SimValuePartialEq}, source_location::SourceLocation, ty::{ - serde_impls::SerdeCanonicalType, CanonicalType, MatchVariantWithoutScope, StaticType, Type, - TypeProperties, TypeWithDeref, + CanonicalType, MatchVariantWithoutScope, StaticType, Type, TypeProperties, TypeWithDeref, }, util::ConstUsize, }; -use bitvec::slice::BitSlice; -use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; -use std::{iter::FusedIterator, ops::Index}; +use std::ops::Index; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct ArrayType { @@ -98,12 +91,6 @@ impl> ArrayType { } } -impl Default for ArrayType { - fn default() -> Self { - Self::TYPE - } -} - impl StaticType for ArrayType { const TYPE: Self = Self { element: LazyInterned::new_lazy(&|| T::TYPE.intern_sized()), @@ -152,7 +139,6 @@ impl, Len: Size, State: Visitor + ?Sized> Visit impl Type for ArrayType { type BaseType = Array; type MaskType = ArrayType; - type SimValue = Len::ArraySimValue; type MatchVariant = Len::ArrayMatch; type MatchActiveScope = (); type MatchVariantAndInactiveScope = MatchVariantWithoutScope>; @@ -162,8 +148,10 @@ impl Type for ArrayType { this: Expr, source_location: SourceLocation, ) -> Self::MatchVariantsIter { + let base = Expr::as_dyn_array(this); + let base_ty = Expr::ty(base); let _ = source_location; - let retval = Vec::from_iter(this); + let retval = Vec::from_iter((0..base_ty.len()).map(|i| ArrayIndex::new(base, i).to_expr())); std::iter::once(MatchVariantWithoutScope( Len::ArrayMatch::::try_from(retval) .ok() @@ -189,97 +177,16 @@ impl Type for ArrayType { Len::from_usize(array.len()), ) } - fn source_location() -> SourceLocation { SourceLocation::builtin() } - - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), self.type_properties.bit_width); - let element = self.element(); - let element_bit_width = element.canonical().bit_width(); - TryFrom::try_from(Vec::from_iter((0..self.len()).map(|i| { - SimValue::from_bitslice(element, &bits[i * element_bit_width..][..element_bit_width]) - }))) - .ok() - .expect("used correct length") - } - - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), self.type_properties.bit_width); - let element_ty = self.element(); - let element_bit_width = element_ty.canonical().bit_width(); - let value: &mut [SimValue] = value.as_mut(); - assert_eq!(self.len(), value.len()); - for (i, element_value) in value.iter_mut().enumerate() { - assert_eq!(SimValue::ty(element_value), element_ty); - SimValue::bits_mut(element_value) - .bits_mut() - .copy_from_bitslice(&bits[i * element_bit_width..][..element_bit_width]); - } - } - - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), self.type_properties.bit_width); - let element_ty = self.element(); - let element_bit_width = element_ty.canonical().bit_width(); - let value: &[SimValue] = value.as_ref(); - assert_eq!(self.len(), value.len()); - for (i, element_value) in value.iter().enumerate() { - assert_eq!(SimValue::ty(element_value), element_ty); - bits[i * element_bit_width..][..element_bit_width] - .copy_from_bitslice(SimValue::bits(element_value).bits()); - } - } -} - -impl Serialize for ArrayType { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - SerdeCanonicalType::::Array { - element: self.element(), - len: self.len(), - } - .serialize(serializer) - } -} - -impl<'de, T: Type + Deserialize<'de>, Len: Size> Deserialize<'de> for ArrayType { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let name = |len| -> String { - if let Some(len) = len { - format!("an Array<_, {len}>") - } else { - "an Array<_>".to_string() - } - }; - match SerdeCanonicalType::::deserialize(deserializer)? { - SerdeCanonicalType::Array { element, len } => { - if let Some(len) = Len::try_from_usize(len) { - Ok(Self::new(element, len)) - } else { - Err(Error::invalid_value( - serde::de::Unexpected::Other(&name(Some(len))), - &&*name(Len::KNOWN_VALUE), - )) - } - } - ty => Err(Error::invalid_value( - serde::de::Unexpected::Other(ty.as_serde_unexpected_str()), - &&*name(Len::KNOWN_VALUE), - )), - } - } } impl TypeWithDeref for ArrayType { fn expr_deref(this: &Expr) -> &Self::MatchVariant { - let retval = Vec::from_iter(*this); + let base = Expr::as_dyn_array(*this); + let base_ty = Expr::ty(base); + let retval = Vec::from_iter((0..base_ty.len()).map(|i| ArrayIndex::new(base, i).to_expr())); Interned::into_inner(Intern::intern_sized( Len::ArrayMatch::::try_from(retval) .ok() @@ -311,143 +218,3 @@ impl Index for ArrayWithoutLen { Interned::into_inner(Intern::intern_sized(ArrayType::new(self.element, len))) } } - -impl ExprPartialEq> for ArrayType -where - Lhs: ExprPartialEq, -{ - fn cmp_eq(lhs: Expr, rhs: Expr>) -> Expr { - let lhs_ty = Expr::ty(lhs); - let rhs_ty = Expr::ty(rhs); - assert_eq!(lhs_ty.len(), rhs_ty.len()); - lhs.into_iter() - .zip(rhs) - .map(|(l, r)| l.cmp_eq(r)) - .collect::>>() - .cast_to_bits() - .all_one_bits() - } - - fn cmp_ne(lhs: Expr, rhs: Expr>) -> Expr { - let lhs_ty = Expr::ty(lhs); - let rhs_ty = Expr::ty(rhs); - assert_eq!(lhs_ty.len(), rhs_ty.len()); - lhs.into_iter() - .zip(rhs) - .map(|(l, r)| l.cmp_ne(r)) - .collect::>>() - .cast_to_bits() - .any_one_bits() - } -} - -impl SimValuePartialEq> for ArrayType -where - Lhs: SimValuePartialEq, -{ - fn sim_value_eq(this: &SimValue, other: &SimValue>) -> bool { - AsRef::<[_]>::as_ref(&**this) - .iter() - .zip(AsRef::<[_]>::as_ref(&**other)) - .all(|(l, r)| SimValuePartialEq::sim_value_eq(l, r)) - } -} - -impl ExprIntoIterator for ArrayType { - type Item = T; - type ExprIntoIter = ExprArrayIter; - - fn expr_into_iter(e: Expr) -> Self::ExprIntoIter { - ExprArrayIter { - base: e, - indexes: 0..Expr::ty(e).len(), - } - } -} - -#[derive(Clone, Debug)] -pub struct ExprArrayIter { - base: Expr>, - indexes: std::ops::Range, -} - -impl ExprArrayIter { - pub fn base(&self) -> Expr> { - self.base - } - pub fn indexes(&self) -> std::ops::Range { - self.indexes.clone() - } -} - -impl Iterator for ExprArrayIter { - type Item = Expr; - - fn next(&mut self) -> Option { - self.indexes.next().map(|i| self.base[i]) - } - - fn size_hint(&self) -> (usize, Option) { - self.indexes.size_hint() - } - - fn count(self) -> usize { - self.indexes.count() - } - - fn last(mut self) -> Option { - self.next_back() - } - - fn nth(&mut self, n: usize) -> Option { - self.indexes.nth(n).map(|i| self.base[i]) - } - - fn fold(self, init: B, mut f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.indexes.fold(init, |b, i| f(b, self.base[i])) - } -} - -impl DoubleEndedIterator for ExprArrayIter { - fn next_back(&mut self) -> Option { - self.indexes.next_back().map(|i| self.base[i]) - } - - fn nth_back(&mut self, n: usize) -> Option { - self.indexes.nth_back(n).map(|i| self.base[i]) - } - - fn rfold(self, init: B, mut f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.indexes.rfold(init, |b, i| f(b, self.base[i])) - } -} - -impl ExactSizeIterator for ExprArrayIter { - fn len(&self) -> usize { - self.indexes.len() - } -} - -impl FusedIterator for ExprArrayIter {} - -impl ExprFromIterator> for Array { - fn expr_from_iter>>(iter: T) -> Expr { - ArrayLiteral::new( - A::TYPE, - iter.into_iter().map(|v| Expr::canonical(v)).collect(), - ) - .to_expr() - } -} - -impl<'a, A: StaticType> ExprFromIterator<&'a Expr> for Array { - fn expr_from_iter>>(iter: T) -> Expr { - iter.into_iter().copied().collect() - } -} diff --git a/crates/fayalite/src/bundle.rs b/crates/fayalite/src/bundle.rs index 240c0c6..995510e 100644 --- a/crates/fayalite/src/bundle.rs +++ b/crates/fayalite/src/bundle.rs @@ -2,25 +2,20 @@ // See Notices.txt for copyright information use crate::{ - expr::{ - ops::{ArrayLiteral, BundleLiteral, ExprPartialEq}, - CastToBits, Expr, ReduceBits, ToExpr, - }, - int::{Bool, DynSize}, + expr::{ops::BundleLiteral, Expr, ToExpr}, intern::{Intern, Interned}, - sim::value::{SimValue, SimValuePartialEq, ToSimValue, ToSimValueWithType}, + sim::{SimValue, ToSimValue}, source_location::SourceLocation, ty::{ - impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, OpaqueSimValue, - StaticType, Type, TypeProperties, TypeWithDeref, + impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, StaticType, Type, + TypeProperties, TypeWithDeref, }, - util::HashMap, }; -use bitvec::{slice::BitSlice, vec::BitVec}; -use serde::{Deserialize, Serialize}; +use bitvec::vec::BitVec; +use hashbrown::HashMap; use std::{fmt, marker::PhantomData}; -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct BundleField { pub name: Interned, pub flipped: bool, @@ -160,7 +155,7 @@ impl Default for BundleTypePropertiesBuilder { impl Bundle { #[track_caller] pub fn new(fields: Interned<[BundleField]>) -> Self { - let mut name_indexes = HashMap::with_capacity_and_hasher(fields.len(), Default::default()); + let mut name_indexes = HashMap::with_capacity(fields.len()); let mut field_offsets = Vec::with_capacity(fields.len()); let mut type_props_builder = BundleTypePropertiesBuilder::new(); for (index, &BundleField { name, flipped, ty }) in fields.iter().enumerate() { @@ -217,7 +212,6 @@ impl Bundle { impl Type for Bundle { type BaseType = Bundle; type MaskType = Bundle; - type SimValue = OpaqueSimValue; impl_match_variant_as_self!(); fn mask_type(&self) -> Self::MaskType { Self::new(Interned::from_iter(self.0.fields.into_iter().map( @@ -241,20 +235,6 @@ impl Type for Bundle { fn source_location() -> SourceLocation { SourceLocation::builtin() } - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), self.type_properties().bit_width); - OpaqueSimValue::from_bitslice(bits) - } - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), self.type_properties().bit_width); - assert_eq!(value.bit_width(), self.type_properties().bit_width); - value.bits_mut().bits_mut().copy_from_bitslice(bits); - } - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), self.type_properties().bit_width); - assert_eq!(value.bit_width(), self.type_properties().bit_width); - bits.copy_from_bitslice(value.bits().bits()); - } } pub trait BundleType: Type { @@ -263,93 +243,6 @@ pub trait BundleType: Type { fn fields(&self) -> Interned<[BundleField]>; } -pub struct BundleSimValueFromBits<'a> { - fields: std::slice::Iter<'static, BundleField>, - bits: &'a BitSlice, -} - -impl<'a> BundleSimValueFromBits<'a> { - #[track_caller] - pub fn new(bundle_ty: T, bits: &'a BitSlice) -> Self { - let fields = bundle_ty.fields(); - assert_eq!( - bits.len(), - fields - .iter() - .map(|BundleField { ty, .. }| ty.bit_width()) - .sum::() - ); - Self { - fields: Interned::into_inner(fields).iter(), - bits, - } - } - #[track_caller] - fn field_ty_and_bits(&mut self) -> (T, &'a BitSlice) { - let Some(&BundleField { - name: _, - flipped: _, - ty, - }) = self.fields.next() - else { - panic!("tried to read too many fields from BundleSimValueFromBits"); - }; - let (field_bits, rest) = self.bits.split_at(ty.bit_width()); - self.bits = rest; - (T::from_canonical(ty), field_bits) - } - #[track_caller] - pub fn field_from_bits(&mut self) -> SimValue { - let (field_ty, field_bits) = self.field_ty_and_bits::(); - SimValue::from_bitslice(field_ty, field_bits) - } - #[track_caller] - pub fn field_clone_from_bits(&mut self, field_value: &mut SimValue) { - let (field_ty, field_bits) = self.field_ty_and_bits::(); - assert_eq!(field_ty, SimValue::ty(field_value)); - SimValue::bits_mut(field_value) - .bits_mut() - .copy_from_bitslice(field_bits); - } -} - -pub struct BundleSimValueToBits<'a> { - fields: std::slice::Iter<'static, BundleField>, - bits: &'a mut BitSlice, -} - -impl<'a> BundleSimValueToBits<'a> { - #[track_caller] - pub fn new(bundle_ty: T, bits: &'a mut BitSlice) -> Self { - let fields = bundle_ty.fields(); - assert_eq!( - bits.len(), - fields - .iter() - .map(|BundleField { ty, .. }| ty.bit_width()) - .sum::() - ); - Self { - fields: Interned::into_inner(fields).iter(), - bits, - } - } - #[track_caller] - pub fn field_to_bits(&mut self, field_value: &SimValue) { - let Some(&BundleField { - name: _, - flipped: _, - ty, - }) = self.fields.next() - else { - panic!("tried to read too many fields from BundleSimValueFromBits"); - }; - assert_eq!(T::from_canonical(ty), SimValue::ty(field_value)); - self.bits[..ty.bit_width()].copy_from_bitslice(SimValue::bits(field_value).bits()); - self.bits = &mut std::mem::take(&mut self.bits)[ty.bit_width()..]; - } -} - #[derive(Default)] pub struct NoBuilder; @@ -432,19 +325,7 @@ macro_rules! impl_tuple_builder_fields { } macro_rules! impl_tuples { - ( - [$({ - #[ - num = $num:tt, - field = $field:ident, - ty = $ty_var:ident: $Ty:ident, - lhs = $lhs_var:ident: $Lhs:ident, - rhs = $rhs_var:ident: $Rhs:ident - ] - $var:ident: $T:ident - })*] - [] - ) => { + ([$({#[num = $num:literal, field = $field:ident, ty = $ty_var:ident: $Ty:ident] $var:ident: $T:ident})*] []) => { impl_tuple_builder_fields! { {} [$({ @@ -456,7 +337,6 @@ macro_rules! impl_tuples { impl<$($T: Type,)*> Type for ($($T,)*) { type BaseType = Bundle; type MaskType = ($($T::MaskType,)*); - type SimValue = ($(SimValue<$T>,)*); type MatchVariant = ($(Expr<$T>,)*); type MatchActiveScope = (); type MatchVariantAndInactiveScope = MatchVariantWithoutScope; @@ -495,24 +375,6 @@ macro_rules! impl_tuples { fn source_location() -> SourceLocation { SourceLocation::builtin() } - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - #![allow(unused_mut, unused_variables)] - let mut v = BundleSimValueFromBits::new(*self, bits); - $(let $var = v.field_from_bits();)* - ($($var,)*) - } - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - #![allow(unused_mut, unused_variables)] - let mut v = BundleSimValueFromBits::new(*self, bits); - let ($($var,)*) = value; - $(v.field_clone_from_bits($var);)* - } - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - #![allow(unused_mut, unused_variables)] - let mut v = BundleSimValueToBits::new(*self, bits); - let ($($var,)*) = value; - $(v.field_to_bits($var);)* - } } impl<$($T: Type,)*> BundleType for ($($T,)*) { type Builder = TupleBuilder<($(Unfilled<$T>,)*)>; @@ -563,104 +425,77 @@ macro_rules! impl_tuples { BundleLiteral::new(ty, field_values[..].intern()).to_expr() } } - impl<$($T: ToSimValueWithType,)*> ToSimValueWithType for ($($T,)*) { + impl<$($T: ToSimValue,)*> ToSimValue for ($($T,)*) { #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(ToSimValueWithType::::to_sim_value_with_type(self, Bundle::from_canonical(ty))) + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + ToSimValue::::to_sim_value(self, Bundle::from_canonical(ty)).into_canonical() } #[track_caller] - fn into_sim_value_with_type(self, ty: CanonicalType) -> SimValue + fn into_sim_value(self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(ToSimValueWithType::::into_sim_value_with_type(self, Bundle::from_canonical(ty))) + ToSimValue::::into_sim_value(self, Bundle::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + ToSimValue::::box_into_sim_value(self, Bundle::from_canonical(ty)).into_canonical() } } - impl<$($T: ToSimValueWithType,)*> ToSimValueWithType for ($($T,)*) { + impl<$($T: ToSimValue,)*> ToSimValue for ($($T,)*) { #[track_caller] - fn to_sim_value_with_type(&self, ty: Bundle) -> SimValue { + fn to_sim_value(&self, ty: Bundle) -> SimValue { let ($($var,)*) = self; let [$($ty_var,)*] = *ty.fields() else { panic!("bundle has wrong number of fields"); }; - $(let $var = $var.to_sim_value_with_type($ty_var.ty);)* - ToSimValueWithType::into_sim_value_with_type(($($var,)*), ty) + $(let $var = $var.to_sim_value($ty_var.ty);)* + ToSimValue::into_sim_value(($($var,)*), ty) } #[track_caller] - fn into_sim_value_with_type(self, ty: Bundle) -> SimValue { + fn into_sim_value(self, ty: Bundle) -> SimValue { #![allow(unused_mut)] #![allow(clippy::unused_unit)] let ($($var,)*) = self; let [$($ty_var,)*] = *ty.fields() else { panic!("bundle has wrong number of fields"); }; - let mut bits = BitVec::new(); - $(let $var = $var.into_sim_value_with_type($ty_var.ty); - assert_eq!(SimValue::ty(&$var), $ty_var.ty); - bits.extend_from_bitslice(SimValue::bits(&$var).bits()); + let mut bits: Option = None; + $(let $var = $var.into_sim_value($ty_var.ty); + assert_eq!($var.ty(), $ty_var.ty); + if !$var.bits().is_empty() { + if let Some(bits) = &mut bits { + bits.extend_from_bitslice($var.bits()); + } else { + let mut $var = $var.into_bits(); + $var.reserve(ty.type_properties().bit_width - $var.len()); + bits = Some($var); + } + } )* - bits.into_sim_value_with_type(ty) + bits.unwrap_or_else(BitVec::new).into_sim_value(ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Bundle) -> SimValue { + Self::into_sim_value(*self, ty) } } - impl<$($T: ToSimValueWithType<$Ty>, $Ty: Type,)*> ToSimValueWithType<($($Ty,)*)> for ($($T,)*) { + impl<$($T: ToSimValue<$Ty>, $Ty: Type,)*> ToSimValue<($($Ty,)*)> for ($($T,)*) { #[track_caller] - fn to_sim_value_with_type(&self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { + fn to_sim_value(&self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { let ($($var,)*) = self; let ($($ty_var,)*) = ty; - $(let $var = $var.to_sim_value_with_type($ty_var);)* - SimValue::from_value(ty, ($($var,)*)) + $(let $var = $var.to_sim_value($ty_var).into_canonical();)* + SimValue::from_canonical(ToSimValue::into_sim_value(($($var,)*), ty.canonical())) } #[track_caller] - fn into_sim_value_with_type(self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { + fn into_sim_value(self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { let ($($var,)*) = self; let ($($ty_var,)*) = ty; - $(let $var = $var.into_sim_value_with_type($ty_var);)* - SimValue::from_value(ty, ($($var,)*)) - } - } - impl<$($T: ToSimValue,)*> ToSimValue for ($($T,)*) { - type Type = ($($T::Type,)*); - #[track_caller] - fn to_sim_value(&self) -> SimValue { - let ($($var,)*) = self; - $(let $var = $var.to_sim_value();)* - SimValue::from_value(($(SimValue::ty(&$var),)*), ($($var,)*)) + $(let $var = $var.into_sim_value($ty_var).into_canonical();)* + SimValue::from_canonical(ToSimValue::into_sim_value(($($var,)*), ty.canonical())) } #[track_caller] - fn into_sim_value(self) -> SimValue { - let ($($var,)*) = self; - $(let $var = $var.to_sim_value();)* - SimValue::from_value(($(SimValue::ty(&$var),)*), ($($var,)*)) - } - } - impl<$($Lhs: Type + ExprPartialEq<$Rhs>, $Rhs: Type,)*> ExprPartialEq<($($Rhs,)*)> for ($($Lhs,)*) { - fn cmp_eq(lhs: Expr, rhs: Expr<($($Rhs,)*)>) -> Expr { - let ($($lhs_var,)*) = *lhs; - let ($($rhs_var,)*) = *rhs; - ArrayLiteral::::new( - Bool, - FromIterator::from_iter([$(Expr::canonical(ExprPartialEq::cmp_eq($lhs_var, $rhs_var)),)*]), - ) - .cast_to_bits() - .all_one_bits() - } - - fn cmp_ne(lhs: Expr, rhs: Expr<($($Rhs,)*)>) -> Expr { - let ($($lhs_var,)*) = *lhs; - let ($($rhs_var,)*) = *rhs; - ArrayLiteral::::new( - Bool, - FromIterator::from_iter([$(Expr::canonical(ExprPartialEq::cmp_ne($lhs_var, $rhs_var)),)*]), - ) - .cast_to_bits() - .any_one_bits() - } - } - impl<$($Lhs: SimValuePartialEq<$Rhs>, $Rhs: Type,)*> SimValuePartialEq<($($Rhs,)*)> for ($($Lhs,)*) { - fn sim_value_eq(lhs: &SimValue, rhs: &SimValue<($($Rhs,)*)>) -> bool { - let ($($lhs_var,)*) = &**lhs; - let ($($rhs_var,)*) = &**rhs; - let retval = true; - $(let retval = retval && $lhs_var == $rhs_var;)* - retval + fn box_into_sim_value(self: Box, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { + Self::into_sim_value(*self, ty) } } }; @@ -672,25 +507,24 @@ macro_rules! impl_tuples { impl_tuples! { [] [ - {#[num = 0, field = field_0, ty = ty0: Ty0, lhs = lhs0: Lhs0, rhs = rhs0: Rhs0] v0: T0} - {#[num = 1, field = field_1, ty = ty1: Ty1, lhs = lhs1: Lhs1, rhs = rhs1: Rhs1] v1: T1} - {#[num = 2, field = field_2, ty = ty2: Ty2, lhs = lhs2: Lhs2, rhs = rhs2: Rhs2] v2: T2} - {#[num = 3, field = field_3, ty = ty3: Ty3, lhs = lhs3: Lhs3, rhs = rhs3: Rhs3] v3: T3} - {#[num = 4, field = field_4, ty = ty4: Ty4, lhs = lhs4: Lhs4, rhs = rhs4: Rhs4] v4: T4} - {#[num = 5, field = field_5, ty = ty5: Ty5, lhs = lhs5: Lhs5, rhs = rhs5: Rhs5] v5: T5} - {#[num = 6, field = field_6, ty = ty6: Ty6, lhs = lhs6: Lhs6, rhs = rhs6: Rhs6] v6: T6} - {#[num = 7, field = field_7, ty = ty7: Ty7, lhs = lhs7: Lhs7, rhs = rhs7: Rhs7] v7: T7} - {#[num = 8, field = field_8, ty = ty8: Ty8, lhs = lhs8: Lhs8, rhs = rhs8: Rhs8] v8: T8} - {#[num = 9, field = field_9, ty = ty9: Ty9, lhs = lhs9: Lhs9, rhs = rhs9: Rhs9] v9: T9} - {#[num = 10, field = field_10, ty = ty10: Ty10, lhs = lhs10: Lhs10, rhs = rhs10: Rhs10] v10: T10} - {#[num = 11, field = field_11, ty = ty11: Ty11, lhs = lhs11: Lhs11, rhs = rhs11: Rhs11] v11: T11} + {#[num = 0, field = field_0, ty = ty0: Ty0] v0: T0} + {#[num = 1, field = field_1, ty = ty1: Ty1] v1: T1} + {#[num = 2, field = field_2, ty = ty2: Ty2] v2: T2} + {#[num = 3, field = field_3, ty = ty3: Ty3] v3: T3} + {#[num = 4, field = field_4, ty = ty4: Ty4] v4: T4} + {#[num = 5, field = field_5, ty = ty5: Ty5] v5: T5} + {#[num = 6, field = field_6, ty = ty6: Ty6] v6: T6} + {#[num = 7, field = field_7, ty = ty7: Ty7] v7: T7} + {#[num = 8, field = field_8, ty = ty8: Ty8] v8: T8} + {#[num = 9, field = field_9, ty = ty9: Ty9] v9: T9} + {#[num = 10, field = field_10, ty = ty10: Ty10] v10: T10} + {#[num = 11, field = field_11, ty = ty11: Ty11] v11: T11} ] } impl Type for PhantomData { type BaseType = Bundle; type MaskType = (); - type SimValue = PhantomData; type MatchVariant = PhantomData; type MatchActiveScope = (); type MatchVariantAndInactiveScope = MatchVariantWithoutScope; @@ -723,16 +557,6 @@ impl Type for PhantomData { fn source_location() -> SourceLocation { SourceLocation::builtin() } - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert!(bits.is_empty()); - *self - } - fn sim_value_clone_from_bits(&self, _value: &mut Self::SimValue, bits: &BitSlice) { - assert!(bits.is_empty()); - } - fn sim_value_to_bits(&self, _value: &Self::SimValue, bits: &mut BitSlice) { - assert!(bits.is_empty()); - } } pub struct PhantomDataBuilder(PhantomData); @@ -780,38 +604,26 @@ impl ToExpr for PhantomData { } } -impl ToSimValue for PhantomData { - type Type = PhantomData; - +impl ToSimValue for PhantomData { #[track_caller] - fn to_sim_value(&self) -> SimValue { - SimValue::from_value(*self, *self) + fn to_sim_value(&self, ty: Self) -> SimValue { + ToSimValue::into_sim_value(BitVec::new(), ty) } } -impl ToSimValueWithType for PhantomData { +impl ToSimValue for PhantomData { #[track_caller] - fn to_sim_value_with_type(&self, ty: Self) -> SimValue { - SimValue::from_value(ty, *self) - } -} - -impl ToSimValueWithType for PhantomData { - #[track_caller] - fn to_sim_value_with_type(&self, ty: Bundle) -> SimValue { + fn to_sim_value(&self, ty: Bundle) -> SimValue { assert!(ty.fields().is_empty()); - ToSimValueWithType::into_sim_value_with_type(BitVec::new(), ty) + ToSimValue::into_sim_value(BitVec::new(), ty) } } -impl ToSimValueWithType for PhantomData { +impl ToSimValue for PhantomData { #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { let ty = Bundle::from_canonical(ty); assert!(ty.fields().is_empty()); - SimValue::into_canonical(ToSimValueWithType::into_sim_value_with_type( - BitVec::new(), - ty, - )) + ToSimValue::into_sim_value(BitVec::new(), ty).into_canonical() } } diff --git a/crates/fayalite/src/cli.rs b/crates/fayalite/src/cli.rs index 1f208a8..66741ef 100644 --- a/crates/fayalite/src/cli.rs +++ b/crates/fayalite/src/cli.rs @@ -258,7 +258,7 @@ pub struct VerilogArgs { default_value = "firtool", env = "FIRTOOL", value_hint = ValueHint::CommandName, - value_parser = OsStringValueParser::new().try_map(which) + value_parser = OsStringValueParser::new().try_map(which::which) )] pub firtool: PathBuf, #[arg(long)] @@ -428,13 +428,6 @@ impl clap::Args for FormalAdjustArgs { } } -fn which(v: std::ffi::OsString) -> which::Result { - #[cfg(not(miri))] - return which::which(v); - #[cfg(miri)] - return Ok(Path::new("/").join(v)); -} - #[derive(Parser, Clone)] #[non_exhaustive] pub struct FormalArgs { @@ -445,7 +438,7 @@ pub struct FormalArgs { default_value = "sby", env = "SBY", value_hint = ValueHint::CommandName, - value_parser = OsStringValueParser::new().try_map(which) + value_parser = OsStringValueParser::new().try_map(which::which) )] pub sby: PathBuf, #[arg(long)] diff --git a/crates/fayalite/src/clock.rs b/crates/fayalite/src/clock.rs index f0623d4..711432b 100644 --- a/crates/fayalite/src/clock.rs +++ b/crates/fayalite/src/clock.rs @@ -8,7 +8,6 @@ use crate::{ source_location::SourceLocation, ty::{impl_match_variant_as_self, CanonicalType, StaticType, Type, TypeProperties}, }; -use bitvec::slice::BitSlice; #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)] pub struct Clock; @@ -16,7 +15,6 @@ pub struct Clock; impl Type for Clock { type BaseType = Clock; type MaskType = Bool; - type SimValue = bool; impl_match_variant_as_self!(); @@ -38,21 +36,6 @@ impl Type for Clock { }; retval } - - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), 1); - bits[0] - } - - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), 1); - *value = bits[0]; - } - - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), 1); - bits.set(0, *value); - } } impl Clock { diff --git a/crates/fayalite/src/enum_.rs b/crates/fayalite/src/enum_.rs index 36b5aa7..2ed0b8e 100644 --- a/crates/fayalite/src/enum_.rs +++ b/crates/fayalite/src/enum_.rs @@ -2,30 +2,21 @@ // See Notices.txt for copyright information use crate::{ - expr::{ - ops::{ExprPartialEq, VariantAccess}, - Expr, ToExpr, - }, + expr::{ops::VariantAccess, Expr, ToExpr}, hdl, - int::{Bool, UIntValue}, + int::Bool, intern::{Intern, Interned}, module::{ connect, enum_match_variants_helper, incomplete_wire, wire, EnumMatchVariantAndInactiveScopeImpl, EnumMatchVariantsIterImpl, Scope, }, - sim::value::{SimValue, SimValuePartialEq}, source_location::SourceLocation, - ty::{ - CanonicalType, MatchVariantAndInactiveScope, OpaqueSimValue, StaticType, Type, - TypeProperties, - }, - util::HashMap, + ty::{CanonicalType, MatchVariantAndInactiveScope, StaticType, Type, TypeProperties}, }; -use bitvec::{order::Lsb0, slice::BitSlice, view::BitView}; -use serde::{Deserialize, Serialize}; -use std::{convert::Infallible, fmt, iter::FusedIterator, sync::Arc}; +use hashbrown::HashMap; +use std::{convert::Infallible, fmt, iter::FusedIterator}; -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct EnumVariant { pub name: Interned, pub ty: Option, @@ -158,12 +149,6 @@ impl EnumTypePropertiesBuilder { variant_count: variant_count + 1, } } - #[must_use] - pub fn variants(self, variants: impl IntoIterator) -> Self { - variants.into_iter().fold(self, |this, variant| { - this.variant(variant.ty.map(CanonicalType::type_properties)) - }) - } pub const fn finish(self) -> TypeProperties { assert!( self.variant_count != 0, @@ -193,8 +178,7 @@ impl Default for EnumTypePropertiesBuilder { impl Enum { #[track_caller] pub fn new(variants: Interned<[EnumVariant]>) -> Self { - let mut name_indexes = - HashMap::with_capacity_and_hasher(variants.len(), Default::default()); + let mut name_indexes = HashMap::with_capacity(variants.len()); let mut type_props_builder = EnumTypePropertiesBuilder::new(); for (index, EnumVariant { name, ty }) in variants.iter().enumerate() { if let Some(old_index) = name_indexes.insert(*name, index) { @@ -261,7 +245,6 @@ pub trait EnumType: MatchVariantsIter = EnumMatchVariantsIter, > { - type SimBuilder: From; fn variants(&self) -> Interned<[EnumVariant]>; fn match_activate_scope( v: Self::MatchVariantAndInactiveScope, @@ -324,18 +307,7 @@ impl DoubleEndedIterator for EnumMatchVariantsIter { } } -pub struct NoBuilder { - _ty: Enum, -} - -impl From for NoBuilder { - fn from(_ty: Enum) -> Self { - Self { _ty } - } -} - impl EnumType for Enum { - type SimBuilder = NoBuilder; fn match_activate_scope( v: Self::MatchVariantAndInactiveScope, ) -> (Self::MatchVariant, Self::MatchActiveScope) { @@ -350,7 +322,6 @@ impl EnumType for Enum { impl Type for Enum { type BaseType = Enum; type MaskType = Bool; - type SimValue = OpaqueSimValue; type MatchVariant = Option>; type MatchActiveScope = Scope; type MatchVariantAndInactiveScope = EnumMatchVariantAndInactiveScope; @@ -381,309 +352,6 @@ impl Type for Enum { fn source_location() -> SourceLocation { SourceLocation::builtin() } - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), self.type_properties().bit_width); - OpaqueSimValue::from_bitslice(bits) - } - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), self.type_properties().bit_width); - assert_eq!(value.bit_width(), self.type_properties().bit_width); - value.bits_mut().bits_mut().copy_from_bitslice(bits); - } - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), self.type_properties().bit_width); - assert_eq!(value.bit_width(), self.type_properties().bit_width); - bits.copy_from_bitslice(value.bits().bits()); - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, Default)] -pub struct EnumPaddingSimValue { - bits: Option, -} - -impl EnumPaddingSimValue { - pub const fn new() -> Self { - Self { bits: None } - } - pub fn bit_width(&self) -> Option { - self.bits.as_ref().map(UIntValue::width) - } - pub fn bits(&self) -> &Option { - &self.bits - } - pub fn bits_mut(&mut self) -> &mut Option { - &mut self.bits - } - pub fn into_bits(self) -> Option { - self.bits - } - pub fn from_bits(bits: Option) -> Self { - Self { bits } - } - pub fn from_bitslice(v: &BitSlice) -> Self { - Self { - bits: Some(UIntValue::new(Arc::new(v.to_bitvec()))), - } - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct UnknownVariantSimValue { - discriminant: usize, - body_bits: UIntValue, -} - -impl UnknownVariantSimValue { - pub fn discriminant(&self) -> usize { - self.discriminant - } - pub fn body_bits(&self) -> &UIntValue { - &self.body_bits - } - pub fn body_bits_mut(&mut self) -> &mut UIntValue { - &mut self.body_bits - } - pub fn into_body_bits(self) -> UIntValue { - self.body_bits - } - pub fn into_parts(self) -> (usize, UIntValue) { - (self.discriminant, self.body_bits) - } - pub fn new(discriminant: usize, body_bits: UIntValue) -> Self { - Self { - discriminant, - body_bits, - } - } -} - -pub struct EnumSimValueFromBits<'a> { - variants: Interned<[EnumVariant]>, - discriminant: usize, - body_bits: &'a BitSlice, -} - -impl<'a> EnumSimValueFromBits<'a> { - #[track_caller] - pub fn new(ty: T, bits: &'a BitSlice) -> Self { - let variants = ty.variants(); - let bit_width = EnumTypePropertiesBuilder::new() - .variants(variants) - .finish() - .bit_width; - assert_eq!(bit_width, bits.len()); - let (discriminant_bits, body_bits) = - bits.split_at(discriminant_bit_width_impl(variants.len())); - let mut discriminant = 0usize; - discriminant.view_bits_mut::()[..discriminant_bits.len()] - .copy_from_bitslice(discriminant_bits); - Self { - variants, - discriminant, - body_bits, - } - } - pub fn discriminant(&self) -> usize { - self.discriminant - } - #[track_caller] - #[cold] - fn usage_error(&self, clone: bool) -> ! { - let clone = if clone { "clone_" } else { "" }; - match self.variants.get(self.discriminant) { - None => { - panic!("should have called EnumSimValueFromBits::unknown_variant_{clone}from_bits"); - } - Some(EnumVariant { ty: None, .. }) => { - panic!( - "should have called EnumSimValueFromBits::variant_no_field_{clone}from_bits" - ); - } - Some(EnumVariant { ty: Some(_), .. }) => { - panic!( - "should have called EnumSimValueFromBits::variant_with_field_{clone}from_bits" - ); - } - } - } - #[track_caller] - fn known_variant(&self, clone: bool) -> (Option, &'a BitSlice, &'a BitSlice) { - let Some(EnumVariant { ty, .. }) = self.variants.get(self.discriminant) else { - self.usage_error(clone); - }; - let variant_bit_width = ty.map_or(0, CanonicalType::bit_width); - let (variant_bits, padding_bits) = self.body_bits.split_at(variant_bit_width); - (*ty, variant_bits, padding_bits) - } - #[track_caller] - pub fn unknown_variant_from_bits(self) -> UnknownVariantSimValue { - let None = self.variants.get(self.discriminant) else { - self.usage_error(false); - }; - UnknownVariantSimValue::new( - self.discriminant, - UIntValue::new(Arc::new(self.body_bits.to_bitvec())), - ) - } - #[track_caller] - pub fn unknown_variant_clone_from_bits(self, value: &mut UnknownVariantSimValue) { - let None = self.variants.get(self.discriminant) else { - self.usage_error(true); - }; - value.discriminant = self.discriminant; - assert_eq!(value.body_bits.width(), self.body_bits.len()); - value - .body_bits - .bits_mut() - .copy_from_bitslice(self.body_bits); - } - #[track_caller] - pub fn variant_no_field_from_bits(self) -> EnumPaddingSimValue { - let (None, _variant_bits, padding_bits) = self.known_variant(false) else { - self.usage_error(false); - }; - EnumPaddingSimValue::from_bitslice(padding_bits) - } - #[track_caller] - pub fn variant_with_field_from_bits(self) -> (SimValue, EnumPaddingSimValue) { - let (Some(variant_ty), variant_bits, padding_bits) = self.known_variant(false) else { - self.usage_error(false); - }; - ( - SimValue::from_bitslice(T::from_canonical(variant_ty), variant_bits), - EnumPaddingSimValue::from_bitslice(padding_bits), - ) - } - #[track_caller] - fn clone_padding_from_bits(padding: &mut EnumPaddingSimValue, padding_bits: &BitSlice) { - match padding.bits_mut() { - None => *padding = EnumPaddingSimValue::from_bitslice(padding_bits), - Some(padding) => { - assert_eq!(padding.width(), padding_bits.len()); - padding.bits_mut().copy_from_bitslice(padding_bits); - } - } - } - #[track_caller] - pub fn variant_no_field_clone_from_bits(self, padding: &mut EnumPaddingSimValue) { - let (None, _variant_bits, padding_bits) = self.known_variant(true) else { - self.usage_error(true); - }; - Self::clone_padding_from_bits(padding, padding_bits); - } - #[track_caller] - pub fn variant_with_field_clone_from_bits( - self, - value: &mut SimValue, - padding: &mut EnumPaddingSimValue, - ) { - let (Some(variant_ty), variant_bits, padding_bits) = self.known_variant(true) else { - self.usage_error(true); - }; - assert_eq!(SimValue::ty(value), T::from_canonical(variant_ty)); - SimValue::bits_mut(value) - .bits_mut() - .copy_from_bitslice(variant_bits); - Self::clone_padding_from_bits(padding, padding_bits); - } -} - -pub struct EnumSimValueToBits<'a> { - variants: Interned<[EnumVariant]>, - bit_width: usize, - discriminant_bit_width: usize, - bits: &'a mut BitSlice, -} - -impl<'a> EnumSimValueToBits<'a> { - #[track_caller] - pub fn new(ty: T, bits: &'a mut BitSlice) -> Self { - let variants = ty.variants(); - let bit_width = EnumTypePropertiesBuilder::new() - .variants(variants) - .finish() - .bit_width; - assert_eq!(bit_width, bits.len()); - Self { - variants, - bit_width, - discriminant_bit_width: discriminant_bit_width_impl(variants.len()), - bits, - } - } - #[track_caller] - fn discriminant_to_bits(&mut self, mut discriminant: usize) { - let orig_discriminant = discriminant; - let discriminant_bits = - &mut discriminant.view_bits_mut::()[..self.discriminant_bit_width]; - self.bits[..self.discriminant_bit_width].copy_from_bitslice(discriminant_bits); - discriminant_bits.fill(false); - assert!( - discriminant == 0, - "{orig_discriminant:#x} is too big to fit in enum discriminant bits", - ); - } - #[track_caller] - pub fn unknown_variant_to_bits(mut self, value: &UnknownVariantSimValue) { - self.discriminant_to_bits(value.discriminant); - let None = self.variants.get(value.discriminant) else { - panic!("can't use UnknownVariantSimValue to set known discriminant"); - }; - assert_eq!( - self.bit_width - self.discriminant_bit_width, - value.body_bits.width() - ); - self.bits[self.discriminant_bit_width..].copy_from_bitslice(value.body_bits.bits()); - } - #[track_caller] - fn known_variant( - mut self, - discriminant: usize, - padding: &EnumPaddingSimValue, - ) -> (Option, &'a mut BitSlice) { - self.discriminant_to_bits(discriminant); - let variant_ty = self.variants[discriminant].ty; - let variant_bit_width = variant_ty.map_or(0, CanonicalType::bit_width); - let padding_bits = &mut self.bits[self.discriminant_bit_width..][variant_bit_width..]; - if let Some(padding) = padding.bits() { - assert_eq!(padding.width(), padding_bits.len()); - padding_bits.copy_from_bitslice(padding.bits()); - } else { - padding_bits.fill(false); - } - let variant_bits = &mut self.bits[self.discriminant_bit_width..][..variant_bit_width]; - (variant_ty, variant_bits) - } - #[track_caller] - pub fn variant_no_field_to_bits(self, discriminant: usize, padding: &EnumPaddingSimValue) { - let (None, _variant_bits) = self.known_variant(discriminant, padding) else { - panic!("expected variant to have no field"); - }; - } - #[track_caller] - pub fn variant_with_field_to_bits( - self, - discriminant: usize, - value: &SimValue, - padding: &EnumPaddingSimValue, - ) { - let (Some(variant_ty), variant_bits) = self.known_variant(discriminant, padding) else { - panic!("expected variant to have a field"); - }; - assert_eq!(SimValue::ty(value), T::from_canonical(variant_ty)); - variant_bits.copy_from_bitslice(SimValue::bits(value).bits()); - } -} - -#[doc(hidden)] -pub fn assert_is_enum_type(v: T) -> T { - v -} - -#[doc(hidden)] -pub fn enum_type_to_sim_builder(v: T) -> T::SimBuilder { - v.into() } #[hdl] @@ -692,79 +360,6 @@ pub enum HdlOption { HdlSome(T), } -impl, Rhs: Type> ExprPartialEq> for HdlOption { - #[hdl] - fn cmp_eq(lhs: Expr, rhs: Expr>) -> Expr { - #[hdl] - let cmp_eq = wire(); - #[hdl] - match lhs { - HdlSome(lhs) => - { - #[hdl] - match rhs { - HdlSome(rhs) => connect(cmp_eq, ExprPartialEq::cmp_eq(lhs, rhs)), - HdlNone => connect(cmp_eq, false), - } - } - HdlNone => - { - #[hdl] - match rhs { - HdlSome(_) => connect(cmp_eq, false), - HdlNone => connect(cmp_eq, true), - } - } - } - cmp_eq - } - - #[hdl] - fn cmp_ne(lhs: Expr, rhs: Expr>) -> Expr { - #[hdl] - let cmp_ne = wire(); - #[hdl] - match lhs { - HdlSome(lhs) => - { - #[hdl] - match rhs { - HdlSome(rhs) => connect(cmp_ne, ExprPartialEq::cmp_ne(lhs, rhs)), - HdlNone => connect(cmp_ne, true), - } - } - HdlNone => - { - #[hdl] - match rhs { - HdlSome(_) => connect(cmp_ne, true), - HdlNone => connect(cmp_ne, false), - } - } - } - cmp_ne - } -} - -impl, Rhs: Type> SimValuePartialEq> for HdlOption { - fn sim_value_eq(this: &SimValue, other: &SimValue>) -> bool { - type SimValueMatch = ::SimValue; - match (&**this, &**other) { - (SimValueMatch::::HdlNone(_), SimValueMatch::>::HdlNone(_)) => { - true - } - (SimValueMatch::::HdlSome(..), SimValueMatch::>::HdlNone(_)) - | (SimValueMatch::::HdlNone(_), SimValueMatch::>::HdlSome(..)) => { - false - } - ( - SimValueMatch::::HdlSome(l, _), - SimValueMatch::>::HdlSome(r, _), - ) => l == r, - } - } -} - #[allow(non_snake_case)] pub fn HdlNone() -> Expr> { HdlOption[T::TYPE].HdlNone() diff --git a/crates/fayalite/src/expr.rs b/crates/fayalite/src/expr.rs index e070674..f0008f4 100644 --- a/crates/fayalite/src/expr.rs +++ b/crates/fayalite/src/expr.rs @@ -16,7 +16,6 @@ use crate::{ transform::visit::{Fold, Folder, Visit, Visitor}, Instance, ModuleIO, }, - phantom_const::PhantomConst, reg::Reg, reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset}, ty::{CanonicalType, StaticType, Type, TypeWithDeref}, @@ -110,7 +109,6 @@ expr_enum! { UIntLiteral(Interned), SIntLiteral(Interned), BoolLiteral(bool), - PhantomConst(PhantomConst), BundleLiteral(ops::BundleLiteral), ArrayLiteral(ops::ArrayLiteral), EnumLiteral(ops::EnumLiteral), @@ -274,17 +272,6 @@ pub struct Expr { impl fmt::Debug for Expr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(debug_assertions)] - { - let Self { - __enum, - __ty, - __flow, - } = self; - let expr_ty = __ty.canonical(); - let enum_ty = __enum.to_expr().__ty; - assert_eq!(expr_ty, enum_ty, "expr ty mismatch:\nExpr {{\n__enum: {__enum:?},\n__ty: {__ty:?},\n__flow: {__flow:?}\n}}"); - } self.__enum.fmt(f) } } @@ -711,7 +698,6 @@ impl CastToBits for T { } pub trait CastBitsTo { - #[track_caller] fn cast_bits_to(&self, ty: T) -> Expr; } @@ -769,27 +755,3 @@ pub fn repeat( ) .to_expr() } - -impl ToExpr for PhantomConst { - type Type = Self; - - fn to_expr(&self) -> Expr { - Expr { - __enum: ExprEnum::PhantomConst(self.canonical_phantom_const()).intern_sized(), - __ty: *self, - __flow: Flow::Source, - } - } -} - -impl GetTarget for PhantomConst { - fn target(&self) -> Option> { - None - } -} - -impl ToLiteralBits for PhantomConst { - fn to_literal_bits(&self) -> Result, NotALiteralExpr> { - Ok(Interned::default()) - } -} diff --git a/crates/fayalite/src/expr/ops.rs b/crates/fayalite/src/expr/ops.rs index e794a68..15c195e 100644 --- a/crates/fayalite/src/expr/ops.rs +++ b/crates/fayalite/src/expr/ops.rs @@ -11,15 +11,14 @@ use crate::{ GetTarget, Target, TargetPathArrayElement, TargetPathBundleField, TargetPathDynArrayElement, TargetPathElement, }, - CastBitsTo as _, CastTo, CastToBits as _, Expr, ExprEnum, Flow, HdlPartialEq, - HdlPartialOrd, NotALiteralExpr, ReduceBits, ToExpr, ToLiteralBits, + CastTo, Expr, ExprEnum, Flow, HdlPartialEq, HdlPartialOrd, NotALiteralExpr, ReduceBits, + ToExpr, ToLiteralBits, }, int::{ Bool, BoolOrIntType, DynSize, IntType, KnownSize, SInt, SIntType, SIntValue, Size, UInt, UIntType, UIntValue, }, intern::{Intern, Interned}, - phantom_const::{PhantomConst, PhantomConstValue}, reset::{ AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset, ToAsyncReset, ToReset, ToSyncReset, @@ -1893,26 +1892,6 @@ impl ExprCastTo for Clock { } } -impl ExprCastTo<()> for PhantomConst { - fn cast_to(src: Expr, to_type: ()) -> Expr<()> { - src.cast_to_bits().cast_bits_to(to_type) - } -} - -impl ExprCastTo> for () { - fn cast_to(src: Expr, to_type: PhantomConst) -> Expr> { - src.cast_to_bits().cast_bits_to(to_type) - } -} - -impl ExprCastTo> - for PhantomConst -{ - fn cast_to(src: Expr, to_type: PhantomConst) -> Expr> { - src.cast_to_bits().cast_bits_to(to_type) - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct FieldAccess { base: Expr, @@ -2729,47 +2708,3 @@ impl ToExpr for Uninit { } } } - -pub trait ExprIntoIterator: Type { - type Item: Type; - type ExprIntoIter: Iterator>; - - fn expr_into_iter(e: Expr) -> Self::ExprIntoIter; -} - -impl IntoIterator for Expr { - type Item = Expr; - type IntoIter = T::ExprIntoIter; - - fn into_iter(self) -> Self::IntoIter { - T::expr_into_iter(self) - } -} - -impl IntoIterator for &'_ Expr { - type Item = Expr; - type IntoIter = T::ExprIntoIter; - - fn into_iter(self) -> Self::IntoIter { - T::expr_into_iter(*self) - } -} - -impl IntoIterator for &'_ mut Expr { - type Item = Expr; - type IntoIter = T::ExprIntoIter; - - fn into_iter(self) -> Self::IntoIter { - T::expr_into_iter(*self) - } -} - -pub trait ExprFromIterator: Type { - fn expr_from_iter>(iter: T) -> Expr; -} - -impl, A> FromIterator for Expr { - fn from_iter>(iter: T) -> Self { - This::expr_from_iter(iter) - } -} diff --git a/crates/fayalite/src/firrtl.rs b/crates/fayalite/src/firrtl.rs index d33c7a9..ea76cf8 100644 --- a/crates/fayalite/src/firrtl.rs +++ b/crates/fayalite/src/firrtl.rs @@ -15,7 +15,7 @@ use crate::{ target::{ Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, }, - CastBitsTo, Expr, ExprEnum, + Expr, ExprEnum, }, formal::FormalKind, int::{Bool, DynSize, IntType, SIntValue, UInt, UIntValue}, @@ -36,11 +36,12 @@ use crate::{ ty::{CanonicalType, Type}, util::{ const_str_array_is_strictly_ascending, BitSliceWriteWithBase, DebugAsRawString, - GenericConstBool, HashMap, HashSet, + GenericConstBool, }, }; use bitvec::slice::BitSlice; use clap::value_parser; +use hashbrown::{HashMap, HashSet}; use num_traits::Signed; use serde::Serialize; use std::{ @@ -446,7 +447,6 @@ impl TypeState { CanonicalType::AsyncReset(AsyncReset {}) => "AsyncReset".into(), CanonicalType::SyncReset(SyncReset {}) => "UInt<1>".into(), CanonicalType::Reset(Reset {}) => "Reset".into(), - CanonicalType::PhantomConst(_) => "{}".into(), } } } @@ -1152,7 +1152,6 @@ impl<'a> Exporter<'a> { | CanonicalType::Clock(_) | CanonicalType::AsyncReset(_) | CanonicalType::Reset(_) => format!("asUInt({value_str})"), - CanonicalType::PhantomConst(_) => "UInt<0>(0)".into(), } } fn expr_cast_bits_to_bundle( @@ -1358,12 +1357,6 @@ impl<'a> Exporter<'a> { CanonicalType::AsyncReset(_) => format!("asAsyncReset({value_str})"), CanonicalType::SyncReset(_) => value_str, CanonicalType::Reset(_) => unreachable!("Reset is not bit castable to"), - CanonicalType::PhantomConst(_) => { - let retval = self.module.ns.make_new("_cast_bits_to_phantom_const_expr"); - definitions.add_definition_line(format_args!("{extra_indent}wire {retval}: {{}}")); - definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); - return retval.to_string(); - } } } fn expr_unary( @@ -1402,11 +1395,6 @@ impl<'a> Exporter<'a> { ExprEnum::UIntLiteral(literal) => self.uint_literal(&literal), ExprEnum::SIntLiteral(literal) => self.sint_literal(&literal), ExprEnum::BoolLiteral(literal) => self.bool_literal(literal), - ExprEnum::PhantomConst(ty) => self.expr( - UInt[0].zero().cast_bits_to(ty.canonical()), - definitions, - const_ty, - ), ExprEnum::ArrayLiteral(array_literal) => { self.array_literal_expr(array_literal, definitions, const_ty) } @@ -2257,7 +2245,6 @@ impl<'a> Exporter<'a> { ModuleBody::Extern(ExternModuleBody { verilog_name, parameters, - simulation: _, }) => { let verilog_name = Ident(verilog_name); writeln!(body, "{indent}defname = {verilog_name}").unwrap(); @@ -2621,7 +2608,7 @@ fn export_impl( indent_depth: &indent_depth, indent: " ", }, - seen_modules: HashSet::default(), + seen_modules: HashSet::new(), unwritten_modules: VecDeque::new(), global_ns, module: ModuleState::default(), diff --git a/crates/fayalite/src/int.rs b/crates/fayalite/src/int.rs index d8364b1..5d10b29 100644 --- a/crates/fayalite/src/int.rs +++ b/crates/fayalite/src/int.rs @@ -2,52 +2,27 @@ // See Notices.txt for copyright information use crate::{ - array::ArrayType, expr::{ target::{GetTarget, Target}, Expr, NotALiteralExpr, ToExpr, ToLiteralBits, }, - hdl, intern::{Intern, Interned, Memoize}, - sim::value::{SimValue, ToSimValueWithType}, source_location::SourceLocation, ty::{impl_match_variant_as_self, CanonicalType, StaticType, Type, TypeProperties}, util::{interned_bit, ConstBool, ConstUsize, GenericConstBool, GenericConstUsize}, }; -use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView}; +use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec}; use num_bigint::{BigInt, BigUint, Sign}; -use num_traits::{One, Signed, Zero}; -use serde::{ - de::{DeserializeOwned, Error, Visitor}, - Deserialize, Deserializer, Serialize, Serializer, -}; +use num_traits::{Signed, Zero}; use std::{ borrow::{BorrowMut, Cow}, fmt, marker::PhantomData, num::NonZero, ops::{Bound, Index, Not, Range, RangeBounds, RangeInclusive}, - str::FromStr, sync::Arc, }; -mod uint_in_range; - -#[hdl] -pub type UIntInRangeType = uint_in_range::UIntInRangeType; - -#[hdl] -pub type UIntInRange = - UIntInRangeType, ConstUsize>; - -#[hdl] -pub type UIntInRangeInclusiveType = - uint_in_range::UIntInRangeInclusiveType; - -#[hdl] -pub type UIntInRangeInclusive = - UIntInRangeInclusiveType, ConstUsize>; - mod sealed { pub trait BoolOrIntTypeSealed {} pub trait SizeSealed {} @@ -74,16 +49,6 @@ pub trait KnownSize: + IntoIterator> + TryFrom>> + Into>>; - type ArraySimValue: AsRef<[SimValue]> - + AsMut<[SimValue]> - + BorrowMut<[SimValue]> - + 'static - + Clone - + std::fmt::Debug - + IntoIterator> - + TryFrom>> - + Into>> - + ToSimValueWithType>; } macro_rules! known_widths { @@ -95,7 +60,6 @@ macro_rules! known_widths { }> { const SIZE: Self = Self; type ArrayMatch = [Expr; Self::VALUE]; - type ArraySimValue = [SimValue; Self::VALUE]; } }; ([2 $($rest:tt)*] $($bits:literal)+) => { @@ -108,7 +72,6 @@ macro_rules! known_widths { impl KnownSize for ConstUsize<{2 $(* $rest)*}> { const SIZE: Self = Self; type ArrayMatch = [Expr; Self::VALUE]; - type ArraySimValue = [SimValue; Self::VALUE]; } }; } @@ -116,31 +79,13 @@ macro_rules! known_widths { known_widths!([2 2 2 2 2 2 2 2 2]); pub trait SizeType: - sealed::SizeTypeSealed - + Copy - + Ord - + std::hash::Hash - + std::fmt::Debug - + Send - + Sync - + 'static - + Serialize - + DeserializeOwned + sealed::SizeTypeSealed + Copy + Ord + std::hash::Hash + std::fmt::Debug + Send + Sync + 'static { type Size: Size; } pub trait Size: - sealed::SizeSealed - + Copy - + Ord - + std::hash::Hash - + std::fmt::Debug - + Send - + Sync - + 'static - + Serialize - + DeserializeOwned + sealed::SizeSealed + Copy + Ord + std::hash::Hash + std::fmt::Debug + Send + Sync + 'static { type ArrayMatch: AsRef<[Expr]> + AsMut<[Expr]> @@ -155,16 +100,6 @@ pub trait Size: + IntoIterator> + TryFrom>> + Into>>; - type ArraySimValue: AsRef<[SimValue]> - + AsMut<[SimValue]> - + BorrowMut<[SimValue]> - + 'static - + Clone - + std::fmt::Debug - + IntoIterator> - + TryFrom>> - + Into>> - + ToSimValueWithType>; const KNOWN_VALUE: Option; type SizeType: SizeType + Copy @@ -190,7 +125,6 @@ impl SizeType for usize { impl Size for DynSize { type ArrayMatch = Box<[Expr]>; - type ArraySimValue = Box<[SimValue]>; const KNOWN_VALUE: Option = None; type SizeType = usize; @@ -213,7 +147,6 @@ impl SizeType for T { impl Size for T { type ArrayMatch = ::ArrayMatch; - type ArraySimValue = ::ArraySimValue; const KNOWN_VALUE: Option = Some(T::VALUE); @@ -232,305 +165,6 @@ impl Size for T { } } -#[derive(Clone, PartialEq, Eq, Debug)] -pub enum ParseIntValueError { - Empty, - InvalidDigit, - MissingDigits, - InvalidRadix, - MissingType, - InvalidType, - TypeMismatch { - parsed_signed: bool, - parsed_width: usize, - expected_signed: bool, - expected_width: usize, - }, - PosOverflow, - NegOverflow, - WidthOverflow, - MissingWidth, -} - -impl std::error::Error for ParseIntValueError {} - -impl fmt::Display for ParseIntValueError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match self { - Self::Empty => "can't parse integer from empty string", - Self::InvalidDigit => "invalid digit", - Self::MissingDigits => "missing digits", - Self::InvalidRadix => "invalid radix", - Self::MissingType => "missing type", - Self::InvalidType => "invalid type", - Self::TypeMismatch { - parsed_signed, - parsed_width, - expected_signed, - expected_width, - } => { - return write!( - f, - "type mismatch: parsed type {parsed_signed_str}{parsed_width}, \ - expected type {expected_signed_str}{expected_width}", - parsed_signed_str = if *parsed_signed { "i" } else { "u" }, - expected_signed_str = if *expected_signed { "i" } else { "u" }, - ); - } - Self::PosOverflow => "value too large to fit in type", - Self::NegOverflow => "value too small to fit in type", - Self::WidthOverflow => "width is too large", - Self::MissingWidth => "missing width", - }) - } -} - -fn parse_int_value( - s: &str, - type_is_signed: bool, - type_width: Option, - parse_type: bool, -) -> Result, ParseIntValueError> { - if !parse_type && type_width.is_none() { - return Err(ParseIntValueError::MissingWidth); - } - let mut s = s.trim(); - if s.is_empty() { - return Err(ParseIntValueError::Empty); - } - let negative = match s.bytes().next() { - Some(ch @ (b'+' | b'-')) => { - s = s[1..].trim_start(); - ch == b'-' - } - _ => false, - }; - let radix = match s.bytes().next() { - Some(b'0') => match s.bytes().nth(1) { - Some(b'x' | b'X') => { - s = &s[2..]; - 16 - } - Some(b'b' | b'B') => { - s = &s[2..]; - 2 - } - Some(b'o' | b'O') => { - s = &s[2..]; - 8 - } - _ => 10, - }, - Some(b'1'..=b'9') => 10, - _ => return Err(ParseIntValueError::InvalidDigit), - }; - let mut any_digits = false; - let digits_end = s - .as_bytes() - .iter() - .position(|&ch| { - if ch == b'_' { - false - } else if (ch as char).to_digit(radix).is_some() { - any_digits = true; - false - } else { - true - } - }) - .unwrap_or(s.len()); - let digits = &s[..digits_end]; - s = &s[digits_end..]; - if !any_digits { - return Err(ParseIntValueError::MissingDigits); - } - let width = if parse_type { - const HDL_PREFIX: &[u8] = b"hdl_"; - let mut missing_type = ParseIntValueError::MissingType; - if s.as_bytes() - .get(..HDL_PREFIX.len()) - .is_some_and(|bytes| bytes.eq_ignore_ascii_case(HDL_PREFIX)) - { - s = &s[HDL_PREFIX.len()..]; - missing_type = ParseIntValueError::InvalidType; - } - let signed = match s.bytes().next() { - Some(b'u' | b'U') => false, - Some(b'i' | b'I') => true, - Some(_) => return Err(ParseIntValueError::InvalidType), - None => return Err(missing_type), - }; - s = &s[1..]; - let mut width = 0usize; - let mut any_digits = false; - for ch in s.bytes() { - let digit = (ch as char) - .to_digit(10) - .ok_or(ParseIntValueError::InvalidDigit)?; - any_digits = true; - width = width - .checked_mul(10) - .and_then(|v| v.checked_add(digit as usize)) - .ok_or(ParseIntValueError::WidthOverflow)?; - } - if !any_digits { - return Err(ParseIntValueError::MissingDigits); - } - if width > ::MAX_BITS { - return Err(ParseIntValueError::WidthOverflow); - } - let expected_width = type_width.unwrap_or(width); - if type_is_signed != signed || expected_width != width { - let expected_width = type_width.unwrap_or(width); - return Err(ParseIntValueError::TypeMismatch { - parsed_signed: signed, - parsed_width: width, - expected_signed: type_is_signed, - expected_width, - }); - } - width - } else { - if !s.is_empty() { - return Err(ParseIntValueError::InvalidDigit); - } - type_width.expect("checked earlier") - }; - if !type_is_signed && negative { - return Err(ParseIntValueError::InvalidDigit); - } - if radix == 10 { - let mut value: BigInt = digits - .replace("_", "") - .parse() - .expect("checked that the digits are valid already"); - if negative { - value = -value; - } - let uint_value: UIntValue = UInt::new(width).from_bigint_wrapping(&value); - if value.is_zero() { - Ok(uint_value.into_bits()) - } else { - for i in 0..width { - value.set_bit(i as u64, type_is_signed && negative); - } - if value.is_zero() { - Ok(uint_value.into_bits()) - } else if type_is_signed && negative { - if value.sign() == Sign::Minus && value.magnitude().is_one() { - Ok(uint_value.into_bits()) - } else { - Err(ParseIntValueError::NegOverflow) - } - } else { - Err(ParseIntValueError::PosOverflow) - } - } - } else { - let mut value = BitVec::repeat(false, width); - let bits_per_digit = match radix { - 2 => 1, - 8 => 3, - 16 => 4, - _ => unreachable!(), - }; - let mut digits = digits - .bytes() - .rev() - .filter_map(|ch| (ch as char).to_digit(radix)); - let overflow_error = if negative { - ParseIntValueError::NegOverflow - } else { - ParseIntValueError::PosOverflow - }; - for chunk in value.chunks_mut(bits_per_digit) { - if let Some(mut digit) = digits.next() { - let digit_bits = &mut digit.view_bits_mut::()[..chunk.len()]; - chunk.clone_from_bitslice(digit_bits); - digit_bits.fill(false); - if digit != 0 { - return Err(overflow_error); - } - } else { - break; - } - } - for digit in digits { - if digit != 0 { - return Err(overflow_error); - } - } - let negative_zero = if negative { - // negating a value happens in three regions: - // * the least-significant zeros, which are left as zeros - // * the least-significant one bit, which is left as a one bit - // * all the most-significant bits, which are inverted - // e.g.: - const { - let inp = 0b1010_1_000_u8; - let out = 0b0101_1_000_u8; - assert!(inp.wrapping_neg() == out); - }; - if let Some(first_one) = value.first_one() { - let most_significant_bits = &mut value[first_one + 1..]; - // modifies in-place despite using `Not::not` - let _ = Not::not(most_significant_bits); - false - } else { - true - } - } else { - false - }; - if !negative_zero && type_is_signed && negative != value[value.len() - 1] { - Err(overflow_error) - } else { - Ok(Arc::new(value)) - } - } -} - -fn deserialize_int_value<'de, D: Deserializer<'de>>( - deserializer: D, - type_is_signed: bool, - type_width: Option, -) -> Result, D::Error> { - struct IntValueVisitor { - type_is_signed: bool, - type_width: Option, - } - impl<'de> Visitor<'de> for IntValueVisitor { - type Value = Arc; - - fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(if self.type_is_signed { - "SIntValue" - } else { - "UIntValue" - })?; - if let Some(type_width) = self.type_width { - write!(f, "<{type_width}>")?; - } - Ok(()) - } - - fn visit_str(self, v: &str) -> Result { - parse_int_value(v, self.type_is_signed, self.type_width, true).map_err(E::custom) - } - - fn visit_bytes(self, v: &[u8]) -> Result { - match std::str::from_utf8(v) { - Ok(v) => self.visit_str(v), - Err(_) => Err(Error::invalid_value(serde::de::Unexpected::Bytes(v), &self)), - } - } - } - deserializer.deserialize_str(IntValueVisitor { - type_is_signed, - type_width, - }) -} - macro_rules! impl_int { ($pretty_name:ident, $name:ident, $generic_name:ident, $value:ident, $SIGNED:literal) => { #[derive(Copy, Clone, PartialEq, Eq, Hash)] @@ -554,14 +188,19 @@ macro_rules! impl_int { pub const $name: $generic_name = $generic_name; impl $name { - pub const fn new(width: Width::SizeType) -> Self { + pub fn new(width: Width::SizeType) -> Self { Self { width } } pub fn width(self) -> usize { Width::as_usize(self.width) } pub fn type_properties(self) -> TypeProperties { - self.as_dyn_int().type_properties_dyn() + TypeProperties { + is_passive: true, + is_storable: true, + is_castable_from_bits: true, + bit_width: self.width(), + } } pub fn bits_from_bigint_wrapping(self, v: &BigInt) -> BitVec { BoolOrIntType::bits_from_bigint_wrapping(self, v) @@ -624,12 +263,6 @@ macro_rules! impl_int { } Expr::from_dyn_int(MemoizeBitsToExpr.get_cow(bits)) } - fn from_str_without_ty( - self, - s: &str, - ) -> Result::Err> { - parse_int_value(s, $SIGNED, Some(self.width()), false).map(Self::Value::new) - } } impl IntType for $name { @@ -637,20 +270,12 @@ macro_rules! impl_int { } impl $name { - pub const fn new_dyn(width: usize) -> Self { + pub fn new_dyn(width: usize) -> Self { Self { width } } pub fn bits_to_bigint(bits: &BitSlice) -> BigInt { ::bits_to_bigint(bits) } - pub const fn type_properties_dyn(self) -> TypeProperties { - TypeProperties { - is_passive: true, - is_storable: true, - is_castable_from_bits: true, - bit_width: self.width, - } - } } impl $name { @@ -662,7 +287,6 @@ macro_rules! impl_int { impl Type for $name { type BaseType = $pretty_name; type MaskType = Bool; - type SimValue = $value; impl_match_variant_as_self!(); fn mask_type(&self) -> Self::MaskType { Bool @@ -673,7 +297,7 @@ macro_rules! impl_int { #[track_caller] fn from_canonical(canonical_type: CanonicalType) -> Self { let CanonicalType::$pretty_name(retval) = canonical_type else { - panic!("expected {}", stringify!($pretty_name)); + panic!("expected {}", stringify!($name)); }; $name { width: Width::from_usize(retval.width), @@ -682,78 +306,20 @@ macro_rules! impl_int { fn source_location() -> SourceLocation { SourceLocation::builtin() } - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), self.width()); - $value::new(Arc::new(bits.to_bitvec())) - } - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), self.width()); - assert_eq!(value.width(), self.width()); - value.bits_mut().copy_from_bitslice(bits); - } - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), self.width()); - assert_eq!(value.width(), self.width()); - bits.copy_from_bitslice(value.bits()); - } - } - - impl Default for $name { - fn default() -> Self { - Self::TYPE - } } impl StaticType for $name { const TYPE: Self = Self { width: Width::SIZE }; const MASK_TYPE: Self::MaskType = Bool; - const TYPE_PROPERTIES: TypeProperties = $name { - width: Width::VALUE, - } - .type_properties_dyn(); + const TYPE_PROPERTIES: TypeProperties = TypeProperties { + is_passive: true, + is_storable: true, + is_castable_from_bits: true, + bit_width: Width::VALUE, + }; const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES; } - impl Serialize for $name { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.canonical().serialize(serializer) - } - } - - impl<'de, Width: Size> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let name = |width| -> String { - if let Some(width) = width { - format!("a {}<{width}>", stringify!($pretty_name)) - } else { - format!("a {}", stringify!($pretty_name)) - } - }; - match CanonicalType::deserialize(deserializer)? { - CanonicalType::$pretty_name(retval) => { - if let Some(width) = Width::try_from_usize(retval.width()) { - Ok($name { width }) - } else { - Err(Error::invalid_value( - serde::de::Unexpected::Other(&name(Some(retval.width()))), - &&*name(Width::KNOWN_VALUE), - )) - } - } - ty => Err(Error::invalid_value( - serde::de::Unexpected::Other(ty.as_serde_unexpected_str()), - &&*name(Width::KNOWN_VALUE), - )), - } - } - } - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] pub struct $generic_name; @@ -771,7 +337,7 @@ macro_rules! impl_int { _phantom: PhantomData, } - impl fmt::Display for $value { + impl fmt::Debug for $value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let value = self.to_bigint(); let (sign, magnitude) = value.into_parts(); @@ -785,38 +351,15 @@ macro_rules! impl_int { } } - impl fmt::Debug for $value { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } - } - - impl std::str::FromStr for $value { - type Err = ParseIntValueError; - - fn from_str(s: &str) -> Result { - parse_int_value(s, $SIGNED, Width::KNOWN_VALUE, true).map(Self::new) - } - } - - impl Serialize for $value { - fn serialize(&self, serializer: S) -> Result { - self.to_string().serialize(serializer) - } - } - - impl<'de, Width: Size> Deserialize<'de> for $value { - fn deserialize>(deserializer: D) -> Result { - deserialize_int_value(deserializer, $SIGNED, Width::KNOWN_VALUE).map(Self::new) - } - } - impl PartialOrd for $value { fn partial_cmp(&self, other: &Self) -> Option { - if self.width() != other.width() { - return None; - } - Some(self.to_bigint().cmp(&other.to_bigint())) + Some(self.cmp(other)) + } + } + + impl Ord for $value { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.to_bigint().cmp(&other.to_bigint()) } } @@ -858,9 +401,6 @@ macro_rules! impl_int { pub fn bits(&self) -> &Arc { &self.bits } - pub fn bits_mut(&mut self) -> &mut BitSlice { - Arc::::make_mut(&mut self.bits) - } } impl ToLiteralBits for $value { @@ -915,10 +455,6 @@ impl UInt { let v: BigUint = v.into(); Self::new(v.bits().try_into().expect("too big")) } - /// gets the smallest `UInt` that fits `v` losslessly - pub const fn for_value_usize(v: usize) -> Self { - Self::new((usize::BITS - v.leading_zeros()) as usize) - } /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty #[track_caller] pub fn range(r: Range>) -> Self { @@ -929,12 +465,6 @@ impl UInt { } /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty #[track_caller] - pub const fn range_usize(r: Range) -> Self { - assert!(r.end != 0, "empty range"); - Self::range_inclusive_usize(r.start..=(r.end - 1)) - } - /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty - #[track_caller] pub fn range_inclusive(r: RangeInclusive>) -> Self { let (start, end) = r.into_inner(); let start: BigUint = start.into(); @@ -944,16 +474,6 @@ impl UInt { // so must not take more bits than `end` Self::for_value(end) } - /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty - #[track_caller] - pub const fn range_inclusive_usize(r: RangeInclusive) -> Self { - let start = *r.start(); - let end = *r.end(); - assert!(start <= end, "empty range"); - // no need to check `start`` since it's no larger than `end` - // so must not take more bits than `end` - Self::for_value_usize(end) - } } impl SInt { @@ -1060,17 +580,14 @@ pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed { type Width: Size; type Signed: GenericConstBool; type Value: Clone - + PartialOrd - + Eq + + Ord + std::hash::Hash + fmt::Debug - + fmt::Display + Send + Sync + 'static + ToExpr - + Into - + std::str::FromStr; + + Into; fn width(self) -> usize; fn new(width: ::SizeType) -> Self; fn new_static() -> Self @@ -1104,12 +621,6 @@ pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed { let bitslice = &BitSlice::::from_slice(&bytes)[..width]; bits.clone_from_bitslice(bitslice); } - fn bits_equal_bigint_wrapping(v: &BigInt, bits: &BitSlice) -> bool { - bits.iter() - .by_vals() - .enumerate() - .all(|(bit_index, bit): (usize, bool)| v.bit(bit_index as u64) == bit) - } fn bits_to_bigint(bits: &BitSlice) -> BigInt { let sign_byte = if Self::Signed::VALUE && bits.last().as_deref().copied().unwrap_or(false) { 0xFF @@ -1143,12 +654,9 @@ pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed { bytes, bit_width, ))) } - fn from_str_without_ty(self, s: &str) -> Result::Err>; } -pub trait IntType: - BoolOrIntType::Dyn, Value: FromStr> -{ +pub trait IntType: BoolOrIntType::Dyn> { type Dyn: IntType; fn as_dyn_int(self) -> Self::Dyn { Self::new_dyn(self.width()) @@ -1188,7 +696,7 @@ pub trait IntType: } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct Bool; impl sealed::BoolOrIntTypeSealed for Bool {} @@ -1220,10 +728,6 @@ impl BoolOrIntType for Bool { assert_eq!(bits.len(), 1); bits[0] } - - fn from_str_without_ty(self, s: &str) -> Result::Err> { - FromStr::from_str(s) - } } impl Bool { @@ -1238,7 +742,6 @@ impl Bool { impl Type for Bool { type BaseType = Bool; type MaskType = Bool; - type SimValue = bool; impl_match_variant_as_self!(); fn mask_type(&self) -> Self::MaskType { Bool @@ -1256,18 +759,6 @@ impl Type for Bool { fn source_location() -> SourceLocation { SourceLocation::builtin() } - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), 1); - bits[0] - } - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), 1); - *value = bits[0]; - } - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), 1); - bits.set(0, *value); - } } impl StaticType for Bool { @@ -1292,13 +783,6 @@ impl ToLiteralBits for bool { mod tests { use super::*; - #[test] - fn test_different_value_widths_compare_ne() { - // interning relies on [SU]IntValue with different `width` comparing not equal - assert_ne!(UInt[3].from_int_wrapping(0), UInt[4].from_int_wrapping(0)); - assert_ne!(SInt[3].from_int_wrapping(0), SInt[4].from_int_wrapping(0)); - } - #[test] fn test_uint_for_value() { assert_eq!(UInt::for_value(0u8).width, 0); @@ -1321,104 +805,4 @@ mod tests { assert_eq!(SInt::for_value(3).width, 3); assert_eq!(SInt::for_value(4).width, 4); } - - #[test] - fn test_serde_round_trip() { - use serde_json::json; - #[track_caller] - fn check( - value: T, - expected: serde_json::Value, - ) { - assert_eq!(serde_json::to_value(&value).unwrap(), expected); - assert_eq!(value, T::deserialize(expected).unwrap()); - } - check(UInt[0], json! { { "UInt": { "width": 0 } } }); - check(UInt::<0>::TYPE, json! { { "UInt": { "width": 0 } } }); - check(UInt::<35>::TYPE, json! { { "UInt": { "width": 35 } } }); - check(SInt[0], json! { { "SInt": { "width": 0 } } }); - check(SInt::<0>::TYPE, json! { { "SInt": { "width": 0 } } }); - check(SInt::<35>::TYPE, json! { { "SInt": { "width": 35 } } }); - check(Bool, json! { "Bool" }); - check(UIntValue::from(0u8), json! { "0x0_u8" }); - check(SIntValue::from(-128i8), json! { "-0x80_i8" }); - check(UInt[3].from_int_wrapping(5), json! { "0x5_u3" }); - check(UInt[12].from_int_wrapping(0x1123), json! { "0x123_u12" }); - check(SInt[12].from_int_wrapping(0xFEE), json! { "-0x12_i12" }); - check(SInt[12].from_int_wrapping(0x7EE), json! { "0x7EE_i12" }); - } - - #[test] - fn test_deserialize() { - use serde_json::json; - #[track_caller] - fn check( - expected: Result, - input: serde_json::Value, - ) { - let mut error = String::new(); - let value = T::deserialize(input).map_err(|e| -> &str { - error = e.to_string(); - &error - }); - assert_eq!(value, expected); - } - check::>( - Err("invalid value: a UInt<2>, expected a UInt<0>"), - json! { { "UInt": { "width": 2 } } }, - ); - check::>( - Err("invalid value: a Bool, expected a UInt<0>"), - json! { "Bool" }, - ); - check::>( - Err("invalid value: a Bool, expected a SInt<0>"), - json! { "Bool" }, - ); - check::( - Err("invalid value: a Bool, expected a UInt"), - json! { "Bool" }, - ); - check::( - Err("invalid value: a Bool, expected a SInt"), - json! { "Bool" }, - ); - check::(Err("value too large to fit in type"), json! { "2_u1" }); - check::(Err("value too large to fit in type"), json! { "10_u1" }); - check::(Err("value too large to fit in type"), json! { "0x2_u1" }); - check::(Err("value too large to fit in type"), json! { "0b10_u1" }); - check::(Err("value too large to fit in type"), json! { "0o2_u1" }); - check::(Err("value too large to fit in type"), json! { "0o377_i8" }); - check::(Err("value too large to fit in type"), json! { "0o200_i8" }); - check(Ok(SInt[8].from_int_wrapping(i8::MAX)), json! { "0o177_i8" }); - check::(Err("value too small to fit in type"), json! { "-0o201_i8" }); - check::(Err("value too small to fit in type"), json! { "-0o377_i8" }); - check::(Err("value too small to fit in type"), json! { "-0o400_i8" }); - check::( - Err("value too small to fit in type"), - json! { "-0o4000_i8" }, - ); - check(Ok(UIntValue::from(0u8)), json! { "0_u8" }); - check(Ok(UIntValue::from(0u8)), json! { "0b0_u8" }); - check(Ok(UIntValue::from(0u8)), json! { "00_u8" }); - check(Ok(UIntValue::from(0u8)), json! { "0x0_u8" }); - check(Ok(UIntValue::from(0u8)), json! { "0o0_u8" }); - check(Ok(SIntValue::from(-128i8)), json! { "-0x000_80_i8" }); - check(Ok(SIntValue::from(-128i8)), json! { "-0o002_00_hdl_i8" }); - check(Ok(SIntValue::from(-128i8)), json! { "-0b1__000_0000_i8" }); - check(Ok(UInt[3].from_int_wrapping(5)), json! { " + 0x5_u3 " }); - check( - Ok(UInt[12].from_int_wrapping(0x1123)), - json! { "0x1_2_3_hdl_u12" }, - ); - check(Ok(SInt[12].from_int_wrapping(0xFEE)), json! { "-0x12_i12" }); - check( - Ok(SInt[12].from_int_wrapping(0x7EE)), - json! { " + \t0x7__E_e_i012\n" }, - ); - check(Ok(SInt[0].from_int_wrapping(0)), json! { "-0i0" }); - check(Ok(SInt[1].from_int_wrapping(0)), json! { "-0i1" }); - check(Ok(SInt[0].from_int_wrapping(0)), json! { "-0x0i0" }); - check(Ok(SInt[1].from_int_wrapping(0)), json! { "-0x0i1" }); - } } diff --git a/crates/fayalite/src/int/uint_in_range.rs b/crates/fayalite/src/int/uint_in_range.rs deleted file mode 100644 index 0e2d07e..0000000 --- a/crates/fayalite/src/int/uint_in_range.rs +++ /dev/null @@ -1,614 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - bundle::{Bundle, BundleField, BundleType, BundleTypePropertiesBuilder, NoBuilder}, - expr::{ - ops::{ExprCastTo, ExprPartialEq, ExprPartialOrd}, - CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, - }, - int::{Bool, DynSize, KnownSize, Size, SizeType, UInt, UIntType}, - intern::{Intern, Interned}, - phantom_const::PhantomConst, - sim::value::{SimValue, SimValuePartialEq, ToSimValueWithType}, - source_location::SourceLocation, - ty::{impl_match_variant_as_self, CanonicalType, StaticType, Type, TypeProperties}, -}; -use bitvec::{order::Lsb0, slice::BitSlice, view::BitView}; -use serde::{ - de::{value::UsizeDeserializer, Error, Visitor}, - Deserialize, Deserializer, Serialize, Serializer, -}; -use std::{fmt, marker::PhantomData, ops::Index}; - -const UINT_IN_RANGE_TYPE_FIELD_NAMES: [&'static str; 2] = ["value", "range"]; - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] -pub struct UIntInRangeMaskType { - value: Bool, - range: PhantomConstRangeMaskType, -} - -impl Type for UIntInRangeMaskType { - type BaseType = Bundle; - type MaskType = Self; - type SimValue = bool; - impl_match_variant_as_self!(); - - fn mask_type(&self) -> Self::MaskType { - *self - } - - fn canonical(&self) -> CanonicalType { - CanonicalType::Bundle(Bundle::new(self.fields())) - } - - fn from_canonical(canonical_type: CanonicalType) -> Self { - let fields = Bundle::from_canonical(canonical_type).fields(); - let [BundleField { - name: value_name, - flipped: false, - ty: value, - }, BundleField { - name: range_name, - flipped: false, - ty: range, - }] = *fields - else { - panic!("expected UIntInRangeMaskType"); - }; - assert_eq!([&*value_name, &*range_name], UINT_IN_RANGE_TYPE_FIELD_NAMES); - let value = Bool::from_canonical(value); - let range = PhantomConstRangeMaskType::from_canonical(range); - Self { value, range } - } - - fn source_location() -> SourceLocation { - SourceLocation::builtin() - } - - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - Bool.sim_value_from_bits(bits) - } - - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - Bool.sim_value_clone_from_bits(value, bits); - } - - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - Bool.sim_value_to_bits(value, bits); - } -} - -impl BundleType for UIntInRangeMaskType { - type Builder = NoBuilder; - type FilledBuilder = Expr; - - fn fields(&self) -> Interned<[BundleField]> { - let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES; - let Self { value, range } = self; - [ - BundleField { - name: value_name.intern(), - flipped: false, - ty: value.canonical(), - }, - BundleField { - name: range_name.intern(), - flipped: false, - ty: range.canonical(), - }, - ][..] - .intern() - } -} - -impl StaticType for UIntInRangeMaskType { - const TYPE: Self = Self { - value: Bool, - range: PhantomConstRangeMaskType::TYPE, - }; - const MASK_TYPE: Self::MaskType = Self::TYPE; - const TYPE_PROPERTIES: TypeProperties = BundleTypePropertiesBuilder::new() - .field(false, Bool::TYPE_PROPERTIES) - .field(false, PhantomConstRangeMaskType::TYPE_PROPERTIES) - .finish(); - const MASK_TYPE_PROPERTIES: TypeProperties = Self::TYPE_PROPERTIES; -} - -impl ToSimValueWithType for bool { - fn to_sim_value_with_type(&self, ty: UIntInRangeMaskType) -> SimValue { - SimValue::from_value(ty, *self) - } -} - -impl ExprCastTo for UIntInRangeMaskType { - fn cast_to(src: Expr, to_type: Bool) -> Expr { - src.cast_to_bits().cast_to(to_type) - } -} - -impl ExprCastTo for Bool { - fn cast_to(src: Expr, to_type: UIntInRangeMaskType) -> Expr { - src.cast_to_static::>().cast_bits_to(to_type) - } -} - -impl ExprPartialEq for UIntInRangeMaskType { - fn cmp_eq(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits()) - } - fn cmp_ne(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to_bits().cmp_ne(rhs.cast_to_bits()) - } -} - -impl SimValuePartialEq for UIntInRangeMaskType { - fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { - **this == **other - } -} - -type PhantomConstRangeMaskType = > as Type>::MaskType; - -#[derive(Default, Copy, Clone, Debug)] -struct RangeParseError; - -macro_rules! define_uint_in_range_type { - ( - $UIntInRange:ident, - $UIntInRangeType:ident, - $UIntInRangeTypeWithoutGenerics:ident, - $UIntInRangeTypeWithStart:ident, - $SerdeRange:ident, - $range_operator_str:literal, - |$uint_range_usize_start:ident, $uint_range_usize_end:ident| $uint_range_usize:expr, - ) => { - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] - struct $SerdeRange { - start: Start::SizeType, - end: End::SizeType, - } - - impl Default for $SerdeRange { - fn default() -> Self { - Self { - start: Start::SIZE, - end: End::SIZE, - } - } - } - - impl std::str::FromStr for $SerdeRange { - type Err = RangeParseError; - - fn from_str(s: &str) -> Result { - let Some((start, end)) = s.split_once($range_operator_str) else { - return Err(RangeParseError); - }; - if start.is_empty() - || start.bytes().any(|b| !b.is_ascii_digit()) - || end.is_empty() - || end.bytes().any(|b| !b.is_ascii_digit()) - { - return Err(RangeParseError); - } - let start = start.parse().map_err(|_| RangeParseError)?; - let end = end.parse().map_err(|_| RangeParseError)?; - let retval = Self { start, end }; - if retval.is_empty() { - Err(RangeParseError) - } else { - Ok(retval) - } - } - } - - impl fmt::Display for $SerdeRange { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { start, end } = *self; - write!( - f, - "{}{}{}", - Start::as_usize(start), - $range_operator_str, - End::as_usize(end), - ) - } - } - - impl Serialize for $SerdeRange { - fn serialize(&self, serializer: S) -> Result { - serializer.collect_str(self) - } - } - - impl<'de, Start: Size, End: Size> Deserialize<'de> for $SerdeRange { - fn deserialize>(deserializer: D) -> Result { - struct SerdeRangeVisitor(PhantomData<(Start, End)>); - impl<'de, Start: Size, End: Size> Visitor<'de> for SerdeRangeVisitor { - type Value = $SerdeRange; - - fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("a string with format \"")?; - if let Some(start) = Start::KNOWN_VALUE { - write!(f, "{start}")?; - } else { - f.write_str("")?; - }; - f.write_str($range_operator_str)?; - if let Some(end) = End::KNOWN_VALUE { - write!(f, "{end}")?; - } else { - f.write_str("")?; - }; - f.write_str("\" that is a non-empty range") - } - - fn visit_str(self, v: &str) -> Result { - let $SerdeRange:: { start, end } = - v.parse().map_err(|_| { - Error::invalid_value(serde::de::Unexpected::Str(v), &self) - })?; - let start = - Start::SizeType::deserialize(UsizeDeserializer::::new(start))?; - let end = End::SizeType::deserialize(UsizeDeserializer::::new(end))?; - Ok($SerdeRange { start, end }) - } - - fn visit_bytes(self, v: &[u8]) -> Result { - match std::str::from_utf8(v) { - Ok(v) => self.visit_str(v), - Err(_) => { - Err(Error::invalid_value(serde::de::Unexpected::Bytes(v), &self)) - } - } - } - } - deserializer.deserialize_str(SerdeRangeVisitor(PhantomData)) - } - } - - #[derive(Copy, Clone, PartialEq, Eq, Hash)] - pub struct $UIntInRangeType { - value: UInt, - range: PhantomConst<$SerdeRange>, - } - - impl $UIntInRangeType { - fn from_phantom_const_range(range: PhantomConst<$SerdeRange>) -> Self { - let $SerdeRange { start, end } = *range.get(); - let $uint_range_usize_start = Start::as_usize(start); - let $uint_range_usize_end = End::as_usize(end); - Self { - value: $uint_range_usize, - range, - } - } - pub fn new(start: Start::SizeType, end: End::SizeType) -> Self { - Self::from_phantom_const_range(PhantomConst::new( - $SerdeRange { start, end }.intern_sized(), - )) - } - } - - impl fmt::Debug for $UIntInRangeType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { value, range } = self; - let $SerdeRange { start, end } = *range.get(); - f.debug_struct(&format!( - "{}<{}, {}>", - stringify!($UIntInRange), - Start::as_usize(start), - End::as_usize(end), - )) - .field("value", value) - .finish_non_exhaustive() - } - } - - impl Type for $UIntInRangeType { - type BaseType = Bundle; - type MaskType = UIntInRangeMaskType; - type SimValue = usize; - impl_match_variant_as_self!(); - - fn mask_type(&self) -> Self::MaskType { - UIntInRangeMaskType::TYPE - } - - fn canonical(&self) -> CanonicalType { - CanonicalType::Bundle(Bundle::new(self.fields())) - } - - fn from_canonical(canonical_type: CanonicalType) -> Self { - let fields = Bundle::from_canonical(canonical_type).fields(); - let [BundleField { - name: value_name, - flipped: false, - ty: value, - }, BundleField { - name: range_name, - flipped: false, - ty: range, - }] = *fields - else { - panic!("expected {}", stringify!($UIntInRange)); - }; - assert_eq!([&*value_name, &*range_name], UINT_IN_RANGE_TYPE_FIELD_NAMES); - let value = UInt::from_canonical(value); - let range = PhantomConst::<$SerdeRange>::from_canonical(range); - let retval = Self::from_phantom_const_range(range); - assert_eq!(retval, Self { value, range }); - retval - } - - fn source_location() -> SourceLocation { - SourceLocation::builtin() - } - - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - let mut retval = 0usize; - retval.view_bits_mut::()[..bits.len()].clone_from_bitslice(bits); - retval - } - - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - *value = self.sim_value_from_bits(bits); - } - - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - bits.clone_from_bitslice(&value.view_bits::()[..bits.len()]); - } - } - - impl BundleType for $UIntInRangeType { - type Builder = NoBuilder; - type FilledBuilder = Expr; - - fn fields(&self) -> Interned<[BundleField]> { - let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES; - let Self { value, range } = self; - [ - BundleField { - name: value_name.intern(), - flipped: false, - ty: value.canonical(), - }, - BundleField { - name: range_name.intern(), - flipped: false, - ty: range.canonical(), - }, - ][..] - .intern() - } - } - - impl Default for $UIntInRangeType { - fn default() -> Self { - Self::TYPE - } - } - - impl StaticType for $UIntInRangeType { - const TYPE: Self = { - let $uint_range_usize_start = Start::VALUE; - let $uint_range_usize_end = End::VALUE; - Self { - value: $uint_range_usize, - range: PhantomConst::<$SerdeRange>::TYPE, - } - }; - const MASK_TYPE: Self::MaskType = UIntInRangeMaskType::TYPE; - const TYPE_PROPERTIES: TypeProperties = BundleTypePropertiesBuilder::new() - .field(false, Self::TYPE.value.type_properties_dyn()) - .field( - false, - PhantomConst::<$SerdeRange>::TYPE_PROPERTIES, - ) - .finish(); - const MASK_TYPE_PROPERTIES: TypeProperties = UIntInRangeMaskType::TYPE_PROPERTIES; - } - - impl ToSimValueWithType<$UIntInRangeType> for usize { - fn to_sim_value_with_type( - &self, - ty: $UIntInRangeType, - ) -> SimValue<$UIntInRangeType> { - SimValue::from_value(ty, *self) - } - } - - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] - pub struct $UIntInRangeTypeWithoutGenerics; - - #[allow(non_upper_case_globals)] - pub const $UIntInRangeType: $UIntInRangeTypeWithoutGenerics = - $UIntInRangeTypeWithoutGenerics; - - impl Index for $UIntInRangeTypeWithoutGenerics { - type Output = $UIntInRangeTypeWithStart; - - fn index(&self, start: StartSize) -> &Self::Output { - Interned::into_inner($UIntInRangeTypeWithStart(start).intern_sized()) - } - } - - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] - pub struct $UIntInRangeTypeWithStart(Start::SizeType); - - impl, End: Size> - Index for $UIntInRangeTypeWithStart - { - type Output = $UIntInRangeType; - - fn index(&self, end: EndSize) -> &Self::Output { - Interned::into_inner($UIntInRangeType::new(self.0, end).intern_sized()) - } - } - - impl ExprCastTo for $UIntInRangeType { - fn cast_to(src: Expr, to_type: UInt) -> Expr { - src.cast_to_bits().cast_to(to_type) - } - } - - impl ExprCastTo<$UIntInRangeType> for UInt { - fn cast_to( - src: Expr, - to_type: $UIntInRangeType, - ) -> Expr<$UIntInRangeType> { - src.cast_bits_to(to_type) - } - } - - impl - ExprPartialEq<$UIntInRangeType> - for $UIntInRangeType - { - fn cmp_eq( - lhs: Expr, - rhs: Expr<$UIntInRangeType>, - ) -> Expr { - lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits()) - } - fn cmp_ne( - lhs: Expr, - rhs: Expr<$UIntInRangeType>, - ) -> Expr { - lhs.cast_to_bits().cmp_ne(rhs.cast_to_bits()) - } - } - - impl - ExprPartialOrd<$UIntInRangeType> - for $UIntInRangeType - { - fn cmp_lt( - lhs: Expr, - rhs: Expr<$UIntInRangeType>, - ) -> Expr { - lhs.cast_to_bits().cmp_lt(rhs.cast_to_bits()) - } - fn cmp_le( - lhs: Expr, - rhs: Expr<$UIntInRangeType>, - ) -> Expr { - lhs.cast_to_bits().cmp_le(rhs.cast_to_bits()) - } - fn cmp_gt( - lhs: Expr, - rhs: Expr<$UIntInRangeType>, - ) -> Expr { - lhs.cast_to_bits().cmp_gt(rhs.cast_to_bits()) - } - fn cmp_ge( - lhs: Expr, - rhs: Expr<$UIntInRangeType>, - ) -> Expr { - lhs.cast_to_bits().cmp_ge(rhs.cast_to_bits()) - } - } - - impl - SimValuePartialEq<$UIntInRangeType> - for $UIntInRangeType - { - fn sim_value_eq( - this: &SimValue, - other: &SimValue<$UIntInRangeType>, - ) -> bool { - **this == **other - } - } - - impl ExprPartialEq> - for $UIntInRangeType - { - fn cmp_eq(lhs: Expr, rhs: Expr>) -> Expr { - lhs.cast_to_bits().cmp_eq(rhs) - } - fn cmp_ne(lhs: Expr, rhs: Expr>) -> Expr { - lhs.cast_to_bits().cmp_ne(rhs) - } - } - - impl ExprPartialEq<$UIntInRangeType> - for UIntType - { - fn cmp_eq(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { - lhs.cmp_eq(rhs.cast_to_bits()) - } - fn cmp_ne(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { - lhs.cmp_ne(rhs.cast_to_bits()) - } - } - - impl ExprPartialOrd> - for $UIntInRangeType - { - fn cmp_lt(lhs: Expr, rhs: Expr>) -> Expr { - lhs.cast_to_bits().cmp_lt(rhs) - } - fn cmp_le(lhs: Expr, rhs: Expr>) -> Expr { - lhs.cast_to_bits().cmp_le(rhs) - } - fn cmp_gt(lhs: Expr, rhs: Expr>) -> Expr { - lhs.cast_to_bits().cmp_gt(rhs) - } - fn cmp_ge(lhs: Expr, rhs: Expr>) -> Expr { - lhs.cast_to_bits().cmp_ge(rhs) - } - } - - impl ExprPartialOrd<$UIntInRangeType> - for UIntType - { - fn cmp_lt(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { - lhs.cmp_lt(rhs.cast_to_bits()) - } - fn cmp_le(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { - lhs.cmp_le(rhs.cast_to_bits()) - } - fn cmp_gt(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { - lhs.cmp_gt(rhs.cast_to_bits()) - } - fn cmp_ge(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { - lhs.cmp_ge(rhs.cast_to_bits()) - } - } - }; -} - -define_uint_in_range_type! { - UIntInRange, - UIntInRangeType, - UIntInRangeTypeWithoutGenerics, - UIntInRangeTypeWithStart, - SerdeRange, - "..", - |start, end| UInt::range_usize(start..end), -} - -define_uint_in_range_type! { - UIntInRangeInclusive, - UIntInRangeInclusiveType, - UIntInRangeInclusiveTypeWithoutGenerics, - UIntInRangeInclusiveTypeWithStart, - SerdeRangeInclusive, - "..=", - |start, end| UInt::range_inclusive_usize(start..=end), -} - -impl SerdeRange { - fn is_empty(self) -> bool { - self.start >= self.end - } -} - -impl SerdeRangeInclusive { - fn is_empty(self) -> bool { - self.start > self.end - } -} diff --git a/crates/fayalite/src/intern.rs b/crates/fayalite/src/intern.rs index af91f0a..3780ad3 100644 --- a/crates/fayalite/src/intern.rs +++ b/crates/fayalite/src/intern.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information #![allow(clippy::type_complexity)] -use crate::{intern::type_map::TypeIdMap, util::DefaultBuildHasher}; +use crate::intern::type_map::TypeIdMap; use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec}; -use hashbrown::HashTable; +use hashbrown::{hash_map::RawEntryMut, HashMap, HashTable}; use serde::{Deserialize, Serialize}; use std::{ any::{Any, TypeId}, @@ -17,7 +17,7 @@ use std::{ sync::{Mutex, RwLock}, }; -mod type_map; +pub mod type_map; pub trait LazyInternedTrait: Send + Sync + Any { fn get(&self) -> Interned; @@ -316,13 +316,8 @@ pub trait Intern: Any + Send + Sync { } } -struct InternerState { - table: HashTable<&'static T>, - hasher: DefaultBuildHasher, -} - pub struct Interner { - state: Mutex>, + map: Mutex>, } impl Interner { @@ -335,10 +330,7 @@ impl Interner { impl Default for Interner { fn default() -> Self { Self { - state: Mutex::new(InternerState { - table: HashTable::new(), - hasher: Default::default(), - }), + map: Default::default(), } } } @@ -349,16 +341,17 @@ impl Interner { alloc: F, value: Cow<'_, T>, ) -> Interned { - let mut state = self.state.lock().unwrap(); - let InternerState { table, hasher } = &mut *state; - let inner = *table - .entry( - hasher.hash_one(&*value), - |k| **k == *value, - |k| hasher.hash_one(&**k), - ) - .or_insert_with(|| alloc(value)) - .get(); + let mut map = self.map.lock().unwrap(); + let hasher = map.hasher().clone(); + let hash = hasher.hash_one(&*value); + let inner = match map.raw_entry_mut().from_hash(hash, |k| **k == *value) { + RawEntryMut::Occupied(entry) => *entry.key(), + RawEntryMut::Vacant(entry) => { + *entry + .insert_with_hasher(hash, alloc(value), (), |k| hasher.hash_one(&**k)) + .0 + } + }; Interned { inner } } } @@ -749,7 +742,7 @@ pub trait MemoizeGeneric: 'static + Send + Sync + Hash + Eq + Copy { fn get_cow(self, input: Self::InputCow<'_>) -> Self::Output { static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new(); let map: &RwLock<( - DefaultBuildHasher, + hashbrown::hash_map::DefaultHashBuilder, HashTable<(Self, Self::InputOwned, Self::Output)>, )> = TYPE_ID_MAP.get_or_insert_default(); fn hash_eq_key<'a, 'b, T: MemoizeGeneric>( diff --git a/crates/fayalite/src/intern/type_map.rs b/crates/fayalite/src/intern/type_map.rs index 945116b..48433af 100644 --- a/crates/fayalite/src/intern/type_map.rs +++ b/crates/fayalite/src/intern/type_map.rs @@ -1,8 +1,10 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information +use hashbrown::HashMap; use std::{ any::{Any, TypeId}, hash::{BuildHasher, Hasher}, + ptr::NonNull, sync::RwLock, }; @@ -73,36 +75,59 @@ impl BuildHasher for TypeIdBuildHasher { } } -pub(crate) struct TypeIdMap( - RwLock>, -); +struct Value(NonNull); + +impl Value { + unsafe fn get_transmute_lifetime<'b>(&self) -> &'b (dyn Any + Send + Sync) { + unsafe { &*self.0.as_ptr() } + } + fn new(v: Box) -> Self { + unsafe { Self(NonNull::new_unchecked(Box::into_raw(v))) } + } +} + +unsafe impl Send for Value {} +unsafe impl Sync for Value {} + +impl Drop for Value { + fn drop(&mut self) { + unsafe { std::ptr::drop_in_place(self.0.as_ptr()) } + } +} + +pub struct TypeIdMap(RwLock>); impl TypeIdMap { - pub(crate) const fn new() -> Self { - Self(RwLock::new(hashbrown::HashMap::with_hasher( - TypeIdBuildHasher, - ))) + pub const fn new() -> Self { + Self(RwLock::new(HashMap::with_hasher(TypeIdBuildHasher))) } #[cold] - fn insert_slow( + unsafe fn insert_slow( &self, type_id: TypeId, make: fn() -> Box, - ) -> &'static (dyn Any + Sync + Send) { - let value = Box::leak(make()); + ) -> &(dyn Any + Sync + Send) { + let value = Value::new(make()); let mut write_guard = self.0.write().unwrap(); - *write_guard.entry(type_id).or_insert(value) + unsafe { + write_guard + .entry(type_id) + .or_insert(value) + .get_transmute_lifetime() + } } - pub(crate) fn get_or_insert_default(&self) -> &T { + pub fn get_or_insert_default(&self) -> &T { let type_id = TypeId::of::(); let read_guard = self.0.read().unwrap(); - let retval = read_guard.get(&type_id).map(|v| *v); + let retval = read_guard + .get(&type_id) + .map(|v| unsafe { Value::get_transmute_lifetime(v) }); drop(read_guard); let retval = match retval { Some(retval) => retval, - None => self.insert_slow(type_id, move || Box::new(T::default())), + None => unsafe { self.insert_slow(type_id, move || Box::new(T::default())) }, }; - retval.downcast_ref().expect("known to have correct TypeId") + unsafe { &*(retval as *const dyn Any as *const T) } } } diff --git a/crates/fayalite/src/lib.rs b/crates/fayalite/src/lib.rs index 932464b..88fe169 100644 --- a/crates/fayalite/src/lib.rs +++ b/crates/fayalite/src/lib.rs @@ -76,8 +76,6 @@ pub use fayalite_proc_macros::hdl_module; #[doc(inline)] pub use fayalite_proc_macros::hdl; -pub use bitvec; - /// struct used as a placeholder when applying defaults #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct __; @@ -98,7 +96,6 @@ pub mod int; pub mod intern; pub mod memory; pub mod module; -pub mod phantom_const; pub mod prelude; pub mod reg; pub mod reset; diff --git a/crates/fayalite/src/memory.rs b/crates/fayalite/src/memory.rs index 622ffc6..2f0ec47 100644 --- a/crates/fayalite/src/memory.rs +++ b/crates/fayalite/src/memory.rs @@ -470,7 +470,7 @@ pub enum ReadUnderWrite { Undefined, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] struct MemImpl { scoped_name: ScopedNameId, source_location: SourceLocation, @@ -1082,7 +1082,6 @@ pub fn splat_mask(ty: T, value: Expr) -> Expr> { ) .to_expr(), )), - CanonicalType::PhantomConst(_) => Expr::from_canonical(Expr::canonical(().to_expr())), } } diff --git a/crates/fayalite/src/module.rs b/crates/fayalite/src/module.rs index 920b0af..5a18ac9 100644 --- a/crates/fayalite/src/module.rs +++ b/crates/fayalite/src/module.rs @@ -21,20 +21,18 @@ use crate::{ memory::{Mem, MemBuilder, MemBuilderTarget, PortName}, reg::Reg, reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset}, - sim::{ExternModuleSimGenerator, ExternModuleSimulation}, source_location::SourceLocation, ty::{CanonicalType, Type}, - util::{HashMap, HashSet, ScopedRef}, + util::ScopedRef, wire::{IncompleteWire, Wire}, }; -use hashbrown::hash_map::Entry; +use hashbrown::{hash_map::Entry, HashMap, HashSet}; use num_bigint::BigInt; use std::{ cell::RefCell, collections::VecDeque, convert::Infallible, fmt, - future::IntoFuture, hash::{Hash, Hasher}, iter::FusedIterator, marker::PhantomData, @@ -1083,7 +1081,6 @@ pub struct ExternModuleBody< > { pub verilog_name: Interned, pub parameters: P, - pub simulation: Option, } impl From>> for ExternModuleBody { @@ -1091,13 +1088,11 @@ impl From>> for ExternModuleBody { let ExternModuleBody { verilog_name, parameters, - simulation, } = value; let parameters = Intern::intern_owned(parameters); Self { verilog_name, parameters, - simulation, } } } @@ -1288,12 +1283,10 @@ impl fmt::Debug for DebugModuleBody { ModuleBody::Extern(ExternModuleBody { verilog_name, parameters, - simulation, }) => { debug_struct .field("verilog_name", verilog_name) - .field("parameters", parameters) - .field("simulation", simulation); + .field("parameters", parameters); } } debug_struct.finish_non_exhaustive() @@ -1497,9 +1490,6 @@ impl TargetState { }) .collect(), }, - CanonicalType::PhantomConst(_) => TargetStateInner::Decomposed { - subtargets: HashMap::default(), - }, CanonicalType::Array(ty) => TargetStateInner::Decomposed { subtargets: (0..ty.len()) .map(|index| { @@ -1768,7 +1758,6 @@ impl AssertValidityState { ModuleBody::Extern(ExternModuleBody { verilog_name: _, parameters: _, - simulation: _, }) => {} ModuleBody::Normal(NormalModuleBody { body }) => { let body = self.make_block_index(body); @@ -1864,7 +1853,7 @@ impl Module { AssertValidityState { module: self.canonical(), blocks: vec![], - target_states: HashMap::with_capacity_and_hasher(64, Default::default()), + target_states: HashMap::with_capacity(64), } .assert_validity(); } @@ -2116,7 +2105,6 @@ impl ModuleBuilder { ModuleKind::Extern => ModuleBody::Extern(ExternModuleBody { verilog_name: name.0, parameters: vec![], - simulation: None, }), ModuleKind::Normal => ModuleBody::Normal(NormalModuleBody { body: BuilderModuleBody { @@ -2125,8 +2113,8 @@ impl ModuleBuilder { incomplete_declarations: vec![], stmts: vec![], }], - annotations_map: HashMap::default(), - memory_map: HashMap::default(), + annotations_map: HashMap::new(), + memory_map: HashMap::new(), }, }), }; @@ -2136,7 +2124,7 @@ impl ModuleBuilder { impl_: RefCell::new(ModuleBuilderImpl { body, io: vec![], - io_indexes: HashMap::default(), + io_indexes: HashMap::new(), module_annotations: vec![], }), }; @@ -2183,7 +2171,6 @@ impl ModuleBuilder { .builder_extern_body() .verilog_name = name.intern(); } - #[track_caller] pub fn parameter(&self, name: impl AsRef, value: ExternModuleParameterValue) { let name = name.as_ref(); self.impl_ @@ -2196,7 +2183,6 @@ impl ModuleBuilder { value, }); } - #[track_caller] pub fn parameter_int(&self, name: impl AsRef, value: impl Into) { let name = name.as_ref(); let value = value.into(); @@ -2210,7 +2196,6 @@ impl ModuleBuilder { value: ExternModuleParameterValue::Integer(value), }); } - #[track_caller] pub fn parameter_str(&self, name: impl AsRef, value: impl AsRef) { let name = name.as_ref(); let value = value.as_ref(); @@ -2224,7 +2209,6 @@ impl ModuleBuilder { value: ExternModuleParameterValue::String(value.intern()), }); } - #[track_caller] pub fn parameter_raw_verilog(&self, name: impl AsRef, raw_verilog: impl AsRef) { let name = name.as_ref(); let raw_verilog = raw_verilog.as_ref(); @@ -2238,26 +2222,6 @@ impl ModuleBuilder { value: ExternModuleParameterValue::RawVerilog(raw_verilog.intern()), }); } - #[track_caller] - pub fn extern_module_simulation(&self, generator: G) { - let mut impl_ = self.impl_.borrow_mut(); - let simulation = &mut impl_.body.builder_extern_body().simulation; - if simulation.is_some() { - panic!("already added an extern module simulation"); - } - *simulation = Some(ExternModuleSimulation::new(generator)); - } - #[track_caller] - pub fn extern_module_simulation_fn< - Args: fmt::Debug + Clone + Hash + Eq + Send + Sync + 'static, - Fut: IntoFuture + 'static, - >( - &self, - args: Args, - f: fn(Args, crate::sim::ExternModuleSimulationState) -> Fut, - ) { - self.extern_module_simulation(crate::sim::SimGeneratorFn { args, f }); - } } #[track_caller] diff --git a/crates/fayalite/src/module/transform/deduce_resets.rs b/crates/fayalite/src/module/transform/deduce_resets.rs index 5fb829e..fe518a5 100644 --- a/crates/fayalite/src/module/transform/deduce_resets.rs +++ b/crates/fayalite/src/module/transform/deduce_resets.rs @@ -24,9 +24,8 @@ use crate::{ }, prelude::*, reset::{ResetType, ResetTypeDispatch}, - util::{HashMap, HashSet}, }; -use hashbrown::hash_map::Entry; +use hashbrown::{hash_map::Entry, HashMap, HashSet}; use num_bigint::BigInt; use petgraph::unionfind::UnionFind; use std::{fmt, marker::PhantomData}; @@ -156,7 +155,6 @@ impl ResetsLayout { CanonicalType::SyncReset(_) => ResetsLayout::SyncReset, CanonicalType::Reset(_) => ResetsLayout::Reset, CanonicalType::Clock(_) => ResetsLayout::NoResets, - CanonicalType::PhantomConst(_) => ResetsLayout::NoResets, } } } @@ -409,8 +407,7 @@ impl Resets { | CanonicalType::Bool(_) | CanonicalType::AsyncReset(_) | CanonicalType::SyncReset(_) - | CanonicalType::Clock(_) - | CanonicalType::PhantomConst(_) => Ok(self.ty), + | CanonicalType::Clock(_) => Ok(self.ty), CanonicalType::Array(ty) => Ok(CanonicalType::Array(Array::new_dyn( self.array_elements().substituted_type( reset_graph, @@ -1001,8 +998,7 @@ fn cast_bit_op( CanonicalType::Array(_) | CanonicalType::Enum(_) | CanonicalType::Bundle(_) - | CanonicalType::Reset(_) - | CanonicalType::PhantomConst(_) => unreachable!(), + | CanonicalType::Reset(_) => unreachable!(), $(CanonicalType::$Variant(ty) => Expr::expr_enum($arg.cast_to(ty)),)* } }; @@ -1014,7 +1010,6 @@ fn cast_bit_op( | CanonicalType::Enum(_) | CanonicalType::Bundle(_) | CanonicalType::Reset(_) => unreachable!(), - CanonicalType::PhantomConst(_) => Expr::expr_enum(arg), $(CanonicalType::$Variant(_) => { let arg = Expr::<$Variant>::from_canonical(arg); match_expr_ty!(arg, UInt, SInt, Bool, AsyncReset, SyncReset, Clock) @@ -1045,7 +1040,6 @@ impl RunPass

for ExprEnum { ExprEnum::UIntLiteral(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::SIntLiteral(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::BoolLiteral(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), - ExprEnum::PhantomConst(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::BundleLiteral(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::ArrayLiteral(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), ExprEnum::EnumLiteral(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)), @@ -1676,8 +1670,7 @@ impl RunPassDispatch for AnyReg { | CanonicalType::Enum(_) | CanonicalType::Bundle(_) | CanonicalType::Reset(_) - | CanonicalType::Clock(_) - | CanonicalType::PhantomConst(_) => unreachable!(), + | CanonicalType::Clock(_) => unreachable!(), } }) } @@ -1776,7 +1769,6 @@ impl_run_pass_copy!([] SVAttributeAnnotation); impl_run_pass_copy!([] UInt); impl_run_pass_copy!([] usize); impl_run_pass_copy!([] FormalKind); -impl_run_pass_copy!([] PhantomConst); macro_rules! impl_run_pass_for_struct { ( @@ -2252,9 +2244,9 @@ pub fn deduce_resets( fallback_to_sync_reset: bool, ) -> Result>, DeduceResetsError> { let mut state = State { - modules_added_to_graph: HashSet::default(), - substituted_modules: HashMap::default(), - expr_resets: HashMap::default(), + modules_added_to_graph: HashSet::new(), + substituted_modules: HashMap::new(), + expr_resets: HashMap::new(), reset_graph: ResetGraph::default(), fallback_to_sync_reset, }; diff --git a/crates/fayalite/src/module/transform/simplify_enums.rs b/crates/fayalite/src/module/transform/simplify_enums.rs index 333451d..4eb0d0c 100644 --- a/crates/fayalite/src/module/transform/simplify_enums.rs +++ b/crates/fayalite/src/module/transform/simplify_enums.rs @@ -18,10 +18,10 @@ use crate::{ }, source_location::SourceLocation, ty::{CanonicalType, Type}, - util::HashMap, wire::Wire, }; use core::fmt; +use hashbrown::HashMap; #[derive(Debug)] pub enum SimplifyEnumsError { @@ -69,8 +69,7 @@ fn contains_any_enum_types(ty: CanonicalType) -> bool { | CanonicalType::AsyncReset(_) | CanonicalType::SyncReset(_) | CanonicalType::Reset(_) - | CanonicalType::Clock(_) - | CanonicalType::PhantomConst(_) => false, + | CanonicalType::Clock(_) => false, } } } @@ -513,8 +512,7 @@ impl State { | CanonicalType::AsyncReset(_) | CanonicalType::SyncReset(_) | CanonicalType::Reset(_) - | CanonicalType::Clock(_) - | CanonicalType::PhantomConst(_) => unreachable!(), + | CanonicalType::Clock(_) => unreachable!(), } } } @@ -579,8 +577,7 @@ fn connect_port( | (CanonicalType::Clock(_), _) | (CanonicalType::AsyncReset(_), _) | (CanonicalType::SyncReset(_), _) - | (CanonicalType::Reset(_), _) - | (CanonicalType::PhantomConst(_), _) => unreachable!( + | (CanonicalType::Reset(_), _) => unreachable!( "trying to connect memory ports:\n{:?}\n{:?}", Expr::ty(lhs), Expr::ty(rhs), @@ -668,7 +665,6 @@ impl Folder for State { ExprEnum::UIntLiteral(_) | ExprEnum::SIntLiteral(_) | ExprEnum::BoolLiteral(_) - | ExprEnum::PhantomConst(_) | ExprEnum::BundleLiteral(_) | ExprEnum::ArrayLiteral(_) | ExprEnum::Uninit(_) @@ -927,8 +923,7 @@ impl Folder for State { | CanonicalType::Clock(_) | CanonicalType::AsyncReset(_) | CanonicalType::SyncReset(_) - | CanonicalType::Reset(_) - | CanonicalType::PhantomConst(_) => canonical_type.default_fold(self), + | CanonicalType::Reset(_) => canonical_type.default_fold(self), } } @@ -965,8 +960,8 @@ pub fn simplify_enums( kind: SimplifyEnumsKind, ) -> Result>, SimplifyEnumsError> { module.fold(&mut State { - enum_types: HashMap::default(), - replacement_mem_ports: HashMap::default(), + enum_types: HashMap::new(), + replacement_mem_ports: HashMap::new(), kind, module_state_stack: vec![], }) diff --git a/crates/fayalite/src/module/transform/simplify_memories.rs b/crates/fayalite/src/module/transform/simplify_memories.rs index 6357843..e8f9cbf 100644 --- a/crates/fayalite/src/module/transform/simplify_memories.rs +++ b/crates/fayalite/src/module/transform/simplify_memories.rs @@ -14,10 +14,11 @@ use crate::{ }, source_location::SourceLocation, ty::{CanonicalType, Type}, - util::{HashMap, MakeMutSlice}, + util::MakeMutSlice, wire::Wire, }; use bitvec::{slice::BitSlice, vec::BitVec}; +use hashbrown::HashMap; use std::{ convert::Infallible, fmt::Write, @@ -61,7 +62,6 @@ enum MemSplit { Bundle { fields: Rc<[MemSplit]>, }, - PhantomConst, Single { output_mem: Option, element_type: SingleType, @@ -76,7 +76,6 @@ impl MemSplit { fn mark_changed_element_type(self) -> Self { match self { MemSplit::Bundle { fields: _ } => self, - MemSplit::PhantomConst => self, MemSplit::Single { output_mem, element_type, @@ -98,7 +97,6 @@ impl MemSplit { .map(|field| Self::new(field.ty).mark_changed_element_type()) .collect(), }, - CanonicalType::PhantomConst(_) => MemSplit::PhantomConst, CanonicalType::Array(ty) => { let element = MemSplit::new(ty.element()); if let Self::Single { @@ -341,7 +339,6 @@ impl SplitMemState<'_, '_> { self.split_state_stack.pop(); } } - MemSplit::PhantomConst => {} MemSplit::Single { output_mem, element_type: single_type, @@ -541,12 +538,7 @@ impl ModuleState { }; loop { match input_element_type { - CanonicalType::Bundle(_) => { - unreachable!("bundle types are always split") - } - CanonicalType::PhantomConst(_) => { - unreachable!("PhantomConst are always removed") - } + CanonicalType::Bundle(_) => unreachable!("bundle types are always split"), CanonicalType::Enum(_) if input_array_types .first() @@ -751,8 +743,7 @@ impl ModuleState { .. } | MemSplit::Bundle { .. } - | MemSplit::Array { .. } - | MemSplit::PhantomConst => { + | MemSplit::Array { .. } => { let mut replacement_ports = Vec::with_capacity(input_mem.ports().len()); let mut wire_port_rdata = Vec::with_capacity(input_mem.ports().len()); let mut wire_port_wdata = Vec::with_capacity(input_mem.ports().len()); @@ -896,7 +887,7 @@ impl Folder for State { module, ModuleState { output_module: None, - memories: HashMap::default(), + memories: HashMap::new(), }, ); let mut this = PushedState::push_module(self, module); diff --git a/crates/fayalite/src/module/transform/visit.rs b/crates/fayalite/src/module/transform/visit.rs index 526a62c..97de4fc 100644 --- a/crates/fayalite/src/module/transform/visit.rs +++ b/crates/fayalite/src/module/transform/visit.rs @@ -28,10 +28,8 @@ use crate::{ NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg, StmtWire, }, - phantom_const::PhantomConst, reg::Reg, reset::{AsyncReset, Reset, ResetType, SyncReset}, - sim::ExternModuleSimulation, source_location::SourceLocation, ty::{CanonicalType, Type}, wire::Wire, diff --git a/crates/fayalite/src/phantom_const.rs b/crates/fayalite/src/phantom_const.rs deleted file mode 100644 index c481692..0000000 --- a/crates/fayalite/src/phantom_const.rs +++ /dev/null @@ -1,410 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - expr::{ - ops::{ExprPartialEq, ExprPartialOrd}, - Expr, ToExpr, - }, - int::Bool, - intern::{Intern, Interned, InternedCompare, LazyInterned, LazyInternedTrait, Memoize}, - sim::value::{SimValue, SimValuePartialEq, ToSimValue, ToSimValueWithType}, - source_location::SourceLocation, - ty::{ - impl_match_variant_as_self, - serde_impls::{SerdeCanonicalType, SerdePhantomConst}, - CanonicalType, StaticType, Type, TypeProperties, - }, -}; -use bitvec::slice::BitSlice; -use serde::{ - de::{DeserializeOwned, Error}, - Deserialize, Deserializer, Serialize, Serializer, -}; -use std::{ - any::Any, - fmt, - hash::{Hash, Hasher}, - marker::PhantomData, - ops::Index, -}; - -#[derive(Clone)] -pub struct PhantomConstCanonicalValue { - parsed: serde_json::Value, - serialized: Interned, -} - -impl PhantomConstCanonicalValue { - pub fn from_json_value(parsed: serde_json::Value) -> Self { - let serialized = Intern::intern_owned( - serde_json::to_string(&parsed) - .expect("conversion from json value to text shouldn't fail"), - ); - Self { parsed, serialized } - } - pub fn as_json_value(&self) -> &serde_json::Value { - &self.parsed - } - pub fn as_str(&self) -> Interned { - self.serialized - } -} - -impl fmt::Debug for PhantomConstCanonicalValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.serialized) - } -} - -impl fmt::Display for PhantomConstCanonicalValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.serialized) - } -} - -impl PartialEq for PhantomConstCanonicalValue { - fn eq(&self, other: &Self) -> bool { - self.serialized == other.serialized - } -} - -impl Eq for PhantomConstCanonicalValue {} - -impl Hash for PhantomConstCanonicalValue { - fn hash(&self, state: &mut H) { - self.serialized.hash(state); - } -} - -impl Serialize for PhantomConstCanonicalValue { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.parsed.serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for PhantomConstCanonicalValue { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - Ok(Self::from_json_value(serde_json::Value::deserialize( - deserializer, - )?)) - } -} - -pub trait PhantomConstValue: Intern + InternedCompare + Serialize + fmt::Debug { - fn deserialize_value<'de, D>(deserializer: D) -> Result, D::Error> - where - D: serde::Deserializer<'de>; -} - -impl PhantomConstValue for T -where - T: ?Sized + Intern + InternedCompare + Serialize + fmt::Debug, - Interned: DeserializeOwned, -{ - fn deserialize_value<'de, D>(deserializer: D) -> Result, D::Error> - where - D: serde::Deserializer<'de>, - { - as Deserialize<'de>>::deserialize(deserializer) - } -} - -/// Wrapper type that allows any Rust value to be smuggled as a HDL [`Type`]. -/// This only works for values that can be [serialized][Serialize] to and [deserialized][Deserialize] from [JSON][serde_json]. -pub struct PhantomConst { - value: LazyInterned, -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] -pub struct PhantomConstWithoutGenerics; - -#[allow(non_upper_case_globals)] -pub const PhantomConst: PhantomConstWithoutGenerics = PhantomConstWithoutGenerics; - -impl Index for PhantomConstWithoutGenerics { - type Output = PhantomConst; - - fn index(&self, value: T) -> &Self::Output { - Interned::into_inner(PhantomConst::new(value.intern()).intern_sized()) - } -} - -impl fmt::Debug for PhantomConst { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("PhantomConst").field(&self.get()).finish() - } -} - -impl Clone for PhantomConst { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for PhantomConst {} - -impl PartialEq for PhantomConst { - fn eq(&self, other: &Self) -> bool { - self.get() == other.get() - } -} - -impl Eq for PhantomConst {} - -impl Hash for PhantomConst { - fn hash(&self, state: &mut H) { - self.get().hash(state); - } -} - -struct PhantomConstCanonicalMemoize(PhantomData); - -impl Copy - for PhantomConstCanonicalMemoize -{ -} - -impl Clone - for PhantomConstCanonicalMemoize -{ - fn clone(&self) -> Self { - *self - } -} - -impl Eq - for PhantomConstCanonicalMemoize -{ -} - -impl PartialEq - for PhantomConstCanonicalMemoize -{ - fn eq(&self, _other: &Self) -> bool { - true - } -} - -impl Hash - for PhantomConstCanonicalMemoize -{ - fn hash(&self, _state: &mut H) {} -} - -impl Memoize for PhantomConstCanonicalMemoize { - type Input = Interned; - type InputOwned = Interned; - type Output = Interned; - - fn inner(self, input: &Self::Input) -> Self::Output { - Intern::intern_sized(PhantomConstCanonicalValue::from_json_value( - serde_json::to_value(input) - .expect("serialization failed when constructing a canonical PhantomConst"), - )) - } -} - -impl Memoize for PhantomConstCanonicalMemoize { - type Input = Interned; - type InputOwned = Interned; - type Output = Interned; - - fn inner(self, input: &Self::Input) -> Self::Output { - PhantomConstValue::deserialize_value(input.as_json_value()) - .expect("deserialization failed ") - } -} - -impl PhantomConst { - pub fn new(value: Interned) -> Self { - Self { - value: LazyInterned::Interned(value), - } - } - pub const fn new_lazy(v: &'static dyn LazyInternedTrait) -> Self { - Self { - value: LazyInterned::new_lazy(v), - } - } - pub fn get(self) -> Interned { - self.value.interned() - } - pub fn type_properties(self) -> TypeProperties { - <()>::TYPE_PROPERTIES - } - pub fn can_connect(self, other: Self) -> bool { - self == other - } - pub fn canonical_phantom_const(self) -> PhantomConst { - if let Some(&retval) = ::downcast_ref::(&self) { - return retval; - } - ::new( - PhantomConstCanonicalMemoize::(PhantomData).get_owned(self.get()), - ) - } - pub fn from_canonical_phantom_const(canonical_type: PhantomConst) -> Self { - if let Some(&retval) = ::downcast_ref::(&canonical_type) { - return retval; - } - Self::new( - PhantomConstCanonicalMemoize::(PhantomData).get_owned(canonical_type.get()), - ) - } -} - -impl Type for PhantomConst { - type BaseType = PhantomConst; - type MaskType = (); - type SimValue = PhantomConst; - impl_match_variant_as_self!(); - - fn mask_type(&self) -> Self::MaskType { - () - } - - fn canonical(&self) -> CanonicalType { - CanonicalType::PhantomConst(self.canonical_phantom_const()) - } - - fn from_canonical(canonical_type: CanonicalType) -> Self { - let CanonicalType::PhantomConst(phantom_const) = canonical_type else { - panic!("expected PhantomConst"); - }; - Self::from_canonical_phantom_const(phantom_const) - } - - fn source_location() -> SourceLocation { - SourceLocation::builtin() - } - - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert!(bits.is_empty()); - *self - } - - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert!(bits.is_empty()); - assert_eq!(*value, *self); - } - - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert!(bits.is_empty()); - assert_eq!(*value, *self); - } -} - -impl Default for PhantomConst -where - Interned: Default, -{ - fn default() -> Self { - Self::TYPE - } -} - -impl StaticType for PhantomConst -where - Interned: Default, -{ - const TYPE: Self = PhantomConst { - value: LazyInterned::new_lazy(&Interned::::default), - }; - const MASK_TYPE: Self::MaskType = (); - const TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES; - const MASK_TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES; -} - -type SerdeType = SerdeCanonicalType>>; - -impl Serialize for PhantomConst { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - SerdeType::::PhantomConst(SerdePhantomConst(self.get())).serialize(serializer) - } -} - -impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for PhantomConst { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - match SerdeType::::deserialize(deserializer)? { - SerdeCanonicalType::PhantomConst(SerdePhantomConst(value)) => Ok(Self::new(value)), - ty => Err(Error::invalid_value( - serde::de::Unexpected::Other(ty.as_serde_unexpected_str()), - &"a PhantomConst", - )), - } - } -} - -impl ExprPartialEq for PhantomConst { - fn cmp_eq(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); - true.to_expr() - } - - fn cmp_ne(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); - false.to_expr() - } -} - -impl ExprPartialOrd for PhantomConst { - fn cmp_lt(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); - false.to_expr() - } - - fn cmp_le(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); - true.to_expr() - } - - fn cmp_gt(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); - false.to_expr() - } - - fn cmp_ge(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); - true.to_expr() - } -} - -impl SimValuePartialEq for PhantomConst { - fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { - assert_eq!(SimValue::ty(this), SimValue::ty(other)); - true - } -} - -impl ToSimValue for PhantomConst { - type Type = PhantomConst; - - fn to_sim_value(&self) -> SimValue { - SimValue::from_value(*self, *self) - } -} - -impl ToSimValueWithType> for PhantomConst { - fn to_sim_value_with_type(&self, ty: PhantomConst) -> SimValue> { - SimValue::from_value(ty, *self) - } -} - -impl ToSimValueWithType for PhantomConst { - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_value(Self::from_canonical(ty), *self)) - } -} diff --git a/crates/fayalite/src/prelude.rs b/crates/fayalite/src/prelude.rs index 519210f..9e7a85e 100644 --- a/crates/fayalite/src/prelude.rs +++ b/crates/fayalite/src/prelude.rs @@ -20,24 +20,17 @@ pub use crate::{ hdl_cover_with_enable, MakeFormalExpr, }, hdl, hdl_module, - int::{Bool, DynSize, KnownSize, SInt, SIntType, SIntValue, Size, UInt, UIntType, UIntValue}, + int::{Bool, DynSize, KnownSize, SInt, SIntType, Size, UInt, UIntType}, memory::{Mem, MemBuilder, ReadUnderWrite}, module::{ annotate, connect, connect_any, incomplete_wire, instance, memory, memory_array, memory_with_init, reg_builder, wire, Instance, Module, ModuleBuilder, }, - phantom_const::PhantomConst, reg::Reg, reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset}, - sim::{ - time::{SimDuration, SimInstant}, - value::{SimValue, ToSimValue, ToSimValueWithType}, - ExternModuleSimulationState, Simulation, - }, source_location::SourceLocation, ty::{AsMask, CanonicalType, Type}, util::{ConstUsize, GenericConstUsize}, wire::Wire, __, }; -pub use bitvec::{slice::BitSlice, vec::BitVec}; diff --git a/crates/fayalite/src/reset.rs b/crates/fayalite/src/reset.rs index 312a8ea..9328365 100644 --- a/crates/fayalite/src/reset.rs +++ b/crates/fayalite/src/reset.rs @@ -7,7 +7,6 @@ use crate::{ source_location::SourceLocation, ty::{impl_match_variant_as_self, CanonicalType, StaticType, Type, TypeProperties}, }; -use bitvec::slice::BitSlice; mod sealed { pub trait ResetTypeSealed {} @@ -46,7 +45,6 @@ macro_rules! reset_type { impl Type for $name { type BaseType = $name; type MaskType = Bool; - type SimValue = bool; impl_match_variant_as_self!(); @@ -68,21 +66,6 @@ macro_rules! reset_type { }; retval } - - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), 1); - bits[0] - } - - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), 1); - *value = bits[0]; - } - - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), 1); - bits.set(0, *value); - } } impl $name { diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 6659391..f630f5a 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -14,16 +14,13 @@ use crate::{ }, ExprEnum, Flow, ToLiteralBits, }, - int::{BoolOrIntType, UIntValue}, - intern::{ - Intern, Interned, InternedCompare, Memoize, PtrEqWithTypeId, SupportsPtrEqWithTypeId, - }, + int::{BoolOrIntType, IntType, SIntValue, UIntValue}, + intern::{Intern, Interned, Memoize}, memory::PortKind, module::{ - transform::deduce_resets::deduce_resets, AnnotatedModuleIO, Block, ExternModuleBody, Id, - InstantiatedModule, ModuleBody, NameId, NormalModuleBody, ScopedNameId, Stmt, StmtConnect, - StmtDeclaration, StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg, StmtWire, - TargetInInstantiatedModule, + transform::deduce_resets::deduce_resets, AnnotatedModuleIO, Block, Id, InstantiatedModule, + ModuleBody, NameId, NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration, + StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg, StmtWire, TargetInInstantiatedModule, }, prelude::*, reset::{ResetType, ResetTypeDispatch}, @@ -38,12 +35,12 @@ use crate::{ TypeIndexRange, TypeLayout, TypeLen, TypeParts, }, time::{SimDuration, SimInstant}, - value::SimValue, }, ty::StaticType, - util::{BitSliceWriteWithBase, DebugAsDisplay, HashMap, HashSet}, + util::{BitSliceWriteWithBase, DebugAsDisplay}, }; use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView}; +use hashbrown::{HashMap, HashSet}; use num_bigint::BigInt; use num_traits::{Signed, Zero}; use petgraph::{ @@ -54,25 +51,11 @@ use petgraph::{ }, }; use std::{ - any::Any, - borrow::Cow, - cell::RefCell, - collections::BTreeSet, - fmt, - future::{Future, IntoFuture}, - hash::Hash, - marker::PhantomData, - mem, - ops::IndexMut, - pin::Pin, - rc::Rc, - sync::Arc, - task::Poll, + borrow::Cow, collections::BTreeSet, fmt, marker::PhantomData, mem, ops::IndexMut, sync::Arc, }; mod interpreter; pub mod time; -pub mod value; pub mod vcd; #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] @@ -184,14 +167,6 @@ impl CompiledTypeLayout { body: CompiledTypeLayoutBody::Array { element }, } } - CanonicalType::PhantomConst(_) => { - let unit_layout = CompiledTypeLayout::get(()); - CompiledTypeLayout { - ty: *input, - layout: unit_layout.layout, - body: unit_layout.body, - } - } CanonicalType::Bundle(bundle) => { let mut layout = TypeLayout::empty(); let fields = bundle @@ -579,9 +554,8 @@ impl Assignments { big_slots, }) = self.slot_readers(); AssignmentsElements { - node_indexes: HashMap::with_capacity_and_hasher( + node_indexes: HashMap::with_capacity( self.assignments().len() + small_slots.len() + big_slots.len(), - Default::default(), ), nodes: self.node_references(), edges: self.edge_references(), @@ -1022,16 +996,6 @@ impl VisitMap for AssignmentsVisitMap { AssignmentOrSlotIndex::BigSlot(slot) => self.slots.contains(slot), } } - - fn unvisit(&mut self, n: AssignmentOrSlotIndex) -> bool { - match n { - AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { - mem::replace(&mut self.assignments[assignment_index], false) - } - AssignmentOrSlotIndex::SmallSlot(slot) => self.slots.remove(slot), - AssignmentOrSlotIndex::BigSlot(slot) => self.slots.remove(slot), - } - } } impl Visitable for Assignments { @@ -1645,20 +1609,12 @@ impl fmt::Debug for DebugOpaque { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -struct CompiledExternModule { - module_io_targets: Interned<[Target]>, - module_io: Interned<[CompiledValue]>, - simulation: ExternModuleSimulation, -} - #[derive(Debug)] pub struct Compiler { insns: Insns, original_base_module: Interned>, base_module: Interned>, modules: HashMap, - extern_modules: Vec, compiled_values: HashMap>, compiled_exprs: HashMap, CompiledExpr>, compiled_exprs_to_values: HashMap, CompiledValue>, @@ -1686,18 +1642,17 @@ impl Compiler { insns: Insns::new(), original_base_module, base_module, - modules: HashMap::default(), - extern_modules: Vec::new(), - compiled_values: HashMap::default(), - compiled_exprs: HashMap::default(), - compiled_exprs_to_values: HashMap::default(), - decl_conditions: HashMap::default(), - compiled_values_to_dyn_array_indexes: HashMap::default(), - compiled_value_bool_dest_is_small_map: HashMap::default(), + modules: HashMap::new(), + compiled_values: HashMap::new(), + compiled_exprs: HashMap::new(), + compiled_exprs_to_values: HashMap::new(), + decl_conditions: HashMap::new(), + compiled_values_to_dyn_array_indexes: HashMap::new(), + compiled_value_bool_dest_is_small_map: HashMap::new(), assignments: Assignments::default(), clock_triggers: Vec::new(), - compiled_value_to_clock_trigger_map: HashMap::default(), - enum_discriminants: HashMap::default(), + compiled_value_to_clock_trigger_map: HashMap::new(), + enum_discriminants: HashMap::new(), registers: Vec::new(), traces: SimTraces(Vec::new()), memories: Vec::new(), @@ -1837,7 +1792,7 @@ impl Compiler { } .into() } - CanonicalType::Bundle(_) | CanonicalType::PhantomConst(_) => unreachable!(), + CanonicalType::Bundle(_) => unreachable!(), CanonicalType::AsyncReset(_) => TraceAsyncReset { location: self.make_trace_scalar_helper( instantiated_module, @@ -2054,13 +2009,6 @@ impl Compiler { | CanonicalType::Clock(_) => { self.make_trace_scalar(instantiated_module, target, name, source_location) } - CanonicalType::PhantomConst(_) => TraceBundle { - name, - fields: Interned::default(), - ty: Bundle::new(Interned::default()), - flow: target.flow(), - } - .into(), } } fn make_trace_decl( @@ -2521,9 +2469,6 @@ impl Compiler { Expr::field(Expr::::from_canonical(expr.arg()), &field.name) }), ), - CanonicalType::PhantomConst(_) => { - self.compile_cast_aggregate_to_bits(instantiated_module, []) - } } } fn compile_cast_bits_to( @@ -2573,10 +2518,6 @@ impl Compiler { CanonicalType::SyncReset(ty) => Expr::canonical(expr.arg().cast_to(ty)), CanonicalType::Reset(_) => unreachable!(), CanonicalType::Clock(ty) => Expr::canonical(expr.arg().cast_to(ty)), - CanonicalType::PhantomConst(ty) => { - let _ = self.compile_expr(instantiated_module, Expr::canonical(expr.arg())); - Expr::canonical(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()) @@ -2626,7 +2567,6 @@ impl Compiler { CanonicalType::SyncReset(_) => false, CanonicalType::Reset(_) => false, CanonicalType::Clock(_) => false, - CanonicalType::PhantomConst(_) => unreachable!(), }; let dest_signed = match Expr::ty(expr) { CanonicalType::UInt(_) => false, @@ -2639,7 +2579,6 @@ impl Compiler { CanonicalType::SyncReset(_) => false, CanonicalType::Reset(_) => false, CanonicalType::Clock(_) => false, - CanonicalType::PhantomConst(_) => unreachable!(), }; self.simple_nary_big_expr(instantiated_module, Expr::ty(expr), [arg], |dest, [src]| { match (src_signed, dest_signed) { @@ -2695,9 +2634,6 @@ impl Compiler { }] }) .into(), - ExprEnum::PhantomConst(_) => self - .compile_aggregate_literal(instantiated_module, Expr::ty(expr), Interned::default()) - .into(), ExprEnum::BundleLiteral(literal) => self .compile_aggregate_literal( instantiated_module, @@ -3601,7 +3537,6 @@ impl Compiler { CanonicalType::SyncReset(_) => unreachable!(), CanonicalType::Reset(_) => unreachable!(), CanonicalType::Clock(_) => unreachable!(), - CanonicalType::PhantomConst(_) => unreachable!("PhantomConst mismatch"), } } let Some(target) = lhs.target() else { @@ -3966,7 +3901,6 @@ impl Compiler { CanonicalType::SyncReset(_) => false, CanonicalType::Reset(_) => false, CanonicalType::Clock(_) => false, - CanonicalType::PhantomConst(_) => unreachable!(), }; let width = data_layout.ty.bit_width(); if let Some(MemoryPortReadInsns { @@ -4713,27 +4647,8 @@ impl Compiler { ModuleBody::Normal(NormalModuleBody { body }) => { self.compile_block(module, body, Interned::default(), &mut trace_decls); } - ModuleBody::Extern(ExternModuleBody { - verilog_name: _, - parameters: _, - simulation, - }) => { - let Some(simulation) = simulation else { - panic!( - "can't simulate extern module without extern_module_simulation: {}", - module.leaf_module().source_location() - ); - }; - self.extern_modules.push(CompiledExternModule { - module_io_targets: module - .leaf_module() - .module_io() - .iter() - .map(|v| Target::from(v.module_io)) - .collect(), - module_io, - simulation, - }); + ModuleBody::Extern(_extern_module_body) => { + todo!("simulating extern module: {:?}", module); } } let hashbrown::hash_map::Entry::Vacant(entry) = self.modules.entry(*module) else { @@ -5014,7 +4929,6 @@ impl Compiler { Compiled { insns: Insns::from(self.insns).intern_sized(), base_module, - extern_modules: Intern::intern_owned(self.extern_modules), io: Instance::new_unchecked( ScopedNameId( NameId("".intern(), Id::new()), @@ -5047,7 +4961,6 @@ struct CompiledModule { pub struct Compiled { insns: Interned>, base_module: CompiledModule, - extern_modules: Interned<[CompiledExternModule]>, io: Instance, traces: SimTraces]>>, trace_memories: Interned<[(StatePartIndex, TraceMem)]>, @@ -5062,7 +4975,6 @@ impl Compiled { let Self { insns, base_module, - extern_modules, io, traces, trace_memories, @@ -5071,7 +4983,6 @@ impl Compiled { Compiled { insns, base_module, - extern_modules, io: Instance::from_canonical(io.canonical()), traces, trace_memories, @@ -5082,7 +4993,6 @@ impl Compiled { let Compiled { insns, base_module, - extern_modules, io, traces, trace_memories, @@ -5091,7 +5001,6 @@ impl Compiled { Self { insns, base_module, - extern_modules, io: Instance::from_canonical(io.canonical()), traces, trace_memories, @@ -5793,7 +5702,7 @@ where } } -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, Hash)] struct SimTrace { kind: K, state: S, @@ -5916,85 +5825,680 @@ impl SimTraceKind { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -enum MaybeNeedsSettle { - NeedsSettle(S), - NoSettleNeeded(N), +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct SimValue { + ty: T, + bits: BitVec, } -impl MaybeNeedsSettle { - fn map(self, f: impl FnOnce(T) -> U) -> MaybeNeedsSettle { - match self { - MaybeNeedsSettle::NeedsSettle(v) => MaybeNeedsSettle::NeedsSettle(f(v)), - MaybeNeedsSettle::NoSettleNeeded(v) => MaybeNeedsSettle::NoSettleNeeded(f(v)), +impl SimValue { + #[track_caller] + fn to_expr_impl(ty: CanonicalType, bits: &BitSlice) -> Expr { + match ty { + CanonicalType::UInt(_) => Expr::canonical(::bits_to_expr(Cow::Borrowed(bits))), + CanonicalType::SInt(_) => Expr::canonical(::bits_to_expr(Cow::Borrowed(bits))), + CanonicalType::Bool(_) => Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits))), + CanonicalType::Array(ty) => { + let element_bit_width = ty.element().bit_width(); + Expr::::canonical( + crate::expr::ops::ArrayLiteral::new( + ty.element(), + (0..ty.len()) + .map(|array_index| { + let start = element_bit_width * array_index; + let end = start + element_bit_width; + Self::to_expr_impl(ty.element(), &bits[start..end]) + }) + .collect(), + ) + .to_expr(), + ) + } + CanonicalType::Enum(ty) => { + let discriminant_bit_width = ty.discriminant_bit_width(); + let mut variant_index = [0; mem::size_of::()]; + variant_index.view_bits_mut::()[0..discriminant_bit_width] + .clone_from_bitslice(&bits[..discriminant_bit_width]); + let variant_index = usize::from_le_bytes(variant_index); + if let Some(variant) = ty.variants().get(variant_index) { + let data_bit_width = variant.ty.map_or(0, CanonicalType::bit_width); + Expr::canonical( + crate::expr::ops::EnumLiteral::new_by_index( + ty, + variant_index, + variant.ty.map(|ty| { + Self::to_expr_impl( + ty, + &bits[discriminant_bit_width + ..discriminant_bit_width + data_bit_width], + ) + }), + ) + .to_expr(), + ) + } else { + Expr::canonical(::bits_to_expr(Cow::Borrowed(bits)).cast_bits_to(ty)) + } + } + CanonicalType::Bundle(ty) => Expr::canonical( + crate::expr::ops::BundleLiteral::new( + ty, + ty.fields() + .iter() + .zip(ty.field_offsets().iter()) + .map(|(field, &field_offset)| { + Self::to_expr_impl( + field.ty, + &bits[field_offset..field_offset + field.ty.bit_width()], + ) + }) + .collect(), + ) + .to_expr(), + ), + CanonicalType::AsyncReset(ty) => { + Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits)).cast_to(ty)) + } + CanonicalType::SyncReset(ty) => { + Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits)).cast_to(ty)) + } + CanonicalType::Reset(_) => panic!( + "can't convert SimValue to Expr -- \ + can't deduce whether reset value should be sync or async" + ), + CanonicalType::Clock(ty) => { + Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits)).cast_to(ty)) + } } } } -// workaround implementing FnOnce not being stable -trait MaybeNeedsSettleFn { - type Output; +impl ToExpr for SimValue { + type Type = T; - fn call(self, arg: A) -> Self::Output; -} - -impl O, A, O> MaybeNeedsSettleFn for T { - type Output = O; - - fn call(self, arg: A) -> Self::Output { - self(arg) + #[track_caller] + fn to_expr(&self) -> Expr { + Expr::from_canonical(SimValue::to_expr_impl(self.ty.canonical(), &self.bits)) } } -impl MaybeNeedsSettle { - fn apply_no_settle(self, arg: T) -> MaybeNeedsSettle +impl ToSimValue for SimValue { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + assert_eq!(self.ty, ty); + self.clone() + } + + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + assert_eq!(self.ty, ty); + self + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + assert_eq!(self.ty, ty); + *self + } +} + +impl ToSimValue for BitVec { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + self.clone().into_sim_value(ty) + } + + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + assert_eq!(ty.canonical().bit_width(), self.len()); + SimValue { ty, bits: self } + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + Self::into_sim_value(*self, ty) + } +} + +impl ToSimValue for bitvec::boxed::BitBox { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + self.clone().into_sim_value(ty) + } + + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + assert_eq!(ty.canonical().bit_width(), self.len()); + SimValue { + ty, + bits: self.into_bitvec(), + } + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + Self::into_sim_value(*self, ty) + } +} + +impl ToSimValue for BitSlice { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + assert_eq!(ty.canonical().bit_width(), self.len()); + SimValue { + ty, + bits: self.to_bitvec(), + } + } +} + +impl SimValue { + pub fn ty(&self) -> T { + self.ty + } + pub fn bits(&self) -> &BitSlice { + &self.bits + } + pub fn into_bits(self) -> BitVec { + self.bits + } + #[track_caller] + pub fn from_canonical(v: SimValue) -> Self { + Self { + ty: T::from_canonical(v.ty), + bits: v.bits, + } + } + pub fn into_canonical(self) -> SimValue { + SimValue { + ty: self.ty.canonical(), + bits: self.bits, + } + } + #[track_caller] + pub fn from_dyn_int(v: SimValue) -> Self where - N: MaybeNeedsSettleFn, + T: IntType, { - match self { - MaybeNeedsSettle::NeedsSettle(v) => MaybeNeedsSettle::NeedsSettle(v), - MaybeNeedsSettle::NoSettleNeeded(v) => MaybeNeedsSettle::NoSettleNeeded(v.call(arg)), + Self { + ty: T::from_dyn_int(v.ty), + bits: v.bits, + } + } + pub fn into_dyn_int(self) -> SimValue + where + T: IntType, + { + SimValue { + ty: self.ty.as_dyn_int(), + bits: self.bits, + } + } + #[track_caller] + pub fn from_bundle(v: SimValue) -> Self + where + T: BundleType, + { + Self { + ty: T::from_canonical(CanonicalType::Bundle(v.ty)), + bits: v.bits, + } + } + pub fn into_bundle(self) -> SimValue + where + T: BundleType, + { + SimValue { + ty: Bundle::from_canonical(self.ty.canonical()), + bits: self.bits, + } + } + #[track_caller] + pub fn from_enum(v: SimValue) -> Self + where + T: EnumType, + { + Self { + ty: T::from_canonical(CanonicalType::Enum(v.ty)), + bits: v.bits, + } + } + pub fn into_enum(self) -> SimValue + where + T: EnumType, + { + SimValue { + ty: Enum::from_canonical(self.ty.canonical()), + bits: self.bits, } } } -struct SimulationModuleState { - base_targets: Vec, - uninitialized_ios: HashMap>, - io_targets: HashMap>, - did_initial_settle: bool, -} - -impl fmt::Debug for SimulationModuleState { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - base_targets, - uninitialized_ios, - io_targets, - did_initial_settle, - } = self; - f.debug_struct("SimulationModuleState") - .field("base_targets", base_targets) - .field("uninitialized_ios", &SortedSetDebug(uninitialized_ios)) - .field("io_targets", &SortedSetDebug(io_targets)) - .field("did_initial_settle", did_initial_settle) - .finish() +pub trait ToSimValue { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue; + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue + where + Self: Sized, + { + self.to_sim_value(ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + self.to_sim_value(ty) } } -impl SimulationModuleState { - fn new(base_targets: impl IntoIterator)>) -> Self { - let mut retval = Self { - base_targets: Vec::new(), - uninitialized_ios: HashMap::default(), - io_targets: HashMap::default(), - did_initial_settle: false, +impl, T: Type> ToSimValue for &'_ This { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } +} + +impl, T: Type> ToSimValue for &'_ mut This { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } +} + +impl, T: Type> ToSimValue for Box { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + This::box_into_sim_value(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + This::box_into_sim_value(*self, ty) + } +} + +impl + Send + Sync + 'static, T: Type> ToSimValue + for Interned +{ + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } +} + +impl SimValue> { + #[track_caller] + pub fn from_array_elements< + I: IntoIterator, IntoIter: ExactSizeIterator>, + >( + elements: I, + ty: ArrayType, + ) -> Self { + let mut iter = elements.into_iter(); + assert_eq!(iter.len(), ty.len()); + let Some(first) = iter.next() else { + return SimValue { + ty, + bits: BitVec::new(), + }; }; - for (base_target, value) in base_targets { - retval.base_targets.push(base_target); - retval.parse_io(base_target, value); + let SimValue { + ty: element_ty, + mut bits, + } = first.into_sim_value(ty.element()); + assert_eq!(element_ty, ty.element()); + bits.reserve(ty.type_properties().bit_width - bits.len()); + for element in iter { + let SimValue { + ty: element_ty, + bits: element_bits, + } = element.into_sim_value(ty.element()); + assert_eq!(element_ty, ty.element()); + bits.extend_from_bitslice(&element_bits); } - retval + SimValue { ty, bits } + } +} + +impl, T: Type> ToSimValue> for [Element] { + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } +} + +impl> ToSimValue for [Element] { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } +} + +impl, T: Type, const N: usize> ToSimValue> for [Element; N] +where + ConstUsize: KnownSize, +{ + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements( as From>>::from(self), ty) + } +} + +impl, T: Type, const N: usize> ToSimValue> for [Element; N] +where + ConstUsize: KnownSize, +{ + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements( as From>>::from(self), ty) + } +} + +impl, const N: usize> ToSimValue + for [Element; N] +{ + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn into_sim_value(self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements( + as From>>::from(self), + ::from_canonical(ty), + ) + .into_canonical() + } +} + +impl, T: Type> ToSimValue> for Vec { + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements(*self, ty) + } +} + +impl> ToSimValue for Vec { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn into_sim_value(self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(*self, ::from_canonical(ty)).into_canonical() + } +} + +impl ToSimValue for Expr { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + assert_eq!(Expr::ty(*self), ty); + SimValue { + ty, + bits: self + .to_literal_bits() + .expect("must be a literal expression") + .to_bitvec(), + } + } +} + +macro_rules! impl_to_sim_value_for_bool_like { + ($ty:ident) => { + impl ToSimValue<$ty> for bool { + fn to_sim_value(&self, ty: $ty) -> SimValue<$ty> { + SimValue { + ty, + bits: BitVec::repeat(*self, 1), + } + } + } + }; +} + +impl_to_sim_value_for_bool_like!(Bool); +impl_to_sim_value_for_bool_like!(AsyncReset); +impl_to_sim_value_for_bool_like!(SyncReset); +impl_to_sim_value_for_bool_like!(Reset); +impl_to_sim_value_for_bool_like!(Clock); + +impl ToSimValue for bool { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + match ty { + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Array(_) + | CanonicalType::Enum(_) + | CanonicalType::Bundle(_) => { + panic!("can't create SimValue from bool: expected value of type: {ty:?}"); + } + CanonicalType::Bool(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) => SimValue { + ty, + bits: BitVec::repeat(*self, 1), + }, + } + } +} + +macro_rules! impl_to_sim_value_for_primitive_int { + ($prim:ident) => { + impl ToSimValue<<$prim as ToExpr>::Type> for $prim { + #[track_caller] + fn to_sim_value( + &self, + ty: <$prim as ToExpr>::Type, + ) -> SimValue<<$prim as ToExpr>::Type> { + SimValue { + ty, + bits: <<$prim as ToExpr>::Type as BoolOrIntType>::le_bytes_to_bits_wrapping( + &self.to_le_bytes(), + ty.width(), + ), + } + } + } + + impl ToSimValue<<<$prim as ToExpr>::Type as IntType>::Dyn> for $prim { + #[track_caller] + fn to_sim_value( + &self, + ty: <<$prim as ToExpr>::Type as IntType>::Dyn, + ) -> SimValue<<<$prim as ToExpr>::Type as IntType>::Dyn> { + SimValue { + ty, + bits: <<$prim as ToExpr>::Type as BoolOrIntType>::le_bytes_to_bits_wrapping( + &self.to_le_bytes(), + ty.width(), + ), + } + } + } + + impl ToSimValue for $prim { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + let ty: <<$prim as ToExpr>::Type as IntType>::Dyn = Type::from_canonical(ty); + self.to_sim_value(ty).into_canonical() + } + } + }; +} + +impl_to_sim_value_for_primitive_int!(u8); +impl_to_sim_value_for_primitive_int!(u16); +impl_to_sim_value_for_primitive_int!(u32); +impl_to_sim_value_for_primitive_int!(u64); +impl_to_sim_value_for_primitive_int!(u128); +impl_to_sim_value_for_primitive_int!(usize); +impl_to_sim_value_for_primitive_int!(i8); +impl_to_sim_value_for_primitive_int!(i16); +impl_to_sim_value_for_primitive_int!(i32); +impl_to_sim_value_for_primitive_int!(i64); +impl_to_sim_value_for_primitive_int!(i128); +impl_to_sim_value_for_primitive_int!(isize); + +macro_rules! impl_to_sim_value_for_int_value { + ($IntValue:ident, $Int:ident, $IntType:ident) => { + impl ToSimValue<$IntType> for $IntValue { + fn to_sim_value(&self, ty: $IntType) -> SimValue<$IntType> { + self.bits().to_bitvec().into_sim_value(ty) + } + + fn into_sim_value(self, ty: $IntType) -> SimValue<$IntType> { + Arc::try_unwrap(self.into_bits()) + .unwrap_or_else(|v: Arc| v.to_bitvec()) + .into_sim_value(ty) + } + + fn box_into_sim_value( + self: Box, + ty: $IntType, + ) -> SimValue<$IntType> { + Self::into_sim_value(*self, ty) + } + } + + impl ToSimValue<$Int> for $IntValue { + fn to_sim_value(&self, ty: $Int) -> SimValue<$Int> { + self.bits().to_bitvec().into_sim_value(ty) + } + + fn into_sim_value(self, ty: $Int) -> SimValue<$Int> { + Arc::try_unwrap(self.into_bits()) + .unwrap_or_else(|v: Arc| v.to_bitvec()) + .into_sim_value(ty) + } + + fn box_into_sim_value(self: Box, ty: $Int) -> SimValue<$Int> { + Self::into_sim_value(*self, ty) + } + } + + impl ToSimValue for $IntValue { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + ToSimValue::<$Int>::to_sim_value(self, $Int::from_canonical(ty)).into_canonical() + } + + #[track_caller] + fn into_sim_value(self, ty: CanonicalType) -> SimValue { + ToSimValue::<$Int>::into_sim_value(self, $Int::from_canonical(ty)).into_canonical() + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + Self::into_sim_value(*self, ty) + } + } + }; +} + +impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType); +impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType); + +struct SimulationImpl { + state: interpreter::State, + io: Expr, + uninitialized_inputs: HashMap>, + io_targets: HashMap>, + made_initial_step: bool, + needs_settle: bool, + trace_decls: TraceModule, + traces: SimTraces]>>, + trace_memories: HashMap, TraceMem>, + trace_writers: Vec>, + instant: SimInstant, + clocks_triggered: Interned<[StatePartIndex]>, + breakpoints: Option, +} + +impl fmt::Debug for SimulationImpl { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.debug_fmt(None, f) + } +} + +impl SimulationImpl { + fn debug_fmt(&self, io: Option<&dyn fmt::Debug>, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + state, + io: self_io, + uninitialized_inputs, + io_targets, + made_initial_step, + needs_settle, + trace_decls, + traces, + trace_memories, + trace_writers, + instant, + clocks_triggered, + breakpoints: _, + } = self; + f.debug_struct("Simulation") + .field("state", state) + .field("io", io.unwrap_or(self_io)) + .field( + "uninitialized_inputs", + &SortedSetDebug(uninitialized_inputs), + ) + .field("io_targets", &SortedMapDebug(io_targets)) + .field("made_initial_step", made_initial_step) + .field("needs_settle", needs_settle) + .field("trace_decls", trace_decls) + .field("traces", traces) + .field("trace_memories", trace_memories) + .field("trace_writers", trace_writers) + .field("instant", instant) + .field("clocks_triggered", clocks_triggered) + .finish_non_exhaustive() } /// returns `true` if `target` or any sub-targets are uninitialized inputs fn parse_io(&mut self, target: Target, value: CompiledValue) -> bool { @@ -6003,7 +6507,7 @@ impl SimulationModuleState { CompiledTypeLayoutBody::Scalar => match target.flow() { Flow::Source => false, Flow::Sink => { - self.uninitialized_ios.insert(target, vec![]); + self.uninitialized_inputs.insert(target, vec![]); true } Flow::Duplex => unreachable!(), @@ -6022,7 +6526,7 @@ impl SimulationModuleState { if sub_targets.is_empty() { false } else { - self.uninitialized_ios.insert(target, sub_targets); + self.uninitialized_inputs.insert(target, sub_targets); true } } @@ -6040,510 +6544,20 @@ impl SimulationModuleState { if sub_targets.is_empty() { false } else { - self.uninitialized_ios.insert(target, sub_targets); + self.uninitialized_inputs.insert(target, sub_targets); true } } } } - fn mark_target_as_initialized(&mut self, mut target: Target) { - fn remove_target_and_children( - uninitialized_ios: &mut HashMap>, - target: Target, - ) { - let Some(children) = uninitialized_ios.remove(&target) else { - return; - }; - for child in children { - remove_target_and_children(uninitialized_ios, child); - } - } - remove_target_and_children(&mut self.uninitialized_ios, target); - while let Some(target_child) = target.child() { - let parent = target_child.parent(); - for child in self - .uninitialized_ios - .get(&*parent) - .map(|v| &**v) - .unwrap_or(&[]) - { - if self.uninitialized_ios.contains_key(child) { - return; - } - } - target = *parent; - self.uninitialized_ios.remove(&target); - } - } - #[track_caller] - fn get_io( - &self, - mut target: Target, - which_module: WhichModule, - ) -> CompiledValue { - assert!( - target.canonical_ty().is_passive(), - "simulator read/write expression must have a passive type \ - (recursively contains no fields with `#[hdl(flip)]`)" - ); - if let Some(&retval) = self.io_targets.get(&target) { - return retval; - } - loop { - target = match target { - Target::Base(_) => break, - Target::Child(child) => { - match *child.path_element() { - TargetPathElement::BundleField(_) | TargetPathElement::ArrayElement(_) => {} - TargetPathElement::DynArrayElement(_) => panic!( - "simulator read/write expression must not have dynamic array indexes" - ), - } - *child.parent() - } - }; - } - match which_module { - WhichModule::Main => panic!( - "simulator read/write expression must be \ - an array element/field of `Simulation::io()`" - ), - WhichModule::Extern { .. } => panic!( - "simulator read/write expression must be \ - one of this module's inputs/outputs or an \ - array element/field of one of this module's inputs/outputs" - ), - } - } - #[track_caller] - fn read_helper( - &self, - io: Expr, - which_module: WhichModule, - ) -> MaybeNeedsSettle> { - let Some(target) = io.target() else { - match which_module { - WhichModule::Main => panic!( - "can't read from an expression that's not a field/element of `Simulation::io()`" - ), - WhichModule::Extern { .. } => panic!( - "can't read from an expression that's not based on one of this module's inputs/outputs" - ), - } - }; - let compiled_value = self.get_io(*target, which_module); - match target.flow() { - Flow::Source => { - if !self.uninitialized_ios.is_empty() { - match which_module { - WhichModule::Main => { - panic!("can't read from an output before initializing all inputs"); - } - WhichModule::Extern { .. } => { - panic!("can't read from an input before initializing all outputs"); - } - } - } - MaybeNeedsSettle::NeedsSettle(compiled_value) - } - Flow::Sink => { - if self.uninitialized_ios.contains_key(&*target) { - match which_module { - WhichModule::Main => panic!("can't read from an uninitialized input"), - WhichModule::Extern { .. } => { - panic!("can't read from an uninitialized output"); - } - } - } - MaybeNeedsSettle::NoSettleNeeded(compiled_value) - } - Flow::Duplex => unreachable!(), - } - } - #[track_caller] - fn write_helper( - &mut self, - io: Expr, - which_module: WhichModule, - ) -> CompiledValue { - let Some(target) = io.target() else { - match which_module { - WhichModule::Main => panic!( - "can't write to an expression that's not a field/element of `Simulation::io()`" - ), - WhichModule::Extern { .. } => panic!( - "can't write to an expression that's not based on one of this module's outputs" - ), - } - }; - let compiled_value = self.get_io(*target, which_module); - match target.flow() { - Flow::Source => match which_module { - WhichModule::Main => panic!("can't write to an output"), - WhichModule::Extern { .. } => panic!("can't write to an input"), - }, - Flow::Sink => {} - Flow::Duplex => unreachable!(), - } - if !self.did_initial_settle { - self.mark_target_as_initialized(*target); - } - compiled_value - } -} - -#[derive(Copy, Clone, Debug)] -enum WaitTarget { - Settle, - Instant(SimInstant), - Change { key: ChangeKey, value: ChangeValue }, -} - -#[derive(Clone)] -struct EarliestWaitTargets { - settle: bool, - instant: Option, - changes: HashMap, SimValue>, -} - -impl fmt::Debug for EarliestWaitTargets { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_set().entries(self.iter()).finish() - } -} - -impl Default for EarliestWaitTargets { - fn default() -> Self { - Self { - settle: false, - instant: None, - changes: HashMap::default(), - } - } -} - -impl EarliestWaitTargets { - fn settle() -> Self { - Self { - settle: true, - instant: None, - changes: HashMap::default(), - } - } - fn instant(instant: SimInstant) -> Self { - Self { - settle: false, - instant: Some(instant), - changes: HashMap::default(), - } - } - fn len(&self) -> usize { - self.settle as usize + self.instant.is_some() as usize + self.changes.len() - } - fn is_empty(&self) -> bool { - self.len() == 0 - } - fn clear(&mut self) { - let Self { - settle, - instant, - changes, - } = self; - *settle = false; - *instant = None; - changes.clear(); - } - fn insert( - &mut self, - value: impl std::borrow::Borrow, ChangeValue>>, - ) where - ChangeValue: std::borrow::Borrow>, - { - let value = value.borrow(); - match value { - WaitTarget::Settle => self.settle = true, - WaitTarget::Instant(instant) => { - if self.instant.is_none_or(|v| v > *instant) { - self.instant = Some(*instant); - } - } - WaitTarget::Change { key, value } => { - self.changes - .entry(*key) - .or_insert_with(|| value.borrow().clone()); - } - } - } - fn convert_earlier_instants_to_settle(&mut self, instant: SimInstant) { - if self.instant.is_some_and(|v| v <= instant) { - self.settle = true; - self.instant = None; - } - } - fn iter<'a>( - &'a self, - ) -> impl Clone - + Iterator, &'a SimValue>> - + 'a { - self.settle - .then_some(WaitTarget::Settle) - .into_iter() - .chain(self.instant.map(|instant| WaitTarget::Instant(instant))) - .chain( - self.changes - .iter() - .map(|(&key, value)| WaitTarget::Change { key, value }), - ) - } -} - -impl>> - Extend, ChangeValue>> for EarliestWaitTargets -{ - fn extend, ChangeValue>>>( - &mut self, - iter: T, - ) { - iter.into_iter().for_each(|v| self.insert(v)) - } -} - -impl<'a, ChangeValue: std::borrow::Borrow>> - Extend<&'a WaitTarget, ChangeValue>> for EarliestWaitTargets -{ - fn extend, ChangeValue>>>( - &mut self, - iter: T, - ) { - iter.into_iter().for_each(|v| self.insert(v)) - } -} - -impl FromIterator for EarliestWaitTargets -where - Self: Extend, -{ - fn from_iter>(iter: T) -> Self { - let mut retval = Self::default(); - retval.extend(iter); - retval - } -} - -struct SimulationExternModuleState { - module_state: SimulationModuleState, - sim: ExternModuleSimulation, - running_generator: Option + 'static>>>, - wait_targets: EarliestWaitTargets, -} - -impl fmt::Debug for SimulationExternModuleState { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - module_state, - sim, - running_generator, - wait_targets, - } = self; - f.debug_struct("SimulationExternModuleState") - .field("module_state", module_state) - .field("sim", sim) - .field( - "running_generator", - &running_generator.as_ref().map(|_| DebugAsDisplay("...")), - ) - .field("wait_targets", wait_targets) - .finish() - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -enum WhichModule { - Main, - Extern { module_index: usize }, -} - -struct ReadBitFn { - compiled_value: CompiledValue, -} - -impl MaybeNeedsSettleFn<&'_ mut interpreter::State> for ReadBitFn { - type Output = bool; - - fn call(self, state: &mut interpreter::State) -> Self::Output { - match self.compiled_value.range.len() { - TypeLen::A_SMALL_SLOT => { - state.small_slots[self.compiled_value.range.small_slots.start] != 0 - } - TypeLen::A_BIG_SLOT => !state.big_slots[self.compiled_value.range.big_slots.start] - .clone() - .is_zero(), - _ => unreachable!(), - } - } -} - -struct ReadBoolOrIntFn { - compiled_value: CompiledValue, - io: Expr, -} - -impl MaybeNeedsSettleFn<&'_ mut interpreter::State> for ReadBoolOrIntFn { - type Output = I::Value; - - fn call(self, state: &mut interpreter::State) -> Self::Output { - let Self { compiled_value, io } = self; - match compiled_value.range.len() { - TypeLen::A_SMALL_SLOT => Expr::ty(io) - .value_from_int_wrapping(state.small_slots[compiled_value.range.small_slots.start]), - TypeLen::A_BIG_SLOT => Expr::ty(io).value_from_int_wrapping( - state.big_slots[compiled_value.range.big_slots.start].clone(), - ), - _ => unreachable!(), - } - } -} - -struct ReadFn { - compiled_value: CompiledValue, - io: Expr, -} - -impl MaybeNeedsSettleFn<&'_ mut interpreter::State> for ReadFn { - type Output = SimValue; - - fn call(self, state: &mut interpreter::State) -> Self::Output { - let Self { compiled_value, io } = self; - SimulationImpl::read_no_settle_helper( - state, - io, - compiled_value, - UIntValue::new(Arc::new(BitVec::repeat(false, Expr::ty(io).bit_width()))), - ) - } -} - -struct GeneratorWaker; - -impl std::task::Wake for GeneratorWaker { - fn wake(self: Arc) { - panic!("can't await other kinds of futures in function passed to ExternalModuleSimulation"); - } -} - -#[derive(Default)] -struct ReadyToRunSet { - state_ready_to_run: bool, - extern_modules_ready_to_run: Vec, -} - -impl ReadyToRunSet { - fn clear(&mut self) { - let Self { - state_ready_to_run, - extern_modules_ready_to_run, - } = self; - *state_ready_to_run = false; - extern_modules_ready_to_run.clear(); - } -} - -struct SimulationImpl { - state: interpreter::State, - io: Expr, - main_module: SimulationModuleState, - extern_modules: Box<[SimulationExternModuleState]>, - state_ready_to_run: bool, - trace_decls: TraceModule, - traces: SimTraces]>>, - trace_memories: HashMap, TraceMem>, - trace_writers: Vec>, - instant: SimInstant, - clocks_triggered: Interned<[StatePartIndex]>, - breakpoints: Option, - generator_waker: std::task::Waker, -} - -impl fmt::Debug for SimulationImpl { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.debug_fmt(None, f) - } -} - -impl SimulationImpl { - fn debug_fmt(&self, io: Option<&dyn fmt::Debug>, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - state, - io: self_io, - main_module, - extern_modules, - state_ready_to_run, - trace_decls, - traces, - trace_memories, - trace_writers, - instant, - clocks_triggered, - breakpoints: _, - generator_waker: _, - } = self; - f.debug_struct("Simulation") - .field("state", state) - .field("io", io.unwrap_or(self_io)) - .field("main_module", main_module) - .field("extern_modules", extern_modules) - .field("state_ready_to_run", state_ready_to_run) - .field("trace_decls", trace_decls) - .field("traces", traces) - .field("trace_memories", trace_memories) - .field("trace_writers", trace_writers) - .field("instant", instant) - .field("clocks_triggered", clocks_triggered) - .finish_non_exhaustive() - } fn new(compiled: Compiled) -> Self { - let io_target = Target::from(compiled.io); - let extern_modules = Box::from_iter(compiled.extern_modules.iter().map( - |&CompiledExternModule { - module_io_targets, - module_io, - simulation, - }| { - SimulationExternModuleState { - module_state: SimulationModuleState::new( - module_io_targets - .iter() - .copied() - .zip(module_io.iter().copied()), - ), - sim: simulation, - running_generator: None, - wait_targets: EarliestWaitTargets::settle(), - } - }, - )); - Self { + let mut retval = Self { state: State::new(compiled.insns), io: compiled.io.to_expr(), - main_module: SimulationModuleState::new( - compiled - .io - .ty() - .fields() - .into_iter() - .zip(compiled.base_module.module_io) - .map(|(BundleField { name, .. }, value)| { - ( - io_target.join( - TargetPathElement::from(TargetPathBundleField { name }) - .intern_sized(), - ), - value, - ) - }), - ), - extern_modules, - state_ready_to_run: true, + uninitialized_inputs: HashMap::new(), + io_targets: HashMap::new(), + made_initial_step: false, + needs_settle: true, trace_decls: compiled.base_module.trace_decls, traces: SimTraces(Box::from_iter(compiled.traces.0.iter().map( |&SimTrace { @@ -6561,8 +6575,22 @@ impl SimulationImpl { instant: SimInstant::START, clocks_triggered: compiled.clocks_triggered, breakpoints: None, - generator_waker: Arc::new(GeneratorWaker).into(), + }; + let io_target = Target::from(compiled.io); + for (BundleField { name, .. }, value) in compiled + .io + .ty() + .fields() + .into_iter() + .zip(compiled.base_module.module_io) + { + retval.parse_io( + io_target + .join(TargetPathElement::from(TargetPathBundleField { name }).intern_sized()), + value, + ); } + retval } fn write_traces( &mut self, @@ -6700,120 +6728,9 @@ impl SimulationImpl { } } #[track_caller] - fn advance_time(this_ref: &Rc>, duration: SimDuration) { - let run_target = this_ref.borrow().instant + duration; - Self::run_until(this_ref, run_target); - } - /// clears `targets` - #[must_use] - fn yield_wait<'a>( - this: Rc>, - module_index: usize, - targets: &'a mut EarliestWaitTargets, - ) -> impl Future + 'a { - struct MyGenerator<'a> { - sim: Rc>, - yielded_at_all: bool, - module_index: usize, - targets: &'a mut EarliestWaitTargets, - } - impl Future for MyGenerator<'_> { - type Output = (); - - fn poll( - mut self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> Poll { - let this = &mut *self; - let mut sim = this.sim.borrow_mut(); - let sim = &mut *sim; - assert!(cx.waker().will_wake(&sim.generator_waker), "can't use ExternModuleSimulationState's methods outside of ExternModuleSimulation"); - this.targets.convert_earlier_instants_to_settle(sim.instant); - if this.targets.is_empty() { - this.targets.settle = true; - } - if this.targets.settle { - if this.yielded_at_all { - this.targets.clear(); - return Poll::Ready(()); - } - } - sim.extern_modules[this.module_index] - .wait_targets - .extend(this.targets.iter()); - this.targets.clear(); - this.yielded_at_all = true; - Poll::Pending - } - } - MyGenerator { - sim: this, - yielded_at_all: false, - module_index, - targets, - } - } - async fn yield_advance_time_or_settle( - this: Rc>, - module_index: usize, - duration: Option, - ) { - let mut targets = duration.map_or(EarliestWaitTargets::settle(), |duration| { - EarliestWaitTargets::instant(this.borrow().instant + duration) - }); - Self::yield_wait(this, module_index, &mut targets).await; - } - fn is_extern_module_ready_to_run(&mut self, module_index: usize) -> Option { - let module = &self.extern_modules[module_index]; - let mut retval = None; - for wait_target in module.wait_targets.iter() { - retval = match (wait_target, retval) { - (WaitTarget::Settle, _) => Some(self.instant), - (WaitTarget::Instant(instant), _) if instant <= self.instant => Some(self.instant), - (WaitTarget::Instant(instant), None) => Some(instant), - (WaitTarget::Instant(instant), Some(retval)) => Some(instant.min(retval)), - (WaitTarget::Change { key, value }, retval) => { - if Self::value_changed(&mut self.state, key, SimValue::bits(value).bits()) { - Some(self.instant) - } else { - retval - } - } - }; - if retval == Some(self.instant) { - break; - } - } - retval - } - fn get_ready_to_run_set(&mut self, ready_to_run_set: &mut ReadyToRunSet) -> Option { - ready_to_run_set.clear(); - let mut retval = None; - if self.state_ready_to_run { - ready_to_run_set.state_ready_to_run = true; - retval = Some(self.instant); - } - for module_index in 0..self.extern_modules.len() { - let Some(instant) = self.is_extern_module_ready_to_run(module_index) else { - continue; - }; - if let Some(retval) = &mut retval { - match instant.cmp(retval) { - std::cmp::Ordering::Less => ready_to_run_set.clear(), - std::cmp::Ordering::Equal => {} - std::cmp::Ordering::Greater => continue, - } - } else { - retval = Some(instant); - } - ready_to_run_set - .extern_modules_ready_to_run - .push(module_index); - } - retval - } - fn set_instant_no_sim(&mut self, instant: SimInstant) { - self.instant = instant; + fn advance_time(&mut self, duration: SimDuration) { + self.settle(); + self.instant += duration; self.for_each_trace_writer_storing_error(|this, mut trace_writer_state| { match &mut trace_writer_state { TraceWriterState::Decls(_) | TraceWriterState::Init(_) => unreachable!(), @@ -6825,145 +6742,54 @@ impl SimulationImpl { Ok(trace_writer_state) }); } - #[must_use] #[track_caller] - fn run_state_settle_cycle(&mut self) -> bool { - self.state_ready_to_run = false; - self.state.setup_call(0); - if self.breakpoints.is_some() { - loop { - match self - .state - .run(self.breakpoints.as_mut().expect("just checked")) - { - RunResult::Break(break_action) => { - println!( - "hit breakpoint at:\n{:?}", - self.state.debug_insn_at(self.state.pc), - ); - match break_action { - BreakAction::DumpStateAndContinue => { - println!("{self:#?}"); - } - BreakAction::Continue => {} - } - } - RunResult::Return(()) => break, - } - } - } else { - let RunResult::Return(()) = self.state.run(()); - } - if self - .clocks_triggered - .iter() - .any(|i| self.state.small_slots[*i] != 0) - { - self.state_ready_to_run = true; - true - } else { - false - } - } - #[track_caller] - fn run_extern_modules_cycle( - this_ref: &Rc>, - generator_waker: &std::task::Waker, - extern_modules_ready_to_run: &[usize], - ) { - let mut this = this_ref.borrow_mut(); - for module_index in extern_modules_ready_to_run.iter().copied() { - let extern_module = &mut this.extern_modules[module_index]; - extern_module.wait_targets.clear(); - let mut generator = if !extern_module.module_state.did_initial_settle { - let sim = extern_module.sim; - drop(this); - Box::into_pin(sim.run(ExternModuleSimulationState { - sim_impl: this_ref.clone(), - module_index, - wait_for_changes_wait_targets: EarliestWaitTargets::default(), - })) - } else if let Some(generator) = extern_module.running_generator.take() { - drop(this); - generator - } else { - continue; - }; - let generator = match generator - .as_mut() - .poll(&mut std::task::Context::from_waker(generator_waker)) - { - Poll::Ready(()) => None, - Poll::Pending => Some(generator), - }; - this = this_ref.borrow_mut(); - this.extern_modules[module_index] - .module_state - .did_initial_settle = true; - if !this.extern_modules[module_index] - .module_state - .uninitialized_ios - .is_empty() - { - panic!( - "extern module didn't initialize all outputs before \ - waiting, settling, or reading any inputs: {}", - this.extern_modules[module_index].sim.source_location - ); - } - this.extern_modules[module_index].running_generator = generator; - } - } - /// clears `targets` - #[track_caller] - fn run_until(this_ref: &Rc>, run_target: SimInstant) { - let mut this = this_ref.borrow_mut(); - let mut ready_to_run_set = ReadyToRunSet::default(); - let generator_waker = this.generator_waker.clone(); + fn settle(&mut self) { assert!( - this.main_module.uninitialized_ios.is_empty(), + self.uninitialized_inputs.is_empty(), "didn't initialize all inputs", ); - let run_target = run_target.max(this.instant); - let mut settle_cycle = 0; - let mut run_extern_modules = true; - loop { - assert!(settle_cycle < 100000, "settle(): took too many steps"); - settle_cycle += 1; - let next_wait_target = match this.get_ready_to_run_set(&mut ready_to_run_set) { - Some(next_wait_target) if next_wait_target <= run_target => next_wait_target, - _ => break, - }; - if next_wait_target > this.instant { - settle_cycle = 0; - this.set_instant_no_sim(next_wait_target); + for _ in 0..100000 { + if !self.needs_settle { + return; } - if run_extern_modules { - drop(this); - Self::run_extern_modules_cycle( - this_ref, - &generator_waker, - &ready_to_run_set.extern_modules_ready_to_run, - ); - this = this_ref.borrow_mut(); - } - if ready_to_run_set.state_ready_to_run { - if this.run_state_settle_cycle() { - // wait for clocks to settle before running extern modules again - run_extern_modules = false; - } else { - run_extern_modules = true; + self.state.setup_call(0); + if self.breakpoints.is_some() { + loop { + match self + .state + .run(self.breakpoints.as_mut().expect("just checked")) + { + RunResult::Break(break_action) => { + println!( + "hit breakpoint at:\n{:?}", + self.state.debug_insn_at(self.state.pc), + ); + match break_action { + BreakAction::DumpStateAndContinue => { + println!("{self:#?}"); + } + BreakAction::Continue => {} + } + } + RunResult::Return(()) => break, + } } - } - if this.main_module.did_initial_settle { - this.read_traces::(); } else { - this.read_traces::(); + let RunResult::Return(()) = self.state.run(()); } - this.state.memory_write_log.sort_unstable(); - this.state.memory_write_log.dedup(); - this.main_module.did_initial_settle = true; - this.for_each_trace_writer_storing_error(|this, trace_writer_state| { + if self.made_initial_step { + self.read_traces::(); + } else { + self.read_traces::(); + } + self.state.memory_write_log.sort_unstable(); + self.state.memory_write_log.dedup(); + self.made_initial_step = true; + self.needs_settle = self + .clocks_triggered + .iter() + .any(|i| self.state.small_slots[*i] != 0); + self.for_each_trace_writer_storing_error(|this, trace_writer_state| { Ok(match trace_writer_state { TraceWriterState::Decls(trace_writer_decls) => TraceWriterState::Running( this.init_trace_writer(trace_writer_decls.write_decls( @@ -6981,48 +6807,114 @@ impl SimulationImpl { TraceWriterState::Errored(e) => TraceWriterState::Errored(e), }) }); - this.state.memory_write_log.clear(); - } - if run_target > this.instant { - this.set_instant_no_sim(run_target); + self.state.memory_write_log.clear(); } + panic!("settle(): took too many steps"); } #[track_caller] - fn settle(this_ref: &Rc>) { - let run_target = this_ref.borrow().instant; - Self::run_until(this_ref, run_target); - } - fn get_module(&self, which_module: WhichModule) -> &SimulationModuleState { - match which_module { - WhichModule::Main => &self.main_module, - WhichModule::Extern { module_index } => &self.extern_modules[module_index].module_state, + fn get_io(&self, target: Target) -> CompiledValue { + if let Some(&retval) = self.io_targets.get(&target) { + return retval; } + if Some(&target) == self.io.target().as_deref() + || Some(target.base()) != self.io.target().map(|v| v.base()) + { + panic!("simulator read/write expression must be an array element/field of `Simulation::io()`"); + }; + panic!("simulator read/write expression must not have dynamic array indexes"); } - fn get_module_mut(&mut self, which_module: WhichModule) -> &mut SimulationModuleState { - match which_module { - WhichModule::Main => &mut self.main_module, - WhichModule::Extern { module_index } => { - &mut self.extern_modules[module_index].module_state + fn mark_target_as_initialized(&mut self, mut target: Target) { + fn remove_target_and_children( + uninitialized_inputs: &mut HashMap>, + target: Target, + ) { + let Some(children) = uninitialized_inputs.remove(&target) else { + return; + }; + for child in children { + remove_target_and_children(uninitialized_inputs, child); } } + remove_target_and_children(&mut self.uninitialized_inputs, target); + while let Some(target_child) = target.child() { + let parent = target_child.parent(); + for child in self + .uninitialized_inputs + .get(&*parent) + .map(|v| &**v) + .unwrap_or(&[]) + { + if self.uninitialized_inputs.contains_key(child) { + return; + } + } + target = *parent; + self.uninitialized_inputs.remove(&target); + } } #[track_caller] - fn read_bit( - &mut self, - io: Expr, - which_module: WhichModule, - ) -> MaybeNeedsSettle { - self.get_module(which_module) - .read_helper(Expr::canonical(io), which_module) - .map(|compiled_value| ReadBitFn { compiled_value }) - .apply_no_settle(&mut self.state) + fn read_helper(&mut self, io: Expr) -> CompiledValue { + let Some(target) = io.target() else { + panic!("can't read from expression that's not a field/element of `Simulation::io()`"); + }; + let compiled_value = self.get_io(*target); + if self.made_initial_step { + self.settle(); + } else { + match target.flow() { + Flow::Source => { + if !self.uninitialized_inputs.is_empty() { + panic!( + "can't read from an output before the simulation has made any steps" + ); + } + self.settle(); + } + Flow::Sink => { + if self.uninitialized_inputs.contains_key(&*target) { + panic!("can't read from an uninitialized input"); + } + } + Flow::Duplex => unreachable!(), + } + } + compiled_value } #[track_caller] - fn write_bit(&mut self, io: Expr, value: bool, which_module: WhichModule) { - let compiled_value = self - .get_module_mut(which_module) - .write_helper(io, which_module); - self.state_ready_to_run = true; + fn write_helper(&mut self, io: Expr) -> CompiledValue { + let Some(target) = io.target() else { + panic!("can't write to an expression that's not a field/element of `Simulation::io()`"); + }; + let compiled_value = self.get_io(*target); + match target.flow() { + Flow::Source => { + panic!("can't write to an output"); + } + Flow::Sink => {} + Flow::Duplex => unreachable!(), + } + if !self.made_initial_step { + self.mark_target_as_initialized(*target); + } + self.needs_settle = true; + compiled_value + } + #[track_caller] + fn read_bit(&mut self, io: Expr) -> bool { + let compiled_value = self.read_helper(Expr::canonical(io)); + match compiled_value.range.len() { + TypeLen::A_SMALL_SLOT => { + self.state.small_slots[compiled_value.range.small_slots.start] != 0 + } + TypeLen::A_BIG_SLOT => !self.state.big_slots[compiled_value.range.big_slots.start] + .clone() + .is_zero(), + _ => unreachable!(), + } + } + #[track_caller] + fn write_bit(&mut self, io: Expr, value: bool) { + let compiled_value = self.write_helper(io); match compiled_value.range.len() { TypeLen::A_SMALL_SLOT => { self.state.small_slots[compiled_value.range.small_slots.start] = value as _; @@ -7034,27 +6926,21 @@ impl SimulationImpl { } } #[track_caller] - fn read_bool_or_int( - &mut self, - io: Expr, - which_module: WhichModule, - ) -> MaybeNeedsSettle, I::Value> { - self.get_module(which_module) - .read_helper(Expr::canonical(io), which_module) - .map(|compiled_value| ReadBoolOrIntFn { compiled_value, io }) - .apply_no_settle(&mut self.state) + fn read_bool_or_int(&mut self, io: Expr) -> I::Value { + let compiled_value = self.read_helper(Expr::canonical(io)); + match compiled_value.range.len() { + TypeLen::A_SMALL_SLOT => Expr::ty(io).value_from_int_wrapping( + self.state.small_slots[compiled_value.range.small_slots.start], + ), + TypeLen::A_BIG_SLOT => Expr::ty(io).value_from_int_wrapping( + self.state.big_slots[compiled_value.range.big_slots.start].clone(), + ), + _ => unreachable!(), + } } #[track_caller] - fn write_bool_or_int( - &mut self, - io: Expr, - value: I::Value, - which_module: WhichModule, - ) { - let compiled_value = self - .get_module_mut(which_module) - .write_helper(Expr::canonical(io), which_module); - self.state_ready_to_run = true; + fn write_bool_or_int(&mut self, io: Expr, value: I::Value) { + let compiled_value = self.write_helper(Expr::canonical(io)); let value: BigInt = value.into(); match compiled_value.range.len() { TypeLen::A_SMALL_SLOT => { @@ -7071,13 +6957,12 @@ impl SimulationImpl { } } #[track_caller] - fn read_write_sim_value_helper( - state: &mut interpreter::State, + fn read_write_sim_value_helper( + &mut self, compiled_value: CompiledValue, - start_bit_index: usize, - bits: &mut Bits, - read_write_big_scalar: impl Fn(bool, std::ops::Range, &mut Bits, &mut BigInt) + Copy, - read_write_small_scalar: impl Fn(bool, std::ops::Range, &mut Bits, &mut SmallUInt) + Copy, + bits: &mut BitSlice, + read_write_big_scalar: impl Fn(bool, &mut BitSlice, &mut BigInt) + Copy, + read_write_small_scalar: impl Fn(bool, &mut BitSlice, &mut SmallUInt) + Copy, ) { match compiled_value.layout.body { CompiledTypeLayoutBody::Scalar => { @@ -7092,22 +6977,17 @@ impl SimulationImpl { CanonicalType::SyncReset(_) => false, CanonicalType::Reset(_) => false, CanonicalType::Clock(_) => false, - CanonicalType::PhantomConst(_) => unreachable!(), }; - let bit_indexes = - start_bit_index..start_bit_index + compiled_value.layout.ty.bit_width(); match compiled_value.range.len() { TypeLen::A_SMALL_SLOT => read_write_small_scalar( signed, - bit_indexes, bits, - &mut state.small_slots[compiled_value.range.small_slots.start], + &mut self.state.small_slots[compiled_value.range.small_slots.start], ), TypeLen::A_BIG_SLOT => read_write_big_scalar( signed, - bit_indexes, bits, - &mut state.big_slots[compiled_value.range.big_slots.start], + &mut self.state.big_slots[compiled_value.range.big_slots.start], ), _ => unreachable!(), } @@ -7116,8 +6996,7 @@ impl SimulationImpl { let ty = ::from_canonical(compiled_value.layout.ty); let element_bit_width = ty.element().bit_width(); for element_index in 0..ty.len() { - Self::read_write_sim_value_helper( - state, + self.read_write_sim_value_helper( CompiledValue { layout: *element, range: compiled_value @@ -7125,8 +7004,7 @@ impl SimulationImpl { .index_array(element.layout.len(), element_index), write: None, }, - start_bit_index + element_index * element_bit_width, - bits, + &mut bits[element_index * element_bit_width..][..element_bit_width], read_write_big_scalar, read_write_small_scalar, ); @@ -7135,15 +7013,14 @@ impl SimulationImpl { CompiledTypeLayoutBody::Bundle { fields } => { let ty = Bundle::from_canonical(compiled_value.layout.ty); for ( - (_field, offset), + (field, offset), CompiledBundleField { offset: layout_offset, ty: field_layout, }, ) in ty.fields().iter().zip(ty.field_offsets()).zip(fields) { - Self::read_write_sim_value_helper( - state, + self.read_write_sim_value_helper( CompiledValue { layout: field_layout, range: compiled_value.range.slice(TypeIndexRange::new( @@ -7152,8 +7029,7 @@ impl SimulationImpl { )), write: None, }, - start_bit_index + offset, - bits, + &mut bits[offset..][..field.ty.bit_width()], read_write_big_scalar, read_write_small_scalar, ); @@ -7162,139 +7038,48 @@ impl SimulationImpl { } } #[track_caller] - fn read_no_settle_helper( - state: &mut interpreter::State, - io: Expr, - compiled_value: CompiledValue, - mut bits: UIntValue, - ) -> SimValue { - SimulationImpl::read_write_sim_value_helper( - state, + fn read(&mut self, io: Expr) -> SimValue { + let compiled_value = self.read_helper(io); + let mut bits = BitVec::repeat(false, compiled_value.layout.ty.bit_width()); + self.read_write_sim_value_helper( compiled_value, - 0, - bits.bits_mut(), - |_signed, bit_range, bits, value| { - ::copy_bits_from_bigint_wrapping(value, &mut bits[bit_range]); - }, - |_signed, bit_range, bits, value| { - let bytes = value.to_le_bytes(); - let bitslice = BitSlice::::from_slice(&bytes); - let bitslice = &bitslice[..bit_range.len()]; - bits[bit_range].clone_from_bitslice(bitslice); - }, - ); - SimValue::from_bits(Expr::ty(io), bits) - } - /// doesn't modify `bits` - fn value_changed( - state: &mut interpreter::State, - compiled_value: CompiledValue, - mut bits: &BitSlice, - ) -> bool { - assert_eq!(bits.len(), compiled_value.layout.ty.bit_width()); - let any_change = std::cell::Cell::new(false); - SimulationImpl::read_write_sim_value_helper( - state, - compiled_value, - 0, &mut bits, - |_signed, bit_range, bits, value| { - if !::bits_equal_bigint_wrapping(value, &bits[bit_range]) { - any_change.set(true); - } - }, - |_signed, bit_range, bits, value| { + |_signed, bits, value| ::copy_bits_from_bigint_wrapping(value, bits), + |_signed, bits, value| { let bytes = value.to_le_bytes(); let bitslice = BitSlice::::from_slice(&bytes); - let bitslice = &bitslice[..bit_range.len()]; - if bits[bit_range] != *bitslice { - any_change.set(true); - } + bits.clone_from_bitslice(&bitslice[..bits.len()]); }, ); - any_change.get() + SimValue { + ty: Expr::ty(io), + bits, + } } #[track_caller] - fn read( - &mut self, - io: Expr, - which_module: WhichModule, - ) -> ( - CompiledValue, - MaybeNeedsSettle>, - ) { - let compiled_value = self.get_module(which_module).read_helper(io, which_module); - let value = compiled_value - .map(|compiled_value| ReadFn { compiled_value, io }) - .apply_no_settle(&mut self.state); - let (MaybeNeedsSettle::NeedsSettle(compiled_value) - | MaybeNeedsSettle::NoSettleNeeded(compiled_value)) = compiled_value; - (compiled_value, value) - } - #[track_caller] - fn write( - &mut self, - io: Expr, - value: &SimValue, - which_module: WhichModule, - ) { - let compiled_value = self - .get_module_mut(which_module) - .write_helper(io, which_module); - self.state_ready_to_run = true; - assert_eq!(Expr::ty(io), SimValue::ty(value)); - Self::read_write_sim_value_helper( - &mut self.state, + fn write(&mut self, io: Expr, value: SimValue) { + let compiled_value = self.write_helper(io); + assert_eq!(Expr::ty(io), value.ty()); + self.read_write_sim_value_helper( compiled_value, - 0, - &mut value.bits().bits(), - |signed, bit_range, bits, value| { + &mut value.into_bits(), + |signed, bits, value| { if signed { - *value = SInt::bits_to_bigint(&bits[bit_range]); + *value = SInt::bits_to_bigint(bits); } else { - *value = UInt::bits_to_bigint(&bits[bit_range]); + *value = UInt::bits_to_bigint(bits); } }, - |signed, bit_range, bits, value| { + |signed, bits, value| { let mut small_value = [0; mem::size_of::()]; - if signed && bits[bit_range.clone()].last().as_deref().copied() == Some(true) { + if signed && bits.last().as_deref().copied() == Some(true) { small_value.fill(u8::MAX); } - small_value.view_bits_mut::()[0..bit_range.len()] - .clone_from_bitslice(&bits[bit_range]); + small_value.view_bits_mut::()[0..bits.len()].clone_from_bitslice(bits); *value = SmallUInt::from_le_bytes(small_value); }, ); } - #[track_caller] - fn settle_if_needed(this_ref: &Rc>, v: MaybeNeedsSettle) -> O - where - for<'a> F: MaybeNeedsSettleFn<&'a mut interpreter::State, Output = O>, - { - match v { - MaybeNeedsSettle::NeedsSettle(v) => { - Self::settle(this_ref); - v.call(&mut this_ref.borrow_mut().state) - } - MaybeNeedsSettle::NoSettleNeeded(v) => v, - } - } - async fn yield_settle_if_needed( - this_ref: &Rc>, - module_index: usize, - v: MaybeNeedsSettle, - ) -> O - where - for<'a> F: MaybeNeedsSettleFn<&'a mut interpreter::State, Output = O>, - { - match v { - MaybeNeedsSettle::NeedsSettle(v) => { - Self::yield_advance_time_or_settle(this_ref.clone(), module_index, None).await; - v.call(&mut this_ref.borrow_mut().state) - } - MaybeNeedsSettle::NoSettleNeeded(v) => v, - } - } fn close_all_trace_writers(&mut self) -> std::io::Result<()> { let trace_writers = mem::take(&mut self.trace_writers); let mut retval = Ok(()); @@ -7364,17 +7149,17 @@ impl SimulationImpl { self.trace_writers = trace_writers; retval } - fn close(this: Rc>) -> std::io::Result<()> { - if this.borrow().main_module.did_initial_settle { - Self::settle(&this); + fn close(mut self) -> std::io::Result<()> { + if self.made_initial_step { + self.settle(); } - this.borrow_mut().close_all_trace_writers() + self.close_all_trace_writers() } - fn flush_traces(this_ref: &Rc>) -> std::io::Result<()> { - if this_ref.borrow().main_module.did_initial_settle { - Self::settle(this_ref); + fn flush_traces(&mut self) -> std::io::Result<()> { + if self.made_initial_step { + self.settle(); } - this_ref.borrow_mut().for_each_trace_writer_getting_error( + self.for_each_trace_writer_getting_error( |this, trace_writer: TraceWriterState| match trace_writer { TraceWriterState::Decls(v) => { let mut v = v.write_decls( @@ -7408,7 +7193,7 @@ impl Drop for SimulationImpl { } pub struct Simulation { - sim_impl: Rc>, + sim_impl: SimulationImpl, io: Expr, } @@ -7455,117 +7240,24 @@ impl fmt::Debug for SortedMapDebug<'_, K, V> { impl fmt::Debug for Simulation { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { sim_impl, io } = self; - sim_impl.borrow().debug_fmt(Some(io), f) + sim_impl.debug_fmt(Some(io), f) } } -macro_rules! impl_simulation_methods { - ( - async_await = ($($async:tt, $await:tt)?), - track_caller = ($(#[$track_caller:tt])?), - which_module = |$self:ident| $which_module:expr, - ) => { - $(#[$track_caller])? - pub $($async)? fn read_bool_or_int(&mut $self, io: Expr) -> I::Value { - let retval = $self - .sim_impl - .borrow_mut() - .read_bool_or_int(io, $which_module); - $self.settle_if_needed(retval)$(.$await)? - } - $(#[$track_caller])? - pub $($async)? fn write_bool_or_int( - &mut $self, - io: Expr, - value: impl ToExpr, - ) { - let value = value.to_expr(); - assert_eq!(Expr::ty(io), Expr::ty(value), "type mismatch"); - let value = value - .to_literal_bits() - .expect("the value that is being written to an input must be a literal"); - $self.sim_impl.borrow_mut().write_bool_or_int( - io, - I::bits_to_value(Cow::Borrowed(&value)), - $which_module, - ); - } - $(#[$track_caller])? - pub $($async)? fn write_clock(&mut $self, io: Expr, value: bool) { - $self.sim_impl - .borrow_mut() - .write_bit(Expr::canonical(io), value, $which_module); - } - $(#[$track_caller])? - pub $($async)? fn read_clock(&mut $self, io: Expr) -> bool { - let retval = $self - .sim_impl - .borrow_mut() - .read_bit(Expr::canonical(io), $which_module); - $self.settle_if_needed(retval)$(.$await)? - } - $(#[$track_caller])? - pub $($async)? fn write_bool(&mut $self, io: Expr, value: bool) { - $self.sim_impl - .borrow_mut() - .write_bit(Expr::canonical(io), value, $which_module); - } - $(#[$track_caller])? - pub $($async)? fn read_bool(&mut $self, io: Expr) -> bool { - let retval = $self - .sim_impl - .borrow_mut() - .read_bit(Expr::canonical(io), $which_module); - $self.settle_if_needed(retval)$(.$await)? - } - $(#[$track_caller])? - pub $($async)? fn write_reset(&mut $self, io: Expr, value: bool) { - $self.sim_impl - .borrow_mut() - .write_bit(Expr::canonical(io), value, $which_module); - } - $(#[$track_caller])? - pub $($async)? fn read_reset(&mut $self, io: Expr) -> bool { - let retval = $self - .sim_impl - .borrow_mut() - .read_bit(Expr::canonical(io), $which_module); - $self.settle_if_needed(retval)$(.$await)? - } - $(#[$track_caller])? - pub $($async)? fn read(&mut $self, io: Expr) -> SimValue { - let retval = $self - .sim_impl - .borrow_mut() - .read(Expr::canonical(io), $which_module).1; - SimValue::from_canonical($self.settle_if_needed(retval)$(.$await)?) - } - $(#[$track_caller])? - pub $($async)? fn write>(&mut $self, io: Expr, value: V) { - $self.sim_impl.borrow_mut().write( - Expr::canonical(io), - &SimValue::into_canonical(value.into_sim_value_with_type(Expr::ty(io))), - $which_module, - ); - } - }; -} - impl Simulation { pub fn new(module: Interned>) -> Self { Self::from_compiled(Compiled::new(module)) } pub fn add_trace_writer(&mut self, writer: W) { self.sim_impl - .borrow_mut() .trace_writers .push(TraceWriterState::Decls(DynTraceWriterDecls::new(writer))); } pub fn flush_traces(&mut self) -> std::io::Result<()> { - SimulationImpl::flush_traces(&self.sim_impl) + self.sim_impl.flush_traces() } pub fn close(self) -> std::io::Result<()> { - SimulationImpl::close(self.sim_impl) + self.sim_impl.close() } pub fn canonical(self) -> Simulation { let Self { sim_impl, io } = self; @@ -7588,225 +7280,77 @@ impl Simulation { let sim_impl = SimulationImpl::new(compiled.canonical()); Self { io: Expr::from_bundle(sim_impl.io), - sim_impl: Rc::new(RefCell::new(sim_impl)), + sim_impl, } } #[track_caller] pub fn settle(&mut self) { - SimulationImpl::settle(&self.sim_impl); + self.sim_impl.settle(); } #[track_caller] pub fn advance_time(&mut self, duration: SimDuration) { - SimulationImpl::advance_time(&self.sim_impl, duration); + self.sim_impl.advance_time(duration); } #[track_caller] - fn settle_if_needed(&mut self, v: MaybeNeedsSettle) -> O - where - for<'a> F: MaybeNeedsSettleFn<&'a mut interpreter::State, Output = O>, - { - SimulationImpl::settle_if_needed(&self.sim_impl, v) + pub fn read_bool_or_int(&mut self, io: Expr) -> I::Value { + self.sim_impl.read_bool_or_int(io) + } + #[track_caller] + pub fn write_bool_or_int( + &mut self, + io: Expr, + value: impl ToExpr, + ) { + let value = value.to_expr(); + assert_eq!(Expr::ty(io), Expr::ty(value), "type mismatch"); + let value = value + .to_literal_bits() + .expect("the value that is being written to an input must be a literal"); + self.sim_impl + .write_bool_or_int(io, I::bits_to_value(Cow::Borrowed(&value))); + } + #[track_caller] + pub fn write_clock(&mut self, io: Expr, value: bool) { + self.sim_impl.write_bit(Expr::canonical(io), value); + } + #[track_caller] + pub fn read_clock(&mut self, io: Expr) -> bool { + self.sim_impl.read_bit(Expr::canonical(io)) + } + #[track_caller] + pub fn write_bool(&mut self, io: Expr, value: bool) { + self.sim_impl.write_bit(Expr::canonical(io), value); + } + #[track_caller] + pub fn read_bool(&mut self, io: Expr) -> bool { + self.sim_impl.read_bit(Expr::canonical(io)) + } + #[track_caller] + pub fn write_reset(&mut self, io: Expr, value: bool) { + self.sim_impl.write_bit(Expr::canonical(io), value); + } + #[track_caller] + pub fn read_reset(&mut self, io: Expr) -> bool { + self.sim_impl.read_bit(Expr::canonical(io)) + } + #[track_caller] + pub fn read(&mut self, io: Expr) -> SimValue { + SimValue::from_canonical(self.sim_impl.read(Expr::canonical(io))) + } + #[track_caller] + pub fn write>(&mut self, io: Expr, value: V) { + self.sim_impl.write( + Expr::canonical(io), + value.into_sim_value(Expr::ty(io)).into_canonical(), + ); } - impl_simulation_methods!( - async_await = (), - track_caller = (#[track_caller]), - which_module = |self| WhichModule::Main, - ); #[doc(hidden)] /// This is explicitly unstable and may be changed/removed at any time pub fn set_breakpoints_unstable(&mut self, pcs: HashSet, trace: bool) { - self.sim_impl.borrow_mut().breakpoints = Some(BreakpointsSet { + self.sim_impl.breakpoints = Some(BreakpointsSet { last_was_break: false, set: pcs, trace, }); } } - -pub struct ExternModuleSimulationState { - sim_impl: Rc>, - module_index: usize, - wait_for_changes_wait_targets: EarliestWaitTargets, -} - -impl fmt::Debug for ExternModuleSimulationState { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - sim_impl: _, - module_index, - wait_for_changes_wait_targets: _, - } = self; - f.debug_struct("ExternModuleSimulationState") - .field("sim_impl", &DebugAsDisplay("...")) - .field("module_index", module_index) - .finish_non_exhaustive() - } -} - -impl ExternModuleSimulationState { - pub async fn settle(&mut self) { - SimulationImpl::yield_advance_time_or_settle(self.sim_impl.clone(), self.module_index, None) - .await - } - pub async fn advance_time(&mut self, duration: SimDuration) { - SimulationImpl::yield_advance_time_or_settle( - self.sim_impl.clone(), - self.module_index, - Some(duration), - ) - .await - } - pub async fn wait_for_changes>( - &mut self, - iter: I, - timeout: Option, - ) { - self.wait_for_changes_wait_targets.clear(); - let which_module = WhichModule::Extern { - module_index: self.module_index, - }; - for io in iter { - let io = Expr::canonical(io.to_expr()); - let (key, value) = self.sim_impl.borrow_mut().read(io, which_module); - let value = self.settle_if_needed(value).await; - self.wait_for_changes_wait_targets - .insert(WaitTarget::Change { key, value }); - } - if let Some(timeout) = timeout { - self.wait_for_changes_wait_targets.instant = - Some(self.sim_impl.borrow().instant + timeout); - } - SimulationImpl::yield_wait( - self.sim_impl.clone(), - self.module_index, - &mut self.wait_for_changes_wait_targets, - ) - .await; - } - pub async fn wait_for_clock_edge(&mut self, clk: impl ToExpr) { - let clk = clk.to_expr(); - while self.read_clock(clk).await { - self.wait_for_changes([clk], None).await; - } - while !self.read_clock(clk).await { - self.wait_for_changes([clk], None).await; - } - } - async fn settle_if_needed(&mut self, v: MaybeNeedsSettle) -> O - where - for<'a> F: MaybeNeedsSettleFn<&'a mut interpreter::State, Output = O>, - { - SimulationImpl::yield_settle_if_needed(&self.sim_impl, self.module_index, v).await - } - impl_simulation_methods!( - async_await = (async, await), - track_caller = (), - which_module = |self| WhichModule::Extern { module_index: self.module_index }, - ); -} - -pub trait ExternModuleSimGenerator: Clone + Eq + Hash + Any + Send + Sync + fmt::Debug { - fn run<'a>(&'a self, sim: ExternModuleSimulationState) -> impl IntoFuture + 'a; -} - -pub struct SimGeneratorFn { - pub args: Args, - pub f: fn(Args, ExternModuleSimulationState) -> Fut, -} - -impl fmt::Debug for SimGeneratorFn { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { args, f: _ } = self; - f.debug_struct("SimGeneratorFn") - .field("args", args) - .field("f", &DebugAsDisplay("...")) - .finish() - } -} - -impl Hash for SimGeneratorFn { - fn hash(&self, state: &mut H) { - let Self { args, f } = self; - args.hash(state); - f.hash(state); - } -} - -impl Eq for SimGeneratorFn {} - -impl PartialEq for SimGeneratorFn { - fn eq(&self, other: &Self) -> bool { - let Self { args, f } = self; - *args == other.args && *f == other.f - } -} - -impl Clone for SimGeneratorFn { - fn clone(&self) -> Self { - Self { - args: self.args.clone(), - f: self.f, - } - } -} - -impl Copy for SimGeneratorFn {} - -impl< - T: fmt::Debug + Clone + Eq + Hash + Send + Sync + 'static, - Fut: IntoFuture + 'static, - > ExternModuleSimGenerator for SimGeneratorFn -{ - fn run<'a>(&'a self, sim: ExternModuleSimulationState) -> impl IntoFuture + 'a { - (self.f)(self.args.clone(), sim) - } -} - -trait DynExternModuleSimGenerator: Any + Send + Sync + SupportsPtrEqWithTypeId + fmt::Debug { - fn dyn_run<'a>(&'a self, sim: ExternModuleSimulationState) - -> Box + 'a>; -} - -impl DynExternModuleSimGenerator for T { - fn dyn_run<'a>( - &'a self, - sim: ExternModuleSimulationState, - ) -> Box + 'a> { - Box::new(self.run(sim).into_future()) - } -} - -impl InternedCompare for dyn DynExternModuleSimGenerator { - type InternedCompareKey = PtrEqWithTypeId; - - fn interned_compare_key_ref(this: &Self) -> Self::InternedCompareKey { - this.get_ptr_eq_with_type_id() - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub struct ExternModuleSimulation { - generator: Interned, - source_location: SourceLocation, -} - -impl ExternModuleSimulation { - pub fn new_with_loc( - source_location: SourceLocation, - generator: G, - ) -> Self { - Self { - generator: Interned::cast_unchecked( - generator.intern(), - |v| -> &dyn DynExternModuleSimGenerator { v }, - ), - source_location, - } - } - #[track_caller] - pub fn new(generator: G) -> Self { - Self::new_with_loc(SourceLocation::caller(), generator) - } - fn run(&self, sim: ExternModuleSimulationState) -> Box + 'static> { - Interned::into_inner(self.generator).dyn_run(sim) - } -} diff --git a/crates/fayalite/src/sim/interpreter.rs b/crates/fayalite/src/sim/interpreter.rs index de582f0..22f6f5f 100644 --- a/crates/fayalite/src/sim/interpreter.rs +++ b/crates/fayalite/src/sim/interpreter.rs @@ -7,9 +7,10 @@ use crate::{ intern::{Intern, Interned, Memoize}, source_location::SourceLocation, ty::CanonicalType, - util::{get_many_mut, HashMap, HashSet}, + util::get_many_mut, }; use bitvec::{boxed::BitBox, slice::BitSlice}; +use hashbrown::{HashMap, HashSet}; use num_bigint::BigInt; use num_traits::{One, Signed, ToPrimitive, Zero}; use std::{ diff --git a/crates/fayalite/src/sim/value.rs b/crates/fayalite/src/sim/value.rs deleted file mode 100644 index 8dace78..0000000 --- a/crates/fayalite/src/sim/value.rs +++ /dev/null @@ -1,913 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - array::{Array, ArrayType}, - bundle::{Bundle, BundleType}, - clock::Clock, - enum_::{Enum, EnumType}, - expr::{CastBitsTo, Expr, ToExpr}, - int::{Bool, IntType, KnownSize, SInt, SIntType, SIntValue, Size, UInt, UIntType, UIntValue}, - reset::{AsyncReset, Reset, SyncReset}, - ty::{CanonicalType, StaticType, Type}, - util::{ - alternating_cell::{AlternatingCell, AlternatingCellMethods}, - ConstUsize, - }, -}; -use bitvec::{slice::BitSlice, vec::BitVec}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::{ - fmt, - ops::{Deref, DerefMut}, - sync::Arc, -}; - -#[derive(Copy, Clone, Eq, PartialEq)] -enum ValidFlags { - BothValid = 0, - OnlyValueValid = 1, - OnlyBitsValid = 2, -} - -#[derive(Clone)] -struct SimValueInner { - value: T::SimValue, - bits: UIntValue, - valid_flags: ValidFlags, - ty: T, -} - -impl SimValueInner { - fn fill_bits(&mut self) { - match self.valid_flags { - ValidFlags::BothValid | ValidFlags::OnlyBitsValid => {} - ValidFlags::OnlyValueValid => { - self.ty.sim_value_to_bits(&self.value, self.bits.bits_mut()); - self.valid_flags = ValidFlags::BothValid; - } - } - } - fn into_bits(mut self) -> UIntValue { - self.fill_bits(); - self.bits - } - fn bits_mut(&mut self) -> &mut UIntValue { - self.fill_bits(); - self.valid_flags = ValidFlags::OnlyBitsValid; - &mut self.bits - } - fn fill_value(&mut self) { - match self.valid_flags { - ValidFlags::BothValid | ValidFlags::OnlyValueValid => {} - ValidFlags::OnlyBitsValid => { - self.ty - .sim_value_clone_from_bits(&mut self.value, self.bits.bits()); - self.valid_flags = ValidFlags::BothValid; - } - } - } - fn into_value(mut self) -> T::SimValue { - self.fill_value(); - self.value - } - fn value_mut(&mut self) -> &mut T::SimValue { - self.fill_value(); - self.valid_flags = ValidFlags::OnlyValueValid; - &mut self.value - } -} - -impl AlternatingCellMethods for SimValueInner { - fn unique_to_shared(&mut self) { - match self.valid_flags { - ValidFlags::BothValid => return, - ValidFlags::OnlyValueValid => { - self.ty.sim_value_to_bits(&self.value, self.bits.bits_mut()) - } - ValidFlags::OnlyBitsValid => self - .ty - .sim_value_clone_from_bits(&mut self.value, self.bits.bits()), - } - self.valid_flags = ValidFlags::BothValid; - } - - fn shared_to_unique(&mut self) {} -} - -#[derive(Serialize, Deserialize)] -#[serde(rename = "SimValue")] -#[serde(bound( - serialize = "T: Type + Serialize", - deserialize = "T: Type> + Deserialize<'de>" -))] -struct SerdeSimValue<'a, T: Type> { - ty: T, - value: std::borrow::Cow<'a, T::SimValue>, -} - -impl + Serialize> Serialize for SimValue { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - SerdeSimValue { - ty: SimValue::ty(self), - value: std::borrow::Cow::Borrowed(&*self), - } - .serialize(serializer) - } -} - -impl<'de, T: Type> + Deserialize<'de>> Deserialize<'de> for SimValue { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let SerdeSimValue { ty, value } = SerdeSimValue::::deserialize(deserializer)?; - Ok(SimValue::from_value(ty, value.into_owned())) - } -} - -pub struct SimValue { - inner: AlternatingCell>, -} - -impl Clone for SimValue { - fn clone(&self) -> Self { - Self { - inner: AlternatingCell::new_unique(self.inner.share().clone()), - } - } -} - -impl SimValue { - #[track_caller] - pub fn from_bits(ty: T, bits: UIntValue) -> Self { - assert_eq!(ty.canonical().bit_width(), bits.width()); - let inner = SimValueInner { - value: ty.sim_value_from_bits(bits.bits()), - bits, - valid_flags: ValidFlags::BothValid, - ty, - }; - Self { - inner: AlternatingCell::new_shared(inner), - } - } - #[track_caller] - pub fn from_bitslice(ty: T, bits: &BitSlice) -> Self { - Self::from_bits(ty, UIntValue::new(Arc::new(bits.to_bitvec()))) - } - pub fn from_value(ty: T, value: T::SimValue) -> Self { - let inner = SimValueInner { - bits: UIntValue::new_dyn(Arc::new(BitVec::repeat(false, ty.canonical().bit_width()))), - value, - valid_flags: ValidFlags::OnlyValueValid, - ty, - }; - Self { - inner: AlternatingCell::new_unique(inner), - } - } - pub fn ty(this: &Self) -> T { - this.inner.share().ty - } - pub fn into_bits(this: Self) -> UIntValue { - this.inner.into_inner().into_bits() - } - pub fn into_ty_and_bits(this: Self) -> (T, UIntValue) { - let inner = this.inner.into_inner(); - (inner.ty, inner.into_bits()) - } - pub fn bits(this: &Self) -> &UIntValue { - &this.inner.share().bits - } - pub fn bits_mut(this: &mut Self) -> &mut UIntValue { - this.inner.unique().bits_mut() - } - pub fn into_value(this: Self) -> T::SimValue { - this.inner.into_inner().into_value() - } - pub fn value(this: &Self) -> &T::SimValue { - &this.inner.share().value - } - pub fn value_mut(this: &mut Self) -> &mut T::SimValue { - this.inner.unique().value_mut() - } - #[track_caller] - pub fn from_canonical(v: SimValue) -> Self { - let (ty, bits) = SimValue::into_ty_and_bits(v); - Self::from_bits(T::from_canonical(ty), bits) - } - pub fn into_canonical(this: Self) -> SimValue { - let (ty, bits) = Self::into_ty_and_bits(this); - SimValue::from_bits(ty.canonical(), bits) - } - pub fn canonical(this: &Self) -> SimValue { - SimValue::from_bits(Self::ty(this).canonical(), Self::bits(this).clone()) - } - #[track_caller] - pub fn from_dyn_int(v: SimValue) -> Self - where - T: IntType, - { - let (ty, bits) = SimValue::into_ty_and_bits(v); - SimValue::from_bits(T::from_dyn_int(ty), bits) - } - pub fn into_dyn_int(this: Self) -> SimValue - where - T: IntType, - { - let (ty, bits) = Self::into_ty_and_bits(this); - SimValue::from_bits(ty.as_dyn_int(), bits) - } - pub fn to_dyn_int(this: &Self) -> SimValue - where - T: IntType, - { - SimValue::from_bits(Self::ty(this).as_dyn_int(), Self::bits(&this).clone()) - } - #[track_caller] - pub fn from_bundle(v: SimValue) -> Self - where - T: BundleType, - { - let (ty, bits) = SimValue::into_ty_and_bits(v); - SimValue::from_bits(T::from_canonical(CanonicalType::Bundle(ty)), bits) - } - pub fn into_bundle(this: Self) -> SimValue - where - T: BundleType, - { - let (ty, bits) = Self::into_ty_and_bits(this); - SimValue::from_bits(Bundle::from_canonical(ty.canonical()), bits) - } - pub fn to_bundle(this: &Self) -> SimValue - where - T: BundleType, - { - SimValue::from_bits( - Bundle::from_canonical(Self::ty(this).canonical()), - Self::bits(&this).clone(), - ) - } - #[track_caller] - pub fn from_enum(v: SimValue) -> Self - where - T: EnumType, - { - let (ty, bits) = SimValue::into_ty_and_bits(v); - SimValue::from_bits(T::from_canonical(CanonicalType::Enum(ty)), bits) - } - pub fn into_enum(this: Self) -> SimValue - where - T: EnumType, - { - let (ty, bits) = Self::into_ty_and_bits(this); - SimValue::from_bits(Enum::from_canonical(ty.canonical()), bits) - } - pub fn to_enum(this: &Self) -> SimValue - where - T: EnumType, - { - SimValue::from_bits( - Enum::from_canonical(Self::ty(this).canonical()), - Self::bits(&this).clone(), - ) - } -} - -impl Deref for SimValue { - type Target = T::SimValue; - - fn deref(&self) -> &Self::Target { - Self::value(self) - } -} - -impl DerefMut for SimValue { - fn deref_mut(&mut self) -> &mut Self::Target { - Self::value_mut(self) - } -} - -impl fmt::Debug for SimValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let inner = self.inner.share(); - f.debug_struct("SimValue") - .field("ty", &inner.ty) - .field("value", &inner.value) - .finish() - } -} - -impl ToExpr for SimValue { - type Type = T; - - #[track_caller] - fn to_expr(&self) -> Expr { - let inner = self.inner.share(); - inner.bits.cast_bits_to(inner.ty) - } -} - -pub trait SimValuePartialEq: Type { - #[track_caller] - fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool; -} - -impl, U: Type> PartialEq> for SimValue { - #[track_caller] - fn eq(&self, other: &SimValue) -> bool { - T::sim_value_eq(self, other) - } -} - -impl SimValuePartialEq for UIntType { - fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { - **this == **other - } -} - -impl SimValuePartialEq for SIntType { - fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { - **this == **other - } -} - -impl SimValuePartialEq for Bool { - fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { - **this == **other - } -} - -pub trait ToSimValue: ToSimValueWithType<::Type> { - type Type: Type; - - #[track_caller] - fn to_sim_value(&self) -> SimValue; - #[track_caller] - fn into_sim_value(self) -> SimValue - where - Self: Sized, - { - self.to_sim_value() - } - #[track_caller] - fn arc_into_sim_value(self: Arc) -> SimValue { - self.to_sim_value() - } - #[track_caller] - fn arc_to_sim_value(self: &Arc) -> SimValue { - self.to_sim_value() - } -} - -pub trait ToSimValueWithType { - #[track_caller] - fn to_sim_value_with_type(&self, ty: T) -> SimValue; - #[track_caller] - fn into_sim_value_with_type(self, ty: T) -> SimValue - where - Self: Sized, - { - self.to_sim_value_with_type(ty) - } - #[track_caller] - fn arc_into_sim_value_with_type(self: Arc, ty: T) -> SimValue { - self.to_sim_value_with_type(ty) - } - #[track_caller] - fn arc_to_sim_value_with_type(self: &Arc, ty: T) -> SimValue { - self.to_sim_value_with_type(ty) - } -} - -macro_rules! forward_to_sim_value_with_type { - ([$($generics:tt)*] $ty:ty) => { - impl<$($generics)*> ToSimValueWithType<::Type> for $ty { - fn to_sim_value_with_type(&self, ty: ::Type) -> SimValue<::Type> { - let retval = Self::to_sim_value(self); - assert_eq!(SimValue::ty(&retval), ty); - retval - } - #[track_caller] - fn into_sim_value_with_type(self, ty: ::Type) -> SimValue<::Type> - where - Self: Sized, - { - let retval = Self::into_sim_value(self); - assert_eq!(SimValue::ty(&retval), ty); - retval - } - #[track_caller] - fn arc_into_sim_value_with_type(self: Arc, ty: ::Type) -> SimValue<::Type> { - let retval = Self::arc_into_sim_value(self); - assert_eq!(SimValue::ty(&retval), ty); - retval - } - #[track_caller] - fn arc_to_sim_value_with_type(self: &Arc, ty: ::Type) -> SimValue<::Type> { - let retval = Self::arc_to_sim_value(self); - assert_eq!(SimValue::ty(&retval), ty); - retval - } - } - }; -} - -impl ToSimValue for SimValue { - type Type = T; - fn to_sim_value(&self) -> SimValue { - self.clone() - } - - fn into_sim_value(self) -> SimValue { - self - } -} - -forward_to_sim_value_with_type!([T: Type] SimValue); - -impl ToSimValueWithType for BitVec { - #[track_caller] - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - self.clone().into_sim_value_with_type(ty) - } - - #[track_caller] - fn into_sim_value_with_type(self, ty: T) -> SimValue { - Arc::new(self).arc_into_sim_value_with_type(ty) - } - - #[track_caller] - fn arc_into_sim_value_with_type(self: Arc, ty: T) -> SimValue { - SimValue::from_bits(ty, UIntValue::new_dyn(self)) - } - - #[track_caller] - fn arc_to_sim_value_with_type(self: &Arc, ty: T) -> SimValue { - SimValue::from_bits(ty, UIntValue::new_dyn(self.clone())) - } -} - -impl ToSimValueWithType for bitvec::boxed::BitBox { - #[track_caller] - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - self.clone().into_sim_value_with_type(ty) - } - - #[track_caller] - fn into_sim_value_with_type(self, ty: T) -> SimValue { - self.into_bitvec().into_sim_value_with_type(ty) - } -} - -impl ToSimValueWithType for BitSlice { - #[track_caller] - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - self.to_bitvec().into_sim_value_with_type(ty) - } -} - -impl ToSimValue for &'_ This { - type Type = This::Type; - - fn to_sim_value(&self) -> SimValue { - This::to_sim_value(self) - } -} - -impl, T: Type> ToSimValueWithType for &'_ This { - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - This::to_sim_value_with_type(self, ty) - } -} - -impl ToSimValue for &'_ mut This { - type Type = This::Type; - - fn to_sim_value(&self) -> SimValue { - This::to_sim_value(self) - } -} - -impl, T: Type> ToSimValueWithType for &'_ mut This { - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - This::to_sim_value_with_type(self, ty) - } -} - -impl ToSimValue for Arc { - type Type = This::Type; - - fn to_sim_value(&self) -> SimValue { - This::arc_to_sim_value(self) - } - fn into_sim_value(self) -> SimValue { - This::arc_into_sim_value(self) - } -} - -impl, T: Type> ToSimValueWithType for Arc { - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - This::arc_to_sim_value_with_type(self, ty) - } - fn into_sim_value_with_type(self, ty: T) -> SimValue { - This::arc_into_sim_value_with_type(self, ty) - } -} - -impl ToSimValue - for crate::intern::Interned -{ - type Type = This::Type; - fn to_sim_value(&self) -> SimValue { - This::to_sim_value(self) - } -} - -impl + Send + Sync + 'static, T: Type> ToSimValueWithType - for crate::intern::Interned -{ - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - This::to_sim_value_with_type(self, ty) - } -} - -impl ToSimValue for Box { - type Type = This::Type; - - fn to_sim_value(&self) -> SimValue { - This::to_sim_value(self) - } - fn into_sim_value(self) -> SimValue { - This::into_sim_value(*self) - } -} - -impl, T: Type> ToSimValueWithType for Box { - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - This::to_sim_value_with_type(self, ty) - } - fn into_sim_value_with_type(self, ty: T) -> SimValue { - This::into_sim_value_with_type(*self, ty) - } -} - -impl SimValue> { - #[track_caller] - pub fn from_array_elements>>( - ty: ArrayType, - elements: I, - ) -> Self { - let element_ty = ty.element(); - let elements = Vec::from_iter( - elements - .into_iter() - .map(|element| element.into_sim_value_with_type(element_ty)), - ); - assert_eq!(elements.len(), ty.len()); - SimValue::from_value(ty, elements.try_into().ok().expect("already checked len")) - } -} - -impl, T: Type> ToSimValueWithType> for [Element] { - #[track_caller] - fn to_sim_value_with_type(&self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } -} - -impl> ToSimValue for [Element] { - type Type = Array; - - #[track_caller] - fn to_sim_value(&self) -> SimValue { - SimValue::from_array_elements(ArrayType::new_dyn(StaticType::TYPE, self.len()), self) - } -} - -impl> ToSimValueWithType for [Element] { - #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_array_elements( - ::from_canonical(ty), - self, - )) - } -} - -impl, T: Type, const N: usize> ToSimValueWithType> - for [Element; N] -where - ConstUsize: KnownSize, -{ - #[track_caller] - fn to_sim_value_with_type(&self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } - #[track_caller] - fn into_sim_value_with_type(self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } -} - -impl, const N: usize> ToSimValue for [Element; N] -where - ConstUsize: KnownSize, -{ - type Type = Array; - - fn to_sim_value(&self) -> SimValue { - SimValue::from_array_elements(StaticType::TYPE, self) - } - - fn into_sim_value(self) -> SimValue { - SimValue::from_array_elements(StaticType::TYPE, self) - } -} - -impl, T: Type, const N: usize> ToSimValueWithType> - for [Element; N] -{ - #[track_caller] - fn to_sim_value_with_type(&self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } - #[track_caller] - fn into_sim_value_with_type(self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } -} - -impl, const N: usize> ToSimValueWithType - for [Element; N] -{ - #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_array_elements( - ::from_canonical(ty), - self, - )) - } - #[track_caller] - fn into_sim_value_with_type(self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_array_elements( - ::from_canonical(ty), - self, - )) - } -} - -impl, T: Type> ToSimValueWithType> for Vec { - #[track_caller] - fn to_sim_value_with_type(&self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } - #[track_caller] - fn into_sim_value_with_type(self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } -} - -impl> ToSimValue for Vec { - type Type = Array; - - fn to_sim_value(&self) -> SimValue { - SimValue::from_array_elements(ArrayType::new_dyn(StaticType::TYPE, self.len()), self) - } - - fn into_sim_value(self) -> SimValue { - SimValue::from_array_elements(ArrayType::new_dyn(StaticType::TYPE, self.len()), self) - } -} - -impl> ToSimValueWithType - for Vec -{ - #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_array_elements( - ::from_canonical(ty), - self, - )) - } - #[track_caller] - fn into_sim_value_with_type(self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_array_elements( - ::from_canonical(ty), - self, - )) - } -} - -impl, T: Type> ToSimValueWithType> for Box<[Element]> { - #[track_caller] - fn to_sim_value_with_type(&self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } - #[track_caller] - fn into_sim_value_with_type(self, ty: Array) -> SimValue> { - SimValue::from_array_elements(ty, self) - } -} - -impl> ToSimValue for Box<[Element]> { - type Type = Array; - - fn to_sim_value(&self) -> SimValue { - SimValue::from_array_elements(ArrayType::new_dyn(StaticType::TYPE, self.len()), self) - } - - fn into_sim_value(self) -> SimValue { - SimValue::from_array_elements(ArrayType::new_dyn(StaticType::TYPE, self.len()), self) - } -} - -impl> ToSimValueWithType - for Box<[Element]> -{ - #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_array_elements( - ::from_canonical(ty), - self, - )) - } - #[track_caller] - fn into_sim_value_with_type(self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical(SimValue::from_array_elements( - ::from_canonical(ty), - self, - )) - } -} - -impl ToSimValue for Expr { - type Type = T; - #[track_caller] - fn to_sim_value(&self) -> SimValue { - SimValue::from_bitslice( - Expr::ty(*self), - &crate::expr::ToLiteralBits::to_literal_bits(self) - .expect("must be a literal expression"), - ) - } -} - -forward_to_sim_value_with_type!([T: Type] Expr); - -macro_rules! impl_to_sim_value_for_bool_like { - ($ty:ident) => { - impl ToSimValueWithType<$ty> for bool { - fn to_sim_value_with_type(&self, ty: $ty) -> SimValue<$ty> { - SimValue::from_value(ty, *self) - } - } - }; -} - -impl ToSimValue for bool { - type Type = Bool; - - fn to_sim_value(&self) -> SimValue { - SimValue::from_value(Bool, *self) - } -} - -impl_to_sim_value_for_bool_like!(Bool); -impl_to_sim_value_for_bool_like!(AsyncReset); -impl_to_sim_value_for_bool_like!(SyncReset); -impl_to_sim_value_for_bool_like!(Reset); -impl_to_sim_value_for_bool_like!(Clock); - -impl ToSimValueWithType for bool { - #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - match ty { - CanonicalType::UInt(_) - | CanonicalType::SInt(_) - | CanonicalType::Array(_) - | CanonicalType::Enum(_) - | CanonicalType::Bundle(_) - | CanonicalType::PhantomConst(_) => { - panic!("can't create SimValue from bool: expected value of type: {ty:?}"); - } - CanonicalType::Bool(_) - | CanonicalType::AsyncReset(_) - | CanonicalType::SyncReset(_) - | CanonicalType::Reset(_) - | CanonicalType::Clock(_) => { - SimValue::from_bits(ty, UIntValue::new(Arc::new(BitVec::repeat(*self, 1)))) - } - } - } -} - -macro_rules! impl_to_sim_value_for_primitive_int { - ($prim:ident) => { - impl ToSimValue for $prim { - type Type = <$prim as ToExpr>::Type; - - #[track_caller] - fn to_sim_value( - &self, - ) -> SimValue { - SimValue::from_value(StaticType::TYPE, (*self).into()) - } - } - - forward_to_sim_value_with_type!([] $prim); - - impl ToSimValueWithType<<<$prim as ToExpr>::Type as IntType>::Dyn> for $prim { - #[track_caller] - fn to_sim_value_with_type( - &self, - ty: <<$prim as ToExpr>::Type as IntType>::Dyn, - ) -> SimValue<<<$prim as ToExpr>::Type as IntType>::Dyn> { - SimValue::from_value( - ty, - <<$prim as ToExpr>::Type as Type>::SimValue::from(*self).as_dyn_int(), - ) - } - } - - impl ToSimValueWithType for $prim { - #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - let ty: <<$prim as ToExpr>::Type as IntType>::Dyn = Type::from_canonical(ty); - SimValue::into_canonical(self.to_sim_value_with_type(ty)) - } - } - }; -} - -impl_to_sim_value_for_primitive_int!(u8); -impl_to_sim_value_for_primitive_int!(u16); -impl_to_sim_value_for_primitive_int!(u32); -impl_to_sim_value_for_primitive_int!(u64); -impl_to_sim_value_for_primitive_int!(u128); -impl_to_sim_value_for_primitive_int!(usize); -impl_to_sim_value_for_primitive_int!(i8); -impl_to_sim_value_for_primitive_int!(i16); -impl_to_sim_value_for_primitive_int!(i32); -impl_to_sim_value_for_primitive_int!(i64); -impl_to_sim_value_for_primitive_int!(i128); -impl_to_sim_value_for_primitive_int!(isize); - -macro_rules! impl_to_sim_value_for_int_value { - ($IntValue:ident, $Int:ident, $IntType:ident) => { - impl ToSimValue for $IntValue { - type Type = $IntType; - - 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 ToSimValueWithType<$IntType> for $IntValue { - fn to_sim_value_with_type(&self, ty: $IntType) -> SimValue<$IntType> { - SimValue::from_value(ty, self.clone()) - } - - fn into_sim_value_with_type(self, ty: $IntType) -> SimValue<$IntType> { - SimValue::from_value(ty, self) - } - } - - impl ToSimValueWithType<$Int> for $IntValue { - fn to_sim_value_with_type(&self, ty: $Int) -> SimValue<$Int> { - self.bits().to_sim_value_with_type(ty) - } - - fn into_sim_value_with_type(self, ty: $Int) -> SimValue<$Int> { - self.into_bits().into_sim_value_with_type(ty) - } - } - - impl ToSimValueWithType for $IntValue { - #[track_caller] - fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical( - self.to_sim_value_with_type($IntType::::from_canonical(ty)), - ) - } - - #[track_caller] - fn into_sim_value_with_type(self, ty: CanonicalType) -> SimValue { - SimValue::into_canonical( - self.into_sim_value_with_type($IntType::::from_canonical(ty)), - ) - } - } - }; -} - -impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType); -impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType); diff --git a/crates/fayalite/src/sim/vcd.rs b/crates/fayalite/src/sim/vcd.rs index fcf6743..fde30be 100644 --- a/crates/fayalite/src/sim/vcd.rs +++ b/crates/fayalite/src/sim/vcd.rs @@ -14,10 +14,9 @@ use crate::{ TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, TraceScope, TraceSyncReset, TraceUInt, TraceWire, TraceWriter, TraceWriterDecls, }, - util::HashMap, }; use bitvec::{order::Lsb0, slice::BitSlice}; -use hashbrown::hash_map::Entry; +use hashbrown::{hash_map::Entry, HashMap}; use std::{ fmt::{self, Write as _}, io, mem, diff --git a/crates/fayalite/src/source_location.rs b/crates/fayalite/src/source_location.rs index 1a168b1..d143f22 100644 --- a/crates/fayalite/src/source_location.rs +++ b/crates/fayalite/src/source_location.rs @@ -2,8 +2,9 @@ // See Notices.txt for copyright information use crate::{ intern::{Intern, Interned}, - util::{DebugAsDisplay, HashMap}, + util::DebugAsDisplay, }; +use hashbrown::HashMap; use std::{cell::RefCell, fmt, num::NonZeroUsize, panic, path::Path}; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -96,7 +97,7 @@ impl NormalizeFilesForTestsState { fn new() -> Self { Self { test_position: panic::Location::caller(), - file_pattern_matches: HashMap::default(), + file_pattern_matches: HashMap::new(), } } } @@ -142,7 +143,7 @@ impl From<&'_ panic::Location<'_>> for SourceLocation { map.entry_ref(file) .or_insert_with(|| NormalizedFileForTestState { file_name_id: NonZeroUsize::new(len + 1).unwrap(), - positions_map: HashMap::default(), + positions_map: HashMap::new(), }); file_str = m.generate_file_name(file_state.file_name_id); file = &file_str; diff --git a/crates/fayalite/src/testing.rs b/crates/fayalite/src/testing.rs index b81bc3f..4517e34 100644 --- a/crates/fayalite/src/testing.rs +++ b/crates/fayalite/src/testing.rs @@ -3,9 +3,9 @@ use crate::{ cli::{FormalArgs, FormalMode, FormalOutput, RunPhase}, firrtl::ExportOptions, - util::HashMap, }; use clap::Parser; +use hashbrown::HashMap; use serde::Deserialize; use std::{ fmt::Write, @@ -87,7 +87,7 @@ fn get_assert_formal_target_path(test_name: &dyn std::fmt::Display) -> PathBuf { let index = *DIRS .lock() .unwrap() - .get_or_insert_with(HashMap::default) + .get_or_insert_with(HashMap::new) .entry_ref(&dir) .and_modify(|v| *v += 1) .or_insert(0); diff --git a/crates/fayalite/src/ty.rs b/crates/fayalite/src/ty.rs index 8f41c5c..69080c9 100644 --- a/crates/fayalite/src/ty.rs +++ b/crates/fayalite/src/ty.rs @@ -7,19 +7,12 @@ use crate::{ clock::Clock, enum_::Enum, expr::Expr, - int::{Bool, SInt, UInt, UIntValue}, + int::{Bool, SInt, UInt}, intern::{Intern, Interned}, - phantom_const::PhantomConst, reset::{AsyncReset, Reset, SyncReset}, - sim::value::{SimValue, ToSimValueWithType}, source_location::SourceLocation, - util::ConstUsize, }; -use bitvec::slice::BitSlice; -use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize, Serializer}; -use std::{fmt, hash::Hash, iter::FusedIterator, ops::Index, sync::Arc}; - -pub(crate) mod serde_impls; +use std::{fmt, hash::Hash, iter::FusedIterator, ops::Index}; #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] #[non_exhaustive] @@ -42,7 +35,6 @@ pub enum CanonicalType { SyncReset(SyncReset), Reset(Reset), Clock(Clock), - PhantomConst(PhantomConst), } impl fmt::Debug for CanonicalType { @@ -58,29 +50,10 @@ impl fmt::Debug for CanonicalType { Self::SyncReset(v) => v.fmt(f), Self::Reset(v) => v.fmt(f), Self::Clock(v) => v.fmt(f), - Self::PhantomConst(v) => v.fmt(f), } } } -impl Serialize for CanonicalType { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serde_impls::SerdeCanonicalType::from(*self).serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for CanonicalType { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - Ok(serde_impls::SerdeCanonicalType::deserialize(deserializer)?.into()) - } -} - impl CanonicalType { pub fn type_properties(self) -> TypeProperties { match self { @@ -94,7 +67,6 @@ impl CanonicalType { CanonicalType::SyncReset(v) => v.type_properties(), CanonicalType::Reset(v) => v.type_properties(), CanonicalType::Clock(v) => v.type_properties(), - CanonicalType::PhantomConst(v) => v.type_properties(), } } pub fn is_passive(self) -> bool { @@ -171,17 +143,8 @@ impl CanonicalType { }; lhs.can_connect(rhs) } - CanonicalType::PhantomConst(lhs) => { - let CanonicalType::PhantomConst(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() - } } pub trait MatchVariantAndInactiveScope: Sized { @@ -203,7 +166,7 @@ impl MatchVariantAndInactiveScope for MatchVariantWith } pub trait FillInDefaultedGenerics { - type Type; + type Type: Type; fn fill_in_defaulted_generics(self) -> Self::Type; } @@ -215,22 +178,6 @@ impl FillInDefaultedGenerics for T { } } -impl FillInDefaultedGenerics for usize { - type Type = usize; - - fn fill_in_defaulted_generics(self) -> Self::Type { - self - } -} - -impl FillInDefaultedGenerics for ConstUsize { - type Type = ConstUsize; - - fn fill_in_defaulted_generics(self) -> Self::Type { - self - } -} - mod sealed { pub trait TypeOrDefaultSealed {} pub trait BaseTypeSealed {} @@ -248,34 +195,6 @@ macro_rules! impl_base_type { }; } -macro_rules! impl_base_type_serde { - ($name:ident, $expected:literal) => { - impl Serialize for $name { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.canonical().serialize(serializer) - } - } - - impl<'de> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - match CanonicalType::deserialize(deserializer)? { - CanonicalType::$name(retval) => Ok(retval), - ty => Err(serde::de::Error::invalid_value( - serde::de::Unexpected::Other(ty.as_serde_unexpected_str()), - &$expected, - )), - } - } - } - }; -} - impl_base_type!(UInt); impl_base_type!(SInt); impl_base_type!(Bool); @@ -286,15 +205,6 @@ impl_base_type!(AsyncReset); impl_base_type!(SyncReset); impl_base_type!(Reset); impl_base_type!(Clock); -impl_base_type!(PhantomConst); - -impl_base_type_serde!(Bool, "a Bool"); -impl_base_type_serde!(Enum, "an Enum"); -impl_base_type_serde!(Bundle, "a Bundle"); -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 sealed::BaseTypeSealed for CanonicalType {} @@ -330,7 +240,6 @@ pub trait Type: { type BaseType: BaseType; type MaskType: Type; - type SimValue: fmt::Debug + Clone + 'static + ToSimValueWithType; type MatchVariant: 'static + Send + Sync; type MatchActiveScope; type MatchVariantAndInactiveScope: MatchVariantAndInactiveScope< @@ -348,22 +257,9 @@ pub trait Type: fn canonical(&self) -> CanonicalType; fn from_canonical(canonical_type: CanonicalType) -> Self; fn source_location() -> SourceLocation; - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue; - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice); - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice); } -pub trait BaseType: - Type< - BaseType = Self, - MaskType: Serialize + DeserializeOwned, - SimValue: Serialize + DeserializeOwned, - > + sealed::BaseTypeSealed - + Into - + Serialize - + DeserializeOwned -{ -} +pub trait BaseType: Type + sealed::BaseTypeSealed + Into {} macro_rules! impl_match_variant_as_self { () => { @@ -390,7 +286,6 @@ pub trait TypeWithDeref: Type { impl Type for CanonicalType { type BaseType = CanonicalType; type MaskType = CanonicalType; - type SimValue = OpaqueSimValue; impl_match_variant_as_self!(); fn mask_type(&self) -> Self::MaskType { match self { @@ -404,7 +299,6 @@ impl Type for CanonicalType { CanonicalType::SyncReset(v) => v.mask_type().canonical(), CanonicalType::Reset(v) => v.mask_type().canonical(), CanonicalType::Clock(v) => v.mask_type().canonical(), - CanonicalType::PhantomConst(v) => v.mask_type().canonical(), } } fn canonical(&self) -> CanonicalType { @@ -416,60 +310,9 @@ impl Type for CanonicalType { fn source_location() -> SourceLocation { SourceLocation::builtin() } - fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue { - assert_eq!(bits.len(), self.bit_width()); - OpaqueSimValue::from_bitslice(bits) - } - fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) { - assert_eq!(bits.len(), self.bit_width()); - assert_eq!(value.bit_width(), self.bit_width()); - value.bits_mut().bits_mut().copy_from_bitslice(bits); - } - fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) { - assert_eq!(bits.len(), self.bit_width()); - assert_eq!(value.bit_width(), self.bit_width()); - bits.copy_from_bitslice(value.bits().bits()); - } } -#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] -pub struct OpaqueSimValue { - bits: UIntValue, -} - -impl OpaqueSimValue { - pub fn bit_width(&self) -> usize { - self.bits.width() - } - pub fn bits(&self) -> &UIntValue { - &self.bits - } - pub fn bits_mut(&mut self) -> &mut UIntValue { - &mut self.bits - } - pub fn into_bits(self) -> UIntValue { - self.bits - } - pub fn from_bits(bits: UIntValue) -> Self { - Self { bits } - } - pub fn from_bitslice(v: &BitSlice) -> Self { - Self { - bits: UIntValue::new(Arc::new(v.to_bitvec())), - } - } -} - -impl> ToSimValueWithType for OpaqueSimValue { - fn to_sim_value_with_type(&self, ty: T) -> SimValue { - SimValue::from_value(ty, self.clone()) - } - fn into_sim_value_with_type(self, ty: T) -> SimValue { - SimValue::from_value(ty, self) - } -} - -pub trait StaticType: Type + Default { +pub trait StaticType: Type { const TYPE: Self; const MASK_TYPE: Self::MaskType; const TYPE_PROPERTIES: TypeProperties; diff --git a/crates/fayalite/src/ty/serde_impls.rs b/crates/fayalite/src/ty/serde_impls.rs deleted file mode 100644 index 2ea4362..0000000 --- a/crates/fayalite/src/ty/serde_impls.rs +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - array::Array, - bundle::{Bundle, BundleType}, - clock::Clock, - enum_::{Enum, EnumType}, - int::{Bool, SInt, UInt}, - intern::Interned, - phantom_const::{PhantomConstCanonicalValue, PhantomConstValue}, - prelude::PhantomConst, - reset::{AsyncReset, Reset, SyncReset}, - ty::{BaseType, CanonicalType}, -}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -pub(crate) struct SerdePhantomConst(pub T); - -impl Serialize for SerdePhantomConst> { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.0.serialize(serializer) - } -} - -impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for SerdePhantomConst> { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - T::deserialize_value(deserializer).map(Self) - } -} - -#[derive(Serialize, Deserialize)] -#[serde(rename = "CanonicalType")] -pub(crate) enum SerdeCanonicalType< - ArrayElement = CanonicalType, - ThePhantomConst = SerdePhantomConst>, -> { - UInt { - width: usize, - }, - SInt { - width: usize, - }, - Bool, - Array { - element: ArrayElement, - len: usize, - }, - Enum { - variants: Interned<[crate::enum_::EnumVariant]>, - }, - Bundle { - fields: Interned<[crate::bundle::BundleField]>, - }, - AsyncReset, - SyncReset, - Reset, - Clock, - PhantomConst(ThePhantomConst), -} - -impl SerdeCanonicalType { - pub(crate) fn as_serde_unexpected_str(&self) -> &'static str { - match self { - Self::UInt { .. } => "a UInt", - Self::SInt { .. } => "a SInt", - Self::Bool => "a Bool", - Self::Array { .. } => "an Array", - Self::Enum { .. } => "an Enum", - Self::Bundle { .. } => "a Bundle", - Self::AsyncReset => "an AsyncReset", - Self::SyncReset => "a SyncReset", - Self::Reset => "a Reset", - Self::Clock => "a Clock", - Self::PhantomConst(_) => "a PhantomConst", - } - } -} - -impl From for SerdeCanonicalType { - fn from(ty: T) -> Self { - let ty: CanonicalType = ty.into(); - match ty { - CanonicalType::UInt(ty) => Self::UInt { width: ty.width() }, - CanonicalType::SInt(ty) => Self::SInt { width: ty.width() }, - CanonicalType::Bool(Bool {}) => Self::Bool, - CanonicalType::Array(ty) => Self::Array { - element: ty.element(), - len: ty.len(), - }, - CanonicalType::Enum(ty) => Self::Enum { - variants: ty.variants(), - }, - CanonicalType::Bundle(ty) => Self::Bundle { - fields: ty.fields(), - }, - CanonicalType::AsyncReset(AsyncReset {}) => Self::AsyncReset, - CanonicalType::SyncReset(SyncReset {}) => Self::SyncReset, - CanonicalType::Reset(Reset {}) => Self::Reset, - CanonicalType::Clock(Clock {}) => Self::Clock, - CanonicalType::PhantomConst(ty) => Self::PhantomConst(SerdePhantomConst(ty.get())), - } - } -} - -impl From for CanonicalType { - fn from(ty: SerdeCanonicalType) -> Self { - match ty { - SerdeCanonicalType::UInt { width } => Self::UInt(UInt::new(width)), - SerdeCanonicalType::SInt { width } => Self::SInt(SInt::new(width)), - SerdeCanonicalType::Bool => Self::Bool(Bool), - SerdeCanonicalType::Array { element, len } => Self::Array(Array::new(element, len)), - SerdeCanonicalType::Enum { variants } => Self::Enum(Enum::new(variants)), - SerdeCanonicalType::Bundle { fields } => Self::Bundle(Bundle::new(fields)), - SerdeCanonicalType::AsyncReset => Self::AsyncReset(AsyncReset), - SerdeCanonicalType::SyncReset => Self::SyncReset(SyncReset), - SerdeCanonicalType::Reset => Self::Reset(Reset), - SerdeCanonicalType::Clock => Self::Clock(Clock), - SerdeCanonicalType::PhantomConst(value) => { - Self::PhantomConst(PhantomConst::new(value.0)) - } - } - } -} diff --git a/crates/fayalite/src/util.rs b/crates/fayalite/src/util.rs index 233867e..fadc7af 100644 --- a/crates/fayalite/src/util.rs +++ b/crates/fayalite/src/util.rs @@ -1,23 +1,12 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information -pub(crate) mod alternating_cell; mod const_bool; mod const_cmp; mod const_usize; mod misc; mod scoped_ref; pub(crate) mod streaming_read_utf8; -mod test_hasher; - -// allow easily switching the hasher crate-wide for testing -#[cfg(feature = "unstable-test-hasher")] -pub type DefaultBuildHasher = test_hasher::DefaultBuildHasher; -#[cfg(not(feature = "unstable-test-hasher"))] -pub(crate) type DefaultBuildHasher = hashbrown::DefaultHashBuilder; - -pub(crate) type HashMap = hashbrown::HashMap; -pub(crate) type HashSet = hashbrown::HashSet; #[doc(inline)] pub use const_bool::{ConstBool, ConstBoolDispatch, ConstBoolDispatchTag, GenericConstBool}; @@ -40,5 +29,4 @@ pub use misc::{ }; pub mod job_server; -pub mod prefix_sum; pub mod ready_valid; diff --git a/crates/fayalite/src/util/alternating_cell.rs b/crates/fayalite/src/util/alternating_cell.rs deleted file mode 100644 index 17e06a6..0000000 --- a/crates/fayalite/src/util/alternating_cell.rs +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::util::DebugAsDisplay; -use std::{ - cell::{Cell, UnsafeCell}, - fmt, -}; - -pub(crate) trait AlternatingCellMethods { - fn unique_to_shared(&mut self); - fn shared_to_unique(&mut self); -} - -#[derive(Copy, Clone, Debug)] -enum State { - Unique, - Shared, - Locked, -} - -pub(crate) struct AlternatingCell { - state: Cell, - value: UnsafeCell, -} - -impl fmt::Debug for AlternatingCell { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("AlternatingCell") - .field( - self.try_share() - .as_ref() - .map(|v| -> &dyn fmt::Debug { v }) - .unwrap_or(&DebugAsDisplay("<...>")), - ) - .finish() - } -} - -impl AlternatingCell { - pub(crate) const fn new_shared(value: T) -> Self - where - T: Sized, - { - Self { - state: Cell::new(State::Shared), - value: UnsafeCell::new(value), - } - } - pub(crate) const fn new_unique(value: T) -> Self - where - T: Sized, - { - Self { - state: Cell::new(State::Unique), - value: UnsafeCell::new(value), - } - } - pub(crate) fn is_unique(&self) -> bool { - matches!(self.state.get(), State::Unique) - } - pub(crate) fn is_shared(&self) -> bool { - matches!(self.state.get(), State::Shared) - } - pub(crate) fn into_inner(self) -> T - where - T: Sized, - { - self.value.into_inner() - } - pub(crate) fn try_share(&self) -> Option<&T> - where - T: AlternatingCellMethods, - { - match self.state.get() { - State::Shared => {} - State::Unique => { - struct Locked<'a>(&'a Cell); - impl Drop for Locked<'_> { - fn drop(&mut self) { - self.0.set(State::Shared); - } - } - self.state.set(State::Locked); - let lock = Locked(&self.state); - // Safety: state is Locked, so nothing else will - // access value while calling unique_to_shared. - unsafe { &mut *self.value.get() }.unique_to_shared(); - drop(lock); - } - State::Locked => return None, - } - - // Safety: state is Shared so nothing will create any mutable - // references until the returned reference's lifetime expires. - Some(unsafe { &*self.value.get() }) - } - #[track_caller] - pub(crate) fn share(&self) -> &T - where - T: AlternatingCellMethods, - { - let Some(retval) = self.try_share() else { - panic!("`share` called recursively"); - }; - retval - } - pub(crate) fn unique(&mut self) -> &mut T - where - T: AlternatingCellMethods, - { - match self.state.get() { - State::Shared => { - self.state.set(State::Unique); - self.value.get_mut().shared_to_unique(); - } - State::Unique => {} - State::Locked => unreachable!(), - } - self.value.get_mut() - } -} diff --git a/crates/fayalite/src/util/const_bool.rs b/crates/fayalite/src/util/const_bool.rs index 7def3b5..7033d6a 100644 --- a/crates/fayalite/src/util/const_bool.rs +++ b/crates/fayalite/src/util/const_bool.rs @@ -1,9 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information -use serde::{ - de::{DeserializeOwned, Error, Unexpected}, - Deserialize, Deserializer, Serialize, Serializer, -}; use std::{fmt::Debug, hash::Hash, mem::ManuallyDrop, ptr}; mod sealed { @@ -13,17 +9,7 @@ mod sealed { /// # Safety /// the only implementation is `ConstBool` pub unsafe trait GenericConstBool: - sealed::Sealed - + Copy - + Ord - + Hash - + Default - + Debug - + 'static - + Send - + Sync - + Serialize - + DeserializeOwned + sealed::Sealed + Copy + Ord + Hash + Default + Debug + 'static + Send + Sync { const VALUE: bool; } @@ -44,32 +30,6 @@ unsafe impl GenericConstBool for ConstBool { const VALUE: bool = VALUE; } -impl Serialize for ConstBool { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - VALUE.serialize(serializer) - } -} - -impl<'de, const VALUE: bool> Deserialize<'de> for ConstBool { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let value = bool::deserialize(deserializer)?; - if value == VALUE { - Ok(ConstBool) - } else { - Err(D::Error::invalid_value( - Unexpected::Bool(value), - &if VALUE { "true" } else { "false" }, - )) - } - } -} - pub trait ConstBoolDispatchTag { type Type; } diff --git a/crates/fayalite/src/util/const_usize.rs b/crates/fayalite/src/util/const_usize.rs index e098a12..a605336 100644 --- a/crates/fayalite/src/util/const_usize.rs +++ b/crates/fayalite/src/util/const_usize.rs @@ -1,9 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information -use serde::{ - de::{DeserializeOwned, Error, Unexpected}, - Deserialize, Deserializer, Serialize, Serializer, -}; use std::{fmt::Debug, hash::Hash}; mod sealed { @@ -12,17 +8,7 @@ mod sealed { /// the only implementation is `ConstUsize` pub trait GenericConstUsize: - sealed::Sealed - + Copy - + Ord - + Hash - + Default - + Debug - + 'static - + Send - + Sync - + Serialize - + DeserializeOwned + sealed::Sealed + Copy + Ord + Hash + Default + Debug + 'static + Send + Sync { const VALUE: usize; } @@ -41,29 +27,3 @@ impl sealed::Sealed for ConstUsize {} impl GenericConstUsize for ConstUsize { const VALUE: usize = VALUE; } - -impl Serialize for ConstUsize { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - VALUE.serialize(serializer) - } -} - -impl<'de, const VALUE: usize> Deserialize<'de> for ConstUsize { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let value = usize::deserialize(deserializer)?; - if value == VALUE { - Ok(ConstUsize) - } else { - Err(D::Error::invalid_value( - Unexpected::Unsigned(value as u64), - &&*VALUE.to_string(), - )) - } - } -} diff --git a/crates/fayalite/src/util/prefix_sum.rs b/crates/fayalite/src/util/prefix_sum.rs deleted file mode 100644 index 98e6d95..0000000 --- a/crates/fayalite/src/util/prefix_sum.rs +++ /dev/null @@ -1,839 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -// code derived from: -// https://web.archive.org/web/20250303054010/https://git.libre-soc.org/?p=nmutil.git;a=blob;f=src/nmutil/prefix_sum.py;hb=effeb28e5848392adddcdad1f6e7a098f2a44c9c - -use crate::intern::{Intern, Interned, Memoize}; -use std::{borrow::Cow, num::NonZeroUsize}; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct PrefixSumOp { - pub lhs_index: usize, - pub rhs_and_dest_index: NonZeroUsize, - pub row: u32, -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -#[non_exhaustive] -pub struct DiagramConfig { - pub space: Cow<'static, str>, - pub vertical_bar: Cow<'static, str>, - pub plus: Cow<'static, str>, - pub slant: Cow<'static, str>, - pub connect: Cow<'static, str>, - pub no_connect: Cow<'static, str>, - pub padding: usize, -} - -impl DiagramConfig { - pub const fn new() -> Self { - Self { - space: Cow::Borrowed(" "), - vertical_bar: Cow::Borrowed("|"), - plus: Cow::Borrowed("\u{2295}"), // ⊕ - slant: Cow::Borrowed(r"\"), - connect: Cow::Borrowed("\u{25CF}"), // ● - no_connect: Cow::Borrowed("X"), - padding: 1, - } - } - pub fn draw(self, ops: impl IntoIterator, item_count: usize) -> String { - #[derive(Copy, Clone, Debug)] - struct DiagramCell { - slant: bool, - plus: bool, - tee: bool, - } - let mut ops_by_row: Vec> = Vec::new(); - let mut last_row = 0; - ops.into_iter().for_each(|op| { - assert!( - op.lhs_index < op.rhs_and_dest_index.get(), - "invalid PrefixSumOp! lhs_index must be less \ - than rhs_and_dest_index: {op:?}", - ); - assert!( - op.row >= last_row, - "invalid PrefixSumOp! row must \ - not decrease (row last was: {last_row}): {op:?}", - ); - let ops = if op.row > last_row || ops_by_row.is_empty() { - ops_by_row.push(vec![]); - ops_by_row.last_mut().expect("just pushed") - } else { - ops_by_row - .last_mut() - .expect("just checked if ops_by_row is empty") - }; - if let Some(last) = ops.last() { - assert!( - op.rhs_and_dest_index < last.rhs_and_dest_index, - "invalid PrefixSumOp! rhs_and_dest_index must strictly \ - decrease in a row:\nthis op: {op:?}\nlast op: {last:?}", - ); - } - ops.push(op); - last_row = op.row; - }); - let blank_row = || { - vec![ - DiagramCell { - slant: false, - plus: false, - tee: false - }; - item_count - ] - }; - let mut cells = vec![blank_row()]; - for ops in ops_by_row { - let max_distance = ops - .iter() - .map( - |&PrefixSumOp { - lhs_index, - rhs_and_dest_index, - .. - }| { rhs_and_dest_index.get() - lhs_index }, - ) - .max() - .expect("ops is known to be non-empty"); - cells.extend((0..max_distance).map(|_| blank_row())); - for op in ops { - let mut y = cells.len() - 1; - assert!( - op.rhs_and_dest_index.get() < item_count, - "invalid PrefixSumOp! rhs_and_dest_index must be \ - less than item_count ({item_count}): {op:?}", - ); - let mut x = op.rhs_and_dest_index.get(); - cells[y][x].plus = true; - x -= 1; - y -= 1; - while op.lhs_index < x { - cells[y][x].slant = true; - x -= 1; - y -= 1; - } - cells[y][x].tee = true; - } - } - let mut retval = String::new(); - let mut row_text = vec![String::new(); 2 * self.padding + 1]; - for cells_row in cells { - for cell in cells_row { - // top padding - for y in 0..self.padding { - // top left padding - for x in 0..self.padding { - row_text[y] += if x == y && (cell.plus || cell.slant) { - &self.slant - } else { - &self.space - }; - } - // top vertical bar - row_text[y] += &self.vertical_bar; - // top right padding - for _ in 0..self.padding { - row_text[y] += &self.space; - } - } - // center left padding - for _ in 0..self.padding { - row_text[self.padding] += &self.space; - } - // center - row_text[self.padding] += if cell.plus { - &self.plus - } else if cell.tee { - &self.connect - } else if cell.slant { - &self.no_connect - } else { - &self.vertical_bar - }; - // center right padding - for _ in 0..self.padding { - row_text[self.padding] += &self.space; - } - let bottom_padding_start = self.padding + 1; - let bottom_padding_last = self.padding * 2; - // bottom padding - for y in bottom_padding_start..=bottom_padding_last { - // bottom left padding - for _ in 0..self.padding { - row_text[y] += &self.space; - } - // bottom vertical bar - row_text[y] += &self.vertical_bar; - // bottom right padding - for x in bottom_padding_start..=bottom_padding_last { - row_text[y] += if x == y && (cell.tee || cell.slant) { - &self.slant - } else { - &self.space - }; - } - } - } - for line in &mut row_text { - retval += line.trim_end(); - retval += "\n"; - line.clear(); - } - } - retval - } -} - -impl Default for DiagramConfig { - fn default() -> Self { - Self::new() - } -} - -impl PrefixSumOp { - pub fn diagram(ops: impl IntoIterator, item_count: usize) -> String { - Self::diagram_with_config(ops, item_count, DiagramConfig::new()) - } - pub fn diagram_with_config( - ops: impl IntoIterator, - item_count: usize, - config: DiagramConfig, - ) -> String { - config.draw(ops, item_count) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub enum PrefixSumAlgorithm { - /// Uses the algorithm from: - /// - LowLatency, - /// Uses the algorithm from: - /// - WorkEfficient, -} - -impl PrefixSumAlgorithm { - fn ops_impl(self, item_count: usize) -> Vec { - let mut retval = Vec::new(); - let mut distance = 1; - let mut row = 0; - while distance < item_count { - let double_distance = distance - .checked_mul(2) - .expect("prefix-sum item_count is too big"); - let (start, step) = match self { - Self::LowLatency => (distance, 1), - Self::WorkEfficient => (double_distance - 1, double_distance), - }; - for rhs_and_dest_index in (start..item_count).step_by(step).rev() { - let Some(rhs_and_dest_index) = NonZeroUsize::new(rhs_and_dest_index) else { - unreachable!(); - }; - let lhs_index = rhs_and_dest_index.get() - distance; - retval.push(PrefixSumOp { - lhs_index, - rhs_and_dest_index, - row, - }); - } - distance = double_distance; - row += 1; - } - match self { - Self::LowLatency => {} - Self::WorkEfficient => { - distance /= 2; - while distance >= 1 { - let start = distance - .checked_mul(3) - .expect("prefix-sum item_count is too big") - - 1; - for rhs_and_dest_index in (start..item_count).step_by(distance * 2).rev() { - let Some(rhs_and_dest_index) = NonZeroUsize::new(rhs_and_dest_index) else { - unreachable!(); - }; - let lhs_index = rhs_and_dest_index.get() - distance; - retval.push(PrefixSumOp { - lhs_index, - rhs_and_dest_index, - row, - }); - } - row += 1; - distance /= 2; - } - } - } - retval - } - pub fn ops(self, item_count: usize) -> Interned<[PrefixSumOp]> { - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] - struct MyMemoize(PrefixSumAlgorithm); - impl Memoize for MyMemoize { - type Input = usize; - type InputOwned = usize; - type Output = Interned<[PrefixSumOp]>; - - fn inner(self, item_count: &Self::Input) -> Self::Output { - Intern::intern_owned(self.0.ops_impl(*item_count)) - } - } - MyMemoize(self).get_owned(item_count) - } - pub fn run(self, items: impl IntoIterator, f: impl FnMut(&T, &T) -> T) -> Vec { - let mut items = Vec::from_iter(items); - self.run_on_slice(&mut items, f); - items - } - pub fn run_on_slice(self, items: &mut [T], mut f: impl FnMut(&T, &T) -> T) -> &mut [T] { - self.ops(items.len()).into_iter().for_each( - |PrefixSumOp { - lhs_index, - rhs_and_dest_index, - row: _, - }| { - items[rhs_and_dest_index.get()] = - f(&items[lhs_index], &items[rhs_and_dest_index.get()]); - }, - ); - items - } - pub fn filtered_ops( - self, - item_live_out_flags: impl IntoIterator, - ) -> Vec { - let mut item_live_out_flags = Vec::from_iter(item_live_out_flags); - let prefix_sum_ops = self.ops(item_live_out_flags.len()); - let mut ops_live_flags = vec![false; prefix_sum_ops.len()]; - for ( - op_index, - &PrefixSumOp { - lhs_index, - rhs_and_dest_index, - row: _, - }, - ) in prefix_sum_ops.iter().enumerate().rev() - { - let live = item_live_out_flags[rhs_and_dest_index.get()]; - item_live_out_flags[lhs_index] |= live; - ops_live_flags[op_index] = live; - } - prefix_sum_ops - .into_iter() - .zip(ops_live_flags) - .filter_map(|(op, live)| live.then_some(op)) - .collect() - } - pub fn reduce_ops(self, item_count: usize) -> Interned<[PrefixSumOp]> { - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] - struct MyMemoize(PrefixSumAlgorithm); - impl Memoize for MyMemoize { - type Input = usize; - type InputOwned = usize; - type Output = Interned<[PrefixSumOp]>; - - fn inner(self, item_count: &Self::Input) -> Self::Output { - let mut item_live_out_flags = vec![false; *item_count]; - let Some(last_item_live_out_flag) = item_live_out_flags.last_mut() else { - return Interned::default(); - }; - *last_item_live_out_flag = true; - Intern::intern_owned(self.0.filtered_ops(item_live_out_flags)) - } - } - MyMemoize(self).get_owned(item_count) - } -} - -pub fn reduce_ops(item_count: usize) -> Interned<[PrefixSumOp]> { - PrefixSumAlgorithm::LowLatency.reduce_ops(item_count) -} - -pub fn reduce(items: impl IntoIterator, mut f: impl FnMut(T, T) -> T) -> Option { - let mut items: Vec<_> = items.into_iter().map(Some).collect(); - for op in reduce_ops(items.len()) { - let (Some(lhs), Some(rhs)) = ( - items[op.lhs_index].take(), - items[op.rhs_and_dest_index.get()].take(), - ) else { - unreachable!(); - }; - items[op.rhs_and_dest_index.get()] = Some(f(lhs, rhs)); - } - items.last_mut().and_then(Option::take) -} - -#[cfg(test)] -mod tests { - use super::*; - - fn input_strings() -> [String; 9] { - std::array::from_fn(|i| String::from_utf8(vec![b'a' + i as u8]).unwrap()) - } - - #[test] - fn test_prefix_sum_strings() { - let input = input_strings(); - let expected: Vec = input - .iter() - .scan(String::new(), |l, r| { - *l += r; - Some(l.clone()) - }) - .collect(); - println!("expected: {expected:?}"); - assert_eq!( - *PrefixSumAlgorithm::WorkEfficient - .run_on_slice(&mut input.clone(), |l, r| l.to_string() + r), - *expected - ); - assert_eq!( - *PrefixSumAlgorithm::LowLatency - .run_on_slice(&mut input.clone(), |l, r| l.to_string() + r), - *expected - ); - } - - #[test] - fn test_reduce_string() { - let input = input_strings(); - let expected = input.clone().into_iter().reduce(|l, r| l + &r); - assert_eq!(reduce(input, |l, r| l + &r), expected); - } - - fn op(lhs_index: usize, rhs_and_dest_index: usize, row: u32) -> PrefixSumOp { - PrefixSumOp { - lhs_index, - rhs_and_dest_index: NonZeroUsize::new(rhs_and_dest_index).expect("should be non-zero"), - row, - } - } - - #[test] - fn test_reduce_ops_9() { - let expected = vec![ - op(7, 8, 0), - op(5, 6, 0), - op(3, 4, 0), - op(1, 2, 0), - op(6, 8, 1), - op(2, 4, 1), - op(4, 8, 2), - op(0, 8, 3), - ]; - println!("expected: {expected:#?}"); - let ops = reduce_ops(9); - println!("ops: {ops:#?}"); - assert_eq!(*ops, *expected); - } - - #[test] - fn test_reduce_ops_8() { - let expected = vec![ - op(6, 7, 0), - op(4, 5, 0), - op(2, 3, 0), - op(0, 1, 0), - op(5, 7, 1), - op(1, 3, 1), - op(3, 7, 2), - ]; - println!("expected: {expected:#?}"); - let ops = reduce_ops(8); - println!("ops: {ops:#?}"); - assert_eq!(*ops, *expected); - } - - #[test] - fn test_count_ones() { - for width in 0..=10u32 { - for v in 0..1u32 << width { - let expected = v.count_ones(); - assert_eq!( - reduce((0..width).map(|i| (v >> i) & 1), |l, r| l + r).unwrap_or(0), - expected, - "v={v:#X}" - ); - } - } - } - - #[track_caller] - fn test_diagram(ops: impl IntoIterator, item_count: usize, expected: &str) { - let text = PrefixSumOp::diagram_with_config( - ops, - item_count, - DiagramConfig { - plus: Cow::Borrowed("@"), - ..Default::default() - }, - ); - println!("text:\n{text}\n"); - assert_eq!(text, expected); - } - - #[test] - fn test_work_efficient_diagram_16() { - let item_count = 16; - test_diagram( - PrefixSumAlgorithm::WorkEfficient.ops(item_count), - item_count, - &r" - | | | | | | | | | | | | | | | | - ● | ● | ● | ● | ● | ● | ● | ● | - |\ | |\ | |\ | |\ | |\ | |\ | |\ | |\ | - | \| | \| | \| | \| | \| | \| | \| | \| - | @ | @ | @ | @ | @ | @ | @ | @ - | |\ | | | |\ | | | |\ | | | |\ | | - | | \| | | | \| | | | \| | | | \| | - | | X | | | X | | | X | | | X | - | | |\ | | | |\ | | | |\ | | | |\ | - | | | \| | | | \| | | | \| | | | \| - | | | @ | | | @ | | | @ | | | @ - | | | |\ | | | | | | | |\ | | | | - | | | | \| | | | | | | | \| | | | - | | | | X | | | | | | | X | | | - | | | | |\ | | | | | | | |\ | | | - | | | | | \| | | | | | | | \| | | - | | | | | X | | | | | | | X | | - | | | | | |\ | | | | | | | |\ | | - | | | | | | \| | | | | | | | \| | - | | | | | | X | | | | | | | X | - | | | | | | |\ | | | | | | | |\ | - | | | | | | | \| | | | | | | | \| - | | | | | | | @ | | | | | | | @ - | | | | | | | |\ | | | | | | | | - | | | | | | | | \| | | | | | | | - | | | | | | | | X | | | | | | | - | | | | | | | | |\ | | | | | | | - | | | | | | | | | \| | | | | | | - | | | | | | | | | X | | | | | | - | | | | | | | | | |\ | | | | | | - | | | | | | | | | | \| | | | | | - | | | | | | | | | | X | | | | | - | | | | | | | | | | |\ | | | | | - | | | | | | | | | | | \| | | | | - | | | | | | | | | | | X | | | | - | | | | | | | | | | | |\ | | | | - | | | | | | | | | | | | \| | | | - | | | | | | | | | | | | X | | | - | | | | | | | | | | | | |\ | | | - | | | | | | | | | | | | | \| | | - | | | | | | | | | | | | | X | | - | | | | | | | | | | | | | |\ | | - | | | | | | | | | | | | | | \| | - | | | | | | | | | | | | | | X | - | | | | | | | | | | | | | | |\ | - | | | | | | | | | | | | | | | \| - | | | | | | | ● | | | | | | | @ - | | | | | | | |\ | | | | | | | | - | | | | | | | | \| | | | | | | | - | | | | | | | | X | | | | | | | - | | | | | | | | |\ | | | | | | | - | | | | | | | | | \| | | | | | | - | | | | | | | | | X | | | | | | - | | | | | | | | | |\ | | | | | | - | | | | | | | | | | \| | | | | | - | | | | | | | | | | X | | | | | - | | | | | | | | | | |\ | | | | | - | | | | | | | | | | | \| | | | | - | | | ● | | | ● | | | @ | | | | - | | | |\ | | | |\ | | | |\ | | | | - | | | | \| | | | \| | | | \| | | | - | | | | X | | | X | | | X | | | - | | | | |\ | | | |\ | | | |\ | | | - | | | | | \| | | | \| | | | \| | | - | ● | ● | @ | ● | @ | ● | @ | | - | |\ | |\ | |\ | |\ | |\ | |\ | |\ | | - | | \| | \| | \| | \| | \| | \| | \| | - | | @ | @ | @ | @ | @ | @ | @ | - | | | | | | | | | | | | | | | | -"[1..], // trim newline at start - ); - } - - #[test] - fn test_low_latency_diagram_16() { - let item_count = 16; - test_diagram( - PrefixSumAlgorithm::LowLatency.ops(item_count), - item_count, - &r" - | | | | | | | | | | | | | | | | - ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● | - |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ | - | \| \| \| \| \| \| \| \| \| \| \| \| \| \| \| - ● @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ - |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ | | - | \| \| \| \| \| \| \| \| \| \| \| \| \| \| | - | X X X X X X X X X X X X X X | - | |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ | - | | \| \| \| \| \| \| \| \| \| \| \| \| \| \| - ● ● @ @ @ @ @ @ @ @ @ @ @ @ @ @ - |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ | | | | - | \| \| \| \| \| \| \| \| \| \| \| \| | | | - | X X X X X X X X X X X X | | | - | |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ | | | - | | \| \| \| \| \| \| \| \| \| \| \| \| | | - | | X X X X X X X X X X X X | | - | | |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ | | - | | | \| \| \| \| \| \| \| \| \| \| \| \| | - | | | X X X X X X X X X X X X | - | | | |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ |\ | - | | | | \| \| \| \| \| \| \| \| \| \| \| \| - ● ● ● ● @ @ @ @ @ @ @ @ @ @ @ @ - |\ |\ |\ |\ |\ |\ |\ |\ | | | | | | | | - | \| \| \| \| \| \| \| \| | | | | | | | - | X X X X X X X X | | | | | | | - | |\ |\ |\ |\ |\ |\ |\ |\ | | | | | | | - | | \| \| \| \| \| \| \| \| | | | | | | - | | X X X X X X X X | | | | | | - | | |\ |\ |\ |\ |\ |\ |\ |\ | | | | | | - | | | \| \| \| \| \| \| \| \| | | | | | - | | | X X X X X X X X | | | | | - | | | |\ |\ |\ |\ |\ |\ |\ |\ | | | | | - | | | | \| \| \| \| \| \| \| \| | | | | - | | | | X X X X X X X X | | | | - | | | | |\ |\ |\ |\ |\ |\ |\ |\ | | | | - | | | | | \| \| \| \| \| \| \| \| | | | - | | | | | X X X X X X X X | | | - | | | | | |\ |\ |\ |\ |\ |\ |\ |\ | | | - | | | | | | \| \| \| \| \| \| \| \| | | - | | | | | | X X X X X X X X | | - | | | | | | |\ |\ |\ |\ |\ |\ |\ |\ | | - | | | | | | | \| \| \| \| \| \| \| \| | - | | | | | | | X X X X X X X X | - | | | | | | | |\ |\ |\ |\ |\ |\ |\ |\ | - | | | | | | | | \| \| \| \| \| \| \| \| - | | | | | | | | @ @ @ @ @ @ @ @ - | | | | | | | | | | | | | | | | -"[1..], // trim newline at start - ); - } - - #[test] - fn test_work_efficient_diagram_9() { - let item_count = 9; - test_diagram( - PrefixSumAlgorithm::WorkEfficient.ops(item_count), - item_count, - &r" - | | | | | | | | | - ● | ● | ● | ● | | - |\ | |\ | |\ | |\ | | - | \| | \| | \| | \| | - | @ | @ | @ | @ | - | |\ | | | |\ | | | - | | \| | | | \| | | - | | X | | | X | | - | | |\ | | | |\ | | - | | | \| | | | \| | - | | | @ | | | @ | - | | | |\ | | | | | - | | | | \| | | | | - | | | | X | | | | - | | | | |\ | | | | - | | | | | \| | | | - | | | | | X | | | - | | | | | |\ | | | - | | | | | | \| | | - | | | | | | X | | - | | | | | | |\ | | - | | | | | | | \| | - | | | ● | | | @ | - | | | |\ | | | | | - | | | | \| | | | | - | | | | X | | | | - | | | | |\ | | | | - | | | | | \| | | | - | ● | ● | @ | ● | - | |\ | |\ | |\ | |\ | - | | \| | \| | \| | \| - | | @ | @ | @ | @ - | | | | | | | | | -"[1..], // trim newline at start - ); - } - - #[test] - fn test_low_latency_diagram_9() { - let item_count = 9; - test_diagram( - PrefixSumAlgorithm::LowLatency.ops(item_count), - item_count, - &r" - | | | | | | | | | - ● ● ● ● ● ● ● ● | - |\ |\ |\ |\ |\ |\ |\ |\ | - | \| \| \| \| \| \| \| \| - ● @ @ @ @ @ @ @ @ - |\ |\ |\ |\ |\ |\ |\ | | - | \| \| \| \| \| \| \| | - | X X X X X X X | - | |\ |\ |\ |\ |\ |\ |\ | - | | \| \| \| \| \| \| \| - ● ● @ @ @ @ @ @ @ - |\ |\ |\ |\ |\ | | | | - | \| \| \| \| \| | | | - | X X X X X | | | - | |\ |\ |\ |\ |\ | | | - | | \| \| \| \| \| | | - | | X X X X X | | - | | |\ |\ |\ |\ |\ | | - | | | \| \| \| \| \| | - | | | X X X X X | - | | | |\ |\ |\ |\ |\ | - | | | | \| \| \| \| \| - ● | | | @ @ @ @ @ - |\ | | | | | | | | - | \| | | | | | | | - | X | | | | | | | - | |\ | | | | | | | - | | \| | | | | | | - | | X | | | | | | - | | |\ | | | | | | - | | | \| | | | | | - | | | X | | | | | - | | | |\ | | | | | - | | | | \| | | | | - | | | | X | | | | - | | | | |\ | | | | - | | | | | \| | | | - | | | | | X | | | - | | | | | |\ | | | - | | | | | | \| | | - | | | | | | X | | - | | | | | | |\ | | - | | | | | | | \| | - | | | | | | | X | - | | | | | | | |\ | - | | | | | | | | \| - | | | | | | | | @ - | | | | | | | | | -"[1..], // trim newline at start - ); - } - - #[test] - fn test_reduce_diagram_16() { - let item_count = 16; - test_diagram( - reduce_ops(item_count), - item_count, - &r" - | | | | | | | | | | | | | | | | - ● | ● | ● | ● | ● | ● | ● | ● | - |\ | |\ | |\ | |\ | |\ | |\ | |\ | |\ | - | \| | \| | \| | \| | \| | \| | \| | \| - | @ | @ | @ | @ | @ | @ | @ | @ - | |\ | | | |\ | | | |\ | | | |\ | | - | | \| | | | \| | | | \| | | | \| | - | | X | | | X | | | X | | | X | - | | |\ | | | |\ | | | |\ | | | |\ | - | | | \| | | | \| | | | \| | | | \| - | | | @ | | | @ | | | @ | | | @ - | | | |\ | | | | | | | |\ | | | | - | | | | \| | | | | | | | \| | | | - | | | | X | | | | | | | X | | | - | | | | |\ | | | | | | | |\ | | | - | | | | | \| | | | | | | | \| | | - | | | | | X | | | | | | | X | | - | | | | | |\ | | | | | | | |\ | | - | | | | | | \| | | | | | | | \| | - | | | | | | X | | | | | | | X | - | | | | | | |\ | | | | | | | |\ | - | | | | | | | \| | | | | | | | \| - | | | | | | | @ | | | | | | | @ - | | | | | | | |\ | | | | | | | | - | | | | | | | | \| | | | | | | | - | | | | | | | | X | | | | | | | - | | | | | | | | |\ | | | | | | | - | | | | | | | | | \| | | | | | | - | | | | | | | | | X | | | | | | - | | | | | | | | | |\ | | | | | | - | | | | | | | | | | \| | | | | | - | | | | | | | | | | X | | | | | - | | | | | | | | | | |\ | | | | | - | | | | | | | | | | | \| | | | | - | | | | | | | | | | | X | | | | - | | | | | | | | | | | |\ | | | | - | | | | | | | | | | | | \| | | | - | | | | | | | | | | | | X | | | - | | | | | | | | | | | | |\ | | | - | | | | | | | | | | | | | \| | | - | | | | | | | | | | | | | X | | - | | | | | | | | | | | | | |\ | | - | | | | | | | | | | | | | | \| | - | | | | | | | | | | | | | | X | - | | | | | | | | | | | | | | |\ | - | | | | | | | | | | | | | | | \| - | | | | | | | | | | | | | | | @ - | | | | | | | | | | | | | | | | -"[1..], // trim newline at start - ); - } - - #[test] - fn test_reduce_diagram_9() { - let item_count = 9; - test_diagram( - reduce_ops(item_count), - item_count, - &r" - | | | | | | | | | - | ● | ● | ● | ● | - | |\ | |\ | |\ | |\ | - | | \| | \| | \| | \| - | | @ | @ | @ | @ - | | |\ | | | |\ | | - | | | \| | | | \| | - | | | X | | | X | - | | | |\ | | | |\ | - | | | | \| | | | \| - | | | | @ | | | @ - | | | | |\ | | | | - | | | | | \| | | | - | | | | | X | | | - | | | | | |\ | | | - | | | | | | \| | | - | | | | | | X | | - | | | | | | |\ | | - | | | | | | | \| | - | | | | | | | X | - | | | | | | | |\ | - | | | | | | | | \| - ● | | | | | | | @ - |\ | | | | | | | | - | \| | | | | | | | - | X | | | | | | | - | |\ | | | | | | | - | | \| | | | | | | - | | X | | | | | | - | | |\ | | | | | | - | | | \| | | | | | - | | | X | | | | | - | | | |\ | | | | | - | | | | \| | | | | - | | | | X | | | | - | | | | |\ | | | | - | | | | | \| | | | - | | | | | X | | | - | | | | | |\ | | | - | | | | | | \| | | - | | | | | | X | | - | | | | | | |\ | | - | | | | | | | \| | - | | | | | | | X | - | | | | | | | |\ | - | | | | | | | | \| - | | | | | | | | @ - | | | | | | | | | -"[1..], // trim newline at start - ); - } -} diff --git a/crates/fayalite/src/util/test_hasher.rs b/crates/fayalite/src/util/test_hasher.rs deleted file mode 100644 index 20df5b7..0000000 --- a/crates/fayalite/src/util/test_hasher.rs +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information -#![cfg(feature = "unstable-test-hasher")] - -use std::{ - fmt::Write as _, - hash::{BuildHasher, Hash, Hasher}, - io::Write as _, - marker::PhantomData, - sync::LazyLock, -}; - -type BoxDynHasher = Box; -type BoxDynBuildHasher = Box; -type BoxDynMakeBuildHasher = Box BoxDynBuildHasher + Send + Sync>; - -trait TryGetDynBuildHasher: Copy { - type Type; - fn try_get_make_build_hasher(self) -> Option; -} - -impl TryGetDynBuildHasher for PhantomData { - type Type = T; - fn try_get_make_build_hasher(self) -> Option { - None - } -} - -impl + Send + Sync + 'static + Clone> - TryGetDynBuildHasher for &'_ PhantomData -{ - type Type = T; - fn try_get_make_build_hasher(self) -> Option { - Some(Box::new(|| Box::>::default())) - } -} - -#[derive(Default, Clone)] -struct DynBuildHasher(T); - -trait DynBuildHasherTrait: BuildHasher { - fn clone_dyn_build_hasher(&self) -> BoxDynBuildHasher; -} - -impl> BuildHasher for DynBuildHasher { - type Hasher = BoxDynHasher; - - fn build_hasher(&self) -> Self::Hasher { - Box::new(self.0.build_hasher()) - } - - fn hash_one(&self, x: T) -> u64 { - self.0.hash_one(x) - } -} - -impl DynBuildHasherTrait for DynBuildHasher -where - Self: Clone + BuildHasher + Send + Sync + 'static, -{ - fn clone_dyn_build_hasher(&self) -> BoxDynBuildHasher { - Box::new(self.clone()) - } -} - -pub struct DefaultBuildHasher(BoxDynBuildHasher); - -impl Clone for DefaultBuildHasher { - fn clone(&self) -> Self { - DefaultBuildHasher(self.0.clone_dyn_build_hasher()) - } -} - -const ENV_VAR_NAME: &'static str = "FAYALITE_TEST_HASHER"; - -struct EnvVarValue { - key: &'static str, - try_get_make_build_hasher: fn() -> Option, - description: &'static str, -} - -macro_rules! env_var_value { - ( - key: $key:literal, - build_hasher: $build_hasher:ty, - description: $description:literal, - ) => { - EnvVarValue { - key: $key, - try_get_make_build_hasher: || { - // use rust method resolution to detect if $build_hasher is usable - // (e.g. hashbrown's hasher won't be usable without the right feature enabled) - (&PhantomData::>).try_get_make_build_hasher() - }, - description: $description, - } - }; -} - -#[derive(Default)] -struct AlwaysZeroHasher; - -impl Hasher for AlwaysZeroHasher { - fn write(&mut self, _bytes: &[u8]) {} - fn finish(&self) -> u64 { - 0 - } -} - -const ENV_VAR_VALUES: &'static [EnvVarValue] = &[ - env_var_value! { - key: "std", - build_hasher: std::hash::RandomState, - description: "use std::hash::RandomState", - }, - env_var_value! { - key: "hashbrown", - build_hasher: hashbrown::DefaultHashBuilder, - description: "use hashbrown's DefaultHashBuilder", - }, - env_var_value! { - key: "always_zero", - build_hasher: std::hash::BuildHasherDefault, - description: "use a hasher that always returns 0 for all hashes,\n \ - this is useful for checking that PartialEq impls are correct", - }, -]; - -fn report_bad_env_var(msg: impl std::fmt::Display) -> ! { - let mut msg = format!("{ENV_VAR_NAME}: {msg}\n"); - for &EnvVarValue { - key, - try_get_make_build_hasher, - description, - } in ENV_VAR_VALUES - { - let availability = match try_get_make_build_hasher() { - Some(_) => "available", - None => "unavailable", - }; - writeln!(msg, "{key}: ({availability})\n {description}").expect("can't fail"); - } - std::io::stderr() - .write_all(msg.as_bytes()) - .expect("should be able to write to stderr"); - std::process::abort(); -} - -impl Default for DefaultBuildHasher { - fn default() -> Self { - static DEFAULT_FN: LazyLock = LazyLock::new(|| { - let var = std::env::var_os(ENV_VAR_NAME); - let var = var.as_deref().unwrap_or("std".as_ref()); - for &EnvVarValue { - key, - try_get_make_build_hasher, - description: _, - } in ENV_VAR_VALUES - { - if var.as_encoded_bytes().eq_ignore_ascii_case(key.as_bytes()) { - return try_get_make_build_hasher().unwrap_or_else(|| { - report_bad_env_var(format_args!( - "unavailable hasher: {key} (is the appropriate feature enabled?)" - )); - }); - } - } - report_bad_env_var(format_args!("unrecognized hasher: {var:?}")); - }); - Self(DEFAULT_FN()) - } -} - -pub struct DefaultHasher(BoxDynHasher); - -impl BuildHasher for DefaultBuildHasher { - type Hasher = DefaultHasher; - - fn build_hasher(&self) -> Self::Hasher { - DefaultHasher(self.0.build_hasher()) - } -} - -impl Hasher for DefaultHasher { - fn finish(&self) -> u64 { - self.0.finish() - } - - fn write(&mut self, bytes: &[u8]) { - self.0.write(bytes) - } - - fn write_u8(&mut self, i: u8) { - self.0.write_u8(i) - } - - fn write_u16(&mut self, i: u16) { - self.0.write_u16(i) - } - - fn write_u32(&mut self, i: u32) { - self.0.write_u32(i) - } - - fn write_u64(&mut self, i: u64) { - self.0.write_u64(i) - } - - fn write_u128(&mut self, i: u128) { - self.0.write_u128(i) - } - - fn write_usize(&mut self, i: usize) { - self.0.write_usize(i) - } - - fn write_i8(&mut self, i: i8) { - self.0.write_i8(i) - } - - fn write_i16(&mut self, i: i16) { - self.0.write_i16(i) - } - - fn write_i32(&mut self, i: i32) { - self.0.write_i32(i) - } - - fn write_i64(&mut self, i: i64) { - self.0.write_i64(i) - } - - fn write_i128(&mut self, i: i128) { - self.0.write_i128(i) - } - - fn write_isize(&mut self, i: isize) { - self.0.write_isize(i) - } -} diff --git a/crates/fayalite/tests/hdl_types.rs b/crates/fayalite/tests/hdl_types.rs index 8802fd4..b191016 100644 --- a/crates/fayalite/tests/hdl_types.rs +++ b/crates/fayalite/tests/hdl_types.rs @@ -4,17 +4,11 @@ use fayalite::{ bundle::BundleType, enum_::EnumType, int::{BoolOrIntType, IntType}, - phantom_const::PhantomConst, prelude::*, ty::StaticType, }; use std::marker::PhantomData; -#[hdl(outline_generated)] -pub struct MyConstSize { - pub size: PhantomConst>, -} - #[hdl(outline_generated)] pub struct S { pub a: T, diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index c2dc24e..49f5689 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -1,13 +1,8 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information use fayalite::{ - assert_export_firrtl, - firrtl::ExportOptions, - int::{UIntInRange, UIntInRangeInclusive}, - intern::Intern, - module::transform::simplify_enums::SimplifyEnumsKind, - prelude::*, - reset::ResetType, + assert_export_firrtl, firrtl::ExportOptions, intern::Intern, + module::transform::simplify_enums::SimplifyEnumsKind, prelude::*, reset::ResetType, ty::StaticType, }; use serde_json::json; @@ -196,14 +191,10 @@ circuit check_array_repeat: }; } -pub trait UnknownTrait {} - -impl UnknownTrait for T {} - #[hdl_module(outline_generated)] pub fn check_skipped_generics(v: U) where - T: StaticType + UnknownTrait, + T: StaticType, ConstUsize: KnownSize, U: std::fmt::Display, { @@ -385,18 +376,18 @@ circuit check_written_inside_both_if_else: }; } -#[hdl(outline_generated, cmp_eq)] +#[hdl(outline_generated)] pub struct TestStruct { pub a: T, pub b: UInt<8>, } -#[hdl(outline_generated, cmp_eq)] +#[hdl(outline_generated)] pub struct TestStruct2 { pub v: UInt<8>, } -#[hdl(outline_generated, cmp_eq)] +#[hdl(outline_generated)] pub struct TestStruct3 {} #[hdl_module(outline_generated)] @@ -4430,204 +4421,3 @@ circuit check_let_patterns: ", }; } - -#[hdl_module(outline_generated)] -pub fn check_struct_cmp_eq() { - #[hdl] - let tuple_lhs: (UInt<1>, SInt<1>, Bool) = m.input(); - #[hdl] - let tuple_rhs: (UInt<1>, SInt<1>, Bool) = m.input(); - #[hdl] - let tuple_cmp_eq: Bool = m.output(); - connect(tuple_cmp_eq, tuple_lhs.cmp_eq(tuple_rhs)); - #[hdl] - let tuple_cmp_ne: Bool = m.output(); - connect(tuple_cmp_ne, tuple_lhs.cmp_ne(tuple_rhs)); - - #[hdl] - let test_struct_lhs: TestStruct> = m.input(); - #[hdl] - let test_struct_rhs: TestStruct> = m.input(); - #[hdl] - let test_struct_cmp_eq: Bool = m.output(); - connect(test_struct_cmp_eq, test_struct_lhs.cmp_eq(test_struct_rhs)); - #[hdl] - let test_struct_cmp_ne: Bool = m.output(); - connect(test_struct_cmp_ne, test_struct_lhs.cmp_ne(test_struct_rhs)); - - #[hdl] - let test_struct_2_lhs: TestStruct2 = m.input(); - #[hdl] - let test_struct_2_rhs: TestStruct2 = m.input(); - #[hdl] - let test_struct_2_cmp_eq: Bool = m.output(); - connect( - test_struct_2_cmp_eq, - test_struct_2_lhs.cmp_eq(test_struct_2_rhs), - ); - #[hdl] - let test_struct_2_cmp_ne: Bool = m.output(); - connect( - test_struct_2_cmp_ne, - test_struct_2_lhs.cmp_ne(test_struct_2_rhs), - ); - - #[hdl] - let test_struct_3_lhs: TestStruct3 = m.input(); - #[hdl] - let test_struct_3_rhs: TestStruct3 = m.input(); - #[hdl] - let test_struct_3_cmp_eq: Bool = m.output(); - connect( - test_struct_3_cmp_eq, - test_struct_3_lhs.cmp_eq(test_struct_3_rhs), - ); - #[hdl] - let test_struct_3_cmp_ne: Bool = m.output(); - connect( - test_struct_3_cmp_ne, - test_struct_3_lhs.cmp_ne(test_struct_3_rhs), - ); -} - -#[test] -fn test_struct_cmp_eq() { - let _n = SourceLocation::normalize_files_for_tests(); - let m = check_struct_cmp_eq(); - dbg!(m); - #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 - assert_export_firrtl! { - m => - "/test/check_struct_cmp_eq.fir": r"FIRRTL version 3.2.0 -circuit check_struct_cmp_eq: - type Ty0 = {`0`: UInt<1>, `1`: SInt<1>, `2`: UInt<1>} - type Ty1 = {a: SInt<8>, b: UInt<8>} - type Ty2 = {v: UInt<8>} - type Ty3 = {} - module check_struct_cmp_eq: @[module-XXXXXXXXXX.rs 1:1] - input tuple_lhs: Ty0 @[module-XXXXXXXXXX.rs 2:1] - input tuple_rhs: Ty0 @[module-XXXXXXXXXX.rs 3:1] - output tuple_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 4:1] - output tuple_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 6:1] - input test_struct_lhs: Ty1 @[module-XXXXXXXXXX.rs 8:1] - input test_struct_rhs: Ty1 @[module-XXXXXXXXXX.rs 9:1] - output test_struct_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 10:1] - output test_struct_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 12:1] - input test_struct_2_lhs: Ty2 @[module-XXXXXXXXXX.rs 14:1] - input test_struct_2_rhs: Ty2 @[module-XXXXXXXXXX.rs 15:1] - output test_struct_2_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 16:1] - output test_struct_2_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 18:1] - input test_struct_3_lhs: Ty3 @[module-XXXXXXXXXX.rs 20:1] - input test_struct_3_rhs: Ty3 @[module-XXXXXXXXXX.rs 21:1] - output test_struct_3_cmp_eq: UInt<1> @[module-XXXXXXXXXX.rs 22:1] - output test_struct_3_cmp_ne: UInt<1> @[module-XXXXXXXXXX.rs 24:1] - wire _array_literal_expr: UInt<1>[3] - connect _array_literal_expr[0], eq(tuple_lhs.`0`, tuple_rhs.`0`) - connect _array_literal_expr[1], eq(tuple_lhs.`1`, tuple_rhs.`1`) - connect _array_literal_expr[2], eq(tuple_lhs.`2`, tuple_rhs.`2`) - wire _cast_array_to_bits_expr: UInt<1>[3] - connect _cast_array_to_bits_expr[0], _array_literal_expr[0] - connect _cast_array_to_bits_expr[1], _array_literal_expr[1] - connect _cast_array_to_bits_expr[2], _array_literal_expr[2] - wire _cast_to_bits_expr: UInt<3> - connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) - connect tuple_cmp_eq, andr(_cast_to_bits_expr) @[module-XXXXXXXXXX.rs 5:1] - wire _array_literal_expr_1: UInt<1>[3] - connect _array_literal_expr_1[0], neq(tuple_lhs.`0`, tuple_rhs.`0`) - connect _array_literal_expr_1[1], neq(tuple_lhs.`1`, tuple_rhs.`1`) - connect _array_literal_expr_1[2], neq(tuple_lhs.`2`, tuple_rhs.`2`) - wire _cast_array_to_bits_expr_1: UInt<1>[3] - connect _cast_array_to_bits_expr_1[0], _array_literal_expr_1[0] - connect _cast_array_to_bits_expr_1[1], _array_literal_expr_1[1] - connect _cast_array_to_bits_expr_1[2], _array_literal_expr_1[2] - wire _cast_to_bits_expr_1: UInt<3> - connect _cast_to_bits_expr_1, cat(_cast_array_to_bits_expr_1[2], cat(_cast_array_to_bits_expr_1[1], _cast_array_to_bits_expr_1[0])) - connect tuple_cmp_ne, orr(_cast_to_bits_expr_1) @[module-XXXXXXXXXX.rs 7:1] - connect test_struct_cmp_eq, and(eq(test_struct_lhs.a, test_struct_rhs.a), eq(test_struct_lhs.b, test_struct_rhs.b)) @[module-XXXXXXXXXX.rs 11:1] - connect test_struct_cmp_ne, or(neq(test_struct_lhs.a, test_struct_rhs.a), neq(test_struct_lhs.b, test_struct_rhs.b)) @[module-XXXXXXXXXX.rs 13:1] - connect test_struct_2_cmp_eq, eq(test_struct_2_lhs.v, test_struct_2_rhs.v) @[module-XXXXXXXXXX.rs 17:1] - connect test_struct_2_cmp_ne, neq(test_struct_2_lhs.v, test_struct_2_rhs.v) @[module-XXXXXXXXXX.rs 19:1] - connect test_struct_3_cmp_eq, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 23:1] - connect test_struct_3_cmp_ne, UInt<1>(0h0) @[module-XXXXXXXXXX.rs 25:1] -", - }; -} - -#[hdl_module(outline_generated)] -pub fn check_uint_in_range() { - #[hdl] - let i_0_to_1: UIntInRange<0, 1> = m.input(); - #[hdl] - let i_0_to_2: UIntInRange<0, 2> = m.input(); - #[hdl] - let i_0_to_3: UIntInRange<0, 3> = m.input(); - #[hdl] - let i_0_to_4: UIntInRange<0, 4> = m.input(); - #[hdl] - let i_0_to_7: UIntInRange<0, 7> = m.input(); - #[hdl] - let i_0_to_8: UIntInRange<0, 8> = m.input(); - #[hdl] - let i_0_to_9: UIntInRange<0, 9> = m.input(); - #[hdl] - let i_0_through_0: UIntInRangeInclusive<0, 0> = m.input(); - #[hdl] - let i_0_through_1: UIntInRangeInclusive<0, 1> = m.input(); - #[hdl] - let i_0_through_2: UIntInRangeInclusive<0, 2> = m.input(); - #[hdl] - let i_0_through_3: UIntInRangeInclusive<0, 3> = m.input(); - #[hdl] - let i_0_through_4: UIntInRangeInclusive<0, 4> = m.input(); - #[hdl] - let i_0_through_7: UIntInRangeInclusive<0, 7> = m.input(); - #[hdl] - let i_0_through_8: UIntInRangeInclusive<0, 8> = m.input(); - #[hdl] - let i_0_through_9: UIntInRangeInclusive<0, 9> = m.input(); -} - -#[test] -fn test_uint_in_range() { - let _n = SourceLocation::normalize_files_for_tests(); - let m = check_uint_in_range(); - dbg!(m); - #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 - assert_export_firrtl! { - m => - "/test/check_uint_in_range.fir": r"FIRRTL version 3.2.0 -circuit check_uint_in_range: - type Ty0 = {value: UInt<0>, range: {}} - type Ty1 = {value: UInt<1>, range: {}} - type Ty2 = {value: UInt<2>, range: {}} - type Ty3 = {value: UInt<2>, range: {}} - type Ty4 = {value: UInt<3>, range: {}} - type Ty5 = {value: UInt<3>, range: {}} - type Ty6 = {value: UInt<4>, range: {}} - type Ty7 = {value: UInt<0>, range: {}} - type Ty8 = {value: UInt<1>, range: {}} - type Ty9 = {value: UInt<2>, range: {}} - type Ty10 = {value: UInt<2>, range: {}} - type Ty11 = {value: UInt<3>, range: {}} - type Ty12 = {value: UInt<3>, range: {}} - type Ty13 = {value: UInt<4>, range: {}} - type Ty14 = {value: UInt<4>, range: {}} - module check_uint_in_range: @[module-XXXXXXXXXX.rs 1:1] - input i_0_to_1: Ty0 @[module-XXXXXXXXXX.rs 2:1] - input i_0_to_2: Ty1 @[module-XXXXXXXXXX.rs 3:1] - input i_0_to_3: Ty2 @[module-XXXXXXXXXX.rs 4:1] - input i_0_to_4: Ty3 @[module-XXXXXXXXXX.rs 5:1] - input i_0_to_7: Ty4 @[module-XXXXXXXXXX.rs 6:1] - input i_0_to_8: Ty5 @[module-XXXXXXXXXX.rs 7:1] - input i_0_to_9: Ty6 @[module-XXXXXXXXXX.rs 8:1] - input i_0_through_0: Ty7 @[module-XXXXXXXXXX.rs 9:1] - input i_0_through_1: Ty8 @[module-XXXXXXXXXX.rs 10:1] - input i_0_through_2: Ty9 @[module-XXXXXXXXXX.rs 11:1] - input i_0_through_3: Ty10 @[module-XXXXXXXXXX.rs 12:1] - input i_0_through_4: Ty11 @[module-XXXXXXXXXX.rs 13:1] - input i_0_through_7: Ty12 @[module-XXXXXXXXXX.rs 14:1] - input i_0_through_8: Ty13 @[module-XXXXXXXXXX.rs 15:1] - input i_0_through_9: Ty14 @[module-XXXXXXXXXX.rs 16:1] -", - }; -} diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index 655a497..8c8a10f 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -2,11 +2,11 @@ // See Notices.txt for copyright information use fayalite::{ - memory::{ReadStruct, ReadWriteStruct, WriteStruct}, - module::{instance_with_loc, reg_builder_with_loc}, + int::UIntValue, prelude::*, reset::ResetType, - sim::vcd::VcdWriterDecls, + sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue}, + ty::StaticType, util::RcWriter, }; use std::num::NonZeroUsize; @@ -316,13 +316,8 @@ pub fn enums() { let which_out: UInt<2> = m.output(); #[hdl] let data_out: UInt<4> = m.output(); - let b_out_ty = HdlOption[(UInt[1], Bool)]; #[hdl] - let b_out: HdlOption<(UInt, Bool)> = m.output(HdlOption[(UInt[1], Bool)]); - #[hdl] - let b2_out: HdlOption<(UInt<1>, Bool)> = m.output(); - - connect_any(b2_out, b_out); + let b_out: HdlOption<(UInt<1>, Bool)> = m.output(); #[hdl] struct MyStruct { @@ -362,7 +357,7 @@ pub fn enums() { } } - connect(b_out, b_out_ty.HdlNone()); + connect(b_out, HdlNone()); #[hdl] match the_reg { @@ -373,7 +368,7 @@ pub fn enums() { MyEnum::B(v) => { connect(which_out, 1_hdl_u2); connect_any(data_out, v.0 | (v.1.cast_to_static::>() << 1)); - connect_any(b_out, HdlSome(v)); + connect(b_out, HdlSome(v)); } MyEnum::C(v) => { connect(which_out, 2_hdl_u2); @@ -389,136 +384,132 @@ fn test_enums() { let mut sim = Simulation::new(enums()); let mut writer = RcWriter::default(); sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - sim.write(sim.io().cd.clk, false); - sim.write(sim.io().cd.rst, true); - sim.write(sim.io().en, false); - sim.write(sim.io().which_in, 0_hdl_u2); - sim.write(sim.io().data_in, 0_hdl_u4); + sim.write_clock(sim.io().cd.clk, false); + sim.write_reset(sim.io().cd.rst, true); + sim.write_bool(sim.io().en, false); + sim.write_bool_or_int(sim.io().which_in, 0_hdl_u2); + sim.write_bool_or_int(sim.io().data_in, 0_hdl_u4); sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().cd.clk, true); + sim.write_clock(sim.io().cd.clk, true); sim.advance_time(SimDuration::from_nanos(100)); - sim.write(sim.io().cd.rst, false); + sim.write_reset(sim.io().cd.rst, false); sim.advance_time(SimDuration::from_nanos(900)); - #[hdl(cmp_eq)] - struct IO { - en: Bool, - which_in: UInt<2>, - data_in: UInt<4>, - which_out: UInt<2>, - data_out: UInt<4>, - b_out: HdlOption<(UIntType, Bool)>, - b2_out: HdlOption<(UInt<1>, Bool)>, + type BOutTy = HdlOption<(UInt<1>, Bool)>; + #[derive(Debug)] + struct IO { + en: bool, + which_in: u8, + data_in: u8, + which_out: u8, + data_out: u8, + b_out: Expr, + } + impl PartialEq for IO { + fn eq(&self, other: &Self) -> bool { + let Self { + en, + which_in, + data_in, + which_out, + data_out, + b_out, + } = *self; + en == other.en + && which_in == other.which_in + && data_in == other.data_in + && which_out == other.which_out + && data_out == other.data_out + && b_out.to_sim_value(BOutTy::TYPE) == other.b_out.to_sim_value(BOutTy::TYPE) + } } - let io_ty = IO[1]; let io_cycles = [ - #[hdl(sim)] - IO::<_> { + IO { en: false, - which_in: 0_hdl_u2, - data_in: 0_hdl_u4, - which_out: 0_hdl_u2, - data_out: 0_hdl_u4, - b_out: #[hdl(sim)] - (io_ty.b_out).HdlNone(), - b2_out: #[hdl(sim)] - HdlNone(), + which_in: 0, + data_in: 0, + which_out: 0, + data_out: 0, + b_out: HdlNone(), }, - #[hdl(sim)] - IO::<_> { + IO { en: true, - which_in: 1_hdl_u2, - data_in: 0_hdl_u4, - which_out: 0_hdl_u2, - data_out: 0_hdl_u4, - b_out: #[hdl(sim)] - (io_ty.b_out).HdlNone(), - b2_out: #[hdl(sim)] - HdlNone(), + which_in: 1, + data_in: 0, + which_out: 0, + data_out: 0, + b_out: HdlNone(), }, - #[hdl(sim)] - IO::<_> { + IO { en: false, - which_in: 0_hdl_u2, - data_in: 0_hdl_u4, - which_out: 1_hdl_u2, - data_out: 0_hdl_u4, - b_out: #[hdl(sim)] - (io_ty.b_out).HdlSome((0u8.cast_to(UInt[1]), false)), - b2_out: #[hdl(sim)] - HdlSome((0_hdl_u1, false)), + which_in: 0, + data_in: 0, + which_out: 1, + data_out: 0, + b_out: HdlSome((0_hdl_u1, false)), }, - #[hdl(sim)] - IO::<_> { + IO { en: true, - which_in: 1_hdl_u2, - data_in: 0xF_hdl_u4, - which_out: 1_hdl_u2, - data_out: 0_hdl_u4, - b_out: #[hdl(sim)] - (io_ty.b_out).HdlSome((0u8.cast_to(UInt[1]), false)), - b2_out: #[hdl(sim)] - HdlSome((0_hdl_u1, false)), + which_in: 1, + data_in: 0xF, + which_out: 1, + data_out: 0, + b_out: HdlSome((0_hdl_u1, false)), }, - #[hdl(sim)] - IO::<_> { + IO { en: true, - which_in: 1_hdl_u2, - data_in: 0xF_hdl_u4, - which_out: 1_hdl_u2, - data_out: 0x3_hdl_u4, - b_out: #[hdl(sim)] - (io_ty.b_out).HdlSome((1u8.cast_to(UInt[1]), true)), - b2_out: #[hdl(sim)] - HdlSome((1_hdl_u1, true)), + which_in: 1, + data_in: 0xF, + which_out: 1, + data_out: 0x3, + b_out: HdlSome((1_hdl_u1, true)), }, - #[hdl(sim)] - IO::<_> { + IO { en: true, - which_in: 2_hdl_u2, - data_in: 0xF_hdl_u4, - which_out: 1_hdl_u2, - data_out: 0x3_hdl_u4, - b_out: #[hdl(sim)] - (io_ty.b_out).HdlSome((1u8.cast_to(UInt[1]), true)), - b2_out: #[hdl(sim)] - HdlSome((1_hdl_u1, true)), + which_in: 2, + data_in: 0xF, + which_out: 1, + data_out: 0x3, + b_out: HdlSome((1_hdl_u1, true)), }, - #[hdl(sim)] - IO::<_> { + IO { en: true, - which_in: 2_hdl_u2, - data_in: 0xF_hdl_u4, - which_out: 2_hdl_u2, - data_out: 0xF_hdl_u4, - b_out: #[hdl(sim)] - (io_ty.b_out).HdlNone(), - b2_out: #[hdl(sim)] - HdlNone(), + which_in: 2, + data_in: 0xF, + which_out: 2, + data_out: 0xF, + b_out: HdlNone(), }, ]; - for (cycle, expected) in io_cycles.into_iter().enumerate() { - #[hdl(sim)] - let IO::<_> { + for ( + cycle, + expected @ IO { en, which_in, data_in, which_out: _, data_out: _, b_out: _, - b2_out: _, - } = expected; - sim.write(sim.io().en, &en); - sim.write(sim.io().which_in, &which_in); - sim.write(sim.io().data_in, &data_in); - let io = #[hdl(sim)] - IO::<_> { + }, + ) in io_cycles.into_iter().enumerate() + { + sim.write_bool(sim.io().en, en); + sim.write_bool_or_int(sim.io().which_in, which_in.cast_to_static()); + sim.write_bool_or_int(sim.io().data_in, data_in.cast_to_static()); + let io = IO { en, which_in, data_in, - which_out: sim.read(sim.io().which_out), - data_out: sim.read(sim.io().data_out), - b_out: sim.read(sim.io().b_out), - b2_out: sim.read(sim.io().b2_out), + which_out: sim + .read_bool_or_int(sim.io().which_out) + .to_bigint() + .try_into() + .expect("known to be in range"), + data_out: sim + .read_bool_or_int(sim.io().data_out) + .to_bigint() + .try_into() + .expect("known to be in range"), + b_out: sim.read(sim.io().b_out).to_expr(), }; assert_eq!( expected, @@ -526,12 +517,6 @@ fn test_enums() { "vcd:\n{}\ncycle: {cycle}", String::from_utf8(writer.take()).unwrap(), ); - // make sure matching on SimValue works - #[hdl(sim)] - match io.b_out { - HdlNone => println!("io.b_out is HdlNone"), - HdlSome(v) => println!("io.b_out is HdlSome(({:?}, {:?}))", *v.0, *v.1), - } sim.write_clock(sim.io().cd.clk, false); sim.advance_time(SimDuration::from_micros(1)); sim.write_clock(sim.io().cd.clk, true); @@ -553,9 +538,9 @@ fn test_enums() { #[hdl_module(outline_generated)] pub fn memories() { #[hdl] - let r: ReadStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input(); + let r: fayalite::memory::ReadStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input(); #[hdl] - let w: WriteStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input(); + let w: fayalite::memory::WriteStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input(); #[hdl] let mut mem = memory_with_init([(0x01u8, 0x23i8); 16]); mem.read_latency(0); @@ -574,131 +559,120 @@ fn test_memories() { sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); sim.write_clock(sim.io().r.clk, false); sim.write_clock(sim.io().w.clk, false); - #[hdl(cmp_eq)] + #[derive(Debug, PartialEq, Eq)] struct IO { - r_addr: UInt<4>, - r_en: Bool, - r_data: (UInt<8>, SInt<8>), - w_addr: UInt<4>, - w_en: Bool, - w_data: (UInt<8>, SInt<8>), - w_mask: (Bool, Bool), + r_addr: u8, + r_en: bool, + r_data: (u8, i8), + w_addr: u8, + w_en: bool, + w_data: (u8, i8), + w_mask: (bool, bool), } let io_cycles = [ - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: false, - r_data: (0u8, 0i8), - w_addr: 0_hdl_u4, + r_data: (0, 0), + w_addr: 0, w_en: false, - w_data: (0u8, 0i8), + w_data: (0, 0), w_mask: (false, false), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x1u8, 0x23i8), - w_addr: 0_hdl_u4, + r_data: (0x1, 0x23), + w_addr: 0, w_en: true, - w_data: (0x10u8, 0x20i8), + w_data: (0x10, 0x20), w_mask: (true, true), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x10u8, 0x20i8), - w_addr: 0_hdl_u4, + r_data: (0x10, 0x20), + w_addr: 0, w_en: true, - w_data: (0x30u8, 0x40i8), + w_data: (0x30, 0x40), w_mask: (false, true), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x10u8, 0x40i8), - w_addr: 0_hdl_u4, + r_data: (0x10, 0x40), + w_addr: 0, w_en: true, - w_data: (0x50u8, 0x60i8), + w_data: (0x50, 0x60), w_mask: (true, false), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x50u8, 0x40i8), - w_addr: 0_hdl_u4, + r_data: (0x50, 0x40), + w_addr: 0, w_en: true, - w_data: (0x70u8, -0x80i8), + w_data: (0x70, -0x80), w_mask: (false, false), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x50u8, 0x40i8), - w_addr: 0_hdl_u4, + r_data: (0x50, 0x40), + w_addr: 0, w_en: false, - w_data: (0x90u8, 0xA0u8 as i8), + w_data: (0x90, 0xA0u8 as i8), w_mask: (false, false), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x50u8, 0x40i8), - w_addr: 1_hdl_u4, + r_data: (0x50, 0x40), + w_addr: 1, w_en: true, - w_data: (0x90u8, 0xA0u8 as i8), + w_data: (0x90, 0xA0u8 as i8), w_mask: (true, true), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x50u8, 0x40i8), - w_addr: 2_hdl_u4, + r_data: (0x50, 0x40), + w_addr: 2, w_en: true, - w_data: (0xB0u8, 0xC0u8 as i8), + w_data: (0xB0, 0xC0u8 as i8), w_mask: (true, true), }, - #[hdl(sim)] IO { - r_addr: 0_hdl_u4, + r_addr: 0, r_en: true, - r_data: (0x50u8, 0x40i8), - w_addr: 2_hdl_u4, + r_data: (0x50, 0x40), + w_addr: 2, w_en: false, - w_data: (0xD0u8, 0xE0u8 as i8), + w_data: (0xD0, 0xE0u8 as i8), w_mask: (true, true), }, - #[hdl(sim)] IO { - r_addr: 1_hdl_u4, + r_addr: 1, r_en: true, - r_data: (0x90u8, 0xA0u8 as i8), - w_addr: 2_hdl_u4, + r_data: (0x90, 0xA0u8 as i8), + w_addr: 2, w_en: false, - w_data: (0xD0u8, 0xE0u8 as i8), + w_data: (0xD0, 0xE0u8 as i8), w_mask: (true, true), }, - #[hdl(sim)] IO { - r_addr: 2_hdl_u4, + r_addr: 2, r_en: true, - r_data: (0xB0u8, 0xC0u8 as i8), - w_addr: 2_hdl_u4, + r_data: (0xB0, 0xC0u8 as i8), + w_addr: 2, w_en: false, - w_data: (0xD0u8, 0xE0u8 as i8), + w_data: (0xD0, 0xE0u8 as i8), w_mask: (true, true), }, ]; - for (cycle, expected) in io_cycles.into_iter().enumerate() { - #[hdl(sim)] - let IO { + for ( + cycle, + expected @ IO { r_addr, r_en, r_data: _, @@ -706,18 +680,30 @@ fn test_memories() { w_en, w_data, w_mask, - } = expected; - sim.write(sim.io().r.addr, &r_addr); - sim.write(sim.io().r.en, &r_en); - sim.write(sim.io().w.addr, &w_addr); - sim.write(sim.io().w.en, &w_en); - sim.write(sim.io().w.data, &w_data); - sim.write(sim.io().w.mask, &w_mask); - let io = #[hdl(sim)] - IO { + }, + ) in io_cycles.into_iter().enumerate() + { + sim.write_bool_or_int(sim.io().r.addr, r_addr.cast_to_static()); + sim.write_bool(sim.io().r.en, r_en); + sim.write_bool_or_int(sim.io().w.addr, w_addr.cast_to_static()); + sim.write_bool(sim.io().w.en, w_en); + sim.write_bool_or_int(sim.io().w.data.0, w_data.0); + sim.write_bool_or_int(sim.io().w.data.1, w_data.1); + sim.write_bool(sim.io().w.mask.0, w_mask.0); + sim.write_bool(sim.io().w.mask.1, w_mask.1); + let io = IO { r_addr, r_en, - r_data: sim.read(sim.io().r.data), + r_data: ( + sim.read_bool_or_int(sim.io().r.data.0) + .to_bigint() + .try_into() + .expect("known to be in range"), + sim.read_bool_or_int(sim.io().r.data.1) + .to_bigint() + .try_into() + .expect("known to be in range"), + ), w_addr, w_en, w_data, @@ -730,11 +716,11 @@ fn test_memories() { String::from_utf8(writer.take()).unwrap(), ); sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().r.clk, true); - sim.write(sim.io().w.clk, true); + sim.write_clock(sim.io().r.clk, true); + sim.write_clock(sim.io().w.clk, true); sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().r.clk, false); - sim.write(sim.io().w.clk, false); + sim.write_clock(sim.io().r.clk, false); + sim.write_clock(sim.io().w.clk, false); } sim.flush_traces().unwrap(); let vcd = String::from_utf8(writer.take()).unwrap(); @@ -752,7 +738,7 @@ fn test_memories() { #[hdl_module(outline_generated)] pub fn memories2() { #[hdl] - let rw: ReadWriteStruct, ConstUsize<3>> = m.input(); + let rw: fayalite::memory::ReadWriteStruct, ConstUsize<3>> = m.input(); #[hdl] let mut mem = memory_with_init([HdlSome(true); 5]); mem.read_latency(1); @@ -1025,9 +1011,9 @@ fn test_memories2() { #[hdl_module(outline_generated)] pub fn memories3() { #[hdl] - let r: ReadStruct, 8>, ConstUsize<3>> = m.input(); + let r: fayalite::memory::ReadStruct, 8>, ConstUsize<3>> = m.input(); #[hdl] - let w: WriteStruct, 8>, ConstUsize<3>> = m.input(); + let w: fayalite::memory::WriteStruct, 8>, ConstUsize<3>> = m.input(); #[hdl] let mut mem: MemBuilder, 8>> = memory(); mem.depth(8); @@ -1457,172 +1443,3 @@ fn test_conditional_assignment_last() { panic!(); } } - -#[hdl_module(outline_generated, extern)] -pub fn extern_module() { - #[hdl] - let i: Bool = m.input(); - #[hdl] - let o: Bool = m.output(); - m.extern_module_simulation_fn((i, o), |(i, o), mut sim| async move { - sim.write(o, true).await; - sim.advance_time(SimDuration::from_nanos(500)).await; - let mut invert = false; - loop { - sim.advance_time(SimDuration::from_micros(1)).await; - let v = sim.read_bool(i).await; - sim.write(o, v ^ invert).await; - invert = !invert; - } - }); -} - -#[test] -fn test_extern_module() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(extern_module()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - sim.write(sim.io().i, false); - sim.advance_time(SimDuration::from_micros(10)); - sim.write(sim.io().i, true); - sim.advance_time(SimDuration::from_micros(10)); - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/extern_module.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/extern_module.txt") { - panic!(); - } -} - -#[hdl_module(outline_generated, extern)] -pub fn extern_module2() { - #[hdl] - let en: Bool = m.input(); - #[hdl] - let clk: Clock = m.input(); - #[hdl] - let o: UInt<8> = m.output(); - m.extern_module_simulation_fn((en, clk, o), |(en, clk, o), mut sim| async move { - for b in "Hello, World!\n".bytes().cycle() { - sim.write(o, b).await; - loop { - sim.wait_for_clock_edge(clk).await; - if sim.read_bool(en).await { - break; - } - } - } - }); -} - -#[test] -fn test_extern_module2() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(extern_module2()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - for i in 0..30 { - sim.write(sim.io().en, i % 10 < 5); - sim.write(sim.io().clk, false); - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clk, true); - sim.advance_time(SimDuration::from_micros(1)); - } - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/extern_module2.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/extern_module2.txt") { - panic!(); - } -} - -// use an extern module to simulate a register to test that the -// simulator can handle chains of alternating circuits and extern modules. -#[hdl_module(outline_generated, extern)] -pub fn sw_reg() { - #[hdl] - let clk: Clock = m.input(); - #[hdl] - let o: Bool = m.output(); - m.extern_module_simulation_fn((clk, o), |(clk, o), mut sim| async move { - let mut state = false; - loop { - sim.write(o, state).await; - sim.wait_for_clock_edge(clk).await; - state = !state; - } - }); -} - -#[hdl_module(outline_generated)] -pub fn ripple_counter() { - #[hdl] - let clk: Clock = m.input(); - #[hdl] - let o: UInt<6> = m.output(); - - #[hdl] - let bits: Array = wire(); - - connect_any(o, bits.cast_to_bits()); - - let mut clk_in = clk; - for (i, bit) in bits.into_iter().enumerate() { - if i % 2 == 0 { - let bit_reg = reg_builder_with_loc(&format!("bit_reg_{i}"), SourceLocation::caller()) - .clock_domain( - #[hdl] - ClockDomain { - clk: clk_in, - rst: false.to_sync_reset(), - }, - ) - .no_reset(Bool) - .build(); - connect(bit, bit_reg); - connect(bit_reg, !bit_reg); - } else { - let bit_reg = - instance_with_loc(&format!("bit_reg_{i}"), sw_reg(), SourceLocation::caller()); - connect(bit_reg.clk, clk_in); - connect(bit, bit_reg.o); - } - clk_in = bit.to_clock(); - } -} - -#[test] -fn test_ripple_counter() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(ripple_counter()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - for _ in 0..0x80 { - sim.write(sim.io().clk, false); - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clk, true); - sim.advance_time(SimDuration::from_micros(1)); - } - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/ripple_counter.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/ripple_counter.txt") { - panic!(); - } -} diff --git a/crates/fayalite/tests/sim/expected/array_rw.txt b/crates/fayalite/tests/sim/expected/array_rw.txt index 34643f2..f016e72 100644 --- a/crates/fayalite/tests/sim/expected/array_rw.txt +++ b/crates/fayalite/tests/sim/expected/array_rw.txt @@ -488,338 +488,1501 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, 16>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 16, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[8]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[9]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[10]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[11]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[12]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[13]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[14]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_in[15]", + ty: UInt<8>, + }, + ], + .. + }, }, - }.array_in, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, }, - }.array_out, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.read_index, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.read_data, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.write_index, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.write_data, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.write_en, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[0], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[10], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[11], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[12], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[13], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[14], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[15], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[1], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[2], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[3], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[4], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[5], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[6], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[7], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[8], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_in[9], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[0], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[10], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[11], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[12], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[13], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[14], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[15], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[1], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[2], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[3], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[4], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[5], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[6], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[7], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[8], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.array_out[9], - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.read_data, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.read_index, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.write_data, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.write_en, - Instance { - name: ::array_rw, - instantiated: Module { - name: array_rw, - .. - }, - }.write_index, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 16 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[10]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 10, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[11]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 11, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[12]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 12, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[13]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 13, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[14]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 14, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[15]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 15, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 6, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 7, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[8]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 8, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_in[9]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 9, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, 16>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 16, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[8]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[9]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[10]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[11]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[12]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[13]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[14]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::array_out[15]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 16, len: 16 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 16, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[10]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 26, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[11]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 27, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[12]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 28, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[13]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 29, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[14]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 30, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[15]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 31, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 17, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 18, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 19, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 20, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 21, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 22, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 23, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[8]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 24, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.array_out[9]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 25, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.read_data: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::read_data", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 33, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.read_index: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::read_index", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 32, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.write_data: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::write_data", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 35, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.write_en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::write_en", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 36, len: 1 }, + }, + write: None, + }, + Instance { + name: ::array_rw, + instantiated: Module { + name: array_rw, + .. + }, + }.write_index: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(array_rw: array_rw).array_rw::write_index", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 34, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "array_rw", children: [ diff --git a/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt b/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt index c4242c4..186e5a5 100644 --- a/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt +++ b/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt @@ -92,30 +92,45 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::conditional_assignment_last, - instantiated: Module { - name: conditional_assignment_last, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::conditional_assignment_last, + instantiated: Module { + name: conditional_assignment_last, + .. + }, + }.i: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::i", + ty: Bool, + }, + ], + .. + }, }, - }.i, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::conditional_assignment_last, - instantiated: Module { - name: conditional_assignment_last, - .. - }, - }.i, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "conditional_assignment_last", children: [ diff --git a/crates/fayalite/tests/sim/expected/connect_const.txt b/crates/fayalite/tests/sim/expected/connect_const.txt index d357741..e44c50d 100644 --- a/crates/fayalite/tests/sim/expected/connect_const.txt +++ b/crates/fayalite/tests/sim/expected/connect_const.txt @@ -68,30 +68,45 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::connect_const, - instantiated: Module { - name: connect_const, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::connect_const, + instantiated: Module { + name: connect_const, + .. + }, + }.o: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(connect_const: connect_const).connect_const::o", + ty: UInt<8>, + }, + ], + .. + }, }, - }.o, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::connect_const, - instantiated: Module { - name: connect_const, - .. - }, - }.o, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "connect_const", children: [ diff --git a/crates/fayalite/tests/sim/expected/connect_const_reset.txt b/crates/fayalite/tests/sim/expected/connect_const_reset.txt index b3eb3ea..d1ab998 100644 --- a/crates/fayalite/tests/sim/expected/connect_const_reset.txt +++ b/crates/fayalite/tests/sim/expected/connect_const_reset.txt @@ -97,44 +97,79 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::connect_const_reset, - instantiated: Module { - name: connect_const_reset, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::connect_const_reset, + instantiated: Module { + name: connect_const_reset, + .. + }, + }.bit_out: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::bit_out", + ty: Bool, + }, + ], + .. + }, }, - }.reset_out, - Instance { - name: ::connect_const_reset, - instantiated: Module { - name: connect_const_reset, - .. - }, - }.bit_out, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::connect_const_reset, - instantiated: Module { - name: connect_const_reset, - .. - }, - }.bit_out, - Instance { - name: ::connect_const_reset, - instantiated: Module { - name: connect_const_reset, - .. - }, - }.reset_out, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::connect_const_reset, + instantiated: Module { + name: connect_const_reset, + .. + }, + }.reset_out: CompiledValue { + layout: CompiledTypeLayout { + ty: AsyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(connect_const_reset: connect_const_reset).connect_const_reset::reset_out", + ty: AsyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "connect_const_reset", children: [ diff --git a/crates/fayalite/tests/sim/expected/counter_async.txt b/crates/fayalite/tests/sim/expected/counter_async.txt index 558d943..2e005a0 100644 --- a/crates/fayalite/tests/sim/expected/counter_async.txt +++ b/crates/fayalite/tests/sim/expected/counter_async.txt @@ -203,58 +203,213 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.cd: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + clk: Clock, + /* offset = 1 */ + rst: AsyncReset, }, - }.cd, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(counter: counter).counter::cd.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(counter: counter).counter::cd.rst", + ty: AsyncReset, + }, + ], + .. + }, }, - }.count, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: AsyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: AsyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], }, - }.cd, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. - }, - }.cd.clk, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. - }, - }.cd.rst, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. - }, - }.count, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 2 }, + }, + write: None, + }, + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.cd.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.cd.rst: CompiledValue { + layout: CompiledTypeLayout { + ty: AsyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: AsyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.count: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(counter: counter).counter::count", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "counter", children: [ diff --git a/crates/fayalite/tests/sim/expected/counter_sync.txt b/crates/fayalite/tests/sim/expected/counter_sync.txt index d31db25..78fc200 100644 --- a/crates/fayalite/tests/sim/expected/counter_sync.txt +++ b/crates/fayalite/tests/sim/expected/counter_sync.txt @@ -184,58 +184,213 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.cd: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + clk: Clock, + /* offset = 1 */ + rst: SyncReset, }, - }.cd, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(counter: counter).counter::cd.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(counter: counter).counter::cd.rst", + ty: SyncReset, + }, + ], + .. + }, }, - }.count, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], }, - }.cd, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. - }, - }.cd.clk, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. - }, - }.cd.rst, - Instance { - name: ::counter, - instantiated: Module { - name: counter, - .. - }, - }.count, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 2 }, + }, + write: None, + }, + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.cd.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.cd.rst: CompiledValue { + layout: CompiledTypeLayout { + ty: SyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::counter, + instantiated: Module { + name: counter, + .. + }, + }.count: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(counter: counter).counter::count", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "counter", children: [ diff --git a/crates/fayalite/tests/sim/expected/duplicate_names.txt b/crates/fayalite/tests/sim/expected/duplicate_names.txt index 5c6c18a..8a59861 100644 --- a/crates/fayalite/tests/sim/expected/duplicate_names.txt +++ b/crates/fayalite/tests/sim/expected/duplicate_names.txt @@ -88,14 +88,10 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [], - uninitialized_ios: {}, - io_targets: {}, - did_initial_settle: true, - }, - extern_modules: [], - state_ready_to_run: false, + uninitialized_inputs: {}, + io_targets: {}, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "duplicate_names", children: [ diff --git a/crates/fayalite/tests/sim/expected/enums.txt b/crates/fayalite/tests/sim/expected/enums.txt index 61ce5d5..ebfae3e 100644 --- a/crates/fayalite/tests/sim/expected/enums.txt +++ b/crates/fayalite/tests/sim/expected/enums.txt @@ -4,7 +4,7 @@ Simulation { state_layout: StateLayout { ty: TypeLayout { small_slots: StatePartLayout { - len: 7, + len: 6, debug_data: [ SlotDebugData { name: "", @@ -13,13 +13,6 @@ Simulation { HdlSome, }, }, - SlotDebugData { - name: "", - ty: Enum { - HdlNone, - HdlSome, - }, - }, SlotDebugData { name: "", ty: Bool, @@ -48,7 +41,7 @@ Simulation { .. }, big_slots: StatePartLayout { - len: 111, + len: 103, debug_data: [ SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.clk", @@ -113,41 +106,6 @@ Simulation { name: "", ty: Bool, }, - SlotDebugData { - name: "InstantiatedModule(enums: enums).enums::b2_out", - ty: Enum { - HdlNone, - HdlSome(Bundle {0: UInt<1>, 1: Bool}), - }, - }, - SlotDebugData { - name: ".0", - ty: UInt<1>, - }, - SlotDebugData { - name: ".1", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<3>, - }, - SlotDebugData { - name: "", - ty: UInt<2>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum { @@ -540,640 +498,594 @@ Simulation { insns: [ // at: module-XXXXXXXXXX.rs:1:1 0: Const { - dest: StatePartIndex(98), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(90), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, value: 0x1, }, 1: Const { - dest: StatePartIndex(90), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(82), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, value: 0x0, }, 2: Const { - dest: StatePartIndex(88), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, + dest: StatePartIndex(80), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, value: 0x0, }, 3: Copy { - dest: StatePartIndex(89), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - src: StatePartIndex(88), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, + dest: StatePartIndex(81), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(80), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, }, - // at: module-XXXXXXXXXX.rs:18:1 + // at: module-XXXXXXXXXX.rs:16:1 4: Copy { dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - src: StatePartIndex(89), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(81), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, }, // at: module-XXXXXXXXXX.rs:1:1 5: SliceInt { - dest: StatePartIndex(77), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(69), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, start: 2, len: 2, }, 6: CastToSInt { - dest: StatePartIndex(78), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, - src: StatePartIndex(77), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(70), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + src: StatePartIndex(69), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, dest_width: 2, }, 7: Const { - dest: StatePartIndex(70), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(62), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, value: 0x2, }, 8: SliceInt { - dest: StatePartIndex(57), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(49), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, start: 1, len: 1, }, 9: Copy { - dest: StatePartIndex(58), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(57), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(50), // (0x1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(49), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 10: Copy { - dest: StatePartIndex(76), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(58), // (0x1) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(68), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(50), // (0x1) SlotDebugData { name: "", ty: Bool }, }, 11: SliceInt { - dest: StatePartIndex(54), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(46), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, start: 0, len: 1, }, 12: Copy { - dest: StatePartIndex(55), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(54), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(46), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 13: Copy { - dest: StatePartIndex(56), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(55), // (0x1) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(48), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: Bool }, }, 14: Copy { - dest: StatePartIndex(52), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - src: StatePartIndex(56), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(44), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(48), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 15: Copy { - dest: StatePartIndex(53), // (0x1) SlotDebugData { name: ".1", ty: Bool }, - src: StatePartIndex(58), // (0x1) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(45), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + src: StatePartIndex(50), // (0x1) SlotDebugData { name: "", ty: Bool }, }, 16: Copy { - dest: StatePartIndex(74), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, - src: StatePartIndex(56), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(66), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + src: StatePartIndex(48), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 17: Copy { - dest: StatePartIndex(75), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, - src: StatePartIndex(76), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(67), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + src: StatePartIndex(68), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 18: Copy { - dest: StatePartIndex(71), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, - src: StatePartIndex(74), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + dest: StatePartIndex(63), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + src: StatePartIndex(66), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, }, 19: Copy { - dest: StatePartIndex(72), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, - src: StatePartIndex(75), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + dest: StatePartIndex(64), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + src: StatePartIndex(67), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, }, 20: Copy { - dest: StatePartIndex(73), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, - src: StatePartIndex(78), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + dest: StatePartIndex(65), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + src: StatePartIndex(70), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, }, 21: Copy { - dest: StatePartIndex(66), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, - src: StatePartIndex(70), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(58), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, + src: StatePartIndex(62), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, 22: Copy { - dest: StatePartIndex(67), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, - src: StatePartIndex(71), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + dest: StatePartIndex(59), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, + src: StatePartIndex(63), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, }, 23: Copy { - dest: StatePartIndex(68), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, - src: StatePartIndex(72), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + dest: StatePartIndex(60), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, + src: StatePartIndex(64), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, }, 24: Copy { - dest: StatePartIndex(69), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, - src: StatePartIndex(73), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + dest: StatePartIndex(61), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, + src: StatePartIndex(65), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, }, 25: Shl { - dest: StatePartIndex(79), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(68), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, + dest: StatePartIndex(71), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(60), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, rhs: 1, }, 26: Or { - dest: StatePartIndex(80), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(67), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, - rhs: StatePartIndex(79), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(72), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(59), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, + rhs: StatePartIndex(71), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, 27: CastToUInt { - dest: StatePartIndex(81), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(69), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, + dest: StatePartIndex(73), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(61), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, dest_width: 2, }, 28: Shl { - dest: StatePartIndex(82), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(81), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(74), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(73), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, rhs: 2, }, 29: Or { - dest: StatePartIndex(83), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(80), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - rhs: StatePartIndex(82), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(75), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(72), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + rhs: StatePartIndex(74), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, }, 30: Shl { - dest: StatePartIndex(84), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, - lhs: StatePartIndex(83), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(76), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, + lhs: StatePartIndex(75), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, rhs: 2, }, 31: Or { - dest: StatePartIndex(85), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - lhs: StatePartIndex(66), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, - rhs: StatePartIndex(84), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(77), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + lhs: StatePartIndex(58), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, + rhs: StatePartIndex(76), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, }, 32: CastToUInt { - dest: StatePartIndex(86), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - src: StatePartIndex(85), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(78), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + src: StatePartIndex(77), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, dest_width: 6, }, 33: Copy { - dest: StatePartIndex(87), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(86), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(79), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(78), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, }, 34: Const { - dest: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, value: 0x1, }, 35: CmpEq { - dest: StatePartIndex(48), // (0x0) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Bool }, lhs: StatePartIndex(3), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_in", ty: UInt<2> }, - rhs: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + rhs: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, }, 36: Copy { - dest: StatePartIndex(49), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, - src: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(41), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, + src: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, }, 37: Copy { - dest: StatePartIndex(50), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, - src: StatePartIndex(52), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + dest: StatePartIndex(42), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, + src: StatePartIndex(44), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, }, 38: Copy { - dest: StatePartIndex(51), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, - src: StatePartIndex(53), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + dest: StatePartIndex(43), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + src: StatePartIndex(45), // (0x1) SlotDebugData { name: ".1", ty: Bool }, }, 39: Copy { - dest: StatePartIndex(59), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(51), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + dest: StatePartIndex(51), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(43), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, }, 40: Shl { - dest: StatePartIndex(60), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(59), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(52), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(51), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, rhs: 1, }, 41: Or { - dest: StatePartIndex(61), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(50), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, - rhs: StatePartIndex(60), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(53), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(42), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, + rhs: StatePartIndex(52), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, 42: Shl { - dest: StatePartIndex(62), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(61), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(54), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(53), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, rhs: 2, }, 43: Or { - dest: StatePartIndex(63), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(49), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, - rhs: StatePartIndex(62), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(55), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(41), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, + rhs: StatePartIndex(54), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, }, 44: CastToUInt { - dest: StatePartIndex(64), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, - src: StatePartIndex(63), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(56), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, + src: StatePartIndex(55), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, dest_width: 6, }, 45: Copy { - dest: StatePartIndex(65), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(64), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(57), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(56), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, }, 46: Const { - dest: StatePartIndex(45), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(37), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, value: 0x0, }, 47: CmpEq { - dest: StatePartIndex(46), // (0x0) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(38), // (0x0) SlotDebugData { name: "", ty: Bool }, lhs: StatePartIndex(3), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_in", ty: UInt<2> }, - rhs: StatePartIndex(45), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + rhs: StatePartIndex(37), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, }, 48: Copy { - dest: StatePartIndex(29), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - src: StatePartIndex(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + dest: StatePartIndex(21), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + src: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, }, 49: SliceInt { - dest: StatePartIndex(30), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(29), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(22), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(21), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, start: 2, len: 2, }, 50: SliceInt { - dest: StatePartIndex(31), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(30), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(23), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(22), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, start: 0, len: 1, }, 51: SliceInt { - dest: StatePartIndex(32), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(30), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(24), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(22), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, start: 1, len: 1, }, 52: Copy { - dest: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(32), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(25), // (0x1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(24), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 53: Copy { - dest: StatePartIndex(27), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - src: StatePartIndex(31), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(19), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(23), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 54: Copy { - dest: StatePartIndex(28), // (0x1) SlotDebugData { name: ".1", ty: Bool }, - src: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(20), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + src: StatePartIndex(25), // (0x1) SlotDebugData { name: "", ty: Bool }, }, 55: Copy { - dest: StatePartIndex(91), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(28), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + dest: StatePartIndex(83), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(20), // (0x1) SlotDebugData { name: ".1", ty: Bool }, }, 56: Shl { + dest: StatePartIndex(84), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(83), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + rhs: 1, + }, + 57: Or { + dest: StatePartIndex(85), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(19), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + rhs: StatePartIndex(84), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + }, + 58: CastToUInt { + dest: StatePartIndex(86), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(85), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest_width: 4, + }, + 59: Copy { + dest: StatePartIndex(87), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(90), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 60: Copy { + dest: StatePartIndex(88), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, + src: StatePartIndex(19), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + }, + 61: Copy { + dest: StatePartIndex(89), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + src: StatePartIndex(20), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + }, + 62: Copy { + dest: StatePartIndex(91), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(89), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + }, + 63: Shl { dest: StatePartIndex(92), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, lhs: StatePartIndex(91), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, rhs: 1, }, - 57: Or { + 64: Or { dest: StatePartIndex(93), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(27), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + lhs: StatePartIndex(88), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, rhs: StatePartIndex(92), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, - 58: CastToUInt { - dest: StatePartIndex(94), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(93), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - dest_width: 4, - }, - 59: Copy { - dest: StatePartIndex(95), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - src: StatePartIndex(98), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - }, - 60: Copy { - dest: StatePartIndex(96), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, - src: StatePartIndex(27), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - }, - 61: Copy { - dest: StatePartIndex(97), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, - src: StatePartIndex(28), // (0x1) SlotDebugData { name: ".1", ty: Bool }, - }, - 62: Copy { - dest: StatePartIndex(99), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(97), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, - }, - 63: Shl { - dest: StatePartIndex(100), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(99), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - rhs: 1, - }, - 64: Or { - dest: StatePartIndex(101), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(96), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, - rhs: StatePartIndex(100), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - }, 65: Shl { - dest: StatePartIndex(102), // (0x6) SlotDebugData { name: "", ty: UInt<3> }, - lhs: StatePartIndex(101), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(94), // (0x6) SlotDebugData { name: "", ty: UInt<3> }, + lhs: StatePartIndex(93), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, rhs: 1, }, 66: Or { - dest: StatePartIndex(103), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, - lhs: StatePartIndex(95), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - rhs: StatePartIndex(102), // (0x6) SlotDebugData { name: "", ty: UInt<3> }, + dest: StatePartIndex(95), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + lhs: StatePartIndex(87), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + rhs: StatePartIndex(94), // (0x6) SlotDebugData { name: "", ty: UInt<3> }, }, 67: CastToUInt { - dest: StatePartIndex(104), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, - src: StatePartIndex(103), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + dest: StatePartIndex(96), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(95), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, dest_width: 3, }, 68: Copy { - dest: StatePartIndex(105), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - src: StatePartIndex(104), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + dest: StatePartIndex(97), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(96), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, }, 69: SliceInt { - dest: StatePartIndex(39), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(29), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(31), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(21), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, start: 2, len: 4, }, 70: SliceInt { - dest: StatePartIndex(40), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(39), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(32), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(31), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, start: 0, len: 2, }, 71: SliceInt { - dest: StatePartIndex(41), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(40), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(32), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, start: 0, len: 1, }, 72: SliceInt { - dest: StatePartIndex(42), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(40), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(34), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(32), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, start: 1, len: 1, }, 73: Copy { - dest: StatePartIndex(37), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, - src: StatePartIndex(41), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(29), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + src: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 74: Copy { - dest: StatePartIndex(38), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, - src: StatePartIndex(42), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(30), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + src: StatePartIndex(34), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, 75: SliceInt { - dest: StatePartIndex(43), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(39), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(35), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(31), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, start: 2, len: 2, }, 76: CastToSInt { - dest: StatePartIndex(44), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, - src: StatePartIndex(43), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(36), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + src: StatePartIndex(35), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, dest_width: 2, }, 77: Copy { - dest: StatePartIndex(34), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, - src: StatePartIndex(37), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + dest: StatePartIndex(26), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + src: StatePartIndex(29), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, }, 78: Copy { - dest: StatePartIndex(35), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, - src: StatePartIndex(38), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + dest: StatePartIndex(27), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + src: StatePartIndex(30), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, }, 79: Copy { - dest: StatePartIndex(36), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, - src: StatePartIndex(44), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + dest: StatePartIndex(28), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + src: StatePartIndex(36), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, }, 80: Shl { - dest: StatePartIndex(106), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(35), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + dest: StatePartIndex(98), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(27), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, rhs: 1, }, 81: Or { - dest: StatePartIndex(107), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(34), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, - rhs: StatePartIndex(106), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(99), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(26), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + rhs: StatePartIndex(98), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, 82: CastToUInt { - dest: StatePartIndex(108), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(36), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + dest: StatePartIndex(100), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(28), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, dest_width: 2, }, 83: Shl { - dest: StatePartIndex(109), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(108), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(101), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(100), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, rhs: 2, }, 84: Or { - dest: StatePartIndex(110), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(107), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - rhs: StatePartIndex(109), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + dest: StatePartIndex(102), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(99), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + rhs: StatePartIndex(101), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, }, - // at: module-XXXXXXXXXX.rs:11:1 + // at: module-XXXXXXXXXX.rs:9:1 85: AndBigWithSmallImmediate { - dest: StatePartIndex(6), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, - lhs: StatePartIndex(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + dest: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + lhs: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, rhs: 0x3, }, - // at: module-XXXXXXXXXX.rs:19:1 + // at: module-XXXXXXXXXX.rs:17:1 86: BranchIfSmallNeImmediate { target: 89, - lhs: StatePartIndex(6), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + lhs: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, rhs: 0x0, }, - // at: module-XXXXXXXXXX.rs:20:1 + // at: module-XXXXXXXXXX.rs:18:1 87: Copy { dest: StatePartIndex(5), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_out", ty: UInt<2> }, - src: StatePartIndex(45), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(37), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, }, - // at: module-XXXXXXXXXX.rs:21:1 + // at: module-XXXXXXXXXX.rs:19:1 88: Copy { dest: StatePartIndex(6), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4> }, - src: StatePartIndex(90), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(82), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, }, - // at: module-XXXXXXXXXX.rs:19:1 + // at: module-XXXXXXXXXX.rs:17:1 89: BranchIfSmallNeImmediate { target: 93, - lhs: StatePartIndex(6), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + lhs: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, rhs: 0x1, }, - // at: module-XXXXXXXXXX.rs:22:1 + // at: module-XXXXXXXXXX.rs:20:1 90: Copy { dest: StatePartIndex(5), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_out", ty: UInt<2> }, - src: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, }, - // at: module-XXXXXXXXXX.rs:23:1 + // at: module-XXXXXXXXXX.rs:21:1 91: Copy { dest: StatePartIndex(6), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4> }, - src: StatePartIndex(94), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(86), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, }, - // at: module-XXXXXXXXXX.rs:24:1 + // at: module-XXXXXXXXXX.rs:22:1 92: Copy { dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - src: StatePartIndex(105), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(97), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, }, - // at: module-XXXXXXXXXX.rs:19:1 + // at: module-XXXXXXXXXX.rs:17:1 93: BranchIfSmallNeImmediate { target: 96, - lhs: StatePartIndex(6), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + lhs: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, rhs: 0x2, }, - // at: module-XXXXXXXXXX.rs:25:1 + // at: module-XXXXXXXXXX.rs:23:1 94: Copy { dest: StatePartIndex(5), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_out", ty: UInt<2> }, - src: StatePartIndex(70), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(62), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, - // at: module-XXXXXXXXXX.rs:26:1 + // at: module-XXXXXXXXXX.rs:24:1 95: Copy { dest: StatePartIndex(6), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4> }, - src: StatePartIndex(110), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(102), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, }, - // at: module-XXXXXXXXXX.rs:11:1 + // at: module-XXXXXXXXXX.rs:9:1 96: IsNonZeroDestIsSmall { - dest: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.rst", ty: SyncReset }, }, // at: module-XXXXXXXXXX.rs:1:1 97: Const { - dest: StatePartIndex(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, value: 0x0, }, 98: Copy { - dest: StatePartIndex(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, + dest: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, }, - // at: module-XXXXXXXXXX.rs:12:1 + // at: module-XXXXXXXXXX.rs:10:1 99: BranchIfZero { target: 107, value: StatePartIndex(2), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::en", ty: Bool }, }, - // at: module-XXXXXXXXXX.rs:13:1 + // at: module-XXXXXXXXXX.rs:11:1 100: BranchIfZero { target: 102, - value: StatePartIndex(46), // (0x0) SlotDebugData { name: "", ty: Bool }, + value: StatePartIndex(38), // (0x0) SlotDebugData { name: "", ty: Bool }, }, - // at: module-XXXXXXXXXX.rs:14:1 + // at: module-XXXXXXXXXX.rs:12:1 101: Copy { - dest: StatePartIndex(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - }, - // at: module-XXXXXXXXXX.rs:13:1 - 102: BranchIfNonZero { - target: 107, - value: StatePartIndex(46), // (0x0) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:15:1 - 103: BranchIfZero { - target: 105, - value: StatePartIndex(48), // (0x0) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:16:1 - 104: Copy { - dest: StatePartIndex(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(65), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - }, - // at: module-XXXXXXXXXX.rs:15:1 - 105: BranchIfNonZero { - target: 107, - value: StatePartIndex(48), // (0x0) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:17:1 - 106: Copy { - dest: StatePartIndex(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(87), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + dest: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, }, // at: module-XXXXXXXXXX.rs:11:1 + 102: BranchIfNonZero { + target: 107, + value: StatePartIndex(38), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:13:1 + 103: BranchIfZero { + target: 105, + value: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:14:1 + 104: Copy { + dest: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(57), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + }, + // at: module-XXXXXXXXXX.rs:13:1 + 105: BranchIfNonZero { + target: 107, + value: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:15:1 + 106: Copy { + dest: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(79), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + }, + // at: module-XXXXXXXXXX.rs:9:1 107: IsNonZeroDestIsSmall { - dest: StatePartIndex(4), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.clk", ty: Clock }, }, 108: AndSmall { - dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(4), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + dest: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + rhs: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, }, - // at: module-XXXXXXXXXX.rs:10:1 + // at: module-XXXXXXXXXX.rs:1:1 109: Copy { - dest: StatePartIndex(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - src: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 110: Copy { - dest: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, - src: StatePartIndex(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - }, - 111: SliceInt { - dest: StatePartIndex(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, - start: 1, - len: 2, - }, - 112: SliceInt { - dest: StatePartIndex(20), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - start: 0, - len: 1, - }, - 113: SliceInt { - dest: StatePartIndex(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(19), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - start: 1, - len: 1, - }, - 114: Copy { - dest: StatePartIndex(22), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - }, - 115: Copy { - dest: StatePartIndex(16), // (0x0) SlotDebugData { name: ".0", ty: UInt<1> }, - src: StatePartIndex(20), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - }, - 116: Copy { - dest: StatePartIndex(17), // (0x0) SlotDebugData { name: ".1", ty: Bool }, - src: StatePartIndex(22), // (0x0) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:9:1 - 117: AndBigWithSmallImmediate { - dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} }, - lhs: StatePartIndex(15), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b2_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, - rhs: 0x1, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 118: Copy { dest: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, src: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, }, - 119: SliceInt { + 110: SliceInt { dest: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, src: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, start: 1, len: 2, }, - 120: SliceInt { + 111: SliceInt { dest: StatePartIndex(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, src: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, start: 0, len: 1, }, - 121: SliceInt { + 112: SliceInt { dest: StatePartIndex(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, src: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, start: 1, len: 1, }, - 122: Copy { + 113: Copy { dest: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, }, - 123: Copy { + 114: Copy { dest: StatePartIndex(8), // (0x0) SlotDebugData { name: ".0", ty: UInt<1> }, src: StatePartIndex(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, }, - 124: Copy { + 115: Copy { dest: StatePartIndex(9), // (0x0) SlotDebugData { name: ".1", ty: Bool }, src: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:8:1 - 125: AndBigWithSmallImmediate { + 116: AndBigWithSmallImmediate { dest: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} }, lhs: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, rhs: 0x1, }, - // at: module-XXXXXXXXXX.rs:11:1 - 126: BranchIfSmallZero { - target: 131, - value: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + // at: module-XXXXXXXXXX.rs:9:1 + 117: BranchIfSmallZero { + target: 122, + value: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, }, - 127: BranchIfSmallNonZero { - target: 130, - value: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + 118: BranchIfSmallNonZero { + target: 121, + value: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, }, - 128: Copy { - dest: StatePartIndex(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(24), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + 119: Copy { + dest: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, }, - 129: Branch { - target: 131, + 120: Branch { + target: 122, }, - 130: Copy { - dest: StatePartIndex(23), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(26), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + 121: Copy { + dest: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, }, - 131: XorSmallImmediate { - dest: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(4), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + 122: XorSmallImmediate { + dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, rhs: 0x1, }, // at: module-XXXXXXXXXX.rs:1:1 - 132: Return, + 123: Return, ], .. }, - pc: 132, + pc: 123, memory_write_log: [], memories: StatePart { value: [], @@ -1183,7 +1095,6 @@ Simulation { 0, 0, 0, - 0, 1, 0, 2, @@ -1206,14 +1117,6 @@ Simulation { 0, 0, 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, 62, 62, 0, @@ -1312,142 +1215,389 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.b_out: CompiledValue { + layout: CompiledTypeLayout { + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), }, - }.cd, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::b_out", + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + }, + ], + .. + }, }, - }.en, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.which_in, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.data_in, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.which_out, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.data_out, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.b_out, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.b2_out, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.b2_out, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.b_out, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.cd, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.cd.clk, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.cd.rst, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.data_in, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.data_out, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.en, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.which_in, - Instance { - name: ::enums, - instantiated: Module { - name: enums, - .. - }, - }.which_out, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 7, len: 1 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.cd: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + clk: Clock, + /* offset = 1 */ + rst: SyncReset, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::cd.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::cd.rst", + ty: SyncReset, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 2 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.cd.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.cd.rst: CompiledValue { + layout: CompiledTypeLayout { + ty: SyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.data_in: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::data_in", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.data_out: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::data_out", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 6, len: 1 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::en", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.which_in: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::which_in", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, + }, + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.which_out: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::which_out", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "enums", children: [ @@ -1587,22 +1737,23 @@ Simulation { }, flow: Sink, }, - TraceModuleIO { - name: "b2_out", + TraceReg { + name: "the_reg", child: TraceEnumWithFields { - name: "b2_out", + name: "the_reg", discriminant: TraceEnumDiscriminant { location: TraceScalarId(10), name: "$tag", ty: Enum { - HdlNone, - HdlSome(Bundle {0: UInt<1>, 1: Bool}), + A, + B(Bundle {0: UInt<1>, 1: Bool}), + C(Bundle {a: Array, 2>, b: SInt<2>}), }, - flow: Sink, + flow: Duplex, }, non_empty_fields: [ TraceBundle { - name: "HdlSome", + name: "B", fields: [ TraceUInt { location: TraceScalarId(11), @@ -1624,57 +1775,6 @@ Simulation { }, flow: Source, }, - ], - ty: Enum { - HdlNone, - HdlSome(Bundle {0: UInt<1>, 1: Bool}), - }, - flow: Sink, - }, - ty: Enum { - HdlNone, - HdlSome(Bundle {0: UInt<1>, 1: Bool}), - }, - flow: Sink, - }, - TraceReg { - name: "the_reg", - child: TraceEnumWithFields { - name: "the_reg", - discriminant: TraceEnumDiscriminant { - location: TraceScalarId(13), - name: "$tag", - ty: Enum { - A, - B(Bundle {0: UInt<1>, 1: Bool}), - C(Bundle {a: Array, 2>, b: SInt<2>}), - }, - flow: Duplex, - }, - non_empty_fields: [ - TraceBundle { - name: "B", - fields: [ - TraceUInt { - location: TraceScalarId(14), - name: "0", - ty: UInt<1>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(15), - name: "1", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - 0: UInt<1>, - /* offset = 1 */ - 1: Bool, - }, - flow: Source, - }, TraceBundle { name: "C", fields: [ @@ -1682,13 +1782,13 @@ Simulation { name: "a", elements: [ TraceUInt { - location: TraceScalarId(16), + location: TraceScalarId(13), name: "[0]", ty: UInt<1>, flow: Source, }, TraceUInt { - location: TraceScalarId(17), + location: TraceScalarId(14), name: "[1]", ty: UInt<1>, flow: Source, @@ -1698,7 +1798,7 @@ Simulation { flow: Source, }, TraceSInt { - location: TraceScalarId(18), + location: TraceScalarId(15), name: "b", ty: SInt<2>, flow: Source, @@ -1821,36 +1921,7 @@ Simulation { SimTrace { id: TraceScalarId(10), kind: EnumDiscriminant { - index: StatePartIndex(1), - ty: Enum { - HdlNone, - HdlSome(Bundle {0: UInt<1>, 1: Bool}), - }, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(11), - kind: BigUInt { - index: StatePartIndex(16), - ty: UInt<1>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(12), - kind: BigBool { - index: StatePartIndex(17), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(13), - kind: EnumDiscriminant { - index: StatePartIndex(6), + index: StatePartIndex(5), ty: Enum { A, B(Bundle {0: UInt<1>, 1: Bool}), @@ -1860,6 +1931,32 @@ Simulation { state: 0x2, last_state: 0x2, }, + SimTrace { + id: TraceScalarId(11), + kind: BigUInt { + index: StatePartIndex(19), + ty: UInt<1>, + }, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(12), + kind: BigBool { + index: StatePartIndex(20), + }, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(13), + kind: BigUInt { + index: StatePartIndex(26), + ty: UInt<1>, + }, + state: 0x1, + last_state: 0x1, + }, SimTrace { id: TraceScalarId(14), kind: BigUInt { @@ -1871,34 +1968,8 @@ Simulation { }, SimTrace { id: TraceScalarId(15), - kind: BigBool { - index: StatePartIndex(28), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(16), - kind: BigUInt { - index: StatePartIndex(34), - ty: UInt<1>, - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(17), - kind: BigUInt { - index: StatePartIndex(35), - ty: UInt<1>, - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(18), kind: BigSInt { - index: StatePartIndex(36), + index: StatePartIndex(28), ty: SInt<2>, }, state: 0x3, @@ -1917,7 +1988,7 @@ Simulation { ], instant: 16 μs, clocks_triggered: [ - StatePartIndex(3), + StatePartIndex(2), ], .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/enums.vcd b/crates/fayalite/tests/sim/expected/enums.vcd index aff867b..07cbd32 100644 --- a/crates/fayalite/tests/sim/expected/enums.vcd +++ b/crates/fayalite/tests/sim/expected/enums.vcd @@ -16,25 +16,18 @@ $var wire 1 ) \0 $end $var wire 1 * \1 $end $upscope $end $upscope $end -$scope struct b2_out $end -$var string 1 + \$tag $end -$scope struct HdlSome $end -$var wire 1 , \0 $end -$var wire 1 - \1 $end -$upscope $end -$upscope $end $scope struct the_reg $end -$var string 1 . \$tag $end +$var string 1 + \$tag $end $scope struct B $end -$var reg 1 / \0 $end -$var reg 1 0 \1 $end +$var reg 1 , \0 $end +$var reg 1 - \1 $end $upscope $end $scope struct C $end $scope struct a $end -$var reg 1 1 \[0] $end -$var reg 1 2 \[1] $end +$var reg 1 . \[0] $end +$var reg 1 / \[1] $end $upscope $end -$var reg 2 3 b $end +$var reg 2 0 b $end $upscope $end $upscope $end $upscope $end @@ -50,15 +43,12 @@ b0 ' sHdlNone\x20(0) ( 0) 0* -sHdlNone\x20(0) + +sA\x20(0) + 0, 0- -sA\x20(0) . +0. 0/ -00 -01 -02 -b0 3 +b0 0 $end #1000000 1! @@ -76,8 +66,7 @@ b1 $ 1! b1 & sHdlSome\x20(1) ( -sHdlSome\x20(1) + -sB\x20(1) . +sB\x20(1) + #6000000 0# b0 $ @@ -96,10 +85,8 @@ b11 ' 1* 1, 1- +1. 1/ -10 -11 -12 #10000000 0! #11000000 @@ -114,11 +101,8 @@ b1111 ' sHdlNone\x20(0) ( 0) 0* -sHdlNone\x20(0) + -0, -0- -sC\x20(2) . -b11 3 +sC\x20(2) + +b11 0 #14000000 0! #15000000 diff --git a/crates/fayalite/tests/sim/expected/extern_module.txt b/crates/fayalite/tests/sim/expected/extern_module.txt deleted file mode 100644 index 6cce70b..0000000 --- a/crates/fayalite/tests/sim/expected/extern_module.txt +++ /dev/null @@ -1,220 +0,0 @@ -Simulation { - state: State { - insns: Insns { - state_layout: StateLayout { - ty: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 2, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(extern_module: extern_module).extern_module::i", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(extern_module: extern_module).extern_module::o", - ty: Bool, - }, - ], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 1, - 1, - ], - }, - }, - io: Instance { - name: ::extern_module, - instantiated: Module { - name: extern_module, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::extern_module, - instantiated: Module { - name: extern_module, - .. - }, - }.i, - Instance { - name: ::extern_module, - instantiated: Module { - name: extern_module, - .. - }, - }.o, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::extern_module, - instantiated: Module { - name: extern_module, - .. - }, - }.i, - Instance { - name: ::extern_module, - instantiated: Module { - name: extern_module, - .. - }, - }.o, - }, - did_initial_settle: true, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: extern_module::i, - is_input: true, - ty: Bool, - .. - }, - ModuleIO { - name: extern_module::o, - is_input: false, - ty: Bool, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: extern_module::i, - is_input: true, - ty: Bool, - .. - }, - ModuleIO { - name: extern_module::o, - is_input: false, - ty: Bool, - .. - }, - }, - did_initial_settle: true, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: extern_module::i, - is_input: true, - ty: Bool, - .. - }, - ModuleIO { - name: extern_module::o, - is_input: false, - ty: Bool, - .. - }, - ), - f: ..., - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - wait_targets: { - Instant( - 20.500000000000 μs, - ), - }, - }, - ], - state_ready_to_run: false, - trace_decls: TraceModule { - name: "extern_module", - children: [ - TraceModuleIO { - name: "i", - child: TraceBool { - location: TraceScalarId(0), - name: "i", - flow: Source, - }, - ty: Bool, - flow: Source, - }, - TraceModuleIO { - name: "o", - child: TraceBool { - location: TraceScalarId(1), - name: "o", - flow: Sink, - }, - ty: Bool, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigBool { - index: StatePartIndex(0), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigBool { - index: StatePartIndex(1), - }, - state: 0x1, - last_state: 0x1, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - instant: 20 μs, - clocks_triggered: [], - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/extern_module.vcd b/crates/fayalite/tests/sim/expected/extern_module.vcd deleted file mode 100644 index e026a50..0000000 --- a/crates/fayalite/tests/sim/expected/extern_module.vcd +++ /dev/null @@ -1,51 +0,0 @@ -$timescale 1 ps $end -$scope module extern_module $end -$var wire 1 ! i $end -$var wire 1 " o $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -1" -$end -#500000 -#1500000 -0" -#2500000 -1" -#3500000 -0" -#4500000 -1" -#5500000 -0" -#6500000 -1" -#7500000 -0" -#8500000 -1" -#9500000 -0" -#10000000 -1! -#10500000 -#11500000 -1" -#12500000 -0" -#13500000 -1" -#14500000 -0" -#15500000 -1" -#16500000 -0" -#17500000 -1" -#18500000 -0" -#19500000 -1" -#20000000 diff --git a/crates/fayalite/tests/sim/expected/extern_module2.txt b/crates/fayalite/tests/sim/expected/extern_module2.txt deleted file mode 100644 index ec842ff..0000000 --- a/crates/fayalite/tests/sim/expected/extern_module2.txt +++ /dev/null @@ -1,310 +0,0 @@ -Simulation { - state: State { - insns: Insns { - state_layout: StateLayout { - ty: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(extern_module2: extern_module2).extern_module2::en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(extern_module2: extern_module2).extern_module2::clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(extern_module2: extern_module2).extern_module2::o", - ty: UInt<8>, - }, - ], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 0, - 1, - 101, - ], - }, - }, - io: Instance { - name: ::extern_module2, - instantiated: Module { - name: extern_module2, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::extern_module2, - instantiated: Module { - name: extern_module2, - .. - }, - }.en, - Instance { - name: ::extern_module2, - instantiated: Module { - name: extern_module2, - .. - }, - }.clk, - Instance { - name: ::extern_module2, - instantiated: Module { - name: extern_module2, - .. - }, - }.o, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::extern_module2, - instantiated: Module { - name: extern_module2, - .. - }, - }.clk, - Instance { - name: ::extern_module2, - instantiated: Module { - name: extern_module2, - .. - }, - }.en, - Instance { - name: ::extern_module2, - instantiated: Module { - name: extern_module2, - .. - }, - }.o, - }, - did_initial_settle: true, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: extern_module2::en, - is_input: true, - ty: Bool, - .. - }, - ModuleIO { - name: extern_module2::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: extern_module2::o, - is_input: false, - ty: UInt<8>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: extern_module2::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: extern_module2::en, - is_input: true, - ty: Bool, - .. - }, - ModuleIO { - name: extern_module2::o, - is_input: false, - ty: UInt<8>, - .. - }, - }, - did_initial_settle: true, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: extern_module2::en, - is_input: true, - ty: Bool, - .. - }, - ModuleIO { - name: extern_module2::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: extern_module2::o, - is_input: false, - ty: UInt<8>, - .. - }, - ), - f: ..., - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:5:1, - ), - }, - running_generator: Some( - ..., - ), - wait_targets: { - Change { - key: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(extern_module2: extern_module2).extern_module2::clk", - ty: Clock, - }, - ], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - }, - write: None, - }, - value: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x1_u1, - }, - }, - }, - }, - }, - ], - state_ready_to_run: false, - trace_decls: TraceModule { - name: "extern_module2", - children: [ - TraceModuleIO { - name: "en", - child: TraceBool { - location: TraceScalarId(0), - name: "en", - flow: Source, - }, - ty: Bool, - flow: Source, - }, - TraceModuleIO { - name: "clk", - child: TraceClock { - location: TraceScalarId(1), - name: "clk", - flow: Source, - }, - ty: Clock, - flow: Source, - }, - TraceModuleIO { - name: "o", - child: TraceUInt { - location: TraceScalarId(2), - name: "o", - ty: UInt<8>, - flow: Sink, - }, - ty: UInt<8>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigBool { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigClock { - index: StatePartIndex(1), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigUInt { - index: StatePartIndex(2), - ty: UInt<8>, - }, - state: 0x65, - last_state: 0x65, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - instant: 60 μs, - clocks_triggered: [], - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/extern_module2.vcd b/crates/fayalite/tests/sim/expected/extern_module2.vcd deleted file mode 100644 index 464f4bd..0000000 --- a/crates/fayalite/tests/sim/expected/extern_module2.vcd +++ /dev/null @@ -1,150 +0,0 @@ -$timescale 1 ps $end -$scope module extern_module2 $end -$var wire 1 ! en $end -$var wire 1 " clk $end -$var wire 8 # o $end -$upscope $end -$enddefinitions $end -$dumpvars -1! -0" -b1001000 # -$end -#1000000 -1" -b1100101 # -#2000000 -0" -#3000000 -1" -b1101100 # -#4000000 -0" -#5000000 -1" -#6000000 -0" -#7000000 -1" -b1101111 # -#8000000 -0" -#9000000 -1" -b101100 # -#10000000 -0! -0" -#11000000 -1" -#12000000 -0" -#13000000 -1" -#14000000 -0" -#15000000 -1" -#16000000 -0" -#17000000 -1" -#18000000 -0" -#19000000 -1" -#20000000 -1! -0" -#21000000 -1" -b100000 # -#22000000 -0" -#23000000 -1" -b1010111 # -#24000000 -0" -#25000000 -1" -b1101111 # -#26000000 -0" -#27000000 -1" -b1110010 # -#28000000 -0" -#29000000 -1" -b1101100 # -#30000000 -0! -0" -#31000000 -1" -#32000000 -0" -#33000000 -1" -#34000000 -0" -#35000000 -1" -#36000000 -0" -#37000000 -1" -#38000000 -0" -#39000000 -1" -#40000000 -1! -0" -#41000000 -1" -b1100100 # -#42000000 -0" -#43000000 -1" -b100001 # -#44000000 -0" -#45000000 -1" -b1010 # -#46000000 -0" -#47000000 -1" -b1001000 # -#48000000 -0" -#49000000 -1" -b1100101 # -#50000000 -0! -0" -#51000000 -1" -#52000000 -0" -#53000000 -1" -#54000000 -0" -#55000000 -1" -#56000000 -0" -#57000000 -1" -#58000000 -0" -#59000000 -1" -#60000000 diff --git a/crates/fayalite/tests/sim/expected/memories.txt b/crates/fayalite/tests/sim/expected/memories.txt index cd778d4..afccd8a 100644 --- a/crates/fayalite/tests/sim/expected/memories.txt +++ b/crates/fayalite/tests/sim/expected/memories.txt @@ -570,149 +570,1309 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.r: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<4>, + /* offset = 4 */ + en: Bool, + /* offset = 5 */ + clk: Clock, + #[hdl(flip)] /* offset = 6 */ + data: Bundle { + /* offset = 0 */ + 0: UInt<8>, + /* offset = 8 */ + 1: SInt<8>, + }, }, - }.r, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 5, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::r.addr", + ty: UInt<4>, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::r.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::r.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::r.data.0", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::r.data.1", + ty: SInt<8>, + }, + ], + .. + }, }, - }.w, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + 0: UInt<8>, + /* offset = 8 */ + 1: SInt<8>, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: ".0", + ty: UInt<8>, + }, + SlotDebugData { + name: ".1", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + }, + ], }, - }.r, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.r.addr, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.r.clk, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.r.data, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.r.data.0, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.r.data.1, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.r.en, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.addr, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.clk, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.data, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.data.0, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.data.1, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.en, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.mask, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.mask.0, - Instance { - name: ::memories, - instantiated: Module { - name: memories, - .. - }, - }.w.mask.1, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 5 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.r.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.r.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.r.data: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + 0: UInt<8>, + /* offset = 8 */ + 1: SInt<8>, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: ".0", + ty: UInt<8>, + }, + SlotDebugData { + name: ".1", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 2 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.r.data.0: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.r.data.1: CompiledValue { + layout: CompiledTypeLayout { + ty: SInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.r.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<4>, + /* offset = 4 */ + en: Bool, + /* offset = 5 */ + clk: Clock, + /* offset = 6 */ + data: Bundle { + /* offset = 0 */ + 0: UInt<8>, + /* offset = 8 */ + 1: SInt<8>, + }, + /* offset = 22 */ + mask: Bundle { + /* offset = 0 */ + 0: Bool, + /* offset = 1 */ + 1: Bool, + }, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 7, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::w.addr", + ty: UInt<4>, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::w.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::w.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::w.data.0", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::w.data.1", + ty: SInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::w.mask.0", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories: memories).memories::w.mask.1", + ty: Bool, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + 0: UInt<8>, + /* offset = 8 */ + 1: SInt<8>, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: ".0", + ty: UInt<8>, + }, + SlotDebugData { + name: ".1", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(5), + }, + ty: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + 0: Bool, + /* offset = 1 */ + 1: Bool, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: ".0", + ty: Bool, + }, + SlotDebugData { + name: ".1", + ty: Bool, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 7 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 7, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.data: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + 0: UInt<8>, + /* offset = 8 */ + 1: SInt<8>, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: ".0", + ty: UInt<8>, + }, + SlotDebugData { + name: ".1", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 8, len: 2 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.data.0: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 8, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.data.1: CompiledValue { + layout: CompiledTypeLayout { + ty: SInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 9, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 6, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.mask: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + 0: Bool, + /* offset = 1 */ + 1: Bool, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: ".0", + ty: Bool, + }, + SlotDebugData { + name: ".1", + ty: Bool, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 10, len: 2 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.mask.0: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 10, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories, + instantiated: Module { + name: memories, + .. + }, + }.w.mask.1: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 11, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "memories", children: [ diff --git a/crates/fayalite/tests/sim/expected/memories2.txt b/crates/fayalite/tests/sim/expected/memories2.txt index 2359749..5d90815 100644 --- a/crates/fayalite/tests/sim/expected/memories2.txt +++ b/crates/fayalite/tests/sim/expected/memories2.txt @@ -598,79 +598,514 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: UInt<2>, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: UInt<2>, + /* offset = 10 */ + wmask: Bool, }, - }.rw, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 7, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.rdata", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wmode", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wdata", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wmask", + ty: Bool, + }, + ], + .. + }, }, - }.rw, - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(4), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(5), + }, + ty: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(6), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], }, - }.rw.addr, - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. - }, - }.rw.clk, - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. - }, - }.rw.en, - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. - }, - }.rw.rdata, - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. - }, - }.rw.wdata, - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. - }, - }.rw.wmask, - Instance { - name: ::memories2, - instantiated: Module { - name: memories2, - .. - }, - }.rw.wmode, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 7 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.rdata: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.wdata: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.wmask: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 6, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.wmode: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "memories2", children: [ diff --git a/crates/fayalite/tests/sim/expected/memories3.txt b/crates/fayalite/tests/sim/expected/memories3.txt index ad12aa4..7860bc5 100644 --- a/crates/fayalite/tests/sim/expected/memories3.txt +++ b/crates/fayalite/tests/sim/expected/memories3.txt @@ -1486,275 +1486,1882 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, }, - }.r, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 11, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[7]", + ty: UInt<8>, + }, + ], + .. + }, }, - }.w, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + }, + ], }, - }.r, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.addr, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.clk, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[0], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[1], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[2], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[3], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[4], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[5], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[6], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.data[7], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.r.en, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.addr, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.clk, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[0], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[1], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[2], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[3], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[4], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[5], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[6], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.data[7], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.en, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask, - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[0], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[1], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[2], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[3], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[4], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[5], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[6], - Instance { - name: ::memories3, - instantiated: Module { - name: memories3, - .. - }, - }.w.mask[7], + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 11 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 8 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 6, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 7, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 8, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 9, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 10, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 19, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[0]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[1]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[2]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[3]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[4]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[5]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[6]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[7]", + ty: Bool, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(11), + }, + ty: CompiledTypeLayout { + ty: Array, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: Bool, + }, + SlotDebugData { + name: "[1]", + ty: Bool, + }, + SlotDebugData { + name: "[2]", + ty: Bool, + }, + SlotDebugData { + name: "[3]", + ty: Bool, + }, + SlotDebugData { + name: "[4]", + ty: Bool, + }, + SlotDebugData { + name: "[5]", + ty: Bool, + }, + SlotDebugData { + name: "[6]", + ty: Bool, + }, + SlotDebugData { + name: "[7]", + ty: Bool, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 11, len: 19 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 11, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 13, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 14, len: 8 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 14, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 15, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 16, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 17, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 18, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 19, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 20, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 21, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 12, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: Bool, + }, + SlotDebugData { + name: "[1]", + ty: Bool, + }, + SlotDebugData { + name: "[2]", + ty: Bool, + }, + SlotDebugData { + name: "[3]", + ty: Bool, + }, + SlotDebugData { + name: "[4]", + ty: Bool, + }, + SlotDebugData { + name: "[5]", + ty: Bool, + }, + SlotDebugData { + name: "[6]", + ty: Bool, + }, + SlotDebugData { + name: "[7]", + ty: Bool, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 22, len: 8 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 22, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 23, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 24, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 25, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 26, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 27, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 28, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 29, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "memories3", children: [ diff --git a/crates/fayalite/tests/sim/expected/mod1.txt b/crates/fayalite/tests/sim/expected/mod1.txt index 3656247..5c2b7eb 100644 --- a/crates/fayalite/tests/sim/expected/mod1.txt +++ b/crates/fayalite/tests/sim/expected/mod1.txt @@ -216,58 +216,313 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::mod1, - instantiated: Module { - name: mod1, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::mod1, + instantiated: Module { + name: mod1, + .. + }, + }.o: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + #[hdl(flip)] /* offset = 0 */ + i: UInt<4>, + /* offset = 4 */ + o: SInt<2>, + #[hdl(flip)] /* offset = 6 */ + i2: SInt<2>, + /* offset = 8 */ + o2: UInt<4>, }, - }.o, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::mod1, - instantiated: Module { - name: mod1, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 4, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(mod1: mod1).mod1::o.i", + ty: UInt<4>, + }, + SlotDebugData { + name: "InstantiatedModule(mod1: mod1).mod1::o.o", + ty: SInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(mod1: mod1).mod1::o.i2", + ty: SInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(mod1: mod1).mod1::o.o2", + ty: UInt<4>, + }, + ], + .. + }, }, - }.o, - Instance { - name: ::mod1, - instantiated: Module { - name: mod1, - .. + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: SInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], }, - }.o.i, - Instance { - name: ::mod1, - instantiated: Module { - name: mod1, - .. - }, - }.o.i2, - Instance { - name: ::mod1, - instantiated: Module { - name: mod1, - .. - }, - }.o.o, - Instance { - name: ::mod1, - instantiated: Module { - name: mod1, - .. - }, - }.o.o2, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 4 }, + }, + write: None, + }, + Instance { + name: ::mod1, + instantiated: Module { + name: mod1, + .. + }, + }.o.i: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::mod1, + instantiated: Module { + name: mod1, + .. + }, + }.o.i2: CompiledValue { + layout: CompiledTypeLayout { + ty: SInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::mod1, + instantiated: Module { + name: mod1, + .. + }, + }.o.o: CompiledValue { + layout: CompiledTypeLayout { + ty: SInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::mod1, + instantiated: Module { + name: mod1, + .. + }, + }.o.o2: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<4>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<4>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "mod1", children: [ diff --git a/crates/fayalite/tests/sim/expected/ripple_counter.txt b/crates/fayalite/tests/sim/expected/ripple_counter.txt deleted file mode 100644 index 5472950..0000000 --- a/crates/fayalite/tests/sim/expected/ripple_counter.txt +++ /dev/null @@ -1,1498 +0,0 @@ -Simulation { - state: State { - insns: Insns { - state_layout: StateLayout { - ty: TypeLayout { - small_slots: StatePartLayout { - len: 9, - debug_data: [ - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - ], - .. - }, - big_slots: StatePartLayout { - len: 58, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::o", - ty: UInt<6>, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[0]", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[1]", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[2]", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[3]", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[4]", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[5]", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: UInt<2>, - }, - SlotDebugData { - name: "", - ty: UInt<2>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: UInt<3>, - }, - SlotDebugData { - name: "", - ty: UInt<3>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: UInt<5>, - }, - SlotDebugData { - name: "", - ty: UInt<5>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: UInt<6>, - }, - SlotDebugData { - name: "", - ty: UInt<6>, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_0", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_0$next", - ty: Bool, - }, - SlotDebugData { - name: ".clk", - ty: Clock, - }, - SlotDebugData { - name: ".rst", - ty: SyncReset, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: SyncReset, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_1.o", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::o", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_2", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_2$next", - ty: Bool, - }, - SlotDebugData { - name: ".clk", - ty: Clock, - }, - SlotDebugData { - name: ".rst", - ty: SyncReset, - }, - SlotDebugData { - name: "", - ty: Clock, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_3.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_3.o", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::o", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_4", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_4$next", - ty: Bool, - }, - SlotDebugData { - name: ".clk", - ty: Clock, - }, - SlotDebugData { - name: ".rst", - ty: SyncReset, - }, - SlotDebugData { - name: "", - ty: Clock, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_5.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_5.o", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::o", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Clock, - }, - ], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:9:1 - 0: Copy { - dest: StatePartIndex(54), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_5.o", ty: Bool }, - src: StatePartIndex(56), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::o", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:11:1 - 1: Copy { - dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[5]", ty: Bool }, - src: StatePartIndex(54), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_5.o", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 2: NotU { - dest: StatePartIndex(52), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(47), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_4", ty: Bool }, - width: 1, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 3: Copy { - dest: StatePartIndex(48), // (0x1) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_4$next", ty: Bool }, - src: StatePartIndex(52), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:7:1 - 4: Copy { - dest: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[4]", ty: Bool }, - src: StatePartIndex(47), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_4", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 5: Copy { - dest: StatePartIndex(57), // (0x0) SlotDebugData { name: "", ty: Clock }, - src: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[4]", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:10:1 - 6: Copy { - dest: StatePartIndex(53), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_5.clk", ty: Clock }, - src: StatePartIndex(57), // (0x0) SlotDebugData { name: "", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:9:1 - 7: Copy { - dest: StatePartIndex(55), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::clk", ty: Clock }, - src: StatePartIndex(53), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_5.clk", ty: Clock }, - }, - 8: Copy { - dest: StatePartIndex(43), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_3.o", ty: Bool }, - src: StatePartIndex(45), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::o", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:11:1 - 9: Copy { - dest: StatePartIndex(5), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[3]", ty: Bool }, - src: StatePartIndex(43), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_3.o", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 10: Copy { - dest: StatePartIndex(51), // (0x0) SlotDebugData { name: "", ty: Clock }, - src: StatePartIndex(5), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[3]", ty: Bool }, - }, - 11: NotU { - dest: StatePartIndex(41), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(36), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_2", ty: Bool }, - width: 1, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 12: Copy { - dest: StatePartIndex(37), // (0x1) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_2$next", ty: Bool }, - src: StatePartIndex(41), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:7:1 - 13: Copy { - dest: StatePartIndex(4), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[2]", ty: Bool }, - src: StatePartIndex(36), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_2", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 14: Copy { - dest: StatePartIndex(46), // (0x0) SlotDebugData { name: "", ty: Clock }, - src: StatePartIndex(4), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[2]", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:10:1 - 15: Copy { - dest: StatePartIndex(42), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_3.clk", ty: Clock }, - src: StatePartIndex(46), // (0x0) SlotDebugData { name: "", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:9:1 - 16: Copy { - dest: StatePartIndex(44), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::clk", ty: Clock }, - src: StatePartIndex(42), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_3.clk", ty: Clock }, - }, - 17: Copy { - dest: StatePartIndex(32), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_1.o", ty: Bool }, - src: StatePartIndex(34), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::o", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:11:1 - 18: Copy { - dest: StatePartIndex(3), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[1]", ty: Bool }, - src: StatePartIndex(32), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_1.o", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 19: Copy { - dest: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Clock }, - src: StatePartIndex(3), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[1]", ty: Bool }, - }, - 20: NotU { - dest: StatePartIndex(30), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(24), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_0", ty: Bool }, - width: 1, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 21: Copy { - dest: StatePartIndex(25), // (0x1) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_0$next", ty: Bool }, - src: StatePartIndex(30), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:7:1 - 22: Copy { - dest: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[0]", ty: Bool }, - src: StatePartIndex(24), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_0", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 23: Copy { - dest: StatePartIndex(35), // (0x0) SlotDebugData { name: "", ty: Clock }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[0]", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:10:1 - 24: Copy { - dest: StatePartIndex(31), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_1.clk", ty: Clock }, - src: StatePartIndex(35), // (0x0) SlotDebugData { name: "", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:9:1 - 25: Copy { - dest: StatePartIndex(33), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::clk", ty: Clock }, - src: StatePartIndex(31), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_1.clk", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 26: Const { - dest: StatePartIndex(28), // (0x0) SlotDebugData { name: "", ty: Bool }, - value: 0x0, - }, - 27: Copy { - dest: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: SyncReset }, - src: StatePartIndex(28), // (0x0) SlotDebugData { name: "", ty: Bool }, - }, - 28: Copy { - dest: StatePartIndex(26), // (0x1) SlotDebugData { name: ".clk", ty: Clock }, - src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::clk", ty: Clock }, - }, - 29: Copy { - dest: StatePartIndex(27), // (0x0) SlotDebugData { name: ".rst", ty: SyncReset }, - src: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: SyncReset }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 30: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(26), // (0x1) SlotDebugData { name: ".clk", ty: Clock }, - }, - 31: 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 }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 32: Copy { - dest: StatePartIndex(38), // (0x0) SlotDebugData { name: ".clk", ty: Clock }, - src: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Clock }, - }, - 33: Copy { - dest: StatePartIndex(39), // (0x0) SlotDebugData { name: ".rst", ty: SyncReset }, - src: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: SyncReset }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 34: IsNonZeroDestIsSmall { - dest: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(38), // (0x0) SlotDebugData { name: ".clk", ty: Clock }, - }, - 35: AndSmall { - dest: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 36: Copy { - dest: StatePartIndex(49), // (0x0) SlotDebugData { name: ".clk", ty: Clock }, - src: StatePartIndex(51), // (0x0) SlotDebugData { name: "", ty: Clock }, - }, - 37: Copy { - dest: StatePartIndex(50), // (0x0) SlotDebugData { name: ".rst", ty: SyncReset }, - src: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: SyncReset }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 38: IsNonZeroDestIsSmall { - dest: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(49), // (0x0) SlotDebugData { name: ".clk", ty: Clock }, - }, - 39: AndSmall { - dest: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(6), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 40: Copy { - dest: StatePartIndex(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[5]", ty: Bool }, - }, - 41: Shl { - dest: StatePartIndex(22), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, - lhs: StatePartIndex(21), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - rhs: 5, - }, - 42: Copy { - dest: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[4]", ty: Bool }, - }, - 43: Shl { - dest: StatePartIndex(19), // (0x0) SlotDebugData { name: "", ty: UInt<5> }, - lhs: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - rhs: 4, - }, - 44: Copy { - dest: StatePartIndex(15), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(5), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[3]", ty: Bool }, - }, - 45: Shl { - dest: StatePartIndex(16), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(15), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - rhs: 3, - }, - 46: Copy { - dest: StatePartIndex(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(4), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[2]", ty: Bool }, - }, - 47: Shl { - dest: StatePartIndex(13), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, - lhs: StatePartIndex(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - rhs: 2, - }, - 48: Copy { - dest: StatePartIndex(9), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(3), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[1]", ty: Bool }, - }, - 49: Shl { - dest: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(9), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - rhs: 1, - }, - 50: Copy { - dest: StatePartIndex(8), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bits[0]", ty: Bool }, - }, - 51: Or { - dest: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(8), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - rhs: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - }, - 52: Or { - dest: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, - lhs: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - rhs: StatePartIndex(13), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, - }, - 53: Or { - dest: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, - rhs: StatePartIndex(16), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 54: Or { - dest: StatePartIndex(20), // (0x0) SlotDebugData { name: "", ty: UInt<5> }, - lhs: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, - rhs: StatePartIndex(19), // (0x0) SlotDebugData { name: "", ty: UInt<5> }, - }, - 55: Or { - dest: StatePartIndex(23), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, - lhs: StatePartIndex(20), // (0x0) SlotDebugData { name: "", ty: UInt<5> }, - rhs: StatePartIndex(22), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, - }, - // at: module-XXXXXXXXXX.rs:5:1 - 56: Copy { - dest: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::o", ty: UInt<6> }, - src: StatePartIndex(23), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 57: BranchIfSmallZero { - target: 59, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 58: Copy { - dest: StatePartIndex(24), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_0", ty: Bool }, - src: StatePartIndex(25), // (0x1) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_0$next", ty: Bool }, - }, - 59: BranchIfSmallZero { - target: 61, - value: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 60: Copy { - dest: StatePartIndex(36), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_2", ty: Bool }, - src: StatePartIndex(37), // (0x1) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_2$next", ty: Bool }, - }, - 61: BranchIfSmallZero { - target: 63, - value: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 62: Copy { - dest: StatePartIndex(47), // (0x0) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_4", ty: Bool }, - src: StatePartIndex(48), // (0x1) SlotDebugData { name: "InstantiatedModule(ripple_counter: ripple_counter).ripple_counter::bit_reg_4$next", ty: Bool }, - }, - 63: XorSmallImmediate { - dest: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 64: XorSmallImmediate { - dest: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 65: XorSmallImmediate { - dest: StatePartIndex(6), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 66: Return, - ], - .. - }, - pc: 66, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [ - 0, - 0, - 1, - 1, - 0, - 0, - 1, - 0, - 0, - ], - }, - big_slots: StatePart { - value: [ - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - ], - }, - }, - io: Instance { - name: ::ripple_counter, - instantiated: Module { - name: ripple_counter, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::ripple_counter, - instantiated: Module { - name: ripple_counter, - .. - }, - }.clk, - Instance { - name: ::ripple_counter, - instantiated: Module { - name: ripple_counter, - .. - }, - }.o, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::ripple_counter, - instantiated: Module { - name: ripple_counter, - .. - }, - }.clk, - Instance { - name: ::ripple_counter, - instantiated: Module { - name: ripple_counter, - .. - }, - }.o, - }, - did_initial_settle: true, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - }, - did_initial_settle: true, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - ), - f: ..., - }, - source_location: SourceLocation( - module-XXXXXXXXXX-2.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - wait_targets: { - Change { - key: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_1: sw_reg).sw_reg::clk", - ty: Clock, - }, - ], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 33, len: 1 }, - }, - write: None, - }, - value: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - }, - }, - }, - }, - }, - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - }, - did_initial_settle: true, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - ), - f: ..., - }, - source_location: SourceLocation( - module-XXXXXXXXXX-2.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - wait_targets: { - Change { - key: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_3: sw_reg).sw_reg::clk", - ty: Clock, - }, - ], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 44, len: 1 }, - }, - write: None, - }, - value: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - }, - }, - }, - }, - }, - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - }, - did_initial_settle: true, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sw_reg::clk, - is_input: true, - ty: Clock, - .. - }, - ModuleIO { - name: sw_reg::o, - is_input: false, - ty: Bool, - .. - }, - ), - f: ..., - }, - source_location: SourceLocation( - module-XXXXXXXXXX-2.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - wait_targets: { - Change { - key: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(ripple_counter.bit_reg_5: sw_reg).sw_reg::clk", - ty: Clock, - }, - ], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 55, len: 1 }, - }, - write: None, - }, - value: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - }, - }, - }, - }, - }, - ], - state_ready_to_run: false, - trace_decls: TraceModule { - name: "ripple_counter", - children: [ - TraceModuleIO { - name: "clk", - child: TraceClock { - location: TraceScalarId(0), - name: "clk", - flow: Source, - }, - ty: Clock, - flow: Source, - }, - TraceModuleIO { - name: "o", - child: TraceUInt { - location: TraceScalarId(1), - name: "o", - ty: UInt<6>, - flow: Sink, - }, - ty: UInt<6>, - flow: Sink, - }, - TraceWire { - name: "bits", - child: TraceArray { - name: "bits", - elements: [ - TraceBool { - location: TraceScalarId(2), - name: "[0]", - flow: Duplex, - }, - TraceBool { - location: TraceScalarId(3), - name: "[1]", - flow: Duplex, - }, - TraceBool { - location: TraceScalarId(4), - name: "[2]", - flow: Duplex, - }, - TraceBool { - location: TraceScalarId(5), - name: "[3]", - flow: Duplex, - }, - TraceBool { - location: TraceScalarId(6), - name: "[4]", - flow: Duplex, - }, - TraceBool { - location: TraceScalarId(7), - name: "[5]", - flow: Duplex, - }, - ], - ty: Array, - flow: Duplex, - }, - ty: Array, - }, - TraceReg { - name: "bit_reg_0", - child: TraceBool { - location: TraceScalarId(8), - name: "bit_reg_0", - flow: Duplex, - }, - ty: Bool, - }, - TraceInstance { - name: "bit_reg_1", - instance_io: TraceBundle { - name: "bit_reg_1", - fields: [ - TraceClock { - location: TraceScalarId(11), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(12), - name: "o", - flow: Source, - }, - ], - ty: Bundle { - #[hdl(flip)] /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - o: Bool, - }, - flow: Source, - }, - module: TraceModule { - name: "sw_reg", - children: [ - TraceModuleIO { - name: "clk", - child: TraceClock { - location: TraceScalarId(9), - name: "clk", - flow: Source, - }, - ty: Clock, - flow: Source, - }, - TraceModuleIO { - name: "o", - child: TraceBool { - location: TraceScalarId(10), - name: "o", - flow: Sink, - }, - ty: Bool, - flow: Sink, - }, - ], - }, - ty: Bundle { - #[hdl(flip)] /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - o: Bool, - }, - }, - TraceReg { - name: "bit_reg_2", - child: TraceBool { - location: TraceScalarId(13), - name: "bit_reg_2", - flow: Duplex, - }, - ty: Bool, - }, - TraceInstance { - name: "bit_reg_3", - instance_io: TraceBundle { - name: "bit_reg_3", - fields: [ - TraceClock { - location: TraceScalarId(16), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(17), - name: "o", - flow: Source, - }, - ], - ty: Bundle { - #[hdl(flip)] /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - o: Bool, - }, - flow: Source, - }, - module: TraceModule { - name: "sw_reg", - children: [ - TraceModuleIO { - name: "clk", - child: TraceClock { - location: TraceScalarId(14), - name: "clk", - flow: Source, - }, - ty: Clock, - flow: Source, - }, - TraceModuleIO { - name: "o", - child: TraceBool { - location: TraceScalarId(15), - name: "o", - flow: Sink, - }, - ty: Bool, - flow: Sink, - }, - ], - }, - ty: Bundle { - #[hdl(flip)] /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - o: Bool, - }, - }, - TraceReg { - name: "bit_reg_4", - child: TraceBool { - location: TraceScalarId(18), - name: "bit_reg_4", - flow: Duplex, - }, - ty: Bool, - }, - TraceInstance { - name: "bit_reg_5", - instance_io: TraceBundle { - name: "bit_reg_5", - fields: [ - TraceClock { - location: TraceScalarId(21), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(22), - name: "o", - flow: Source, - }, - ], - ty: Bundle { - #[hdl(flip)] /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - o: Bool, - }, - flow: Source, - }, - module: TraceModule { - name: "sw_reg", - children: [ - TraceModuleIO { - name: "clk", - child: TraceClock { - location: TraceScalarId(19), - name: "clk", - flow: Source, - }, - ty: Clock, - flow: Source, - }, - TraceModuleIO { - name: "o", - child: TraceBool { - location: TraceScalarId(20), - name: "o", - flow: Sink, - }, - ty: Bool, - flow: Sink, - }, - ], - }, - ty: Bundle { - #[hdl(flip)] /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - o: Bool, - }, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigUInt { - index: StatePartIndex(1), - ty: UInt<6>, - }, - state: 0x00, - last_state: 0x00, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigBool { - index: StatePartIndex(2), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(3), - kind: BigBool { - index: StatePartIndex(3), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(4), - kind: BigBool { - index: StatePartIndex(4), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(5), - kind: BigBool { - index: StatePartIndex(5), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(6), - kind: BigBool { - index: StatePartIndex(6), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(7), - kind: BigBool { - index: StatePartIndex(7), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(8), - kind: BigBool { - index: StatePartIndex(24), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(9), - kind: BigClock { - index: StatePartIndex(33), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(10), - kind: BigBool { - index: StatePartIndex(34), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(11), - kind: BigClock { - index: StatePartIndex(31), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(12), - kind: BigBool { - index: StatePartIndex(32), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(13), - kind: BigBool { - index: StatePartIndex(36), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(14), - kind: BigClock { - index: StatePartIndex(44), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(15), - kind: BigBool { - index: StatePartIndex(45), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(16), - kind: BigClock { - index: StatePartIndex(42), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(17), - kind: BigBool { - index: StatePartIndex(43), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(18), - kind: BigBool { - index: StatePartIndex(47), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(19), - kind: BigClock { - index: StatePartIndex(55), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(20), - kind: BigBool { - index: StatePartIndex(56), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(21), - kind: BigClock { - index: StatePartIndex(53), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(22), - kind: BigBool { - index: StatePartIndex(54), - }, - state: 0x0, - last_state: 0x0, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - instant: 256 μs, - clocks_triggered: [ - StatePartIndex(1), - StatePartIndex(4), - StatePartIndex(7), - ], - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/ripple_counter.vcd b/crates/fayalite/tests/sim/expected/ripple_counter.vcd deleted file mode 100644 index 6f14a8e..0000000 --- a/crates/fayalite/tests/sim/expected/ripple_counter.vcd +++ /dev/null @@ -1,1753 +0,0 @@ -$timescale 1 ps $end -$scope module ripple_counter $end -$var wire 1 ! clk $end -$var wire 6 " o $end -$scope struct bits $end -$var wire 1 # \[0] $end -$var wire 1 $ \[1] $end -$var wire 1 % \[2] $end -$var wire 1 & \[3] $end -$var wire 1 ' \[4] $end -$var wire 1 ( \[5] $end -$upscope $end -$var reg 1 ) bit_reg_0 $end -$scope struct bit_reg_1 $end -$var wire 1 , clk $end -$var wire 1 - o $end -$upscope $end -$scope module sw_reg $end -$var wire 1 * clk $end -$var wire 1 + o $end -$upscope $end -$var reg 1 . bit_reg_2 $end -$scope struct bit_reg_3 $end -$var wire 1 1 clk $end -$var wire 1 2 o $end -$upscope $end -$scope module sw_reg_2 $end -$var wire 1 / clk $end -$var wire 1 0 o $end -$upscope $end -$var reg 1 3 bit_reg_4 $end -$scope struct bit_reg_5 $end -$var wire 1 6 clk $end -$var wire 1 7 o $end -$upscope $end -$scope module sw_reg_3 $end -$var wire 1 4 clk $end -$var wire 1 5 o $end -$upscope $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -b0 " -0# -0$ -0% -0& -0' -0( -0) -0* -0+ -0, -0- -0. -0/ -00 -01 -02 -03 -04 -05 -06 -07 -$end -#1000000 -1! -1) -b1 " -1# -1* -1, -1+ -b11 " -1$ -1- -1. -b111 " -1% -1/ -11 -10 -b1111 " -1& -12 -13 -b11111 " -1' -14 -16 -15 -b111111 " -1( -17 -#2000000 -0! -#3000000 -1! -0) -b111110 " -0# -0* -0, -#4000000 -0! -#5000000 -1! -1) -b111111 " -1# -1* -1, -0+ -b111101 " -0$ -0- -#6000000 -0! -#7000000 -1! -0) -b111100 " -0# -0* -0, -#8000000 -0! -#9000000 -1! -1) -b111101 " -1# -1* -1, -1+ -b111111 " -1$ -1- -0. -b111011 " -0% -0/ -01 -#10000000 -0! -#11000000 -1! -0) -b111010 " -0# -0* -0, -#12000000 -0! -#13000000 -1! -1) -b111011 " -1# -1* -1, -0+ -b111001 " -0$ -0- -#14000000 -0! -#15000000 -1! -0) -b111000 " -0# -0* -0, -#16000000 -0! -#17000000 -1! -1) -b111001 " -1# -1* -1, -1+ -b111011 " -1$ -1- -1. -b111111 " -1% -1/ -11 -00 -b110111 " -0& -02 -#18000000 -0! -#19000000 -1! -0) -b110110 " -0# -0* -0, -#20000000 -0! -#21000000 -1! -1) -b110111 " -1# -1* -1, -0+ -b110101 " -0$ -0- -#22000000 -0! -#23000000 -1! -0) -b110100 " -0# -0* -0, -#24000000 -0! -#25000000 -1! -1) -b110101 " -1# -1* -1, -1+ -b110111 " -1$ -1- -0. -b110011 " -0% -0/ -01 -#26000000 -0! -#27000000 -1! -0) -b110010 " -0# -0* -0, -#28000000 -0! -#29000000 -1! -1) -b110011 " -1# -1* -1, -0+ -b110001 " -0$ -0- -#30000000 -0! -#31000000 -1! -0) -b110000 " -0# -0* -0, -#32000000 -0! -#33000000 -1! -1) -b110001 " -1# -1* -1, -1+ -b110011 " -1$ -1- -1. -b110111 " -1% -1/ -11 -10 -b111111 " -1& -12 -03 -b101111 " -0' -04 -06 -#34000000 -0! -#35000000 -1! -0) -b101110 " -0# -0* -0, -#36000000 -0! -#37000000 -1! -1) -b101111 " -1# -1* -1, -0+ -b101101 " -0$ -0- -#38000000 -0! -#39000000 -1! -0) -b101100 " -0# -0* -0, -#40000000 -0! -#41000000 -1! -1) -b101101 " -1# -1* -1, -1+ -b101111 " -1$ -1- -0. -b101011 " -0% -0/ -01 -#42000000 -0! -#43000000 -1! -0) -b101010 " -0# -0* -0, -#44000000 -0! -#45000000 -1! -1) -b101011 " -1# -1* -1, -0+ -b101001 " -0$ -0- -#46000000 -0! -#47000000 -1! -0) -b101000 " -0# -0* -0, -#48000000 -0! -#49000000 -1! -1) -b101001 " -1# -1* -1, -1+ -b101011 " -1$ -1- -1. -b101111 " -1% -1/ -11 -00 -b100111 " -0& -02 -#50000000 -0! -#51000000 -1! -0) -b100110 " -0# -0* -0, -#52000000 -0! -#53000000 -1! -1) -b100111 " -1# -1* -1, -0+ -b100101 " -0$ -0- -#54000000 -0! -#55000000 -1! -0) -b100100 " -0# -0* -0, -#56000000 -0! -#57000000 -1! -1) -b100101 " -1# -1* -1, -1+ -b100111 " -1$ -1- -0. -b100011 " -0% -0/ -01 -#58000000 -0! -#59000000 -1! -0) -b100010 " -0# -0* -0, -#60000000 -0! -#61000000 -1! -1) -b100011 " -1# -1* -1, -0+ -b100001 " -0$ -0- -#62000000 -0! -#63000000 -1! -0) -b100000 " -0# -0* -0, -#64000000 -0! -#65000000 -1! -1) -b100001 " -1# -1* -1, -1+ -b100011 " -1$ -1- -1. -b100111 " -1% -1/ -11 -10 -b101111 " -1& -12 -13 -b111111 " -1' -14 -16 -05 -b11111 " -0( -07 -#66000000 -0! -#67000000 -1! -0) -b11110 " -0# -0* -0, -#68000000 -0! -#69000000 -1! -1) -b11111 " -1# -1* -1, -0+ -b11101 " -0$ -0- -#70000000 -0! -#71000000 -1! -0) -b11100 " -0# -0* -0, -#72000000 -0! -#73000000 -1! -1) -b11101 " -1# -1* -1, -1+ -b11111 " -1$ -1- -0. -b11011 " -0% -0/ -01 -#74000000 -0! -#75000000 -1! -0) -b11010 " -0# -0* -0, -#76000000 -0! -#77000000 -1! -1) -b11011 " -1# -1* -1, -0+ -b11001 " -0$ -0- -#78000000 -0! -#79000000 -1! -0) -b11000 " -0# -0* -0, -#80000000 -0! -#81000000 -1! -1) -b11001 " -1# -1* -1, -1+ -b11011 " -1$ -1- -1. -b11111 " -1% -1/ -11 -00 -b10111 " -0& -02 -#82000000 -0! -#83000000 -1! -0) -b10110 " -0# -0* -0, -#84000000 -0! -#85000000 -1! -1) -b10111 " -1# -1* -1, -0+ -b10101 " -0$ -0- -#86000000 -0! -#87000000 -1! -0) -b10100 " -0# -0* -0, -#88000000 -0! -#89000000 -1! -1) -b10101 " -1# -1* -1, -1+ -b10111 " -1$ -1- -0. -b10011 " -0% -0/ -01 -#90000000 -0! -#91000000 -1! -0) -b10010 " -0# -0* -0, -#92000000 -0! -#93000000 -1! -1) -b10011 " -1# -1* -1, -0+ -b10001 " -0$ -0- -#94000000 -0! -#95000000 -1! -0) -b10000 " -0# -0* -0, -#96000000 -0! -#97000000 -1! -1) -b10001 " -1# -1* -1, -1+ -b10011 " -1$ -1- -1. -b10111 " -1% -1/ -11 -10 -b11111 " -1& -12 -03 -b1111 " -0' -04 -06 -#98000000 -0! -#99000000 -1! -0) -b1110 " -0# -0* -0, -#100000000 -0! -#101000000 -1! -1) -b1111 " -1# -1* -1, -0+ -b1101 " -0$ -0- -#102000000 -0! -#103000000 -1! -0) -b1100 " -0# -0* -0, -#104000000 -0! -#105000000 -1! -1) -b1101 " -1# -1* -1, -1+ -b1111 " -1$ -1- -0. -b1011 " -0% -0/ -01 -#106000000 -0! -#107000000 -1! -0) -b1010 " -0# -0* -0, -#108000000 -0! -#109000000 -1! -1) -b1011 " -1# -1* -1, -0+ -b1001 " -0$ -0- -#110000000 -0! -#111000000 -1! -0) -b1000 " -0# -0* -0, -#112000000 -0! -#113000000 -1! -1) -b1001 " -1# -1* -1, -1+ -b1011 " -1$ -1- -1. -b1111 " -1% -1/ -11 -00 -b111 " -0& -02 -#114000000 -0! -#115000000 -1! -0) -b110 " -0# -0* -0, -#116000000 -0! -#117000000 -1! -1) -b111 " -1# -1* -1, -0+ -b101 " -0$ -0- -#118000000 -0! -#119000000 -1! -0) -b100 " -0# -0* -0, -#120000000 -0! -#121000000 -1! -1) -b101 " -1# -1* -1, -1+ -b111 " -1$ -1- -0. -b11 " -0% -0/ -01 -#122000000 -0! -#123000000 -1! -0) -b10 " -0# -0* -0, -#124000000 -0! -#125000000 -1! -1) -b11 " -1# -1* -1, -0+ -b1 " -0$ -0- -#126000000 -0! -#127000000 -1! -0) -b0 " -0# -0* -0, -#128000000 -0! -#129000000 -1! -1) -b1 " -1# -1* -1, -1+ -b11 " -1$ -1- -1. -b111 " -1% -1/ -11 -10 -b1111 " -1& -12 -13 -b11111 " -1' -14 -16 -15 -b111111 " -1( -17 -#130000000 -0! -#131000000 -1! -0) -b111110 " -0# -0* -0, -#132000000 -0! -#133000000 -1! -1) -b111111 " -1# -1* -1, -0+ -b111101 " -0$ -0- -#134000000 -0! -#135000000 -1! -0) -b111100 " -0# -0* -0, -#136000000 -0! -#137000000 -1! -1) -b111101 " -1# -1* -1, -1+ -b111111 " -1$ -1- -0. -b111011 " -0% -0/ -01 -#138000000 -0! -#139000000 -1! -0) -b111010 " -0# -0* -0, -#140000000 -0! -#141000000 -1! -1) -b111011 " -1# -1* -1, -0+ -b111001 " -0$ -0- -#142000000 -0! -#143000000 -1! -0) -b111000 " -0# -0* -0, -#144000000 -0! -#145000000 -1! -1) -b111001 " -1# -1* -1, -1+ -b111011 " -1$ -1- -1. -b111111 " -1% -1/ -11 -00 -b110111 " -0& -02 -#146000000 -0! -#147000000 -1! -0) -b110110 " -0# -0* -0, -#148000000 -0! -#149000000 -1! -1) -b110111 " -1# -1* -1, -0+ -b110101 " -0$ -0- -#150000000 -0! -#151000000 -1! -0) -b110100 " -0# -0* -0, -#152000000 -0! -#153000000 -1! -1) -b110101 " -1# -1* -1, -1+ -b110111 " -1$ -1- -0. -b110011 " -0% -0/ -01 -#154000000 -0! -#155000000 -1! -0) -b110010 " -0# -0* -0, -#156000000 -0! -#157000000 -1! -1) -b110011 " -1# -1* -1, -0+ -b110001 " -0$ -0- -#158000000 -0! -#159000000 -1! -0) -b110000 " -0# -0* -0, -#160000000 -0! -#161000000 -1! -1) -b110001 " -1# -1* -1, -1+ -b110011 " -1$ -1- -1. -b110111 " -1% -1/ -11 -10 -b111111 " -1& -12 -03 -b101111 " -0' -04 -06 -#162000000 -0! -#163000000 -1! -0) -b101110 " -0# -0* -0, -#164000000 -0! -#165000000 -1! -1) -b101111 " -1# -1* -1, -0+ -b101101 " -0$ -0- -#166000000 -0! -#167000000 -1! -0) -b101100 " -0# -0* -0, -#168000000 -0! -#169000000 -1! -1) -b101101 " -1# -1* -1, -1+ -b101111 " -1$ -1- -0. -b101011 " -0% -0/ -01 -#170000000 -0! -#171000000 -1! -0) -b101010 " -0# -0* -0, -#172000000 -0! -#173000000 -1! -1) -b101011 " -1# -1* -1, -0+ -b101001 " -0$ -0- -#174000000 -0! -#175000000 -1! -0) -b101000 " -0# -0* -0, -#176000000 -0! -#177000000 -1! -1) -b101001 " -1# -1* -1, -1+ -b101011 " -1$ -1- -1. -b101111 " -1% -1/ -11 -00 -b100111 " -0& -02 -#178000000 -0! -#179000000 -1! -0) -b100110 " -0# -0* -0, -#180000000 -0! -#181000000 -1! -1) -b100111 " -1# -1* -1, -0+ -b100101 " -0$ -0- -#182000000 -0! -#183000000 -1! -0) -b100100 " -0# -0* -0, -#184000000 -0! -#185000000 -1! -1) -b100101 " -1# -1* -1, -1+ -b100111 " -1$ -1- -0. -b100011 " -0% -0/ -01 -#186000000 -0! -#187000000 -1! -0) -b100010 " -0# -0* -0, -#188000000 -0! -#189000000 -1! -1) -b100011 " -1# -1* -1, -0+ -b100001 " -0$ -0- -#190000000 -0! -#191000000 -1! -0) -b100000 " -0# -0* -0, -#192000000 -0! -#193000000 -1! -1) -b100001 " -1# -1* -1, -1+ -b100011 " -1$ -1- -1. -b100111 " -1% -1/ -11 -10 -b101111 " -1& -12 -13 -b111111 " -1' -14 -16 -05 -b11111 " -0( -07 -#194000000 -0! -#195000000 -1! -0) -b11110 " -0# -0* -0, -#196000000 -0! -#197000000 -1! -1) -b11111 " -1# -1* -1, -0+ -b11101 " -0$ -0- -#198000000 -0! -#199000000 -1! -0) -b11100 " -0# -0* -0, -#200000000 -0! -#201000000 -1! -1) -b11101 " -1# -1* -1, -1+ -b11111 " -1$ -1- -0. -b11011 " -0% -0/ -01 -#202000000 -0! -#203000000 -1! -0) -b11010 " -0# -0* -0, -#204000000 -0! -#205000000 -1! -1) -b11011 " -1# -1* -1, -0+ -b11001 " -0$ -0- -#206000000 -0! -#207000000 -1! -0) -b11000 " -0# -0* -0, -#208000000 -0! -#209000000 -1! -1) -b11001 " -1# -1* -1, -1+ -b11011 " -1$ -1- -1. -b11111 " -1% -1/ -11 -00 -b10111 " -0& -02 -#210000000 -0! -#211000000 -1! -0) -b10110 " -0# -0* -0, -#212000000 -0! -#213000000 -1! -1) -b10111 " -1# -1* -1, -0+ -b10101 " -0$ -0- -#214000000 -0! -#215000000 -1! -0) -b10100 " -0# -0* -0, -#216000000 -0! -#217000000 -1! -1) -b10101 " -1# -1* -1, -1+ -b10111 " -1$ -1- -0. -b10011 " -0% -0/ -01 -#218000000 -0! -#219000000 -1! -0) -b10010 " -0# -0* -0, -#220000000 -0! -#221000000 -1! -1) -b10011 " -1# -1* -1, -0+ -b10001 " -0$ -0- -#222000000 -0! -#223000000 -1! -0) -b10000 " -0# -0* -0, -#224000000 -0! -#225000000 -1! -1) -b10001 " -1# -1* -1, -1+ -b10011 " -1$ -1- -1. -b10111 " -1% -1/ -11 -10 -b11111 " -1& -12 -03 -b1111 " -0' -04 -06 -#226000000 -0! -#227000000 -1! -0) -b1110 " -0# -0* -0, -#228000000 -0! -#229000000 -1! -1) -b1111 " -1# -1* -1, -0+ -b1101 " -0$ -0- -#230000000 -0! -#231000000 -1! -0) -b1100 " -0# -0* -0, -#232000000 -0! -#233000000 -1! -1) -b1101 " -1# -1* -1, -1+ -b1111 " -1$ -1- -0. -b1011 " -0% -0/ -01 -#234000000 -0! -#235000000 -1! -0) -b1010 " -0# -0* -0, -#236000000 -0! -#237000000 -1! -1) -b1011 " -1# -1* -1, -0+ -b1001 " -0$ -0- -#238000000 -0! -#239000000 -1! -0) -b1000 " -0# -0* -0, -#240000000 -0! -#241000000 -1! -1) -b1001 " -1# -1* -1, -1+ -b1011 " -1$ -1- -1. -b1111 " -1% -1/ -11 -00 -b111 " -0& -02 -#242000000 -0! -#243000000 -1! -0) -b110 " -0# -0* -0, -#244000000 -0! -#245000000 -1! -1) -b111 " -1# -1* -1, -0+ -b101 " -0$ -0- -#246000000 -0! -#247000000 -1! -0) -b100 " -0# -0* -0, -#248000000 -0! -#249000000 -1! -1) -b101 " -1# -1* -1, -1+ -b111 " -1$ -1- -0. -b11 " -0% -0/ -01 -#250000000 -0! -#251000000 -1! -0) -b10 " -0# -0* -0, -#252000000 -0! -#253000000 -1! -1) -b11 " -1# -1* -1, -0+ -b1 " -0$ -0- -#254000000 -0! -#255000000 -1! -0) -b0 " -0# -0* -0, -#256000000 diff --git a/crates/fayalite/tests/sim/expected/shift_register.txt b/crates/fayalite/tests/sim/expected/shift_register.txt index 901cf70..73f6263 100644 --- a/crates/fayalite/tests/sim/expected/shift_register.txt +++ b/crates/fayalite/tests/sim/expected/shift_register.txt @@ -265,72 +265,247 @@ Simulation { .. }, }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::shift_register, + instantiated: Module { + name: shift_register, + .. + }, + }.cd: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + clk: Clock, + /* offset = 1 */ + rst: SyncReset, }, - }.cd, - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 2, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.rst", + ty: SyncReset, + }, + ], + .. + }, }, - }.d, - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: SyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], }, - }.q, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. - }, - }.cd, - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. - }, - }.cd.clk, - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. - }, - }.cd.rst, - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. - }, - }.d, - Instance { - name: ::shift_register, - instantiated: Module { - name: shift_register, - .. - }, - }.q, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 2 }, + }, + write: None, + }, + Instance { + name: ::shift_register, + instantiated: Module { + name: shift_register, + .. + }, + }.cd.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::shift_register, + instantiated: Module { + name: shift_register, + .. + }, + }.cd.rst: CompiledValue { + layout: CompiledTypeLayout { + ty: SyncReset, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: SyncReset, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::shift_register, + instantiated: Module { + name: shift_register, + .. + }, + }.d: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(shift_register: shift_register).shift_register::d", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::shift_register, + instantiated: Module { + name: shift_register, + .. + }, + }.q: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(shift_register: shift_register).shift_register::q", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, }, - did_initial_settle: true, }, - extern_modules: [], - state_ready_to_run: false, + made_initial_step: true, + needs_settle: false, trace_decls: TraceModule { name: "shift_register", children: [ diff --git a/crates/fayalite/tests/ui/simvalue_is_not_internable.rs b/crates/fayalite/tests/ui/simvalue_is_not_internable.rs deleted file mode 100644 index d40990f..0000000 --- a/crates/fayalite/tests/ui/simvalue_is_not_internable.rs +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -//! check that SimValue can't be interned, since equality may ignore types - -use fayalite::{ - intern::{Intern, Interned}, - sim::value::SimValue, -}; - -fn f(v: SimValue<()>) -> Interned> { - Intern::intern_sized(v) -} - -fn main() {} diff --git a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr deleted file mode 100644 index eb8877b..0000000 --- a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr +++ /dev/null @@ -1,178 +0,0 @@ -error[E0277]: `Cell` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:11:26 - | -11 | fn f(v: SimValue<()>) -> Interned> { - | ^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely - | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell`, which is required by `SimValue<()>: Sync` - = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` -note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ -note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` - -error[E0277]: `UnsafeCell>` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:11:26 - | -11 | fn f(v: SimValue<()>) -> Interned> { - | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely - | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>`, which is required by `SimValue<()>: Sync` -note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ -note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` - -error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied - --> tests/ui/simvalue_is_not_internable.rs:12:26 - | -12 | Intern::intern_sized(v) - | -------------------- ^ the trait `Hash` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern` - | | - | required by a bound introduced by this call - | - = help: the following other types implement trait `Intern`: - BitSlice - [T] - str - = note: required for `SimValue<()>` to implement `Intern` - -error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied - --> tests/ui/simvalue_is_not_internable.rs:12:26 - | -12 | Intern::intern_sized(v) - | -------------------- ^ the trait `std::cmp::Eq` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern` - | | - | required by a bound introduced by this call - | - = help: the following other types implement trait `Intern`: - BitSlice - [T] - str - = note: required for `SimValue<()>` to implement `Intern` - -error[E0277]: `Cell` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:26 - | -12 | Intern::intern_sized(v) - | -------------------- ^ `Cell` cannot be shared between threads safely - | | - | required by a bound introduced by this call - | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell`, which is required by `SimValue<()>: Sync` - = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` -note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ -note: required by a bound in `intern_sized` - --> src/intern.rs - | - | pub trait Intern: Any + Send + Sync { - | ^^^^ required by this bound in `Intern::intern_sized` - | fn intern(&self) -> Interned; - | fn intern_sized(self) -> Interned - | ------------ required by a bound in this associated function - -error[E0277]: `UnsafeCell>` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:26 - | -12 | Intern::intern_sized(v) - | -------------------- ^ `UnsafeCell>` cannot be shared between threads safely - | | - | required by a bound introduced by this call - | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>`, which is required by `SimValue<()>: Sync` -note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ -note: required by a bound in `intern_sized` - --> src/intern.rs - | - | pub trait Intern: Any + Send + Sync { - | ^^^^ required by this bound in `Intern::intern_sized` - | fn intern(&self) -> Interned; - | fn intern_sized(self) -> Interned - | ------------ required by a bound in this associated function - -error[E0277]: `Cell` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:5 - | -12 | Intern::intern_sized(v) - | ^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely - | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell`, which is required by `SimValue<()>: Sync` - = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` -note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ -note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` - -error[E0277]: `UnsafeCell>` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:5 - | -12 | Intern::intern_sized(v) - | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely - | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>`, which is required by `SimValue<()>: Sync` -note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ -note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` diff --git a/crates/fayalite/visit_types.json b/crates/fayalite/visit_types.json index ff2050a..3eff1f5 100644 --- a/crates/fayalite/visit_types.json +++ b/crates/fayalite/visit_types.json @@ -49,8 +49,7 @@ "AsyncReset": "Visible", "SyncReset": "Visible", "Reset": "Visible", - "Clock": "Visible", - "PhantomConst": "Visible" + "Clock": "Visible" } }, "Bundle": { @@ -160,8 +159,7 @@ "data": { "$kind": "Struct", "verilog_name": "Visible", - "parameters": "Visible", - "simulation": "Visible" + "parameters": "Visible" } }, "ExternModuleParameter": { @@ -1264,17 +1262,6 @@ "ArrayElement": "Visible", "DynArrayElement": "Visible" } - }, - "PhantomConst": { - "data": { - "$kind": "Opaque" - }, - "generics": "" - }, - "ExternModuleSimulation": { - "data": { - "$kind": "Opaque" - } } } } \ No newline at end of file