diff --git a/.forgejo/workflows/deps.yml b/.forgejo/workflows/deps.yml new file mode 100644 index 0000000..b29723c --- /dev/null +++ b/.forgejo/workflows/deps.yml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +# See Notices.txt for copyright information +on: + workflow_call: + outputs: + cache-primary-key: + value: ${{ jobs.deps.outputs.cache-primary-key }} + +jobs: + deps: + runs-on: debian-12 + outputs: + cache-primary-key: ${{ steps.restore-deps.outputs.cache-primary-key }} + steps: + - uses: https://git.libre-chip.org/mirrors/checkout@v3 + with: + fetch-depth: 0 + - uses: https://git.libre-chip.org/mirrors/cache/restore@v3 + id: restore-deps + with: + path: deps + key: ${{ github.repository }}-deps-${{ runner.os }}-${{ hashFiles('.forgejo/workflows/deps.yml') }} + lookup-only: true + - name: Install Apt packages + if: steps.restore-deps.outputs.cache-hit != 'true' + run: | + apt-get update -qq + apt-get install -qq \ + bison \ + build-essential \ + ccache \ + clang \ + cvc5 \ + flex \ + gawk \ + g++ \ + git \ + libboost-filesystem-dev \ + libboost-python-dev \ + libboost-system-dev \ + libffi-dev \ + libreadline-dev \ + lld \ + pkg-config \ + python3 \ + python3-click \ + tcl-dev \ + zlib1g-dev + - name: Install Firtool + if: steps.restore-deps.outputs.cache-hit != 'true' + run: | + mkdir -p deps + wget -O deps/firrtl.tar.gz https://github.com/llvm/circt/releases/download/firtool-1.86.0/firrtl-bin-linux-x64.tar.gz + sha256sum -c - <<<'bf6f4ab18ae76f135c944efbd81e25391c31c1bd0617c58ab0592640abefee14 deps/firrtl.tar.gz' + tar -C deps -xvaf deps/firrtl.tar.gz + rm -rf deps/firtool + mv deps/firtool-1.86.0 deps/firtool + - 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 + - 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 + (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 + make -C deps/yosys -j"$(nproc)" + - uses: https://git.libre-chip.org/mirrors/cache/save@v3 + if: steps.restore-deps.outputs.cache-hit != 'true' + with: + path: deps + key: ${{ steps.restore-deps.outputs.cache-primary-key }} diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index 001168f..294ccaa 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -3,16 +3,57 @@ on: [push, pull_request] jobs: + deps: + runs-on: debian-12 + uses: ./.forgejo/workflows/deps.yml test: runs-on: debian-12 - container: - image: git.libre-chip.org/libre-chip/fayalite-deps:latest + needs: deps steps: - - uses: actions/checkout@v3 + - uses: https://git.libre-chip.org/mirrors/checkout@v3 with: fetch-depth: 0 - run: | scripts/check-copyright.sh + - run: | + apt-get update -qq + apt-get install -qq \ + bison \ + build-essential \ + ccache \ + clang \ + cvc5 \ + flex \ + gawk \ + git \ + libboost-filesystem-dev \ + libboost-python-dev \ + libboost-system-dev \ + libffi-dev \ + libreadline-dev \ + lld \ + pkg-config \ + python3 \ + python3-click \ + tcl-dev \ + z3 \ + zlib1g-dev + - run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.89.0 + source "$HOME/.cargo/env" + rustup component add rust-src + echo "$PATH" >> "$GITHUB_PATH" + - uses: https://git.libre-chip.org/mirrors/cache/restore@v3 + with: + path: deps + key: ${{ needs.deps.outputs.cache-primary-key }} + fail-on-cache-miss: true + - run: | + make -C deps/z3/build install + make -C deps/sby install + 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 with: save-if: ${{ github.ref == 'refs/heads/master' }} @@ -21,5 +62,3 @@ jobs: - 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 - - run: cargo run --example blinky yosys-nextpnr-xray --platform=arty-a7-100t --nextpnr-xilinx-chipdb-dir /opt/fayalite-deps/nextpnr-xilinx/xilinx --prjxray-db-dir /opt/fayalite-deps/prjxray-db -o target/blinky-out - - run: cargo run --example tx_only_uart yosys-nextpnr-xray --platform=arty-a7-100t --nextpnr-xilinx-chipdb-dir /opt/fayalite-deps/nextpnr-xilinx/xilinx --prjxray-db-dir /opt/fayalite-deps/prjxray-db -o target/tx_only_uart-out diff --git a/Cargo.lock b/Cargo.lock index be5f3bc..e0c32e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 4 +version = 3 [[package]] name = "allocator-api2" @@ -25,9 +25,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" @@ -81,12 +81,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "basic-toml" version = "0.1.8" @@ -155,9 +149,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.48" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -165,9 +159,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -175,20 +169,11 @@ dependencies = [ "strsim", ] -[[package]] -name = "clap_complete" -version = "4.5.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75bf0b32ad2e152de789bb635ea4d3078f6b838ad7974143e99b99f45a04af4a" -dependencies = [ - "clap", -] - [[package]] name = "clap_derive" -version = "4.5.47" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck", "proc-macro2", @@ -198,9 +183,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "colorchoice" @@ -306,11 +291,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" name = "fayalite" version = "0.3.0" dependencies = [ - "base64", "bitvec", "blake3", "clap", - "clap_complete", "ctor", "eyre", "fayalite-proc-macros", @@ -319,7 +302,7 @@ dependencies = [ "jobslot", "num-bigint", "num-traits", - "ordered-float", + "os_pipe", "petgraph", "serde", "serde_json", @@ -394,13 +377,12 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.3" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", - "r-efi", "wasi", ] @@ -467,23 +449,23 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobslot" -version = "0.2.23" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58715c67c327da7f1558708348d68c207fd54900c4ae0529e29305d04d795b8c" +checksum = "fe10868679d7a24c2c67d862d0e64a342ce9aef7cdde9ce8019bd35d353d458d" dependencies = [ "cfg-if", "derive_destructure2", "getrandom", "libc", "scopeguard", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] name = "libc" -version = "0.2.176" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "linux-raw-sys" @@ -526,14 +508,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] -name = "ordered-float" -version = "5.1.0" +name = "os_pipe" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" dependencies = [ - "num-traits", - "rand", - "serde", + "libc", + "windows-sys 0.59.0", ] [[package]] @@ -576,37 +557,12 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "radium" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_core", - "serde", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "serde", -] - [[package]] name = "rustix" version = "0.38.31" @@ -792,21 +748,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.14.7+wasi-0.2.4" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "which" @@ -851,12 +795,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - [[package]] name = "windows-sys" version = "0.52.0" @@ -868,11 +806,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.61.2" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-link", + "windows-targets", ] [[package]] @@ -945,12 +883,6 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 2380ea7..5a792c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,19 +18,17 @@ fayalite-proc-macros = { version = "=0.3.0", path = "crates/fayalite-proc-macros fayalite-proc-macros-impl = { version = "=0.3.0", path = "crates/fayalite-proc-macros-impl" } fayalite-visit-gen = { version = "=0.3.0", path = "crates/fayalite-visit-gen" } base16ct = "0.2.0" -base64 = "0.22.1" bitvec = { version = "1.0.1", features = ["serde"] } blake3 = { version = "1.5.4", features = ["serde"] } clap = { version = "4.5.9", features = ["derive", "env", "string"] } -clap_complete = "4.5.58" ctor = "0.2.8" eyre = "0.6.12" hashbrown = "0.15.2" indexmap = { version = "2.5.0", features = ["serde"] } -jobslot = "0.2.23" +jobslot = "0.2.19" num-bigint = "0.4.6" num-traits = "0.2.16" -ordered-float = { version = "5.1.0", features = ["serde"] } +os_pipe = "1.2.1" petgraph = "0.8.1" prettyplease = "0.2.20" proc-macro2 = "1.0.83" diff --git a/README.md b/README.md index 18cd78c..0b91833 100644 --- a/README.md +++ b/README.md @@ -8,73 +8,6 @@ Fayalite is a library for designing digital hardware -- a hardware description l [FIRRTL]: https://github.com/chipsalliance/firrtl-spec -# Building the [Blinky example] for the Arty A7 100T on Linux - -[Blinky example]: crates/fayalite/examples/blinky.rs - -This uses the container image containing all the external programs and files that Fayalite needs to build for FPGAs, the sources for the container image are in - -Steps: - -Install podman (or docker). - -Run: -```bash -podman run --rm --security-opt label=disable --volume="$(pwd):$(pwd)" -w="$(pwd)" -it git.libre-chip.org/libre-chip/fayalite-deps:latest cargo run --example blinky yosys-nextpnr-xray --nextpnr-xilinx-chipdb-dir /opt/fayalite-deps/nextpnr-xilinx/xilinx --prjxray-db-dir /opt/fayalite-deps/prjxray-db --platform arty-a7-100t -o target/blinky-out -``` - -To actually program the FPGA, you'll need to install [openFPGALoader] on your host OS: - -[openFPGALoader]: https://github.com/trabucayre/openFPGALoader - -On Debian 12: -```bash -sudo apt update && sudo apt install openfpgaloader -``` - -Then program the FPGA: -```bash -sudo openFPGALoader --board arty_a7_100t target/blinky-out/blinky.bit -``` - -This will program the FPGA but leave the Flash chip unmodified, so the FPGA will revert when the board is power-cycled. - -To program the Flash also, so it stays programmed when power-cycling the board: - -```bash -sudo openFPGALoader --board arty_a7_100t -f target/blinky-out/blinky.bit -``` - -# Building the [Transmit-only UART example] for the Arty A7 100T on Linux - -[Transmit-only UART example]: crates/fayalite/examples/tx_only_uart.rs - -Follow the steps above of building the Blinky example, but replace `blinky` with `tx_only_uart`. - -View the output using [tio](https://github.com/tio/tio) which you can install in Debian using `apt`. - -Find the correct USB device: -```bash -sudo tio --list -``` - -You want the device with a name like (note the `if01`, `if00` is presumably the JTAG port): -`/dev/serial/by-id/usb-Digilent_Digilent_USB_Device_210319B4A51E-if01-port0` - -Connect to the serial port: -```bash -sudo tio -b115200 /dev/serial/by-id/put-your-device-id-here -``` - -You'll see (repeating endlessly): -```text -Hello World from Fayalite!!! -Hello World from Fayalite!!! -Hello World from Fayalite!!! -``` - -Press Ctrl+T then `q` to exit tio. - # Funding ## NLnet Grants diff --git a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs index 97fa3ff..538c2da 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_bundle.rs @@ -87,11 +87,7 @@ impl ParsedBundle { no_static: _, no_runtime_generics: _, cmp_eq: _, - ref get, } = options.body; - if let Some((get, ..)) = get { - errors.error(get, "#[hdl(get(...))] is not allowed on structs"); - } let mut fields = match fields { syn::Fields::Named(fields) => fields, syn::Fields::Unnamed(fields) => { @@ -224,7 +220,7 @@ impl Builder { .args .push_value(match get_field_state(field_index) { BuilderFieldState::Unfilled => parse_quote_spanned! {self.ident.span()=> - () + ::fayalite::bundle::Unfilled<#ty> }, BuilderFieldState::Generic => { let type_var = type_var_for_field_name(ident); @@ -349,6 +345,7 @@ impl ToTokens for Builder { } })); quote_spanned! {self.ident.span()=> + #[automatically_derived] #[allow(non_camel_case_types, non_snake_case, dead_code)] impl #impl_generics #unfilled_ty #where_clause @@ -383,7 +380,7 @@ impl ToTokens for Builder { fn default() -> Self { #ident { #phantom_field_name: ::fayalite::__std::marker::PhantomData, - #(#field_idents: (),)* + #(#field_idents: ::fayalite::__std::default::Default::default(),)* } } } @@ -395,30 +392,16 @@ impl ToTokens for Builder { let type_generics = self.generics.split_for_impl().1; quote_spanned! {self.ident.span()=> #[automatically_derived] - #[allow(non_camel_case_types, dead_code, private_interfaces)] - impl #filled_impl_generics ::fayalite::expr::ValueType for #filled_ty - #filled_where_clause - { - type Type = #target #type_generics; - type ValueCategory = ::fayalite::expr::value_category::ValueCategoryExpr; - - fn ty(&self) -> ::Type { - #target { - #(#field_idents: ::fayalite::expr::ValueType::ty(&self.#field_idents),)* - } - } - } - - #[automatically_derived] - #[allow(non_camel_case_types, dead_code, private_interfaces)] + #[allow(non_camel_case_types, dead_code)] impl #filled_impl_generics ::fayalite::expr::ToExpr for #filled_ty #filled_where_clause { + type Type = #target #type_generics; fn to_expr( &self, - ) -> ::fayalite::expr::Expr<::Type> { + ) -> ::fayalite::expr::Expr<::Type> { let __ty = #target { - #(#field_idents: ::fayalite::expr::ValueType::ty(&self.#field_idents),)* + #(#field_idents: ::fayalite::expr::Expr::ty(self.#field_idents),)* }; let __field_values = [ #(::fayalite::expr::Expr::canonical(self.#field_idents),)* @@ -463,7 +446,6 @@ impl ToTokens for ParsedBundle { no_static, no_runtime_generics, cmp_eq, - get: _, } = &options.body; let target = get_target(target, ident); let mut item_attrs = attrs.clone(); @@ -513,6 +495,7 @@ impl ToTokens for ParsedBundle { }; builder.to_tokens(tokens); let unfilled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Unfilled); + let filled_builder_ty = builder.builder_struct_ty(|_| BuilderFieldState::Filled); let mut mask_type_fields = FieldsNamed::from(fields.clone()); for Field { ty, .. } in &mut mask_type_fields.named { *ty = parse_quote_spanned! {span=> @@ -530,6 +513,8 @@ impl ToTokens for ParsedBundle { mask_type_builder.to_tokens(tokens); let unfilled_mask_type_builder_ty = mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Unfilled); + let filled_mask_type_builder_ty = + mask_type_builder.builder_struct_ty(|_| BuilderFieldState::Filled); ItemStruct { attrs: vec![ common_derives(span), @@ -709,10 +694,10 @@ impl ToTokens for ParsedBundle { v.field(&value.#ident); } })); - let value_type_fields = Vec::from_iter(fields.named().into_iter().map(|field| { + 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::expr::ValueType::ty(&self.#ident), + #ident: ::fayalite::sim::value::SimValue::ty(&self.#ident), } })); let fields_len = fields.named().into_iter().len(); @@ -796,6 +781,7 @@ impl ToTokens for ParsedBundle { #where_clause { type Builder = #unfilled_mask_type_builder_ty; + type FilledBuilder = #filled_mask_type_builder_ty; fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> { ::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..]) } @@ -820,39 +806,28 @@ impl ToTokens for ParsedBundle { } } #[automatically_derived] - impl #impl_generics ::fayalite::expr::ValueType for #mask_type_sim_value_ident #type_generics - #where_clause - { - type Type = #mask_type_ident #type_generics; - type ValueCategory = ::fayalite::expr::value_category::ValueCategorySimValue; - - fn ty(&self) -> ::Type { - #mask_type_ident { - #(#value_type_fields)* - } - } - } - #[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, + ::Type, > { let ty = #mask_type_ident { - #(#value_type_fields)* + #(#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, + ::Type, > { let ty = #mask_type_ident { - #(#value_type_fields)* + #(#to_sim_value_fields)* }; ::fayalite::sim::value::SimValue::from_value(ty, self) } @@ -956,6 +931,7 @@ impl ToTokens for ParsedBundle { #where_clause { type Builder = #unfilled_builder_ty; + type FilledBuilder = #filled_builder_ty; fn fields(&#self_token) -> ::fayalite::intern::Interned<[::fayalite::bundle::BundleField]> { ::fayalite::intern::Intern::intern(&[#(#fields_body_fields)*][..]) } @@ -980,39 +956,28 @@ impl ToTokens for ParsedBundle { } } #[automatically_derived] - impl #impl_generics ::fayalite::expr::ValueType for #sim_value_ident #type_generics - #where_clause - { - type Type = #target #type_generics; - type ValueCategory = ::fayalite::expr::value_category::ValueCategorySimValue; - - fn ty(&self) -> ::Type { - #target { - #(#value_type_fields)* - } - } - } - #[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, + ::Type, > { let ty = #target { - #(#value_type_fields)* + #(#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, + ::Type, > { let ty = #target { - #(#value_type_fields)* + #(#to_sim_value_fields)* }; ::fayalite::sim::value::SimValue::from_value(ty, self) } @@ -1038,172 +1003,91 @@ impl ToTokens for ParsedBundle { } .to_tokens(tokens); if let Some((cmp_eq,)) = cmp_eq { - let mut cmp_eq_where_clause = + 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 fields_value_eq = vec![]; - let mut fields_value_ne = vec![]; - let mut fields_expr_eq = vec![]; - let mut fields_expr_ne = vec![]; - let mut fields_valueless_eq = vec![]; - let mut fields_valueless_ne = vec![]; + 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(); - cmp_eq_where_clause + expr_where_clause .predicates .push(parse_quote_spanned! {cmp_eq.span=> - #field_ty: ::fayalite::expr::HdlPartialEqImpl<#field_ty> + #field_ty: ::fayalite::expr::ops::ExprPartialEq<#field_ty> }); - fields_value_eq.push(quote_spanned! {span=> - ::fayalite::expr::HdlPartialEqImpl::cmp_value_eq( - __lhs.#field_ident, - ::fayalite::__std::borrow::Cow::Borrowed(&__lhs_value.#field_ident), - __rhs.#field_ident, - ::fayalite::__std::borrow::Cow::Borrowed(&__rhs_value.#field_ident), - ) + 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_value_ne.push(quote_spanned! {span=> - ::fayalite::expr::HdlPartialEqImpl::cmp_value_ne( - __lhs.#field_ident, - ::fayalite::__std::borrow::Cow::Borrowed(&__lhs_value.#field_ident), - __rhs.#field_ident, - ::fayalite::__std::borrow::Cow::Borrowed(&__rhs_value.#field_ident), - ) + fields_cmp_eq.push(quote_spanned! {span=> + ::fayalite::expr::ops::ExprPartialEq::cmp_eq(__lhs.#field_ident, __rhs.#field_ident) }); - fields_expr_eq.push(quote_spanned! {span=> - ::fayalite::expr::HdlPartialEqImpl::cmp_expr_eq( - __lhs.#field_ident, - __rhs.#field_ident, - ) - }); - fields_expr_ne.push(quote_spanned! {span=> - ::fayalite::expr::HdlPartialEqImpl::cmp_expr_ne( - __lhs.#field_ident, - __rhs.#field_ident, - ) - }); - fields_valueless_eq.push(quote_spanned! {span=> - ::fayalite::expr::HdlPartialEqImpl::cmp_valueless_eq( - ::fayalite::expr::Valueless::new(__lhs.#field_ident), - ::fayalite::expr::Valueless::new(__rhs.#field_ident), - ) - }); - fields_valueless_ne.push(quote_spanned! {span=> - ::fayalite::expr::HdlPartialEqImpl::cmp_valueless_ne( - ::fayalite::expr::Valueless::new(__lhs.#field_ident), - ::fayalite::expr::Valueless::new(__rhs.#field_ident), - ) + fields_cmp_ne.push(quote_spanned! {span=> + ::fayalite::expr::ops::ExprPartialEq::cmp_ne(__lhs.#field_ident, __rhs.#field_ident) }); } - let value_eq_body; - let value_ne_body; - let expr_eq_body; - let expr_ne_body; - let valueless_eq_body; - let valueless_ne_body; + let sim_value_eq_body; + let cmp_eq_body; + let cmp_ne_body; if fields_len == 0 { - value_eq_body = quote_spanned! {span=> + sim_value_eq_body = quote_spanned! {span=> true }; - value_ne_body = quote_spanned! {span=> - false - }; - expr_eq_body = quote_spanned! {span=> + cmp_eq_body = quote_spanned! {span=> ::fayalite::expr::ToExpr::to_expr(&true) }; - expr_ne_body = quote_spanned! {span=> + cmp_ne_body = quote_spanned! {span=> ::fayalite::expr::ToExpr::to_expr(&false) }; - valueless_eq_body = quote_spanned! {span=> - ::fayalite::expr::Valueless::new(::fayalite::int::Bool) - }; - valueless_ne_body = quote_spanned! {span=> - ::fayalite::expr::Valueless::new(::fayalite::int::Bool) - }; } else { - value_eq_body = quote_spanned! {span=> - #(#fields_value_eq)&* + sim_value_eq_body = quote_spanned! {span=> + #(#fields_sim_value_eq)&&* }; - value_ne_body = quote_spanned! {span=> - #(#fields_value_ne)|* + cmp_eq_body = quote_spanned! {span=> + #(#fields_cmp_eq)&* }; - expr_eq_body = quote_spanned! {span=> - #(#fields_expr_eq)&* - }; - expr_ne_body = quote_spanned! {span=> - #(#fields_expr_ne)|* - }; - valueless_eq_body = quote_spanned! {span=> - let __lhs = ::fayalite::expr::ValueType::ty(&__lhs); - let __rhs = ::fayalite::expr::ValueType::ty(&__rhs); - #(#fields_valueless_eq)|* - }; - valueless_ne_body = quote_spanned! {span=> - let __lhs = ::fayalite::expr::ValueType::ty(&__lhs); - let __rhs = ::fayalite::expr::ValueType::ty(&__rhs); - #(#fields_valueless_ne)|* + cmp_ne_body = quote_spanned! {span=> + #(#fields_cmp_ne)|* }; }; quote_spanned! {span=> #[automatically_derived] - impl #impl_generics ::fayalite::expr::HdlPartialEqImpl for #target #type_generics - #cmp_eq_where_clause + impl #impl_generics ::fayalite::expr::ops::ExprPartialEq for #target #type_generics + #expr_where_clause { - #[track_caller] - fn cmp_value_eq( - __lhs: Self, - __lhs_value: ::fayalite::__std::borrow::Cow<'_, ::SimValue>, - __rhs: Self, - __rhs_value: ::fayalite::__std::borrow::Cow<'_, ::SimValue>, - ) -> ::fayalite::__std::primitive::bool { - #value_eq_body - } - - #[track_caller] - fn cmp_value_ne( - __lhs: Self, - __lhs_value: ::fayalite::__std::borrow::Cow<'_, ::SimValue>, - __rhs: Self, - __rhs_value: ::fayalite::__std::borrow::Cow<'_, ::SimValue>, - ) -> ::fayalite::__std::primitive::bool { - #value_ne_body - } - - #[track_caller] - fn cmp_expr_eq( + fn cmp_eq( __lhs: ::fayalite::expr::Expr, __rhs: ::fayalite::expr::Expr, ) -> ::fayalite::expr::Expr<::fayalite::int::Bool> { - #expr_eq_body + #cmp_eq_body } - - #[track_caller] - fn cmp_expr_ne( + fn cmp_ne( __lhs: ::fayalite::expr::Expr, __rhs: ::fayalite::expr::Expr, ) -> ::fayalite::expr::Expr<::fayalite::int::Bool> { - #expr_ne_body + #cmp_ne_body } - - #[track_caller] - fn cmp_valueless_eq( - __lhs: ::fayalite::expr::Valueless, - __rhs: ::fayalite::expr::Valueless, - ) -> ::fayalite::expr::Valueless<::fayalite::int::Bool> { - #valueless_eq_body - } - - #[track_caller] - fn cmp_valueless_ne( - __lhs: ::fayalite::expr::Valueless, - __rhs: ::fayalite::expr::Valueless, - ) -> ::fayalite::expr::Valueless<::fayalite::int::Bool> { - #valueless_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 } } } diff --git a/crates/fayalite-proc-macros-impl/src/hdl_enum.rs b/crates/fayalite-proc-macros-impl/src/hdl_enum.rs index 90838f0..e5cbe27 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_enum.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_enum.rs @@ -159,14 +159,10 @@ impl ParsedEnum { no_static: _, no_runtime_generics: _, cmp_eq, - ref get, } = options.body; if let Some((cmp_eq,)) = cmp_eq { errors.error(cmp_eq, "#[hdl(cmp_eq)] is not yet implemented for enums"); } - if let Some((get, ..)) = get { - errors.error(get, "#[hdl(get(...))] is not allowed on enums"); - } attrs.retain(|attr| { if attr.path().is_ident("repr") { errors.error(attr, "#[repr] is not supported on #[hdl] enums"); @@ -229,7 +225,6 @@ impl ToTokens for ParsedEnum { no_static, no_runtime_generics, cmp_eq: _, // TODO: implement cmp_eq for enums - get: _, } = &options.body; let target = get_target(target, ident); let mut struct_attrs = attrs.clone(); @@ -554,6 +549,7 @@ impl ToTokens for ParsedEnum { for (index, ParsedVariant { ident, field, .. }) in variants.iter().enumerate() { if let Some(ParsedVariantField { ty, .. }) = field { quote_spanned! {span=> + #[automatically_derived] impl #impl_generics #target #type_generics #where_clause { @@ -575,6 +571,7 @@ impl ToTokens for ParsedEnum { ) } } + #[automatically_derived] impl #impl_generics #sim_builder_ident #type_generics #where_clause { @@ -596,6 +593,7 @@ impl ToTokens for ParsedEnum { } } else { quote_spanned! {span=> + #[automatically_derived] impl #impl_generics #target #type_generics #where_clause { @@ -610,6 +608,7 @@ impl ToTokens for ParsedEnum { ) } } + #[automatically_derived] impl #impl_generics #sim_builder_ident #type_generics #where_clause { @@ -1024,26 +1023,16 @@ impl ToTokens for ParsedEnum { <::fayalite::int::Bool as ::fayalite::ty::StaticType>::TYPE_PROPERTIES; } #[automatically_derived] - impl #static_impl_generics ::fayalite::expr::ValueType - for #sim_value_ident #static_type_generics - #static_where_clause - { - type Type = #target #static_type_generics; - type ValueCategory = ::fayalite::expr::value_category::ValueCategorySimValue; - - fn ty(&self) -> ::Type { - ::fayalite::ty::StaticType::TYPE - } - } - #[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, + ::Type, > { ::fayalite::sim::value::SimValue::from_value( ::fayalite::ty::StaticType::TYPE, @@ -1053,7 +1042,7 @@ impl ToTokens for ParsedEnum { fn into_sim_value( self, ) -> ::fayalite::sim::value::SimValue< - ::Type, + ::Type, > { ::fayalite::sim::value::SimValue::from_value( ::fayalite::ty::StaticType::TYPE, diff --git a/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs b/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs index 0fa2222..d4a035b 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_alias.rs @@ -3,264 +3,29 @@ use crate::{ Errors, HdlAttr, hdl_type_common::{ - ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, - PhantomConstGetBound, TypesParser, WrappedInConst, common_derives, get_target, known_items, + ItemOptions, MakeHdlTypeExpr, MaybeParsed, ParsedGenerics, ParsedType, TypesParser, + get_target, }, kw, }; use proc_macro2::TokenStream; -use quote::{ToTokens, format_ident, quote_spanned}; -use syn::{ - Attribute, Expr, Fields, GenericParam, Generics, Ident, ItemStruct, ItemType, Token, Type, - TypeGroup, TypeParam, TypeParen, Visibility, parse_quote_spanned, punctuated::Pair, - token::Paren, -}; +use quote::ToTokens; +use syn::{Attribute, Generics, Ident, ItemType, Token, Type, Visibility, parse_quote_spanned}; #[derive(Clone, Debug)] -pub(crate) struct PhantomConstAccessorTypeParam { - attrs: Vec, - ident: Ident, - colon_token: Token![:], - phantom_const_get_bound: PhantomConstGetBound, - plus_token: Option, -} - -impl From for TypeParam { - fn from(value: PhantomConstAccessorTypeParam) -> Self { - let PhantomConstAccessorTypeParam { - attrs, - ident, - colon_token, - phantom_const_get_bound, - plus_token, - } = value; - TypeParam { - attrs, - ident, - colon_token: Some(colon_token), - bounds: FromIterator::from_iter([Pair::new( - phantom_const_get_bound.into(), - plus_token, - )]), - eq_token: None, - default: None, - } - } -} - -impl From for GenericParam { - fn from(value: PhantomConstAccessorTypeParam) -> Self { - TypeParam::from(value).into() - } -} - -impl PhantomConstAccessorTypeParam { - fn parse_opt(generic_param: GenericParam) -> Option { - let GenericParam::Type(TypeParam { - attrs, - ident, - colon_token, - bounds, - eq_token: None, - default: None, - }) = generic_param - else { - return None; - }; - let colon_token = colon_token.unwrap_or(Token![:](ident.span())); - let mut bounds = bounds.into_pairs(); - let (bound, plus_token) = bounds.next()?.into_tuple(); - let phantom_const_get_bound = PhantomConstGetBound::parse_type_param_bound(bound) - .ok()? - .ok()?; - let None = bounds.next() else { - return None; - }; - Some(Self { - attrs, - ident, - colon_token, - phantom_const_get_bound, - plus_token, - }) - } -} - -#[derive(Clone, Debug)] -pub(crate) struct PhantomConstAccessorGenerics { - lt_token: Token![<], - type_param: PhantomConstAccessorTypeParam, - comma_token: Option, - gt_token: Token![>], -} - -impl From for Generics { - fn from(value: PhantomConstAccessorGenerics) -> Self { - let PhantomConstAccessorGenerics { - lt_token, - type_param, - comma_token, - gt_token, - } = value; - Generics { - lt_token: Some(lt_token), - params: FromIterator::from_iter([Pair::new(type_param.into(), comma_token)]), - gt_token: Some(gt_token), - where_clause: None, - } - } -} - -impl<'a> From<&'a PhantomConstAccessorGenerics> for Generics { - fn from(value: &'a PhantomConstAccessorGenerics) -> Self { - value.clone().into() - } -} - -impl PhantomConstAccessorGenerics { - fn parse_opt(generics: Generics) -> Option { - let Generics { - lt_token, - params, - gt_token, - where_clause: None, - } = generics - else { - return None; - }; - let mut params = params.into_pairs(); - let (generic_param, comma_token) = params.next()?.into_tuple(); - let type_param = PhantomConstAccessorTypeParam::parse_opt(generic_param)?; - let span = type_param.ident.span(); - let lt_token = lt_token.unwrap_or(Token![<](span)); - let gt_token = gt_token.unwrap_or(Token![>](span)); - let None = params.next() else { - return None; - }; - Some(Self { - lt_token, - type_param, - comma_token, - gt_token, - }) - } -} - -#[derive(Clone, Debug)] -pub(crate) enum ParsedTypeAlias { - TypeAlias { - attrs: Vec, - options: HdlAttr, - vis: Visibility, - type_token: Token![type], - ident: Ident, - generics: MaybeParsed, - eq_token: Token![=], - ty: MaybeParsed, - semi_token: Token![;], - }, - PhantomConstAccessor { - attrs: Vec, - options: HdlAttr, - get: (kw::get, Paren, Expr), - vis: Visibility, - type_token: Token![type], - ident: Ident, - generics: PhantomConstAccessorGenerics, - eq_token: Token![=], - ty: Type, - ty_is_dyn_size: Option, - semi_token: Token![;], - }, +pub(crate) struct ParsedTypeAlias { + pub(crate) attrs: Vec, + pub(crate) options: HdlAttr, + pub(crate) vis: Visibility, + pub(crate) type_token: Token![type], + pub(crate) ident: Ident, + pub(crate) generics: MaybeParsed, + pub(crate) eq_token: Token![=], + pub(crate) ty: MaybeParsed, + pub(crate) semi_token: Token![;], } impl ParsedTypeAlias { - fn ty_is_dyn_size(ty: &Type) -> Option { - match ty { - Type::Group(TypeGroup { - group_token: _, - elem, - }) => Self::ty_is_dyn_size(elem), - Type::Paren(TypeParen { - paren_token: _, - elem, - }) => Self::ty_is_dyn_size(elem), - Type::Path(syn::TypePath { qself: None, path }) => { - known_items::DynSize::parse_path(path.clone()).ok() - } - _ => None, - } - } - fn parse_phantom_const_accessor( - item: ItemType, - mut errors: Errors, - options: HdlAttr, - get: (kw::get, Paren, Expr), - ) -> syn::Result { - let ItemType { - attrs, - vis, - type_token, - ident, - generics, - eq_token, - ty, - semi_token, - } = item; - let ItemOptions { - outline_generated: _, - ref target, - custom_bounds, - no_static, - no_runtime_generics, - cmp_eq, - get: _, - } = options.body; - if let Some((no_static,)) = no_static { - errors.error(no_static, "no_static is not valid on type aliases"); - } - if let Some((target, ..)) = target { - errors.error( - target, - "target is not implemented on PhantomConstGet type aliases", - ); - } - if let Some((no_runtime_generics,)) = no_runtime_generics { - errors.error( - no_runtime_generics, - "no_runtime_generics is not implemented on PhantomConstGet type aliases", - ); - } - if let Some((cmp_eq,)) = cmp_eq { - errors.error(cmp_eq, "cmp_eq is not valid on type aliases"); - } - if let Some((custom_bounds,)) = custom_bounds { - errors.error( - custom_bounds, - "custom_bounds is not implemented on PhantomConstGet type aliases", - ); - } - let Some(generics) = PhantomConstAccessorGenerics::parse_opt(generics) else { - errors.error(ident, "#[hdl(get(...))] type alias must be of the form:\ntype MyTypeGetter> = RetType;"); - errors.finish()?; - unreachable!(); - }; - errors.finish()?; - let ty_is_dyn_size = Self::ty_is_dyn_size(&ty); - Ok(Self::PhantomConstAccessor { - attrs, - options, - get, - vis, - type_token, - ident, - generics, - eq_token, - ty: *ty, - ty_is_dyn_size, - semi_token, - }) - } fn parse(item: ItemType) -> syn::Result { let ItemType { mut attrs, @@ -286,25 +51,7 @@ impl ParsedTypeAlias { no_static, no_runtime_generics: _, cmp_eq, - ref mut get, } = options.body; - if let Some(get) = get.take() { - return Self::parse_phantom_const_accessor( - ItemType { - attrs, - vis, - type_token, - ident, - generics, - eq_token, - ty, - semi_token, - }, - errors, - options, - get, - ); - } if let Some((no_static,)) = no_static { errors.error(no_static, "no_static is not valid on type aliases"); } @@ -320,7 +67,7 @@ impl ParsedTypeAlias { }; let ty = TypesParser::maybe_run(generics.as_ref(), *ty, &mut errors); errors.finish()?; - Ok(Self::TypeAlias { + Ok(Self { attrs, options, vis, @@ -336,155 +83,54 @@ impl ParsedTypeAlias { impl ToTokens for ParsedTypeAlias { fn to_tokens(&self, tokens: &mut TokenStream) { - match self { - Self::TypeAlias { - attrs, - options, - vis, - type_token, - ident, - generics, - eq_token, - ty, - semi_token, - } => { - let ItemOptions { - outline_generated: _, - target, - custom_bounds: _, - no_static: _, - no_runtime_generics, - cmp_eq: _, - get: _, - } = &options.body; - let target = get_target(target, ident); - let mut type_attrs = attrs.clone(); - type_attrs.push(parse_quote_spanned! {ident.span()=> - #[allow(type_alias_bounds)] - }); - ItemType { - attrs: type_attrs, - vis: vis.clone(), - type_token: *type_token, - ident: ident.clone(), - generics: generics.into(), - eq_token: *eq_token, - ty: Box::new(ty.clone().into()), - semi_token: *semi_token, - } - .to_tokens(tokens); - if let (MaybeParsed::Parsed(generics), MaybeParsed::Parsed(ty), None) = - (generics, ty, no_runtime_generics) - { - generics.make_runtime_generics(tokens, vis, ident, &target, |context| { - ty.make_hdl_type_expr(context) - }) - } - } - Self::PhantomConstAccessor { - attrs, - options, - get: (_get_kw, _get_paren, get_expr), - vis, - type_token, - ident, - generics, - eq_token, - ty, - ty_is_dyn_size, - semi_token, - } => { - let ItemOptions { - outline_generated: _, - target: _, - custom_bounds: _, - no_static: _, - no_runtime_generics: _, - cmp_eq: _, - get: _, - } = &options.body; - let span = ident.span(); - let mut type_attrs = attrs.clone(); - type_attrs.push(parse_quote_spanned! {span=> - #[allow(type_alias_bounds)] - }); - let type_param_ident = &generics.type_param.ident; - let syn_generics = Generics::from(generics); - ItemType { - attrs: type_attrs, - vis: vis.clone(), - type_token: *type_token, - ident: ident.clone(), - generics: syn_generics.clone(), - eq_token: *eq_token, - ty: parse_quote_spanned! {span=> - <#ty as ::fayalite::phantom_const::ReturnSelfUnchanged<#type_param_ident>>::Type - }, - semi_token: *semi_token, - } - .to_tokens(tokens); - let generics_accumulation_ident = - format_ident!("__{}__GenericsAccumulation", ident); - ItemStruct { - attrs: vec![ - common_derives(span), - parse_quote_spanned! {span=> - #[allow(non_camel_case_types)] - }, - ], - vis: vis.clone(), - struct_token: Token![struct](span), - ident: generics_accumulation_ident.clone(), - generics: Generics::default(), - fields: Fields::Unnamed(parse_quote_spanned! {span=> - (()) - }), - semi_token: Some(Token![;](span)), - } - .to_tokens(tokens); - quote_spanned! {span=> - #[allow(non_upper_case_globals, dead_code)] - #vis const #ident: #generics_accumulation_ident = #generics_accumulation_ident(()); - } - .to_tokens(tokens); - let mut wrapped_in_const = WrappedInConst::new(tokens, span); - let tokens = wrapped_in_const.inner(); - let (impl_generics, _type_generics, where_clause) = syn_generics.split_for_impl(); - let phantom_const_get_ty = &generics.type_param.phantom_const_get_bound.ty; - let index_output = if let Some(ty_is_dyn_size) = ty_is_dyn_size { - known_items::usize(ty_is_dyn_size.span).to_token_stream() - } else { - ty.to_token_stream() - }; - quote_spanned! {span=> - #[allow(non_upper_case_globals)] - #[automatically_derived] - impl #impl_generics ::fayalite::__std::ops::Index<#type_param_ident> - for #generics_accumulation_ident - #where_clause - { - type Output = #index_output; - - fn index(&self, __param: #type_param_ident) -> &Self::Output { - ::fayalite::phantom_const::type_alias_phantom_const_get_helper::<#phantom_const_get_ty, #index_output>( - __param, - #get_expr, - ) - } - } - } - .to_tokens(tokens); - } + let Self { + attrs, + options, + vis, + type_token, + ident, + generics, + eq_token, + ty, + semi_token, + } = self; + let ItemOptions { + outline_generated: _, + target, + custom_bounds: _, + no_static: _, + no_runtime_generics, + cmp_eq: _, + } = &options.body; + let target = get_target(target, ident); + let mut type_attrs = attrs.clone(); + type_attrs.push(parse_quote_spanned! {ident.span()=> + #[allow(type_alias_bounds)] + }); + ItemType { + attrs: type_attrs, + vis: vis.clone(), + type_token: *type_token, + ident: ident.clone(), + generics: generics.into(), + eq_token: *eq_token, + ty: Box::new(ty.clone().into()), + semi_token: *semi_token, + } + .to_tokens(tokens); + if let (MaybeParsed::Parsed(generics), MaybeParsed::Parsed(ty), None) = + (generics, ty, no_runtime_generics) + { + generics.make_runtime_generics(tokens, vis, ident, &target, |context| { + ty.make_hdl_type_expr(context) + }) } } } pub(crate) fn hdl_type_alias_impl(item: ItemType) -> syn::Result { let item = ParsedTypeAlias::parse(item)?; - let outline_generated = match &item { - ParsedTypeAlias::TypeAlias { options, .. } - | ParsedTypeAlias::PhantomConstAccessor { options, .. } => options.body.outline_generated, - }; + let outline_generated = item.options.body.outline_generated; let mut contents = item.to_token_stream(); if outline_generated.is_some() { contents = crate::outline_generated(contents, "hdl-type-alias-"); diff --git a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs index 3a0e5e9..1206f11 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs @@ -8,9 +8,9 @@ use syn::{ AngleBracketedGenericArguments, Attribute, Block, ConstParam, Expr, ExprBlock, ExprGroup, ExprIndex, ExprParen, ExprPath, ExprTuple, Field, FieldMutability, Fields, FieldsNamed, FieldsUnnamed, GenericArgument, GenericParam, Generics, Ident, ImplGenerics, Index, ItemStruct, - Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, TraitBound, Turbofish, - Type, TypeGenerics, TypeGroup, TypeParam, TypeParamBound, TypeParen, TypePath, TypeTuple, - Visibility, WhereClause, WherePredicate, + Path, PathArguments, PathSegment, PredicateType, QSelf, Stmt, Token, Turbofish, Type, + TypeGenerics, TypeGroup, TypeParam, TypeParen, TypePath, TypeTuple, Visibility, WhereClause, + WherePredicate, parse::{Parse, ParseStream}, parse_quote, parse_quote_spanned, punctuated::{Pair, Punctuated}, @@ -27,7 +27,6 @@ crate::options! { NoStatic(no_static), NoRuntimeGenerics(no_runtime_generics), CmpEq(cmp_eq), - Get(get, Expr), } } @@ -2046,7 +2045,6 @@ pub(crate) mod known_items { impl_known_item!(::fayalite::int::Size); impl_known_item!(::fayalite::int::UInt); impl_known_item!(::fayalite::int::UIntType); - impl_known_item!(::fayalite::phantom_const::PhantomConstGet); impl_known_item!(::fayalite::reset::ResetType); impl_known_item!(::fayalite::ty::CanonicalType); impl_known_item!(::fayalite::ty::StaticType); @@ -2065,174 +2063,6 @@ pub(crate) mod known_items { ); } -#[derive(Clone, Debug)] -pub(crate) struct PhantomConstGetBound { - pub(crate) phantom_const_get: known_items::PhantomConstGet, - pub(crate) colon2_token: Option, - pub(crate) lt_token: Token![<], - pub(crate) ty: Type, - pub(crate) comma_token: Option, - pub(crate) gt_token: Token![>], -} - -impl PhantomConstGetBound { - pub(crate) fn parse_path_with_arguments(path: Path) -> syn::Result> { - match known_items::PhantomConstGet::parse_path_with_arguments(path) { - Ok((phantom_const_get, arguments)) => { - Self::parse_path_and_arguments(phantom_const_get, arguments).map(Ok) - } - Err(path) => Ok(Err(path)), - } - } - pub(crate) fn parse_path_and_arguments( - phantom_const_get: known_items::PhantomConstGet, - arguments: PathArguments, - ) -> syn::Result { - let error = |arguments: PathArguments, message: &str| { - let mut path = phantom_const_get.path.clone(); - path.segments.last_mut().expect("known to exist").arguments = arguments; - syn::Error::new_spanned(path, message) - }; - match arguments { - PathArguments::None => Err(error(arguments, "missing generics for PhantomConstGet")), - PathArguments::AngleBracketed(AngleBracketedGenericArguments { - colon2_token, - lt_token, - args, - gt_token, - }) => { - let error = |args: Punctuated, message| { - error( - PathArguments::AngleBracketed(AngleBracketedGenericArguments { - colon2_token, - lt_token, - args, - gt_token, - }), - message, - ) - }; - let mut args = args.into_pairs().peekable(); - let Some((generic_argument, comma_token)) = args.next().map(Pair::into_tuple) - else { - return Err(error( - Default::default(), - "PhantomConstGet takes a type argument but no generic arguments were supplied", - )); - }; - if args.peek().is_some() { - return Err(error( - [Pair::new(generic_argument, comma_token)] - .into_iter() - .chain(args) - .collect(), - "PhantomConstGet takes a single type argument but too many generic arguments were supplied", - )); - }; - let GenericArgument::Type(ty) = generic_argument else { - return Err(error( - Punctuated::from_iter([Pair::new(generic_argument, comma_token)]), - "PhantomConstGet requires a type argument", - )); - }; - Ok(Self { - phantom_const_get, - colon2_token, - lt_token, - ty, - comma_token, - gt_token, - }) - } - PathArguments::Parenthesized(_) => Err(error( - arguments, - "parenthetical generics are not valid for PhantomConstGet", - )), - } - } - pub(crate) fn parse_type_param_bound( - bound: TypeParamBound, - ) -> syn::Result> { - let TypeParamBound::Trait(TraitBound { - paren_token: None, - modifier: syn::TraitBoundModifier::None, - lifetimes: None, - path, - }) = bound - else { - return Ok(Err(bound)); - }; - Ok(match Self::parse_path_with_arguments(path)? { - Ok(v) => Ok(v), - Err(path) => Err(TypeParamBound::Trait(TraitBound { - paren_token: None, - modifier: syn::TraitBoundModifier::None, - lifetimes: None, - path, - })), - }) - } -} - -impl ToTokens for PhantomConstGetBound { - fn to_tokens(&self, tokens: &mut TokenStream) { - let Self { - phantom_const_get, - colon2_token, - lt_token, - ty, - comma_token, - gt_token, - } = self; - phantom_const_get.to_tokens(tokens); - colon2_token.to_tokens(tokens); - lt_token.to_tokens(tokens); - ty.to_tokens(tokens); - comma_token.to_tokens(tokens); - gt_token.to_tokens(tokens); - } -} - -impl From for Path { - fn from(value: PhantomConstGetBound) -> Self { - let PhantomConstGetBound { - phantom_const_get, - colon2_token, - lt_token, - ty, - comma_token, - gt_token, - } = value; - let mut path = phantom_const_get.path; - path.segments.last_mut().expect("known to exist").arguments = - PathArguments::AngleBracketed(AngleBracketedGenericArguments { - colon2_token, - lt_token, - args: FromIterator::from_iter([Pair::new(GenericArgument::Type(ty), comma_token)]), - gt_token, - }); - path - } -} - -impl From for TraitBound { - fn from(value: PhantomConstGetBound) -> Self { - let path = Path::from(value); - TraitBound { - paren_token: None, - modifier: syn::TraitBoundModifier::None, - lifetimes: None, - path, - } - } -} - -impl From for TypeParamBound { - fn from(value: PhantomConstGetBound) -> Self { - TraitBound::from(value).into() - } -} - macro_rules! impl_bounds { ( #[struct = $struct_type:ident] @@ -2240,10 +2070,6 @@ macro_rules! impl_bounds { $( $Variant:ident, )* - $( - #[has_body] - $VariantHasBody:ident($variant_has_body_ty:ty), - )* $( #[unknown] $Unknown:ident, @@ -2253,7 +2079,6 @@ macro_rules! impl_bounds { #[derive(Clone, Debug)] $vis enum $enum_type { $($Variant(known_items::$Variant),)* - $($VariantHasBody($variant_has_body_ty),)* $($Unknown(syn::TypeParamBound),)? } @@ -2263,42 +2088,31 @@ macro_rules! impl_bounds { } })* - $(impl From<$variant_has_body_ty> for $enum_type { - fn from(v: $variant_has_body_ty) -> Self { - Self::$VariantHasBody(v) - } - })* - impl ToTokens for $enum_type { fn to_tokens(&self, tokens: &mut TokenStream) { match self { $(Self::$Variant(v) => v.to_tokens(tokens),)* - $(Self::$VariantHasBody(v) => v.to_tokens(tokens),)* $(Self::$Unknown(v) => v.to_tokens(tokens),)? } } } impl $enum_type { - $vis fn parse_path_with_arguments(path: Path) -> syn::Result> { + $vis fn parse_path(path: Path) -> Result { #![allow(unreachable_code)] $(let path = match known_items::$Variant::parse_path(path) { - Ok(v) => return Ok(Ok(Self::$Variant(v))), + Ok(v) => return Ok(Self::$Variant(v)), Err(path) => path, };)* - $(let path = match <$variant_has_body_ty>::parse_path_with_arguments(path)? { - Ok(v) => return Ok(Ok(Self::$VariantHasBody(v))), - Err(path) => path, - };)* - $(return Ok(Ok(Self::$Unknown(syn::TraitBound { + $(return Ok(Self::$Unknown(syn::TraitBound { paren_token: None, modifier: syn::TraitBoundModifier::None, lifetimes: None, path, - }.into())));)? - Ok(Err(path)) + }.into()));)? + Err(path) } - $vis fn parse_type_param_bound(mut type_param_bound: syn::TypeParamBound) -> syn::Result> { + $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 { @@ -2307,24 +2121,24 @@ macro_rules! impl_bounds { lifetimes: None, path: _, } = trait_bound { - match Self::parse_path_with_arguments(trait_bound.path)? { - Ok(retval) => return Ok(Ok(retval)), + 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(Ok(Self::$Unknown(type_param_bound)));)? - Ok(Err(type_param_bound)) + $(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()?)? + Self::parse_type_param_bound(input.parse()?) .map_err(|type_param_bound| syn::Error::new_spanned( type_param_bound, - format_args!("expected one of: {}", [$(stringify!($Variant),)* $(stringify!($VariantHasBody)),*].join(", ")), + format_args!("expected one of: {}", [$(stringify!($Variant)),*].join(", ")), )) } } @@ -2333,7 +2147,6 @@ macro_rules! impl_bounds { #[allow(non_snake_case)] $vis struct $struct_type { $($vis $Variant: Option,)* - $($vis $VariantHasBody: Option<$variant_has_body_ty>,)* $($vis $Unknown: Vec,)? } @@ -2346,11 +2159,6 @@ macro_rules! impl_bounds { separator = Some(::default()); v.to_tokens(tokens); })* - $(if let Some(v) = &self.$VariantHasBody { - separator.to_tokens(tokens); - separator = Some(::default()); - v.to_tokens(tokens); - })* $(for v in &self.$Unknown { separator.to_tokens(tokens); separator = Some(::default()); @@ -2364,7 +2172,6 @@ macro_rules! impl_bounds { #[allow(non_snake_case)] $vis struct Iter { $($Variant: Option,)* - $($VariantHasBody: Option<$variant_has_body_ty>,)* $($Unknown: std::vec::IntoIter,)? } @@ -2375,7 +2182,6 @@ macro_rules! impl_bounds { fn into_iter(self) -> Self::IntoIter { Iter { $($Variant: self.$Variant,)* - $($VariantHasBody: self.$VariantHasBody,)* $($Unknown: self.$Unknown.into_iter(),)? } } @@ -2390,11 +2196,6 @@ macro_rules! impl_bounds { return Some($enum_type::$Variant(value)); } )* - $( - if let Some(value) = self.$VariantHasBody.take() { - return Some($enum_type::$VariantHasBody(value)); - } - )* $( if let Some(value) = self.$Unknown.next() { return Some($enum_type::$Unknown(value)); @@ -2410,11 +2211,6 @@ macro_rules! impl_bounds { init = f(init, $enum_type::$Variant(value)); } )* - $( - if let Some(value) = self.$VariantHasBody.take() { - init = f(init, $enum_type::$VariantHasBody(value)); - } - )* $( if let Some(value) = self.$Unknown.next() { init = f(init, $enum_type::$Unknown(value)); @@ -2431,9 +2227,6 @@ macro_rules! impl_bounds { $($enum_type::$Variant(v) => { self.$Variant = Some(v); })* - $($enum_type::$VariantHasBody(v) => { - self.$VariantHasBody = Some(v); - })* $($enum_type::$Unknown(v) => { self.$Unknown.push(v); })? @@ -2455,9 +2248,6 @@ macro_rules! impl_bounds { $(if let Some(v) = v.$Variant { self.$Variant = Some(v); })* - $(if let Some(v) = v.$VariantHasBody { - self.$VariantHasBody = Some(v); - })* $(self.$Unknown.extend(v.$Unknown);)* }); } @@ -2512,8 +2302,6 @@ impl_bounds! { Size, StaticType, Type, - #[has_body] - PhantomConstGet(PhantomConstGetBound), #[unknown] Unknown, } @@ -2529,8 +2317,6 @@ impl_bounds! { ResetType, StaticType, Type, - #[has_body] - PhantomConstGet(PhantomConstGetBound), #[unknown] Unknown, } @@ -2546,7 +2332,6 @@ impl From for ParsedBound { ParsedTypeBound::ResetType(v) => ParsedBound::ResetType(v), ParsedTypeBound::StaticType(v) => ParsedBound::StaticType(v), ParsedTypeBound::Type(v) => ParsedBound::Type(v), - ParsedTypeBound::PhantomConstGet(v) => ParsedBound::PhantomConstGet(v), ParsedTypeBound::Unknown(v) => ParsedBound::Unknown(v), } } @@ -2562,7 +2347,6 @@ impl From for ParsedBounds { ResetType, StaticType, Type, - PhantomConstGet, Unknown, } = value; Self { @@ -2575,7 +2359,6 @@ impl From for ParsedBounds { Size: None, StaticType, Type, - PhantomConstGet, Unknown, } } @@ -2612,10 +2395,6 @@ impl ParsedTypeBound { ParsedTypeBound::Type(known_items::Type(span)), ]), Self::Type(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::from(v)]), - Self::PhantomConstGet(v) => ParsedTypeBounds::from_iter([ - ParsedTypeBound::from(v), - ParsedTypeBound::Type(known_items::Type(span)), - ]), Self::Unknown(v) => ParsedTypeBounds::from_iter([ParsedTypeBound::Unknown(v)]), } } @@ -2651,7 +2430,6 @@ impl From for ParsedBounds { Size, StaticType: None, Type: None, - PhantomConstGet: None, Unknown: vec![], } } @@ -2754,9 +2532,6 @@ 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::PhantomConstGet(v) => { - ParsedBoundCategory::Type(ParsedTypeBound::PhantomConstGet(v)) - } Self::Unknown(v) => ParsedBoundCategory::Unknown(v), } } @@ -3642,8 +3417,7 @@ impl ParsedGenerics { | ParsedTypeBound::BundleType(_) | ParsedTypeBound::EnumType(_) | ParsedTypeBound::IntType(_) - | ParsedTypeBound::ResetType(_) - | ParsedTypeBound::PhantomConstGet(_) => { + | ParsedTypeBound::ResetType(_) => { errors.error(bound, "bounds on mask types are not implemented"); } ParsedTypeBound::StaticType(bound) => { @@ -4612,124 +4386,3 @@ impl MakeHdlTypeExpr for ParsedTypeTuple { }) } } - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub(crate) enum ParsedSimpleVisibility { - Public(Token![pub]), - PubCrate { - pub_token: Token![pub], - paren_token: Paren, - crate_token: Token![crate], - }, - Inherited, -} - -impl From for Visibility { - fn from(value: ParsedSimpleVisibility) -> Self { - match value { - ParsedSimpleVisibility::Public(v) => Visibility::Public(v), - ParsedSimpleVisibility::PubCrate { - pub_token, - paren_token, - crate_token, - } => Visibility::Restricted(syn::VisRestricted { - pub_token, - paren_token, - in_token: None, - path: Box::new(Ident::new("crate", crate_token.span).into()), - }), - ParsedSimpleVisibility::Inherited => Visibility::Inherited, - } - } -} - -impl PartialOrd for ParsedSimpleVisibility { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for ParsedSimpleVisibility { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.visibility_level().cmp(&other.visibility_level()) - } -} - -impl ParsedSimpleVisibility { - const VISIBILITY_LEVEL_INHERITED: u8 = 0; - const VISIBILITY_LEVEL_RESTRICTED: u8 = 1 + Self::VISIBILITY_LEVEL_INHERITED; - const VISIBILITY_LEVEL_PUB_CRATE: u8 = 1 + Self::VISIBILITY_LEVEL_RESTRICTED; - const VISIBILITY_LEVEL_PUB: u8 = 1 + Self::VISIBILITY_LEVEL_PUB_CRATE; - fn visibility_level(self) -> u8 { - match self { - Self::Public(_) => Self::VISIBILITY_LEVEL_PUB, - Self::PubCrate { .. } => Self::VISIBILITY_LEVEL_PUB_CRATE, - Self::Inherited => Self::VISIBILITY_LEVEL_INHERITED, - } - } - pub(crate) fn parse(vis: Visibility) -> Result { - match vis { - Visibility::Public(v) => Ok(Self::Public(v)), - Visibility::Restricted(syn::VisRestricted { - pub_token, - paren_token, - in_token: None, - path, - }) if path.is_ident("crate") => Ok(Self::PubCrate { - pub_token, - paren_token, - crate_token: Token![crate](path.get_ident().expect("just checked").span()), - }), - Visibility::Restricted(v) => Err(v), - Visibility::Inherited => Ok(Self::Inherited), - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub(crate) enum ParsedVisibility { - Simple(ParsedSimpleVisibility), - Restricted(syn::VisRestricted), -} - -impl From for Visibility { - fn from(value: ParsedVisibility) -> Self { - match value { - ParsedVisibility::Simple(v) => v.into(), - ParsedVisibility::Restricted(v) => Visibility::Restricted(v), - } - } -} - -impl PartialOrd for ParsedVisibility { - fn partial_cmp(&self, other: &Self) -> Option { - match (self, other) { - (ParsedVisibility::Simple(l), ParsedVisibility::Simple(r)) => Some(l.cmp(r)), - (ParsedVisibility::Simple(l), ParsedVisibility::Restricted(_)) => Some( - l.visibility_level() - .cmp(&ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED), - ), - (ParsedVisibility::Restricted(_), ParsedVisibility::Simple(r)) => { - Some(ParsedSimpleVisibility::VISIBILITY_LEVEL_RESTRICTED.cmp(&r.visibility_level())) - } - (ParsedVisibility::Restricted(l), ParsedVisibility::Restricted(r)) => { - (l == r).then_some(std::cmp::Ordering::Equal) - } - } - } -} - -impl ParsedVisibility { - #[allow(dead_code)] - pub(crate) fn parse(vis: Visibility) -> Self { - match ParsedSimpleVisibility::parse(vis) { - Ok(simple) => Self::Simple(simple), - Err(restricted) => Self::Restricted(restricted), - } - } - #[allow(dead_code)] - pub(crate) fn min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> { - self.partial_cmp(other) - .map(|ord| if ord.is_lt() { self } else { other }) - } -} diff --git a/crates/fayalite-proc-macros-impl/src/lib.rs b/crates/fayalite-proc-macros-impl/src/lib.rs index 152053c..def91eb 100644 --- a/crates/fayalite-proc-macros-impl/src/lib.rs +++ b/crates/fayalite-proc-macros-impl/src/lib.rs @@ -66,7 +66,6 @@ mod kw { } custom_keyword!(__evaluated_cfgs); - custom_keyword!(add_platform_io); custom_keyword!(all); custom_keyword!(any); custom_keyword!(cfg); @@ -76,7 +75,6 @@ mod kw { custom_keyword!(connect_inexact); custom_keyword!(custom_bounds); custom_keyword!(flip); - custom_keyword!(get); custom_keyword!(hdl); custom_keyword!(hdl_module); custom_keyword!(incomplete_wire); @@ -887,13 +885,7 @@ pub(crate) fn outline_generated(contents: TokenStream, prefix: &str) -> TokenStr } } let _print_on_panic = PrintOnPanic(&contents); - let mut parse_err = None; - let (Ok(contents) | Err(contents)) = syn::parse2(contents.clone()) - .map(|file| prettyplease::unparse(&file)) - .map_err(|e| { - parse_err = Some(e); - contents.to_string() - }); + let contents = prettyplease::unparse(&parse_quote! { #contents }); let hash = ::digest(&contents); let hash = base16ct::HexDisplay(&hash[..5]); file.write_all(contents.as_bytes()).unwrap(); @@ -905,26 +897,9 @@ pub(crate) fn outline_generated(contents: TokenStream, prefix: &str) -> TokenStr e.unwrap(); } } - let log_msg = if let Some(parse_err) = parse_err { - format!( - "fayalite-proc-macros-impl internal error:\nfailed to parse generated output: {parse_err}\nunformatted output is in: {}\n", - dest_file.display() - ) - } else { - format!("generated {}\n", dest_file.display()) - }; - // write message atomically if possible - let mut stderr = std::io::stderr().lock(); - let write_result = stderr.write_all(log_msg.as_bytes()); - let flush_result = stderr.flush(); - drop(stderr); // unlock before we try to panic - write_result.unwrap(); - flush_result.unwrap(); - std::io::stderr() - .lock() - .write_all(log_msg.as_bytes()) - .unwrap(); + eprintln!("generated {}", dest_file.display()); let dest_file = dest_file.to_str().unwrap(); + quote! { include!(#dest_file); } diff --git a/crates/fayalite-proc-macros-impl/src/module.rs b/crates/fayalite-proc-macros-impl/src/module.rs index 5628ff9..c7caa16 100644 --- a/crates/fayalite-proc-macros-impl/src/module.rs +++ b/crates/fayalite-proc-macros-impl/src/module.rs @@ -4,7 +4,7 @@ use crate::{ Errors, HdlAttr, PairsIterExt, hdl_type_common::{ParsedGenerics, SplitForImpl}, kw, - module::transform_body::{HdlLet, HdlLetKindIO, ModuleIOOrAddPlatformIO}, + module::transform_body::{HdlLet, HdlLetKindIO}, options, }; use proc_macro2::TokenStream; @@ -39,7 +39,7 @@ pub(crate) fn check_name_conflicts_with_module_builder(name: &Ident) -> syn::Res if name == "m" { Err(Error::new_spanned( name, - "name conflicts with implicit `m: &ModuleBuilder`", + "name conflicts with implicit `m: &mut ModuleBuilder<_>`", )) } else { Ok(()) @@ -67,7 +67,7 @@ struct ModuleFnModule { vis: Visibility, sig: Signature, block: Box, - struct_generics: Option, + struct_generics: ParsedGenerics, the_struct: TokenStream, } @@ -290,7 +290,7 @@ impl ModuleFn { paren_token, body, } => { - debug_assert!(matches!(io, ModuleIOOrAddPlatformIO::ModuleIO(v) if v.is_empty())); + debug_assert!(io.is_empty()); return Ok(Self(ModuleFnImpl::Fn { attrs, config_options: HdlAttr { @@ -322,21 +322,6 @@ impl ModuleFn { body, }, }; - let io = match io { - ModuleIOOrAddPlatformIO::ModuleIO(io) => io, - ModuleIOOrAddPlatformIO::AddPlatformIO => { - return Ok(Self(ModuleFnImpl::Module(ModuleFnModule { - attrs, - config_options, - module_kind: module_kind.unwrap(), - vis, - sig, - block, - struct_generics: None, - the_struct: TokenStream::new(), - }))); - } - }; let (_struct_impl_generics, _struct_type_generics, struct_where_clause) = struct_generics.split_for_impl(); let struct_where_clause: Option = parse_quote! { #struct_where_clause }; @@ -379,7 +364,7 @@ impl ModuleFn { vis, sig, block, - struct_generics: Some(struct_generics), + struct_generics, the_struct, }))) } @@ -448,14 +433,9 @@ impl ModuleFn { ModuleKind::Normal => quote! { ::fayalite::module::ModuleKind::Normal }, }; let fn_name = &outer_sig.ident; - let struct_ty = match struct_generics { - Some(struct_generics) => { - let (_struct_impl_generics, struct_type_generics, _struct_where_clause) = - struct_generics.split_for_impl(); - quote! {#fn_name #struct_type_generics} - } - None => quote! {::fayalite::bundle::Bundle}, - }; + let (_struct_impl_generics, struct_type_generics, _struct_where_clause) = + struct_generics.split_for_impl(); + let struct_ty = quote! {#fn_name #struct_type_generics}; body_sig.ident = parse_quote! {__body}; body_sig .inputs 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 7b41f5e..6859f69 100644 --- a/crates/fayalite-proc-macros-impl/src/module/transform_body.rs +++ b/crates/fayalite-proc-macros-impl/src/module/transform_body.rs @@ -39,7 +39,6 @@ options! { pub(crate) enum LetFnKind { Input(input), Output(output), - AddPlatformIO(add_platform_io), Instance(instance), RegBuilder(reg_builder), Wire(wire), @@ -217,49 +216,6 @@ impl HdlLetKindToTokens for HdlLetKindInstance { } } -#[derive(Clone, Debug)] -pub(crate) struct HdlLetKindAddPlatformIO { - pub(crate) m: kw::m, - pub(crate) dot_token: Token![.], - pub(crate) add_platform_io: kw::add_platform_io, - pub(crate) paren: Paren, - pub(crate) platform_io_builder: Box, -} - -impl ParseTypes for HdlLetKindAddPlatformIO { - fn parse_types(input: &mut Self, _parser: &mut TypesParser<'_>) -> Result { - Ok(input.clone()) - } -} - -impl_fold! { - struct HdlLetKindAddPlatformIO<> { - m: kw::m, - dot_token: Token![.], - add_platform_io: kw::add_platform_io, - paren: Paren, - platform_io_builder: Box, - } -} - -impl HdlLetKindToTokens for HdlLetKindAddPlatformIO { - fn ty_to_tokens(&self, _tokens: &mut TokenStream) {} - - fn expr_to_tokens(&self, tokens: &mut TokenStream) { - let Self { - m, - dot_token, - add_platform_io, - paren, - platform_io_builder, - } = self; - m.to_tokens(tokens); - dot_token.to_tokens(tokens); - add_platform_io.to_tokens(tokens); - paren.surround(tokens, |tokens| platform_io_builder.to_tokens(tokens)); - } -} - #[derive(Clone, Debug)] pub(crate) struct RegBuilderClockDomain { pub(crate) dot_token: Token![.], @@ -755,7 +711,6 @@ impl HdlLetKindMemory { #[derive(Clone, Debug)] pub(crate) enum HdlLetKind { IO(HdlLetKindIO), - AddPlatformIO(HdlLetKindAddPlatformIO), Incomplete(HdlLetKindIncomplete), Instance(HdlLetKindInstance), RegBuilder(HdlLetKindRegBuilder), @@ -766,7 +721,6 @@ pub(crate) enum HdlLetKind { impl_fold! { enum HdlLetKind { IO(HdlLetKindIO), - AddPlatformIO(HdlLetKindAddPlatformIO), Incomplete(HdlLetKindIncomplete), Instance(HdlLetKindInstance), RegBuilder(HdlLetKindRegBuilder), @@ -782,9 +736,6 @@ impl, I> ParseTypes> for HdlLetKind { ) -> Result { match input { HdlLetKind::IO(input) => ParseTypes::parse_types(input, parser).map(HdlLetKind::IO), - HdlLetKind::AddPlatformIO(input) => { - ParseTypes::parse_types(input, parser).map(HdlLetKind::AddPlatformIO) - } HdlLetKind::Incomplete(input) => { ParseTypes::parse_types(input, parser).map(HdlLetKind::Incomplete) } @@ -910,23 +861,6 @@ impl HdlLetKindParse for HdlLetKind { ModuleIOKind::Output(output), ) .map(Self::IO), - LetFnKind::AddPlatformIO((add_platform_io,)) => { - if let Some(parsed_ty) = parsed_ty { - return Err(Error::new_spanned( - parsed_ty.1, - "type annotation not allowed for instance", - )); - } - let (m, dot_token) = unwrap_m_dot(m_dot, kind)?; - let paren_contents; - Ok(Self::AddPlatformIO(HdlLetKindAddPlatformIO { - m, - dot_token, - add_platform_io, - paren: parenthesized!(paren_contents in input), - platform_io_builder: paren_contents.call(parse_single_fn_arg)?, - })) - } LetFnKind::Instance((instance,)) => { if let Some(parsed_ty) = parsed_ty { return Err(Error::new_spanned( @@ -1002,7 +936,6 @@ impl HdlLetKindToTokens for HdlLetKind { fn ty_to_tokens(&self, tokens: &mut TokenStream) { match self { HdlLetKind::IO(v) => v.ty_to_tokens(tokens), - HdlLetKind::AddPlatformIO(v) => v.ty_to_tokens(tokens), HdlLetKind::Incomplete(v) => v.ty_to_tokens(tokens), HdlLetKind::Instance(v) => v.ty_to_tokens(tokens), HdlLetKind::RegBuilder(v) => v.ty_to_tokens(tokens), @@ -1014,7 +947,6 @@ impl HdlLetKindToTokens for HdlLetKind { fn expr_to_tokens(&self, tokens: &mut TokenStream) { match self { HdlLetKind::IO(v) => v.expr_to_tokens(tokens), - HdlLetKind::AddPlatformIO(v) => v.expr_to_tokens(tokens), HdlLetKind::Incomplete(v) => v.expr_to_tokens(tokens), HdlLetKind::Instance(v) => v.expr_to_tokens(tokens), HdlLetKind::RegBuilder(v) => v.expr_to_tokens(tokens), @@ -1217,7 +1149,7 @@ impl ToTokens for ImplicitName { struct Visitor<'a> { module_kind: Option, errors: Errors, - io: ModuleIOOrAddPlatformIO, + io: Vec, block_depth: usize, parsed_generics: &'a ParsedGenerics, } @@ -1357,81 +1289,7 @@ impl Visitor<'_> { }), semi_token: hdl_let.semi_token, }; - match &mut self.io { - ModuleIOOrAddPlatformIO::ModuleIO(io) => io.push(hdl_let), - ModuleIOOrAddPlatformIO::AddPlatformIO => { - self.errors.error( - kind, - "can't have other inputs/outputs in a module using m.add_platform_io()", - ); - } - } - let_stmt - } - fn process_hdl_let_add_platform_io( - &mut self, - hdl_let: HdlLet, - ) -> Local { - let HdlLet { - mut attrs, - hdl_attr: _, - let_token, - mut_token, - ref name, - eq_token, - kind: - HdlLetKindAddPlatformIO { - m, - dot_token, - add_platform_io, - paren, - platform_io_builder, - }, - semi_token, - } = hdl_let; - let mut expr = quote! {#m #dot_token #add_platform_io}; - paren.surround(&mut expr, |expr| { - let name_str = ImplicitName { - name, - span: name.span(), - }; - quote_spanned! {name.span()=> - #name_str, #platform_io_builder - } - .to_tokens(expr); - }); - self.require_module(add_platform_io); - attrs.push(parse_quote_spanned! {let_token.span=> - #[allow(unused_variables)] - }); - let let_stmt = Local { - attrs, - let_token, - pat: parse_quote! { #mut_token #name }, - init: Some(LocalInit { - eq_token, - expr: parse_quote! { #expr }, - diverge: None, - }), - semi_token, - }; - match &mut self.io { - ModuleIOOrAddPlatformIO::ModuleIO(io) => { - for io in io { - self.errors.error( - io.kind.kind, - "can't have other inputs/outputs in a module using m.add_platform_io()", - ); - } - } - ModuleIOOrAddPlatformIO::AddPlatformIO => { - self.errors.error( - add_platform_io, - "can't use m.add_platform_io() more than once in a single module", - ); - } - } - self.io = ModuleIOOrAddPlatformIO::AddPlatformIO; + self.io.push(hdl_let); let_stmt } fn process_hdl_let_instance(&mut self, hdl_let: HdlLet) -> Local { @@ -1652,7 +1510,6 @@ impl Visitor<'_> { } the_match! { IO => process_hdl_let_io, - AddPlatformIO => process_hdl_let_add_platform_io, Incomplete => process_hdl_let_incomplete, Instance => process_hdl_let_instance, RegBuilder => process_hdl_let_reg_builder, @@ -1896,20 +1753,15 @@ impl Fold for Visitor<'_> { } } -pub(crate) enum ModuleIOOrAddPlatformIO { - ModuleIO(Vec), - AddPlatformIO, -} - pub(crate) fn transform_body( module_kind: Option, mut body: Box, parsed_generics: &ParsedGenerics, -) -> syn::Result<(Box, ModuleIOOrAddPlatformIO)> { +) -> syn::Result<(Box, Vec)> { let mut visitor = Visitor { module_kind, errors: Errors::new(), - io: ModuleIOOrAddPlatformIO::ModuleIO(vec![]), + io: vec![], block_depth: 0, parsed_generics, }; 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 e30eb0f..1aabb19 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 @@ -88,9 +88,6 @@ impl Visitor<'_> { field.expr = parse_quote_spanned! {field.member.span()=> ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr)) }; - field - .colon_token - .get_or_insert(Token![:](field.member.span())); } return parse_quote_spanned! {name_span=> { diff --git a/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_match.rs b/crates/fayalite-proc-macros-impl/src/module/transform_body/expand_match.rs index ca06c0b..069f00d 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 @@ -10,7 +10,7 @@ use crate::{ }; use proc_macro2::{Span, TokenStream}; use quote::{ToTokens, TokenStreamExt, format_ident, quote_spanned}; -use std::collections::BTreeMap; +use std::collections::BTreeSet; use syn::{ Arm, Attribute, Expr, ExprMatch, FieldPat, Ident, Local, Member, Pat, PatIdent, PatOr, PatParen, PatPath, PatRest, PatStruct, PatTuple, PatTupleStruct, PatWild, Path, PathSegment, @@ -24,65 +24,65 @@ use syn::{ macro_rules! visit_trait { ( - $($vis:vis fn $fn:ident($state:ident: _, $value:ident: &mut $Value:ty) $block:block)* + $($vis:vis fn $fn:ident($state:ident: _, $value:ident: &$Value:ty) $block:block)* ) => { trait VisitMatchPat<'a> { - $(fn $fn(&mut self, $value: &'a mut $Value) { + $(fn $fn(&mut self, $value: &'a $Value) { $fn(self, $value); })* } - $($vis fn $fn<'a>($state: &mut (impl ?Sized + VisitMatchPat<'a>), $value: &'a mut $Value) $block)* + $($vis fn $fn<'a>($state: &mut (impl ?Sized + VisitMatchPat<'a>), $value: &'a $Value) $block)* }; } visit_trait! { - fn visit_match_pat_binding(_state: _, v: &mut MatchPatBinding) { - let MatchPatBinding { mutability: _, ident: _ } = v; + fn visit_match_pat_binding(_state: _, v: &MatchPatBinding) { + let MatchPatBinding { ident: _ } = v; } - fn visit_match_pat_wild(_state: _, v: &mut MatchPatWild) { + fn visit_match_pat_wild(_state: _, v: &MatchPatWild) { let MatchPatWild { underscore_token: _ } = v; } - fn visit_match_pat_rest(_state: _, v: &mut MatchPatRest) { + fn visit_match_pat_rest(_state: _, v: &MatchPatRest) { let MatchPatRest { dot2_token: _ } = v; } - fn visit_match_pat_paren(state: _, v: &mut MatchPatParen) { + fn visit_match_pat_paren(state: _, v: &MatchPatParen) { let MatchPatParen { paren_token: _, pat } = v; state.visit_match_pat(pat); } - fn visit_match_pat_paren_simple(state: _, v: &mut MatchPatParen) { + fn visit_match_pat_paren_simple(state: _, v: &MatchPatParen) { let MatchPatParen { paren_token: _, pat } = v; state.visit_match_pat_simple(pat); } - fn visit_match_pat_or(state: _, v: &mut MatchPatOr) { + fn visit_match_pat_or(state: _, v: &MatchPatOr) { let MatchPatOr { leading_vert: _, cases } = v; for v in cases { state.visit_match_pat(v); } } - fn visit_match_pat_or_simple(state: _, v: &mut MatchPatOr) { + fn visit_match_pat_or_simple(state: _, v: &MatchPatOr) { let MatchPatOr { leading_vert: _, cases } = v; for v in cases { state.visit_match_pat_simple(v); } } - fn visit_match_pat_struct_field(state: _, v: &mut MatchPatStructField) { + fn visit_match_pat_struct_field(state: _, v: &MatchPatStructField) { let MatchPatStructField { field_name: _, colon_token: _, pat } = v; state.visit_match_pat_simple(pat); } - fn visit_match_pat_struct(state: _, v: &mut MatchPatStruct) { + fn visit_match_pat_struct(state: _, v: &MatchPatStruct) { let MatchPatStruct { match_span: _, path: _, brace_token: _, fields, rest: _ } = v; for v in fields { state.visit_match_pat_struct_field(v); } } - fn visit_match_pat_tuple(state: _, v: &mut MatchPatTuple) { + fn visit_match_pat_tuple(state: _, v: &MatchPatTuple) { let MatchPatTuple { paren_token: _, fields } = v; for v in fields { state.visit_match_pat_simple(v); } } - fn visit_match_pat_enum_variant(state: _, v: &mut MatchPatEnumVariant) { + fn visit_match_pat_enum_variant(state: _, v: &MatchPatEnumVariant) { let MatchPatEnumVariant { match_span:_, sim:_, @@ -95,7 +95,7 @@ visit_trait! { state.visit_match_pat_simple(v); } } - fn visit_match_pat_simple(state: _, v: &mut MatchPatSimple) { + fn visit_match_pat_simple(state: _, v: &MatchPatSimple) { match v { MatchPatSimple::Paren(v) => state.visit_match_pat_paren_simple(v), MatchPatSimple::Or(v) => state.visit_match_pat_or_simple(v), @@ -104,7 +104,7 @@ visit_trait! { MatchPatSimple::Rest(v) => state.visit_match_pat_rest(v), } } - fn visit_match_pat(state: _, v: &mut MatchPat) { + fn visit_match_pat(state: _, v: &MatchPat) { match v { MatchPat::Simple(v) => state.visit_match_pat_simple(v), MatchPat::Or(v) => state.visit_match_pat_or(v), @@ -118,15 +118,13 @@ visit_trait! { with_debug_clone_and_fold! { struct MatchPatBinding<> { - mutability: Option, ident: Ident, } } impl ToTokens for MatchPatBinding { fn to_tokens(&self, tokens: &mut TokenStream) { - let Self { mutability, ident } = self; - mutability.to_tokens(tokens); + let Self { ident } = self; ident.to_tokens(tokens); } } @@ -213,20 +211,12 @@ impl ToTokens for MatchPatStructField { colon_token, pat, } = self; - if let ( - None, - MatchPatSimple::Binding(MatchPatBinding { - mutability: _, - ident, - }), - ) = (colon_token, pat) - { + field_name.to_tokens(tokens); + if let (None, MatchPatSimple::Binding(MatchPatBinding { ident })) = (colon_token, pat) { if field_name == ident { - pat.to_tokens(tokens); return; } } - field_name.to_tokens(tokens); colon_token .unwrap_or_else(|| Token![:](field_name.span())) .to_tokens(tokens); @@ -460,7 +450,7 @@ trait ParseMatchPat: Sized { Pat::Ident(PatIdent { attrs: _, by_ref, - mut mutability, + mutability, ident, subpat, }) => { @@ -469,13 +459,10 @@ trait ParseMatchPat: Sized { .errors .error(by_ref, "ref not allowed in #[hdl] patterns"); } - if let Some(mut_token) = mutability { - if state.sim.is_none() { - state - .errors - .error(mut_token, "mut not allowed in #[hdl] patterns"); - mutability = None; // avoid duplicate errors - } + if let Some(mutability) = mutability { + state + .errors + .error(mutability, "mut not allowed in #[hdl] patterns"); } if let Some((at_token, _)) = subpat { state @@ -487,26 +474,18 @@ trait ParseMatchPat: Sized { variant_path, enum_path, variant_name, - }) => { - if let Some(mut_token) = mutability { - state - .errors - .error(mut_token, "mut not allowed on unit variants"); - } - Self::enum_variant( - state, - MatchPatEnumVariant { - match_span: state.match_span, - sim: state.sim, - variant_path, - enum_path, - variant_name, - field: None, - }, - ) - } + }) => Self::enum_variant( + state, + MatchPatEnumVariant { + match_span: state.match_span, + sim: state.sim, + variant_path, + enum_path, + variant_name, + field: None, + }, + ), Err(ident) => Ok(Self::simple(MatchPatSimple::Binding(MatchPatBinding { - mutability, ident, }))), } @@ -1001,16 +980,15 @@ struct HdlMatchParseState<'a> { struct HdlLetPatVisitState<'a> { errors: &'a mut Errors, - bindings: BTreeMap, + bindings: BTreeSet<&'a Ident>, } impl<'a> VisitMatchPat<'a> for HdlLetPatVisitState<'a> { - fn visit_match_pat_binding(&mut self, v: &'a mut MatchPatBinding) { - self.bindings.insert(v.ident.clone(), v.clone()); - v.mutability = None; + fn visit_match_pat_binding(&mut self, v: &'a MatchPatBinding) { + self.bindings.insert(&v.ident); } - fn visit_match_pat_or(&mut self, v: &'a mut MatchPatOr) { + fn visit_match_pat_or(&mut self, v: &'a MatchPatOr) { if let Some(first_inner_vert) = v.first_inner_vert() { self.errors.error( first_inner_vert, @@ -1020,7 +998,7 @@ impl<'a> VisitMatchPat<'a> for HdlLetPatVisitState<'a> { visit_match_pat_or(self, v); } - fn visit_match_pat_or_simple(&mut self, v: &'a mut MatchPatOr) { + fn visit_match_pat_or_simple(&mut self, v: &'a MatchPatOr) { if let Some(first_inner_vert) = v.first_inner_vert() { self.errors.error( first_inner_vert, @@ -1030,7 +1008,7 @@ impl<'a> VisitMatchPat<'a> for HdlLetPatVisitState<'a> { visit_match_pat_or_simple(self, v); } - fn visit_match_pat_enum_variant(&mut self, v: &'a mut MatchPatEnumVariant) { + fn visit_match_pat_enum_variant(&mut self, v: &'a MatchPatEnumVariant) { self.errors.error(v, "refutable pattern in let statement"); } } @@ -1070,7 +1048,7 @@ impl Visitor<'_> { .error(else_, "#[hdl] let ... else { ... } is not implemented"); return empty_let(); } - let Ok(mut pat) = MatchPat::parse( + let Ok(pat) = MatchPat::parse( &mut HdlMatchParseState { sim, match_span: span, @@ -1082,27 +1060,20 @@ impl Visitor<'_> { }; let mut state = HdlLetPatVisitState { errors: &mut self.errors, - bindings: BTreeMap::new(), + bindings: BTreeSet::new(), }; - state.visit_match_pat(&mut pat); + state.visit_match_pat(&pat); let HdlLetPatVisitState { errors: _, bindings, } = state; - let bindings_idents = bindings.keys(); - let bindings = bindings.values(); let retval = if sim.is_some() { parse_quote_spanned! {span=> let (#(#bindings,)*) = { type __MatchTy = ::SimValue; - let __match_value = #expr; - let __match_value = { - use ::fayalite::sim::value::match_sim_value::*; - // use method syntax to deduce the correct trait to call - ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value).__fayalite_match_sim_value() - }; - #let_token #pat #eq_token __match_value #semi_token - (#(#bindings_idents,)*) + 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,)*) }; } } else { @@ -1134,7 +1105,7 @@ impl Visitor<'_> { __match_variant, ); #let_token #pat #eq_token __match_variant #semi_token - (#(#bindings_idents,)* __scope,) + (#(#bindings,)* __scope,) }; } }; @@ -1171,13 +1142,8 @@ impl Visitor<'_> { quote_spanned! {span=> { type __MatchTy = ::SimValue; - let __match_value = #expr; - let __match_value = { - use ::fayalite::sim::value::match_sim_value::*; - // use method syntax to deduce the correct trait to call - ::fayalite::sim::value::match_sim_value::MatchSimValueHelper::new(__match_value).__fayalite_match_sim_value() - }; - #match_token __match_value { + let __match_expr = ::fayalite::sim::value::ToSimValue::to_sim_value(&(#expr)); + #match_token ::fayalite::sim::value::SimValue::into_value(__match_expr) { #(#arms)* } } diff --git a/crates/fayalite/Cargo.toml b/crates/fayalite/Cargo.toml index fdf1c87..082e607 100644 --- a/crates/fayalite/Cargo.toml +++ b/crates/fayalite/Cargo.toml @@ -14,11 +14,9 @@ rust-version.workspace = true version.workspace = true [dependencies] -base64.workspace = true bitvec.workspace = true blake3.workspace = true clap.workspace = true -clap_complete.workspace = true ctor.workspace = true eyre.workspace = true fayalite-proc-macros.workspace = true @@ -26,7 +24,7 @@ hashbrown.workspace = true jobslot.workspace = true num-bigint.workspace = true num-traits.workspace = true -ordered-float.workspace = true +os_pipe.workspace = true petgraph.workspace = true serde_json.workspace = true serde.workspace = true diff --git a/crates/fayalite/examples/blinky.rs b/crates/fayalite/examples/blinky.rs index d2cdb33..87b77c1 100644 --- a/crates/fayalite/examples/blinky.rs +++ b/crates/fayalite/examples/blinky.rs @@ -1,64 +1,47 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information -use fayalite::prelude::*; +use clap::Parser; +use fayalite::{cli, prelude::*}; #[hdl_module] -fn blinky(platform_io_builder: PlatformIOBuilder<'_>) { - let clk_input = - platform_io_builder.peripherals_with_type::()[0].use_peripheral(); - let rst = platform_io_builder.peripherals_with_type::()[0].use_peripheral(); +fn blinky(clock_frequency: u64) { + #[hdl] + let clk: Clock = m.input(); + #[hdl] + let rst: SyncReset = m.input(); let cd = #[hdl] ClockDomain { - clk: clk_input.clk, - rst, + clk, + rst: rst.to_reset(), }; - let max_value = (clk_input.ty().frequency() / 2.0).round_ties_even() as u64 - 1; + let max_value = clock_frequency / 2 - 1; let int_ty = UInt::range_inclusive(0..=max_value); #[hdl] let counter_reg: UInt = reg_builder().clock_domain(cd).reset(0u8.cast_to(int_ty)); #[hdl] let output_reg: Bool = reg_builder().clock_domain(cd).reset(false); #[hdl] - let rgb_output_reg = reg_builder().clock_domain(cd).reset( - #[hdl] - peripherals::RgbLed { - r: false, - g: false, - b: false, - }, - ); - #[hdl] if counter_reg.cmp_eq(max_value) { connect_any(counter_reg, 0u8); connect(output_reg, !output_reg); - connect(rgb_output_reg.r, !rgb_output_reg.r); - #[hdl] - if rgb_output_reg.r { - connect(rgb_output_reg.g, !rgb_output_reg.g); - #[hdl] - if rgb_output_reg.g { - connect(rgb_output_reg.b, !rgb_output_reg.b); - } - } } else { connect_any(counter_reg, counter_reg + 1_hdl_u1); } - for led in platform_io_builder.peripherals_with_type::() { - if let Ok(led) = led.try_use_peripheral() { - connect(led.on, output_reg); - } - } - for rgb_led in platform_io_builder.peripherals_with_type::() { - if let Ok(rgb_led) = rgb_led.try_use_peripheral() { - connect(rgb_led, rgb_output_reg); - } - } #[hdl] - let io = m.add_platform_io(platform_io_builder); + let led: Bool = m.output(); + connect(led, output_reg); } -fn main() { - ::main("blinky", |_, platform, _| { - Ok(JobParams::new(platform.wrap_main_module(blinky))) - }); +#[derive(Parser)] +struct Cli { + /// clock frequency in hertz + #[arg(long, default_value = "1000000", value_parser = clap::value_parser!(u64).range(2..))] + clock_frequency: u64, + #[command(subcommand)] + cli: cli::Cli, +} + +fn main() -> cli::Result { + let cli = Cli::parse(); + cli.cli.run(blinky(cli.clock_frequency)) } diff --git a/crates/fayalite/examples/tx_only_uart.rs b/crates/fayalite/examples/tx_only_uart.rs deleted file mode 100644 index 59e2968..0000000 --- a/crates/fayalite/examples/tx_only_uart.rs +++ /dev/null @@ -1,188 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information -use clap::builder::TypedValueParser; -use fayalite::{ - build::{ToArgs, WriteArgs}, - platform::PeripheralRef, - prelude::*, -}; -use ordered_float::NotNan; - -fn pick_clock<'a>( - platform_io_builder: &PlatformIOBuilder<'a>, -) -> PeripheralRef<'a, peripherals::ClockInput> { - let mut clks = platform_io_builder.peripherals_with_type::(); - clks.sort_by_key(|clk| { - // sort clocks by preference, smaller return values means higher preference - let mut frequency = clk.ty().frequency(); - let priority; - if frequency < 10e6 { - frequency = -frequency; // prefer bigger frequencies - priority = 1; - } else if frequency > 50e6 { - // prefer smaller frequencies - priority = 2; // least preferred - } else { - priority = 0; // most preferred - frequency = (frequency - 25e6).abs(); // prefer closer to 25MHz - } - (priority, NotNan::new(frequency).expect("should be valid")) - }); - clks[0] -} - -#[hdl_module] -fn tx_only_uart( - platform_io_builder: PlatformIOBuilder<'_>, - divisor: f64, - message: impl AsRef<[u8]>, -) { - let message = message.as_ref(); - let clk_input = pick_clock(&platform_io_builder).use_peripheral(); - let rst = platform_io_builder.peripherals_with_type::()[0].use_peripheral(); - let cd = #[hdl] - ClockDomain { - clk: clk_input.clk, - rst, - }; - let numerator = 1u128 << 16; - let denominator = (divisor * numerator as f64).round() as u128; - - #[hdl] - let remainder_reg: UInt<128> = reg_builder().clock_domain(cd).reset(0u128); - - #[hdl] - let sum: UInt<128> = wire(); - connect_any(sum, remainder_reg + numerator); - - #[hdl] - let tick_reg = reg_builder().clock_domain(cd).reset(false); - connect(tick_reg, false); - - #[hdl] - let next_remainder: UInt<128> = wire(); - connect(remainder_reg, next_remainder); - - #[hdl] - if sum.cmp_ge(denominator) { - connect_any(next_remainder, sum - denominator); - connect(tick_reg, true); - } else { - connect(next_remainder, sum); - } - - #[hdl] - let uart_state_reg = reg_builder().clock_domain(cd).reset(0_hdl_u4); - #[hdl] - let next_uart_state: UInt<4> = wire(); - - connect_any(next_uart_state, uart_state_reg + 1u8); - - #[hdl] - let message_mem: Array> = wire(Array[UInt::new_static()][message.len()]); - for (message, message_mem) in message.iter().zip(message_mem) { - connect(message_mem, *message); - } - #[hdl] - let addr_reg: UInt<32> = reg_builder().clock_domain(cd).reset(0u32); - #[hdl] - let next_addr: UInt<32> = wire(); - connect(next_addr, addr_reg); - - #[hdl] - let tx = reg_builder().clock_domain(cd).reset(true); - - #[hdl] - let tx_bits: Array = wire(); - - connect(tx_bits[0], false); // start bit - connect(tx_bits[9], true); // stop bit - - for i in 0..8 { - connect(tx_bits[i + 1], message_mem[addr_reg][i]); // data bits - } - - connect(tx, tx_bits[uart_state_reg]); - - #[hdl] - if uart_state_reg.cmp_eq(tx_bits.ty().len() - 1) { - connect(next_uart_state, 0_hdl_u4); - let next_addr_val = addr_reg + 1u8; - #[hdl] - if next_addr_val.cmp_lt(message.len()) { - connect_any(next_addr, next_addr_val); - } else { - connect(next_addr, 0u32); - } - } - - #[hdl] - if tick_reg { - connect(uart_state_reg, next_uart_state); - connect(addr_reg, next_addr); - } - - for uart in platform_io_builder.peripherals_with_type::() { - connect(uart.use_peripheral().tx, tx); - } - - #[hdl] - let io = m.add_platform_io(platform_io_builder); -} - -fn parse_baud_rate( - v: impl AsRef, -) -> Result, Box> { - let retval: NotNan = v - .as_ref() - .parse() - .map_err(|_| "invalid baud rate, must be a finite positive floating-point value")?; - if *retval > 0.0 && retval.is_finite() { - Ok(retval) - } else { - Err("baud rate must be finite and positive".into()) - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -pub struct ExtraArgs { - #[arg(long, value_parser = clap::builder::StringValueParser::new().try_map(parse_baud_rate), default_value = "115200")] - pub baud_rate: NotNan, - #[arg(long, default_value = "Hello World from Fayalite!!!\r\n", value_parser = clap::builder::NonEmptyStringValueParser::new())] - pub message: String, -} - -impl ToArgs for ExtraArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { baud_rate, message } = self; - args.write_display_arg(format_args!("--baud-rate={baud_rate}")); - args.write_long_option_eq("message", message); - } -} - -fn main() { - type Cli = BuildCli; - Cli::main( - "tx_only_uart", - |_, platform, ExtraArgs { baud_rate, message }| { - Ok(JobParams::new(platform.try_wrap_main_module(|io| { - let clk = pick_clock(&io).ty(); - let divisor = clk.frequency() / *baud_rate; - let baud_rate_error = |msg| { - ::command() - .error(clap::error::ErrorKind::ValueValidation, msg) - }; - const HUGE_DIVISOR: f64 = u64::MAX as f64; - match divisor { - divisor if !divisor.is_finite() => { - return Err(baud_rate_error("bad baud rate")); - } - HUGE_DIVISOR.. => return Err(baud_rate_error("baud rate is too small")), - 4.0.. => {} - _ => return Err(baud_rate_error("baud rate is too large")), - } - Ok(tx_only_uart(io, divisor, message)) - })?)) - }, - ); -} diff --git a/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs b/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs index 8d70d21..1fc4705 100644 --- a/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs +++ b/crates/fayalite/src/_docs/modules/module_bodies/hdl_let_statements/destructuring.rs @@ -31,81 +31,3 @@ //! } //! } //! ``` -//! -//! You can also use `#[hdl(sim)] let` to destructure [`SimValue`]s (or anything that implements [`ToSimValue`]). -//! -//! [`SimValue`]: crate::sim::value::SimValue -//! [`ToSimValue`]: crate::sim::value::ToSimValue -//! -//! ``` -//! # use fayalite::prelude::*; -//! #[hdl] -//! struct MyStruct { -//! a: UInt<8>, -//! b: Bool, -//! c: T, -//! } -//! -//! #[hdl] -//! fn destructure(v: SimValue>) { -//! #[hdl(sim)] -//! let MyStruct:: { -//! a, -//! mut b, -//! c, -//! } = v; -//! -//! // that gives these types: -//! let _: SimValue> = a; -//! let _: SimValue = b; -//! let _: SimValue = c; -//! *b = false; // can modify b since mut was used -//! } -//! -//! #[hdl] -//! fn destructure_ref<'a, T: Type>(v: &'a SimValue>) { -//! #[hdl(sim)] -//! let MyStruct:: { -//! a, -//! b, -//! c, -//! } = v; -//! -//! // that gives these types: -//! let _: &'a SimValue> = a; -//! let _: &'a SimValue = b; -//! let _: &'a SimValue = c; -//! } -//! -//! #[hdl] -//! fn destructure_mut<'a, T: Type>(v: &'a mut SimValue>) { -//! #[hdl(sim)] -//! let MyStruct:: { -//! a, -//! b, -//! c, -//! } = v; -//! -//! **b = true; // you can modify v by modifying b which borrows from it -//! -//! // that gives these types: -//! let _: &'a mut SimValue> = a; -//! let _: &'a mut SimValue = b; -//! let _: &'a mut SimValue = c; -//! } -//! -//! #[hdl] -//! fn destructure_to_sim_value<'a, T: Type>(v: impl ToSimValue>) { -//! #[hdl(sim)] -//! let MyStruct:: { -//! a, -//! b, -//! c, -//! } = v; -//! -//! // that gives these types: -//! let _: SimValue> = a; -//! let _: SimValue = b; -//! let _: SimValue = c; -//! } -//! ``` diff --git a/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs b/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs index accd3d7..6df70f1 100644 --- a/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs +++ b/crates/fayalite/src/_docs/modules/module_bodies/hdl_match_statements.rs @@ -9,78 +9,3 @@ //! //! `#[hdl] match` statements can only match one level of struct/tuple/enum pattern for now, //! e.g. you can match with the pattern `HdlSome(v)`, but not `HdlSome(HdlSome(_))`. -//! -//! You can also use `#[hdl(sim)] match` to match [`SimValue`]s (or anything that implements [`ToSimValue`]). -//! -//! `#[hdl(sim)] match` statements' bodies may have any type, unlike `#[hdl] match`. -//! -//! [`SimValue`]: crate::sim::value::SimValue -//! [`ToSimValue`]: crate::sim::value::ToSimValue -//! -//! ``` -//! # use fayalite::prelude::*; -//! #[hdl] -//! enum MyEnum { -//! A, -//! B(Bool), -//! C(T), -//! } -//! -//! #[hdl] -//! fn match_move(v: SimValue>) -> String { -//! #[hdl(sim)] -//! match v { -//! MyEnum::::A => String::from("got A"), -//! MyEnum::::B(mut b) => { -//! let _: SimValue = b; // b has this type -//! let text = format!("got B({b})"); -//! *b = true; // can modify b since mut was used -//! text -//! } -//! _ => String::from("something else"), -//! } -//! } -//! -//! #[hdl] -//! fn match_ref<'a, T: Type>(v: &'a SimValue>) -> u32 { -//! #[hdl(sim)] -//! match v { -//! MyEnum::::A => 1, -//! MyEnum::::B(b) => { -//! let _: &'a SimValue = b; // b has this type -//! println!("got B({b})"); -//! 5 -//! } -//! _ => 42, -//! } -//! } -//! -//! #[hdl] -//! fn match_mut<'a, T: Type>(v: &'a mut SimValue>) -> Option<&'a mut SimValue> { -//! #[hdl(sim)] -//! match v { -//! MyEnum::::A => None, -//! MyEnum::::B(b) => { -//! println!("got B({b})"); -//! **b = true; // you can modify v by modifying b which borrows from it -//! let _: &'a mut SimValue = b; // b has this type -//! None -//! } -//! MyEnum::::C(v) => Some(v), // you can return matched values -//! _ => None, // HDL enums can have invalid discriminants, so we need this extra match arm -//! } -//! } -//! -//! #[hdl] -//! fn match_to_sim_value<'a, T: Type>(v: impl ToSimValue>) { -//! #[hdl(sim)] -//! match v { -//! MyEnum::::A => println!("got A"), -//! MyEnum::::B(b) => { -//! let _: SimValue = b; // b has this type -//! println!("got B({b})"); -//! } -//! _ => println!("something else"), -//! } -//! } -//! ``` diff --git a/crates/fayalite/src/annotations.rs b/crates/fayalite/src/annotations.rs index 4ca84dd..70f0460 100644 --- a/crates/fayalite/src/annotations.rs +++ b/crates/fayalite/src/annotations.rs @@ -145,73 +145,52 @@ pub struct DocStringAnnotation { macro_rules! make_annotation_enum { ( - #[$non_exhaustive:ident] $(#[$meta:meta])* - $vis:vis enum $AnnotationEnum:ident { - $($Variant:ident($T:ty),)* + $vis:vis enum $Annotation:ident { + $($Variant:ident($T:ident),)* } ) => { - crate::annotations::make_annotation_enum!(@require_non_exhaustive $non_exhaustive); - - #[$non_exhaustive] $(#[$meta])* - #[derive(Clone, PartialEq, Eq, Hash)] - $vis enum $AnnotationEnum { + $vis enum $Annotation { $($Variant($T),)* } - impl std::fmt::Debug for $AnnotationEnum { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - $(Self::$Variant(v) => v.fmt(f),)* - } - } - } - - $(impl From<$T> for crate::annotations::Annotation { - fn from(v: $T) -> Self { - $AnnotationEnum::$Variant(v).into() - } - } - - impl crate::annotations::IntoAnnotations for $T { - type IntoAnnotations = [crate::annotations::Annotation; 1]; + $(impl IntoAnnotations for $T { + type IntoAnnotations = [$Annotation; 1]; fn into_annotations(self) -> Self::IntoAnnotations { - [self.into()] + [$Annotation::$Variant(self)] } } - impl crate::annotations::IntoAnnotations for &'_ $T { - type IntoAnnotations = [crate::annotations::Annotation; 1]; + impl IntoAnnotations for &'_ $T { + type IntoAnnotations = [$Annotation; 1]; fn into_annotations(self) -> Self::IntoAnnotations { - [crate::annotations::Annotation::from(self.clone())] + [$Annotation::$Variant(*self)] } } - impl crate::annotations::IntoAnnotations for &'_ mut $T { - type IntoAnnotations = [crate::annotations::Annotation; 1]; + impl IntoAnnotations for &'_ mut $T { + type IntoAnnotations = [$Annotation; 1]; fn into_annotations(self) -> Self::IntoAnnotations { - [crate::annotations::Annotation::from(self.clone())] + [$Annotation::$Variant(*self)] } } - impl crate::annotations::IntoAnnotations for Box<$T> { - type IntoAnnotations = [crate::annotations::Annotation; 1]; + impl IntoAnnotations for Box<$T> { + type IntoAnnotations = [$Annotation; 1]; fn into_annotations(self) -> Self::IntoAnnotations { - [crate::annotations::Annotation::from(*self)] + [$Annotation::$Variant(*self)] } })* }; - (@require_non_exhaustive non_exhaustive) => {}; } -pub(crate) use make_annotation_enum; - make_annotation_enum! { + #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[non_exhaustive] pub enum Annotation { DontTouch(DontTouchAnnotation), @@ -220,7 +199,6 @@ make_annotation_enum! { BlackBoxPath(BlackBoxPathAnnotation), DocString(DocStringAnnotation), CustomFirrtl(CustomFirrtlAnnotation), - Xilinx(crate::vendor::xilinx::XilinxAnnotation), } } diff --git a/crates/fayalite/src/array.rs b/crates/fayalite/src/array.rs index 4e2b223..569f2e2 100644 --- a/crates/fayalite/src/array.rs +++ b/crates/fayalite/src/array.rs @@ -3,13 +3,13 @@ use crate::{ expr::{ - CastToBits, Expr, HdlPartialEq, HdlPartialEqImpl, ReduceBits, ToExpr, ValueType, Valueless, - ops::{ArrayLiteral, ExprFromIterator, ExprIntoIterator}, + CastToBits, Expr, HdlPartialEq, ReduceBits, ToExpr, + ops::{ArrayLiteral, ExprFromIterator, ExprIntoIterator, ExprPartialEq}, }, int::{Bool, DYN_SIZE, DynSize, KnownSize, Size, SizeType}, intern::{Intern, Interned, LazyInterned}, module::transform::visit::{Fold, Folder, Visit, Visitor}, - sim::value::SimValue, + sim::value::{SimValue, SimValuePartialEq}, source_location::SourceLocation, ty::{ CanonicalType, MatchVariantWithoutScope, OpaqueSimValueSlice, OpaqueSimValueWriter, @@ -19,7 +19,7 @@ use crate::{ util::ConstUsize, }; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error}; -use std::{borrow::Cow, iter::FusedIterator, ops::Index}; +use std::{iter::FusedIterator, ops::Index}; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct ArrayType { @@ -221,7 +221,7 @@ impl Type for ArrayType { let value = AsMut::<[SimValue]>::as_mut(value); assert_eq!(self.len(), value.len()); for element_value in value { - assert_eq!(element_value.ty(), element_ty); + assert_eq!(SimValue::ty(element_value), element_ty); let (element_opaque, rest) = opaque.split_at(element_size); SimValue::opaque_mut(element_value).clone_from_slice(element_opaque); opaque = rest; @@ -238,7 +238,7 @@ impl Type for ArrayType { let value = AsRef::<[SimValue]>::as_ref(value); assert_eq!(self.len(), value.len()); for element_value in value { - assert_eq!(element_value.ty(), element_ty); + assert_eq!(SimValue::ty(element_value), element_ty); writer.fill_prefix_with(element_size, |writer| { writer.fill_cloned_from_slice(SimValue::opaque(element_value).as_slice()) }); @@ -326,30 +326,14 @@ impl Index for ArrayWithoutLen { } } -impl HdlPartialEqImpl> for ArrayType +impl ExprPartialEq> for ArrayType where - Lhs: HdlPartialEqImpl, + Lhs: ExprPartialEq, { - fn cmp_value_eq( - lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - rhs: ArrayType, - rhs_value: Cow<'_, as Type>::SimValue>, - ) -> bool { - assert_eq!(lhs.len(), rhs.len()); - let lhs = lhs.element(); - let rhs = rhs.element(); - let lhs_value: &[_] = (*lhs_value).as_ref(); - let rhs_value: &[_] = (*rhs_value).as_ref(); - for (lhs_value, rhs_value) in lhs_value.iter().zip(rhs_value) { - if !Lhs::cmp_value_eq(lhs, Cow::Borrowed(lhs_value), rhs, Cow::Borrowed(rhs_value)) { - return false; - } - } - true - } - fn cmp_expr_eq(lhs: Expr, rhs: Expr>) -> Expr { - assert_eq!(lhs.ty().len(), rhs.ty().len()); + 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)) @@ -357,8 +341,11 @@ where .cast_to_bits() .all_one_bits() } - fn cmp_expr_ne(lhs: Expr, rhs: Expr>) -> Expr { - assert_eq!(lhs.ty().len(), rhs.ty().len()); + + 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)) @@ -366,19 +353,17 @@ where .cast_to_bits() .any_one_bits() } - fn cmp_valueless_eq( - lhs: Valueless, - rhs: Valueless>, - ) -> Valueless { - assert_eq!(lhs.ty().len(), rhs.ty().len()); - Valueless::new(Bool) - } - fn cmp_valueless_ne( - lhs: Valueless, - rhs: Valueless>, - ) -> Valueless { - assert_eq!(lhs.ty().len(), rhs.ty().len()); - Valueless::new(Bool) +} + +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)) } } @@ -389,7 +374,7 @@ impl ExprIntoIterator for ArrayType { fn expr_into_iter(e: Expr) -> Self::ExprIntoIter { ExprArrayIter { base: e, - indexes: 0..e.ty().len(), + indexes: 0..Expr::ty(e).len(), } } } diff --git a/crates/fayalite/src/build.rs b/crates/fayalite/src/build.rs deleted file mode 100644 index a9e9635..0000000 --- a/crates/fayalite/src/build.rs +++ /dev/null @@ -1,2803 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - build::graph::JobGraph, - bundle::{Bundle, BundleType}, - intern::{Intern, InternSlice, Interned}, - module::Module, - platform::{DynPlatform, Platform}, - util::{job_server::AcquiredJob, os_str_strip_prefix}, - vendor, -}; -use clap::ArgAction; -use serde::{ - Deserialize, Deserializer, Serialize, Serializer, - de::{DeserializeOwned, Error as _}, - ser::Error as _, -}; -use std::{ - any::{Any, TypeId}, - borrow::Cow, - cmp::Ordering, - ffi::{OsStr, OsString}, - fmt, - hash::{Hash, Hasher}, - io::Write, - marker::PhantomData, - path::{Path, PathBuf}, - sync::{Arc, OnceLock}, -}; -use tempfile::TempDir; - -pub mod external; -pub mod firrtl; -pub mod formal; -pub mod graph; -pub mod registry; -pub mod verilog; - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - [DynJobKind::new(BaseJobKind)] - .into_iter() - .chain(firrtl::built_in_job_kinds()) - .chain(formal::built_in_job_kinds()) - .chain(vendor::built_in_job_kinds()) - .chain(verilog::built_in_job_kinds()) -} - -#[derive(Clone, Hash, PartialEq, Eq, Debug)] -#[non_exhaustive] -pub enum JobItem { - Path { - path: Interned, - }, - DynamicPaths { - paths: Vec>, - source_job_name: Interned, - }, -} - -impl JobItem { - pub fn name(&self) -> JobItemName { - match self { - &JobItem::Path { path } => JobItemName::Path { path }, - &JobItem::DynamicPaths { - paths: _, - source_job_name, - } => JobItemName::DynamicPaths { source_job_name }, - } - } -} - -#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)] -#[non_exhaustive] -pub enum JobItemName { - Path { path: Interned }, - DynamicPaths { source_job_name: Interned }, -} - -impl JobItemName { - fn as_ref(&self) -> JobItemNameRef<'_> { - match self { - JobItemName::Path { path } => JobItemNameRef::Path { path }, - JobItemName::DynamicPaths { source_job_name } => { - JobItemNameRef::DynamicPaths { source_job_name } - } - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -enum JobItemNameRef<'a> { - Path { path: &'a Path }, - DynamicPaths { source_job_name: &'a str }, -} - -/// ordered by string contents, not by `Interned` -impl PartialOrd for JobItemName { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -/// ordered by string contents, not by `Interned` -impl Ord for JobItemName { - fn cmp(&self, other: &Self) -> Ordering { - if self == other { - Ordering::Equal - } else { - self.as_ref().cmp(&other.as_ref()) - } - } -} - -pub trait WriteArgs: - for<'a> Extend<&'a str> - + for<'a> Extend<&'a OsStr> - + for<'a> Extend<&'a Path> - + for<'a> Extend> - + for<'a> Extend> - + for<'a> Extend> - + Extend - + Extend - + Extend - + Extend> - + Extend> - + Extend> -{ - fn write_display_args(&mut self, args: impl IntoIterator) { - self.extend(args.into_iter().map(|v| v.to_string())); - } - fn write_owned_args(&mut self, args: impl IntoIterator>) { - self.extend(args.into_iter().map(Into::::into)) - } - fn write_args<'a>(&mut self, args: impl IntoIterator>); - fn write_interned_args(&mut self, args: impl IntoIterator>>) { - self.extend(args.into_iter().map(Into::>::into)) - } - fn write_display_arg(&mut self, arg: impl fmt::Display) { - self.write_display_args([arg]); - } - fn write_owned_arg(&mut self, arg: impl Into) { - self.extend([arg.into()]); - } - fn write_arg(&mut self, arg: impl AsRef) { - self.extend([arg.as_ref()]); - } - /// writes `--{name}={value}` - fn write_long_option_eq(&mut self, name: impl AsRef, value: impl AsRef) { - let name = name.as_ref(); - let value = value.as_ref(); - let mut option = - OsString::with_capacity(name.len().saturating_add(value.len()).saturating_add(3)); - option.push("--"); - option.push(name); - option.push("="); - option.push(value); - self.write_owned_arg(option); - } - fn write_interned_arg(&mut self, arg: impl Into>) { - self.extend([arg.into()]); - } - /// finds the first option that is `--{option_name}={value}` and returns `value` - fn get_long_option_eq(&self, option_name: impl AsRef) -> Option<&OsStr>; -} - -pub trait ArgsWriterArg: - AsRef - + From> - + for<'a> From> - + for<'a> From<&'a OsStr> - + From -{ -} - -impl ArgsWriterArg for Interned {} - -impl ArgsWriterArg for OsString {} - -pub struct ArgsWriter(pub Vec); - -impl Default for ArgsWriter { - fn default() -> Self { - Self(Default::default()) - } -} - -impl ArgsWriter { - fn get_long_option_eq_helper(&self, option_name: &str) -> Option<&OsStr> { - self.0.iter().find_map(|arg| { - os_str_strip_prefix(arg.as_ref(), "--") - .and_then(|arg| os_str_strip_prefix(arg, option_name)) - .and_then(|arg| os_str_strip_prefix(arg, "=")) - }) - } -} - -impl<'a, A: ArgsWriterArg> Extend<&'a str> for ArgsWriter { - fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().map(AsRef::::as_ref)) - } -} - -impl<'a, A: ArgsWriterArg> Extend<&'a OsStr> for ArgsWriter { - fn extend>(&mut self, iter: T) { - self.0.extend(iter.into_iter().map(Into::into)) - } -} - -impl<'a, A: ArgsWriterArg> Extend<&'a Path> for ArgsWriter { - fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().map(AsRef::::as_ref)) - } -} - -impl Extend for ArgsWriter { - fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().map(OsString::from)) - } -} - -impl Extend for ArgsWriter { - fn extend>(&mut self, iter: T) { - self.0.extend(iter.into_iter().map(Into::into)) - } -} - -impl Extend for ArgsWriter { - fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().map(OsString::from)) - } -} - -impl Extend> for ArgsWriter { - fn extend>>(&mut self, iter: T) { - self.extend(iter.into_iter().map(Interned::::from)) - } -} - -impl Extend> for ArgsWriter { - fn extend>>(&mut self, iter: T) { - self.0.extend(iter.into_iter().map(Into::into)) - } -} - -impl Extend> for ArgsWriter { - fn extend>>(&mut self, iter: T) { - self.extend(iter.into_iter().map(Interned::::from)) - } -} - -impl<'a, A: ArgsWriterArg> Extend> for ArgsWriter { - fn extend>>(&mut self, iter: T) { - self.0.extend(iter.into_iter().map(|v| { - match v { - Cow::Borrowed(v) => Cow::::Borrowed(v.as_ref()), - Cow::Owned(v) => Cow::Owned(v.into()), - } - .into() - })) - } -} - -impl<'a, A: ArgsWriterArg> Extend> for ArgsWriter { - fn extend>>(&mut self, iter: T) { - self.0.extend(iter.into_iter().map(Into::into)) - } -} - -impl<'a, A: ArgsWriterArg> Extend> for ArgsWriter { - fn extend>>(&mut self, iter: T) { - self.0.extend(iter.into_iter().map(|v| { - match v { - Cow::Borrowed(v) => Cow::::Borrowed(v.as_ref()), - Cow::Owned(v) => Cow::Owned(v.into()), - } - .into() - })) - } -} - -impl WriteArgs for ArgsWriter { - fn write_args<'a>(&mut self, args: impl IntoIterator>) { - self.0.extend(args.into_iter().map(|v| v.as_ref().into())) - } - fn get_long_option_eq(&self, option_name: impl AsRef) -> Option<&OsStr> { - self.get_long_option_eq_helper(option_name.as_ref()) - } -} - -pub trait ToArgs: clap::Args + 'static + Send + Sync + Hash + Eq + fmt::Debug + Clone { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)); - fn to_interned_args(&self) -> Interned<[Interned]> { - Intern::intern_owned(self.to_interned_args_vec()) - } - fn to_interned_args_vec(&self) -> Vec> { - let mut retval = ArgsWriter::default(); - self.to_args(&mut retval); - retval.0 - } - fn to_os_string_args(&self) -> Vec { - let mut retval = ArgsWriter::default(); - self.to_args(&mut retval); - retval.0 - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct JobKindAndArgs { - pub kind: K, - pub args: K::Args, -} - -impl JobKindAndArgs { - pub fn args_to_jobs( - self, - dependencies: ::KindsAndArgs, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - K::args_to_jobs( - JobArgsAndDependencies { - args: self, - dependencies, - }, - params, - global_params, - ) - } -} - -impl> Copy for JobKindAndArgs {} - -impl From> for DynJobArgs { - fn from(value: JobKindAndArgs) -> Self { - let JobKindAndArgs { kind, args } = value; - DynJobArgs::new(kind, args) - } -} - -impl TryFrom for JobKindAndArgs { - type Error = DynJobArgs; - fn try_from(value: DynJobArgs) -> Result { - value.downcast() - } -} - -#[derive(Debug, PartialEq, Eq, Hash)] -pub struct JobAndKind { - pub kind: K, - pub job: K::Job, -} - -impl> Clone for JobAndKind { - fn clone(&self) -> Self { - Self { - kind: self.kind.clone(), - job: self.job.clone(), - } - } -} - -impl> Copy for JobAndKind {} - -impl From> for DynJob { - fn from(value: JobAndKind) -> Self { - let JobAndKind { kind, job } = value; - DynJob::new(kind, job) - } -} - -impl> TryFrom for JobAndKind { - type Error = DynJob; - fn try_from(value: DynJob) -> Result { - value.downcast() - } -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct JobKindAndDependencies { - pub kind: K, - pub dependencies: K::Dependencies, -} - -impl Default for JobKindAndDependencies { - fn default() -> Self { - Self::new(K::default()) - } -} - -impl JobKindAndDependencies { - pub fn new(kind: K) -> Self { - Self { - kind, - dependencies: kind.dependencies(), - } - } -} - -#[derive(Debug, PartialEq, Eq, Hash)] -pub struct JobAndDependencies { - pub job: JobAndKind, - pub dependencies: ::JobsAndKinds, -} - -impl JobAndDependencies { - pub fn get_job(&self) -> &J - where - Self: GetJob, - { - GetJob::get_job(self) - } - pub fn base_job(&self) -> &BaseJob { - self.job.kind.base_job(&self.job.job, &self.dependencies) - } -} - -impl Clone for JobAndDependencies -where - K::Job: Clone, - ::JobsAndKinds: Clone, -{ - fn clone(&self) -> Self { - Self { - job: self.job.clone(), - dependencies: self.dependencies.clone(), - } - } -} - -impl Copy for JobAndDependencies -where - K::Job: Copy, - ::JobsAndKinds: Copy, -{ -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct JobArgsAndDependencies { - pub args: JobKindAndArgs, - pub dependencies: ::KindsAndArgs, -} - -impl Copy for JobArgsAndDependencies -where - K::Args: Copy, - ::KindsAndArgs: Copy, -{ -} - -impl JobArgsAndDependencies { - pub fn args_to_jobs( - self, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - K::args_to_jobs(self, params, global_params) - } - pub fn base_job_args(&self) -> &BaseJobArgs { - self.args - .kind - .base_job_args(&self.args.args, &self.dependencies) - } -} - -impl>, D: JobKind> JobArgsAndDependencies { - pub fn args_to_jobs_simple( - self, - params: &JobParams, - global_params: &GlobalParams, - f: F, - ) -> eyre::Result> - where - F: FnOnce(K, K::Args, &mut JobAndDependencies) -> eyre::Result, - { - let Self { - args: JobKindAndArgs { kind, args }, - dependencies, - } = self; - let mut dependencies = dependencies.args_to_jobs(params, global_params)?; - let job = f(kind, args, &mut dependencies)?; - Ok(JobAndDependencies { - job: JobAndKind { kind, job }, - dependencies, - }) - } -} - -impl>, D: JobKind> - JobArgsAndDependencies> -{ - pub fn args_to_jobs_external_simple( - self, - params: &JobParams, - global_params: &GlobalParams, - f: F, - ) -> eyre::Result<( - C::AdditionalJobData, - ::JobsAndKinds, - )> - where - F: FnOnce( - external::ExternalCommandArgs, - &mut JobAndDependencies, - ) -> eyre::Result, - { - let Self { - args: JobKindAndArgs { kind: _, args }, - dependencies, - } = self; - let mut dependencies = dependencies.args_to_jobs(params, global_params)?; - let additional_job_data = f(args, &mut dependencies)?; - Ok((additional_job_data, dependencies)) - } -} - -pub trait JobDependencies: 'static + Send + Sync + Hash + Eq + fmt::Debug + Copy { - type KindsAndArgs: 'static + Send + Sync + Hash + Eq + fmt::Debug + Clone; - type JobsAndKinds: 'static + Send + Sync + Hash + Eq + fmt::Debug; - fn kinds_dyn_extend>(self, dyn_kinds: &mut E); - fn kinds_dyn(self) -> Vec { - let mut retval = Vec::new(); - self.kinds_dyn_extend(&mut retval); - retval - } - fn into_dyn_jobs_extend>(jobs: Self::JobsAndKinds, dyn_jobs: &mut E); - fn into_dyn_jobs(jobs: Self::JobsAndKinds) -> Vec { - let mut retval = Vec::new(); - Self::into_dyn_jobs_extend(jobs, &mut retval); - retval - } - #[track_caller] - fn from_dyn_args_prefix>( - args: &mut I, - ) -> Self::KindsAndArgs; - #[track_caller] - fn from_dyn_args>(args: I) -> Self::KindsAndArgs { - let mut iter = args.into_iter(); - let retval = Self::from_dyn_args_prefix(&mut iter); - if iter.next().is_some() { - panic!("wrong number of dependencies"); - } - retval - } -} - -pub trait JobDependenciesHasBase: JobDependencies { - fn base_job_args(args: &Self::KindsAndArgs) -> &BaseJobArgs; - fn base_job(jobs: &Self::JobsAndKinds) -> &BaseJob; - #[track_caller] - fn base_job_args_dyn(dependencies_args: &[DynJobArgs]) -> &BaseJobArgs; - #[track_caller] - fn base_job_dyn(dependencies: &[DynJob]) -> &BaseJob; -} - -impl JobDependencies for JobKindAndDependencies { - type KindsAndArgs = JobArgsAndDependencies; - type JobsAndKinds = JobAndDependencies; - - fn kinds_dyn_extend>(self, dyn_kinds: &mut E) { - let Self { kind, dependencies } = self; - dependencies.kinds_dyn_extend(dyn_kinds); - dyn_kinds.extend([DynJobKind::new(kind)]); - } - - fn into_dyn_jobs_extend>( - jobs: Self::JobsAndKinds, - dyn_jobs: &mut E, - ) { - let JobAndDependencies { job, dependencies } = jobs; - K::Dependencies::into_dyn_jobs_extend(dependencies, dyn_jobs); - dyn_jobs.extend([job.into()]); - } - - #[track_caller] - fn from_dyn_args_prefix>( - args: &mut I, - ) -> Self::KindsAndArgs { - let dependencies = K::Dependencies::from_dyn_args_prefix(args); - let Some(args) = args.next() else { - panic!("wrong number of dependencies"); - }; - match args.downcast() { - Ok(args) => JobArgsAndDependencies { args, dependencies }, - Err(args) => { - panic!( - "wrong type of dependency, expected {} got:\n{args:?}", - std::any::type_name::() - ) - } - } - } -} - -impl JobDependenciesHasBase for JobKindAndDependencies { - fn base_job_args(args: &Self::KindsAndArgs) -> &BaseJobArgs { - args.base_job_args() - } - - fn base_job(jobs: &Self::JobsAndKinds) -> &BaseJob { - jobs.base_job() - } - - #[track_caller] - fn base_job_args_dyn(dependencies_args: &[DynJobArgs]) -> &BaseJobArgs { - let [dependencies_args @ .., args] = dependencies_args else { - panic!("wrong number of dependencies"); - }; - let Some((kind, args)) = args.downcast_ref::() else { - panic!( - "wrong type of dependency, expected {} got:\n{args:?}", - std::any::type_name::() - ) - }; - kind.base_job_args_dyn(args, dependencies_args) - } - - #[track_caller] - fn base_job_dyn(dependencies: &[DynJob]) -> &BaseJob { - let [dependencies @ .., job] = dependencies else { - panic!("wrong number of dependencies"); - }; - let Some((kind, job)) = job.downcast_ref::() else { - panic!( - "wrong type of dependency, expected {} got:\n{job:?}", - std::any::type_name::() - ) - }; - kind.base_job_dyn(job, dependencies) - } -} - -macro_rules! impl_job_dependencies { - (@impl $(($v:ident: $T:ident),)*) => { - impl<$($T: JobDependencies),*> JobDependencies for ($($T,)*) { - type KindsAndArgs = ($($T::KindsAndArgs,)*); - type JobsAndKinds = ($($T::JobsAndKinds,)*); - - fn kinds_dyn_extend>(self, dyn_kinds: &mut E) { - #![allow(unused_variables)] - let ($($v,)*) = self; - $($T::kinds_dyn_extend($v, dyn_kinds);)* - } - - fn into_dyn_jobs_extend>( - jobs: Self::JobsAndKinds, - dyn_jobs: &mut E, - ) { - #![allow(unused_variables)] - let ($($v,)*) = jobs; - $($T::into_dyn_jobs_extend($v, dyn_jobs);)* - } - - #[track_caller] - fn from_dyn_args_prefix>( - args: &mut I, - ) -> Self::KindsAndArgs { - #![allow(unused_variables)] - $(let $v = $T::from_dyn_args_prefix(args);)* - ($($v,)*) - } - } - }; - ($($first:tt, $($rest:tt,)*)?) => { - impl_job_dependencies!(@impl $($first, $($rest,)*)?); - $(impl_job_dependencies!($($rest,)*);)? - }; -} - -impl_job_dependencies! { - (v0: T0), - (v1: T1), - (v2: T2), - (v3: T3), - (v4: T4), - (v5: T5), - (v6: T6), - (v7: T7), - (v8: T8), - (v9: T9), - (v10: T10), - (v11: T11), -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct JobParams { - main_module: Module, -} - -impl AsRef for JobParams { - fn as_ref(&self) -> &Self { - self - } -} - -impl JobParams { - pub fn new_canonical(main_module: Module) -> Self { - Self { main_module } - } - pub fn new(main_module: impl AsRef>) -> Self { - Self::new_canonical(main_module.as_ref().canonical()) - } - pub fn main_module(&self) -> &Module { - &self.main_module - } -} - -#[derive(Clone, Debug)] -pub struct GlobalParams { - top_level_cmd: Option, - application_name: Interned, -} - -impl AsRef for GlobalParams { - fn as_ref(&self) -> &Self { - self - } -} - -impl GlobalParams { - pub fn new(top_level_cmd: Option, application_name: impl AsRef) -> Self { - Self { - top_level_cmd, - application_name: application_name.as_ref().intern(), - } - } - pub fn top_level_cmd(&self) -> Option<&clap::Command> { - self.top_level_cmd.as_ref() - } - pub fn into_top_level_cmd(self) -> Option { - self.top_level_cmd - } - pub fn extract_clap_error(&self, e: eyre::Report) -> eyre::Result { - let e = e.downcast::()?; - Ok(match &self.top_level_cmd { - Some(cmd) => e.with_cmd(cmd), - None => e, - }) - } - pub fn exit_if_clap_error(&self, e: eyre::Report) -> eyre::Report { - match self.extract_clap_error(e) { - Ok(e) => e.exit(), - Err(e) => e, - } - } - pub fn clap_error( - &self, - kind: clap::error::ErrorKind, - message: impl fmt::Display, - ) -> clap::Error { - match self.top_level_cmd.clone() { - Some(top_level_cmd) => top_level_cmd.clone().error(kind, message), - None => clap::Error::raw(kind, message), - } - } - pub fn application_name(&self) -> Interned { - self.application_name - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct CommandParams { - pub command_line: Interned<[Interned]>, - pub current_dir: Option>, -} - -impl CommandParams { - fn to_unix_shell_line( - self, - output: &mut String, - mut escape_arg: impl FnMut(&OsStr, &mut String) -> Result<(), E>, - ) -> Result<(), E> { - let Self { - command_line, - current_dir, - } = self; - let mut end = None; - let mut separator = if let Some(current_dir) = current_dir { - output.push_str("(cd "); - end = Some(")"); - if !current_dir - .as_os_str() - .as_encoded_bytes() - .first() - .is_some_and(|ch| ch.is_ascii_alphanumeric() || matches!(ch, b'/' | b'\\' | b'.')) - { - output.push_str("-- "); - } - escape_arg(current_dir.as_ref(), output)?; - "; exec -- " - } else { - "" - }; - for arg in command_line { - output.push_str(separator); - separator = " "; - escape_arg(&arg, output)?; - } - if let Some(end) = end { - output.push_str(end); - } - Ok(()) - } -} - -pub trait JobKindHelper: 'static + Send + Sync + Hash + Eq + fmt::Debug + Copy { - fn base_job_args<'a>( - self, - args: &'a ::Args, - dependencies: &'a <::Dependencies as JobDependencies>::KindsAndArgs, - ) -> &'a BaseJobArgs - where - Self: JobKind; - fn base_job<'a>( - self, - job: &'a ::Job, - dependencies: &'a <::Dependencies as JobDependencies>::JobsAndKinds, - ) -> &'a BaseJob - where - Self: JobKind; - #[track_caller] - fn base_job_args_dyn<'a>( - self, - args: &'a ::Args, - dependencies_args: &'a [DynJobArgs], - ) -> &'a BaseJobArgs - where - Self: JobKind; - #[track_caller] - fn base_job_dyn<'a>( - self, - job: &'a ::Job, - dependencies: &'a [DynJob], - ) -> &'a BaseJob - where - Self: JobKind; -} - -impl> JobKindHelper for K { - fn base_job_args<'a>( - self, - _args: &'a ::Args, - dependencies: &'a <::Dependencies as JobDependencies>::KindsAndArgs, - ) -> &'a BaseJobArgs { - K::Dependencies::base_job_args(dependencies) - } - fn base_job<'a>( - self, - _job: &'a ::Job, - dependencies: &'a <::Dependencies as JobDependencies>::JobsAndKinds, - ) -> &'a BaseJob { - K::Dependencies::base_job(dependencies) - } - #[track_caller] - fn base_job_args_dyn<'a>( - self, - _args: &'a ::Args, - dependencies_args: &'a [DynJobArgs], - ) -> &'a BaseJobArgs { - K::Dependencies::base_job_args_dyn(dependencies_args) - } - #[track_caller] - fn base_job_dyn<'a>( - self, - _job: &'a ::Job, - dependencies: &'a [DynJob], - ) -> &'a BaseJob { - K::Dependencies::base_job_dyn(dependencies) - } -} - -pub trait JobKind: JobKindHelper { - type Args: ToArgs; - type Job: 'static + Send + Sync + Hash + Eq + fmt::Debug + Serialize + DeserializeOwned; - type Dependencies: JobDependencies; - fn dependencies(self) -> Self::Dependencies; - fn args_to_jobs( - args: JobArgsAndDependencies, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result>; - fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]>; - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]>; - fn name(self) -> Interned; - fn external_command_params(self, job: &Self::Job) -> Option; - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - params: &JobParams, - global_params: &GlobalParams, - acquired_job: &mut AcquiredJob, - ) -> eyre::Result>; - fn subcommand_hidden(self) -> bool { - false - } - fn external_program(self) -> Option> { - None - } -} - -trait DynJobKindTrait: 'static + Send + Sync + fmt::Debug { - fn as_any(&self) -> &dyn Any; - fn as_arc_any(self: Arc) -> Arc; - fn eq_dyn(&self, other: &dyn DynJobKindTrait) -> bool; - fn hash_dyn(&self, state: &mut dyn Hasher); - fn dependencies_kinds_dyn(&self) -> Vec; - fn args_group_id_dyn(&self) -> Option; - fn augment_args_dyn(&self, cmd: clap::Command) -> clap::Command; - fn augment_args_for_update_dyn(&self, cmd: clap::Command) -> clap::Command; - fn from_arg_matches_dyn( - &self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result; - fn name_dyn(&self) -> Interned; - fn subcommand_hidden_dyn(&self) -> bool; - fn deserialize_job_from_json_str(self: Arc, json: &str) -> serde_json::Result; - fn deserialize_job_from_json_value( - self: Arc, - json: &serde_json::Value, - ) -> serde_json::Result; -} - -impl DynJobKindTrait for K { - fn as_any(&self) -> &dyn Any { - self - } - - fn as_arc_any(self: Arc) -> Arc { - self - } - - fn eq_dyn(&self, other: &dyn DynJobKindTrait) -> bool { - other - .as_any() - .downcast_ref::() - .is_some_and(|other| self == other) - } - - fn hash_dyn(&self, mut state: &mut dyn Hasher) { - self.hash(&mut state); - } - - fn dependencies_kinds_dyn(&self) -> Vec { - self.dependencies().kinds_dyn() - } - - fn args_group_id_dyn(&self) -> Option { - ::group_id() - } - - fn augment_args_dyn(&self, cmd: clap::Command) -> clap::Command { - ::augment_args(cmd) - } - - fn augment_args_for_update_dyn(&self, cmd: clap::Command) -> clap::Command { - ::augment_args_for_update(cmd) - } - - fn from_arg_matches_dyn( - &self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result { - Ok(DynJobArgs::new( - *self, - ::from_arg_matches_mut(matches)?, - )) - } - - fn name_dyn(&self) -> Interned { - self.name() - } - - fn subcommand_hidden_dyn(&self) -> bool { - self.subcommand_hidden() - } - - fn deserialize_job_from_json_str(self: Arc, json: &str) -> serde_json::Result { - Ok(DynJob::from_arc(self, serde_json::from_str(json)?)) - } - - fn deserialize_job_from_json_value( - self: Arc, - json: &serde_json::Value, - ) -> serde_json::Result { - Ok(DynJob::from_arc(self, Deserialize::deserialize(json)?)) - } -} - -#[derive(Clone)] -pub struct DynJobKind(Arc); - -impl DynJobKind { - pub fn from_arc(job_kind: Arc) -> Self { - Self(job_kind) - } - pub fn new(job_kind: K) -> Self { - Self(Arc::new(job_kind)) - } - pub fn type_id(&self) -> TypeId { - DynJobKindTrait::as_any(&*self.0).type_id() - } - pub fn downcast(&self) -> Option { - DynJobKindTrait::as_any(&*self.0).downcast_ref().copied() - } - pub fn downcast_arc(self) -> Result, Self> { - if self.downcast::().is_some() { - Ok(Arc::downcast::(self.0.as_arc_any()) - .ok() - .expect("already checked type")) - } else { - Err(self) - } - } - pub fn dependencies_kinds(&self) -> Vec { - DynJobKindTrait::dependencies_kinds_dyn(&*self.0) - } - pub fn args_group_id(&self) -> Option { - DynJobKindTrait::args_group_id_dyn(&*self.0) - } - pub fn augment_args(&self, cmd: clap::Command) -> clap::Command { - DynJobKindTrait::augment_args_dyn(&*self.0, cmd) - } - pub fn augment_args_for_update(&self, cmd: clap::Command) -> clap::Command { - DynJobKindTrait::augment_args_for_update_dyn(&*self.0, cmd) - } - pub fn from_arg_matches( - &self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result { - DynJobKindTrait::from_arg_matches_dyn(&*self.0, matches) - } - pub fn name(&self) -> Interned { - DynJobKindTrait::name_dyn(&*self.0) - } - pub fn subcommand_hidden(&self) -> bool { - DynJobKindTrait::subcommand_hidden_dyn(&*self.0) - } - pub fn deserialize_job_from_json_str(self, json: &str) -> serde_json::Result { - DynJobKindTrait::deserialize_job_from_json_str(self.0, json) - } - pub fn deserialize_job_from_json_value( - self, - json: &serde_json::Value, - ) -> serde_json::Result { - DynJobKindTrait::deserialize_job_from_json_value(self.0, json) - } - fn make_subcommand_without_args(&self) -> clap::Command { - clap::Command::new(Interned::into_inner(self.name())).hide(self.subcommand_hidden()) - } - pub fn make_subcommand(&self) -> clap::Command { - let mut subcommand = self.make_subcommand_without_args(); - for dependency in self.dependencies_kinds() { - subcommand = dependency.augment_args(subcommand); - } - self.augment_args(subcommand) - } - pub fn make_subcommand_for_update(&self) -> clap::Command { - let mut subcommand = self.make_subcommand_without_args(); - for dependency in self.dependencies_kinds() { - subcommand = dependency.augment_args_for_update(subcommand); - } - self.augment_args_for_update(subcommand) - } -} - -impl Hash for DynJobKind { - fn hash(&self, state: &mut H) { - self.type_id().hash(state); - DynJobKindTrait::hash_dyn(&*self.0, state); - } -} - -impl PartialEq for DynJobKind { - fn eq(&self, other: &Self) -> bool { - DynJobKindTrait::eq_dyn(&*self.0, &*other.0) - } -} - -impl Eq for DynJobKind {} - -impl fmt::Debug for DynJobKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl Serialize for DynJobKind { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.name().serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for DynJobKind { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let name = Cow::::deserialize(deserializer)?; - match Self::registry().get_by_name(&name) { - Some(retval) => Ok(retval.clone()), - None => Err(D::Error::custom(format_args!( - "unknown job kind: name not found in registry: {name:?}" - ))), - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -pub struct DynJobKindValueParser; - -#[derive(Clone, PartialEq, Eq, Hash)] -struct DynJobKindValueEnum { - name: Interned, - job_kind: DynJobKind, -} - -impl clap::ValueEnum for DynJobKindValueEnum { - fn value_variants<'a>() -> &'a [Self] { - Interned::into_inner( - registry::JobKindRegistrySnapshot::get() - .iter_with_names() - .map(|(name, job_kind)| Self { - name, - job_kind: job_kind.clone(), - }) - .collect(), - ) - } - - fn to_possible_value(&self) -> Option { - Some(clap::builder::PossibleValue::new(Interned::into_inner( - self.name, - ))) - } -} - -impl clap::builder::TypedValueParser for DynJobKindValueParser { - type Value = DynJobKind; - - fn parse_ref( - &self, - cmd: &clap::Command, - arg: Option<&clap::Arg>, - value: &std::ffi::OsStr, - ) -> clap::error::Result { - clap::builder::EnumValueParser::::new() - .parse_ref(cmd, arg, value) - .map(|v| v.job_kind) - } - - fn possible_values( - &self, - ) -> Option + '_>> { - static ENUM_VALUE_PARSER: OnceLock> = - OnceLock::new(); - ENUM_VALUE_PARSER - .get_or_init(clap::builder::EnumValueParser::::new) - .possible_values() - } -} - -impl clap::builder::ValueParserFactory for DynJobKind { - type Parser = DynJobKindValueParser; - - fn value_parser() -> Self::Parser { - DynJobKindValueParser::default() - } -} - -trait DynExtendInternedStr { - fn extend_from_slice(&mut self, items: &[Interned]); -} - -impl Extend> for dyn DynExtendInternedStr + '_ { - fn extend>>(&mut self, iter: T) { - let mut buf = [Interned::default(); 64]; - let mut buf_len = 0; - iter.into_iter().for_each(|item| { - buf[buf_len] = item; - buf_len += 1; - if buf_len == buf.len() { - ::extend_from_slice(self, &buf); - buf_len = 0; - } - }); - if buf_len > 0 { - ::extend_from_slice( - self, - &buf[..buf_len], - ); - } - } -} - -impl>> DynExtendInternedStr for T { - fn extend_from_slice(&mut self, items: &[Interned]) { - self.extend(items.iter().copied()); - } -} - -#[derive(PartialEq, Eq, Hash, Clone)] -struct DynJobArgsInner(JobKindAndArgs); - -impl fmt::Debug for DynJobArgsInner { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self(JobKindAndArgs { kind, args }) = self; - f.debug_struct("DynJobArgs") - .field("kind", kind) - .field("args", args) - .finish() - } -} - -trait DynJobArgsTrait: 'static + Send + Sync + fmt::Debug { - fn as_any(&self) -> &dyn Any; - fn as_arc_any(self: Arc) -> Arc; - fn kind_type_id(&self) -> TypeId; - fn eq_dyn(&self, other: &dyn DynJobArgsTrait) -> bool; - fn hash_dyn(&self, state: &mut dyn Hasher); - fn kind(&self) -> DynJobKind; - fn to_args_extend_vec(&self, args: Vec>) -> Vec>; - fn clone_into_arc(&self) -> Arc; - fn update_from_arg_matches( - &mut self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result<()>; - #[track_caller] - fn args_to_jobs( - self: Arc, - dependencies_args: Vec, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<(DynJob, Vec)>; - #[track_caller] - fn base_job_args_dyn<'a>(&'a self, dependencies_args: &'a [DynJobArgs]) -> &'a BaseJobArgs; -} - -impl DynJobArgsTrait for DynJobArgsInner { - fn as_any(&self) -> &dyn Any { - self - } - - fn as_arc_any(self: Arc) -> Arc { - self - } - - fn kind_type_id(&self) -> TypeId { - TypeId::of::() - } - - fn eq_dyn(&self, other: &dyn DynJobArgsTrait) -> bool { - other - .as_any() - .downcast_ref::() - .is_some_and(|other| self == other) - } - - fn hash_dyn(&self, mut state: &mut dyn Hasher) { - self.hash(&mut state); - } - - fn kind(&self) -> DynJobKind { - DynJobKind::new(self.0.kind) - } - - fn to_args_extend_vec(&self, args: Vec>) -> Vec> { - let mut writer = ArgsWriter(args); - self.0.args.to_args(&mut writer); - writer.0 - } - - fn clone_into_arc(&self) -> Arc { - Arc::new(self.clone()) - } - - fn update_from_arg_matches( - &mut self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result<()> { - clap::FromArgMatches::update_from_arg_matches_mut(&mut self.0.args, matches) - } - - #[track_caller] - fn args_to_jobs( - self: Arc, - dependencies_args: Vec, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<(DynJob, Vec)> { - let JobAndDependencies { job, dependencies } = JobArgsAndDependencies { - args: Arc::unwrap_or_clone(self).0, - dependencies: K::Dependencies::from_dyn_args(dependencies_args), - } - .args_to_jobs(params, global_params)?; - Ok((job.into(), K::Dependencies::into_dyn_jobs(dependencies))) - } - - #[track_caller] - fn base_job_args_dyn<'a>(&'a self, dependencies_args: &'a [DynJobArgs]) -> &'a BaseJobArgs { - self.0 - .kind - .base_job_args_dyn(&self.0.args, dependencies_args) - } -} - -#[derive(Clone)] -pub struct DynJobArgs(Arc); - -impl DynJobArgs { - pub fn new(kind: K, args: K::Args) -> Self { - Self(Arc::new(DynJobArgsInner(JobKindAndArgs { kind, args }))) - } - pub fn kind_type_id(&self) -> TypeId { - DynJobArgsTrait::kind_type_id(&*self.0) - } - pub fn downcast_ref(&self) -> Option<(&K, &K::Args)> { - let DynJobArgsInner::(JobKindAndArgs { kind, args }) = - DynJobArgsTrait::as_any(&*self.0).downcast_ref()?; - Some((kind, args)) - } - pub fn downcast(self) -> Result, Self> { - if self.downcast_ref::().is_some() { - let this = Arc::downcast::>(self.0.as_arc_any()) - .ok() - .expect("already checked type"); - Ok(Arc::unwrap_or_clone(this).0) - } else { - Err(self) - } - } - pub fn kind(&self) -> DynJobKind { - DynJobArgsTrait::kind(&*self.0) - } - pub fn to_args_vec(&self) -> Vec> { - self.to_args_extend_vec(Vec::new()) - } - pub fn to_args_extend_vec(&self, args: Vec>) -> Vec> { - DynJobArgsTrait::to_args_extend_vec(&*self.0, args) - } - fn make_mut(&mut self) -> &mut dyn DynJobArgsTrait { - // can't just return the reference if the first get_mut returns Some since - // as of rustc 1.90.0 this causes a false-positive lifetime error. - if Arc::get_mut(&mut self.0).is_none() { - self.0 = DynJobArgsTrait::clone_into_arc(&*self.0); - } - Arc::get_mut(&mut self.0).expect("clone_into_arc returns a new arc with a ref-count of 1") - } - pub fn update_from_arg_matches( - &mut self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result<()> { - DynJobArgsTrait::update_from_arg_matches(self.make_mut(), matches) - } - pub fn args_to_jobs( - self, - dependencies_args: Vec, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<(DynJob, Vec)> { - DynJobArgsTrait::args_to_jobs(self.0, dependencies_args, params, global_params) - } - #[track_caller] - pub fn base_job_args_dyn<'a>(&'a self, dependencies_args: &'a [DynJobArgs]) -> &'a BaseJobArgs { - DynJobArgsTrait::base_job_args_dyn(&*self.0, dependencies_args) - } -} - -impl Hash for DynJobArgs { - fn hash(&self, state: &mut H) { - self.kind_type_id().hash(state); - DynJobArgsTrait::hash_dyn(&*self.0, state); - } -} - -impl PartialEq for DynJobArgs { - fn eq(&self, other: &Self) -> bool { - DynJobArgsTrait::eq_dyn(&*self.0, &*other.0) - } -} - -impl Eq for DynJobArgs {} - -impl fmt::Debug for DynJobArgs { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -#[derive(PartialEq, Eq, Hash)] -struct DynJobInner { - kind: Arc, - job: K::Job, - inputs: Interned<[JobItemName]>, - outputs: Interned<[JobItemName]>, - external_command_params: Option, -} - -impl> Clone for DynJobInner { - fn clone(&self) -> Self { - Self { - kind: self.kind.clone(), - job: self.job.clone(), - inputs: self.inputs, - outputs: self.outputs, - external_command_params: self.external_command_params, - } - } -} - -impl fmt::Debug for DynJobInner { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - kind, - job, - inputs, - outputs, - external_command_params, - } = self; - f.debug_struct("DynJob") - .field("kind", kind) - .field("job", job) - .field("inputs", inputs) - .field("outputs", outputs) - .field("external_command_params", external_command_params) - .finish() - } -} - -trait DynJobTrait: 'static + Send + Sync + fmt::Debug { - fn as_any(&self) -> &dyn Any; - fn as_arc_any(self: Arc) -> Arc; - fn eq_dyn(&self, other: &dyn DynJobTrait) -> bool; - fn hash_dyn(&self, state: &mut dyn Hasher); - fn kind_type_id(&self) -> TypeId; - fn kind(&self) -> DynJobKind; - fn inputs(&self) -> Interned<[JobItemName]>; - fn outputs(&self) -> Interned<[JobItemName]>; - fn external_command_params(&self) -> Option; - fn serialize_to_json_ascii(&self) -> serde_json::Result; - fn serialize_to_json_value(&self) -> serde_json::Result; - fn run( - &self, - inputs: &[JobItem], - params: &JobParams, - global_params: &GlobalParams, - acquired_job: &mut AcquiredJob, - ) -> eyre::Result>; - #[track_caller] - fn base_job_dyn<'a>(&'a self, dependencies: &'a [DynJob]) -> &'a BaseJob; -} - -impl DynJobTrait for DynJobInner { - fn as_any(&self) -> &dyn Any { - self - } - - fn as_arc_any(self: Arc) -> Arc { - self - } - - fn eq_dyn(&self, other: &dyn DynJobTrait) -> bool { - other - .as_any() - .downcast_ref::() - .is_some_and(|other| self == other) - } - - fn hash_dyn(&self, mut state: &mut dyn Hasher) { - self.hash(&mut state); - } - - fn kind_type_id(&self) -> TypeId { - TypeId::of::() - } - - fn kind(&self) -> DynJobKind { - DynJobKind(self.kind.clone()) - } - - fn inputs(&self) -> Interned<[JobItemName]> { - self.inputs - } - - fn outputs(&self) -> Interned<[JobItemName]> { - self.outputs - } - - fn external_command_params(&self) -> Option { - self.external_command_params - } - - fn serialize_to_json_ascii(&self) -> serde_json::Result { - crate::util::serialize_to_json_ascii(&self.job) - } - - fn serialize_to_json_value(&self) -> serde_json::Result { - serde_json::to_value(&self.job) - } - - fn run( - &self, - inputs: &[JobItem], - params: &JobParams, - global_params: &GlobalParams, - acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - self.kind - .run(&self.job, inputs, params, global_params, acquired_job) - } - - #[track_caller] - fn base_job_dyn<'a>(&'a self, dependencies: &'a [DynJob]) -> &'a BaseJob { - self.kind.base_job_dyn(&self.job, dependencies) - } -} - -#[derive(Clone, Debug)] -pub struct DynJob(Arc); - -impl DynJob { - pub fn from_arc(job_kind: Arc, job: K::Job) -> Self { - let inputs = job_kind.inputs(&job); - let outputs = job_kind.outputs(&job); - let external_command_params = job_kind.external_command_params(&job); - Self(Arc::new(DynJobInner { - kind: job_kind, - job, - inputs, - outputs, - external_command_params, - })) - } - pub fn new(job_kind: K, job: K::Job) -> Self { - Self::from_arc(Arc::new(job_kind), job) - } - pub fn kind_type_id(&self) -> TypeId { - self.0.kind_type_id() - } - pub fn downcast_ref(&self) -> Option<(&K, &K::Job)> { - let DynJobInner { kind, job, .. } = self.0.as_any().downcast_ref()?; - Some((kind, job)) - } - pub fn downcast>(self) -> Result, Self> { - if self.kind_type_id() == TypeId::of::() { - let DynJobInner { kind, job, .. } = Arc::unwrap_or_clone( - self.0 - .as_arc_any() - .downcast::>() - .expect("already checked type"), - ); - Ok(JobAndKind { kind: *kind, job }) - } else { - Err(self) - } - } - pub fn kind(&self) -> DynJobKind { - DynJobTrait::kind(&*self.0) - } - pub fn inputs(&self) -> Interned<[JobItemName]> { - DynJobTrait::inputs(&*self.0) - } - pub fn outputs(&self) -> Interned<[JobItemName]> { - DynJobTrait::outputs(&*self.0) - } - pub fn serialize_to_json_ascii(&self) -> serde_json::Result { - DynJobTrait::serialize_to_json_ascii(&*self.0) - } - pub fn serialize_to_json_value(&self) -> serde_json::Result { - DynJobTrait::serialize_to_json_value(&*self.0) - } - pub fn external_command_params(&self) -> Option { - DynJobTrait::external_command_params(&*self.0) - } - #[track_caller] - pub fn internal_command_params_with_program_prefix( - &self, - internal_program_prefix: &[Interned], - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> CommandParams { - let mut command_line = internal_program_prefix.to_vec(); - let command_line = match RunSingleJob::try_add_subcommand(platform, self, &mut command_line) - { - Ok(()) => { - command_line.extend_from_slice(extra_args); - Intern::intern_owned(command_line) - } - Err(e) => panic!("Serializing job {:?} failed: {e}", self.kind().name()), - }; - CommandParams { - command_line, - current_dir: None, - } - } - #[track_caller] - pub fn internal_command_params( - &self, - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> CommandParams { - self.internal_command_params_with_program_prefix( - &[program_name_for_internal_jobs()], - platform, - extra_args, - ) - } - #[track_caller] - pub fn command_params_with_internal_program_prefix( - &self, - internal_program_prefix: &[Interned], - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> CommandParams { - match self.external_command_params() { - Some(v) => v, - None => self.internal_command_params_with_program_prefix( - internal_program_prefix, - platform, - extra_args, - ), - } - } - #[track_caller] - pub fn command_params( - &self, - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> CommandParams { - self.command_params_with_internal_program_prefix( - &[program_name_for_internal_jobs()], - platform, - extra_args, - ) - } - pub fn run( - &self, - inputs: &[JobItem], - params: &JobParams, - global_params: &GlobalParams, - acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - DynJobTrait::run(&*self.0, inputs, params, global_params, acquired_job) - } - #[track_caller] - pub fn base_job_dyn<'a>(&'a self, dependencies: &'a [DynJob]) -> &'a BaseJob { - DynJobTrait::base_job_dyn(&*self.0, dependencies) - } -} - -impl Eq for DynJob {} - -impl PartialEq for DynJob { - fn eq(&self, other: &Self) -> bool { - DynJobTrait::eq_dyn(&*self.0, &*other.0) - } -} - -impl Hash for DynJob { - fn hash(&self, state: &mut H) { - DynJobTrait::hash_dyn(&*self.0, state); - } -} - -#[derive(Serialize, Deserialize)] -#[serde(rename = "DynJob")] -struct DynJobSerde { - kind: DynJobKind, - job: serde_json::Value, -} - -impl Serialize for DynJob { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - DynJobSerde { - kind: self.kind(), - job: self.serialize_to_json_value().map_err(S::Error::custom)?, - } - .serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for DynJob { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let DynJobSerde { kind, job } = Deserialize::deserialize(deserializer)?; - kind.deserialize_job_from_json_value(&job) - .map_err(D::Error::custom) - } -} - -pub trait RunBuild: Sized { - fn main_without_platform(application_name: impl AsRef, make_params: F) - where - Self: clap::Parser + Clone, - F: FnOnce(Self, Extra) -> eyre::Result, - { - let application_name = application_name.as_ref(); - match Self::try_main_without_platform(application_name, make_params) { - Ok(()) => {} - Err(e) => { - let e = GlobalParams::new(Some(Self::command()), application_name) - .exit_if_clap_error(e); - eprintln!("{e:#}"); - std::process::exit(1); - } - } - } - fn try_main_without_platform( - application_name: impl AsRef, - make_params: F, - ) -> eyre::Result<()> - where - Self: clap::Parser + Clone, - F: FnOnce(Self, Extra) -> eyre::Result, - { - let args = Self::parse(); - let global_params = GlobalParams::new(Some(Self::command()), application_name); - args.clone() - .run_without_platform(|extra| make_params(args, extra), &global_params) - .map_err(|e| global_params.exit_if_clap_error(e)) - } - fn run_without_platform( - self, - make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(Extra) -> eyre::Result; - fn get_platform(&self) -> Option<&DynPlatform>; - fn main(application_name: impl AsRef, make_params: F) - where - Self: clap::Parser + Clone, - F: FnOnce(Self, DynPlatform, Extra) -> eyre::Result, - { - let application_name = application_name.as_ref(); - match Self::try_main(application_name, make_params) { - Ok(()) => {} - Err(e) => { - let e = GlobalParams::new(Some(Self::command()), application_name) - .exit_if_clap_error(e); - eprintln!("{e:#}"); - std::process::exit(1); - } - } - } - fn try_main(application_name: impl AsRef, make_params: F) -> eyre::Result<()> - where - Self: clap::Parser + Clone, - F: FnOnce(Self, DynPlatform, Extra) -> eyre::Result, - { - let args = Self::parse(); - let global_params = GlobalParams::new(Some(Self::command()), application_name); - let Some(platform) = args.get_platform().cloned() else { - return args.handle_missing_platform(&global_params); - }; - args.clone() - .run( - |platform, extra| make_params(args, platform, extra), - platform, - &global_params, - ) - .map_err(|e| global_params.exit_if_clap_error(e)) - } - fn handle_missing_platform(self, global_params: &GlobalParams) -> eyre::Result<()> { - global_params - .clap_error( - clap::error::ErrorKind::MissingRequiredArgument, - "--platform is required", - ) - .exit(); - } - fn run( - self, - make_params: F, - platform: DynPlatform, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(DynPlatform, Extra) -> eyre::Result, - { - self.run_without_platform(|extra| make_params(platform, extra), global_params) - } -} - -impl RunBuild for JobArgsAndDependencies { - fn run_without_platform( - self, - make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(NoArgs) -> eyre::Result, - { - let params = make_params(NoArgs)?; - self.args_to_jobs(¶ms, global_params)? - .run_without_platform(|_| Ok(params), global_params) - } - fn get_platform(&self) -> Option<&DynPlatform> { - self.base_job_args().platform.as_ref() - } - fn run( - self, - make_params: F, - platform: DynPlatform, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(DynPlatform, NoArgs) -> eyre::Result, - { - let params = make_params(platform.clone(), NoArgs)?; - self.args_to_jobs(¶ms, global_params)? - .run(|_, _| Ok(params), platform, global_params) - } -} - -impl RunBuild for JobAndDependencies { - fn run_without_platform( - self, - make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(NoArgs) -> eyre::Result, - { - let params = make_params(NoArgs)?; - let Self { job, dependencies } = self; - let mut jobs = vec![DynJob::from(job)]; - K::Dependencies::into_dyn_jobs_extend(dependencies, &mut jobs); - let mut job_graph = JobGraph::new(); - job_graph.add_jobs(jobs); // add all at once to avoid recomputing graph properties multiple times - job_graph.run(¶ms, global_params) - } - fn get_platform(&self) -> Option<&DynPlatform> { - self.base_job().platform() - } - fn run( - self, - make_params: F, - platform: DynPlatform, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(DynPlatform, NoArgs) -> eyre::Result, - { - let params = make_params(platform, NoArgs)?; - let Self { job, dependencies } = self; - let mut jobs = vec![DynJob::from(job)]; - K::Dependencies::into_dyn_jobs_extend(dependencies, &mut jobs); - let mut job_graph = JobGraph::new(); - job_graph.add_jobs(jobs); // add all at once to avoid recomputing graph properties multiple times - job_graph.run(¶ms, global_params) - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct RunSingleJob { - pub platform: Option, - pub job: DynJob, - pub extra: Extra, -} - -impl RunSingleJob { - pub const SUBCOMMAND_NAME: &'static str = "run-single-job"; - fn try_add_subcommand( - platform: Option<&DynPlatform>, - job: &DynJob, - subcommand_line: &mut Vec>, - ) -> serde_json::Result<()> { - let mut json = job.serialize_to_json_ascii()?; - json.insert_str(0, "--json="); - subcommand_line.push(Self::SUBCOMMAND_NAME.intern().into()); - if let Some(platform) = platform { - subcommand_line.push( - format!("--platform={}", platform.name()) - .intern_deref() - .into(), - ); - } - subcommand_line.push( - format!("--name={}", job.kind().name()) - .intern_deref() - .into(), - ); - subcommand_line.push(json.intern_deref().into()); - Ok(()) - } -} - -impl TryFrom> for RunSingleJob { - type Error = clap::Error; - - fn try_from(value: RunSingleJobClap) -> Result { - let RunSingleJobClap::RunSingleJob { - platform, - name: job_kind, - json, - extra, - } = value; - let name = job_kind.name(); - job_kind - .deserialize_job_from_json_str(&json) - .map_err(|e| { - clap::Error::raw( - clap::error::ErrorKind::ValueValidation, - format_args!("failed to parse job {name} from JSON: {e}"), - ) - }) - .map(|job| Self { - platform, - job, - extra, - }) - } -} - -#[derive(clap::Subcommand)] -enum RunSingleJobClap { - #[command(name = RunSingleJob::SUBCOMMAND_NAME, hide = true)] - RunSingleJob { - #[arg(long)] - platform: Option, - #[arg(long)] - name: DynJobKind, - #[arg(long)] - json: String, - #[command(flatten)] - extra: Extra, - }, -} - -impl clap::Subcommand for RunSingleJob { - fn augment_subcommands(cmd: clap::Command) -> clap::Command { - RunSingleJobClap::::augment_subcommands(cmd) - } - - fn augment_subcommands_for_update(cmd: clap::Command) -> clap::Command { - RunSingleJobClap::::augment_subcommands(cmd) - } - - fn has_subcommand(name: &str) -> bool { - RunSingleJobClap::::has_subcommand(name) - } -} - -impl clap::FromArgMatches for RunSingleJob { - fn from_arg_matches(matches: &clap::ArgMatches) -> clap::error::Result { - RunSingleJobClap::from_arg_matches(matches)?.try_into() - } - fn from_arg_matches_mut(matches: &mut clap::ArgMatches) -> clap::error::Result { - RunSingleJobClap::from_arg_matches_mut(matches)?.try_into() - } - fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> clap::error::Result<()> { - *self = Self::from_arg_matches(matches)?; - Ok(()) - } - fn update_from_arg_matches_mut( - &mut self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result<()> { - *self = Self::from_arg_matches_mut(matches)?; - Ok(()) - } -} - -impl RunBuild for RunSingleJob { - fn run_without_platform( - self, - make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(Extra) -> eyre::Result, - { - let params = make_params(self.extra)?; - let mut job_graph = JobGraph::new(); - job_graph.add_jobs([self.job]); - job_graph.run(¶ms, global_params) - } - fn get_platform(&self) -> Option<&DynPlatform> { - self.platform.as_ref() - } -} - -#[derive(Clone, PartialEq, Eq, Hash, clap::Subcommand)] -pub enum Completions { - #[non_exhaustive] - Completions { - #[arg(default_value = Self::shell_str_from_env(), required = Self::shell_from_env().is_none())] - shell: clap_complete::aot::Shell, - }, -} - -impl Completions { - pub fn new(shell: clap_complete::aot::Shell) -> Self { - Self::Completions { shell } - } - pub fn from_env() -> Option { - Some(Self::Completions { - shell: Self::shell_from_env()?, - }) - } - fn shell_from_env() -> Option { - static SHELL: OnceLock> = OnceLock::new(); - *SHELL.get_or_init(clap_complete::aot::Shell::from_env) - } - fn shell_str_from_env() -> clap::builder::Resettable { - static SHELL_STR: OnceLock> = OnceLock::new(); - SHELL_STR - .get_or_init(|| Self::shell_from_env().map(|v| v.to_string())) - .as_deref() - .map(Into::into) - .into() - } -} - -impl RunBuild for Completions { - fn run_without_platform( - self, - _make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(NoArgs) -> eyre::Result, - { - let Self::Completions { shell } = self; - let Some(cmd) = global_params.top_level_cmd() else { - eyre::bail!("completions command requires GlobalParams::top_level_cmd() to be Some"); - }; - let bin_name = cmd.get_bin_name().map(str::intern).unwrap_or_else(|| { - program_name_for_internal_jobs() - .to_interned_str() - .expect("program name is invalid UTF-8") - }); - clap_complete::aot::generate( - shell, - &mut cmd.clone(), - &*bin_name, - &mut std::io::BufWriter::new(std::io::stdout().lock()), - ); - Ok(()) - } - fn handle_missing_platform(self, global_params: &GlobalParams) -> eyre::Result<()> { - self.run_without_platform(|_| unreachable!(), global_params) - } - fn get_platform(&self) -> Option<&DynPlatform> { - None - } -} - -#[derive( - clap::Args, - Copy, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Debug, - Default, - Serialize, - Deserialize, -)] -pub struct NoArgs; - -impl ToArgs for NoArgs { - fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { - let Self {} = self; - } -} - -#[derive(Clone, PartialEq, Eq, Hash, clap::Parser)] -pub enum BuildCli { - #[clap(flatten)] - Job(AnyJobSubcommand), - #[clap(flatten)] - RunSingleJob(RunSingleJob), - #[clap(flatten)] - Completions(Completions), - #[cfg(unix)] - #[clap(flatten)] - CreateUnixShellScript(CreateUnixShellScript), -} - -impl RunBuild for BuildCli { - fn run_without_platform( - self, - make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(Extra) -> eyre::Result, - { - match self { - BuildCli::Job(v) => v.run_without_platform(make_params, global_params), - BuildCli::RunSingleJob(v) => v.run_without_platform(make_params, global_params), - BuildCli::Completions(v) => { - v.run_without_platform(|NoArgs {}| unreachable!(), global_params) - } - #[cfg(unix)] - BuildCli::CreateUnixShellScript(v) => { - v.run_without_platform(make_params, global_params) - } - } - } - fn handle_missing_platform(self, global_params: &GlobalParams) -> eyre::Result<()> { - match self { - BuildCli::Job(v) => v.handle_missing_platform(global_params), - BuildCli::RunSingleJob(v) => v.handle_missing_platform(global_params), - BuildCli::Completions(v) => v.handle_missing_platform(global_params), - #[cfg(unix)] - BuildCli::CreateUnixShellScript(v) => v.handle_missing_platform(global_params), - } - } - fn get_platform(&self) -> Option<&DynPlatform> { - match self { - BuildCli::Job(v) => v.get_platform(), - BuildCli::RunSingleJob(v) => v.get_platform(), - BuildCli::Completions(v) => v.get_platform(), - #[cfg(unix)] - BuildCli::CreateUnixShellScript(v) => v.get_platform(), - } - } - fn run( - self, - make_params: F, - platform: DynPlatform, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(DynPlatform, Extra) -> eyre::Result, - { - match self { - BuildCli::Job(v) => v.run(make_params, platform, global_params), - BuildCli::RunSingleJob(v) => v.run(make_params, platform, global_params), - BuildCli::Completions(v) => { - v.run(|_, NoArgs {}| unreachable!(), platform, global_params) - } - #[cfg(unix)] - BuildCli::CreateUnixShellScript(v) => v.run(make_params, platform, global_params), - } - } -} - -#[cfg(unix)] -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Subcommand)] -enum CreateUnixShellScriptInner { - CreateUnixShellScript { - #[arg(name = "i-know-this-is-incomplete", long, required = true, action = ArgAction::SetTrue)] - _incomplete: (), - #[command(subcommand)] - inner: AnyJobSubcommand, - }, -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct CreateUnixShellScript(CreateUnixShellScriptInner); - -impl RunBuild for CreateUnixShellScript { - fn run_without_platform( - self, - make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(Extra) -> eyre::Result, - { - let platform = self.get_platform().cloned(); - let CreateUnixShellScriptInner::CreateUnixShellScript { - _incomplete: (), - inner: - AnyJobSubcommand { - args, - dependencies_args, - extra, - }, - } = self.0; - let extra_args = extra.to_interned_args_vec(); - let params = make_params(extra)?; - let bin_name = global_params - .top_level_cmd() - .and_then(clap::Command::get_bin_name) - .map(|v| OsStr::new(v).intern()); - let (job, dependencies) = args.args_to_jobs(dependencies_args, ¶ms, global_params)?; - let mut job_graph = JobGraph::new(); - job_graph.add_jobs([job].into_iter().chain(dependencies)); - std::io::stdout().write_all( - job_graph - .to_unix_shell_script_with_internal_program_prefix( - &[bin_name.unwrap_or_else(|| program_name_for_internal_jobs())], - platform.as_ref(), - &extra_args, - ) - .as_bytes(), - )?; - Ok(()) - } - fn get_platform(&self) -> Option<&DynPlatform> { - let CreateUnixShellScriptInner::CreateUnixShellScript { inner, .. } = &self.0; - inner.get_platform() - } -} - -impl clap::FromArgMatches for CreateUnixShellScript { - fn from_arg_matches(matches: &clap::ArgMatches) -> Result { - clap::FromArgMatches::from_arg_matches(matches).map(Self) - } - fn from_arg_matches_mut(matches: &mut clap::ArgMatches) -> Result { - clap::FromArgMatches::from_arg_matches_mut(matches).map(Self) - } - fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> Result<(), clap::Error> { - self.0.update_from_arg_matches(matches) - } - fn update_from_arg_matches_mut( - &mut self, - matches: &mut clap::ArgMatches, - ) -> Result<(), clap::Error> { - self.0.update_from_arg_matches_mut(matches) - } -} - -#[cfg(unix)] -impl clap::Subcommand for CreateUnixShellScript { - fn augment_subcommands(cmd: clap::Command) -> clap::Command { - CreateUnixShellScriptInner::::augment_subcommands(cmd) - } - - fn augment_subcommands_for_update(cmd: clap::Command) -> clap::Command { - CreateUnixShellScriptInner::::augment_subcommands_for_update(cmd) - } - - fn has_subcommand(name: &str) -> bool { - CreateUnixShellScriptInner::::has_subcommand(name) - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct AnyJobSubcommand { - pub args: DynJobArgs, - pub dependencies_args: Vec, - pub extra: Extra, -} - -impl AnyJobSubcommand { - pub fn from_subcommand_arg_matches( - job_kind: &DynJobKind, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result { - let dependencies = job_kind.dependencies_kinds(); - let dependencies_args = Result::from_iter( - dependencies - .into_iter() - .map(|dependency| dependency.from_arg_matches(matches)), - )?; - Ok(Self { - args: job_kind.clone().from_arg_matches(matches)?, - dependencies_args, - extra: Extra::from_arg_matches_mut(matches)?, - }) - } - pub fn update_from_subcommand_arg_matches( - &mut self, - job_kind: &DynJobKind, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result<()> { - let Self { - args, - dependencies_args, - extra, - } = self; - if *job_kind == args.kind() { - for dependency in dependencies_args { - dependency.update_from_arg_matches(matches)?; - } - args.update_from_arg_matches(matches)?; - } else { - let dependencies = job_kind.dependencies_kinds(); - let new_dependencies_args = Result::from_iter( - dependencies - .into_iter() - .map(|dependency| dependency.from_arg_matches(matches)), - )?; - *args = job_kind.clone().from_arg_matches(matches)?; - *dependencies_args = new_dependencies_args; - } - extra.update_from_arg_matches_mut(matches) - } -} - -impl clap::Subcommand for AnyJobSubcommand { - fn augment_subcommands(mut cmd: clap::Command) -> clap::Command { - let snapshot = registry::JobKindRegistrySnapshot::get(); - for job_kind in &snapshot { - cmd = cmd.subcommand(Extra::augment_args(job_kind.make_subcommand())); - } - cmd - } - - fn augment_subcommands_for_update(mut cmd: clap::Command) -> clap::Command { - let snapshot = registry::JobKindRegistrySnapshot::get(); - for job_kind in &snapshot { - cmd = cmd.subcommand(Extra::augment_args_for_update( - job_kind.make_subcommand_for_update(), - )); - } - cmd - } - - fn has_subcommand(name: &str) -> bool { - registry::JobKindRegistrySnapshot::get() - .get_by_name(name) - .is_some() - } -} - -impl clap::FromArgMatches for AnyJobSubcommand { - fn from_arg_matches(matches: &clap::ArgMatches) -> clap::error::Result { - Self::from_arg_matches_mut(&mut matches.clone()) - } - - fn from_arg_matches_mut(matches: &mut clap::ArgMatches) -> clap::error::Result { - if let Some((name, mut matches)) = matches.remove_subcommand() { - let job_kind_registry_snapshot = registry::JobKindRegistrySnapshot::get(); - if let Some(job_kind) = job_kind_registry_snapshot.get_by_name(&name) { - Self::from_subcommand_arg_matches(job_kind, &mut matches) - } else { - Err(clap::Error::raw( - clap::error::ErrorKind::InvalidSubcommand, - format!("the subcommand '{name}' wasn't recognized"), - )) - } - } else { - Err(clap::Error::raw( - clap::error::ErrorKind::MissingSubcommand, - "a subcommand is required but one was not provided", - )) - } - } - - fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> clap::error::Result<()> { - Self::update_from_arg_matches_mut(self, &mut matches.clone()) - } - - fn update_from_arg_matches_mut( - &mut self, - matches: &mut clap::ArgMatches, - ) -> clap::error::Result<()> { - if let Some((name, mut matches)) = matches.remove_subcommand() { - let job_kind_registry_snapshot = registry::JobKindRegistrySnapshot::get(); - if let Some(job_kind) = job_kind_registry_snapshot.get_by_name(&name) { - self.update_from_subcommand_arg_matches(job_kind, &mut matches) - } else { - Err(clap::Error::raw( - clap::error::ErrorKind::InvalidSubcommand, - format!("the subcommand '{name}' wasn't recognized"), - )) - } - } else { - Err(clap::Error::raw( - clap::error::ErrorKind::MissingSubcommand, - "a subcommand is required but one was not provided", - )) - } - } -} - -impl RunBuild for AnyJobSubcommand { - fn run_without_platform( - self, - make_params: F, - global_params: &GlobalParams, - ) -> eyre::Result<()> - where - F: FnOnce(Extra) -> eyre::Result, - { - let Self { - args, - dependencies_args, - extra, - } = self; - let params = make_params(extra)?; - let (job, dependencies) = args.args_to_jobs(dependencies_args, ¶ms, global_params)?; - let mut job_graph = JobGraph::new(); - job_graph.add_jobs([job].into_iter().chain(dependencies)); // add all at once to avoid recomputing graph properties multiple times - job_graph.run(¶ms, global_params) - } - fn get_platform(&self) -> Option<&DynPlatform> { - self.args - .base_job_args_dyn(&self.dependencies_args) - .platform - .as_ref() - } -} - -pub fn program_name_for_internal_jobs() -> Interned { - static PROGRAM_NAME: OnceLock> = OnceLock::new(); - *PROGRAM_NAME.get_or_init(|| { - std::env::args_os() - .next() - .expect("can't get program name") - .intern_deref() - }) -} - -#[derive(clap::Args, Debug, Clone, Hash, PartialEq, Eq)] -#[group(id = "BaseJob")] -#[non_exhaustive] -pub struct BaseJobArgs { - /// the directory to put the generated main output file and associated files in - #[arg(short, long, value_hint = clap::ValueHint::DirPath)] - pub output: Option, - #[arg(long, env = "FAYALITE_KEEP_TEMP_DIR")] - pub keep_temp_dir: bool, - /// the stem of the generated main output file, e.g. to get foo.v, pass --file-stem=foo - #[arg(long)] - pub file_stem: Option, - /// run commands even if their results are already cached - #[arg(long, env = Self::RUN_EVEN_IF_CACHED_ENV_NAME)] - pub run_even_if_cached: bool, - /// platform - #[arg(long)] - pub platform: Option, -} - -impl BaseJobArgs { - pub const RUN_EVEN_IF_CACHED_ENV_NAME: &'static str = "FAYALITE_RUN_EVEN_IF_CACHED"; - pub fn from_output_dir_and_env(output: PathBuf, platform: Option) -> Self { - Self { - output: Some(output), - keep_temp_dir: false, - file_stem: None, - run_even_if_cached: std::env::var_os(Self::RUN_EVEN_IF_CACHED_ENV_NAME).is_some(), - platform, - } - } -} - -impl ToArgs for BaseJobArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { - output, - keep_temp_dir, - file_stem, - run_even_if_cached, - platform, - } = self; - if let Some(output) = output { - args.write_long_option_eq("output", output); - } - if *keep_temp_dir { - args.write_arg("--keep-temp-dir"); - } - if let Some(file_stem) = file_stem { - args.write_long_option_eq("file-stem", file_stem); - } - if *run_even_if_cached { - args.write_arg("--run-even-if-cached"); - } - if let Some(platform) = platform { - args.write_long_option_eq("platform", platform.name()); - } - } -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct BaseJob { - output_dir: Interned, - #[serde(skip)] - temp_dir: Option>, - file_stem: Interned, - run_even_if_cached: bool, - platform: Option, -} - -impl Hash for BaseJob { - fn hash(&self, state: &mut H) { - let Self { - output_dir, - temp_dir: _, - file_stem, - run_even_if_cached, - platform, - } = self; - output_dir.hash(state); - file_stem.hash(state); - run_even_if_cached.hash(state); - platform.hash(state); - } -} - -impl Eq for BaseJob {} - -impl PartialEq for BaseJob { - fn eq(&self, other: &Self) -> bool { - let Self { - output_dir, - temp_dir: _, - file_stem, - run_even_if_cached, - ref platform, - } = *self; - output_dir == other.output_dir - && file_stem == other.file_stem - && run_even_if_cached == other.run_even_if_cached - && *platform == other.platform - } -} - -impl BaseJob { - pub fn output_dir(&self) -> Interned { - self.output_dir - } - pub fn temp_dir(&self) -> Option<&Arc> { - self.temp_dir.as_ref() - } - pub fn file_stem(&self) -> Interned { - self.file_stem - } - pub fn file_with_ext(&self, ext: impl AsRef) -> Interned { - let mut retval = self.output_dir().join(self.file_stem()); - retval.set_extension(ext); - retval.intern_deref() - } - pub fn run_even_if_cached(&self) -> bool { - self.run_even_if_cached - } - pub fn platform(&self) -> Option<&DynPlatform> { - self.platform.as_ref() - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)] -pub struct BaseJobKind; - -impl JobKindHelper for BaseJobKind { - fn base_job<'a>( - self, - job: &'a ::Job, - _dependencies: &'a <::Dependencies as JobDependencies>::JobsAndKinds, - ) -> &'a BaseJob { - job - } - fn base_job_args<'a>( - self, - args: &'a ::Args, - _dependencies: &'a <::Dependencies as JobDependencies>::KindsAndArgs, - ) -> &'a BaseJobArgs { - args - } - #[track_caller] - fn base_job_args_dyn<'a>( - self, - args: &'a ::Args, - dependencies_args: &'a [DynJobArgs], - ) -> &'a BaseJobArgs { - let [] = dependencies_args else { - panic!("wrong number of dependencies"); - }; - args - } - #[track_caller] - fn base_job_dyn<'a>( - self, - job: &'a ::Job, - dependencies: &'a [DynJob], - ) -> &'a BaseJob { - let [] = dependencies else { - panic!("wrong number of dependencies"); - }; - job - } -} - -impl JobKind for BaseJobKind { - type Args = BaseJobArgs; - type Job = BaseJob; - type Dependencies = (); - - fn dependencies(self) -> Self::Dependencies { - () - } - - fn args_to_jobs( - args: JobArgsAndDependencies, - params: &JobParams, - _global_params: &GlobalParams, - ) -> eyre::Result> { - let BaseJobArgs { - output, - keep_temp_dir, - file_stem, - run_even_if_cached, - platform, - } = args.args.args; - let (output_dir, temp_dir) = if let Some(output) = output { - (Intern::intern_owned(output), None) - } else { - // we create the temp dir here rather than in run so other - // jobs can have their paths based on the chosen temp dir - let temp_dir = TempDir::new()?; - let output_dir = temp_dir.path().intern(); - let temp_dir = if keep_temp_dir { - // use TempDir::into_path() to no longer automatically delete the temp dir - let temp_dir_path = temp_dir.into_path(); - println!("created temporary directory: {}", temp_dir_path.display()); - None - } else { - Some(Arc::new(temp_dir)) - }; - (output_dir, temp_dir) - }; - let file_stem = file_stem - .map(Intern::intern_deref) - .unwrap_or(params.main_module().name().into()); - Ok(JobAndDependencies { - job: JobAndKind { - kind: BaseJobKind, - job: BaseJob { - output_dir, - temp_dir, - file_stem, - run_even_if_cached, - platform, - }, - }, - dependencies: (), - }) - } - - fn inputs(self, _job: &Self::Job) -> Interned<[JobItemName]> { - Interned::default() - } - - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { - path: job.output_dir, - }] - .intern_slice() - } - - fn name(self) -> Interned { - "base-job".intern() - } - - fn external_command_params(self, job: &Self::Job) -> Option { - Some(CommandParams { - command_line: [ - "mkdir".intern().into(), - "-p".intern().into(), - "--".intern().into(), - job.output_dir.into(), - ] - .intern_slice(), - current_dir: None, - }) - } - - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - _params: &JobParams, - _global_params: &GlobalParams, - _acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - let [] = inputs else { - panic!("invalid inputs for BaseJob"); - }; - std::fs::create_dir_all(&*job.output_dir)?; - Ok(vec![JobItem::Path { - path: job.output_dir, - }]) - } - - fn subcommand_hidden(self) -> bool { - true - } -} - -pub trait GetJob { - fn get_job(this: &Self) -> &J; -} - -impl> GetJob for &'_ T { - fn get_job(this: &Self) -> &J { - T::get_job(this) - } -} - -impl> GetJob for &'_ mut T { - fn get_job(this: &Self) -> &J { - T::get_job(this) - } -} - -impl> GetJob for Box { - fn get_job(this: &Self) -> &J { - T::get_job(this) - } -} - -pub struct GetJobPositionDependencies(PhantomData); - -impl Default for GetJobPositionDependencies { - fn default() -> Self { - Self(Default::default()) - } -} - -impl fmt::Debug for GetJobPositionDependencies { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "GetJobPositionDependencies<{}>", - std::any::type_name::() - ) - } -} - -impl Hash for GetJobPositionDependencies { - fn hash(&self, _state: &mut H) {} -} - -impl Ord for GetJobPositionDependencies { - fn cmp(&self, _other: &Self) -> Ordering { - Ordering::Equal - } -} - -impl PartialOrd for GetJobPositionDependencies { - fn partial_cmp(&self, _other: &Self) -> Option { - Some(Ordering::Equal) - } -} - -impl Eq for GetJobPositionDependencies {} - -impl PartialEq for GetJobPositionDependencies { - fn eq(&self, _other: &Self) -> bool { - true - } -} - -impl Clone for GetJobPositionDependencies { - fn clone(&self) -> Self { - Self(PhantomData) - } -} - -impl Copy for GetJobPositionDependencies {} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] -pub struct GetJobPositionJob; - -impl>>> - GetJob> for JobAndDependencies -{ - fn get_job(this: &Self) -> &J { - GetJob::get_job(&this.dependencies) - } -} - -impl GetJob for JobAndDependencies { - fn get_job(this: &Self) -> &K::Job { - &this.job.job - } -} - -impl>>> - GetJob> for JobArgsAndDependencies -{ - fn get_job(this: &Self) -> &J { - GetJob::get_job(&this.dependencies) - } -} - -impl GetJob for JobArgsAndDependencies { - fn get_job(this: &Self) -> &K::Args { - &this.args.args - } -} - -impl>> - GetJob> for JobKindAndDependencies -{ - fn get_job(this: &Self) -> &J { - GetJob::get_job(&this.dependencies) - } -} - -impl GetJob for JobKindAndDependencies { - fn get_job(this: &Self) -> &K { - &this.kind - } -} diff --git a/crates/fayalite/src/build/external.rs b/crates/fayalite/src/build/external.rs deleted file mode 100644 index 1a90414..0000000 --- a/crates/fayalite/src/build/external.rs +++ /dev/null @@ -1,1177 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - build::{ - ArgsWriter, CommandParams, GlobalParams, JobAndDependencies, JobAndKind, - JobArgsAndDependencies, JobDependencies, JobDependenciesHasBase, JobItem, JobItemName, - JobKind, JobKindAndArgs, JobParams, ToArgs, WriteArgs, - }, - intern::{Intern, Interned}, - util::{job_server::AcquiredJob, streaming_read_utf8::streaming_read_utf8}, -}; -use base64::{Engine, prelude::BASE64_URL_SAFE_NO_PAD}; -use clap::builder::OsStringValueParser; -use eyre::{Context, ensure, eyre}; -use serde::{ - Deserialize, Deserializer, Serialize, Serializer, - de::{DeserializeOwned, Error}, -}; -use std::{ - borrow::Cow, - collections::BTreeMap, - ffi::{OsStr, OsString}, - fmt, - hash::{Hash, Hasher}, - io::Write, - marker::PhantomData, - path::{Path, PathBuf}, - process::ExitStatus, - sync::OnceLock, -}; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)] -#[non_exhaustive] -pub enum ExternalJobCacheVersion { - /// not used, used to be for `FormalCacheVersion` - V1, - V2, -} - -impl ExternalJobCacheVersion { - pub const CURRENT: Self = Self::V2; -} - -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[non_exhaustive] -pub enum MaybeUtf8 { - Utf8(String), - Binary(Vec), -} - -impl MaybeUtf8 { - pub fn as_bytes(&self) -> &[u8] { - match self { - MaybeUtf8::Utf8(v) => v.as_bytes(), - MaybeUtf8::Binary(v) => v, - } - } - pub fn as_os_str(&self) -> &OsStr { - #![allow(unreachable_code)] - #[cfg(unix)] - { - return std::os::unix::ffi::OsStrExt::from_bytes(self.as_bytes()); - } - #[cfg(target_os = "wasi")] - { - return std::os::wasi::ffi::OsStrExt::from_bytes(self.as_bytes()); - } - // implementing WTF-8 is too much of a pain so don't have a special case for windows - if let Ok(s) = str::from_utf8(self.as_bytes()) { - return OsStr::new(s); - } - panic!("invalid UTF-8 conversion to OsStr is not implemented on this platform"); - } - pub fn as_path(&self) -> &Path { - Path::new(self.as_os_str()) - } -} - -#[derive(Serialize, Deserialize)] -#[serde(rename = "MaybeUtf8")] -enum MaybeUtf8Serde<'a> { - Utf8(Cow<'a, str>), - Binary(String), -} - -impl<'de> Deserialize<'de> for MaybeUtf8 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Ok(match MaybeUtf8Serde::deserialize(deserializer)? { - MaybeUtf8Serde::Utf8(v) => Self::Utf8(v.into_owned()), - MaybeUtf8Serde::Binary(v) => BASE64_URL_SAFE_NO_PAD - .decode(&*v) - .map_err(D::Error::custom)? - .into(), - }) - } -} - -impl Serialize for MaybeUtf8 { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match self { - MaybeUtf8::Utf8(v) => MaybeUtf8Serde::Utf8(Cow::Borrowed(v)), - MaybeUtf8::Binary(v) => MaybeUtf8Serde::Binary(BASE64_URL_SAFE_NO_PAD.encode(v)), - } - .serialize(serializer) - } -} - -impl From> for MaybeUtf8 { - fn from(value: Vec) -> Self { - match String::from_utf8(value) { - Ok(value) => Self::Utf8(value), - Err(e) => Self::Binary(e.into_bytes()), - } - } -} - -impl From for MaybeUtf8 { - fn from(value: String) -> Self { - Self::Utf8(value) - } -} - -impl From for MaybeUtf8 { - fn from(value: PathBuf) -> Self { - Self::from(value.into_os_string().into_encoded_bytes()) - } -} - -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)] -#[serde(rename = "File")] -pub struct ExternalJobCacheV2File<'a> { - pub name: MaybeUtf8, - pub contents: Cow<'a, MaybeUtf8>, -} - -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] -pub struct ExternalJobCacheV2Files(pub BTreeMap); - -impl Serialize for ExternalJobCacheV2Files { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_seq( - self.0 - .iter() - .map(|(name, contents)| ExternalJobCacheV2File { - name: name.clone().into(), - contents: Cow::Borrowed(contents), - }), - ) - } -} - -impl<'de> Deserialize<'de> for ExternalJobCacheV2Files { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Ok(Self( - Vec::deserialize(deserializer)? - .into_iter() - .map(|ExternalJobCacheV2File { name, contents }| { - (name.as_path().to_path_buf(), contents.into_owned()) - }) - .collect(), - )) - } -} - -#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] -#[serde(rename = "ExternalJobCache")] -pub struct ExternalJobCacheV2 { - pub version: ExternalJobCacheVersion, - pub inputs_hash: blake3::Hash, - pub stdout_stderr: String, - pub result: Result, -} - -impl ExternalJobCacheV2 { - fn read_from_file(cache_json_path: Interned) -> eyre::Result { - let cache_str = std::fs::read_to_string(&*cache_json_path) - .wrap_err_with(|| format!("can't read {cache_json_path:?}"))?; - serde_json::from_str(&cache_str) - .wrap_err_with(|| format!("can't decode {cache_json_path:?}")) - } - fn write_to_file(&self, cache_json_path: Interned) -> eyre::Result<()> { - let cache_str = serde_json::to_string_pretty(&self).expect("serialization can't fail"); - std::fs::write(&*cache_json_path, cache_str) - .wrap_err_with(|| format!("can't write {cache_json_path:?}")) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ExternalJobCaching { - cache_json_path: Interned, - run_even_if_cached: bool, -} - -#[derive(Default)] -struct JobCacheHasher(blake3::Hasher); - -impl JobCacheHasher { - fn hash_size(&mut self, size: usize) { - self.0.update(&u64::to_le_bytes( - size.try_into().expect("size should fit in u64"), - )); - } - fn hash_sized_bytes(&mut self, bytes: &[u8]) { - self.hash_size(bytes.len()); - self.0.update(bytes); - } - fn hash_sized_os_str(&mut self, s: &OsStr) { - self.hash_sized_bytes(s.as_encoded_bytes()); - } - fn hash_iter>( - &mut self, - iter: I, - mut f: F, - ) { - let iter = iter.into_iter(); - self.hash_size(iter.len()); - iter.for_each(|item| f(self, item)); - } - fn try_hash_iter< - F: FnMut(&mut Self, I::Item) -> Result<(), E>, - E, - I: IntoIterator, - >( - &mut self, - iter: I, - mut f: F, - ) -> Result<(), E> { - let mut iter = iter.into_iter(); - self.hash_size(iter.len()); - iter.try_for_each(|item| f(self, item)) - } -} - -fn write_file_atomically_no_clobber C, C: AsRef<[u8]>>( - path: impl AsRef, - containing_dir: impl AsRef, - contents: F, -) -> std::io::Result<()> { - let path = path.as_ref(); - let containing_dir = containing_dir.as_ref(); - if !matches!(std::fs::exists(&path), Ok(true)) { - // use File::create_new rather than tempfile's code to get normal file permissions rather than mode 600 on Unix. - let mut file = tempfile::Builder::new() - .make_in(containing_dir, |path| std::fs::File::create_new(path))?; - file.write_all(contents().as_ref())?; // write all in one operation to avoid a bunch of tiny writes - file.into_temp_path().persist_noclobber(path)?; - } - Ok(()) -} - -impl ExternalJobCaching { - pub fn get_cache_dir_from_output_dir(output_dir: impl AsRef) -> PathBuf { - output_dir.as_ref().join(".fayalite-job-cache") - } - pub fn make_cache_dir( - cache_dir: impl AsRef, - application_name: &str, - ) -> std::io::Result<()> { - let cache_dir = cache_dir.as_ref(); - std::fs::create_dir_all(cache_dir)?; - write_file_atomically_no_clobber(cache_dir.join("CACHEDIR.TAG"), cache_dir, || { - format!( - "Signature: 8a477f597d28d172789f06886806bc55\n\ - # This file is a cache directory tag created by {application_name}.\n\ - # For information about cache directory tags see https://bford.info/cachedir/\n" - ) - })?; - write_file_atomically_no_clobber(cache_dir.join(".gitignore"), cache_dir, || { - format!( - "# This is a cache directory created by {application_name}.\n\ - # ignore all files\n\ - *\n" - ) - }) - } - pub fn new( - output_dir: impl AsRef, - application_name: &str, - json_file_stem: impl AsRef, - run_even_if_cached: bool, - ) -> std::io::Result { - let cache_dir = Self::get_cache_dir_from_output_dir(output_dir); - Self::make_cache_dir(&cache_dir, application_name)?; - let mut cache_json_path = cache_dir; - cache_json_path.push(json_file_stem.as_ref()); - cache_json_path.set_extension("json"); - Ok(Self { - cache_json_path: Path::intern_owned(cache_json_path), - run_even_if_cached, - }) - } - fn write_stdout_stderr(stdout_stderr: &str) { - if stdout_stderr == "" { - return; - } - // use print! so output goes to Rust test output capture - if stdout_stderr.ends_with('\n') { - print!("{stdout_stderr}"); - } else { - println!("{stdout_stderr}"); - } - } - /// returns `Err(_)` if reading the cache failed, otherwise returns `Ok(_)` with the results from the cache - fn run_from_cache( - self, - inputs_hash: blake3::Hash, - output_file_paths: impl IntoIterator>, - ) -> Result, ()> { - if self.run_even_if_cached { - return Err(()); - } - let Ok(ExternalJobCacheV2 { - version: ExternalJobCacheVersion::CURRENT, - inputs_hash: cached_inputs_hash, - stdout_stderr, - result, - }) = ExternalJobCacheV2::read_from_file(self.cache_json_path) - else { - return Err(()); - }; - if inputs_hash != cached_inputs_hash { - return Err(()); - } - match result { - Ok(outputs) => { - for output_file_path in output_file_paths { - let Some(output_data) = outputs.0.get(&*output_file_path) else { - if let Ok(true) = std::fs::exists(&*output_file_path) { - // assume the existing file is the correct one - continue; - } - return Err(()); - }; - let Ok(()) = std::fs::write(&*output_file_path, output_data.as_bytes()) else { - return Err(()); - }; - } - Self::write_stdout_stderr(&stdout_stderr); - Ok(Ok(())) - } - Err(error) => { - Self::write_stdout_stderr(&stdout_stderr); - Ok(Err(error)) - } - } - } - fn make_command( - command_line: Interned<[Interned]>, - ) -> eyre::Result { - ensure!(!command_line.is_empty(), "command line must not be empty"); - let mut cmd = std::process::Command::new(&*command_line[0]); - cmd.args(command_line[1..].iter().map(|arg| &**arg)) - .stdin(std::process::Stdio::null()); - Ok(cmd) - } - pub fn run( - self, - command_line: Interned<[Interned]>, - input_file_paths: impl IntoIterator>, - output_file_paths: impl IntoIterator> + Clone, - run_fn: F, - exit_status_to_error: impl FnOnce(ExitStatus) -> eyre::Report, - ) -> eyre::Result<()> - where - F: FnOnce(std::process::Command) -> eyre::Result>, - { - let mut hasher = JobCacheHasher::default(); - hasher.hash_iter(command_line.iter(), |hasher, arg| { - hasher.hash_sized_os_str(arg) - }); - let mut input_file_paths = - Vec::<&Path>::from_iter(input_file_paths.into_iter().map(Interned::into_inner)); - input_file_paths.sort_unstable(); - input_file_paths.dedup(); - hasher.try_hash_iter( - &input_file_paths, - |hasher, input_file_path| -> eyre::Result<()> { - hasher.hash_sized_os_str(input_file_path.as_ref()); - hasher.hash_sized_bytes( - &std::fs::read(input_file_path).wrap_err_with(|| { - format!("can't read job input file: {input_file_path:?}") - })?, - ); - Ok(()) - }, - )?; - let inputs_hash = hasher.0.finalize(); - match self.run_from_cache(inputs_hash, output_file_paths.clone()) { - Ok(result) => return result.map_err(|e| eyre!(e)), - Err(()) => {} - } - let (pipe_reader, stdout, stderr) = std::io::pipe() - .and_then(|(r, w)| Ok((r, w.try_clone()?, w))) - .wrap_err_with(|| format!("when trying to create a pipe to run: {command_line:?}"))?; - let mut cmd = Self::make_command(command_line)?; - cmd.stdout(stdout).stderr(stderr); - let mut stdout_stderr = String::new(); - let result = std::thread::scope(|scope| { - std::thread::Builder::new() - .name(format!("stdout:{}", command_line[0].display())) - .spawn_scoped(scope, || { - let _ = streaming_read_utf8(std::io::BufReader::new(pipe_reader), |s| { - stdout_stderr.push_str(s); - // use print! so output goes to Rust test output capture - print!("{s}"); - std::io::Result::Ok(()) - }); - if !stdout_stderr.is_empty() && !stdout_stderr.ends_with('\n') { - println!(); - } - }) - .expect("spawn shouldn't fail"); - run_fn(cmd) - })?; - if let Err(exit_status) = result { - // check if the user may have terminated it or something, don't cache the failure - let user_maybe_terminated; - #[cfg(unix)] - { - user_maybe_terminated = std::os::unix::process::ExitStatusExt::signal(&exit_status) - .is_some() - || exit_status.code().is_none_or(|code| code > 1); - } - #[cfg(not(unix))] - { - user_maybe_terminated = !exit_status.success(); - } - if user_maybe_terminated { - let _ = std::fs::remove_file(self.cache_json_path); - return Err(exit_status_to_error(exit_status)); - } - } - let result = result.map_err(exit_status_to_error); - ExternalJobCacheV2 { - version: ExternalJobCacheVersion::CURRENT, - inputs_hash, - stdout_stderr, - result: match &result { - Ok(()) => Ok(ExternalJobCacheV2Files(Result::from_iter( - output_file_paths.into_iter().map( - |output_file_path: Interned| -> eyre::Result<_> { - let output_file_path = &*output_file_path; - Ok(( - PathBuf::from(output_file_path), - MaybeUtf8::from(std::fs::read(output_file_path).wrap_err_with( - || format!("can't read job output file: {output_file_path:?}"), - )?), - )) - }, - ), - )?)), - Err(e) => Err(format!("{e:#}")), - }, - } - .write_to_file(self.cache_json_path)?; - result - } - pub fn run_maybe_cached( - this: Option, - command_line: Interned<[Interned]>, - input_file_paths: impl IntoIterator>, - output_file_paths: impl IntoIterator> + Clone, - run_fn: F, - exit_status_to_error: impl FnOnce(ExitStatus) -> eyre::Report, - ) -> eyre::Result<()> - where - F: FnOnce(std::process::Command) -> eyre::Result>, - { - match this { - Some(this) => this.run( - command_line, - input_file_paths, - output_file_paths, - run_fn, - exit_status_to_error, - ), - None => run_fn(Self::make_command(command_line)?)?.map_err(exit_status_to_error), - } - } -} - -#[derive(Clone, Eq, Hash)] -pub struct ExternalCommandJobKind(PhantomData); - -impl fmt::Debug for ExternalCommandJobKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ExternalCommandJobKind<{}>", std::any::type_name::()) - } -} - -impl PartialEq for ExternalCommandJobKind { - fn eq(&self, _other: &Self) -> bool { - true - } -} - -impl Ord for ExternalCommandJobKind { - fn cmp(&self, _other: &Self) -> std::cmp::Ordering { - std::cmp::Ordering::Equal - } -} - -impl PartialOrd for ExternalCommandJobKind { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Default for ExternalCommandJobKind { - fn default() -> Self { - Self(PhantomData) - } -} - -impl Copy for ExternalCommandJobKind {} - -impl ExternalCommandJobKind { - pub const fn new() -> Self { - Self(PhantomData) - } -} - -#[derive(Copy, Clone)] -struct ExternalProgramPathValueParser(ExternalProgram); - -fn parse_which_result( - which_result: which::Result, - program_name: impl Into, - program_path_arg_name: impl FnOnce() -> String, -) -> Result, ResolveProgramPathError> { - let which_result = match which_result { - Ok(v) => v, - Err(inner) => { - return Err(ResolveProgramPathError { - inner, - program_name: program_name.into(), - program_path_arg_name: program_path_arg_name(), - }); - } - }; - Ok(which_result.intern_deref()) -} - -impl clap::builder::TypedValueParser for ExternalProgramPathValueParser { - type Value = Interned; - - fn parse_ref( - &self, - cmd: &clap::Command, - arg: Option<&clap::Arg>, - value: &OsStr, - ) -> clap::error::Result { - let program_path_arg_name = self.0.program_path_arg_name; - OsStringValueParser::new() - .try_map(move |program_name| { - parse_which_result(which::which(&program_name), program_name, || { - program_path_arg_name.into() - }) - }) - .parse_ref(cmd, arg, value) - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -#[group(id = T::args_group_id())] -#[non_exhaustive] -pub struct ExternalCommandArgs { - #[command(flatten)] - pub program_path: ExternalProgramPath, - #[arg( - name = Interned::into_inner(T::run_even_if_cached_arg_name()), - long = T::run_even_if_cached_arg_name(), - )] - pub run_even_if_cached: bool, - #[command(flatten)] - pub additional_args: T::AdditionalArgs, -} - -#[derive(Clone, Debug)] -pub struct ResolveProgramPathError { - inner: which::Error, - program_name: OsString, - program_path_arg_name: String, -} - -impl fmt::Display for ResolveProgramPathError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - inner, - program_name, - program_path_arg_name, - } = self; - write!( - f, - "{program_path_arg_name}: failed to resolve {program_name:?} to a valid program: {inner}", - ) - } -} - -impl std::error::Error for ResolveProgramPathError {} - -pub fn resolve_program_path( - program_name: Option<&OsStr>, - default_program_name: impl AsRef, - program_path_env_var_name: Option<&OsStr>, -) -> Result, ResolveProgramPathError> { - let default_program_name = default_program_name.as_ref(); - let owned_program_name; - let program_name = if let Some(program_name) = program_name { - program_name - } else if let Some(v) = program_path_env_var_name.and_then(std::env::var_os) { - owned_program_name = v; - &owned_program_name - } else { - default_program_name - }; - parse_which_result(which::which(program_name), program_name, || { - default_program_name.display().to_string() - }) -} - -impl ExternalCommandArgs { - pub fn with_resolved_program_path( - program_path: Interned, - additional_args: T::AdditionalArgs, - ) -> Self { - Self::new( - ExternalProgramPath::with_resolved_program_path(program_path), - additional_args, - ) - } - pub fn new( - program_path: ExternalProgramPath, - additional_args: T::AdditionalArgs, - ) -> Self { - Self { - program_path, - run_even_if_cached: false, - additional_args, - } - } - pub fn resolve_program_path( - program_name: Option<&OsStr>, - additional_args: T::AdditionalArgs, - ) -> Result { - Ok(Self::new( - ExternalProgramPath::resolve_program_path(program_name)?, - additional_args, - )) - } -} - -impl ToArgs for ExternalCommandArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { - program_path, - run_even_if_cached, - ref additional_args, - } = *self; - program_path.to_args(args); - if run_even_if_cached { - args.write_display_arg(format_args!("--{}", T::run_even_if_cached_arg_name())); - } - additional_args.to_args(args); - } -} - -#[derive(Copy, Clone)] -struct ExternalCommandJobParams { - command_params: CommandParams, - inputs: Interned<[JobItemName]>, - outputs: Interned<[JobItemName]>, - output_paths: Interned<[Interned]>, -} - -impl ExternalCommandJobParams { - fn new(job: &ExternalCommandJob) -> Self { - let output_paths = T::output_paths(job); - let mut command_line = ArgsWriter(vec![job.program_path.as_interned_os_str()]); - T::command_line_args(job, &mut command_line); - Self { - command_params: CommandParams { - command_line: Intern::intern_owned(command_line.0), - current_dir: T::current_dir(job), - }, - inputs: T::inputs(job), - outputs: output_paths - .iter() - .map(|&path| JobItemName::Path { path }) - .collect(), - output_paths, - } - } -} - -#[derive(Deserialize, Serialize)] -pub struct ExternalCommandJob { - additional_job_data: T::AdditionalJobData, - program_path: Interned, - output_dir: Interned, - run_even_if_cached: bool, - #[serde(skip)] - params_cache: OnceLock, -} - -impl Eq for ExternalCommandJob {} - -impl> Clone for ExternalCommandJob { - fn clone(&self) -> Self { - let Self { - ref additional_job_data, - program_path, - output_dir, - run_even_if_cached, - ref params_cache, - } = *self; - Self { - additional_job_data: additional_job_data.clone(), - program_path, - output_dir, - run_even_if_cached, - params_cache: params_cache.clone(), - } - } -} - -impl fmt::Debug for ExternalCommandJob { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - additional_job_data, - program_path, - output_dir, - run_even_if_cached, - params_cache: _, - } = self; - write!(f, "ExternalCommandJob<{}>", std::any::type_name::())?; - f.debug_struct("") - .field("additional_job_data", additional_job_data) - .field("program_path", program_path) - .field("output_dir", output_dir) - .field("run_even_if_cached", run_even_if_cached) - .finish() - } -} - -impl PartialEq for ExternalCommandJob { - fn eq(&self, other: &Self) -> bool { - let Self { - additional_job_data, - program_path, - output_dir, - run_even_if_cached, - params_cache: _, - } = self; - *additional_job_data == other.additional_job_data - && *program_path == other.program_path - && *output_dir == other.output_dir - && *run_even_if_cached == other.run_even_if_cached - } -} - -impl Hash for ExternalCommandJob { - fn hash(&self, state: &mut H) { - let Self { - additional_job_data, - program_path, - output_dir, - run_even_if_cached, - params_cache: _, - } = self; - additional_job_data.hash(state); - program_path.hash(state); - output_dir.hash(state); - run_even_if_cached.hash(state); - } -} - -impl ExternalCommandJob { - pub fn additional_job_data(&self) -> &T::AdditionalJobData { - &self.additional_job_data - } - pub fn program_path(&self) -> Interned { - self.program_path - } - pub fn output_dir(&self) -> Interned { - self.output_dir - } - pub fn run_even_if_cached(&self) -> bool { - self.run_even_if_cached - } - fn params(&self) -> &ExternalCommandJobParams { - self.params_cache - .get_or_init(|| ExternalCommandJobParams::new(self)) - } - pub fn command_params(&self) -> CommandParams { - self.params().command_params - } - pub fn inputs(&self) -> Interned<[JobItemName]> { - self.params().inputs - } - pub fn output_paths(&self) -> Interned<[Interned]> { - self.params().output_paths - } - pub fn outputs(&self) -> Interned<[JobItemName]> { - self.params().outputs - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub struct ExternalProgramPath { - program_path: Interned, - _phantom: PhantomData, -} - -impl ExternalProgramPath { - pub fn with_resolved_program_path(program_path: Interned) -> Self { - Self { - program_path, - _phantom: PhantomData, - } - } - pub fn resolve_program_path( - program_name: Option<&OsStr>, - ) -> Result { - let ExternalProgram { - default_program_name, - program_path_arg_name: _, - program_path_arg_value_name: _, - program_path_env_var_name, - } = ExternalProgram::new::(); - Ok(Self { - program_path: resolve_program_path( - program_name, - default_program_name, - program_path_env_var_name.as_ref().map(OsStr::new), - )?, - _phantom: PhantomData, - }) - } - pub fn program_path(&self) -> Interned { - self.program_path - } -} - -impl fmt::Debug for ExternalProgramPath { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - program_path, - _phantom: _, - } = self; - write!(f, "ExternalProgramPath<{}>", std::any::type_name::())?; - f.debug_tuple("").field(program_path).finish() - } -} - -impl clap::FromArgMatches for ExternalProgramPath { - fn from_arg_matches(matches: &clap::ArgMatches) -> Result { - let id = Interned::into_inner(ExternalProgram::new::().program_path_arg_name); - // don't remove argument so later instances of Self can use it too - let program_path = *matches.get_one(id).expect("arg should always be present"); - Ok(Self { - program_path, - _phantom: PhantomData, - }) - } - - fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> Result<(), clap::Error> { - *self = Self::from_arg_matches(matches)?; - Ok(()) - } -} - -impl clap::Args for ExternalProgramPath { - fn augment_args(cmd: clap::Command) -> clap::Command { - let external_program @ ExternalProgram { - default_program_name, - program_path_arg_name, - program_path_arg_value_name, - program_path_env_var_name, - } = ExternalProgram::new::(); - let arg = cmd - .get_arguments() - .find(|arg| *arg.get_id().as_str() == *program_path_arg_name); - if let Some(arg) = arg { - // don't insert duplicate arguments. - // check that the previous argument actually matches this argument: - assert!(!arg.is_required_set()); - assert!(matches!(arg.get_action(), clap::ArgAction::Set)); - assert_eq!(arg.get_long(), Some(&*program_path_arg_name)); - assert_eq!( - arg.get_value_names(), - Some(&[clap::builder::Str::from(program_path_arg_value_name)][..]) - ); - assert_eq!( - arg.get_env(), - program_path_env_var_name.as_ref().map(OsStr::new) - ); - assert_eq!( - arg.get_default_values(), - &[OsStr::new(&default_program_name)] - ); - assert_eq!(arg.get_value_hint(), clap::ValueHint::CommandName); - cmd - } else { - cmd.arg( - clap::Arg::new(Interned::into_inner(program_path_arg_name)) - .required(false) - .value_parser(ExternalProgramPathValueParser(external_program)) - .action(clap::ArgAction::Set) - .long(program_path_arg_name) - .value_name(program_path_arg_value_name) - .env(program_path_env_var_name.map(Interned::into_inner)) - .default_value(default_program_name) - .value_hint(clap::ValueHint::CommandName), - ) - } - } - - fn augment_args_for_update(cmd: clap::Command) -> clap::Command { - Self::augment_args(cmd) - } -} - -impl ToArgs for ExternalProgramPath { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let ExternalProgram { - program_path_arg_name, - .. - } = ExternalProgram::new::(); - let Self { - program_path, - _phantom: _, - } = self; - if args.get_long_option_eq(program_path_arg_name) != Some(program_path.as_os_str()) { - args.write_long_option_eq(program_path_arg_name, program_path); - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -#[non_exhaustive] -pub struct ExternalProgram { - default_program_name: Interned, - program_path_arg_name: Interned, - program_path_arg_value_name: Interned, - program_path_env_var_name: Option>, -} - -impl ExternalProgram { - pub fn new() -> Self { - Self { - default_program_name: T::default_program_name(), - program_path_arg_name: T::program_path_arg_name(), - program_path_arg_value_name: T::program_path_arg_value_name(), - program_path_env_var_name: T::program_path_env_var_name(), - } - } - pub fn default_program_name(&self) -> Interned { - self.default_program_name - } - pub fn program_path_arg_name(&self) -> Interned { - self.program_path_arg_name - } - pub fn program_path_arg_value_name(&self) -> Interned { - self.program_path_arg_value_name - } - pub fn program_path_env_var_name(&self) -> Option> { - self.program_path_env_var_name - } -} - -impl From for ExternalProgram { - fn from(_value: T) -> Self { - Self::new::() - } -} - -impl From for Interned { - fn from(_value: T) -> Self { - ExternalProgram::new::().intern_sized() - } -} - -pub trait ExternalProgramTrait: - 'static + Send + Sync + Hash + Ord + fmt::Debug + Default + Copy -{ - fn program_path_arg_name() -> Interned { - Self::default_program_name() - } - fn program_path_arg_value_name() -> Interned { - Intern::intern_owned(Self::program_path_arg_name().to_uppercase()) - } - fn default_program_name() -> Interned; - fn program_path_env_var_name() -> Option> { - Some(Intern::intern_owned( - Self::program_path_arg_name() - .to_uppercase() - .replace('-', "_"), - )) - } -} - -pub trait ExternalCommand: 'static + Send + Sync + Hash + Eq + fmt::Debug + Sized + Clone { - type AdditionalArgs: ToArgs; - type AdditionalJobData: 'static - + Send - + Sync - + Hash - + Eq - + fmt::Debug - + Serialize - + DeserializeOwned; - type BaseJobPosition; - type Dependencies: JobDependenciesHasBase; - type ExternalProgram: ExternalProgramTrait; - fn dependencies() -> Self::Dependencies; - fn args_to_jobs( - args: JobArgsAndDependencies>, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<( - Self::AdditionalJobData, - ::JobsAndKinds, - )>; - fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]>; - fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]>; - fn command_line_args(job: &ExternalCommandJob, args: &mut W); - fn current_dir(job: &ExternalCommandJob) -> Option>; - fn job_kind_name() -> Interned; - fn args_group_id() -> clap::Id { - Interned::into_inner(Self::job_kind_name()).into() - } - fn run_even_if_cached_arg_name() -> Interned { - Intern::intern_owned(format!("{}-run-even-if-cached", Self::job_kind_name())) - } - fn subcommand_hidden() -> bool { - false - } -} - -impl JobKind for ExternalCommandJobKind { - type Args = ExternalCommandArgs; - type Job = ExternalCommandJob; - type Dependencies = T::Dependencies; - - fn dependencies(self) -> Self::Dependencies { - T::dependencies() - } - - fn args_to_jobs( - args: JobArgsAndDependencies, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - let JobKindAndArgs { - kind, - args: - ExternalCommandArgs { - program_path: - ExternalProgramPath { - program_path, - _phantom: _, - }, - run_even_if_cached, - additional_args: _, - }, - } = args.args; - let (additional_job_data, dependencies) = T::args_to_jobs(args, params, global_params)?; - let base_job = T::Dependencies::base_job(&dependencies); - let job = ExternalCommandJob { - additional_job_data, - program_path, - output_dir: base_job.output_dir(), - run_even_if_cached: base_job.run_even_if_cached() | run_even_if_cached, - params_cache: OnceLock::new(), - }; - job.params(); // fill cache - Ok(JobAndDependencies { - job: JobAndKind { kind, job }, - dependencies, - }) - } - - fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - job.inputs() - } - - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - job.outputs() - } - - fn name(self) -> Interned { - T::job_kind_name() - } - - fn external_command_params(self, job: &Self::Job) -> Option { - Some(job.command_params()) - } - - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - _params: &JobParams, - global_params: &GlobalParams, - acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - assert!( - inputs.iter().map(JobItem::name).eq(job.inputs()), - "{}\ninputs:\n{inputs:?}\njob.inputs():\n{:?}", - std::any::type_name::(), - job.inputs(), - ); - let CommandParams { - command_line, - current_dir, - } = job.command_params(); - ExternalJobCaching::new( - &job.output_dir, - &global_params.application_name(), - &T::job_kind_name(), - job.run_even_if_cached, - )? - .run( - command_line, - inputs - .iter() - .flat_map(|item| match item { - JobItem::Path { path } => std::slice::from_ref(path), - JobItem::DynamicPaths { - paths, - source_job_name: _, - } => paths, - }) - .copied(), - job.output_paths(), - |mut cmd| { - if let Some(current_dir) = current_dir { - cmd.current_dir(current_dir); - } - let status = acquired_job.run_command(cmd, |cmd| cmd.status())?; - if !status.success() { - Ok(Err(status)) - } else { - Ok(Ok(())) - } - }, - |status| eyre!("running {command_line:?} failed: {status}"), - )?; - Ok(job - .output_paths() - .iter() - .map(|&path| JobItem::Path { path }) - .collect()) - } - - fn subcommand_hidden(self) -> bool { - T::subcommand_hidden() - } - - fn external_program(self) -> Option> { - Some(ExternalProgram::new::().intern_sized()) - } -} diff --git a/crates/fayalite/src/build/firrtl.rs b/crates/fayalite/src/build/firrtl.rs deleted file mode 100644 index b5574a9..0000000 --- a/crates/fayalite/src/build/firrtl.rs +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - build::{ - BaseJob, BaseJobKind, CommandParams, DynJobKind, GlobalParams, JobAndDependencies, - JobArgsAndDependencies, JobItem, JobItemName, JobKind, JobKindAndDependencies, JobParams, - ToArgs, WriteArgs, - }, - firrtl::{ExportOptions, FileBackend}, - intern::{Intern, InternSlice, Interned}, - util::job_server::AcquiredJob, -}; -use clap::Args; -use serde::{Deserialize, Serialize}; -use std::path::{Path, PathBuf}; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)] -pub struct FirrtlJobKind; - -#[derive(Args, Debug, Clone, Hash, PartialEq, Eq)] -#[group(id = "Firrtl")] -#[non_exhaustive] -pub struct FirrtlArgs { - #[command(flatten)] - pub export_options: ExportOptions, -} - -impl ToArgs for FirrtlArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { export_options } = self; - export_options.to_args(args); - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct Firrtl { - base: BaseJob, - export_options: ExportOptions, -} - -impl Firrtl { - fn make_firrtl_file_backend(&self) -> FileBackend { - FileBackend { - dir_path: PathBuf::from(&*self.base.output_dir()), - top_fir_file_stem: Some(self.base.file_stem().into()), - circuit_name: None, - } - } - pub fn firrtl_file(&self) -> Interned { - self.base.file_with_ext("fir") - } -} - -impl JobKind for FirrtlJobKind { - type Args = FirrtlArgs; - type Job = Firrtl; - type Dependencies = JobKindAndDependencies; - - fn dependencies(self) -> Self::Dependencies { - JobKindAndDependencies::new(BaseJobKind) - } - - fn args_to_jobs( - args: JobArgsAndDependencies, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - args.args_to_jobs_simple( - params, - global_params, - |_kind, FirrtlArgs { export_options }, dependencies| { - Ok(Firrtl { - base: dependencies.get_job::().clone(), - export_options, - }) - }, - ) - } - - fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { - path: job.base.output_dir(), - }] - .intern_slice() - } - - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { - path: job.firrtl_file(), - }] - .intern_slice() - } - - fn name(self) -> Interned { - "firrtl".intern() - } - - fn external_command_params(self, _job: &Self::Job) -> Option { - None - } - - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - params: &JobParams, - _global_params: &GlobalParams, - _acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - let [JobItem::Path { path: input_path }] = *inputs else { - panic!("wrong inputs, expected a single `Path`"); - }; - assert_eq!(input_path, job.base.output_dir()); - crate::firrtl::export( - job.make_firrtl_file_backend(), - params.main_module(), - job.export_options, - )?; - Ok(vec![JobItem::Path { - path: job.firrtl_file(), - }]) - } -} - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - [DynJobKind::new(FirrtlJobKind)] -} diff --git a/crates/fayalite/src/build/formal.rs b/crates/fayalite/src/build/formal.rs deleted file mode 100644 index 69c0f2c..0000000 --- a/crates/fayalite/src/build/formal.rs +++ /dev/null @@ -1,388 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - build::{ - BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GlobalParams, - JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind, - JobKindAndDependencies, JobParams, ToArgs, WriteArgs, - external::{ - ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait, - }, - verilog::{UnadjustedVerilog, VerilogDialect, VerilogJob, VerilogJobKind}, - }, - intern::{Intern, InternSlice, Interned}, - module::NameId, - testing::FormalMode, - util::job_server::AcquiredJob, -}; -use clap::Args; -use eyre::Context; -use serde::{Deserialize, Serialize}; -use std::{ - ffi::{OsStr, OsString}, - fmt::{self, Write}, - path::Path, -}; - -#[derive(Args, Clone, Debug, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub struct FormalArgs { - #[arg(long = "sby-extra-arg", value_name = "ARG")] - pub sby_extra_args: Vec, - #[arg(long, default_value_t)] - pub formal_mode: FormalMode, - #[arg(long, default_value_t = Self::DEFAULT_DEPTH)] - pub formal_depth: u64, - #[arg(long, default_value = Self::DEFAULT_SOLVER)] - pub formal_solver: String, - #[arg(long = "smtbmc-extra-arg", value_name = "ARG")] - pub smtbmc_extra_args: Vec, -} - -impl FormalArgs { - pub const DEFAULT_DEPTH: u64 = 20; - pub const DEFAULT_SOLVER: &'static str = "z3"; -} - -impl ToArgs for FormalArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { - sby_extra_args, - formal_mode, - formal_depth, - formal_solver, - smtbmc_extra_args, - } = self; - for arg in sby_extra_args { - args.write_long_option_eq("sby-extra-arg", arg); - } - args.write_display_args([ - format_args!("--formal-mode={formal_mode}"), - format_args!("--formal-depth={formal_depth}"), - format_args!("--formal-solver={formal_solver}"), - ]); - for arg in smtbmc_extra_args { - args.write_long_option_eq("smtbmc-extra-arg", arg); - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -pub struct WriteSbyFileJobKind; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] -pub struct WriteSbyFileJob { - sby_extra_args: Interned<[Interned]>, - formal_mode: FormalMode, - formal_depth: u64, - formal_solver: Interned, - smtbmc_extra_args: Interned<[Interned]>, - sby_file: Interned, - output_dir: Interned, - main_verilog_file: Interned, -} - -impl WriteSbyFileJob { - pub fn sby_extra_args(&self) -> Interned<[Interned]> { - self.sby_extra_args - } - pub fn formal_mode(&self) -> FormalMode { - self.formal_mode - } - pub fn formal_depth(&self) -> u64 { - self.formal_depth - } - pub fn formal_solver(&self) -> Interned { - self.formal_solver - } - pub fn smtbmc_extra_args(&self) -> Interned<[Interned]> { - self.smtbmc_extra_args - } - pub fn sby_file(&self) -> Interned { - self.sby_file - } - pub fn output_dir(&self) -> Interned { - self.output_dir - } - pub fn main_verilog_file(&self) -> Interned { - self.main_verilog_file - } - fn write_sby( - &self, - output: &mut OsString, - additional_files: &[Interned], - main_module_name_id: NameId, - ) -> eyre::Result<()> { - let Self { - sby_extra_args: _, - formal_mode, - formal_depth, - formal_solver, - smtbmc_extra_args, - sby_file: _, - output_dir: _, - main_verilog_file, - } = self; - write!( - output, - "[options]\n\ - mode {formal_mode}\n\ - depth {formal_depth}\n\ - wait on\n\ - \n\ - [engines]\n\ - smtbmc {formal_solver} -- --" - ) - .expect("writing to OsString can't fail"); - for i in smtbmc_extra_args { - output.push(" "); - output.push(i); - } - output.push( - "\n\ - \n\ - [script]\n", - ); - for verilog_file in VerilogJob::all_verilog_files(*main_verilog_file, additional_files)? { - output.push("read_verilog -sv -formal \""); - output.push(verilog_file); - output.push("\"\n"); - } - let circuit_name = crate::firrtl::get_circuit_name(main_module_name_id); - // workaround for wires disappearing -- set `keep` on all wires - writeln!( - output, - "hierarchy -top {circuit_name}\n\ - proc\n\ - setattr -set keep 1 w:\\*\n\ - prep", - ) - .expect("writing to OsString can't fail"); - Ok(()) - } -} - -impl JobKind for WriteSbyFileJobKind { - type Args = FormalArgs; - type Job = WriteSbyFileJob; - type Dependencies = JobKindAndDependencies; - - fn dependencies(self) -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - mut args: JobArgsAndDependencies, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - args.dependencies - .dependencies - .args - .args - .additional_args - .verilog_dialect - .get_or_insert(VerilogDialect::Yosys); - args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { - let FormalArgs { - sby_extra_args, - formal_mode, - formal_depth, - formal_solver, - smtbmc_extra_args, - } = args; - let base_job = dependencies.get_job::(); - Ok(WriteSbyFileJob { - sby_extra_args: sby_extra_args.into_iter().map(Interned::from).collect(), - formal_mode, - formal_depth, - formal_solver: formal_solver.intern_deref(), - smtbmc_extra_args: smtbmc_extra_args.into_iter().map(Interned::from).collect(), - sby_file: base_job.file_with_ext("sby"), - output_dir: base_job.output_dir(), - main_verilog_file: dependencies.get_job::().main_verilog_file(), - }) - }) - } - - fn inputs(self, _job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::DynamicPaths { - source_job_name: VerilogJobKind.name(), - }] - .intern_slice() - } - - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { path: job.sby_file }].intern_slice() - } - - fn name(self) -> Interned { - "write-sby-file".intern() - } - - fn external_command_params(self, _job: &Self::Job) -> Option { - None - } - - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - params: &JobParams, - _global_params: &GlobalParams, - _acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job))); - let [additional_files] = inputs else { - unreachable!(); - }; - let additional_files = VerilogJob::unwrap_additional_files(additional_files); - let mut contents = OsString::new(); - job.write_sby( - &mut contents, - additional_files, - params.main_module().name_id(), - )?; - let path = job.sby_file; - std::fs::write(path, contents.as_encoded_bytes()) - .wrap_err_with(|| format!("writing {path:?} failed"))?; - Ok(vec![JobItem::Path { path }]) - } - - fn subcommand_hidden(self) -> bool { - true - } -} - -#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize)] -pub struct Formal { - #[serde(flatten)] - write_sby_file: WriteSbyFileJob, - sby_file_name: Interned, -} - -impl fmt::Debug for Formal { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - write_sby_file: - WriteSbyFileJob { - sby_extra_args, - formal_mode, - formal_depth, - formal_solver, - smtbmc_extra_args, - sby_file, - output_dir: _, - main_verilog_file, - }, - sby_file_name, - } = self; - f.debug_struct("Formal") - .field("sby_extra_args", sby_extra_args) - .field("formal_mode", formal_mode) - .field("formal_depth", formal_depth) - .field("formal_solver", formal_solver) - .field("smtbmc_extra_args", smtbmc_extra_args) - .field("sby_file", sby_file) - .field("sby_file_name", sby_file_name) - .field("main_verilog_file", main_verilog_file) - .finish_non_exhaustive() - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] -pub struct Symbiyosys; - -impl ExternalProgramTrait for Symbiyosys { - fn default_program_name() -> Interned { - "sby".intern() - } -} - -#[derive(Clone, Hash, PartialEq, Eq, Debug, Args)] -pub struct FormalAdditionalArgs {} - -impl ToArgs for FormalAdditionalArgs { - fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { - let Self {} = self; - } -} - -impl ExternalCommand for Formal { - type AdditionalArgs = FormalAdditionalArgs; - type AdditionalJobData = Formal; - type BaseJobPosition = GetJobPositionDependencies< - GetJobPositionDependencies< - GetJobPositionDependencies<::BaseJobPosition>, - >, - >; - type Dependencies = JobKindAndDependencies; - type ExternalProgram = Symbiyosys; - - fn dependencies() -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - args: JobArgsAndDependencies>, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<( - Self::AdditionalJobData, - ::JobsAndKinds, - )> { - args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { - let FormalAdditionalArgs {} = args.additional_args; - let write_sby_file = dependencies.get_job::().clone(); - Ok(Formal { - sby_file_name: write_sby_file - .sby_file() - .interned_file_name() - .expect("known to have file name"), - write_sby_file, - }) - }) - } - - fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { - [ - JobItemName::Path { - path: job.additional_job_data().write_sby_file.sby_file(), - }, - JobItemName::Path { - path: job.additional_job_data().write_sby_file.main_verilog_file(), - }, - JobItemName::DynamicPaths { - source_job_name: VerilogJobKind.name(), - }, - ] - .intern_slice() - } - - fn output_paths(_job: &ExternalCommandJob) -> Interned<[Interned]> { - Interned::default() - } - - fn command_line_args(job: &ExternalCommandJob, args: &mut W) { - // args.write_str_arg("-j1"); // sby seems not to respect job count in parallel mode - args.write_arg("-f"); - args.write_interned_arg(job.additional_job_data().sby_file_name); - args.write_interned_args(job.additional_job_data().write_sby_file.sby_extra_args()); - } - - fn current_dir(job: &ExternalCommandJob) -> Option> { - Some(job.output_dir()) - } - - fn job_kind_name() -> Interned { - "formal".intern() - } -} - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - [ - DynJobKind::new(WriteSbyFileJobKind), - DynJobKind::new(ExternalCommandJobKind::::new()), - ] -} diff --git a/crates/fayalite/src/build/graph.rs b/crates/fayalite/src/build/graph.rs deleted file mode 100644 index bed8829..0000000 --- a/crates/fayalite/src/build/graph.rs +++ /dev/null @@ -1,855 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - build::{ - DynJob, GlobalParams, JobItem, JobItemName, JobParams, program_name_for_internal_jobs, - }, - intern::Interned, - platform::DynPlatform, - util::{HashMap, HashSet, job_server::AcquiredJob}, -}; -use eyre::{ContextCompat, eyre}; -use petgraph::{ - algo::{DfsSpace, kosaraju_scc, toposort}, - graph::DiGraph, - visit::{GraphBase, Visitable}, -}; -use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error, ser::SerializeSeq}; -use std::{ - cell::OnceCell, - collections::{BTreeMap, BTreeSet, VecDeque}, - convert::Infallible, - ffi::OsStr, - fmt::{self, Write}, - panic, - rc::Rc, - str::Utf8Error, - sync::mpsc, - thread::{self, ScopedJoinHandle}, -}; - -macro_rules! write_str { - ($s:expr, $($rest:tt)*) => { - write!($s, $($rest)*).expect("String::write_fmt can't fail") - }; -} - -#[derive(Clone, Debug)] -enum JobGraphNode { - Job(DynJob), - Item { - #[allow(dead_code, reason = "name used for debugging")] - name: JobItemName, - source_job: Option, - }, -} - -type JobGraphInner = DiGraph; - -#[derive(Clone, Default)] -pub struct JobGraph { - jobs: HashMap::NodeId>, - items: HashMap::NodeId>, - graph: JobGraphInner, - topological_order: Vec<::NodeId>, - space: DfsSpace<::NodeId, ::Map>, -} - -impl fmt::Debug for JobGraph { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - jobs: _, - items: _, - graph, - topological_order, - space: _, - } = self; - f.debug_struct("JobGraph") - .field("graph", graph) - .field("topological_order", topological_order) - .finish_non_exhaustive() - } -} - -#[derive(Clone, Debug)] -pub enum JobGraphError { - CycleError { - job: DynJob, - output: JobItemName, - }, - MultipleJobsCreateSameOutput { - output_item: JobItemName, - existing_job: DynJob, - new_job: DynJob, - }, -} - -impl std::error::Error for JobGraphError {} - -impl fmt::Display for JobGraphError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::CycleError { job, output } => write!( - f, - "job can't be added to job graph because it would introduce a cyclic dependency through this job output:\n\ - {output:?}\n\ - job:\n{job:?}", - ), - JobGraphError::MultipleJobsCreateSameOutput { - output_item, - existing_job, - new_job, - } => write!( - f, - "job can't be added to job graph because the new job has an output that is also produced by an existing job.\n\ - conflicting output:\n\ - {output_item:?}\n\ - existing job:\n\ - {existing_job:?}\n\ - new job:\n\ - {new_job:?}", - ), - } - } -} - -#[derive(Copy, Clone, Debug)] -enum EscapeForUnixShellState { - DollarSingleQuote, - SingleQuote, - Unquoted, -} - -#[derive(Clone)] -pub struct EscapeForUnixShell<'a> { - state: EscapeForUnixShellState, - prefix: [u8; 3], - bytes: &'a [u8], -} - -impl<'a> fmt::Debug for EscapeForUnixShell<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl<'a> fmt::Display for EscapeForUnixShell<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for c in self.clone() { - f.write_char(c)?; - } - Ok(()) - } -} - -impl<'a> EscapeForUnixShell<'a> { - pub fn new(s: &'a (impl ?Sized + AsRef)) -> Self { - Self::from_bytes(s.as_ref().as_encoded_bytes()) - } - fn make_prefix(bytes: &[u8]) -> [u8; 3] { - let mut prefix = [0; 3]; - prefix[..bytes.len()].copy_from_slice(bytes); - prefix - } - pub fn from_bytes(bytes: &'a [u8]) -> Self { - let mut needs_single_quote = bytes.is_empty(); - for &b in bytes { - match b { - b'!' | b'\'' | b'\"' | b' ' => needs_single_quote = true, - 0..0x20 | 0x7F.. => { - return Self { - state: EscapeForUnixShellState::DollarSingleQuote, - prefix: Self::make_prefix(b"$'"), - bytes, - }; - } - _ => {} - } - } - if needs_single_quote { - Self { - state: EscapeForUnixShellState::SingleQuote, - prefix: Self::make_prefix(b"'"), - bytes, - } - } else { - Self { - state: EscapeForUnixShellState::Unquoted, - prefix: Self::make_prefix(b""), - bytes, - } - } - } -} - -impl Iterator for EscapeForUnixShell<'_> { - type Item = char; - - fn next(&mut self) -> Option { - match &mut self.prefix { - [0, 0, 0] => {} - [0, 0, v] | // find first - [0, v, _] | // non-zero byte - [v, _, _] => { - let retval = *v as char; - *v = 0; - return Some(retval); - } - } - let Some(&next_byte) = self.bytes.split_off_first() else { - return match self.state { - EscapeForUnixShellState::DollarSingleQuote - | EscapeForUnixShellState::SingleQuote => { - self.state = EscapeForUnixShellState::Unquoted; - Some('\'') - } - EscapeForUnixShellState::Unquoted => None, - }; - }; - match self.state { - EscapeForUnixShellState::DollarSingleQuote => match next_byte { - b'\'' | b'\\' => { - self.prefix = Self::make_prefix(&[next_byte]); - Some('\\') - } - b'\t' => { - self.prefix = Self::make_prefix(b"t"); - Some('\\') - } - b'\n' => { - self.prefix = Self::make_prefix(b"n"); - Some('\\') - } - b'\r' => { - self.prefix = Self::make_prefix(b"r"); - Some('\\') - } - 0x20..=0x7E => Some(next_byte as char), - _ => { - self.prefix = [ - b'x', - char::from_digit(next_byte as u32 >> 4, 0x10).expect("known to be in range") - as u8, - char::from_digit(next_byte as u32 & 0xF, 0x10) - .expect("known to be in range") as u8, - ]; - Some('\\') - } - }, - EscapeForUnixShellState::SingleQuote => { - if next_byte == b'\'' { - self.prefix = Self::make_prefix(b"\\''"); - Some('\'') - } else { - Some(next_byte as char) - } - } - EscapeForUnixShellState::Unquoted => match next_byte { - b' ' | b'!' | b'"' | b'#' | b'$' | b'&' | b'\'' | b'(' | b')' | b'*' | b',' - | b';' | b'<' | b'>' | b'?' | b'[' | b'\\' | b']' | b'^' | b'`' | b'{' | b'|' - | b'}' | b'~' => { - self.prefix = Self::make_prefix(&[next_byte]); - Some('\\') - } - _ => Some(next_byte as char), - }, - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -#[non_exhaustive] -pub enum UnixMakefileEscapeKind { - NonRecipe, - RecipeWithoutShellEscaping, - RecipeWithShellEscaping, -} - -#[derive(Copy, Clone)] -pub struct EscapeForUnixMakefile<'a> { - s: &'a OsStr, - kind: UnixMakefileEscapeKind, -} - -impl<'a> fmt::Debug for EscapeForUnixMakefile<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl<'a> fmt::Display for EscapeForUnixMakefile<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.do_write( - f, - fmt::Write::write_str, - fmt::Write::write_char, - |_, _| Ok(()), - |_| unreachable!("already checked that the input causes no UTF-8 errors"), - ) - } -} - -impl<'a> EscapeForUnixMakefile<'a> { - fn do_write( - &self, - state: &mut S, - write_str: impl Fn(&mut S, &str) -> Result<(), E>, - write_char: impl Fn(&mut S, char) -> Result<(), E>, - add_variable: impl Fn(&mut S, &'static str) -> Result<(), E>, - utf8_error: impl Fn(Utf8Error) -> E, - ) -> Result<(), E> { - let escape_recipe_char = |c| match c { - '$' => write_str(state, "$$"), - '\0'..='\x1F' | '\x7F' => { - panic!("can't escape a control character for Unix Makefile: {c:?}"); - } - _ => write_char(state, c), - }; - match self.kind { - UnixMakefileEscapeKind::NonRecipe => str::from_utf8(self.s.as_encoded_bytes()) - .map_err(&utf8_error)? - .chars() - .try_for_each(|c| match c { - '=' => { - add_variable(state, "EQUALS = =")?; - write_str(state, "$(EQUALS)") - } - ';' => panic!("can't escape a semicolon (;) for Unix Makefile"), - '$' => write_str(state, "$$"), - '\\' | ' ' | '#' | ':' | '%' | '*' | '?' | '[' | ']' | '~' => { - write_char(state, '\\')?; - write_char(state, c) - } - '\0'..='\x1F' | '\x7F' => { - panic!("can't escape a control character for Unix Makefile: {c:?}"); - } - _ => write_char(state, c), - }), - UnixMakefileEscapeKind::RecipeWithoutShellEscaping => { - str::from_utf8(self.s.as_encoded_bytes()) - .map_err(&utf8_error)? - .chars() - .try_for_each(escape_recipe_char) - } - UnixMakefileEscapeKind::RecipeWithShellEscaping => { - EscapeForUnixShell::new(self.s).try_for_each(escape_recipe_char) - } - } - } - pub fn new( - s: &'a (impl ?Sized + AsRef), - kind: UnixMakefileEscapeKind, - needed_variables: &mut BTreeSet<&'static str>, - ) -> Result { - let s = s.as_ref(); - let retval = Self { s, kind }; - retval.do_write( - needed_variables, - |_, _| Ok(()), - |_, _| Ok(()), - |needed_variables, variable| { - needed_variables.insert(variable); - Ok(()) - }, - |e| e, - )?; - Ok(retval) - } -} - -impl JobGraph { - pub fn new() -> Self { - Self::default() - } - fn try_add_item_node( - &mut self, - name: JobItemName, - new_source_job: Option, - new_nodes: &mut HashSet<::NodeId>, - ) -> Result<::NodeId, JobGraphError> { - use hashbrown::hash_map::Entry; - match self.items.entry(name) { - Entry::Occupied(item_entry) => { - let node_id = *item_entry.get(); - let JobGraphNode::Item { - name: _, - source_job, - } = &mut self.graph[node_id] - else { - unreachable!("known to be an item"); - }; - if let Some(new_source_job) = new_source_job { - if let Some(source_job) = source_job { - return Err(JobGraphError::MultipleJobsCreateSameOutput { - output_item: item_entry.key().clone(), - existing_job: source_job.clone(), - new_job: new_source_job, - }); - } else { - *source_job = Some(new_source_job); - } - } - Ok(node_id) - } - Entry::Vacant(item_entry) => { - let node_id = self.graph.add_node(JobGraphNode::Item { - name, - source_job: new_source_job, - }); - new_nodes.insert(node_id); - item_entry.insert(node_id); - Ok(node_id) - } - } - } - pub fn try_add_jobs>( - &mut self, - jobs: I, - ) -> Result<(), JobGraphError> { - use hashbrown::hash_map::Entry; - let jobs = jobs.into_iter(); - struct RemoveNewNodesOnError<'a> { - this: &'a mut JobGraph, - new_nodes: HashSet<::NodeId>, - } - impl Drop for RemoveNewNodesOnError<'_> { - fn drop(&mut self) { - for node in self.new_nodes.drain() { - self.this.graph.remove_node(node); - } - } - } - let mut remove_new_nodes_on_error = RemoveNewNodesOnError { - this: self, - new_nodes: HashSet::with_capacity_and_hasher(jobs.size_hint().0, Default::default()), - }; - let new_nodes = &mut remove_new_nodes_on_error.new_nodes; - let this = &mut *remove_new_nodes_on_error.this; - for job in jobs { - let Entry::Vacant(job_entry) = this.jobs.entry(job.clone()) else { - continue; - }; - let job_node_id = this - .graph - .add_node(JobGraphNode::Job(job_entry.key().clone())); - new_nodes.insert(job_node_id); - job_entry.insert(job_node_id); - for name in job.outputs() { - let item_node_id = this.try_add_item_node(name, Some(job.clone()), new_nodes)?; - this.graph.add_edge(job_node_id, item_node_id, ()); - } - for name in job.inputs() { - let item_node_id = this.try_add_item_node(name, None, new_nodes)?; - this.graph.add_edge(item_node_id, job_node_id, ()); - } - } - match toposort(&this.graph, Some(&mut this.space)) { - Ok(v) => { - this.topological_order = v; - // no need to remove any of the new nodes on drop since we didn't encounter any errors - remove_new_nodes_on_error.new_nodes.clear(); - Ok(()) - } - Err(_) => { - // there's at least one cycle, find one! - let cycle = kosaraju_scc(&this.graph) - .into_iter() - .find_map(|scc| { - if scc.len() <= 1 { - // can't be a cycle since our graph is bipartite -- - // jobs only connect to items, never jobs to jobs or items to items - None - } else { - Some(scc) - } - }) - .expect("we know there's a cycle"); - let cycle_set = HashSet::from_iter(cycle.iter().copied()); - let job = cycle - .into_iter() - .find_map(|node_id| { - if let JobGraphNode::Job(job) = &this.graph[node_id] { - Some(job.clone()) - } else { - None - } - }) - .expect("a job must be part of the cycle"); - let output = job - .outputs() - .into_iter() - .find(|output| cycle_set.contains(&this.items[output])) - .expect("an output must be part of the cycle"); - Err(JobGraphError::CycleError { job, output }) - } - } - } - #[track_caller] - pub fn add_jobs>(&mut self, jobs: I) { - match self.try_add_jobs(jobs) { - Ok(()) => {} - Err(e) => panic!("error: {e}"), - } - } - pub fn to_unix_makefile( - &self, - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> Result { - self.to_unix_makefile_with_internal_program_prefix( - &[program_name_for_internal_jobs()], - platform, - extra_args, - ) - } - pub fn to_unix_makefile_with_internal_program_prefix( - &self, - internal_program_prefix: &[Interned], - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> Result { - let mut retval = String::new(); - let mut needed_variables = BTreeSet::new(); - let mut phony_targets = BTreeSet::new(); - for &node_id in &self.topological_order { - let JobGraphNode::Job(job) = &self.graph[node_id] else { - continue; - }; - let outputs = job.outputs(); - if outputs.is_empty() { - retval.push_str(":"); - } else { - for output in job.outputs() { - match output { - JobItemName::Path { path } => { - write_str!( - retval, - "{} ", - EscapeForUnixMakefile::new( - &str::from_utf8(path.as_os_str().as_encoded_bytes())?, - UnixMakefileEscapeKind::NonRecipe, - &mut needed_variables - )? - ); - } - JobItemName::DynamicPaths { source_job_name } => { - write_str!( - retval, - "{} ", - EscapeForUnixMakefile::new( - &source_job_name, - UnixMakefileEscapeKind::NonRecipe, - &mut needed_variables - )? - ); - phony_targets.insert(Interned::into_inner(source_job_name)); - } - } - } - if outputs.len() == 1 { - retval.push_str(":"); - } else { - retval.push_str("&:"); - } - } - for input in job.inputs() { - match input { - JobItemName::Path { path } => { - write_str!( - retval, - " {}", - EscapeForUnixMakefile::new( - &str::from_utf8(path.as_os_str().as_encoded_bytes())?, - UnixMakefileEscapeKind::NonRecipe, - &mut needed_variables - )? - ); - } - JobItemName::DynamicPaths { source_job_name } => { - write_str!( - retval, - " {}", - EscapeForUnixMakefile::new( - &source_job_name, - UnixMakefileEscapeKind::NonRecipe, - &mut needed_variables - )? - ); - phony_targets.insert(Interned::into_inner(source_job_name)); - } - } - } - retval.push_str("\n\t"); - job.command_params_with_internal_program_prefix( - internal_program_prefix, - platform, - extra_args, - ) - .to_unix_shell_line(&mut retval, |arg, output| { - write_str!( - output, - "{}", - EscapeForUnixMakefile::new( - arg, - UnixMakefileEscapeKind::RecipeWithShellEscaping, - &mut needed_variables - )? - ); - Ok(()) - })?; - retval.push_str("\n\n"); - } - if !phony_targets.is_empty() { - retval.push_str("\n.PHONY:"); - for phony_target in phony_targets { - write_str!( - retval, - " {}", - EscapeForUnixMakefile::new( - phony_target, - UnixMakefileEscapeKind::NonRecipe, - &mut needed_variables - )? - ); - } - retval.push_str("\n"); - } - if !needed_variables.is_empty() { - retval.insert_str( - 0, - &String::from_iter(needed_variables.into_iter().map(|v| format!("{v}\n"))), - ); - } - Ok(retval) - } - pub fn to_unix_shell_script( - &self, - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> String { - self.to_unix_shell_script_with_internal_program_prefix( - &[program_name_for_internal_jobs()], - platform, - extra_args, - ) - } - pub fn to_unix_shell_script_with_internal_program_prefix( - &self, - internal_program_prefix: &[Interned], - platform: Option<&DynPlatform>, - extra_args: &[Interned], - ) -> String { - let mut retval = String::from( - "#!/bin/sh\n\ - set -ex\n", - ); - for &node_id in &self.topological_order { - let JobGraphNode::Job(job) = &self.graph[node_id] else { - continue; - }; - let Ok(()) = job - .command_params_with_internal_program_prefix( - internal_program_prefix, - platform, - extra_args, - ) - .to_unix_shell_line(&mut retval, |arg, output| -> Result<(), Infallible> { - write_str!(output, "{}", EscapeForUnixShell::new(&arg)); - Ok(()) - }); - retval.push_str("\n"); - } - retval - } - pub fn run(&self, params: &JobParams, global_params: &GlobalParams) -> eyre::Result<()> { - // use scope to auto-join threads on errors - thread::scope(|scope| { - struct WaitingJobState { - job_node_id: ::NodeId, - job: DynJob, - inputs: BTreeMap>, - } - let mut ready_jobs = VecDeque::new(); - let mut item_name_to_waiting_jobs_map = HashMap::<_, Vec<_>>::default(); - for &node_id in &self.topological_order { - let JobGraphNode::Job(job) = &self.graph[node_id] else { - continue; - }; - let waiting_job = WaitingJobState { - job_node_id: node_id, - job: job.clone(), - inputs: job - .inputs() - .iter() - .map(|&name| (name, OnceCell::new())) - .collect(), - }; - if waiting_job.inputs.is_empty() { - ready_jobs.push_back(waiting_job); - } else { - let waiting_job = Rc::new(waiting_job); - for &input_item in waiting_job.inputs.keys() { - item_name_to_waiting_jobs_map - .entry(input_item) - .or_default() - .push(waiting_job.clone()); - } - } - } - struct RunningJob<'scope> { - job: DynJob, - thread: ScopedJoinHandle<'scope, eyre::Result>>, - } - let mut running_jobs = HashMap::default(); - let (finished_jobs_sender, finished_jobs_receiver) = mpsc::channel(); - let mut next_finished_job = None; - loop { - if let Some(finished_job) = next_finished_job - .take() - .or_else(|| finished_jobs_receiver.try_recv().ok()) - { - let Some(RunningJob { job, thread }) = running_jobs.remove(&finished_job) - else { - unreachable!(); - }; - let output_items = thread.join().map_err(panic::resume_unwind)??; - assert!( - output_items.iter().map(JobItem::name).eq(job.outputs()), - "job's run() method returned the wrong output items:\n\ - output items:\n\ - {output_items:?}\n\ - expected outputs:\n\ - {:?}\n\ - job:\n\ - {job:?}", - job.outputs(), - ); - for output_item in output_items { - for waiting_job in item_name_to_waiting_jobs_map - .remove(&output_item.name()) - .unwrap_or_default() - { - let Ok(()) = - waiting_job.inputs[&output_item.name()].set(output_item.clone()) - else { - unreachable!(); - }; - if let Some(waiting_job) = Rc::into_inner(waiting_job) { - ready_jobs.push_back(waiting_job); - } - } - } - continue; - } - if let Some(WaitingJobState { - job_node_id, - job, - inputs, - }) = ready_jobs.pop_front() - { - struct RunningJobInThread<'a> { - job_node_id: ::NodeId, - job: DynJob, - inputs: Vec, - params: &'a JobParams, - global_params: &'a GlobalParams, - acquired_job: AcquiredJob, - finished_jobs_sender: mpsc::Sender<::NodeId>, - } - impl RunningJobInThread<'_> { - fn run(mut self) -> eyre::Result> { - self.job.run( - &self.inputs, - self.params, - self.global_params, - &mut self.acquired_job, - ) - } - } - impl Drop for RunningJobInThread<'_> { - fn drop(&mut self) { - let _ = self.finished_jobs_sender.send(self.job_node_id); - } - } - let name = job.kind().name(); - let running_job_in_thread = RunningJobInThread { - job_node_id, - job: job.clone(), - inputs: Result::from_iter(job.inputs().iter().map(|input_name| { - inputs.get(input_name).and_then(|v| v.get().cloned()).wrap_err_with(|| { - eyre!("failed when trying to run job {name}: nothing provided the input item: {input_name:?}") - }) - }))?, - params, - global_params, - acquired_job: AcquiredJob::acquire()?, - finished_jobs_sender: finished_jobs_sender.clone(), - }; - running_jobs.insert( - job_node_id, - RunningJob { - job, - thread: thread::Builder::new() - .name(format!("job:{name}")) - .spawn_scoped(scope, move || running_job_in_thread.run()) - .expect("failed to spawn thread for job"), - }, - ); - continue; - } - if running_jobs.is_empty() { - assert!(item_name_to_waiting_jobs_map.is_empty()); - assert!(ready_jobs.is_empty()); - return Ok(()); - } - // nothing to do yet, block to avoid busy waiting - next_finished_job = finished_jobs_receiver.recv().ok(); - } - }) - } -} - -impl Extend for JobGraph { - #[track_caller] - fn extend>(&mut self, iter: T) { - self.add_jobs(iter); - } -} - -impl FromIterator for JobGraph { - #[track_caller] - fn from_iter>(iter: T) -> Self { - let mut retval = Self::new(); - retval.add_jobs(iter); - retval - } -} - -impl Serialize for JobGraph { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut serializer = serializer.serialize_seq(Some(self.jobs.len()))?; - for &node_id in &self.topological_order { - let JobGraphNode::Job(job) = &self.graph[node_id] else { - continue; - }; - serializer.serialize_element(job)?; - } - serializer.end() - } -} - -impl<'de> Deserialize<'de> for JobGraph { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let jobs = Vec::::deserialize(deserializer)?; - let mut retval = JobGraph::new(); - retval.try_add_jobs(jobs).map_err(D::Error::custom)?; - Ok(retval) - } -} diff --git a/crates/fayalite/src/build/registry.rs b/crates/fayalite/src/build/registry.rs deleted file mode 100644 index bbd9f2c..0000000 --- a/crates/fayalite/src/build/registry.rs +++ /dev/null @@ -1,313 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - build::{DynJobKind, JobKind, built_in_job_kinds}, - intern::Interned, - util::InternedStrCompareAsStr, -}; -use std::{ - collections::BTreeMap, - fmt, - sync::{Arc, OnceLock, RwLock, RwLockWriteGuard}, -}; - -impl DynJobKind { - pub fn registry() -> JobKindRegistrySnapshot { - JobKindRegistrySnapshot(JobKindRegistry::get()) - } - #[track_caller] - pub fn register(self) { - JobKindRegistry::register(JobKindRegistry::lock(), self); - } -} - -#[derive(Clone, Debug)] -struct JobKindRegistry { - job_kinds: BTreeMap, -} - -enum JobKindRegisterError { - SameName { - name: InternedStrCompareAsStr, - old_job_kind: DynJobKind, - new_job_kind: DynJobKind, - }, -} - -impl fmt::Display for JobKindRegisterError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::SameName { - name, - old_job_kind, - new_job_kind, - } => write!( - f, - "two different `JobKind` can't share the same name:\n\ - {name:?}\n\ - old job kind:\n\ - {old_job_kind:?}\n\ - new job kind:\n\ - {new_job_kind:?}", - ), - } - } -} - -trait JobKindRegistryRegisterLock { - type Locked; - fn lock(self) -> Self::Locked; - fn make_mut(locked: &mut Self::Locked) -> &mut JobKindRegistry; -} - -impl JobKindRegistryRegisterLock for &'static RwLock> { - type Locked = RwLockWriteGuard<'static, Arc>; - fn lock(self) -> Self::Locked { - self.write().expect("shouldn't be poisoned") - } - fn make_mut(locked: &mut Self::Locked) -> &mut JobKindRegistry { - Arc::make_mut(locked) - } -} - -impl JobKindRegistryRegisterLock for &'_ mut JobKindRegistry { - type Locked = Self; - - fn lock(self) -> Self::Locked { - self - } - - fn make_mut(locked: &mut Self::Locked) -> &mut JobKindRegistry { - locked - } -} - -impl JobKindRegistry { - fn lock() -> &'static RwLock> { - static REGISTRY: OnceLock>> = OnceLock::new(); - REGISTRY.get_or_init(Default::default) - } - fn try_register( - lock: L, - job_kind: DynJobKind, - ) -> Result<(), JobKindRegisterError> { - use std::collections::btree_map::Entry; - let name = InternedStrCompareAsStr(job_kind.name()); - // run user code only outside of lock - let mut locked = lock.lock(); - let this = L::make_mut(&mut locked); - let result = match this.job_kinds.entry(name) { - Entry::Occupied(entry) => Err(JobKindRegisterError::SameName { - name, - old_job_kind: entry.get().clone(), - new_job_kind: job_kind, - }), - Entry::Vacant(entry) => { - entry.insert(job_kind); - Ok(()) - } - }; - drop(locked); - // outside of lock now, so we can test if it's the same DynJobKind - match result { - Err(JobKindRegisterError::SameName { - name: _, - old_job_kind, - new_job_kind, - }) if old_job_kind == new_job_kind => Ok(()), - result => result, - } - } - #[track_caller] - fn register(lock: L, job_kind: DynJobKind) { - match Self::try_register(lock, job_kind) { - Err(e) => panic!("{e}"), - Ok(()) => {} - } - } - fn get() -> Arc { - Self::lock().read().expect("shouldn't be poisoned").clone() - } -} - -impl Default for JobKindRegistry { - fn default() -> Self { - let mut retval = Self { - job_kinds: BTreeMap::new(), - }; - for job_kind in built_in_job_kinds() { - Self::register(&mut retval, job_kind); - } - retval - } -} - -#[derive(Clone, Debug)] -pub struct JobKindRegistrySnapshot(Arc); - -impl JobKindRegistrySnapshot { - pub fn get() -> Self { - JobKindRegistrySnapshot(JobKindRegistry::get()) - } - pub fn get_by_name<'a>(&'a self, name: &str) -> Option<&'a DynJobKind> { - self.0.job_kinds.get(name) - } - pub fn iter_with_names(&self) -> JobKindRegistryIterWithNames<'_> { - JobKindRegistryIterWithNames(self.0.job_kinds.iter()) - } - pub fn iter(&self) -> JobKindRegistryIter<'_> { - JobKindRegistryIter(self.0.job_kinds.values()) - } -} - -impl<'a> IntoIterator for &'a JobKindRegistrySnapshot { - type Item = &'a DynJobKind; - type IntoIter = JobKindRegistryIter<'a>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -impl<'a> IntoIterator for &'a mut JobKindRegistrySnapshot { - type Item = &'a DynJobKind; - type IntoIter = JobKindRegistryIter<'a>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -#[derive(Clone, Debug)] -pub struct JobKindRegistryIter<'a>( - std::collections::btree_map::Values<'a, InternedStrCompareAsStr, DynJobKind>, -); - -impl<'a> Iterator for JobKindRegistryIter<'a> { - type Item = &'a DynJobKind; - - fn next(&mut self) -> Option { - self.0.next() - } - - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } - - fn count(self) -> usize - where - Self: Sized, - { - self.0.count() - } - - fn last(self) -> Option { - self.0.last() - } - - fn nth(&mut self, n: usize) -> Option { - self.0.nth(n) - } - - fn fold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0.fold(init, f) - } -} - -impl<'a> std::iter::FusedIterator for JobKindRegistryIter<'a> {} - -impl<'a> ExactSizeIterator for JobKindRegistryIter<'a> {} - -impl<'a> DoubleEndedIterator for JobKindRegistryIter<'a> { - fn next_back(&mut self) -> Option { - self.0.next_back() - } - - fn nth_back(&mut self, n: usize) -> Option { - self.0.nth_back(n) - } - - fn rfold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0.rfold(init, f) - } -} - -#[derive(Clone, Debug)] -pub struct JobKindRegistryIterWithNames<'a>( - std::collections::btree_map::Iter<'a, InternedStrCompareAsStr, DynJobKind>, -); - -impl<'a> Iterator for JobKindRegistryIterWithNames<'a> { - type Item = (Interned, &'a DynJobKind); - - fn next(&mut self) -> Option { - self.0.next().map(|(name, job_kind)| (name.0, job_kind)) - } - - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } - - fn count(self) -> usize - where - Self: Sized, - { - self.0.count() - } - - fn last(self) -> Option { - self.0.last().map(|(name, job_kind)| (name.0, job_kind)) - } - - fn nth(&mut self, n: usize) -> Option { - self.0.nth(n).map(|(name, job_kind)| (name.0, job_kind)) - } - - fn fold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0 - .map(|(name, job_kind)| (name.0, job_kind)) - .fold(init, f) - } -} - -impl<'a> std::iter::FusedIterator for JobKindRegistryIterWithNames<'a> {} - -impl<'a> ExactSizeIterator for JobKindRegistryIterWithNames<'a> {} - -impl<'a> DoubleEndedIterator for JobKindRegistryIterWithNames<'a> { - fn next_back(&mut self) -> Option { - self.0 - .next_back() - .map(|(name, job_kind)| (name.0, job_kind)) - } - - fn nth_back(&mut self, n: usize) -> Option { - self.0 - .nth_back(n) - .map(|(name, job_kind)| (name.0, job_kind)) - } - - fn rfold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0 - .map(|(name, job_kind)| (name.0, job_kind)) - .rfold(init, f) - } -} - -#[track_caller] -pub fn register_job_kind(kind: K) { - DynJobKind::new(kind).register(); -} diff --git a/crates/fayalite/src/build/verilog.rs b/crates/fayalite/src/build/verilog.rs deleted file mode 100644 index 7ce77ec..0000000 --- a/crates/fayalite/src/build/verilog.rs +++ /dev/null @@ -1,418 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - build::{ - BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GetJobPositionJob, - GlobalParams, JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, - JobItemName, JobKind, JobKindAndDependencies, JobParams, ToArgs, WriteArgs, - external::{ - ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait, - }, - firrtl::{Firrtl, FirrtlJobKind}, - }, - intern::{Intern, InternSlice, Interned}, - util::job_server::AcquiredJob, -}; -use clap::Args; -use eyre::{Context, bail}; -use serde::{Deserialize, Serialize}; -use std::{ - ffi::{OsStr, OsString}, - fmt, mem, - path::Path, -}; - -/// based on [LLVM Circt's recommended lowering options][lowering-options] -/// -/// [lowering-options]: https://circt.llvm.org/docs/VerilogGeneration/#recommended-loweringoptions-by-target -#[derive(clap::ValueEnum, Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[non_exhaustive] -pub enum VerilogDialect { - Questa, - Spyglass, - Verilator, - Vivado, - Yosys, -} - -impl fmt::Display for VerilogDialect { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } -} - -impl VerilogDialect { - pub fn as_str(self) -> &'static str { - match self { - VerilogDialect::Questa => "questa", - VerilogDialect::Spyglass => "spyglass", - VerilogDialect::Verilator => "verilator", - VerilogDialect::Vivado => "vivado", - VerilogDialect::Yosys => "yosys", - } - } - pub fn firtool_extra_args(self) -> &'static [&'static str] { - match self { - VerilogDialect::Questa => &["--lowering-options=emitWireInPorts"], - VerilogDialect::Spyglass => { - &["--lowering-options=explicitBitcast,disallowExpressionInliningInPorts"] - } - VerilogDialect::Verilator => &[ - "--lowering-options=locationInfoStyle=wrapInAtSquareBracket,disallowLocalVariables", - ], - VerilogDialect::Vivado => &["--lowering-options=mitigateVivadoArrayIndexConstPropBug"], - VerilogDialect::Yosys => { - &["--lowering-options=disallowLocalVariables,disallowPackedArrays"] - } - } - } -} - -#[derive(Args, Debug, Clone, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub struct UnadjustedVerilogArgs { - #[arg(long = "firtool-extra-arg", value_name = "ARG")] - pub firtool_extra_args: Vec, - /// adapt the generated Verilog for a particular toolchain - #[arg(long)] - pub verilog_dialect: Option, - #[arg(long)] - pub verilog_debug: bool, -} - -impl ToArgs for UnadjustedVerilogArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { - ref firtool_extra_args, - verilog_dialect, - verilog_debug, - } = *self; - for arg in firtool_extra_args { - args.write_long_option_eq("firtool-extra-arg", arg); - } - if let Some(verilog_dialect) = verilog_dialect { - args.write_long_option_eq("verilog-dialect", verilog_dialect.as_str()); - } - if verilog_debug { - args.write_arg("--verilog-debug"); - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] -pub struct Firtool; - -impl ExternalProgramTrait for Firtool { - fn default_program_name() -> Interned { - "firtool".intern() - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, Deserialize, Serialize)] -pub struct UnadjustedVerilog { - firrtl_file: Interned, - firrtl_file_name: Interned, - unadjusted_verilog_file: Interned, - unadjusted_verilog_file_name: Interned, - firtool_extra_args: Interned<[Interned]>, - verilog_dialect: Option, - verilog_debug: bool, -} - -impl UnadjustedVerilog { - pub fn firrtl_file(&self) -> Interned { - self.firrtl_file - } - pub fn unadjusted_verilog_file(&self) -> Interned { - self.unadjusted_verilog_file - } - pub fn firtool_extra_args(&self) -> Interned<[Interned]> { - self.firtool_extra_args - } - pub fn verilog_dialect(&self) -> Option { - self.verilog_dialect - } - pub fn verilog_debug(&self) -> bool { - self.verilog_debug - } -} - -impl ExternalCommand for UnadjustedVerilog { - type AdditionalArgs = UnadjustedVerilogArgs; - type AdditionalJobData = UnadjustedVerilog; - type BaseJobPosition = GetJobPositionDependencies; - type Dependencies = JobKindAndDependencies; - type ExternalProgram = Firtool; - - fn dependencies() -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - args: JobArgsAndDependencies>, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<( - Self::AdditionalJobData, - ::JobsAndKinds, - )> { - args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { - let UnadjustedVerilogArgs { - firtool_extra_args, - verilog_dialect, - verilog_debug, - } = args.additional_args; - let unadjusted_verilog_file = dependencies - .dependencies - .job - .job - .file_with_ext("unadjusted.v"); - let firrtl_job = dependencies.get_job::(); - Ok(UnadjustedVerilog { - firrtl_file: firrtl_job.firrtl_file(), - firrtl_file_name: firrtl_job - .firrtl_file() - .interned_file_name() - .expect("known to have file name"), - unadjusted_verilog_file, - unadjusted_verilog_file_name: unadjusted_verilog_file - .interned_file_name() - .expect("known to have file name"), - firtool_extra_args: firtool_extra_args.into_iter().map(Interned::from).collect(), - verilog_dialect, - verilog_debug, - }) - }) - } - - fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { - [JobItemName::Path { - path: job.additional_job_data().firrtl_file, - }] - .intern_slice() - } - - fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]> { - [job.additional_job_data().unadjusted_verilog_file].intern_slice() - } - - fn command_line_args(job: &ExternalCommandJob, args: &mut W) { - let UnadjustedVerilog { - firrtl_file: _, - firrtl_file_name, - unadjusted_verilog_file: _, - unadjusted_verilog_file_name, - firtool_extra_args, - verilog_dialect, - verilog_debug, - } = *job.additional_job_data(); - args.write_interned_arg(firrtl_file_name); - args.write_arg("-o"); - args.write_interned_arg(unadjusted_verilog_file_name); - if verilog_debug { - args.write_args(["-g", "--preserve-values=all"]); - } - if let Some(dialect) = verilog_dialect { - args.write_args(dialect.firtool_extra_args().iter().copied()); - } - args.write_interned_args(firtool_extra_args); - } - - fn current_dir(job: &ExternalCommandJob) -> Option> { - Some(job.output_dir()) - } - - fn job_kind_name() -> Interned { - "unadjusted-verilog".intern() - } - - fn subcommand_hidden() -> bool { - true - } - - fn run_even_if_cached_arg_name() -> Interned { - "firtool-run-even-if-cached".intern() - } -} - -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct VerilogJobKind; - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Args)] -#[non_exhaustive] -pub struct VerilogJobArgs {} - -impl ToArgs for VerilogJobArgs { - fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { - let Self {} = self; - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct VerilogJob { - output_dir: Interned, - unadjusted_verilog_file: Interned, - main_verilog_file: Interned, -} - -impl VerilogJob { - pub fn output_dir(&self) -> Interned { - self.output_dir - } - pub fn unadjusted_verilog_file(&self) -> Interned { - self.unadjusted_verilog_file - } - pub fn main_verilog_file(&self) -> Interned { - self.main_verilog_file - } - #[track_caller] - pub fn unwrap_additional_files(additional_files: &JobItem) -> &[Interned] { - match additional_files { - JobItem::DynamicPaths { - paths, - source_job_name, - } if *source_job_name == VerilogJobKind.name() => paths, - v => panic!("expected VerilogJob's additional files JobItem: {v:?}"), - } - } - pub fn all_verilog_files( - main_verilog_file: Interned, - additional_files: &[Interned], - ) -> eyre::Result]>> { - let mut retval = Vec::with_capacity(additional_files.len().saturating_add(1)); - for verilog_file in [main_verilog_file].iter().chain(additional_files) { - if !["v", "sv"] - .iter() - .any(|extension| verilog_file.extension() == Some(extension.as_ref())) - { - continue; - } - let verilog_file = std::path::absolute(verilog_file).wrap_err_with(|| { - format!("converting {verilog_file:?} to an absolute path failed") - })?; - if verilog_file - .as_os_str() - .as_encoded_bytes() - .iter() - .any(|&ch| (ch != b' ' && ch != b'\t' && ch.is_ascii_whitespace()) || ch == b'"') - { - bail!("verilog file path contains characters that aren't permitted"); - } - retval.push(verilog_file.intern_deref()); - } - Ok(retval.intern_slice()) - } -} - -impl JobKind for VerilogJobKind { - type Args = VerilogJobArgs; - type Job = VerilogJob; - type Dependencies = JobKindAndDependencies>; - - fn dependencies(self) -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - args: JobArgsAndDependencies, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { - let VerilogJobArgs {} = args; - let base_job = dependencies.get_job::(); - Ok(VerilogJob { - output_dir: base_job.output_dir(), - unadjusted_verilog_file: dependencies - .job - .job - .additional_job_data() - .unadjusted_verilog_file(), - main_verilog_file: base_job.file_with_ext("v"), - }) - }) - } - - fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { - path: job.unadjusted_verilog_file, - }] - .intern_slice() - } - - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [ - JobItemName::Path { - path: job.main_verilog_file, - }, - JobItemName::DynamicPaths { - source_job_name: self.name(), - }, - ] - .intern_slice() - } - - fn name(self) -> Interned { - "verilog".intern() - } - - fn external_command_params(self, _job: &Self::Job) -> Option { - None - } - - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - _params: &JobParams, - _global_params: &GlobalParams, - _acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job))); - let input = std::fs::read_to_string(job.unadjusted_verilog_file())?; - let file_separator_prefix = "\n// ----- 8< ----- FILE \""; - let file_separator_suffix = "\" ----- 8< -----\n\n"; - let mut input = &*input; - let main_verilog_file = job.main_verilog_file(); - let mut file_name = Some(main_verilog_file); - let mut additional_outputs = Vec::new(); - loop { - let (chunk, next_file_name) = if let Some((chunk, rest)) = - input.split_once(file_separator_prefix) - { - let Some((next_file_name, rest)) = rest.split_once(file_separator_suffix) else { - bail!( - "parsing firtool's output failed: found {file_separator_prefix:?} but no {file_separator_suffix:?}" - ); - }; - input = rest; - let next_file_name = job.output_dir.join(next_file_name).intern_deref(); - additional_outputs.push(next_file_name); - (chunk, Some(next_file_name)) - } else { - (mem::take(&mut input), None) - }; - let Some(file_name) = mem::replace(&mut file_name, next_file_name) else { - break; - }; - std::fs::write(&file_name, chunk)?; - } - Ok(vec![ - JobItem::Path { - path: main_verilog_file, - }, - JobItem::DynamicPaths { - paths: additional_outputs, - source_job_name: self.name(), - }, - ]) - } -} - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - [ - DynJobKind::new(ExternalCommandJobKind::::new()), - DynJobKind::new(VerilogJobKind), - ] -} diff --git a/crates/fayalite/src/bundle.rs b/crates/fayalite/src/bundle.rs index 1471f3a..55843ea 100644 --- a/crates/fayalite/src/bundle.rs +++ b/crates/fayalite/src/bundle.rs @@ -3,14 +3,12 @@ use crate::{ expr::{ - CastToBits, Expr, HdlPartialEqImpl, ReduceBits, ToExpr, ToSimValueInner, ValueType, - Valueless, - ops::{ArrayLiteral, BundleLiteral}, - value_category::{ValueCategoryCommon, ValueCategoryExpr, ValueCategoryValue}, + CastToBits, Expr, ReduceBits, ToExpr, + ops::{ArrayLiteral, BundleLiteral, ExprPartialEq}, }, int::{Bool, DynSize}, - intern::{Intern, InternSlice, Interned}, - sim::value::{SimValue, SimValueEq, ToSimValue, ToSimValueWithType}, + intern::{Intern, Interned}, + sim::value::{SimValue, SimValuePartialEq, ToSimValue, ToSimValueWithType}, source_location::SourceLocation, ty::{ CanonicalType, MatchVariantWithoutScope, OpaqueSimValue, OpaqueSimValueSize, @@ -20,7 +18,7 @@ use crate::{ util::HashMap, }; use serde::{Deserialize, Serialize}; -use std::{borrow::Cow, fmt, marker::PhantomData}; +use std::{fmt, marker::PhantomData}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub struct BundleField { @@ -273,6 +271,7 @@ impl Type for Bundle { pub trait BundleType: Type { type Builder: Default; + type FilledBuilder: ToExpr; fn fields(&self) -> Interned<[BundleField]>; } @@ -319,7 +318,7 @@ impl<'a> BundleSimValueFromOpaque<'a> { #[track_caller] pub fn field_clone_from_opaque(&mut self, field_value: &mut SimValue) { let (field_ty, field_opaque) = self.field_ty_and_opaque::(); - assert_eq!(field_ty, field_value.ty()); + assert_eq!(field_ty, SimValue::ty(field_value)); SimValue::opaque_mut(field_value).clone_from_slice(field_opaque); } } @@ -355,7 +354,7 @@ impl<'a> BundleSimValueToOpaque<'a> { else { panic!("tried to write too many fields with BundleSimValueToOpaque"); }; - assert_eq!(T::from_canonical(ty), field_value.ty()); + assert_eq!(T::from_canonical(ty), SimValue::ty(field_value)); self.writer.fill_prefix_with(ty.size(), |writer| { writer.fill_cloned_from_slice(SimValue::opaque(field_value).as_slice()) }); @@ -375,8 +374,17 @@ impl<'a> BundleSimValueToOpaque<'a> { #[derive(Default)] pub struct NoBuilder; +pub struct Unfilled(PhantomData); + +impl Default for Unfilled { + fn default() -> Self { + Self(PhantomData) + } +} + impl BundleType for Bundle { type Builder = NoBuilder; + type FilledBuilder = Expr; fn fields(&self) -> Interned<[BundleField]> { self.0.fields } @@ -412,14 +420,15 @@ macro_rules! impl_tuple_builder_fields { ) => { impl< $($head_type_var,)* + $cur_type_var: Type, $($tail_type_var,)* > TupleBuilder<( $($head_type_var,)* - (), + Unfilled<$cur_type_var>, $($tail_type_var,)* )> { - pub fn $cur_field<$cur_type_var: Type>(self, $cur_var: impl ToExpr) -> TupleBuilder<( + pub fn $cur_field(self, $cur_var: impl ToExpr) -> TupleBuilder<( $($head_type_var,)* Expr<$cur_type_var>, $($tail_type_var,)* @@ -443,12 +452,6 @@ macro_rules! impl_tuple_builder_fields { ($global:tt []) => {}; } -macro_rules! get_unit_ty { - ($($tt:tt)*) => { - () - }; -} - macro_rules! impl_tuples { ( [$({ @@ -542,10 +545,11 @@ macro_rules! impl_tuples { } } impl<$($T: Type,)*> BundleType for ($($T,)*) { - type Builder = TupleBuilder<($(get_unit_ty!($T),)*)>; + type Builder = TupleBuilder<($(Unfilled<$T>,)*)>; + type FilledBuilder = TupleBuilder<($(Expr<$T>,)*)>; fn fields(&self) -> Interned<[BundleField]> { let ($($var,)*) = self; - [$(BundleField { name: stringify!($num).intern(), flipped: false, ty: $var.canonical() }),*].intern_slice() + [$(BundleField { name: stringify!($num).intern(), flipped: false, ty: $var.canonical() }),*][..].intern() } } impl<$($T: Type,)*> TypeWithDeref for ($($T,)*) { @@ -568,56 +572,25 @@ macro_rules! impl_tuples { builder.finish() }; } - impl<'a, $($T: ToSimValue,)*> ToSimValueInner<'a> for ($($T,)*) - where - Self: ValueType, - { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - let ($($var,)*) = this; - Cow::Owned(($($var.to_sim_value(),)*)) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - let ($($var,)*) = this; - Cow::Owned(($($var.into_sim_value(),)*)) - } - } - impl<$($T: ValueType,)*> ValueType for ($($T,)*) - where - ValueCategoryValue: ValueCategoryCommon<($($T::ValueCategory,)*)>, - { + impl<$($T: ToExpr,)*> ToExpr for ($($T,)*) { type Type = ($($T::Type,)*); - type ValueCategory = >::Common; - fn ty(&self) -> Self::Type { - let ($($var,)*) = self; - ($($var.ty(),)*) - } - } - impl<$($T: ToExpr,)*> ToExpr for ($($T,)*) - where - Self: ValueType, - { + fn to_expr(&self) -> Expr { let ($($var,)*) = self; $(let $var = $var.to_expr();)* - let ty = ($($var.ty(),)*); + let ty = ($(Expr::ty($var),)*); let field_values = [$(Expr::canonical($var)),*]; - BundleLiteral::new(ty, field_values.intern_slice()).to_expr() - } - } - impl<$($T: Type,)*> ValueType for TupleBuilder<($(Expr<$T>,)*)> { - type Type = ($($T,)*); - type ValueCategory = ValueCategoryExpr; - fn ty(&self) -> Self::Type { - let ($($var,)*) = self.0; - ($($var.ty(),)*) + BundleLiteral::new(ty, field_values[..].intern()).to_expr() } } impl<$($T: Type,)*> ToExpr for TupleBuilder<($(Expr<$T>,)*)> { + type Type = ($($T,)*); + fn to_expr(&self) -> Expr { let ($($var,)*) = self.0; - let ty = ($($var.ty(),)*); + let ty = ($(Expr::ty($var),)*); let field_values = [$(Expr::canonical($var)),*]; - BundleLiteral::new(ty, field_values.intern_slice()).to_expr() + BundleLiteral::new(ty, field_values[..].intern()).to_expr() } } impl<$($T: ToSimValueWithType,)*> ToSimValueWithType for ($($T,)*) { @@ -651,7 +624,7 @@ macro_rules! impl_tuples { }; let mut opaque = OpaqueSimValue::empty(); $(let $var = $var.into_sim_value_with_type($ty_var.ty); - assert_eq!($var.ty(), $ty_var.ty); + assert_eq!(SimValue::ty(&$var), $ty_var.ty); opaque.extend_from_slice(SimValue::opaque(&$var).as_slice()); )* SimValue::from_opaque(ty, opaque) @@ -673,82 +646,53 @@ macro_rules! impl_tuples { SimValue::from_value(ty, ($($var,)*)) } } - impl<$($T: ToSimValue,)*> ToSimValue for ($($T,)*) - where - Self: ValueType, - { + 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(($($var.ty(),)*), ($($var,)*)) + SimValue::from_value(($(SimValue::ty(&$var),)*), ($($var,)*)) } #[track_caller] fn into_sim_value(self) -> SimValue { let ($($var,)*) = self; $(let $var = $var.to_sim_value();)* - SimValue::from_value(($($var.ty(),)*), ($($var,)*)) + SimValue::from_value(($(SimValue::ty(&$var),)*), ($($var,)*)) } } - impl<$($Lhs: Type + HdlPartialEqImpl<$Rhs>, $Rhs: Type,)*> HdlPartialEqImpl<($($Rhs,)*)> for ($($Lhs,)*) { - #[track_caller] - fn cmp_value_eq( - lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - rhs: ($($Rhs,)*), - rhs_value: Cow<'_, <($($Rhs,)*) as Type>::SimValue>, - ) -> bool { - #![allow(unused_variables)] - let ($($lhs_var,)*) = &*lhs_value; - let ($($rhs_var,)*) = &*rhs_value; - let retval = true; - $(let retval = retval && $Lhs::cmp_value_eq(lhs.$num, Cow::Borrowed($lhs_var), rhs.$num, Cow::Borrowed($rhs_var));)* - retval - } - - #[track_caller] - fn cmp_expr_eq(lhs: Expr, rhs: Expr<($($Rhs,)*)>) -> Expr { + 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($Lhs::cmp_expr_eq($lhs_var, $rhs_var)),)*]), + FromIterator::from_iter([$(Expr::canonical(ExprPartialEq::cmp_eq($lhs_var, $rhs_var)),)*]), ) .cast_to_bits() .all_one_bits() } - #[track_caller] - fn cmp_expr_ne(lhs: Expr, rhs: Expr<($($Rhs,)*)>) -> Expr { + 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($Lhs::cmp_expr_ne($lhs_var, $rhs_var)),)*]), + FromIterator::from_iter([$(Expr::canonical(ExprPartialEq::cmp_ne($lhs_var, $rhs_var)),)*]), ) .cast_to_bits() .any_one_bits() } - - #[track_caller] - fn cmp_valueless_eq(lhs: Valueless, rhs: Valueless<($($Rhs,)*)>) -> Valueless { - let ($($lhs_var,)*) = lhs.ty(); - let ($($rhs_var,)*) = rhs.ty(); - // let them check that the types can be compared - $($Lhs::cmp_valueless_eq(Valueless::new($lhs_var), Valueless::new($rhs_var));)* - Valueless::new(Bool) - } - - #[track_caller] - fn cmp_valueless_ne(lhs: Valueless, rhs: Valueless<($($Rhs,)*)>) -> Valueless { - let ($($lhs_var,)*) = lhs.ty(); - let ($($rhs_var,)*) = rhs.ty(); - // let them check that the types can be compared - $($Lhs::cmp_valueless_ne(Valueless::new($lhs_var), Valueless::new($rhs_var));)* - Valueless::new(Bool) + } + 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 } } - impl<$($T: SimValueEq + HdlPartialEqImpl<$T>,)*> SimValueEq for ($($T,)*) {} }; ([$($lhs:tt)*] [$rhs_first:tt $($rhs:tt)*]) => { impl_tuples!([$($lhs)*] []); @@ -837,16 +781,9 @@ impl Default for PhantomDataBuilder { } } -impl ValueType for PhantomDataBuilder { - type Type = PhantomData; - type ValueCategory = ValueCategoryValue; - - fn ty(&self) -> Self::Type { - PhantomData - } -} - impl ToExpr for PhantomDataBuilder { + type Type = PhantomData; + fn to_expr(&self) -> Expr { PhantomData.to_expr() } @@ -854,6 +791,7 @@ impl ToExpr for PhantomDataBuilder { impl BundleType for PhantomData { type Builder = PhantomDataBuilder; + type FilledBuilder = PhantomDataBuilder; fn fields(&self) -> Interned<[BundleField]> { Interned::default() } @@ -872,22 +810,17 @@ impl StaticType for PhantomData { const MASK_TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES; } -impl ValueType for PhantomData { - type Type = PhantomData; - type ValueCategory = ValueCategoryValue; - - fn ty(&self) -> Self::Type { - PhantomData - } -} - impl ToExpr for PhantomData { + type Type = PhantomData; + fn to_expr(&self) -> Expr { BundleLiteral::new(PhantomData, Interned::default()).to_expr() } } impl ToSimValue for PhantomData { + type Type = PhantomData; + #[track_caller] fn to_sim_value(&self) -> SimValue { SimValue::from_value(*self, *self) diff --git a/crates/fayalite/src/cli.rs b/crates/fayalite/src/cli.rs new file mode 100644 index 0000000..6fb4b5e --- /dev/null +++ b/crates/fayalite/src/cli.rs @@ -0,0 +1,806 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information +use crate::{ + bundle::{Bundle, BundleType}, + firrtl::{self, ExportOptions}, + intern::Interned, + module::Module, + util::{job_server::AcquiredJob, streaming_read_utf8::streaming_read_utf8}, +}; +use clap::{ + Parser, Subcommand, ValueEnum, ValueHint, + builder::{OsStringValueParser, TypedValueParser}, +}; +use eyre::{Report, eyre}; +use serde::{Deserialize, Serialize}; +use std::{ + error, + ffi::OsString, + fmt::{self, Write}, + fs, io, mem, + path::{Path, PathBuf}, + process, +}; +use tempfile::TempDir; + +pub type Result = std::result::Result; + +pub struct CliError(Report); + +impl fmt::Debug for CliError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Display for CliError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl error::Error for CliError {} + +impl From for CliError { + fn from(value: io::Error) -> Self { + CliError(Report::new(value)) + } +} + +pub trait RunPhase { + type Output; + fn run(&self, arg: Arg) -> Result { + self.run_with_job(arg, &mut AcquiredJob::acquire()) + } + fn run_with_job(&self, arg: Arg, acquired_job: &mut AcquiredJob) -> Result; +} + +#[derive(Parser, Debug, Clone)] +#[non_exhaustive] +pub struct BaseArgs { + /// the directory to put the generated main output file and associated files in + #[arg(short, long, value_hint = ValueHint::DirPath, required = true)] + pub output: Option, + /// the stem of the generated main output file, e.g. to get foo.v, pass --file-stem=foo + #[arg(long)] + pub file_stem: Option, + #[arg(long, env = "FAYALITE_KEEP_TEMP_DIR")] + pub keep_temp_dir: bool, + #[arg(skip = false)] + pub redirect_output_for_rust_test: bool, +} + +impl BaseArgs { + fn make_firrtl_file_backend(&self) -> Result<(firrtl::FileBackend, Option)> { + let (dir_path, temp_dir) = match &self.output { + Some(output) => (output.clone(), None), + None => { + let temp_dir = TempDir::new()?; + if self.keep_temp_dir { + let temp_dir = temp_dir.into_path(); + println!("created temporary directory: {}", temp_dir.display()); + (temp_dir, None) + } else { + (temp_dir.path().to_path_buf(), Some(temp_dir)) + } + } + }; + Ok(( + firrtl::FileBackend { + dir_path, + top_fir_file_stem: self.file_stem.clone(), + circuit_name: None, + }, + temp_dir, + )) + } + /// handles possibly redirecting the command's output for Rust tests + pub fn run_external_command( + &self, + _acquired_job: &mut AcquiredJob, + mut command: process::Command, + mut captured_output: Option<&mut String>, + ) -> io::Result { + if self.redirect_output_for_rust_test || captured_output.is_some() { + let (reader, writer) = os_pipe::pipe()?; + let mut reader = io::BufReader::new(reader); + command.stderr(writer.try_clone()?); + command.stdout(writer); // must not leave writer around after spawning child + command.stdin(process::Stdio::null()); + let mut child = command.spawn()?; + drop(command); // close writers + Ok(loop { + let status = child.try_wait()?; + streaming_read_utf8(&mut reader, |s| { + if let Some(captured_output) = captured_output.as_deref_mut() { + captured_output.push_str(s); + } + // use print! so output goes to Rust test output capture + print!("{s}"); + io::Result::Ok(()) + })?; + if let Some(status) = status { + break status; + } + }) + } else { + command.status() + } + } +} + +#[derive(Parser, Debug, Clone)] +#[non_exhaustive] +pub struct FirrtlArgs { + #[command(flatten)] + pub base: BaseArgs, + #[command(flatten)] + pub export_options: ExportOptions, +} + +#[derive(Debug)] +#[non_exhaustive] +pub struct FirrtlOutput { + pub file_stem: String, + pub top_module: String, + pub output_dir: PathBuf, + pub temp_dir: Option, +} + +impl FirrtlOutput { + pub fn file_with_ext(&self, ext: &str) -> PathBuf { + let mut retval = self.output_dir.join(&self.file_stem); + retval.set_extension(ext); + retval + } + pub fn firrtl_file(&self) -> PathBuf { + self.file_with_ext("fir") + } +} + +impl FirrtlArgs { + fn run_impl( + &self, + top_module: Module, + _acquired_job: &mut AcquiredJob, + ) -> Result { + let (file_backend, temp_dir) = self.base.make_firrtl_file_backend()?; + let firrtl::FileBackend { + top_fir_file_stem, + circuit_name, + dir_path, + } = firrtl::export(file_backend, &top_module, self.export_options)?; + Ok(FirrtlOutput { + file_stem: top_fir_file_stem.expect( + "export is known to set the file stem from the circuit name if not provided", + ), + top_module: circuit_name.expect("export is known to set the circuit name"), + output_dir: dir_path, + temp_dir, + }) + } +} + +impl RunPhase> for FirrtlArgs { + type Output = FirrtlOutput; + fn run_with_job( + &self, + top_module: Module, + acquired_job: &mut AcquiredJob, + ) -> Result { + self.run_impl(top_module.canonical(), acquired_job) + } +} + +impl RunPhase>> for FirrtlArgs { + type Output = FirrtlOutput; + fn run_with_job( + &self, + top_module: Interned>, + acquired_job: &mut AcquiredJob, + ) -> Result { + self.run_with_job(*top_module, acquired_job) + } +} + +/// based on [LLVM Circt's recommended lowering options +/// ](https://circt.llvm.org/docs/VerilogGeneration/#recommended-loweringoptions-by-target) +#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub enum VerilogDialect { + Questa, + Spyglass, + Verilator, + Vivado, + Yosys, +} + +impl fmt::Display for VerilogDialect { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +impl VerilogDialect { + pub fn as_str(self) -> &'static str { + match self { + VerilogDialect::Questa => "questa", + VerilogDialect::Spyglass => "spyglass", + VerilogDialect::Verilator => "verilator", + VerilogDialect::Vivado => "vivado", + VerilogDialect::Yosys => "yosys", + } + } + pub fn firtool_extra_args(self) -> &'static [&'static str] { + match self { + VerilogDialect::Questa => &["--lowering-options=emitWireInPorts"], + VerilogDialect::Spyglass => { + &["--lowering-options=explicitBitcast,disallowExpressionInliningInPorts"] + } + VerilogDialect::Verilator => &[ + "--lowering-options=locationInfoStyle=wrapInAtSquareBracket,disallowLocalVariables", + ], + VerilogDialect::Vivado => &["--lowering-options=mitigateVivadoArrayIndexConstPropBug"], + VerilogDialect::Yosys => { + &["--lowering-options=disallowLocalVariables,disallowPackedArrays"] + } + } + } +} + +#[derive(Parser, Debug, Clone)] +#[non_exhaustive] +pub struct VerilogArgs { + #[command(flatten)] + pub firrtl: FirrtlArgs, + #[arg( + long, + default_value = "firtool", + env = "FIRTOOL", + value_hint = ValueHint::CommandName, + value_parser = OsStringValueParser::new().try_map(which) + )] + pub firtool: PathBuf, + #[arg(long)] + pub firtool_extra_args: Vec, + /// adapt the generated Verilog for a particular toolchain + #[arg(long)] + pub verilog_dialect: Option, + #[arg(long, short = 'g')] + pub debug: bool, +} + +#[derive(Debug)] +#[non_exhaustive] +pub struct VerilogOutput { + pub firrtl: FirrtlOutput, + pub verilog_files: Vec, + pub contents_hash: Option, +} + +impl VerilogOutput { + pub fn main_verilog_file(&self) -> PathBuf { + self.firrtl.file_with_ext("v") + } + fn unadjusted_verilog_file(&self) -> PathBuf { + self.firrtl.file_with_ext("unadjusted.v") + } +} + +impl VerilogArgs { + fn process_unadjusted_verilog_file(&self, mut output: VerilogOutput) -> Result { + let input = fs::read_to_string(output.unadjusted_verilog_file())?; + let file_separator_prefix = "\n// ----- 8< ----- FILE \""; + let file_separator_suffix = "\" ----- 8< -----\n\n"; + let mut input = &*input; + output.contents_hash = Some(blake3::hash(input.as_bytes())); + let main_verilog_file = output.main_verilog_file(); + let mut file_name: Option<&Path> = Some(&main_verilog_file); + loop { + let (chunk, next_file_name) = if let Some((chunk, rest)) = + input.split_once(file_separator_prefix) + { + let Some((next_file_name, rest)) = rest.split_once(file_separator_suffix) else { + return Err(CliError(eyre!( + "parsing firtool's output failed: found {file_separator_prefix:?} but no {file_separator_suffix:?}" + ))); + }; + input = rest; + (chunk, Some(next_file_name.as_ref())) + } else { + (mem::take(&mut input), None) + }; + let Some(file_name) = mem::replace(&mut file_name, next_file_name) else { + break; + }; + let file_name = output.firrtl.output_dir.join(file_name); + fs::write(&file_name, chunk)?; + if let Some(extension) = file_name.extension() { + if extension == "v" || extension == "sv" { + output.verilog_files.push(file_name); + } + } + } + Ok(output) + } + fn run_impl( + &self, + firrtl_output: FirrtlOutput, + acquired_job: &mut AcquiredJob, + ) -> Result { + let Self { + firrtl, + firtool, + firtool_extra_args, + verilog_dialect, + debug, + } = self; + let output = VerilogOutput { + firrtl: firrtl_output, + verilog_files: vec![], + contents_hash: None, + }; + let mut cmd = process::Command::new(firtool); + cmd.arg(output.firrtl.firrtl_file()); + cmd.arg("-o"); + cmd.arg(output.unadjusted_verilog_file()); + if *debug { + cmd.arg("-g"); + cmd.arg("--preserve-values=all"); + } + if let Some(dialect) = verilog_dialect { + cmd.args(dialect.firtool_extra_args()); + } + cmd.args(firtool_extra_args); + cmd.current_dir(&output.firrtl.output_dir); + let status = firrtl.base.run_external_command(acquired_job, cmd, None)?; + if status.success() { + self.process_unadjusted_verilog_file(output) + } else { + Err(CliError(eyre!( + "running {} failed: {status}", + self.firtool.display() + ))) + } + } +} + +impl RunPhase for VerilogArgs +where + FirrtlArgs: RunPhase, +{ + type Output = VerilogOutput; + fn run_with_job(&self, arg: Arg, acquired_job: &mut AcquiredJob) -> Result { + let firrtl_output = self.firrtl.run_with_job(arg, acquired_job)?; + self.run_impl(firrtl_output, acquired_job) + } +} + +#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq, Hash, Default)] +#[non_exhaustive] +pub enum FormalMode { + #[default] + BMC, + Prove, + Live, + Cover, +} + +impl FormalMode { + pub fn as_str(self) -> &'static str { + match self { + FormalMode::BMC => "bmc", + FormalMode::Prove => "prove", + FormalMode::Live => "live", + FormalMode::Cover => "cover", + } + } +} + +impl fmt::Display for FormalMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +#[derive(Clone)] +struct FormalAdjustArgs; + +impl clap::FromArgMatches for FormalAdjustArgs { + fn from_arg_matches(_matches: &clap::ArgMatches) -> Result { + Ok(Self) + } + + fn update_from_arg_matches(&mut self, _matches: &clap::ArgMatches) -> Result<(), clap::Error> { + Ok(()) + } +} + +impl clap::Args for FormalAdjustArgs { + fn augment_args(cmd: clap::Command) -> clap::Command { + cmd.mut_arg("output", |arg| arg.required(false)) + .mut_arg("verilog_dialect", |arg| { + arg.default_value(VerilogDialect::Yosys.to_string()) + .hide(true) + }) + } + + fn augment_args_for_update(cmd: clap::Command) -> clap::Command { + Self::augment_args(cmd) + } +} + +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 { + #[command(flatten)] + pub verilog: VerilogArgs, + #[arg( + long, + default_value = "sby", + env = "SBY", + value_hint = ValueHint::CommandName, + value_parser = OsStringValueParser::new().try_map(which) + )] + pub sby: PathBuf, + #[arg(long)] + pub sby_extra_args: Vec, + #[arg(long, default_value_t)] + pub mode: FormalMode, + #[arg(long, default_value_t = Self::DEFAULT_DEPTH)] + pub depth: u64, + #[arg(long, default_value = "z3")] + pub solver: String, + #[arg(long)] + pub smtbmc_extra_args: Vec, + #[arg(long, default_value_t = true, env = "FAYALITE_CACHE_RESULTS")] + pub cache_results: bool, + #[command(flatten)] + _formal_adjust_args: FormalAdjustArgs, +} + +impl fmt::Debug for FormalArgs { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + verilog, + sby, + sby_extra_args, + mode, + depth, + solver, + smtbmc_extra_args, + cache_results, + _formal_adjust_args: _, + } = self; + f.debug_struct("FormalArgs") + .field("verilog", verilog) + .field("sby", sby) + .field("sby_extra_args", sby_extra_args) + .field("mode", mode) + .field("depth", depth) + .field("solver", solver) + .field("smtbmc_extra_args", smtbmc_extra_args) + .field("cache_results", cache_results) + .finish_non_exhaustive() + } +} + +impl FormalArgs { + pub const DEFAULT_DEPTH: u64 = 20; +} + +#[derive(Debug)] +#[non_exhaustive] +pub struct FormalOutput { + pub verilog: VerilogOutput, +} + +impl FormalOutput { + pub fn sby_file(&self) -> PathBuf { + self.verilog.firrtl.file_with_ext("sby") + } + pub fn cache_file(&self) -> PathBuf { + self.verilog.firrtl.file_with_ext("cache.json") + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[non_exhaustive] +pub struct FormalCacheOutput {} + +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[non_exhaustive] +pub enum FormalCacheVersion { + V1, +} + +impl FormalCacheVersion { + pub const CURRENT: Self = Self::V1; +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[non_exhaustive] +pub struct FormalCache { + pub version: FormalCacheVersion, + pub contents_hash: blake3::Hash, + pub stdout_stderr: String, + pub result: Result, +} + +impl FormalCache { + pub fn new( + version: FormalCacheVersion, + contents_hash: blake3::Hash, + stdout_stderr: String, + result: Result, + ) -> Self { + Self { + version, + contents_hash, + stdout_stderr, + result, + } + } +} + +impl FormalArgs { + fn sby_contents(&self, output: &FormalOutput) -> Result { + let Self { + verilog: _, + sby: _, + sby_extra_args: _, + mode, + depth, + smtbmc_extra_args, + solver, + cache_results: _, + _formal_adjust_args: _, + } = self; + let smtbmc_options = smtbmc_extra_args.join(" "); + let top_module = &output.verilog.firrtl.top_module; + let mut retval = format!( + "[options]\n\ + mode {mode}\n\ + depth {depth}\n\ + wait on\n\ + \n\ + [engines]\n\ + smtbmc {solver} -- -- {smtbmc_options}\n\ + \n\ + [script]\n" + ); + for verilog_file in &output.verilog.verilog_files { + let verilog_file = verilog_file + .to_str() + .ok_or_else(|| CliError(eyre!("verilog file path is not UTF-8")))?; + if verilog_file.contains(|ch: char| { + (ch != ' ' && ch != '\t' && ch.is_ascii_whitespace()) || ch == '"' + }) { + return Err(CliError(eyre!( + "verilog file path contains characters that aren't permitted" + ))); + } + writeln!(retval, "read_verilog -sv -formal \"{verilog_file}\"").unwrap(); + } + // workaround for wires disappearing -- set `keep` on all wires + writeln!(retval, "hierarchy -top {top_module}").unwrap(); + writeln!(retval, "proc").unwrap(); + writeln!(retval, "setattr -set keep 1 w:\\*").unwrap(); + writeln!(retval, "prep").unwrap(); + Ok(retval) + } + fn run_impl( + &self, + verilog_output: VerilogOutput, + acquired_job: &mut AcquiredJob, + ) -> Result { + let output = FormalOutput { + verilog: verilog_output, + }; + let sby_file = output.sby_file(); + let sby_contents = self.sby_contents(&output)?; + let contents_hash = output.verilog.contents_hash.map(|verilog_hash| { + let mut hasher = blake3::Hasher::new(); + hasher.update(verilog_hash.as_bytes()); + hasher.update(sby_contents.as_bytes()); + hasher.update(&(self.sby_extra_args.len() as u64).to_le_bytes()); + for sby_extra_arg in self.sby_extra_args.iter() { + hasher.update(&(sby_extra_arg.len() as u64).to_le_bytes()); + hasher.update(sby_extra_arg.as_bytes()); + } + hasher.finalize() + }); + std::fs::write(&sby_file, sby_contents)?; + let mut cmd = process::Command::new(&self.sby); + cmd.arg("-j1"); // sby seems not to respect job count in parallel mode + cmd.arg("-f"); + cmd.arg(sby_file.file_name().unwrap()); + cmd.args(&self.sby_extra_args); + cmd.current_dir(&output.verilog.firrtl.output_dir); + let mut captured_output = String::new(); + let cache_file = output.cache_file(); + let do_cache = if let Some(contents_hash) = contents_hash.filter(|_| self.cache_results) { + if let Some(FormalCache { + version: FormalCacheVersion::CURRENT, + contents_hash: cache_contents_hash, + stdout_stderr, + result, + }) = fs::read(&cache_file) + .ok() + .and_then(|v| serde_json::from_slice(&v).ok()) + { + if cache_contents_hash == contents_hash { + println!("Using cached formal result:\n{stdout_stderr}"); + return match result { + Ok(FormalCacheOutput {}) => Ok(output), + Err(error) => Err(CliError(eyre::Report::msg(error))), + }; + } + } + true + } else { + false + }; + let _ = fs::remove_file(&cache_file); + let status = self.verilog.firrtl.base.run_external_command( + acquired_job, + cmd, + do_cache.then_some(&mut captured_output), + )?; + let result = if status.success() { + Ok(output) + } else { + Err(CliError(eyre!( + "running {} failed: {status}", + self.sby.display() + ))) + }; + fs::write( + cache_file, + serde_json::to_string_pretty(&FormalCache { + version: FormalCacheVersion::CURRENT, + contents_hash: contents_hash.unwrap(), + stdout_stderr: captured_output, + result: match &result { + Ok(FormalOutput { verilog: _ }) => Ok(FormalCacheOutput {}), + Err(error) => Err(error.to_string()), + }, + }) + .expect("serialization shouldn't ever fail"), + )?; + result + } +} + +impl RunPhase for FormalArgs +where + VerilogArgs: RunPhase, +{ + type Output = FormalOutput; + fn run_with_job(&self, arg: Arg, acquired_job: &mut AcquiredJob) -> Result { + let verilog_output = self.verilog.run_with_job(arg, acquired_job)?; + self.run_impl(verilog_output, acquired_job) + } +} + +#[derive(Subcommand, Debug)] +enum CliCommand { + /// Generate FIRRTL + Firrtl(FirrtlArgs), + /// Generate Verilog + Verilog(VerilogArgs), + /// Run a formal proof + Formal(FormalArgs), +} + +/// a simple CLI +/// +/// Use like: +/// +/// ```no_run +/// # use fayalite::prelude::*; +/// # #[hdl_module] +/// # fn my_module() {} +/// use fayalite::cli; +/// +/// fn main() -> cli::Result { +/// cli::Cli::parse().run(my_module()) +/// } +/// ``` +/// +/// You can also use it with a larger [`clap`]-based CLI like so: +/// +/// ```no_run +/// # use fayalite::prelude::*; +/// # #[hdl_module] +/// # fn my_module() {} +/// use clap::{Subcommand, Parser}; +/// use fayalite::cli; +/// +/// #[derive(Subcommand)] +/// pub enum Cmd { +/// #[command(flatten)] +/// Fayalite(cli::Cli), +/// MySpecialCommand { +/// #[arg(long)] +/// foo: bool, +/// }, +/// } +/// +/// #[derive(Parser)] +/// pub struct Cli { +/// #[command(subcommand)] +/// cmd: Cmd, // or just use cli::Cli directly if you don't need more subcommands +/// } +/// +/// fn main() -> cli::Result { +/// match Cli::parse().cmd { +/// Cmd::Fayalite(v) => v.run(my_module())?, +/// Cmd::MySpecialCommand { foo } => println!("special: foo={foo}"), +/// } +/// Ok(()) +/// } +/// ``` +#[derive(Parser, Debug)] +// clear things that would be crate-specific +#[command(name = "Fayalite Simple CLI", about = None, long_about = None)] +pub struct Cli { + #[command(subcommand)] + subcommand: CliCommand, +} + +impl clap::Subcommand for Cli { + fn augment_subcommands(cmd: clap::Command) -> clap::Command { + CliCommand::augment_subcommands(cmd) + } + + fn augment_subcommands_for_update(cmd: clap::Command) -> clap::Command { + CliCommand::augment_subcommands_for_update(cmd) + } + + fn has_subcommand(name: &str) -> bool { + CliCommand::has_subcommand(name) + } +} + +impl RunPhase for Cli +where + FirrtlArgs: RunPhase, +{ + type Output = (); + fn run_with_job(&self, arg: T, acquired_job: &mut AcquiredJob) -> Result { + match &self.subcommand { + CliCommand::Firrtl(c) => { + c.run_with_job(arg, acquired_job)?; + } + CliCommand::Verilog(c) => { + c.run_with_job(arg, acquired_job)?; + } + CliCommand::Formal(c) => { + c.run_with_job(arg, acquired_job)?; + } + } + Ok(()) + } +} + +impl Cli { + /// forwards to [`clap::Parser::parse()`] so you don't have to import [`clap::Parser`] + pub fn parse() -> Self { + clap::Parser::parse() + } + /// forwards to [`RunPhase::run()`] so you don't have to import [`RunPhase`] + pub fn run(&self, top_module: T) -> Result<()> + where + Self: RunPhase, + { + RunPhase::run(self, top_module) + } +} diff --git a/crates/fayalite/src/clock.rs b/crates/fayalite/src/clock.rs index 168142b..909edbd 100644 --- a/crates/fayalite/src/clock.rs +++ b/crates/fayalite/src/clock.rs @@ -1,11 +1,10 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information use crate::{ - expr::{Expr, ValueType}, + expr::{Expr, ToExpr}, hdl, int::Bool, reset::{Reset, ResetType}, - sim::value::SimValue, source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter, @@ -92,34 +91,29 @@ impl StaticType for Clock { } pub trait ToClock { - type Output: ValueType; - fn to_clock(&self) -> Self::Output; + fn to_clock(&self) -> Expr; } impl ToClock for &'_ T { - type Output = T::Output; - fn to_clock(&self) -> Self::Output { + fn to_clock(&self) -> Expr { (**self).to_clock() } } impl ToClock for &'_ mut T { - type Output = T::Output; - fn to_clock(&self) -> Self::Output { + fn to_clock(&self) -> Expr { (**self).to_clock() } } impl ToClock for Box { - type Output = T::Output; - fn to_clock(&self) -> Self::Output { + fn to_clock(&self) -> Expr { (**self).to_clock() } } impl ToClock for Expr { - type Output = Expr; - fn to_clock(&self) -> Self::Output { + fn to_clock(&self) -> Expr { *self } } @@ -131,25 +125,7 @@ pub struct ClockDomain { } impl ToClock for bool { - type Output = SimValue; - - fn to_clock(&self) -> Self::Output { - SimValue::from_value(Clock, *self) - } -} - -impl ToClock for SimValue { - type Output = SimValue; - - fn to_clock(&self) -> Self::Output { - SimValue::from_value(Clock, **self) - } -} - -impl ToClock for SimValue { - type Output = SimValue; - - fn to_clock(&self) -> Self::Output { - self.clone() + fn to_clock(&self) -> Expr { + self.to_expr().to_clock() } } diff --git a/crates/fayalite/src/enum_.rs b/crates/fayalite/src/enum_.rs index a04f67a..083072b 100644 --- a/crates/fayalite/src/enum_.rs +++ b/crates/fayalite/src/enum_.rs @@ -2,7 +2,10 @@ // See Notices.txt for copyright information use crate::{ - expr::{Expr, HdlPartialEq, HdlPartialEqImpl, ToExpr, ValueType, ops::VariantAccess}, + expr::{ + Expr, ToExpr, + ops::{ExprPartialEq, VariantAccess}, + }, hdl, int::{Bool, UIntValue}, intern::{Intern, Interned}, @@ -10,7 +13,7 @@ use crate::{ EnumMatchVariantAndInactiveScopeImpl, EnumMatchVariantsIterImpl, Scope, connect, enum_match_variants_helper, incomplete_wire, wire, }, - sim::value::SimValue, + sim::value::{SimValue, SimValuePartialEq}, source_location::SourceLocation, ty::{ CanonicalType, MatchVariantAndInactiveScope, OpaqueSimValue, OpaqueSimValueSize, @@ -21,7 +24,7 @@ use crate::{ }; use bitvec::{order::Lsb0, slice::BitSlice, view::BitView}; use serde::{Deserialize, Serialize}; -use std::{borrow::Cow, convert::Infallible, fmt, iter::FusedIterator, sync::Arc}; +use std::{convert::Infallible, fmt, iter::FusedIterator, sync::Arc}; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] pub struct EnumVariant { @@ -596,7 +599,7 @@ impl<'a> EnumSimValueFromOpaque<'a> { let (Some(variant_ty), variant_bits, padding_bits) = self.known_variant(true) else { self.usage_error(true); }; - assert_eq!(value.ty(), T::from_canonical(variant_ty)); + assert_eq!(SimValue::ty(value), T::from_canonical(variant_ty)); SimValue::bits_mut(value) .bits_mut() .copy_from_bitslice(variant_bits); @@ -708,7 +711,7 @@ impl<'a> EnumSimValueToOpaque<'a> { let Some(variant_ty) = self.variants[discriminant].ty else { panic!("expected variant to have no field"); }; - assert_eq!(value.ty(), T::from_canonical(variant_ty)); + assert_eq!(SimValue::ty(value), T::from_canonical(variant_ty)); self.known_variant(discriminant, Some(SimValue::opaque(value)), padding) } } @@ -729,38 +732,9 @@ pub enum HdlOption { HdlSome(T), } -impl, Rhs: Type> HdlPartialEqImpl> - for HdlOption -{ - fn cmp_value_eq( - lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - rhs: HdlOption, - rhs_value: Cow<'_, as Type>::SimValue>, - ) -> bool { - type SimValueMatch = ::SimValue; - match (&*lhs_value, &*rhs_value) { - (SimValueMatch::::HdlNone(_), SimValueMatch::>::HdlNone(_)) => { - true - } - (SimValueMatch::::HdlSome(..), SimValueMatch::>::HdlNone(_)) - | (SimValueMatch::::HdlNone(_), SimValueMatch::>::HdlSome(..)) => { - false - } - ( - SimValueMatch::::HdlSome(l, _), - SimValueMatch::>::HdlSome(r, _), - ) => HdlPartialEqImpl::cmp_value_eq( - lhs.HdlSome, - Cow::Borrowed(&**l), - rhs.HdlSome, - Cow::Borrowed(&**r), - ), - } - } - +impl, Rhs: Type> ExprPartialEq> for HdlOption { #[hdl] - fn cmp_expr_eq(lhs: Expr, rhs: Expr>) -> Expr { + fn cmp_eq(lhs: Expr, rhs: Expr>) -> Expr { #[hdl] let cmp_eq = wire(); #[hdl] @@ -769,7 +743,7 @@ impl, Rhs: Type> HdlPartialEqImpl connect(cmp_eq, lhs.cmp_eq(rhs)), + HdlSome(rhs) => connect(cmp_eq, ExprPartialEq::cmp_eq(lhs, rhs)), HdlNone => connect(cmp_eq, false), } } @@ -786,7 +760,7 @@ impl, Rhs: Type> HdlPartialEqImpl, rhs: Expr>) -> Expr { + fn cmp_ne(lhs: Expr, rhs: Expr>) -> Expr { #[hdl] let cmp_ne = wire(); #[hdl] @@ -795,7 +769,7 @@ impl, Rhs: Type> HdlPartialEqImpl connect(cmp_ne, lhs.cmp_ne(rhs)), + HdlSome(rhs) => connect(cmp_ne, ExprPartialEq::cmp_ne(lhs, rhs)), HdlNone => connect(cmp_ne, true), } } @@ -812,6 +786,25 @@ impl, Rhs: Type> HdlPartialEqImpl, 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() @@ -820,7 +813,7 @@ pub fn HdlNone() -> Expr> { #[allow(non_snake_case)] pub fn HdlSome(value: impl ToExpr) -> Expr> { let value = value.to_expr(); - HdlOption[value.ty()].HdlSome(value) + HdlOption[Expr::ty(value)].HdlSome(value) } impl HdlOption { @@ -860,7 +853,7 @@ impl HdlOption { let value = f(value).inspect_err(|_| { and_then_out.complete(()); // avoid error })?; - let and_then_out = and_then_out.complete(value.ty()); + let and_then_out = and_then_out.complete(Expr::ty(value)); connect(and_then_out, value); drop(some_scope); let (Wrap::<::MatchVariant>::HdlNone, none_scope) = @@ -868,7 +861,7 @@ impl HdlOption { else { unreachable!(); }; - connect(and_then_out, and_then_out.ty().HdlNone()); + connect(and_then_out, Expr::ty(and_then_out).HdlNone()); drop(none_scope); Ok(and_then_out) } @@ -886,8 +879,8 @@ impl HdlOption { #[track_caller] pub fn and(expr: Expr, opt_b: Expr>) -> Expr> { #[hdl] - let and_out = wire(opt_b.ty()); - connect(and_out, opt_b.ty().HdlNone()); + let and_out = wire(Expr::ty(opt_b)); + connect(and_out, Expr::ty(opt_b).HdlNone()); #[hdl] if let HdlSome(_) = expr { connect(and_out, opt_b); @@ -901,8 +894,8 @@ impl HdlOption { f: impl FnOnce(Expr) -> Result, E>, ) -> Result, E> { #[hdl] - let filtered = wire(expr.ty()); - connect(filtered, expr.ty().HdlNone()); + let filtered = wire(Expr::ty(expr)); + connect(filtered, Expr::ty(expr).HdlNone()); let mut f = Some(f); #[hdl] if let HdlSome(v) = expr { @@ -976,7 +969,7 @@ impl HdlOption { f: impl FnOnce(Expr) -> Expr, ) -> Expr { #[hdl] - let mapped = wire(default.ty()); + let mapped = wire(Expr::ty(default)); let mut f = Some(f); #[hdl] match expr { @@ -1001,12 +994,12 @@ impl HdlOption { match expr { HdlSome(v) => { let v = f.take().unwrap()(v); - let mapped = *retval.get_or_insert_with(|| mapped.complete(v.ty())); + let mapped = *retval.get_or_insert_with(|| mapped.complete(Expr::ty(v))); connect(mapped, v); } HdlNone => { let v = default.take().unwrap()(); - let mapped = *retval.get_or_insert_with(|| mapped.complete(v.ty())); + let mapped = *retval.get_or_insert_with(|| mapped.complete(Expr::ty(v))); connect(mapped, v); } } @@ -1016,7 +1009,7 @@ impl HdlOption { #[track_caller] pub fn or(expr: Expr, opt_b: Expr) -> Expr { #[hdl] - let or_out = wire(expr.ty()); + let or_out = wire(Expr::ty(expr)); connect(or_out, opt_b); #[hdl] if let HdlSome(_) = expr { @@ -1028,7 +1021,7 @@ impl HdlOption { #[track_caller] pub fn or_else(expr: Expr, f: impl FnOnce() -> Expr) -> Expr { #[hdl] - let or_else_out = wire(expr.ty()); + let or_else_out = wire(Expr::ty(expr)); connect(or_else_out, f()); #[hdl] if let HdlSome(_) = expr { @@ -1040,7 +1033,7 @@ impl HdlOption { #[track_caller] pub fn unwrap_or(expr: Expr, default: Expr) -> Expr { #[hdl] - let unwrap_or_else_out = wire(default.ty()); + let unwrap_or_else_out = wire(Expr::ty(default)); connect(unwrap_or_else_out, default); #[hdl] if let HdlSome(v) = expr { @@ -1052,7 +1045,7 @@ impl HdlOption { #[track_caller] pub fn unwrap_or_else(expr: Expr, f: impl FnOnce() -> Expr) -> Expr { #[hdl] - let unwrap_or_else_out = wire(expr.ty().HdlSome); + let unwrap_or_else_out = wire(Expr::ty(expr).HdlSome); connect(unwrap_or_else_out, f()); #[hdl] if let HdlSome(v) = expr { @@ -1064,14 +1057,14 @@ impl HdlOption { #[track_caller] pub fn xor(expr: Expr, opt_b: Expr) -> Expr { #[hdl] - let xor_out = wire(expr.ty()); + let xor_out = wire(Expr::ty(expr)); #[hdl] if let HdlSome(_) = expr { #[hdl] if let HdlNone = opt_b { connect(xor_out, expr); } else { - connect(xor_out, expr.ty().HdlNone()); + connect(xor_out, Expr::ty(expr).HdlNone()); } } else { connect(xor_out, opt_b); @@ -1082,8 +1075,8 @@ impl HdlOption { #[track_caller] pub fn zip(expr: Expr, other: Expr>) -> Expr> { #[hdl] - let zip_out = wire(HdlOption[(expr.ty().HdlSome, other.ty().HdlSome)]); - connect(zip_out, zip_out.ty().HdlNone()); + let zip_out = wire(HdlOption[(Expr::ty(expr).HdlSome, Expr::ty(other).HdlSome)]); + connect(zip_out, Expr::ty(zip_out).HdlNone()); #[hdl] if let HdlSome(l) = expr { #[hdl] @@ -1100,11 +1093,11 @@ impl HdlOption> { #[track_caller] pub fn flatten(expr: Expr) -> Expr> { #[hdl] - let flattened = wire(expr.ty().HdlSome); + let flattened = wire(Expr::ty(expr).HdlSome); #[hdl] match expr { HdlSome(v) => connect(flattened, v), - HdlNone => connect(flattened, expr.ty().HdlSome.HdlNone()), + HdlNone => connect(flattened, Expr::ty(expr).HdlSome.HdlNone()), } flattened } @@ -1114,7 +1107,7 @@ impl HdlOption<(T, U)> { #[hdl] #[track_caller] pub fn unzip(expr: Expr) -> Expr<(HdlOption, HdlOption)> { - let (t, u) = expr.ty().HdlSome; + let (t, u) = Expr::ty(expr).HdlSome; #[hdl] let unzipped = wire((HdlOption[t], HdlOption[u])); connect(unzipped, (HdlOption[t].HdlNone(), HdlOption[u].HdlNone())); diff --git a/crates/fayalite/src/expr.rs b/crates/fayalite/src/expr.rs index 00a0cee..89e60cd 100644 --- a/crates/fayalite/src/expr.rs +++ b/crates/fayalite/src/expr.rs @@ -5,8 +5,11 @@ use crate::{ array::{Array, ArrayType}, bundle::{Bundle, BundleType}, enum_::{Enum, EnumType}, - expr::target::{GetTarget, Target}, - int::{Bool, DynSize, IntType, SIntValue, Size, SizeType, UInt, UIntType, UIntValue}, + expr::{ + ops::ExprCastTo, + target::{GetTarget, Target}, + }, + int::{Bool, DynSize, IntType, SIntType, SIntValue, Size, SizeType, UInt, UIntType, UIntValue}, intern::{Intern, Interned}, memory::{DynPortType, MemPort, PortType}, module::{ @@ -16,17 +19,14 @@ use crate::{ phantom_const::PhantomConst, reg::Reg, reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset}, - sim::value::{SimValue, ToSimValue, ToSimValueWithType}, - ty::{CanonicalType, OpaqueSimValue, StaticType, Type, TypeWithDeref}, - util::{ConstBool, ConstUsize}, + ty::{CanonicalType, StaticType, Type, TypeWithDeref}, wire::Wire, }; use bitvec::slice::BitSlice; -use std::{borrow::Cow, convert::Infallible, fmt, ops::Deref}; +use std::{convert::Infallible, fmt, ops::Deref}; pub mod ops; pub mod target; -pub mod value_category; macro_rules! expr_enum { ( @@ -77,18 +77,9 @@ macro_rules! expr_enum { } } - impl ValueType for $ExprEnum { - type Type = CanonicalType; - type ValueCategory = value_category::ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - match self { - $(Self::$Variant(v) => v.ty().canonical(),)* - } - } - } - impl ToExpr for $ExprEnum { + type Type = CanonicalType; + fn to_expr(&self) -> Expr { match self { $(Self::$Variant(v) => Expr::canonical(v.to_expr()),)* @@ -291,7 +282,7 @@ impl fmt::Debug for Expr { __flow, } = self; let expr_ty = __ty.canonical(); - let enum_ty = __enum.to_expr().ty(); + 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}}" @@ -305,20 +296,23 @@ impl Expr { pub fn expr_enum(this: Self) -> Interned { this.__enum } + pub fn ty(this: Self) -> T { + this.__ty + } pub fn flow(this: Self) -> Flow { this.__flow } pub fn canonical(this: Self) -> Expr { Expr { __enum: this.__enum, - __ty: this.ty().canonical(), + __ty: this.__ty.canonical(), __flow: this.__flow, } } pub fn from_canonical(this: Expr) -> Self { Expr { __enum: this.__enum, - __ty: T::from_canonical(this.ty()), + __ty: T::from_canonical(this.__ty), __flow: this.__flow, } } @@ -328,7 +322,7 @@ impl Expr { { Expr { __enum: this.__enum, - __ty: T::from_dyn_int(this.ty()), + __ty: T::from_dyn_int(this.__ty), __flow: this.__flow, } } @@ -338,7 +332,7 @@ impl Expr { { Expr { __enum: this.__enum, - __ty: this.ty().as_dyn_int(), + __ty: this.__ty.as_dyn_int(), __flow: this.__flow, } } @@ -348,7 +342,7 @@ impl Expr { { Expr { __enum: this.__enum, - __ty: Bundle::new(this.ty().fields()), + __ty: Bundle::new(this.__ty.fields()), __flow: this.__flow, } } @@ -358,7 +352,7 @@ impl Expr { { Expr { __enum: this.__enum, - __ty: T::from_canonical(CanonicalType::Bundle(this.ty())), + __ty: T::from_canonical(CanonicalType::Bundle(this.__ty)), __flow: this.__flow, } } @@ -375,7 +369,7 @@ impl Expr { { Expr { __enum: this.__enum, - __ty: Enum::new(this.ty().variants()), + __ty: Enum::new(this.__ty.variants()), __flow: this.__flow, } } @@ -385,7 +379,7 @@ impl Expr { { Expr { __enum: this.__enum, - __ty: T::from_canonical(CanonicalType::Enum(this.ty())), + __ty: T::from_canonical(CanonicalType::Enum(this.__ty)), __flow: this.__flow, } } @@ -415,7 +409,7 @@ impl Expr> { pub fn as_dyn_array(this: Self) -> Expr { Expr { __enum: this.__enum, - __ty: this.ty().as_dyn_array(), + __ty: this.__ty.as_dyn_array(), __flow: this.__flow, } } @@ -441,41 +435,54 @@ impl Visit for Expr { } } -pub trait ToExpr: ValueType + ToValueless { +pub trait ToExpr { + type Type: Type; fn to_expr(&self) -> Expr; } impl ToExpr for Expr { + type Type = T; + fn to_expr(&self) -> Expr { *self } } impl ToExpr for &'_ T { + type Type = T::Type; + fn to_expr(&self) -> Expr { T::to_expr(self) } } impl ToExpr for &'_ mut T { + type Type = T::Type; + fn to_expr(&self) -> Expr { T::to_expr(self) } } impl ToExpr for Box { + type Type = T::Type; + fn to_expr(&self) -> Expr { T::to_expr(self) } } impl ToExpr for Interned { + type Type = T::Type; + fn to_expr(&self) -> Expr { T::to_expr(self) } } impl ToExpr for UIntValue { + type Type = UIntType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::UIntLiteral(self.clone().as_dyn_int().intern()).intern(), @@ -486,6 +493,8 @@ impl ToExpr for UIntValue { } impl ToExpr for SIntValue { + type Type = SIntType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::SIntLiteral(self.clone().as_dyn_int().intern()).intern(), @@ -495,16 +504,9 @@ impl ToExpr for SIntValue { } } -impl ValueType for bool { - type Type = Bool; - type ValueCategory = value_category::ValueCategoryValue; - - fn ty(&self) -> Self::Type { - Bool - } -} - impl ToExpr for bool { + type Type = Bool; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::BoolLiteral(*self).intern(), @@ -535,6 +537,8 @@ impl Flow { } impl ToExpr for ModuleIO { + type Type = T; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::ModuleIO(self.canonical()).intern_sized(), @@ -557,6 +561,8 @@ impl GetTarget for ModuleIO { } impl ToExpr for Instance { + type Type = T; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::Instance(self.canonical()).intern_sized(), @@ -579,6 +585,8 @@ impl GetTarget for Instance { } impl ToExpr for Wire { + type Type = T; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::Wire(self.canonical()).intern_sized(), @@ -601,6 +609,8 @@ impl GetTarget for Wire { } impl ToExpr for Reg { + type Type = T; + fn to_expr(&self) -> Expr { struct Dispatch; impl ResetTypeDispatch for Dispatch { @@ -640,6 +650,8 @@ impl GetTarget for Reg { } impl ToExpr for MemPort { + type Type = T::Port; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::MemPort(self.canonical()).intern_sized(), @@ -661,840 +673,69 @@ impl GetTarget for MemPort { } } -macro_rules! impl_hdl_cmp { - ( - #[ - impl_helper = $HdlCmpImplHelper:ident, - $(impl_helper_base = $HdlCmpImplHelperBase:ident,)? - impl_helper_sealed = $HdlCmpImplHelperSealed:ident, - ] - $vis:vis trait $HdlCmp:ident<$Rhs:ident: ValueType>: - ValueType $(+ $HdlCmpImplBase:ident)?> $(+ $HdlCmpBase:ident)? - { - $(type $Output:ident: ValueType;)? - $(#[ - helper = $cmp_fn_helper:ident; - value = $cmp_value_fn:ident( - $cmp_value_lhs:ident, - $cmp_value_lhs_value:ident, - $cmp_value_rhs:ident, - $cmp_value_rhs_value:ident $(,)? - ) $cmp_value_body:tt - sim_value = $cmp_sim_value_fn:ident; - expr = $cmp_expr_fn:ident($cmp_expr_lhs:ident, $cmp_expr_rhs:ident) $cmp_expr_body:tt - valueless = $cmp_valueless_fn:ident; - ] - fn $cmp_fn:ident(&self, rhs: Rhs) -> Self::Output;)+ - } - ) => { - $vis trait $HdlCmp<$Rhs: ValueType>: - ValueType> $(+ $HdlCmpBase<$Rhs>)? - { - $(type $Output: ValueType;)? - $(fn $cmp_fn(&self, rhs: $Rhs) -> Self::Output;)+ - } - - $vis trait $HdlCmpImpl<$Rhs: Type>: Type $(+ $HdlCmpImplBase<$Rhs>)? { - $(#[track_caller] - fn $cmp_value_fn( - $cmp_value_lhs: Self, - $cmp_value_lhs_value: Cow<'_, Self::SimValue>, - $cmp_value_rhs: $Rhs, - $cmp_value_rhs_value: Cow<'_, $Rhs::SimValue>, - ) -> bool - $cmp_value_body)+ - - $(#[track_caller] - fn $cmp_sim_value_fn(lhs: Cow<'_, SimValue>, rhs: Cow<'_, SimValue<$Rhs>>) -> SimValue { - let lhs_ty = lhs.ty(); - let rhs_ty = rhs.ty(); - let lhs = match lhs { - Cow::Borrowed(v) => Cow::Borrowed(&**v), - Cow::Owned(v) => Cow::Owned(SimValue::into_value(v)), - }; - let rhs = match rhs { - Cow::Borrowed(v) => Cow::Borrowed(&**v), - Cow::Owned(v) => Cow::Owned(SimValue::into_value(v)), - }; - Self::$cmp_value_fn(lhs_ty, lhs, rhs_ty, rhs).to_sim_value() - })+ - - $(#[track_caller] - fn $cmp_expr_fn($cmp_expr_lhs: Expr, $cmp_expr_rhs: Expr<$Rhs>) -> Expr - $cmp_expr_body)+ - - $(#[track_caller] - fn $cmp_valueless_fn(lhs: Valueless, rhs: Valueless<$Rhs>) -> Valueless { - let _ = lhs; - let _ = rhs; - Valueless::new(Bool) - })+ - } - - trait $HdlCmpImplHelperSealed<$Rhs, Common> {} - - #[expect(private_bounds)] - $vis trait $HdlCmpImplHelper<$Rhs: ValueType, Common: value_category::ValueCategory>: - $HdlCmpImplHelperSealed<$Rhs, Common> - + ValueType> - $(+ $HdlCmpImplHelperBase<$Rhs, Common>)? - { - $(type $Output: ValueType;)? - $(#[track_caller] - fn $cmp_fn_helper(&self, rhs: $Rhs) -> Self::Output;)+ - } - - impl $HdlCmp<$Rhs> for Lhs - where - Lhs: ?Sized + ValueType $(+ $HdlCmpBase<$Rhs>)?, - $Rhs: ValueType, - LTy: Type + $HdlCmpImpl, - RTy: Type, - LC: value_category::ValueCategory + value_category::ValueCategoryCommon<(RC,), Common = Common>, - RC: value_category::ValueCategory, - Common: value_category::ValueCategory, - Lhs: $HdlCmpImplHelper<$Rhs, Common> $(+ $HdlCmpImplHelperBase<$Rhs, Common, Output = Self::Output>)?, - { - $(type $Output = >::Output;)? - - $(#[track_caller] - fn $cmp_fn(&self, rhs: $Rhs) -> Self::Output { - >::$cmp_fn_helper(self, rhs) - })+ - } - - impl<'l, 'r, Lhs, $Rhs, LTy, RTy> $HdlCmpImplHelperSealed<$Rhs, value_category::ValueCategoryValue> for Lhs - where - Lhs: ?Sized + ValueType + ToSimValueInner<'l> - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategoryValue, Output = bool>)?, - $Rhs: ValueType + ToSimValueInner<'r>, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - } - - impl<'l, 'r, Lhs, $Rhs, LTy, RTy> $HdlCmpImplHelper<$Rhs, value_category::ValueCategoryValue> for Lhs - where - Lhs: ?Sized + ValueType + ToSimValueInner<'l> - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategoryValue, Output = bool>)?, - $Rhs: ValueType + ToSimValueInner<'r>, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - $(type $Output = bool;)? - - $(#[track_caller] - fn $cmp_fn_helper(&self, rhs: Rhs) -> Self::Output { - $HdlCmpImpl::$cmp_value_fn( - self.ty(), - Lhs::to_sim_value_inner(self), - rhs.ty(), - $Rhs::into_sim_value_inner(rhs), - ) - })+ - } - - impl $HdlCmpImplHelperSealed<$Rhs, value_category::ValueCategorySimValue> for Lhs - where - Lhs: ?Sized + ValueType + ToSimValue - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategorySimValue, Output = SimValue>)?, - $Rhs: ValueType + ToSimValue, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - } - - impl $HdlCmpImplHelper<$Rhs, value_category::ValueCategorySimValue> for Lhs - where - Lhs: ?Sized + ValueType + ToSimValue - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategorySimValue, Output = SimValue>)?, - $Rhs: ValueType + ToSimValue, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - $(type $Output = SimValue;)? - - $(#[track_caller] - fn $cmp_fn_helper(&self, rhs: Rhs) -> Self::Output { - $HdlCmpImpl::$cmp_sim_value_fn(Cow::Owned(Lhs::to_sim_value(self)), Cow::Owned($Rhs::into_sim_value(rhs))) - })+ - } - - impl $HdlCmpImplHelperSealed<$Rhs, value_category::ValueCategoryExpr> for Lhs - where - Lhs: ?Sized + ValueType + ToExpr - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategoryExpr, Output = Expr>)?, - $Rhs: ValueType + ToExpr, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - } - - impl $HdlCmpImplHelper<$Rhs, value_category::ValueCategoryExpr> for Lhs - where - Lhs: ?Sized + ValueType + ToExpr - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategoryExpr, Output = Expr>)?, - $Rhs: ValueType + ToExpr, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - $(type $Output = Expr;)? - - $(#[track_caller] - fn $cmp_fn_helper(&self, rhs: Rhs) -> Self::Output { - $HdlCmpImpl::$cmp_expr_fn(Lhs::to_expr(self), $Rhs::to_expr(&rhs)) - })+ - } - - impl $HdlCmpImplHelperSealed<$Rhs, value_category::ValueCategoryValueless> for Lhs - where - Lhs: ?Sized + ValueType - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategoryValueless, Output = Valueless>)?, - $Rhs: ValueType, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - } - - impl $HdlCmpImplHelper<$Rhs, value_category::ValueCategoryValueless> for Lhs - where - Lhs: ?Sized + ValueType - $(+ $HdlCmpImplHelperBase<$Rhs, value_category::ValueCategoryValueless, Output = Valueless>)?, - $Rhs: ValueType, - LTy: Type + $HdlCmpImpl, - RTy: Type, - { - $(type $Output = Valueless;)? - - $(#[track_caller] - fn $cmp_fn_helper(&self, rhs: Rhs) -> Self::Output { - $HdlCmpImpl::$cmp_valueless_fn(Lhs::to_valueless(self), $Rhs::to_valueless(&rhs)) - })+ - } - }; +pub trait HdlPartialEq { + fn cmp_eq(self, rhs: Rhs) -> Expr; + fn cmp_ne(self, rhs: Rhs) -> Expr; } -impl_hdl_cmp! { - #[ - impl_helper = HdlPartialEqImplHelper, - impl_helper_sealed = HdlPartialEqImplHelperSealed, - ] - pub trait HdlPartialEq: - ValueType > +pub trait HdlPartialOrd: HdlPartialEq { + fn cmp_lt(self, rhs: Rhs) -> Expr; + fn cmp_le(self, rhs: Rhs) -> Expr; + fn cmp_gt(self, rhs: Rhs) -> Expr; + fn cmp_ge(self, rhs: Rhs) -> Expr; +} + +pub trait ReduceBits { + type UIntOutput; + type BoolOutput; + fn reduce_bitand(self) -> Self::UIntOutput; + fn reduce_bitor(self) -> Self::UIntOutput; + fn reduce_bitxor(self) -> Self::UIntOutput; + fn any_one_bits(self) -> Self::BoolOutput; + fn any_zero_bits(self) -> Self::BoolOutput; + fn all_one_bits(self) -> Self::BoolOutput; + fn all_zero_bits(self) -> Self::BoolOutput; + fn parity_odd(self) -> Self::BoolOutput; + fn parity_even(self) -> Self::BoolOutput; +} + +pub trait CastToBits { + fn cast_to_bits(&self) -> Expr; +} + +impl CastToBits for T { + fn cast_to_bits(&self) -> Expr { + ops::CastToBits::new(Expr::canonical(self.to_expr())).to_expr() + } +} + +pub trait CastBitsTo { + #[track_caller] + fn cast_bits_to(&self, ty: T) -> Expr; +} + +impl> + ?Sized, Width: Size> CastBitsTo for T { + fn cast_bits_to(&self, ty: ToType) -> Expr { + ops::CastBitsTo::new(Expr::as_dyn_int(self.to_expr()), ty).to_expr() + } +} + +pub trait CastTo: ToExpr { + fn cast_to(&self, to_type: ToType) -> Expr + where + Self::Type: ExprCastTo, { - type Output: ValueType; - #[ - helper = cmp_eq_helper; - value = cmp_value_eq(lhs, lhs_value, rhs, rhs_value); - sim_value = cmp_sim_value_eq; - expr = cmp_expr_eq(lhs, rhs); - valueless = cmp_valueless_eq; - ] - fn cmp_eq(&self, rhs: Rhs) -> Self::Output; - #[ - helper = cmp_ne_helper; - value = cmp_value_ne(lhs, lhs_value, rhs, rhs_value) { - !Self::cmp_value_eq(lhs, lhs_value, rhs, rhs_value) - } - sim_value = cmp_sim_value_ne; - expr = cmp_expr_ne(lhs, rhs) { - !Self::cmp_expr_eq(lhs, rhs) - } - valueless = cmp_valueless_ne; - ] - fn cmp_ne(&self, rhs: Rhs) -> Self::Output; + ExprCastTo::cast_to(self.to_expr(), to_type) } -} - -impl_hdl_cmp! { - #[ - impl_helper = HdlPartialOrdImplHelper, - impl_helper_base = HdlPartialEqImplHelper, - impl_helper_sealed = HdlPartialOrdImplHelperSealed, - ] - pub trait HdlPartialOrd: - ValueType + HdlPartialEqImpl > - + HdlPartialEq + fn cast_to_static(&self) -> Expr + where + Self::Type: ExprCastTo, { - #[ - helper = cmp_lt_helper; - value = cmp_value_lt(lhs, lhs_value, rhs, rhs_value); - sim_value = cmp_sim_value_lt; - expr = cmp_expr_lt(lhs, rhs); - valueless = cmp_valueless_lt; - ] - fn cmp_lt(&self, rhs: Rhs) -> Self::Output; - #[ - helper = cmp_le_helper; - value = cmp_value_le(lhs, lhs_value, rhs, rhs_value); - sim_value = cmp_sim_value_le; - expr = cmp_expr_le(lhs, rhs); - valueless = cmp_valueless_le; - ] - fn cmp_le(&self, rhs: Rhs) -> Self::Output; - #[ - helper = cmp_gt_helper; - value = cmp_value_gt(lhs, lhs_value, rhs, rhs_value); - sim_value = cmp_sim_value_gt; - expr = cmp_expr_gt(lhs, rhs); - valueless = cmp_valueless_gt; - ] - fn cmp_gt(&self, rhs: Rhs) -> Self::Output; - #[ - helper = cmp_ge_helper; - value = cmp_value_ge(lhs, lhs_value, rhs, rhs_value); - sim_value = cmp_sim_value_ge; - expr = cmp_expr_ge(lhs, rhs); - valueless = cmp_valueless_ge; - ] - fn cmp_ge(&self, rhs: Rhs) -> Self::Output; + ExprCastTo::cast_to(self.to_expr(), ToType::TYPE) } } -macro_rules! make_reduce_bits_traits { - ( - $vis:vis trait $ReduceBits:ident { - $(type $Output:ident: ValueType;)* - $(#[ - ty = $ty:ty, - value_ty = $value_ty:ty, - value = $value_f:ident($value_this:ident, $value_value:ident) $value_body:tt - sim_value = $sim_value_f:ident, - expr = $expr_f:ident($expr_this:ident) $expr_body:tt - valueless = $valueless_f:ident, - ] - fn $f:ident(&self) -> Self::$FnOutput:ident;)* - } - ) => { - $vis trait $ReduceBits { - $(type $Output: ValueType;)* - $(fn $f(&self) -> Self::$FnOutput;)* - } - - trait ReduceBitsImplHelperSealed {} - - #[expect(private_bounds)] - $vis trait ReduceBitsImplHelper: ReduceBitsImplHelperSealed { - $(type $Output: ValueType;)* - $(fn $f(this: &Self) -> Self::$FnOutput;)* - } - - impl::ValueCategory>> $ReduceBits for T { - $(type $Output = ::ValueCategory>>::$Output;)* - $(fn $f(&self) -> Self::$FnOutput { - ::ValueCategory>>::$f(self) - })* - } - - $vis trait ReduceBitsImpl: Type { - $(fn $value_f($value_this: Self, $value_value: Cow<'_, Self::SimValue>) -> $value_ty $value_body)* - - $(fn $sim_value_f(this: Cow<'_, SimValue>) -> SimValue<$ty> { - let ty = this.ty(); - let value = match this { - Cow::Borrowed(v) => Cow::Borrowed(SimValue::value(v)), - Cow::Owned(v) => Cow::Owned(SimValue::into_value(v)), - }; - Self::$value_f(ty, value).into_sim_value() - })* - - $(fn $expr_f($expr_this: Expr) -> Expr<$ty> $expr_body)* - - $(fn $valueless_f(_this: Valueless) -> Valueless<$ty> { - Valueless::new(StaticType::TYPE) - })* - } - - impl<'a, T> ReduceBitsImplHelperSealed for T - where - T: ?Sized + ValueType + ToSimValueInner<'a>, - { - } - - impl<'a, T> ReduceBitsImplHelper for T - where - T: ?Sized + ValueType + ToSimValueInner<'a>, - { - type UIntOutput = UIntValue>; - type BoolOutput = bool; - - $(fn $f(this: &Self) -> Self::$FnOutput { - T::Type::$value_f(this.ty(), Self::to_sim_value_inner(this)) - })* - } - - impl<'a, T> ReduceBitsImplHelperSealed for T - where - T: ?Sized + ValueType + ToSimValue, - { - } - - impl<'a, T> ReduceBitsImplHelper for T - where - T: ?Sized + ValueType + ToSimValue, - { - type UIntOutput = SimValue>; - type BoolOutput = SimValue; - - $(fn $f(this: &Self) -> Self::$FnOutput { - T::Type::$sim_value_f(Cow::Owned(this.to_sim_value())) - })* - } - - impl<'a, T> ReduceBitsImplHelperSealed for T - where - T: ?Sized + ValueType + ToExpr, - { - } - - impl<'a, T> ReduceBitsImplHelper for T - where - T: ?Sized + ValueType + ToExpr, - { - type UIntOutput = Expr>; - type BoolOutput = Expr; - - $(fn $f(this: &Self) -> Self::$FnOutput { - T::Type::$expr_f(this.to_expr()) - })* - } - - impl<'a, T> ReduceBitsImplHelperSealed for T - where - T: ?Sized + ValueType, - { - } - - impl<'a, T> ReduceBitsImplHelper for T - where - T: ?Sized + ValueType, - { - type UIntOutput = Valueless>; - type BoolOutput = Valueless; - - $(fn $f(this: &Self) -> Self::$FnOutput { - T::Type::$valueless_f(this.to_valueless()) - })* - } - }; -} - -make_reduce_bits_traits! { - pub trait ReduceBits { - type UIntOutput: ValueType>; - type BoolOutput: ValueType; - - #[ - ty = UInt<1>, - value_ty = UIntValue>, - value = value_reduce_bitand(this, value); - sim_value = sim_value_reduce_bitand, - expr = expr_reduce_bitand(this); - valueless = valueless_reduce_bitand, - ] - fn reduce_bitand(&self) -> Self::UIntOutput; - - #[ - ty = UInt<1>, - value_ty = UIntValue>, - value = value_reduce_bitor(this, value); - sim_value = sim_value_reduce_bitor, - expr = expr_reduce_bitor(this); - valueless = valueless_reduce_bitor, - ] - fn reduce_bitor(&self) -> Self::UIntOutput; - - #[ - ty = UInt<1>, - value_ty = UIntValue>, - value = value_reduce_bitxor(this, value); - sim_value = sim_value_reduce_bitxor, - expr = expr_reduce_bitxor(this); - valueless = valueless_reduce_bitxor, - ] - fn reduce_bitxor(&self) -> Self::UIntOutput; - - #[ - ty = Bool, - value_ty = bool, - value = value_any_one_bits(this, value) { - Self::value_reduce_bitor(this, value).bits()[0] - } - sim_value = sim_value_any_one_bits, - expr = expr_any_one_bits(this) { - this.reduce_bitor().cast_to_static() - } - valueless = valueless_any_one_bits, - ] - fn any_one_bits(&self) -> Self::BoolOutput; - - #[ - ty = Bool, - value_ty = bool, - value = value_any_zero_bits(this, value) { - !Self::value_reduce_bitand(this, value).bits()[0] - } - sim_value = sim_value_any_zero_bits, - expr = expr_any_zero_bits(this) { - (!this.reduce_bitand()).cast_to_static() - } - valueless = valueless_any_zero_bits, - ] - fn any_zero_bits(&self) -> Self::BoolOutput; - - #[ - ty = Bool, - value_ty = bool, - value = value_all_one_bits(this, value) { - Self::value_reduce_bitand(this, value).bits()[0] - } - sim_value = sim_value_all_one_bits, - expr = expr_all_one_bits(this) { - this.reduce_bitand().cast_to_static() - } - valueless = valueless_all_one_bits, - ] - fn all_one_bits(&self) -> Self::BoolOutput; - - #[ - ty = Bool, - value_ty = bool, - value = value_all_zero_bits(this, value) { - !Self::value_reduce_bitor(this, value).bits()[0] - } - sim_value = sim_value_all_zero_bits, - expr = expr_all_zero_bits(this) { - (!this.reduce_bitor()).cast_to_static() - } - valueless = valueless_all_zero_bits, - ] - fn all_zero_bits(&self) -> Self::BoolOutput; - - #[ - ty = Bool, - value_ty = bool, - value = value_parity_odd(this, value) { - Self::value_reduce_bitxor(this, value).bits()[0] - } - sim_value = sim_value_parity_odd, - expr = expr_parity_odd(this) { - this.reduce_bitxor().cast_to_static() - } - valueless = valueless_parity_odd, - ] - fn parity_odd(&self) -> Self::BoolOutput; - - #[ - ty = Bool, - value_ty = bool, - value = value_parity_even(this, value) { - !Self::value_reduce_bitxor(this, value).bits()[0] - } - sim_value = sim_value_parity_even, - expr = expr_parity_even(this) { - (!this.reduce_bitxor()).cast_to_static() - } - valueless = valueless_parity_even, - ] - fn parity_even(&self) -> Self::BoolOutput; - } -} - -pub trait CastToBits: ValueType { - type Output: ValueType; - fn cast_to_bits(&self) -> Self::Output; -} - -impl> CastToBits for T { - type Output = T::ImplOutput; - fn cast_to_bits(&self) -> Self::Output { - Self::cast_to_bits_impl(self) - } -} - -pub trait CastToBitsImpl { - type ImplOutput: ValueType; - fn cast_to_bits_impl(this: &Self) -> Self::ImplOutput; -} - -impl - CastToBitsImpl for T -{ - type ImplOutput = UIntValue; - - fn cast_to_bits_impl(this: &Self) -> Self::ImplOutput { - crate::sim::value::SimValue::bits(&this.to_sim_value()).clone() - } -} - -impl - CastToBitsImpl for T -{ - type ImplOutput = SimValue; - - fn cast_to_bits_impl(this: &Self) -> Self::ImplOutput { - crate::sim::value::SimValue::bits(&this.to_sim_value()).to_sim_value() - } -} - -impl CastToBitsImpl for T { - type ImplOutput = Expr; - - fn cast_to_bits_impl(this: &Self) -> Self::ImplOutput { - ops::CastToBits::new(Expr::canonical(this.to_expr())).to_expr() - } -} - -impl CastToBitsImpl for T { - type ImplOutput = Valueless; - - fn cast_to_bits_impl(this: &Self) -> Self::ImplOutput { - Valueless::new(UInt::new_dyn(this.ty().canonical().bit_width())) - } -} - -pub trait CastBitsTo: ValueType>> { - type Output: ValueType; - - #[track_caller] - fn cast_bits_to(&self, ty: T) -> Self::Output; -} - -impl< - This: ?Sized + ValueType> + CastBitsToImpl, - Width: Size, -> CastBitsTo for This -{ - type Output = This::ImplOutput; - - #[track_caller] - fn cast_bits_to(&self, ty: T) -> Self::Output { - Self::cast_bits_to_impl(self, ty) - } -} - -pub trait CastBitsToImpl { - type ImplOutput: ValueType; - - #[track_caller] - fn cast_bits_to_impl(this: &Self, ty: T) -> Self::ImplOutput; -} - -impl< - 'a, - This: ?Sized + ValueType> + ToSimValueInner<'a>, - Width: Size, - C: value_category::ValueCategoryIsValueOrSimValue, -> CastBitsToImpl for This -{ - type ImplOutput = SimValue; - - #[track_caller] - fn cast_bits_to_impl(this: &Self, ty: T) -> Self::ImplOutput { - let ty_props = ty.canonical().type_properties(); - assert!(ty_props.is_castable_from_bits); - assert_eq!(this.ty().width(), ty_props.bit_width); - crate::sim::value::SimValue::from_opaque( - ty, - OpaqueSimValue::from_bits(Self::to_sim_value_inner(this).into_owned().as_dyn_int()), - ) - } -} - -impl> + ToExpr, Width: Size> - CastBitsToImpl for This -{ - type ImplOutput = Expr; - - #[track_caller] - fn cast_bits_to_impl(this: &Self, ty: T) -> Self::ImplOutput { - ops::CastBitsTo::new(Expr::as_dyn_int(this.to_expr()), ty).to_expr() - } -} - -impl>, Width: Size> - CastBitsToImpl for This -{ - type ImplOutput = Valueless; - - #[track_caller] - fn cast_bits_to_impl(this: &Self, ty: T) -> Self::ImplOutput { - let ty_props = ty.canonical().type_properties(); - assert!(ty_props.is_castable_from_bits); - assert_eq!(this.ty().width(), ty_props.bit_width); - Valueless::new(ty) - } -} - -pub trait CastToImpl: Type { - type ValueOutput: ValueType - + ToSimValueWithType; - #[track_caller] - fn cast_value_to( - this: Self, - value: Cow<'_, Self::SimValue>, - to_type: ToType, - ) -> Self::ValueOutput; - #[track_caller] - fn cast_sim_value_to(value: Cow<'_, SimValue>, to_type: ToType) -> SimValue { - let ty = value.ty(); - let value = match value { - Cow::Borrowed(value) => Cow::Borrowed(&**value), - Cow::Owned(value) => Cow::Owned(SimValue::into_value(value)), - }; - Self::cast_value_to(ty, value, to_type).into_sim_value_with_type(to_type) - } - #[track_caller] - fn cast_expr_to(value: Expr, to_type: ToType) -> Expr; - #[track_caller] - fn cast_valueless_to(value: Valueless, to_type: ToType) -> Valueless { - let _ = value; - Valueless::new(to_type) - } -} - -trait CastToImplHelperSealed {} - -#[expect(private_bounds)] -pub trait CastToImplHelper: - ValueType + CastToImplHelperSealed -{ - type Output: ValueType - where - Self::Type: CastToImpl; - #[track_caller] - fn cast_to_impl_helper(&self, to_type: ToType) -> Self::Output - where - Self::Type: CastToImpl; -} - -impl< - 'a, - This: ?Sized + ValueType + ToSimValueInner<'a>, -> CastToImplHelperSealed for This -{ -} - -impl< - 'a, - This: ?Sized + ValueType + ToSimValueInner<'a>, -> CastToImplHelper for This -{ - type Output - = >::ValueOutput - where - Self::Type: CastToImpl; - - #[track_caller] - fn cast_to_impl_helper(&self, to_type: ToType) -> Self::Output - where - Self::Type: CastToImpl, - { - Self::Type::cast_value_to(self.ty(), Self::to_sim_value_inner(self), to_type) - } -} - -impl + ToSimValue> - CastToImplHelperSealed for This -{ -} - -impl + ToSimValue> - CastToImplHelper for This -{ - type Output - = SimValue - where - Self::Type: CastToImpl; - - #[track_caller] - fn cast_to_impl_helper(&self, to_type: ToType) -> Self::Output - where - Self::Type: CastToImpl, - { - Self::Type::cast_sim_value_to(Cow::Owned(self.to_sim_value()), to_type) - } -} - -impl + ToExpr> - CastToImplHelperSealed for This -{ -} - -impl + ToExpr> - CastToImplHelper for This -{ - type Output - = Expr - where - Self::Type: CastToImpl; - - #[track_caller] - fn cast_to_impl_helper(&self, to_type: ToType) -> Self::Output - where - Self::Type: CastToImpl, - { - Self::Type::cast_expr_to(self.to_expr(), to_type) - } -} - -impl> - CastToImplHelperSealed for This -{ -} - -impl> - CastToImplHelper for This -{ - type Output - = Valueless - where - Self::Type: CastToImpl; - - #[track_caller] - fn cast_to_impl_helper(&self, to_type: ToType) -> Self::Output - where - Self::Type: CastToImpl, - { - Self::Type::cast_valueless_to(self.to_valueless(), to_type) - } -} - -pub trait CastTo: ValueType { - type Output: ValueType - where - Self::Type: CastToImpl; - - #[track_caller] - fn cast_to(&self, to_type: ToType) -> Self::Output - where - Self::Type: CastToImpl; - - #[track_caller] - fn cast_to_static(&self) -> Self::Output - where - Self::Type: CastToImpl, - { - self.cast_to(ToType::TYPE) - } -} - -impl< - T: ValueType + CastToImplHelper + ?Sized, - C: value_category::ValueCategory, -> CastTo for T -{ - type Output - = >::Output - where - Self::Type: CastToImpl; - fn cast_to(&self, to_type: ToType) -> Self::Output - where - Self::Type: CastToImpl, - { - Self::cast_to_impl_helper(self, to_type) - } -} +impl CastTo for T {} #[doc(hidden)] pub fn check_match_expr( @@ -1520,7 +761,7 @@ pub fn repeat( let element = element.to_expr(); let canonical_element = Expr::canonical(element); ops::ArrayLiteral::new( - element.ty(), + Expr::ty(element), std::iter::repeat(canonical_element) .take(L::Size::as_usize(len)) .collect(), @@ -1528,16 +769,9 @@ pub fn repeat( .to_expr() } -impl ValueType for PhantomConst { - type Type = Self; - type ValueCategory = value_category::ValueCategoryValue; - - fn ty(&self) -> Self::Type { - *self - } -} - impl ToExpr for PhantomConst { + type Type = Self; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::PhantomConst(self.canonical_phantom_const()).intern_sized(), @@ -1558,137 +792,3 @@ impl ToLiteralBits for Phan Ok(Interned::default()) } } - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct Valueless(T); - -impl Valueless { - pub const fn new(ty: T) -> Self { - Self(ty) - } - pub const fn ty(self) -> T { - self.0 - } -} - -impl Default for Valueless { - fn default() -> Self { - Self(T::TYPE) - } -} - -pub trait ValueType { - type Type: Type; - type ValueCategory: value_category::ValueCategory; - fn ty(&self) -> Self::Type; -} - -trait ToValuelessSealed {} - -#[expect(private_bounds)] -pub trait ToValueless: ValueType + ToValuelessSealed { - fn to_valueless(&self) -> Valueless { - Valueless::new(self.ty()) - } -} - -impl ToValuelessSealed for T {} - -impl ToValueless for T {} - -impl ValueType for Valueless { - type Type = T; - type ValueCategory = value_category::ValueCategoryValueless; - - fn ty(&self) -> Self::Type { - self.0 - } -} - -impl<'a, T: ?Sized + ValueType> ValueType for &'a T { - type Type = T::Type; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - T::ty(self) - } -} - -impl<'a, T: ?Sized + ValueType> ValueType for &'a mut T { - type Type = T::Type; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - T::ty(self) - } -} - -impl ValueType for Box { - type Type = T::Type; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - T::ty(self) - } -} - -impl ValueType for std::sync::Arc { - type Type = T::Type; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - T::ty(self) - } -} - -impl ValueType for std::rc::Rc { - type Type = T::Type; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - T::ty(self) - } -} - -impl ValueType for Interned { - type Type = T::Type; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - T::ty(self) - } -} - -impl ValueType for Expr { - type Type = T; - type ValueCategory = value_category::ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.__ty - } -} - -pub trait ToSimValueInner<'a>: ValueType { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue>; - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> - where - Self: Sized; -} - -impl<'a, T: Type> ToSimValueInner<'a> for SimValue { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - Cow::Borrowed(&**this) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - Cow::Owned(SimValue::into_value(this)) - } -} - -impl<'a, T: Type> ToSimValueInner<'a> for &'a SimValue { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - Cow::Borrowed(&***this) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - Cow::Borrowed(&**this) - } -} diff --git a/crates/fayalite/src/expr/ops.rs b/crates/fayalite/src/expr/ops.rs index b8ef4f7..b10e3ae 100644 --- a/crates/fayalite/src/expr/ops.rs +++ b/crates/fayalite/src/expr/ops.rs @@ -7,14 +7,12 @@ use crate::{ clock::{Clock, ToClock}, enum_::{Enum, EnumType, EnumVariant}, expr::{ - CastBitsTo as _, CastTo, CastToBits as _, CastToImpl, Expr, ExprEnum, Flow, HdlPartialEq, - HdlPartialEqImpl, HdlPartialOrd, HdlPartialOrdImpl, NotALiteralExpr, ReduceBitsImpl, - ToExpr, ToLiteralBits, ToSimValueInner, ToValueless, ValueType, Valueless, + CastBitsTo as _, CastTo, CastToBits as _, Expr, ExprEnum, Flow, HdlPartialEq, + HdlPartialOrd, NotALiteralExpr, ReduceBits, ToExpr, ToLiteralBits, target::{ GetTarget, Target, TargetPathArrayElement, TargetPathBundleField, TargetPathDynArrayElement, TargetPathElement, }, - value_category::ValueCategoryExpr, }, int::{ Bool, BoolOrIntType, DynSize, IntType, KnownSize, SInt, SIntType, SIntValue, Size, UInt, @@ -26,7 +24,6 @@ use crate::{ AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset, ToAsyncReset, ToReset, ToSyncReset, }, - sim::value::{SimValue, ToSimValue}, ty::{CanonicalType, StaticType, Type}, util::ConstUsize, }; @@ -34,1759 +31,50 @@ use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView}; use num_bigint::BigInt; use num_traits::{ToPrimitive, Zero}; use std::{ - borrow::Cow, fmt, marker::PhantomData, - num::NonZero, ops::{ Add, BitAnd, BitOr, BitXor, Div, Index, Mul, Neg as StdNeg, Not, Range, RangeBounds, Rem, Shl, Shr, Sub, }, }; -macro_rules! make_impls { +macro_rules! forward_value_to_expr_unary_op_trait { ( - $([$($args:tt)*])? - $m:ident! {$($rest:tt)*} + #[generics($($generics:tt)*)] + #[value($Value:ty)] + $Trait:ident::$method:ident ) => { - $m! {$($($args)*)? $($rest)*} - }; - ( - #[kinds()] - $($rest:tt)* - ) => {}; - ( - #[kinds($first_kind:tt $(, $kinds:tt)* $(,)?)] - $($rest:tt)* - ) => { - make_impls! { - #[kind($first_kind)] - $($rest)* - } - make_impls! { - #[kinds($($kinds),*)] - $($rest)* - } - }; - ( - #[type($($ty:tt)*)] - $(#[$($meta:tt)*])* - $([$($args:tt)*])? - $m:ident $($rest:tt)* - ) => { - make_impls! { - $(#[$($meta)*])* - [$($($args)*)? $($ty)*,] - $m $($rest)* - } - }; - ( - #[kind((int_no_nz<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds((uint_no_nz<$lt, $Width>), (sint_no_nz<$lt, $Width>))] - $($rest)* - } - }; - ( - #[kind((int_local<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds((uint_local<$lt, $Width>), (sint_local<$lt, $Width>))] - $($rest)* - } - }; - ( - #[kind((int_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds((uint_value<$lt, $Width>), (sint_value<$lt, $Width>))] - $($rest)* - } - }; - ( - #[kind((int_sim_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds((uint_sim_value<$lt, $Width>), (sint_sim_value<$lt, $Width>))] - $($rest)* - } - }; - ( - #[kind((uint<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (NonZero), - NonZeroU_N, - (uint_no_nz<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind((sint<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (NonZero), - NonZeroI_N, - (sint_no_nz<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind((uint_no_nz<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - usize, - u_N, - (uint_value<$lt, $Width>), - (uint_sim_value<$lt, $Width>), - (Expr>), - (Valueless>), - )] - $($rest)* - } - }; - ( - #[kind((sint_no_nz<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - isize, - i_N, - (sint_value<$lt, $Width>), - (sint_sim_value<$lt, $Width>), - (Expr>), - (Valueless>), - )] - $($rest)* - } - }; - ( - #[kind((uint_at_most_expr<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (uint_at_most_sim_value<$lt, $Width>), - (Expr>), - )] - $($rest)* - } - }; - ( - #[kind((sint_at_most_expr<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (sint_at_most_sim_value<$lt, $Width>), - (Expr>), - )] - $($rest)* - } - }; - ( - #[kind((uint_at_most_sim_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (uint_at_most_value<$lt, $Width>), - (uint_sim_value<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind((sint_at_most_sim_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (sint_at_most_value<$lt, $Width>), - (sint_sim_value<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind((uint_local_at_most_expr<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (uint_local_at_most_sim_value<$lt, $Width>), - (Expr>), - )] - $($rest)* - } - }; - ( - #[kind((sint_local_at_most_expr<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (sint_local_at_most_sim_value<$lt, $Width>), - (Expr>), - )] - $($rest)* - } - }; - ( - #[kind((uint_local_at_most_sim_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (uint_value<$lt, $Width>), - (uint_sim_value<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind((sint_local_at_most_sim_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (sint_value<$lt, $Width>), - (sint_sim_value<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind((uint_at_most_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - prim_uint, - (uint_value<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind((sint_at_most_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - prim_sint, - (sint_value<$lt, $Width>), - )] - $($rest)* - } - }; - ( - #[kind(prim_uint)] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (NonZero), - NonZeroU_N, - usize, - u_N, - )] - $($rest)* - } - }; - ( - #[kind(prim_sint)] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (NonZero), - NonZeroI_N, - isize, - i_N, - )] - $($rest)* - } - }; - ( - #[kind((bool_local_at_most_expr<$lt:lifetime>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (bool_sim_value<$lt>), - (Expr), - )] - $($rest)* - } - }; - ( - #[kind((bool_at_most_expr<$lt:lifetime>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (bool_at_most_sim_value<$lt>), - (Expr), - )] - $($rest)* - } - }; - ( - #[kind((bool_at_most_sim_value<$lt:lifetime>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - bool, - (bool_sim_value<$lt>), - )] - $($rest)* - } - }; - ( - #[kind((uint_local<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (uint_value<$lt, $Width>), - (SimValue>), - (&$lt SimValue>), - (Expr>), - (Valueless>), - )] - $($rest)* - } - }; - ( - #[kind((sint_local<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (sint_value<$lt, $Width>), - (SimValue>), - (&$lt SimValue>), - (Expr>), - (Valueless>), - )] - $($rest)* - } - }; - ( - #[kind((uint_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (UIntValue<$Width: Size>), - (&$lt UIntValue<$Width: Size>), - )] - $($rest)* - } - }; - ( - #[kind((sint_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (SIntValue<$Width: Size>), - (&$lt SIntValue<$Width: Size>), - )] - $($rest)* - } - }; - ( - #[kind((uint_sim_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (SimValue>), - (&$lt SimValue>), - )] - $($rest)* - } - }; - ( - #[kind((sint_sim_value<$lt:lifetime, $Width:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (SimValue>), - (&$lt SimValue>), - )] - $($rest)* - } - }; - ( - #[kind((bool_sim_value<$lt:lifetime>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (SimValue), - (&$lt SimValue), - )] - $($rest)* - } - }; - ( - #[kind((bool<$lt:lifetime>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - bool, - (bool_sim_value<$lt>), - (Expr), - (Valueless), - )] - $($rest)* - } - }; - ( - #[kind((bool_local<$lt:lifetime>))] - $($rest:tt)* - ) => { - make_impls! { - #[kinds( - (bool_sim_value<$lt>), - (Expr), - (Valueless), - )] - $($rest)* - } - }; - ( - #[kind(u_N)] - $($rest:tt)* - ) => { - make_impls! { - #[kinds(u8, u16, u32, u64, u128)] - $($rest)* - } - }; - ( - #[kind(i_N)] - $($rest:tt)* - ) => { - make_impls! { - #[kinds(i8, i16, i32, i64, i128)] - $($rest)* - } - }; - ( - #[kind(NonZeroU_N)] - $($rest:tt)* - ) => { - make_impls! { - #[kinds((NonZero), (NonZero), (NonZero), (NonZero), (NonZero))] - $($rest)* - } - }; - ( - #[kind(NonZeroI_N)] - $($rest:tt)* - ) => { - make_impls! { - #[kinds((NonZero), (NonZero), (NonZero), (NonZero), (NonZero))] - $($rest)* - } - }; - ( - #[kind(($wrapper:ident<$Ty:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[type([][] ($wrapper<$Ty>))] - $($rest)* - } - }; - ( - #[kind((&$lt:lifetime $wrapper:ident<$Ty:ident>))] - $($rest:tt)* - ) => { - make_impls! { - #[type([$lt,][] (&$lt $wrapper<$Ty>))] - $($rest)* - } - }; - ( - #[kind(($wrapper:ident<$Width:ident: Size>))] - $($rest:tt)* - ) => { - make_impls! { - #[type([][$Width: Size,] ($wrapper<$Width>))] - $($rest)* - } - }; - ( - #[kind(($wrapper:ident<$ty:ident<$Width:ident: Size>>))] - $($rest:tt)* - ) => { - make_impls! { - #[type([][$Width: Size,] ($wrapper<$ty<$Width>>))] - $($rest)* - } - }; - ( - #[kind((&$lt:lifetime $wrapper:ident<$Width:ident: Size>))] - $($rest:tt)* - ) => { - make_impls! { - #[type([$lt,][$Width: Size,] (&$lt $wrapper<$Width>))] - $($rest)* - } - }; - ( - #[kind((&$lt:lifetime $wrapper:ident<$ty:ident<$Width:ident: Size>>))] - $($rest:tt)* - ) => { - make_impls! { - #[type([$lt,][$Width: Size,] (&$lt $wrapper<$ty<$Width>>))] - $($rest)* - } - }; - (#[kind(usize)] $($rest:tt)*) => {make_impls! { #[type([][] (usize))] $($rest)* }}; - (#[kind(isize)] $($rest:tt)*) => {make_impls! { #[type([][] (isize))] $($rest)* }}; - (#[kind(bool)] $($rest:tt)*) => {make_impls! { #[type([][] (bool))] $($rest)* }}; - (#[kind(u8)] $($rest:tt)*) => {make_impls! { #[type([][] (u8))] $($rest)* }}; - (#[kind(u16)] $($rest:tt)*) => {make_impls! { #[type([][] (u16))] $($rest)* }}; - (#[kind(u32)] $($rest:tt)*) => {make_impls! { #[type([][] (u32))] $($rest)* }}; - (#[kind(u64)] $($rest:tt)*) => {make_impls! { #[type([][] (u64))] $($rest)* }}; - (#[kind(u128)] $($rest:tt)*) => {make_impls! { #[type([][] (u128))] $($rest)* }}; - (#[kind(i8)] $($rest:tt)*) => {make_impls! { #[type([][] (i8))] $($rest)* }}; - (#[kind(i16)] $($rest:tt)*) => {make_impls! { #[type([][] (i16))] $($rest)* }}; - (#[kind(i32)] $($rest:tt)*) => {make_impls! { #[type([][] (i32))] $($rest)* }}; - (#[kind(i64)] $($rest:tt)*) => {make_impls! { #[type([][] (i64))] $($rest)* }}; - (#[kind(i128)] $($rest:tt)*) => {make_impls! { #[type([][] (i128))] $($rest)* }}; -} -pub(crate) use make_impls; + impl<$($generics)*> $Trait for $Value + where + Expr<<$Value as ToExpr>::Type>: $Trait, + { + type Output = ::Type> as $Trait>::Output; -#[cfg(test)] -mod test_ops_impls; - -macro_rules! impl_simple_binary_op_trait { - ( - [$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), - [$($RLifetimes:tt)*][$($RBounds:tt)*] ($($R:tt)*), - $(#[$meta:meta])* - $Trait:ident::$f:ident($f_self:ident, $f_rhs:ident) -> $Out:ident<_> $body:block $(,)? - ) => { - $(#[$meta])* - impl<$($LLifetimes)* $($RLifetimes)* $($LBounds)* $($RBounds)*> $Trait<$($R)*> for $($L)* { - type Output = $Out<<::Type> as $Trait::Type>>>::Output as ValueType>::Type>; - - fn $f($f_self, $f_rhs: $($R)*) -> Self::Output $body - } - }; - ( - $LLifetimes:tt $LBounds:tt ($($L:tt)*), - $RLifetimes:tt $RBounds:tt ($($R:tt)*), - $(#[$meta:meta])* - $FirstTrait:ident::$first_f:ident($f_self:ident, $f_rhs:ident) -> $Out:ident<_> $body:block, - $($rest:tt)* - ) => { - impl_simple_binary_op_trait! { - $LLifetimes $LBounds ($($L)*), - $RLifetimes $RBounds ($($R)*), - $(#[$meta])* - $FirstTrait::$first_f($f_self, $f_rhs) -> $Out<_> $body - } - impl_simple_binary_op_trait! { - $LLifetimes $LBounds ($($L)*), - $RLifetimes $RBounds ($($R)*), - $(#[$meta])* - $($rest)* - } - }; -} - -make_impls! { - #[kinds((Expr>))] - #[kinds((uint_at_most_sim_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Expr<_> { - AddU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Sub::sub(self, rhs) -> Expr<_> { - SubU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Mul::mul(self, rhs) -> Expr<_> { - MulU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Div::div(self, rhs) -> Expr<_> { - DivU::new(self.to_expr(), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Rem::rem(self, rhs) -> Expr<_> { - RemU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitAnd::bitand(self, rhs) -> Expr<_> { - BitAndU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitOr::bitor(self, rhs) -> Expr<_> { - BitOrU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitXor::bitxor(self, rhs) -> Expr<_> { - BitXorU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - } -} - -make_impls! { - #[kinds((Expr>))] - #[kinds((sint_at_most_sim_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Expr<_> { - AddS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Sub::sub(self, rhs) -> Expr<_> { - SubS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Mul::mul(self, rhs) -> Expr<_> { - MulS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Div::div(self, rhs) -> Expr<_> { - DivS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Rem::rem(self, rhs) -> Expr<_> { - RemS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitAnd::bitand(self, rhs) -> Expr<_> { - BitAndS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitOr::bitor(self, rhs) -> Expr<_> { - BitOrS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitXor::bitxor(self, rhs) -> Expr<_> { - BitXorS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - } -} - -make_impls! { - #[kinds((uint_at_most_expr<'l, L>))] - #[kinds((Expr>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Expr<_> { - AddU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Sub::sub(self, rhs) -> Expr<_> { - SubU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Mul::mul(self, rhs) -> Expr<_> { - MulU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Div::div(self, rhs) -> Expr<_> { - DivU::new(self.to_expr(), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Rem::rem(self, rhs) -> Expr<_> { - RemU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitAnd::bitand(self, rhs) -> Expr<_> { - BitAndU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitOr::bitor(self, rhs) -> Expr<_> { - BitOrU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitXor::bitxor(self, rhs) -> Expr<_> { - BitXorU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - } -} - -make_impls! { - #[kinds((sint_at_most_expr<'l, L>))] - #[kinds((Expr>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Expr<_> { - AddS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Sub::sub(self, rhs) -> Expr<_> { - SubS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Mul::mul(self, rhs) -> Expr<_> { - MulS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Div::div(self, rhs) -> Expr<_> { - DivS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Rem::rem(self, rhs) -> Expr<_> { - RemS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitAnd::bitand(self, rhs) -> Expr<_> { - BitAndS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitOr::bitor(self, rhs) -> Expr<_> { - BitOrS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - BitXor::bitxor(self, rhs) -> Expr<_> { - BitXorS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - } -} - -make_impls! { - #[kinds((uint_sim_value<'l, L>))] - #[kinds((uint_at_most_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())).into_sim_value() - }, - Sub::sub(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())).into_sim_value() - }, - Mul::mul(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())).into_sim_value() - }, - Div::div(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())).into_sim_value() - }, - Rem::rem(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())).into_sim_value() - }, - BitAnd::bitand(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())).into_sim_value() - }, - BitOr::bitor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())).into_sim_value() - }, - BitXor::bitxor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((sint_sim_value<'l, L>))] - #[kinds((sint_at_most_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())).into_sim_value() - }, - Sub::sub(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())).into_sim_value() - }, - Mul::mul(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())).into_sim_value() - }, - Div::div(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())).into_sim_value() - }, - Rem::rem(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())).into_sim_value() - }, - BitAnd::bitand(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())).into_sim_value() - }, - BitOr::bitor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())).into_sim_value() - }, - BitXor::bitxor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((uint_at_most_sim_value<'l, L>))] - #[kinds((uint_sim_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())).into_sim_value() - }, - Sub::sub(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())).into_sim_value() - }, - Mul::mul(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())).into_sim_value() - }, - Div::div(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())).into_sim_value() - }, - Rem::rem(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())).into_sim_value() - }, - BitAnd::bitand(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())).into_sim_value() - }, - BitOr::bitor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())).into_sim_value() - }, - BitXor::bitxor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((sint_at_most_sim_value<'l, L>))] - #[kinds((sint_sim_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())).into_sim_value() - }, - Sub::sub(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())).into_sim_value() - }, - Mul::mul(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())).into_sim_value() - }, - Div::div(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())).into_sim_value() - }, - Rem::rem(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())).into_sim_value() - }, - BitAnd::bitand(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())).into_sim_value() - }, - BitOr::bitor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())).into_sim_value() - }, - BitXor::bitxor(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((uint_at_most_expr<'l, L>))] - #[kinds((Valueless>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Valueless<_> { - self.to_valueless().add(rhs.to_valueless()) - }, - Sub::sub(self, rhs) -> Valueless<_> { - self.to_valueless().sub(rhs.to_valueless()) - }, - Mul::mul(self, rhs) -> Valueless<_> { - self.to_valueless().mul(rhs.to_valueless()) - }, - Div::div(self, rhs) -> Valueless<_> { - self.to_valueless().div(rhs.to_valueless()) - }, - Rem::rem(self, rhs) -> Valueless<_> { - self.to_valueless().rem(rhs.to_valueless()) - }, - BitAnd::bitand(self, rhs) -> Valueless<_> { - self.to_valueless().bitand(rhs.to_valueless()) - }, - BitOr::bitor(self, rhs) -> Valueless<_> { - self.to_valueless().bitor(rhs.to_valueless()) - }, - BitXor::bitxor(self, rhs) -> Valueless<_> { - self.to_valueless().bitxor(rhs.to_valueless()) - }, - } -} - -make_impls! { - #[kinds((sint_at_most_expr<'l, L>))] - #[kinds((Valueless>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Valueless<_> { - self.to_valueless().add(rhs.to_valueless()) - }, - Sub::sub(self, rhs) -> Valueless<_> { - self.to_valueless().sub(rhs.to_valueless()) - }, - Mul::mul(self, rhs) -> Valueless<_> { - self.to_valueless().mul(rhs.to_valueless()) - }, - Div::div(self, rhs) -> Valueless<_> { - self.to_valueless().div(rhs.to_valueless()) - }, - Rem::rem(self, rhs) -> Valueless<_> { - self.to_valueless().rem(rhs.to_valueless()) - }, - BitAnd::bitand(self, rhs) -> Valueless<_> { - self.to_valueless().bitand(rhs.to_valueless()) - }, - BitOr::bitor(self, rhs) -> Valueless<_> { - self.to_valueless().bitor(rhs.to_valueless()) - }, - BitXor::bitxor(self, rhs) -> Valueless<_> { - self.to_valueless().bitxor(rhs.to_valueless()) - }, - } -} - -make_impls! { - #[kinds((Valueless>))] - #[kinds((uint_at_most_expr<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Valueless<_> { - self.to_valueless().add(rhs.to_valueless()) - }, - Sub::sub(self, rhs) -> Valueless<_> { - self.to_valueless().sub(rhs.to_valueless()) - }, - Mul::mul(self, rhs) -> Valueless<_> { - self.to_valueless().mul(rhs.to_valueless()) - }, - Div::div(self, rhs) -> Valueless<_> { - self.to_valueless().div(rhs.to_valueless()) - }, - Rem::rem(self, rhs) -> Valueless<_> { - self.to_valueless().rem(rhs.to_valueless()) - }, - BitAnd::bitand(self, rhs) -> Valueless<_> { - self.to_valueless().bitand(rhs.to_valueless()) - }, - BitOr::bitor(self, rhs) -> Valueless<_> { - self.to_valueless().bitor(rhs.to_valueless()) - }, - BitXor::bitxor(self, rhs) -> Valueless<_> { - self.to_valueless().bitxor(rhs.to_valueless()) - }, - } -} - -make_impls! { - #[kinds((Valueless>))] - #[kinds((sint_at_most_expr<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> Valueless<_> { - self.to_valueless().add(rhs.to_valueless()) - }, - Sub::sub(self, rhs) -> Valueless<_> { - self.to_valueless().sub(rhs.to_valueless()) - }, - Mul::mul(self, rhs) -> Valueless<_> { - self.to_valueless().mul(rhs.to_valueless()) - }, - Div::div(self, rhs) -> Valueless<_> { - self.to_valueless().div(rhs.to_valueless()) - }, - Rem::rem(self, rhs) -> Valueless<_> { - self.to_valueless().rem(rhs.to_valueless()) - }, - BitAnd::bitand(self, rhs) -> Valueless<_> { - self.to_valueless().bitand(rhs.to_valueless()) - }, - BitOr::bitor(self, rhs) -> Valueless<_> { - self.to_valueless().bitor(rhs.to_valueless()) - }, - BitXor::bitxor(self, rhs) -> Valueless<_> { - self.to_valueless().bitxor(rhs.to_valueless()) - }, - } -} - -type SimValueInner = ::SimValue; - -trait ValueIntoBigInt { - fn value_to_bigint(&self) -> BigInt; -} - -macro_rules! impl_value_to_bigint { - ([$($Lifetimes:tt)*][$($Bounds:tt)*] (NonZero<$T:ty>),) => { - impl<$($Lifetimes)* $($Bounds)*> ValueIntoBigInt for NonZero<$T> { - fn value_to_bigint(&self) -> BigInt { - self.get().into() + fn $method(self) -> Self::Output { + $Trait::$method(self.to_expr()) } } }; - ([$($Lifetimes:tt)*][$($Bounds:tt)*] ($(&$lt:lifetime)? $IntValue:ident<$Width:ident>),) => { - impl<$($Lifetimes)* $($Bounds)*> ValueIntoBigInt for $(&$lt)? $IntValue<$Width> { - fn value_to_bigint(&self) -> BigInt { - self.to_bigint() - } - } - }; - ([$($Lifetimes:tt)*][$($Bounds:tt)*] ($(&$lt:lifetime)? SimValue<$IntType:ident<$Width:ident>>),) => { - impl<$($Lifetimes)* $($Bounds)*> ValueIntoBigInt for $(&$lt)? SimValue<$IntType<$Width>> { - fn value_to_bigint(&self) -> BigInt { - self.to_bigint() - } - } - }; - ([$($Lifetimes:tt)*][$($Bounds:tt)*] ($T:ty),) => { - impl<$($Lifetimes)* $($Bounds)*> ValueIntoBigInt for $T { - fn value_to_bigint(&self) -> BigInt { - (*self).into() - } - } - }; -} - -make_impls! { - #[kinds((sint_at_most_sim_value<'a, Width>), (uint_at_most_sim_value<'a, Width>))] - impl_value_to_bigint! {} -} - -make_impls! { - #[kinds((uint_value<'l, L>))] - #[kinds(prim_uint)] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())) - }, - Sub::sub(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())) - }, - Mul::mul(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())) - }, - Div::div(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())) - }, - Rem::rem(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())) - }, - BitAnd::bitand(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())) - }, - BitOr::bitor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())) - }, - BitXor::bitxor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())) - }, - } -} - -make_impls! { - #[kinds((sint_value<'l, L>))] - #[kinds(prim_sint)] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())) - }, - Sub::sub(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())) - }, - Mul::mul(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())) - }, - Div::div(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())) - }, - Rem::rem(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())) - }, - BitAnd::bitand(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())) - }, - BitOr::bitor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())) - }, - BitXor::bitxor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())) - }, - } -} - -make_impls! { - #[kinds((uint_at_most_value<'l, L>))] - #[kinds((uint_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())) - }, - Sub::sub(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())) - }, - Mul::mul(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())) - }, - Div::div(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())) - }, - Rem::rem(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())) - }, - BitAnd::bitand(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())) - }, - BitOr::bitor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())) - }, - BitXor::bitxor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())) - }, - } -} - -make_impls! { - #[kinds((sint_at_most_value<'l, L>))] - #[kinds((sint_value<'r, R>))] - impl_simple_binary_op_trait! { - Add::add(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().add(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().add(rhs.value_to_bigint())) - }, - Sub::sub(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().sub(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().sub(rhs.value_to_bigint())) - }, - Mul::mul(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().mul(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().mul(rhs.value_to_bigint())) - }, - Div::div(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().div(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().div(rhs.value_to_bigint())) - }, - Rem::rem(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().rem(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().rem(rhs.value_to_bigint())) - }, - BitAnd::bitand(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitand(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitand(rhs.value_to_bigint())) - }, - BitOr::bitor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitor(rhs.value_to_bigint())) - }, - BitXor::bitxor(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().bitxor(rhs.to_valueless()).ty(); - ty.from_int_wrapping(self.value_to_bigint().bitxor(rhs.value_to_bigint())) - }, - } -} - -make_impls! { - #[kinds((Expr))] - #[kinds((bool_sim_value<'r>))] - impl_simple_binary_op_trait! { - /// intentionally only implemented for expressions, not rust's bool type, - /// since that helps avoid using `==`/`!=` in hdl boolean expressions, which doesn't do - /// what is usually wanted. - BitAnd::bitand(self, rhs) -> Expr<_> { - BitAndB::new(self.to_expr(), rhs.to_expr()).to_expr() - }, - BitOr::bitor(self, rhs) -> Expr<_> { - BitOrB::new(self.to_expr(), rhs.to_expr()).to_expr() - }, - BitXor::bitxor(self, rhs) -> Expr<_> { - BitXorB::new(self.to_expr(), rhs.to_expr()).to_expr() - }, - } -} - -make_impls! { - #[kinds((bool_local_at_most_expr<'l>))] - #[kinds((Expr))] - impl_simple_binary_op_trait! { - /// intentionally only implemented for expressions, not rust's bool type, - /// since that helps avoid using `==`/`!=` in hdl boolean expressions, which doesn't do - /// what is usually wanted. - BitAnd::bitand(self, rhs) -> Expr<_> { - BitAndB::new(self.to_expr(), rhs.to_expr()).to_expr() - }, - BitOr::bitor(self, rhs) -> Expr<_> { - BitOrB::new(self.to_expr(), rhs.to_expr()).to_expr() - }, - BitXor::bitxor(self, rhs) -> Expr<_> { - BitXorB::new(self.to_expr(), rhs.to_expr()).to_expr() - }, - } -} - -make_impls! { - #[kinds((bool_at_most_sim_value<'l>))] - #[kinds((bool_sim_value<'r>))] - impl_simple_binary_op_trait! { - BitAnd::bitand(self, rhs) -> SimValue<_> { - ToSimValueInner::into_sim_value_inner(self).bitand(*ToSimValueInner::into_sim_value_inner(rhs)).into_sim_value() - }, - BitOr::bitor(self, rhs) -> SimValue<_> { - ToSimValueInner::into_sim_value_inner(self).bitor(*ToSimValueInner::into_sim_value_inner(rhs)).into_sim_value() - }, - BitXor::bitxor(self, rhs) -> SimValue<_> { - ToSimValueInner::into_sim_value_inner(self).bitxor(*ToSimValueInner::into_sim_value_inner(rhs)).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((bool_sim_value<'l>))] - #[kinds(bool)] - impl_simple_binary_op_trait! { - BitAnd::bitand(self, rhs) -> SimValue<_> { - ToSimValueInner::into_sim_value_inner(self).bitand(rhs).into_sim_value() - }, - BitOr::bitor(self, rhs) -> SimValue<_> { - ToSimValueInner::into_sim_value_inner(self).bitor(rhs).into_sim_value() - }, - BitXor::bitxor(self, rhs) -> SimValue<_> { - ToSimValueInner::into_sim_value_inner(self).bitxor(rhs).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((bool_at_most_expr<'l>))] - #[kinds((Valueless))] - impl_simple_binary_op_trait! { - BitAnd::bitand(self, rhs) -> Valueless<_> { - rhs - }, - BitOr::bitor(self, rhs) -> Valueless<_> { - rhs - }, - BitXor::bitxor(self, rhs) -> Valueless<_> { - rhs - }, - } -} - -make_impls! { - #[kinds((Valueless))] - #[kinds((bool_at_most_expr<'r>))] - impl_simple_binary_op_trait! { - BitAnd::bitand(self, rhs) -> Valueless<_> { - rhs.to_valueless() - }, - BitOr::bitor(self, rhs) -> Valueless<_> { - rhs.to_valueless() - }, - BitXor::bitxor(self, rhs) -> Valueless<_> { - rhs.to_valueless() - }, - } -} - -macro_rules! impl_shift_binary_op_trait { - ( - [$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), - [][] (usize), - $(#[$meta:meta])* - $Trait:ident::$f:ident($f_self:ident, $f_rhs:ident) -> $Out:ident<_> $body:block $(,)? - ) => { - $(#[$meta])* - impl<$($LLifetimes)* $($LBounds)*> $Trait for $($L)* { - type Output = $Out<<::Type> as $Trait>::Output as ValueType>::Type>; - - #[track_caller] - fn $f($f_self, $f_rhs: usize) -> Self::Output $body - } - }; - ( - [$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), - [$($RLifetimes:tt)*][$($RBounds:tt)*] ($($R:tt)*), - $(#[$meta:meta])* - $Trait:ident::$f:ident($f_self:ident, $f_rhs:ident) -> $Out:ident<_> $body:block $(,)? - ) => { - $(#[$meta])* - impl<$($LLifetimes)* $($RLifetimes)* $($LBounds)* $($RBounds)*> $Trait<$($R)*> for $($L)* { - type Output = $Out<<::Type> as $Trait::Type>>>::Output as ValueType>::Type>; - - #[track_caller] - fn $f($f_self, $f_rhs: $($R)*) -> Self::Output $body - } - }; - ( - $LLifetimes:tt $LBounds:tt ($($L:tt)*), - $RLifetimes:tt $RBounds:tt ($($R:tt)*), - $(#[$meta:meta])* - $FirstTrait:ident::$first_f:ident($f_self:ident, $f_rhs:ident) -> $Out:ident<_> $body:block, - $($rest:tt)* - ) => { - impl_shift_binary_op_trait! { - $LLifetimes $LBounds ($($L)*), - $RLifetimes $RBounds ($($R)*), - $(#[$meta])* - $FirstTrait::$first_f($f_self, $f_rhs) -> $Out<_> $body - } - impl_shift_binary_op_trait! { - $LLifetimes $LBounds ($($L)*), - $RLifetimes $RBounds ($($R)*), - $(#[$meta])* - $($rest)* - } - }; -} - -make_impls! { - #[kinds((Expr>))] - impl_shift_binary_op_trait! { - [][] (usize), - Shl::shl(self, rhs) -> Expr<_> { - FixedShlU::new(Expr::as_dyn_int(self.to_expr()), rhs).to_expr() - }, - Shr::shr(self, rhs) -> Expr<_> { - FixedShrU::new(Expr::as_dyn_int(self.to_expr()), rhs).to_expr() - }, - } -} - -make_impls! { - #[kinds((Expr>))] - impl_shift_binary_op_trait! { - [][] (usize), - Shl::shl(self, rhs) -> Expr<_> { - FixedShlS::new(Expr::as_dyn_int(self.to_expr()), rhs).to_expr() - }, - Shr::shr(self, rhs) -> Expr<_> { - FixedShrS::new(Expr::as_dyn_int(self.to_expr()), rhs).to_expr() - }, - } -} - -make_impls! { - #[kinds((uint_at_most_expr<'l, L>))] - #[kinds((Expr>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Expr<_> { - DynShlU::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs)).to_expr() - }, - Shr::shr(self, rhs) -> Expr<_> { - DynShrU::new(self.to_expr(), Expr::as_dyn_int(rhs)).to_expr() - }, - } -} - -make_impls! { - #[kinds((sint_at_most_expr<'l, L>))] - #[kinds((Expr>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Expr<_> { - DynShlS::new(Expr::as_dyn_int(self.to_expr()), Expr::as_dyn_int(rhs)).to_expr() - }, - Shr::shr(self, rhs) -> Expr<_> { - DynShrS::new(self.to_expr(), Expr::as_dyn_int(rhs)).to_expr() - }, - } -} - -make_impls! { - #[kinds((Expr>))] - #[kinds((uint_local_at_most_sim_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Expr<_> { - DynShlU::new(Expr::as_dyn_int(self), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Shr::shr(self, rhs) -> Expr<_> { - DynShrU::new(self, Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - } -} - -make_impls! { - #[kinds((Expr>))] - #[kinds((uint_local_at_most_sim_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Expr<_> { - DynShlS::new(Expr::as_dyn_int(self), Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - Shr::shr(self, rhs) -> Expr<_> { - DynShrS::new(self, Expr::as_dyn_int(rhs.to_expr())).to_expr() - }, - } -} - -make_impls! { - #[kinds((uint_at_most_sim_value<'l, L>))] - #[kinds((uint_sim_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shl(rhs.to_valueless()).ty(); - let rhs: usize = rhs.value_to_bigint().try_into().expect("dynamic left-shift's amount is too big"); - ty.from_int_wrapping(self.value_to_bigint() << rhs).into_sim_value() - }, - Shr::shr(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shr(rhs.to_valueless()).ty(); - let rhs = rhs.value_to_bigint().try_into().unwrap_or(usize::MAX); - ty.from_int_wrapping(self.value_to_bigint() >> rhs).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((sint_at_most_sim_value<'l, L>))] - #[kinds((uint_sim_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shl(rhs.to_valueless()).ty(); - let rhs: usize = rhs.value_to_bigint().try_into().expect("dynamic left-shift's amount is too big"); - ty.from_int_wrapping(self.value_to_bigint() << rhs).into_sim_value() - }, - Shr::shr(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shr(rhs.to_valueless()).ty(); - let rhs = rhs.value_to_bigint().try_into().unwrap_or(usize::MAX); - ty.from_int_wrapping(self.value_to_bigint() >> rhs).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((uint_sim_value<'l, L>))] - #[kinds((uint_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shl(rhs.to_valueless()).ty(); - let rhs: usize = rhs.value_to_bigint().try_into().expect("dynamic left-shift's amount is too big"); - ty.from_int_wrapping(self.value_to_bigint() << rhs).into_sim_value() - }, - Shr::shr(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shr(rhs.to_valueless()).ty(); - let rhs = rhs.value_to_bigint().try_into().unwrap_or(usize::MAX); - ty.from_int_wrapping(self.value_to_bigint() >> rhs).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((sint_sim_value<'l, L>))] - #[kinds((uint_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shl(rhs.to_valueless()).ty(); - let rhs: usize = rhs.value_to_bigint().try_into().expect("dynamic left-shift's amount is too big"); - ty.from_int_wrapping(self.value_to_bigint() << rhs).into_sim_value() - }, - Shr::shr(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shr(rhs.to_valueless()).ty(); - let rhs = rhs.value_to_bigint().try_into().unwrap_or(usize::MAX); - ty.from_int_wrapping(self.value_to_bigint() >> rhs).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((uint_sim_value<'l, L>))] - impl_shift_binary_op_trait! { - [][] (usize), - Shl::shl(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shl(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() << rhs).into_sim_value() - }, - Shr::shr(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shr(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() >> rhs).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((sint_sim_value<'l, L>))] - impl_shift_binary_op_trait! { - [][] (usize), - Shl::shl(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shl(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() << rhs).into_sim_value() - }, - Shr::shr(self, rhs) -> SimValue<_> { - let ty = self.to_valueless().shr(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() >> rhs).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((uint_at_most_value<'l, L>))] - #[kinds((uint_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shl(rhs.to_valueless()).ty(); - let rhs: usize = rhs.value_to_bigint().try_into().expect("dynamic left-shift's amount is too big"); - ty.from_int_wrapping(self.value_to_bigint() << rhs) - }, - Shr::shr(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shr(rhs.to_valueless()).ty(); - let rhs = rhs.value_to_bigint().try_into().unwrap_or(usize::MAX); - ty.from_int_wrapping(self.value_to_bigint() >> rhs) - }, - } -} - -make_impls! { - #[kinds((sint_at_most_value<'l, L>))] - #[kinds((uint_value<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shl(rhs.to_valueless()).ty(); - let rhs: usize = rhs.value_to_bigint().try_into().expect("dynamic left-shift's amount is too big"); - ty.from_int_wrapping(self.value_to_bigint() << rhs) - }, - Shr::shr(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shr(rhs.to_valueless()).ty(); - let rhs = rhs.value_to_bigint().try_into().unwrap_or(usize::MAX); - ty.from_int_wrapping(self.value_to_bigint() >> rhs) - }, - } -} - -make_impls! { - #[kinds((uint_value<'l, L>))] - impl_shift_binary_op_trait! { - [][] (usize), - Shl::shl(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shl(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() << rhs) - }, - Shr::shr(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shr(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() >> rhs) - }, - } -} - -make_impls! { - #[kinds((sint_value<'l, L>))] - impl_shift_binary_op_trait! { - [][] (usize), - Shl::shl(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shl(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() << rhs) - }, - Shr::shr(self, rhs) -> SimValueInner<_> { - let ty = self.to_valueless().shr(rhs).ty(); - ty.from_int_wrapping(self.value_to_bigint() >> rhs) - }, - } -} - -make_impls! { - #[kinds((uint_at_most_expr<'l, L>))] - #[kinds((Valueless>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Valueless<_> { - self.to_valueless().shl(rhs) - }, - Shr::shr(self, rhs) -> Valueless<_> { - self.to_valueless().shr(rhs) - }, - } -} - -make_impls! { - #[kinds((sint_at_most_expr<'l, L>))] - #[kinds((Valueless>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Valueless<_> { - self.to_valueless().shl(rhs) - }, - Shr::shr(self, rhs) -> Valueless<_> { - self.to_valueless().shr(rhs) - }, - } -} - -make_impls! { - #[kinds((Valueless>))] - #[kinds((uint_local_at_most_expr<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Valueless<_> { - self.shl(rhs.to_valueless()) - }, - Shr::shr(self, rhs) -> Valueless<_> { - self.shr(rhs.to_valueless()) - }, - } -} - -make_impls! { - #[kinds((Valueless>))] - #[kinds((uint_local_at_most_expr<'r, R>))] - impl_shift_binary_op_trait! { - Shl::shl(self, rhs) -> Valueless<_> { - self.shl(rhs.to_valueless()) - }, - Shr::shr(self, rhs) -> Valueless<_> { - self.shr(rhs.to_valueless()) - }, - } } macro_rules! impl_unary_op_trait { ( - [$($Lifetimes:tt)*][$($Bounds:tt)*] ($($Ty:tt)*), - $(#[$meta:meta])* - $Trait:ident::$f:ident($f_self:ident) -> $Out:ident<_> $body:block $(,)? + #[generics($($generics:tt)*)] + fn $Trait:ident::$method:ident($arg:ident: $Arg:ty) -> $Output:ty { + $($body:tt)* + } ) => { - $(#[$meta])* - impl<$($Lifetimes)* $($Bounds)*> $Trait for $($Ty)* { - type Output = $Out<<::Type> as $Trait>::Output as ValueType>::Type>; + impl<$($generics)*> $Trait for Expr<$Arg> + { + type Output = Expr<$Output>; - fn $f($f_self) -> Self::Output $body + fn $method(self) -> Self::Output { + let $arg = self; + $($body)* + } } }; - ( - $Lifetimes:tt $Bounds:tt $Ty:tt, - $(#[$meta:meta])* - $FirstTrait:ident::$first_f:ident($f_self:ident) -> $Out:ident<_> $body:block, - $($rest:tt)* - ) => { - impl_unary_op_trait! { - $Lifetimes $Bounds $Ty, - $(#[$meta])* - $FirstTrait::$first_f($f_self) -> $Out<_> $body - } - impl_unary_op_trait! { - $Lifetimes $Bounds $Ty, - $(#[$meta])* - $($rest)* - } - }; -} - -make_impls! { - #[kinds((SimValue>))] - impl_unary_op_trait! { - Not::not(self) -> SimValue<_> { - Not::not(SimValue::into_value(self)).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((&'a SimValue>))] - impl_unary_op_trait! { - Not::not(self) -> SimValue<_> { - Not::not(SimValue::value(self)).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((Expr>))] - impl_unary_op_trait! { - Not::not(self) -> Expr<_> { - NotU::new(self).to_expr() - }, - } -} - -make_impls! { - #[kinds((SimValue>))] - impl_unary_op_trait! { - Not::not(self) -> SimValue<_> { - Not::not(SimValue::into_value(self)).into_sim_value() - }, - StdNeg::neg(self) -> SimValue<_> { - StdNeg::neg(SimValue::into_value(self)).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((&'a SimValue>))] - impl_unary_op_trait! { - Not::not(self) -> SimValue<_> { - Not::not(SimValue::value(self)).into_sim_value() - }, - StdNeg::neg(self) -> SimValue<_> { - StdNeg::neg(SimValue::value(self)).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((Expr>))] - impl_unary_op_trait! { - Not::not(self) -> Expr<_> { - NotS::new(self).to_expr() - }, - StdNeg::neg(self) -> Expr<_> { - Neg::new(Expr::as_dyn_int(self)).to_expr() - }, - } -} - -make_impls! { - #[kinds((SimValue))] - impl_unary_op_trait! { - Not::not(self) -> SimValue<_> { - Not::not(SimValue::into_value(self)).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((&'a SimValue))] - impl_unary_op_trait! { - Not::not(self) -> SimValue<_> { - Not::not(*SimValue::value(self)).into_sim_value() - }, - } -} - -make_impls! { - #[kinds((Expr))] - impl_unary_op_trait! { - Not::not(self) -> Expr<_> { - NotB::new(self).to_expr() - }, - } } macro_rules! impl_get_target_none { @@ -1819,16 +107,9 @@ impl NotU { } } -impl ValueType for NotU { - type Type = UIntType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.arg.to_valueless().not().ty() - } -} - impl ToExpr for NotU { + type Type = UIntType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::NotU(NotU { @@ -1836,7 +117,7 @@ impl ToExpr for NotU { literal_bits: self.literal_bits, }) .intern(), - __ty: self.ty(), + __ty: self.arg.__ty, __flow: Flow::Source, } } @@ -1850,6 +131,19 @@ impl ToLiteralBits for NotU { impl_get_target_none!([Width: Size] NotU); +impl_unary_op_trait! { + #[generics(Width: Size)] + fn Not::not(arg: UIntType) -> UIntType { + NotU::new(arg).to_expr() + } +} + +forward_value_to_expr_unary_op_trait! { + #[generics(Width: Size)] + #[value(UIntValue)] + Not::not +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct NotS { arg: Expr>, @@ -1870,16 +164,9 @@ impl NotS { } } -impl ValueType for NotS { - type Type = UIntType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.arg.to_valueless().not().ty() - } -} - impl ToExpr for NotS { + type Type = UIntType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::NotS(NotS { @@ -1887,7 +174,7 @@ impl ToExpr for NotS { literal_bits: self.literal_bits, }) .intern(), - __ty: self.ty(), + __ty: self.arg.__ty.as_same_width_uint(), __flow: Flow::Source, } } @@ -1901,6 +188,19 @@ impl ToLiteralBits for NotS { impl_get_target_none!([Width: Size] NotS); +impl_unary_op_trait! { + #[generics(Width: Size)] + fn Not::not(arg: SIntType) -> UIntType { + NotS::new(arg).to_expr() + } +} + +forward_value_to_expr_unary_op_trait! { + #[generics(Width: Size)] + #[value(SIntValue)] + Not::not +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct NotB { arg: Expr, @@ -1921,16 +221,9 @@ impl NotB { } } -impl ValueType for NotB { - type Type = Bool; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - Bool - } -} - impl ToExpr for NotB { + type Type = Bool; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::NotB(NotB { @@ -1938,7 +231,7 @@ impl ToExpr for NotB { literal_bits: self.literal_bits, }) .intern(), - __ty: self.arg.ty(), + __ty: self.arg.__ty, __flow: Flow::Source, } } @@ -1952,6 +245,13 @@ impl ToLiteralBits for NotB { impl_get_target_none!([] NotB); +impl_unary_op_trait! { + #[generics()] + fn Not::not(arg: Bool) -> Bool { + NotB::new(arg).to_expr() + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct Neg { arg: Expr, @@ -1970,21 +270,22 @@ impl Neg { }); retval } + pub fn ty(self) -> SInt { + SInt::new_dyn( + Expr::ty(self.arg) + .width() + .checked_add(1) + .expect("width too big"), + ) + } pub fn arg(self) -> Expr { self.arg } } -impl ValueType for Neg { - type Type = SInt; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.arg.to_valueless().neg().ty() - } -} - impl ToExpr for Neg { + type Type = SInt; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::Neg(*self).intern(), @@ -2002,6 +303,64 @@ impl ToLiteralBits for Neg { impl_get_target_none!([] Neg); +impl_unary_op_trait! { + #[generics(Width: Size)] + fn StdNeg::neg(arg: SIntType) -> SInt { + Neg::new(Expr::as_dyn_int(arg)).to_expr() + } +} + +forward_value_to_expr_unary_op_trait! { + #[generics(Width: Size)] + #[value(SIntValue)] + StdNeg::neg +} + +macro_rules! impl_binary_op_trait { + ( + #[generics($($generics:tt)*)] + fn $Trait:ident::$method:ident($lhs:ident: $Lhs:ty, $rhs:ident: $Rhs:ty) -> $Output:ty { + $($body:tt)* + } + ) => { + impl< + Rhs: ToExpr, + $($generics)* + > $Trait for Expr<$Lhs> + { + type Output = Expr<$Output>; + + fn $method(self, rhs: Rhs) -> Self::Output { + let $lhs = self; + let $rhs = rhs.to_expr(); + $($body)* + } + } + }; +} + +macro_rules! forward_value_to_expr_binary_op_trait { + ( + #[generics($($generics:tt)*)] + #[lhs_value($LhsValue:ty)] + $Trait:ident::$method:ident + ) => { + impl< + Rhs, + $($generics)* + > $Trait for $LhsValue + where + Expr<<$LhsValue as ToExpr>::Type>: $Trait, + { + type Output = ::Type> as $Trait>::Output; + + fn $method(self, rhs: Rhs) -> Self::Output { + $Trait::$method(self.to_expr(), rhs) + } + } + }; +} + fn binary_op_literal_bits( result_ty: ResultTy, lhs: Expr, @@ -2053,16 +412,9 @@ macro_rules! binary_op_bitwise { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $ty; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - $ty - } - } - impl ToExpr for $name { + type Type = $ty; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -2071,6 +423,17 @@ macro_rules! binary_op_bitwise { } } } + + /// intentionally only implemented for expressions, not rust's bool type, + /// since that helps avoid using `==`/`!=` in hdl boolean expressions, which doesn't do + /// what is usually wanted. + impl $Trait for Expr { + type Output = Expr; + + fn $method(self, rhs: Expr) -> Expr { + $name::new(self, rhs).to_expr() + } + } }; ($name:ident, $ty:ident, $value:ident, $Trait:ident::$method:ident) => { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -2098,6 +461,9 @@ macro_rules! binary_op_bitwise { pub fn rhs(self) -> Expr<$ty> { self.rhs } + pub fn ty(self) -> UInt { + UInt::new_dyn(Expr::ty(self.lhs).width().max(Expr::ty(self.rhs).width())) + } } impl ToLiteralBits for $name { @@ -2108,16 +474,9 @@ macro_rules! binary_op_bitwise { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = UInt; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().$method(self.rhs.to_valueless()).ty() - } - } - impl ToExpr for $name { + type Type = UInt; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -2126,6 +485,19 @@ macro_rules! binary_op_bitwise { } } } + + impl_binary_op_trait! { + #[generics(LhsWidth: Size, RhsWidth: Size)] + fn $Trait::$method(lhs: $ty, rhs: $ty) -> UInt { + $name::new(Expr::as_dyn_int(lhs), Expr::as_dyn_int(rhs)).to_expr() + } + } + + forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value($value)] + $Trait::$method + } }; } @@ -2166,6 +538,15 @@ macro_rules! binary_op_add_sub { pub fn rhs(self) -> Expr<$ty> { self.rhs } + pub fn ty(self) -> $ty { + $ty::new_dyn( + Expr::ty(self.lhs) + .width() + .max(Expr::ty(self.rhs).width()) + .checked_add(1) + .expect("width too big"), + ) + } } impl ToLiteralBits for $name { @@ -2176,16 +557,9 @@ macro_rules! binary_op_add_sub { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $ty; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - $Trait::$method(self.lhs.to_valueless(), self.rhs.to_valueless()).ty() - } - } - impl ToExpr for $name { + type Type = $ty; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -2194,6 +568,19 @@ macro_rules! binary_op_add_sub { } } } + + impl_binary_op_trait! { + #[generics(LhsWidth: Size, RhsWidth: Size)] + fn $Trait::$method(lhs: $ty, rhs: $ty) -> $ty { + $name::new(Expr::as_dyn_int(lhs), Expr::as_dyn_int(rhs)).to_expr() + } + } + + forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value($value)] + $Trait::$method + } }; } @@ -2229,6 +616,14 @@ macro_rules! binary_op_mul { pub fn rhs(self) -> Expr<$ty> { self.rhs } + pub fn ty(self) -> $ty { + $ty::new_dyn( + Expr::ty(self.lhs) + .width() + .checked_add(Expr::ty(self.rhs).width()) + .expect("width too big"), + ) + } } impl ToLiteralBits for $name { @@ -2239,16 +634,9 @@ macro_rules! binary_op_mul { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $ty; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().mul(self.rhs.to_valueless()).ty() - } - } - impl ToExpr for $name { + type Type = $ty; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -2257,6 +645,19 @@ macro_rules! binary_op_mul { } } } + + impl_binary_op_trait! { + #[generics(LhsWidth: Size, RhsWidth: Size)] + fn Mul::mul(lhs: $ty, rhs: $ty) -> $ty { + $name::new(Expr::as_dyn_int(lhs), Expr::as_dyn_int(rhs)).to_expr() + } + } + + forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value($value)] + Mul::mul + } }; } @@ -2288,6 +689,9 @@ impl DivU { pub fn rhs(self) -> Expr { self.rhs } + pub fn ty(self) -> UIntType { + Expr::ty(self.lhs) + } } impl ToLiteralBits for DivU { @@ -2298,16 +702,9 @@ impl ToLiteralBits for DivU { impl_get_target_none!([LhsWidth: Size] DivU); -impl ValueType for DivU { - type Type = UIntType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().div(self.rhs.to_valueless()).ty() - } -} - impl ToExpr for DivU { + type Type = UIntType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::DivU(DivU { @@ -2322,6 +719,19 @@ impl ToExpr for DivU { } } +impl_binary_op_trait! { + #[generics(LhsWidth: Size, RhsWidth: Size)] + fn Div::div(lhs: UIntType, rhs: UIntType) -> UIntType { + DivU::new(lhs, Expr::as_dyn_int(rhs)).to_expr() + } +} + +forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value(UIntValue)] + Div::div +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct DivS { lhs: Expr, @@ -2347,6 +757,14 @@ impl DivS { pub fn rhs(self) -> Expr { self.rhs } + pub fn ty(self) -> SInt { + SInt::new_dyn( + Expr::ty(self.lhs) + .width() + .checked_add(1) + .expect("width too big"), + ) + } } impl ToLiteralBits for DivS { @@ -2357,16 +775,9 @@ impl ToLiteralBits for DivS { impl_get_target_none!([] DivS); -impl ValueType for DivS { - type Type = SInt; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().div(self.rhs.to_valueless()).ty() - } -} - impl ToExpr for DivS { + type Type = SInt; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::DivS(*self).intern(), @@ -2376,6 +787,19 @@ impl ToExpr for DivS { } } +impl_binary_op_trait! { + #[generics(LhsWidth: Size, RhsWidth: Size)] + fn Div::div(lhs: SIntType, rhs: SIntType) -> SInt { + DivS::new(Expr::as_dyn_int(lhs), Expr::as_dyn_int(rhs)).to_expr() + } +} + +forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value(SIntValue)] + Div::div +} + macro_rules! binary_op_rem { ($name:ident, $ty:ident, $value:ident) => { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -2407,6 +831,9 @@ macro_rules! binary_op_rem { pub fn rhs(self) -> Expr<$ty> { self.rhs } + pub fn ty(self) -> $ty { + $ty::new_dyn(Expr::ty(self.lhs).width().min(Expr::ty(self.rhs).width())) + } } impl ToLiteralBits for $name { @@ -2417,16 +844,9 @@ macro_rules! binary_op_rem { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $ty; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().rem(self.rhs.to_valueless()).ty() - } - } - impl ToExpr for $name { + type Type = $ty; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -2435,6 +855,19 @@ macro_rules! binary_op_rem { } } } + + impl_binary_op_trait! { + #[generics(LhsWidth: Size, RhsWidth: Size)] + fn Rem::rem(lhs: $ty, rhs: $ty) -> $ty { + $name::new(Expr::as_dyn_int(lhs), Expr::as_dyn_int(rhs)).to_expr() + } + } + + forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value($value)] + Rem::rem + } }; } @@ -2461,7 +894,7 @@ impl BundleLiteral { for (&field, &field_value) in fields.iter().zip(field_values.iter()) { assert_eq!( field.ty, - field_value.ty(), + Expr::ty(field_value), "field's type doesn't match value's type: field name {:?}", field.name ); @@ -2481,6 +914,9 @@ impl BundleLiteral { .ok_or(NotALiteralExpr), } } + pub fn ty(self) -> T { + self.ty + } pub fn field_values(self) -> Interned<[Expr]> { self.field_values } @@ -2494,16 +930,9 @@ impl ToLiteralBits for BundleLiteral { impl_get_target_none!([T: BundleType] BundleLiteral); -impl ValueType for BundleLiteral { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } -} - impl ToExpr for BundleLiteral { + type Type = T; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::BundleLiteral(BundleLiteral { @@ -2539,7 +968,7 @@ impl ArrayLiteral { for &element_value in element_values.iter() { assert_eq!( canonical_element_type, - element_value.ty(), + Expr::ty(element_value), "array's element type doesn't match element value's type", ); if let (Some(literal_bits), Ok(element_bits)) = @@ -2568,6 +997,12 @@ impl ArrayLiteral { pub fn is_empty(self) -> bool { self.element_values.is_empty() } + pub fn ty(self) -> ArrayType { + ArrayType::new( + self.element_type, + Len::from_usize(self.element_values.len()), + ) + } pub fn element_values(self) -> Interned<[Expr]> { self.element_values } @@ -2581,19 +1016,9 @@ impl ToLiteralBits for ArrayLiteral { impl_get_target_none!([Element: Type, Len: Size] ArrayLiteral); -impl ValueType for ArrayLiteral { - type Type = ArrayType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - ArrayType::new( - self.element_type, - Len::from_usize(self.element_values.len()), - ) - } -} - impl ToExpr for ArrayLiteral { + type Type = ArrayType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::ArrayLiteral(ArrayLiteral { @@ -2609,22 +1034,12 @@ impl ToExpr for ArrayLiteral { } } -impl, const N: usize> ValueType for [T; N] -where - ConstUsize: KnownSize, -{ - type Type = Array; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - StaticType::TYPE - } -} - impl, const N: usize> ToExpr for [T; N] where ConstUsize: KnownSize, { + type Type = Array; + fn to_expr(&self) -> Expr { ArrayLiteral::new( T::Type::TYPE, @@ -2634,16 +1049,9 @@ where } } -impl> ValueType for [T] { - type Type = Array; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - ArrayType::new_dyn(StaticType::TYPE, self.len()) - } -} - impl> ToExpr for [T] { + type Type = Array; + fn to_expr(&self) -> Expr { ArrayLiteral::new( T::Type::TYPE, @@ -2653,16 +1061,9 @@ impl> ToExpr for [T] { } } -impl> ValueType for Vec { - type Type = Array; - type ValueCategory = T::ValueCategory; - - fn ty(&self) -> Self::Type { - <[T]>::ty(self) - } -} - impl> ToExpr for Vec { + type Type = Array; + fn to_expr(&self) -> Expr { <[T]>::to_expr(self) } @@ -2689,7 +1090,7 @@ impl EnumLiteral { assert!(variant_index < variants.len()); assert_eq!( variants[variant_index].ty, - variant_value.map(|v| v.ty()), + variant_value.map(Expr::ty), "variant's type doesn't match value's type: variant name {:?}", variants[variant_index].name ); @@ -2729,6 +1130,9 @@ impl EnumLiteral { }; Self::new_by_index(ty, *variant_index, variant_value) } + pub fn ty(self) -> T { + self.ty + } pub fn variant_index(self) -> usize { self.variant_index } @@ -2748,16 +1152,9 @@ impl ToLiteralBits for EnumLiteral { impl_get_target_none!([T: EnumType] EnumLiteral); -impl ValueType for EnumLiteral { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } -} - impl ToExpr for EnumLiteral { + type Type = T; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::EnumLiteral(EnumLiteral { @@ -2802,6 +1199,25 @@ macro_rules! impl_dyn_shl { pub fn rhs(self) -> Expr { self.rhs } + #[track_caller] + pub fn ty(self) -> $ty { + let Some(pow2_rhs_width) = Expr::ty(self.rhs) + .width() + .try_into() + .ok() + .and_then(|v| 2usize.checked_pow(v)) + else { + panic!( + "dynamic left-shift amount's bit-width is too big, try casting the shift \ + amount to a smaller bit-width before shifting" + ); + }; + $ty::new_dyn( + (pow2_rhs_width - 1) + .checked_add(Expr::ty(self.lhs).width()) + .expect("width too big"), + ) + } } impl ToLiteralBits for $name { @@ -2812,17 +1228,9 @@ macro_rules! impl_dyn_shl { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $ty; - type ValueCategory = ValueCategoryExpr; - - #[track_caller] - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().shl(self.rhs.to_valueless()).ty() - } - } - impl ToExpr for $name { + type Type = $ty; + #[track_caller] fn to_expr(&self) -> Expr { Expr { @@ -2832,6 +1240,14 @@ macro_rules! impl_dyn_shl { } } } + + impl Shl>> for Expr<$ty> { + type Output = Expr<$ty>; + + fn shl(self, rhs: Expr>) -> Self::Output { + $name::new(Expr::as_dyn_int(self), Expr::as_dyn_int(rhs)).to_expr() + } + } }; } @@ -2856,7 +1272,7 @@ macro_rules! impl_dyn_shr { literal_bits: Err(NotALiteralExpr), }; retval.literal_bits = binary_op_literal_bits(retval.ty(), lhs, rhs, |lhs, rhs| { - Ok(lhs >> rhs.to_usize().ok_or(NotALiteralExpr)?) + Ok(lhs << rhs.to_usize().ok_or(NotALiteralExpr)?) }); retval } @@ -2866,6 +1282,10 @@ macro_rules! impl_dyn_shr { pub fn rhs(self) -> Expr { self.rhs } + #[track_caller] + pub fn ty(self) -> $ty { + Expr::ty(self.lhs) + } } impl ToLiteralBits for $name { @@ -2876,17 +1296,9 @@ macro_rules! impl_dyn_shr { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $ty; - type ValueCategory = ValueCategoryExpr; - - #[track_caller] - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().shr(self.rhs.to_valueless()).ty() - } - } - impl ToExpr for $name { + type Type = $ty; + #[track_caller] fn to_expr(&self) -> Expr { Expr { @@ -2896,19 +1308,31 @@ macro_rules! impl_dyn_shr { literal_bits: self.literal_bits, }) .intern(), - __ty: self.ty(), + __ty: Expr::ty(self.lhs), __flow: Flow::Source, } } } + + impl Shr>> for Expr<$ty> { + type Output = Expr<$ty>; + + fn shr(self, rhs: Expr>) -> Self::Output { + $name::new(self, Expr::as_dyn_int(rhs)).to_expr() + } + } }; } impl_dyn_shr!(DynShrU, UIntType, UIntValue); impl_dyn_shr!(DynShrS, SIntType, SIntValue); +fn fixed_shr_width(lhs_width: usize, rhs: usize) -> Option { + Some(lhs_width.saturating_sub(rhs).max(1)) +} + macro_rules! binary_op_fixed_shift { - ($name:ident, $ty:ident, $Trait:ident::$method:ident) => { + ($name:ident, $ty:ident, $value:ident, $width_fn:path, $Trait:ident::$method:ident) => { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct $name { lhs: Expr<$ty>, @@ -2937,6 +1361,11 @@ macro_rules! binary_op_fixed_shift { pub fn rhs(self) -> usize { self.rhs } + pub fn ty(self) -> $ty { + $ty::new_dyn( + $width_fn(Expr::ty(self.lhs).width(), self.rhs).expect("width too big"), + ) + } } impl ToLiteralBits for $name { @@ -2947,16 +1376,9 @@ macro_rules! binary_op_fixed_shift { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $ty; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.lhs.to_valueless().$method(self.rhs).ty() - } - } - impl ToExpr for $name { + type Type = $ty; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -2965,26 +1387,98 @@ macro_rules! binary_op_fixed_shift { } } } + + impl $Trait for Expr<$ty> { + type Output = Expr<$ty>; + + fn $method(self, rhs: usize) -> Self::Output { + $name::new(Expr::as_dyn_int(self), rhs).to_expr() + } + } }; } -binary_op_fixed_shift!(FixedShlU, UInt, Shl::shl); -binary_op_fixed_shift!(FixedShlS, SInt, Shl::shl); -binary_op_fixed_shift!(FixedShrU, UInt, Shr::shr); -binary_op_fixed_shift!(FixedShrS, SInt, Shr::shr); +binary_op_fixed_shift!(FixedShlU, UIntType, UIntValue, usize::checked_add, Shl::shl); +binary_op_fixed_shift!(FixedShlS, SIntType, SIntValue, usize::checked_add, Shl::shl); +binary_op_fixed_shift!(FixedShrU, UIntType, UIntValue, fixed_shr_width, Shr::shr); +binary_op_fixed_shift!(FixedShrS, SIntType, SIntValue, fixed_shr_width, Shr::shr); + +forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value(UIntValue)] + Shl::shl +} + +forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value(SIntValue)] + Shl::shl +} + +forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value(UIntValue)] + Shr::shr +} + +forward_value_to_expr_binary_op_trait! { + #[generics(LhsWidth: Size)] + #[lhs_value(SIntValue)] + Shr::shr +} + +pub trait ExprPartialEq: Type { + fn cmp_eq(lhs: Expr, rhs: Expr) -> Expr; + fn cmp_ne(lhs: Expr, rhs: Expr) -> Expr; +} + +pub trait ExprPartialOrd: ExprPartialEq { + fn cmp_lt(lhs: Expr, rhs: Expr) -> Expr; + fn cmp_le(lhs: Expr, rhs: Expr) -> Expr; + fn cmp_gt(lhs: Expr, rhs: Expr) -> Expr; + fn cmp_ge(lhs: Expr, rhs: Expr) -> Expr; +} + +impl HdlPartialEq for Lhs +where + Lhs::Type: ExprPartialEq, +{ + fn cmp_eq(self, rhs: Rhs) -> Expr { + ExprPartialEq::cmp_eq(self.to_expr(), rhs.to_expr()) + } + fn cmp_ne(self, rhs: Rhs) -> Expr { + ExprPartialEq::cmp_ne(self.to_expr(), rhs.to_expr()) + } +} + +impl HdlPartialOrd for Lhs +where + Lhs::Type: ExprPartialOrd, +{ + fn cmp_lt(self, rhs: Rhs) -> Expr { + ExprPartialOrd::cmp_lt(self.to_expr(), rhs.to_expr()) + } + fn cmp_le(self, rhs: Rhs) -> Expr { + ExprPartialOrd::cmp_le(self.to_expr(), rhs.to_expr()) + } + fn cmp_gt(self, rhs: Rhs) -> Expr { + ExprPartialOrd::cmp_gt(self.to_expr(), rhs.to_expr()) + } + fn cmp_ge(self, rhs: Rhs) -> Expr { + ExprPartialOrd::cmp_ge(self.to_expr(), rhs.to_expr()) + } +} macro_rules! impl_compare_op { ( $(#[width($LhsWidth:ident, $RhsWidth:ident)])? #[dyn_type($DynTy:ident)] #[to_dyn_type($lhs:ident => $dyn_lhs:expr, $rhs:ident => $dyn_rhs:expr)] - #[to_cmp_value($lhs_compare_value:ident => $lhs_compare_value_expr:expr, $rhs_compare_value:ident => $rhs_compare_value_expr:expr)] #[type($Lhs:ty, $Rhs:ty)] #[trait($Trait:ident)] $( struct $name:ident; - fn $value_method:ident(); - fn $expr_method:ident(); + fn $method:ident(); $CmpTrait:ident::$cmp_method:ident(); )* ) => { @@ -3021,16 +1515,9 @@ macro_rules! impl_compare_op { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = Bool; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - Bool - } - } - impl ToExpr for $name { + type Type = Bool; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -3041,15 +1528,7 @@ macro_rules! impl_compare_op { })* impl$(<$LhsWidth: Size, $RhsWidth: Size>)? $Trait<$Rhs> for $Lhs { - $(fn $value_method( - _lhs: Self, - $lhs_compare_value: Cow<'_, ::SimValue>, - _rhs: $Rhs, - $rhs_compare_value: Cow<'_, <$Rhs as Type>::SimValue>, - ) -> bool { - $CmpTrait::$cmp_method($lhs_compare_value_expr, $rhs_compare_value_expr) - })* - $(fn $expr_method($lhs: Expr, $rhs: Expr<$Rhs>) -> Expr { + $(fn $method($lhs: Expr, $rhs: Expr<$Rhs>) -> Expr { $name::new($dyn_lhs, $dyn_rhs).to_expr() })* } @@ -3059,192 +1538,79 @@ macro_rules! impl_compare_op { impl_compare_op! { #[dyn_type(Bool)] #[to_dyn_type(lhs => lhs, rhs => rhs)] - #[to_cmp_value(lhs_value => &*lhs_value, rhs_value => &*rhs_value)] #[type(Bool, Bool)] - #[trait(HdlPartialEqImpl)] - struct CmpEqB; fn cmp_value_eq(); fn cmp_expr_eq(); PartialEq::eq(); - struct CmpNeB; fn cmp_value_ne(); fn cmp_expr_ne(); PartialEq::ne(); + #[trait(ExprPartialEq)] + struct CmpEqB; fn cmp_eq(); PartialEq::eq(); + struct CmpNeB; fn cmp_ne(); PartialEq::ne(); } impl_compare_op! { #[dyn_type(Bool)] #[to_dyn_type(lhs => lhs, rhs => rhs)] - #[to_cmp_value(lhs_value => &*lhs_value, rhs_value => &*rhs_value)] #[type(Bool, Bool)] - #[trait(HdlPartialOrdImpl)] - struct CmpLtB; fn cmp_value_lt(); fn cmp_expr_lt(); PartialOrd::lt(); - struct CmpLeB; fn cmp_value_le(); fn cmp_expr_le(); PartialOrd::le(); - struct CmpGtB; fn cmp_value_gt(); fn cmp_expr_gt(); PartialOrd::gt(); - struct CmpGeB; fn cmp_value_ge(); fn cmp_expr_ge(); PartialOrd::ge(); + #[trait(ExprPartialOrd)] + struct CmpLtB; fn cmp_lt(); PartialOrd::lt(); + struct CmpLeB; fn cmp_le(); PartialOrd::le(); + struct CmpGtB; fn cmp_gt(); PartialOrd::gt(); + struct CmpGeB; fn cmp_ge(); PartialOrd::ge(); } impl_compare_op! { #[width(LhsWidth, RhsWidth)] #[dyn_type(UInt)] #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] - #[to_cmp_value(lhs_value => &lhs_value.to_bigint(), rhs_value => &rhs_value.to_bigint())] #[type(UIntType, UIntType)] - #[trait(HdlPartialEqImpl)] - struct CmpEqU; fn cmp_value_eq(); fn cmp_expr_eq(); PartialEq::eq(); - struct CmpNeU; fn cmp_value_ne(); fn cmp_expr_ne(); PartialEq::ne(); + #[trait(ExprPartialEq)] + struct CmpEqU; fn cmp_eq(); PartialEq::eq(); + struct CmpNeU; fn cmp_ne(); PartialEq::ne(); } impl_compare_op! { #[width(LhsWidth, RhsWidth)] #[dyn_type(UInt)] #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] - #[to_cmp_value(lhs_value => &lhs_value.to_bigint(), rhs_value => &rhs_value.to_bigint())] #[type(UIntType, UIntType)] - #[trait(HdlPartialOrdImpl)] - struct CmpLtU; fn cmp_value_lt(); fn cmp_expr_lt(); PartialOrd::lt(); - struct CmpLeU; fn cmp_value_le(); fn cmp_expr_le(); PartialOrd::le(); - struct CmpGtU; fn cmp_value_gt(); fn cmp_expr_gt(); PartialOrd::gt(); - struct CmpGeU; fn cmp_value_ge(); fn cmp_expr_ge(); PartialOrd::ge(); + #[trait(ExprPartialOrd)] + struct CmpLtU; fn cmp_lt(); PartialOrd::lt(); + struct CmpLeU; fn cmp_le(); PartialOrd::le(); + struct CmpGtU; fn cmp_gt(); PartialOrd::gt(); + struct CmpGeU; fn cmp_ge(); PartialOrd::ge(); } impl_compare_op! { #[width(LhsWidth, RhsWidth)] #[dyn_type(SInt)] #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] - #[to_cmp_value(lhs_value => &lhs_value.to_bigint(), rhs_value => &rhs_value.to_bigint())] #[type(SIntType, SIntType)] - #[trait(HdlPartialEqImpl)] - struct CmpEqS; fn cmp_value_eq(); fn cmp_expr_eq(); PartialEq::eq(); - struct CmpNeS; fn cmp_value_ne(); fn cmp_expr_ne(); PartialEq::ne(); + #[trait(ExprPartialEq)] + struct CmpEqS; fn cmp_eq(); PartialEq::eq(); + struct CmpNeS; fn cmp_ne(); PartialEq::ne(); } impl_compare_op! { #[width(LhsWidth, RhsWidth)] #[dyn_type(SInt)] #[to_dyn_type(lhs => Expr::as_dyn_int(lhs), rhs => Expr::as_dyn_int(rhs))] - #[to_cmp_value(lhs_value => &lhs_value.to_bigint(), rhs_value => &rhs_value.to_bigint())] #[type(SIntType, SIntType)] - #[trait(HdlPartialOrdImpl)] - struct CmpLtS; fn cmp_value_lt(); fn cmp_expr_lt(); PartialOrd::lt(); - struct CmpLeS; fn cmp_value_le(); fn cmp_expr_le(); PartialOrd::le(); - struct CmpGtS; fn cmp_value_gt(); fn cmp_expr_gt(); PartialOrd::gt(); - struct CmpGeS; fn cmp_value_ge(); fn cmp_expr_ge(); PartialOrd::ge(); + #[trait(ExprPartialOrd)] + struct CmpLtS; fn cmp_lt(); PartialOrd::lt(); + struct CmpLeS; fn cmp_le(); PartialOrd::le(); + struct CmpGtS; fn cmp_gt(); PartialOrd::gt(); + struct CmpGeS; fn cmp_ge(); PartialOrd::ge(); } -macro_rules! impl_compare_forwards_to_bool { - ($ty:ident) => { - impl HdlPartialEqImpl for $ty { - #[track_caller] - fn cmp_value_eq( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: Self, - rhs_value: Cow<'_, Self::SimValue>, - ) -> bool { - *lhs_value == *rhs_value - } - - #[track_caller] - fn cmp_expr_eq(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to(Bool).cmp_eq(rhs.cast_to(Bool)) - } - - #[track_caller] - fn cmp_expr_ne(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to(Bool).cmp_ne(rhs.cast_to(Bool)) - } - } - - impl HdlPartialOrdImpl for $ty { - #[track_caller] - fn cmp_value_lt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: Self, - rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - PartialOrd::lt(&*lhs_value, &*rhs_value) - } - - #[track_caller] - fn cmp_value_le( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: Self, - rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - PartialOrd::le(&*lhs_value, &*rhs_value) - } - - #[track_caller] - fn cmp_value_gt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: Self, - rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - PartialOrd::gt(&*lhs_value, &*rhs_value) - } - - #[track_caller] - fn cmp_value_ge( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: Self, - rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - PartialOrd::ge(&*lhs_value, &*rhs_value) - } - - #[track_caller] - fn cmp_expr_lt(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to(Bool).cmp_lt(rhs.cast_to(Bool)) - } - - #[track_caller] - fn cmp_expr_le(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to(Bool).cmp_le(rhs.cast_to(Bool)) - } - - #[track_caller] - fn cmp_expr_gt(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to(Bool).cmp_gt(rhs.cast_to(Bool)) - } - - #[track_caller] - fn cmp_expr_ge(lhs: Expr, rhs: Expr) -> Expr { - lhs.cast_to(Bool).cmp_ge(rhs.cast_to(Bool)) - } - } - }; +pub trait ExprCastTo: Type { + fn cast_to(src: Expr, to_type: ToType) -> Expr; } -impl_compare_forwards_to_bool!(Clock); -impl_compare_forwards_to_bool!(Reset); -impl_compare_forwards_to_bool!(SyncReset); -impl_compare_forwards_to_bool!(AsyncReset); - -impl CastToImpl for Bool { - type ValueOutput = bool; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - _to_type: Bool, - ) -> Self::ValueOutput { - *value - } - - fn cast_sim_value_to(value: Cow<'_, SimValue>, _to_type: Bool) -> SimValue { - value.into_owned() - } - - fn cast_expr_to(value: Expr, _to_type: Bool) -> Expr { - value - } - - fn cast_valueless_to(value: Valueless, _to_type: Bool) -> Valueless { - value +impl ExprCastTo for Bool { + fn cast_to(src: Expr, _to_type: Bool) -> Expr { + src } } macro_rules! impl_cast_int_op { - ($name:ident, $from:ident, $to:ident, $to_value:ident) => { + ($name:ident, $from:ident, $to:ident) => { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct $name { arg: Expr<$from>, @@ -3267,6 +1633,9 @@ macro_rules! impl_cast_int_op { pub fn arg(self) -> Expr<$from> { self.arg } + pub fn ty(self) -> $to { + self.ty + } } impl ToLiteralBits for $name { @@ -3277,16 +1646,9 @@ macro_rules! impl_cast_int_op { impl_get_target_none!([ToWidth: Size] $name); - impl ValueType for $name { - type Type = $to; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } - } - impl ToExpr for $name { + type Type = $to; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name($name { @@ -3301,64 +1663,55 @@ macro_rules! impl_cast_int_op { } } - impl CastToImpl<$to> for $from { - type ValueOutput = $to_value; - - fn cast_value_to(_this: Self, value: Cow<'_, Self::SimValue>, to_type: $to) -> Self::ValueOutput { - to_type.from_int_wrapping(value.to_bigint()) - } - - fn cast_expr_to(value: Expr, to_type: $to) -> Expr<$to> { - $name::new(Expr::as_dyn_int(value), to_type).to_expr() + impl ExprCastTo<$to> for $from { + fn cast_to(src: Expr, to_type: $to) -> Expr<$to> { + $name::new(Expr::as_dyn_int(src), to_type).to_expr() } } }; } -impl_cast_int_op!(CastUIntToUInt, UIntType, UIntType, UIntValue); -impl_cast_int_op!(CastUIntToSInt, UIntType, SIntType, SIntValue); -impl_cast_int_op!(CastSIntToUInt, SIntType, UIntType, UIntValue); -impl_cast_int_op!(CastSIntToSInt, SIntType, SIntType, SIntValue); +impl_cast_int_op!(CastUIntToUInt, UIntType, UIntType); +impl_cast_int_op!(CastUIntToSInt, UIntType, SIntType); +impl_cast_int_op!(CastSIntToUInt, SIntType, UIntType); +impl_cast_int_op!(CastSIntToSInt, SIntType, SIntType); macro_rules! impl_cast_bit_op { - ($name:ident, $from:ty, $(#[dyn] $from_dyn:ty,)? $to:ty, #[to_value = $to_value_expr:expr] $to_value:ty, #[trait] $Trait:ident::$trait_fn:ident $(,)?) => { - impl_cast_bit_op!($name, $from, $(#[dyn] $from_dyn,)? $to, #[to_value = $to_value_expr] $to_value); + ($name:ident, $from:ty, $(#[dyn] $from_dyn:ty,)? $to:ty, #[trait] $Trait:ident::$trait_fn:ident $(,)?) => { + impl_cast_bit_op!($name, $from, $(#[dyn] $from_dyn,)? $to); impl $Trait for Expr<$from> { - type Output = Expr<$to>; - - fn $trait_fn(&self) -> Self::Output { + fn $trait_fn(&self) -> Expr<$to> { self.cast_to_static() } } $(impl $Trait for Expr<$from_dyn> { - type Output = Expr<$to>; - - fn $trait_fn(&self) -> Self::Output { + fn $trait_fn(&self) -> Expr<$to> { self.cast_to_static() } })? }; - ($name:ident, $from:ty, $to:ty, #[to_value = $to_value_expr:expr] $to_value:ty, #[dyn] $to_dyn:ty $(,)?) => { - impl_cast_bit_op!($name, $from, $to, #[to_value = $to_value_expr] $to_value); + ($name:ident, $from:ty, $(#[dyn] $from_dyn:ty,)? $to:ty, #[dyn] $to_dyn:ty $(,)?) => { + impl_cast_bit_op!($name, $from, $(#[dyn] $from_dyn,)? $to); - impl CastToImpl<$to_dyn> for $from { - type ValueOutput = <$to_dyn as BoolOrIntType>::Value; - - fn cast_value_to(this: Self, value: Cow<'_, Self::SimValue>, to_type: $to_dyn) -> Self::ValueOutput { - >::cast_value_to(this, value, StaticType::TYPE).cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: $to_dyn) -> Expr<$to_dyn> { + impl ExprCastTo<$to_dyn> for $from { + fn cast_to(src: Expr, to_type: $to_dyn) -> Expr<$to_dyn> { assert!(to_type.width() == 1); Expr::as_dyn_int( - $name::new(value).to_expr(), + $name::new(src).to_expr(), ) } } + + $(impl ExprCastTo<$to_dyn> for $from_dyn { + fn cast_to(src: Expr, to_type: $to_dyn) -> Expr<$to_dyn> { + assert!(to_type.width() == 1); + Expr::as_dyn_int($name::new(Expr::from_dyn_int(src)).to_expr()) + } + })? }; - ($name:ident, $from:ty, $(#[dyn] $from_dyn:ty,)? $to:ty, #[to_value = $to_value_expr:expr] $to_value:ty $(,)?) => { + ($name:ident, $from:ty, $(#[dyn] $from_dyn:ty,)? $to:ty $(,)?) => { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct $name { arg: Expr<$from>, @@ -3385,16 +1738,9 @@ macro_rules! impl_cast_bit_op { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = $to; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - Self::Type::TYPE - } - } - impl ToExpr for $name { + type Type = $to; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -3404,88 +1750,50 @@ macro_rules! impl_cast_bit_op { } } - impl CastToImpl<$to> for $from { - type ValueOutput = $to_value; - - fn cast_value_to(this: Self, value: Cow<'_, Self::SimValue>, to_type: $to) -> Self::ValueOutput { - ($to_value_expr)(this, value, to_type) - } - - fn cast_expr_to(value: Expr, _to_type: $to) -> Expr<$to> { - $name::new(value).to_expr() + impl ExprCastTo<$to> for $from { + fn cast_to(src: Expr, _to_type: $to) -> Expr<$to> { + $name::new(src).to_expr() } } - $(impl CastToImpl<$to> for $from_dyn { - type ValueOutput = $to_value; - - fn cast_value_to(this: Self, value: Cow<'_, Self::SimValue>, to_type: $to) -> Self::ValueOutput { - <$from_dyn as CastToImpl<$from>>::cast_value_to(this, value, StaticType::TYPE).cast_to(to_type) - } - - fn cast_expr_to(value: Expr, _to_type: $to) -> Expr<$to> { - $name::new(Expr::<$from>::from_dyn_int(value)).to_expr() + $(impl ExprCastTo<$to> for $from_dyn { + fn cast_to(src: Expr, _to_type: $to) -> Expr<$to> { + $name::new(Expr::<$from>::from_dyn_int(src)).to_expr() } })? }; } -impl_cast_bit_op!(CastBoolToUInt, Bool, UInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] UIntValue>, #[dyn] UInt); -impl_cast_bit_op!(CastBoolToSInt, Bool, SInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] SIntValue>, #[dyn] SInt); -impl_cast_bit_op!(CastUIntToBool, UInt<1>, #[dyn] UInt, Bool, #[to_value = |_, v: Cow<'_, UIntValue<_>>, _| v.bits()[0]] bool); -impl_cast_bit_op!(CastSIntToBool, SInt<1>, #[dyn] SInt, Bool, #[to_value = |_, v: Cow<'_, SIntValue<_>>, _| v.bits()[0]] bool); -impl_cast_bit_op!(CastBoolToSyncReset, Bool, SyncReset, #[to_value = |_, v: Cow<'_, bool>, _| v.to_sync_reset()] SimValue, #[trait] ToSyncReset::to_sync_reset); -impl_cast_bit_op!(CastUIntToSyncReset, UInt<1>, #[dyn] UInt, SyncReset, #[to_value = |_, v: Cow<'_, UIntValue<_>>, _| v.bits()[0].to_sync_reset()] SimValue, #[trait] ToSyncReset::to_sync_reset); -impl_cast_bit_op!(CastSIntToSyncReset, SInt<1>, #[dyn] SInt, SyncReset, #[to_value = |_, v: Cow<'_, SIntValue<_>>, _| v.bits()[0].to_sync_reset()] SimValue, #[trait] ToSyncReset::to_sync_reset); -impl_cast_bit_op!(CastBoolToAsyncReset, Bool, AsyncReset, #[to_value = |_, v: Cow<'_, bool>, _| v.to_async_reset()] SimValue, #[trait] ToAsyncReset::to_async_reset); -impl_cast_bit_op!(CastUIntToAsyncReset, UInt<1>, #[dyn] UInt, AsyncReset, #[to_value = |_, v: Cow<'_, UIntValue<_>>, _| v.bits()[0].to_async_reset()] SimValue, #[trait] ToAsyncReset::to_async_reset); -impl_cast_bit_op!(CastSIntToAsyncReset, SInt<1>, #[dyn] SInt, AsyncReset, #[to_value = |_, v: Cow<'_, SIntValue<_>>, _| v.bits()[0].to_async_reset()] SimValue, #[trait] ToAsyncReset::to_async_reset); -impl_cast_bit_op!( - CastSyncResetToBool, - SyncReset, - Bool, - #[to_value = |_, v: Cow<'_, bool>, _| *v] - bool -); -impl_cast_bit_op!(CastSyncResetToUInt, SyncReset, UInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] UIntValue>, #[dyn] UInt); -impl_cast_bit_op!(CastSyncResetToSInt, SyncReset, SInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] SIntValue>, #[dyn] SInt); -impl_cast_bit_op!(CastSyncResetToReset, SyncReset, Reset, #[to_value = |_, v: Cow<'_, bool>, t| SimValue::from_value(t, *v)] SimValue); -impl_cast_bit_op!( - CastAsyncResetToBool, - AsyncReset, - Bool, - #[to_value = |_, v: Cow<'_, bool>, _| *v] - bool -); -impl_cast_bit_op!(CastAsyncResetToUInt, AsyncReset, UInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] UIntValue>, #[dyn] UInt); -impl_cast_bit_op!(CastAsyncResetToSInt, AsyncReset, SInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] SIntValue>, #[dyn] SInt); -impl_cast_bit_op!(CastAsyncResetToReset, AsyncReset, Reset, #[to_value = |_, v: Cow<'_, bool>, t| SimValue::from_value(t, *v)] SimValue); -impl_cast_bit_op!( - CastResetToBool, - Reset, - Bool, - #[to_value = |_, v: Cow<'_, bool>, _| *v] - bool -); -impl_cast_bit_op!(CastResetToUInt, Reset, UInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] UIntValue>, #[dyn] UInt); -impl_cast_bit_op!(CastResetToSInt, Reset, SInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] SIntValue>, #[dyn] SInt); -impl_cast_bit_op!(CastBoolToClock, Bool, Clock, #[to_value = |_, v: Cow<'_, bool>, _| v.to_clock()] SimValue, #[trait] ToClock::to_clock); -impl_cast_bit_op!(CastUIntToClock, UInt<1>, #[dyn] UInt, Clock, #[to_value = |_, v: Cow<'_, UIntValue<_>>, _| v.bits()[0].to_clock()] SimValue, #[trait] ToClock::to_clock); -impl_cast_bit_op!(CastSIntToClock, SInt<1>, #[dyn] SInt, Clock, #[to_value = |_, v: Cow<'_, SIntValue<_>>, _| v.bits()[0].to_clock()] SimValue, #[trait] ToClock::to_clock); -impl_cast_bit_op!( - CastClockToBool, - Clock, - Bool, - #[to_value = |_, v: Cow<'_, bool>, _| *v] - bool -); -impl_cast_bit_op!(CastClockToUInt, Clock, UInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] UIntValue>, #[dyn] UInt); -impl_cast_bit_op!(CastClockToSInt, Clock, SInt<1>, #[to_value = |_, v: Cow<'_, bool>, _| (*v).into()] SIntValue>, #[dyn] SInt); +impl_cast_bit_op!(CastBoolToUInt, Bool, UInt<1>, #[dyn] UInt); +impl_cast_bit_op!(CastBoolToSInt, Bool, SInt<1>, #[dyn] SInt); +impl_cast_bit_op!(CastUIntToBool, UInt<1>, #[dyn] UInt, Bool); +impl_cast_bit_op!(CastSIntToBool, SInt<1>, #[dyn] SInt, Bool); +impl_cast_bit_op!(CastBoolToSyncReset, Bool, SyncReset, #[trait] ToSyncReset::to_sync_reset); +impl_cast_bit_op!(CastUIntToSyncReset, UInt<1>, #[dyn] UInt, SyncReset, #[trait] ToSyncReset::to_sync_reset); +impl_cast_bit_op!(CastSIntToSyncReset, SInt<1>, #[dyn] SInt, SyncReset, #[trait] ToSyncReset::to_sync_reset); +impl_cast_bit_op!(CastBoolToAsyncReset, Bool, AsyncReset, #[trait] ToAsyncReset::to_async_reset); +impl_cast_bit_op!(CastUIntToAsyncReset, UInt<1>, #[dyn] UInt, AsyncReset, #[trait] ToAsyncReset::to_async_reset); +impl_cast_bit_op!(CastSIntToAsyncReset, SInt<1>, #[dyn] SInt, AsyncReset, #[trait] ToAsyncReset::to_async_reset); +impl_cast_bit_op!(CastSyncResetToBool, SyncReset, Bool); +impl_cast_bit_op!(CastSyncResetToUInt, SyncReset, UInt<1>, #[dyn] UInt); +impl_cast_bit_op!(CastSyncResetToSInt, SyncReset, SInt<1>, #[dyn] SInt); +impl_cast_bit_op!(CastSyncResetToReset, SyncReset, Reset); +impl_cast_bit_op!(CastAsyncResetToBool, AsyncReset, Bool); +impl_cast_bit_op!(CastAsyncResetToUInt, AsyncReset, UInt<1>, #[dyn] UInt); +impl_cast_bit_op!(CastAsyncResetToSInt, AsyncReset, SInt<1>, #[dyn] SInt); +impl_cast_bit_op!(CastAsyncResetToReset, AsyncReset, Reset); +impl_cast_bit_op!(CastResetToBool, Reset, Bool); +impl_cast_bit_op!(CastResetToUInt, Reset, UInt<1>, #[dyn] UInt); +impl_cast_bit_op!(CastResetToSInt, Reset, SInt<1>, #[dyn] SInt); +impl_cast_bit_op!(CastBoolToClock, Bool, Clock, #[trait] ToClock::to_clock); +impl_cast_bit_op!(CastUIntToClock, UInt<1>, #[dyn] UInt, Clock, #[trait] ToClock::to_clock); +impl_cast_bit_op!(CastSIntToClock, SInt<1>, #[dyn] SInt, Clock, #[trait] ToClock::to_clock); +impl_cast_bit_op!(CastClockToBool, Clock, Bool); +impl_cast_bit_op!(CastClockToUInt, Clock, UInt<1>, #[dyn] UInt); +impl_cast_bit_op!(CastClockToSInt, Clock, SInt<1>, #[dyn] SInt); impl ToReset for Expr { - type Output = Expr; - - fn to_reset(&self) -> Self::Output { + fn to_reset(&self) -> Expr { struct Dispatch; impl ResetTypeDispatch for Dispatch { type Input = Expr; @@ -3507,279 +1815,101 @@ impl ToReset for Expr { } } -impl ToReset for SimValue { - type Output = Expr; - - fn to_reset(&self) -> Self::Output { - (*self).to_expr().to_sync_reset().to_reset() +impl ExprCastTo for AsyncReset { + fn cast_to(src: Expr, _to_type: AsyncReset) -> Expr { + src } } -impl ToReset for SimValue { - type Output = Expr; - - fn to_reset(&self) -> Self::Output { - (*self).to_expr().to_async_reset().to_reset() +impl ExprCastTo for AsyncReset { + fn cast_to(src: Expr, to_type: SyncReset) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for AsyncReset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - _to_type: AsyncReset, - ) -> Self::ValueOutput { - value.to_async_reset() - } - - fn cast_expr_to(value: Expr, _to_type: AsyncReset) -> Expr { - value +impl ExprCastTo for AsyncReset { + fn cast_to(src: Expr, to_type: Clock) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for AsyncReset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - _to_type: SyncReset, - ) -> Self::ValueOutput { - value.to_sync_reset() - } - - fn cast_expr_to(value: Expr, to_type: SyncReset) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for SyncReset { + fn cast_to(src: Expr, to_type: AsyncReset) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for AsyncReset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: Clock, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: Clock) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for SyncReset { + fn cast_to(src: Expr, _to_type: SyncReset) -> Expr { + src } } -impl CastToImpl for SyncReset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: AsyncReset, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: AsyncReset) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for SyncReset { + fn cast_to(src: Expr, to_type: Clock) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for SyncReset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - _to_type: SyncReset, - ) -> Self::ValueOutput { - value.to_sync_reset() - } - - fn cast_expr_to(value: Expr, _to_type: SyncReset) -> Expr { - value +impl ExprCastTo for Reset { + fn cast_to(src: Expr, to_type: AsyncReset) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for SyncReset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: Clock, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: Clock) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for Reset { + fn cast_to(src: Expr, to_type: SyncReset) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for Reset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: AsyncReset, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: AsyncReset) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for Reset { + fn cast_to(src: Expr, _to_type: Reset) -> Expr { + src } } -impl CastToImpl for Reset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: SyncReset, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: SyncReset) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for Reset { + fn cast_to(src: Expr, to_type: Clock) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for Reset { - type ValueOutput = SimValue; - - #[track_caller] - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: Reset, - ) -> Self::ValueOutput { - SimValue::from_value(to_type, *value) - } - - #[track_caller] - fn cast_expr_to(value: Expr, _to_type: Reset) -> Expr { - value +impl ExprCastTo for Clock { + fn cast_to(src: Expr, to_type: AsyncReset) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for Reset { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: Clock, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: Clock) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for Clock { + fn cast_to(src: Expr, to_type: SyncReset) -> Expr { + src.cast_to(Bool).cast_to(to_type) } } -impl CastToImpl for Clock { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: AsyncReset, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: AsyncReset) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo for Clock { + fn cast_to(src: Expr, _to_type: Clock) -> Expr { + src } } -impl CastToImpl for Clock { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: SyncReset, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: SyncReset) -> Expr { - value.cast_to(Bool).cast_to(to_type) +impl ExprCastTo<()> for PhantomConst { + fn cast_to(src: Expr, to_type: ()) -> Expr<()> { + src.cast_to_bits().cast_bits_to(to_type) } } -impl CastToImpl for Clock { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - _to_type: Clock, - ) -> Self::ValueOutput { - value.to_clock() - } - - fn cast_expr_to(value: Expr, _to_type: Clock) -> Expr { - value +impl ExprCastTo> for () { + fn cast_to(src: Expr, to_type: PhantomConst) -> Expr> { + src.cast_to_bits().cast_bits_to(to_type) } } -impl CastToImpl<()> for PhantomConst { - type ValueOutput = (); - - fn cast_value_to( - _this: Self, - _value: Cow<'_, Self::SimValue>, - _to_type: (), - ) -> Self::ValueOutput { - () - } - - fn cast_expr_to(value: Expr, to_type: ()) -> Expr<()> { - value.cast_to_bits().cast_bits_to(to_type) - } -} - -impl CastToImpl> for () { - type ValueOutput = PhantomConst; - - fn cast_value_to( - _this: Self, - _value: Cow<'_, Self::SimValue>, - to_type: PhantomConst, - ) -> Self::ValueOutput { - to_type - } - - fn cast_expr_to(value: Expr, to_type: PhantomConst) -> Expr> { - value.cast_to_bits().cast_bits_to(to_type) - } -} - -impl CastToImpl> +impl ExprCastTo> for PhantomConst { - type ValueOutput = PhantomConst; - - fn cast_value_to( - _this: Self, - _value: Cow<'_, Self::SimValue>, - to_type: PhantomConst, - ) -> Self::ValueOutput { - to_type - } - - fn cast_expr_to(value: Expr, to_type: PhantomConst) -> Expr> { - value.cast_to_bits().cast_bits_to(to_type) + fn cast_to(src: Expr, to_type: PhantomConst) -> Expr> { + src.cast_to_bits().cast_bits_to(to_type) } } @@ -3804,10 +1934,10 @@ impl fmt::Debug for FieldAccess { impl FieldAccess { #[track_caller] pub fn new_by_index(base: Expr, field_index: usize) -> Self { - let field = base.ty().fields()[field_index]; + let field = Expr::ty(base).fields()[field_index]; let field_type = FieldType::from_canonical(field.ty); let literal_bits = base.to_literal_bits().map(|bits| { - bits[base.ty().field_offsets()[field_index].bit_width..][..field.ty.bit_width()] + bits[Expr::ty(base).field_offsets()[field_index].bit_width..][..field.ty.bit_width()] .intern() }); let target = base.target().map(|base| { @@ -3826,7 +1956,7 @@ impl FieldAccess { } #[track_caller] pub fn new_by_name(base: Expr, name: Interned) -> Self { - let base_ty = base.ty(); + let base_ty = Expr::ty(base); let Some(field_index) = base_ty.name_indexes().get(&name) else { panic!("unknown field {name:?}: in {base_ty:?}"); }; @@ -3861,16 +1991,9 @@ impl ToLiteralBits for FieldAccess { } } -impl ValueType for FieldAccess { - type Type = FieldType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.field_type - } -} - impl ToExpr for FieldAccess { + type Type = FieldType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::FieldAccess(FieldAccess { @@ -3900,10 +2023,10 @@ pub struct VariantAccess { impl VariantAccess { #[track_caller] pub fn new_by_index(base: Expr, variant_index: usize) -> Self { - let variant = base.ty().variants()[variant_index]; + let variant = Expr::ty(base).variants()[variant_index]; let variant_type = variant.ty.map(VariantType::from_canonical); let literal_bits = base.to_literal_bits().and_then(|bits| { - let discriminant_bit_width = base.ty().discriminant_bit_width(); + let discriminant_bit_width = Expr::ty(base).discriminant_bit_width(); if bits[..discriminant_bit_width] != [variant_index].view_bits::()[..discriminant_bit_width] { @@ -3924,7 +2047,7 @@ impl VariantAccess { } #[track_caller] pub fn new_by_name(base: Expr, name: Interned) -> Self { - let base_ty = base.ty(); + let base_ty = Expr::ty(base); let Some(variant_index) = base_ty.name_indexes().get(&name) else { panic!("unknown variant {name:?}: in {base_ty:?}"); }; @@ -3955,17 +2078,9 @@ impl ToLiteralBits for VariantAccess { impl_get_target_none!([VariantType: Type] VariantAccess); -impl ValueType for VariantAccess { - type Type = VariantType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.variant_type - .unwrap_or_else(|| VariantType::from_canonical(().canonical())) - } -} - impl ToExpr for VariantAccess { + type Type = VariantType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::VariantAccess(VariantAccess { @@ -3976,7 +2091,9 @@ impl ToExpr for VariantAccess { literal_bits: self.literal_bits, }) .intern(), - __ty: self.ty(), + __ty: self + .variant_type + .unwrap_or_else(|| VariantType::from_canonical(().canonical())), __flow: Flow::Source, } } @@ -3994,7 +2111,7 @@ pub struct ArrayIndex { impl ArrayIndex { #[track_caller] pub fn new(base: Expr, element_index: usize) -> Self { - let base_ty = base.ty(); + let base_ty = Expr::ty(base); assert!(element_index < base_ty.len()); let element_type = ElementType::from_canonical(base_ty.element()); let literal_bits = base.to_literal_bits().map(|bits| { @@ -4042,22 +2159,15 @@ impl GetTarget for ArrayIndex { } } -impl ValueType for ArrayIndex { - type Type = ElementType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.element_type - } -} - impl ToExpr for ArrayIndex { + type Type = ElementType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::ArrayIndex(ArrayIndex { base: self.base, element_index: self.element_index, - element_type: self.base.ty().element(), + element_type: Expr::ty(self.base).element(), literal_bits: self.literal_bits, target: self.target, }) @@ -4093,7 +2203,7 @@ pub struct DynArrayIndex { impl DynArrayIndex { #[track_caller] pub fn new(base: Expr, element_index: Expr) -> Self { - let base_ty = base.ty(); + let base_ty = Expr::ty(base); let element_type = ElementType::from_canonical(base_ty.element()); let literal_bits = base .to_literal_bits() @@ -4145,22 +2255,15 @@ impl GetTarget for DynArrayIndex { } } -impl ValueType for DynArrayIndex { - type Type = ElementType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.element_type - } -} - impl ToExpr for DynArrayIndex { + type Type = ElementType; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::DynArrayIndex(DynArrayIndex { base: self.base, element_index: self.element_index, - element_type: self.base.ty().element(), + element_type: Expr::ty(self.base).element(), literal_bits: self.literal_bits, target: self.target, }) @@ -4253,7 +2356,7 @@ macro_rules! impl_int_slice { impl $name { pub fn new(base: Expr<$ty>, range: Range) -> Self { assert!( - range.start <= range.end && range.end <= base.ty().width(), + range.start <= range.end && range.end <= Expr::ty(base).width(), "invalid range" ); let literal_bits = base @@ -4282,63 +2385,37 @@ macro_rules! impl_int_slice { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = UInt; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - UInt::new_dyn(self.range().len()) - } - } - impl ToExpr for $name { + type Type = UInt; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), - __ty: self.ty(), + __ty: UInt::new_dyn(self.range().len()), __flow: Flow::Source, } } } - impl> std::ops::Index for Valueless<$ty> { - type Output = Valueless; - - #[track_caller] - fn index(&self, index: I) -> &Self::Output { - let range = self.ty().slice_index_to_range(index); - Interned::into_inner(Valueless::new(UInt::new_dyn(range.len())).intern_sized()) - } - } - impl> ExprIndex for $ty { type Output = UInt; #[track_caller] fn expr_index(this: &Expr, index: I) -> &Expr { let base = Expr::as_dyn_int(*this); - let range = base.ty().slice_index_to_range(index); + let base_ty = Expr::ty(base); + let range = base_ty.slice_index_to_range(index); Interned::into_inner($name::new(base, range).to_expr().intern_sized()) } } - impl std::ops::Index for Valueless<$ty> { - type Output = Valueless; - - #[track_caller] - fn index(&self, index: usize) -> &Self::Output { - assert!(index < self.ty().width()); - &const { Valueless::new(Bool) } - } - } - impl ExprIndex for $ty { type Output = Bool; #[track_caller] fn expr_index(this: &Expr, index: usize) -> &Expr { let base = Expr::as_dyn_int(*this); - let base_ty = base.ty(); + let base_ty = Expr::ty(base); assert!(index < base_ty.width()); Interned::into_inner( $name::new(base, index..(index + 1)) @@ -4380,16 +2457,9 @@ macro_rules! impl_reduce_bits { impl_get_target_none!([] $name); - impl ValueType for $name { - type Type = UInt<1>; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - StaticType::TYPE - } - } - impl ToExpr for $name { + type Type = UInt<1>; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::$name(*self).intern(), @@ -4410,99 +2480,126 @@ impl_reduce_bits!(ReduceBitXorU, UInt, |bits| (bits.count_ones() % 2 != 0) impl_reduce_bits!(ReduceBitXorS, SInt, |bits| (bits.count_ones() % 2 != 0) .to_literal_bits()); -impl ReduceBitsImpl for UIntType { - fn value_reduce_bitand( - _this: Self, - value: Cow<'_, Self::SimValue>, - ) -> UIntValue> { - value.bits().all().into() +impl ReduceBits for Expr> { + type UIntOutput = Expr>; + type BoolOutput = Expr; + + fn reduce_bitand(self) -> Self::UIntOutput { + ReduceBitAndU::new(Expr::as_dyn_int(self)).to_expr() } - fn value_reduce_bitor(_this: Self, value: Cow<'_, Self::SimValue>) -> UIntValue> { - value.bits().any().into() + fn reduce_bitor(self) -> Self::UIntOutput { + ReduceBitOrU::new(Expr::as_dyn_int(self)).to_expr() } - fn value_reduce_bitxor( - _this: Self, - value: Cow<'_, Self::SimValue>, - ) -> UIntValue> { - (value.bits().count_ones() % 2 != 0).into() + fn reduce_bitxor(self) -> Self::UIntOutput { + ReduceBitXorU::new(Expr::as_dyn_int(self)).to_expr() } - fn expr_reduce_bitand(this: Expr) -> Expr> { - ReduceBitAndU::new(Expr::as_dyn_int(this)).to_expr() + fn any_one_bits(self) -> Self::BoolOutput { + self.reduce_bitor().cast_to_static() } - fn expr_reduce_bitor(this: Expr) -> Expr> { - ReduceBitOrU::new(Expr::as_dyn_int(this)).to_expr() + fn any_zero_bits(self) -> Self::BoolOutput { + (!self.reduce_bitand()).cast_to_static() } - fn expr_reduce_bitxor(this: Expr) -> Expr> { - ReduceBitXorU::new(Expr::as_dyn_int(this)).to_expr() + fn all_one_bits(self) -> Self::BoolOutput { + self.reduce_bitand().cast_to_static() + } + + fn all_zero_bits(self) -> Self::BoolOutput { + (!self.reduce_bitor()).cast_to_static() + } + + fn parity_odd(self) -> Self::BoolOutput { + self.reduce_bitxor().cast_to_static() + } + + fn parity_even(self) -> Self::BoolOutput { + (!self.reduce_bitxor()).cast_to_static() } } -impl ReduceBitsImpl for SIntType { - fn value_reduce_bitand( - _this: Self, - value: Cow<'_, Self::SimValue>, - ) -> UIntValue> { - value.bits().all().into() +impl ReduceBits for Expr> { + type UIntOutput = Expr>; + type BoolOutput = Expr; + + fn reduce_bitand(self) -> Self::UIntOutput { + ReduceBitAndS::new(Expr::as_dyn_int(self)).to_expr() } - fn value_reduce_bitor(_this: Self, value: Cow<'_, Self::SimValue>) -> UIntValue> { - value.bits().any().into() + fn reduce_bitor(self) -> Self::UIntOutput { + ReduceBitOrS::new(Expr::as_dyn_int(self)).to_expr() } - fn value_reduce_bitxor( - _this: Self, - value: Cow<'_, Self::SimValue>, - ) -> UIntValue> { - (value.bits().count_ones() % 2 != 0).into() + fn reduce_bitxor(self) -> Self::UIntOutput { + ReduceBitXorS::new(Expr::as_dyn_int(self)).to_expr() } - fn expr_reduce_bitand(this: Expr) -> Expr> { - ReduceBitAndS::new(Expr::as_dyn_int(this)).to_expr() + fn any_one_bits(self) -> Self::BoolOutput { + self.reduce_bitor().cast_to_static() } - fn expr_reduce_bitor(this: Expr) -> Expr> { - ReduceBitOrS::new(Expr::as_dyn_int(this)).to_expr() + fn any_zero_bits(self) -> Self::BoolOutput { + (!self.reduce_bitand()).cast_to_static() } - fn expr_reduce_bitxor(this: Expr) -> Expr> { - ReduceBitXorS::new(Expr::as_dyn_int(this)).to_expr() + fn all_one_bits(self) -> Self::BoolOutput { + self.reduce_bitand().cast_to_static() + } + + fn all_zero_bits(self) -> Self::BoolOutput { + (!self.reduce_bitor()).cast_to_static() + } + + fn parity_odd(self) -> Self::BoolOutput { + self.reduce_bitxor().cast_to_static() + } + + fn parity_even(self) -> Self::BoolOutput { + (!self.reduce_bitxor()).cast_to_static() } } -impl ReduceBitsImpl for Bool { - fn value_reduce_bitand( - _this: Self, - value: Cow<'_, Self::SimValue>, - ) -> UIntValue> { - (*value).into() +impl ReduceBits for Expr { + type UIntOutput = Expr>; + type BoolOutput = Expr; + + fn reduce_bitand(self) -> Self::UIntOutput { + self.cast_to_static() } - fn value_reduce_bitor(_this: Self, value: Cow<'_, Self::SimValue>) -> UIntValue> { - (*value).into() + fn reduce_bitor(self) -> Self::UIntOutput { + self.cast_to_static() } - fn value_reduce_bitxor( - _this: Self, - value: Cow<'_, Self::SimValue>, - ) -> UIntValue> { - (*value).into() + fn reduce_bitxor(self) -> Self::UIntOutput { + self.cast_to_static() } - fn expr_reduce_bitand(this: Expr) -> Expr> { - this.cast_to_static() + fn any_one_bits(self) -> Self::BoolOutput { + self } - fn expr_reduce_bitor(this: Expr) -> Expr> { - this.cast_to_static() + fn any_zero_bits(self) -> Self::BoolOutput { + !self } - fn expr_reduce_bitxor(this: Expr) -> Expr> { - this.cast_to_static() + fn all_one_bits(self) -> Self::BoolOutput { + self + } + + fn all_zero_bits(self) -> Self::BoolOutput { + !self + } + + fn parity_odd(self) -> Self::BoolOutput { + self + } + + fn parity_even(self) -> Self::BoolOutput { + !self } } @@ -4532,20 +2629,13 @@ impl ToLiteralBits for CastToBits { impl_get_target_none!([] CastToBits); -impl ValueType for CastToBits { - type Type = UInt; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - UInt::new_dyn(self.arg.ty().bit_width()) - } -} - impl ToExpr for CastToBits { + type Type = UInt; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::CastToBits(*self).intern(), - __ty: self.ty(), + __ty: UInt::new_dyn(Expr::ty(self.arg).bit_width()), __flow: Flow::Source, } } @@ -4563,7 +2653,7 @@ impl CastBitsTo { pub fn new(arg: Expr, ty: T) -> Self { let ty_props = ty.canonical().type_properties(); assert!(ty_props.is_castable_from_bits); - assert_eq!(arg.ty().width(), ty_props.bit_width); + assert_eq!(Expr::ty(arg).width(), ty_props.bit_width); Self { arg, ty, @@ -4573,6 +2663,9 @@ impl CastBitsTo { pub fn arg(self) -> Expr { self.arg } + pub fn ty(self) -> T { + self.ty + } } impl ToLiteralBits for CastBitsTo { @@ -4583,16 +2676,9 @@ impl ToLiteralBits for CastBitsTo { impl_get_target_none!([T: Type] CastBitsTo); -impl ValueType for CastBitsTo { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } -} - impl ToExpr for CastBitsTo { + type Type = T; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::CastBitsTo(CastBitsTo { @@ -4617,6 +2703,9 @@ impl Uninit { pub fn new(ty: T) -> Self { Self { ty } } + pub fn ty(self) -> T { + self.ty + } } impl ToLiteralBits for Uninit { @@ -4627,16 +2716,9 @@ impl ToLiteralBits for Uninit { impl_get_target_none!([T: Type] Uninit); -impl ValueType for Uninit { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } -} - impl ToExpr for Uninit { + type Type = T; + fn to_expr(&self) -> Expr { Expr { __enum: ExprEnum::Uninit(Uninit { diff --git a/crates/fayalite/src/expr/ops/test_ops_impls.rs b/crates/fayalite/src/expr/ops/test_ops_impls.rs deleted file mode 100644 index d29aff0..0000000 --- a/crates/fayalite/src/expr/ops/test_ops_impls.rs +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{expr::Valueless, expr::ops::make_impls, prelude::*}; -use std::num::NonZero; - -macro_rules! assert_neg_impls { - ([$($Lifetimes:tt)*][$($Bounds:tt)*] ($ty:ty),) => { - const _: () = { - fn _check_neg_impl<$($Lifetimes)*$($Bounds)*>(v: $ty) - -> impl ValueType< - ValueCategory = <$ty as ValueType>::ValueCategory, - Type = <::Type> as std::ops::Neg>::Output as ValueType>::Type, - > { - std::ops::Neg::neg(v) - } - }; - }; -} - -make_impls! { - #[kinds((sint_local<'a, Width>))] - assert_neg_impls! {} -} - -macro_rules! assert_not_impls { - ([$($Lifetimes:tt)*][$($Bounds:tt)*] ($ty:ty),) => { - const _: () = { - fn _check_not_impl<$($Lifetimes)*$($Bounds)*>(v: $ty) - -> impl ValueType< - ValueCategory = <$ty as ValueType>::ValueCategory, - Type = <::Type> as std::ops::Not>::Output as ValueType>::Type, - > { - std::ops::Not::not(v) - } - }; - }; -} - -make_impls! { - #[kinds((int_local<'a, Width>), (bool<'a>))] - assert_not_impls! {} -} - -macro_rules! assert_cast_to_bits_impls { - ([$($Lifetimes:tt)*][$($Bounds:tt)*] ($ty:ty),) => { - const _: () = { - fn _check_cast_to_bits_impl<$($Lifetimes)*$($Bounds)*>(v: $ty) - -> impl ValueType< - ValueCategory = <$ty as ValueType>::ValueCategory, - Type = <::Type> as CastToBits>::Output as ValueType>::Type, - > { - <$ty as CastToBits>::cast_to_bits(&v) - } - }; - }; -} - -make_impls! { - #[kinds((uint<'a, Width>), (sint<'a, Width>), (bool<'a>))] - assert_cast_to_bits_impls! {} -} - -macro_rules! assert_simple_bin_op_impls { - ([$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), [$($RLifetimes:tt)*][$($RBounds:tt)*] ($($R:tt)*), !$Trait:ident::$f:ident) => { - #[expect(dead_code)] - const _: () = { - trait HasImpl { - fn check_impl(self); - } - - trait NoImpl { - fn check_impl(&self) -> &'static dyn NoImpl; - } - - impl NoImpl for (L, R) { - fn check_impl(&self) -> &'static dyn NoImpl { - unreachable!() - } - } - - impl, R> HasImpl for (L, R) { - fn check_impl(self) {} - } - - fn check_simple_bin_op_no_impl<$($LLifetimes)* $($RLifetimes)* $($LBounds)* $($RBounds)*>(l: $($L)*, r: $($R)*) { - let _: &'static dyn NoImpl = (l, r).check_impl(); - } - }; - }; - ([$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), [$($RLifetimes:tt)*][$($RBounds:tt)*] (usize), Shl::shl) => { - const _: () = { - #[expect(dead_code)] - fn check_simple_bin_op_impl<$($LLifetimes)* $($RLifetimes)* $($LBounds)* $($RBounds)*>(l: $($L)*, r: usize) - -> impl ValueType< - ValueCategory = <($($L)*, usize) as ValueType>::ValueCategory, - Type = <::Type> as std::ops::Shl>::Output as ValueType>::Type, - > { - std::ops::Shl::shl(l, r) - } - }; - }; - ([$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), [$($RLifetimes:tt)*][$($RBounds:tt)*] (usize), Shr::shr) => { - const _: () = { - #[expect(dead_code)] - fn check_simple_bin_op_impl<$($LLifetimes)* $($RLifetimes)* $($LBounds)* $($RBounds)*>(l: $($L)*, r: usize) - -> impl ValueType< - ValueCategory = <($($L)*, usize) as ValueType>::ValueCategory, - Type = <::Type> as std::ops::Shr>::Output as ValueType>::Type, - > { - std::ops::Shr::shr(l, r) - } - }; - }; - ([$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), [$($RLifetimes:tt)*][$($RBounds:tt)*] ($($R:tt)*), $Trait:ident::$f:ident) => { - const _: () = { - #[expect(dead_code)] - fn check_simple_bin_op_impl<$($LLifetimes)* $($RLifetimes)* $($LBounds)* $($RBounds)*>(l: $($L)*, r: $($R)*) - -> impl ValueType< - ValueCategory = <($($L)*, $($R)*) as ValueType>::ValueCategory, - Type = <::Type> as std::ops::$Trait::Type>>>::Output as ValueType>::Type, - > { - std::ops::$Trait::$f(l, r) - } - }; - }; - ($LLifetimes:tt $LBounds:tt ($($L:tt)*), $RLifetimes:tt $RBounds:tt ($($R:tt)*), !$FirstTrait:ident::$first_f:ident, $($rest:tt)*) => { - assert_simple_bin_op_impls! { - $LLifetimes $LBounds ($($L)*), $RLifetimes $RBounds ($($R)*), !$FirstTrait::$first_f - } - assert_simple_bin_op_impls! { - $LLifetimes $LBounds ($($L)*), $RLifetimes $RBounds ($($R)*), $($rest)* - } - }; - ($LLifetimes:tt $LBounds:tt ($($L:tt)*), $RLifetimes:tt $RBounds:tt ($($R:tt)*), $FirstTrait:ident::$first_f:ident, $($rest:tt)*) => { - assert_simple_bin_op_impls! { - $LLifetimes $LBounds ($($L)*), $RLifetimes $RBounds ($($R)*), $FirstTrait::$first_f - } - assert_simple_bin_op_impls! { - $LLifetimes $LBounds ($($L)*), $RLifetimes $RBounds ($($R)*), $($rest)* - } - }; -} - -make_impls! { - #[kinds((uint_local<'l, L>))] - #[kinds((uint<'r, R>))] - assert_simple_bin_op_impls! {Add::add, Sub::sub, Mul::mul, Div::div, Rem::rem, BitAnd::bitand, BitOr::bitor, BitXor::bitxor} -} - -make_impls! { - #[kinds((uint<'l, L>))] - #[kinds((uint_local<'r, R>))] - assert_simple_bin_op_impls! {Add::add, Sub::sub, Mul::mul, Div::div, Rem::rem, BitAnd::bitand, BitOr::bitor, BitXor::bitxor, Shl::shl, Shr::shr} -} - -make_impls! { - #[kinds((sint_local<'l, L>))] - #[kinds((sint<'r, R>))] - assert_simple_bin_op_impls! {Add::add, Sub::sub, Mul::mul, Div::div, Rem::rem, BitAnd::bitand, BitOr::bitor, BitXor::bitxor} -} - -make_impls! { - #[kinds((sint<'l, L>))] - #[kinds((sint_local<'r, R>))] - assert_simple_bin_op_impls! {Add::add, Sub::sub, Mul::mul, Div::div, Rem::rem, BitAnd::bitand, BitOr::bitor, BitXor::bitxor} -} - -make_impls! { - #[kinds((sint<'l, L>))] - #[kinds((uint_local<'r, R>))] - assert_simple_bin_op_impls! {Shl::shl, Shr::shr} -} - -make_impls! { - #[kinds((uint_local<'l, L>))] - assert_simple_bin_op_impls! {[][] (usize), Shl::shl, Shr::shr} -} - -make_impls! { - #[kinds((sint_local<'l, L>))] - assert_simple_bin_op_impls! {[][] (usize), Shl::shl, Shr::shr} -} - -make_impls! { - #[kinds((bool_local<'l>))] - #[kinds((bool_local<'r>))] - assert_simple_bin_op_impls! {BitAnd::bitand, BitOr::bitor, BitXor::bitxor} -} - -make_impls! { - #[kinds((bool<'l>))] - #[kinds((Valueless))] - assert_simple_bin_op_impls! {BitAnd::bitand, BitOr::bitor, BitXor::bitxor} -} - -make_impls! { - #[kinds((Valueless))] - #[kinds((bool<'r>))] - assert_simple_bin_op_impls! {BitAnd::bitand, BitOr::bitor, BitXor::bitxor} -} - -make_impls! { - #[kinds((bool_at_most_sim_value<'l>))] - #[kinds((bool_at_most_sim_value<'r>))] - assert_simple_bin_op_impls! {BitAnd::bitand, BitOr::bitor, BitXor::bitxor} -} - -// assert there are no impls of BitAnd/BitOr/BitXor between Expr and Rust's bool, -// since that helps avoid using `==`/`!=` in hdl boolean expressions, which doesn't do -// what is usually wanted. -make_impls! { - #[kinds((Expr))] - #[kinds(bool)] - assert_simple_bin_op_impls! {!BitAnd::bitand, !BitOr::bitor, !BitXor::bitxor} -} - -make_impls! { - #[kinds(bool)] - #[kinds((Expr))] - assert_simple_bin_op_impls! {!BitAnd::bitand, !BitOr::bitor, !BitXor::bitxor} -} diff --git a/crates/fayalite/src/expr/target.rs b/crates/fayalite/src/expr/target.rs index 95d8e0f..c8c55e9 100644 --- a/crates/fayalite/src/expr/target.rs +++ b/crates/fayalite/src/expr/target.rs @@ -3,7 +3,7 @@ use crate::{ array::Array, bundle::{Bundle, BundleField}, - expr::{Expr, Flow, ToExpr, ValueType, value_category::ValueCategoryExpr}, + expr::{Expr, Flow, ToExpr}, intern::{Intern, Interned}, memory::{DynPortType, MemPort}, module::{Instance, ModuleIO, TargetName}, @@ -196,18 +196,9 @@ macro_rules! impl_target_base { } } - impl ValueType for $TargetBase { - type Type = CanonicalType; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - match self { - $(Self::$Variant(v) => v.ty().canonical(),)* - } - } - } - impl ToExpr for $TargetBase { + type Type = CanonicalType; + fn to_expr(&self) -> Expr { match self { $(Self::$Variant(v) => Expr::canonical(v.to_expr()),)* diff --git a/crates/fayalite/src/expr/value_category.rs b/crates/fayalite/src/expr/value_category.rs deleted file mode 100644 index 548ae7b..0000000 --- a/crates/fayalite/src/expr/value_category.rs +++ /dev/null @@ -1,378 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{expr::ValueType, ty::Type}; - -trait ValueCategorySealed {} - -#[expect(private_bounds)] -pub trait ValueCategory: - ValueCategorySealed - + Copy - + Ord - + Default - + std::fmt::Debug - + std::hash::Hash - + 'static - + Send - + Sync -{ - type DispatchOutput>: ValueType; - #[track_caller] - fn dispatch>( - dispatch: D, - ) -> Self::DispatchOutput; - #[track_caller] - fn dispatch_enum>( - dispatch: D, - ) -> ValueCategoryDispatchOutputEnum; -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Debug, Hash)] -pub struct ValueCategoryValue; - -impl ValueCategorySealed for ValueCategoryValue {} - -impl ValueCategory for ValueCategoryValue { - type DispatchOutput> = D::Value; - - #[track_caller] - fn dispatch>( - dispatch: D, - ) -> Self::DispatchOutput { - dispatch.dispatch_value() - } - - #[track_caller] - fn dispatch_enum>( - dispatch: D, - ) -> ValueCategoryDispatchOutputEnum { - ValueCategoryDispatchOutputEnum::Value(dispatch.dispatch_value()) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Debug, Hash)] -pub struct ValueCategorySimValue; - -impl ValueCategorySealed for ValueCategorySimValue {} - -impl ValueCategory for ValueCategorySimValue { - type DispatchOutput> = D::SimValue; - - #[track_caller] - fn dispatch>( - dispatch: D, - ) -> Self::DispatchOutput { - dispatch.dispatch_sim_value() - } - - #[track_caller] - fn dispatch_enum>( - dispatch: D, - ) -> ValueCategoryDispatchOutputEnum { - ValueCategoryDispatchOutputEnum::SimValue(dispatch.dispatch_sim_value()) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Debug, Hash)] -pub struct ValueCategoryExpr; - -impl ValueCategorySealed for ValueCategoryExpr {} - -impl ValueCategory for ValueCategoryExpr { - type DispatchOutput> = D::Expr; - - #[track_caller] - fn dispatch>( - dispatch: D, - ) -> Self::DispatchOutput { - dispatch.dispatch_expr() - } - - #[track_caller] - fn dispatch_enum>( - dispatch: D, - ) -> ValueCategoryDispatchOutputEnum { - ValueCategoryDispatchOutputEnum::Expr(dispatch.dispatch_expr()) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Debug, Hash)] -pub struct ValueCategoryValueless; - -impl ValueCategorySealed for ValueCategoryValueless {} - -impl ValueCategory for ValueCategoryValueless { - type DispatchOutput> = D::Valueless; - - #[track_caller] - fn dispatch>( - dispatch: D, - ) -> Self::DispatchOutput { - dispatch.dispatch_valueless() - } - - #[track_caller] - fn dispatch_enum>( - dispatch: D, - ) -> ValueCategoryDispatchOutputEnum { - ValueCategoryDispatchOutputEnum::Valueless(dispatch.dispatch_valueless()) - } -} - -pub trait ValueCategoryIsValue: ValueCategoryIsValueOrSimValue {} - -impl ValueCategoryIsValue for ValueCategoryValue {} - -pub trait ValueCategoryIsValueOrSimValue: ValueCategoryIsValueSimValueOrExpr {} - -impl ValueCategoryIsValueOrSimValue for ValueCategoryValue {} -impl ValueCategoryIsValueOrSimValue for ValueCategorySimValue {} - -pub trait ValueCategoryIsValueSimValueOrExpr: ValueCategoryIsValueSimValueExprOrValueless {} - -impl ValueCategoryIsValueSimValueOrExpr for ValueCategoryValue {} -impl ValueCategoryIsValueSimValueOrExpr for ValueCategorySimValue {} -impl ValueCategoryIsValueSimValueOrExpr for ValueCategoryExpr {} - -pub trait ValueCategoryIsValueSimValueExprOrValueless: ValueCategory {} - -impl ValueCategoryIsValueSimValueExprOrValueless for ValueCategoryValue {} -impl ValueCategoryIsValueSimValueExprOrValueless for ValueCategorySimValue {} -impl ValueCategoryIsValueSimValueExprOrValueless for ValueCategoryExpr {} -impl ValueCategoryIsValueSimValueExprOrValueless for ValueCategoryValueless {} - -pub trait ValueCategoryIsValueless: ValueCategoryIsExprOrValueless {} - -impl ValueCategoryIsValueless for ValueCategoryValueless {} - -pub trait ValueCategoryIsExprOrValueless: ValueCategoryIsValueSimValueExprOrValueless {} - -impl ValueCategoryIsExprOrValueless for ValueCategoryExpr {} -impl ValueCategoryIsExprOrValueless for ValueCategoryValueless {} - -pub trait ValueCategoryIsSimValueExprOrValueless: - ValueCategoryIsValueSimValueExprOrValueless -{ -} - -impl ValueCategoryIsSimValueExprOrValueless for ValueCategorySimValue {} -impl ValueCategoryIsSimValueExprOrValueless for ValueCategoryExpr {} -impl ValueCategoryIsSimValueExprOrValueless for ValueCategoryValueless {} - -trait ValueCategoryCommonSealed {} - -#[expect(private_bounds)] -pub trait ValueCategoryCommon< - T: ValueCategoryCommonSealed - + Copy - + Ord - + Default - + std::fmt::Debug - + std::hash::Hash - + 'static - + Send - + Sync, ->: ValueCategory -{ - type Common: ValueCategory; -} - -macro_rules! impl_value_category_common { - ($($T:ident),* $(,)?) => { - impl_value_category_common!([$($T,)*]); - }; - ([$($A:ident,)?]) => {}; - ([$FirstT:ident, $($T:ident,)+]) => { - impl_value_category_common!([$($T,)*]); - - impl<$FirstT: ValueCategory, $($T: ValueCategory),*> ValueCategoryCommonSealed for ($FirstT, $($T),*) {} - - impl ValueCategoryCommon<($FirstT, $($T),*)> for This - where - $FirstT: ValueCategory, - $($T: ValueCategory,)* - This: ValueCategoryCommon<($FirstT,), Common: ValueCategoryCommon<($($T,)*)>>, - { - type Common = <>::Common as ValueCategoryCommon<($($T,)*)>>::Common; - } - }; -} - -impl_value_category_common!(T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0); - -impl ValueCategoryCommonSealed for (T,) {} - -impl ValueCategoryCommonSealed for () {} - -impl ValueCategoryCommon<()> for T { - type Common = T; -} - -impl ValueCategoryCommon<(ValueCategoryValue,)> for T { - type Common = ValueCategoryValue; -} - -impl ValueCategoryCommon<(ValueCategorySimValue,)> for T { - type Common = ValueCategorySimValue; -} - -impl ValueCategoryCommon<(T,)> for ValueCategorySimValue { - type Common = ValueCategorySimValue; -} - -impl ValueCategoryCommon<(ValueCategoryExpr,)> for T { - type Common = ValueCategoryExpr; -} - -impl ValueCategoryCommon<(T,)> for ValueCategoryExpr { - type Common = ValueCategoryExpr; -} - -impl ValueCategoryCommon<(ValueCategoryValueless,)> - for T -{ - type Common = ValueCategoryValueless; -} - -impl ValueCategoryCommon<(T,)> for ValueCategoryValueless { - type Common = ValueCategoryValueless; -} - -pub trait ValueCategoryDispatch: Sized { - type Type: Type; - type InputValueCategory: ValueCategory; - type Value: ValueType; - type SimValue: ValueType; - type Expr: ValueType; - type Valueless: ValueType; - fn dispatch_value(self) -> Self::Value - where - Self: ValueCategoryDispatch; - fn dispatch_sim_value(self) -> Self::SimValue - where - Self: ValueCategoryDispatch; - fn dispatch_expr(self) -> Self::Expr - where - Self: ValueCategoryDispatch; - fn dispatch_valueless(self) -> Self::Valueless - where - Self: ValueCategoryDispatch; - fn dispatch(self) -> ::DispatchOutput { - Self::InputValueCategory::dispatch(self) - } - fn dispatch_enum(self) -> ValueCategoryDispatchOutputEnum { - Self::InputValueCategory::dispatch_enum(self) - } -} - -pub enum ValueCategoryDispatchOutputEnum { - Value(T::Value), - SimValue(T::SimValue), - Expr(T::Expr), - Valueless(T::Valueless), -} - -impl ValueCategoryDispatchOutputEnum { - pub fn try_into_value(self) -> Result { - if let Self::Value(v) = self { - Ok(v) - } else { - Err(self) - } - } - pub fn try_into_sim_value(self) -> Result { - if let Self::SimValue(v) = self { - Ok(v) - } else { - Err(self) - } - } - pub fn try_into_expr(self) -> Result { - if let Self::Expr(v) = self { - Ok(v) - } else { - Err(self) - } - } - pub fn try_into_valueless(self) -> Result { - if let Self::Valueless(v) = self { - Ok(v) - } else { - Err(self) - } - } - #[track_caller] - #[cold] - fn unwrap_invalid(self, expected_kind: &'static str) -> ! { - match self { - Self::Value(_) => panic!("expected {expected_kind}, got Value"), - Self::SimValue(_) => panic!("expected {expected_kind}, got SimValue"), - Self::Expr(_) => panic!("expected {expected_kind}, got Expr"), - Self::Valueless(_) => panic!("expected {expected_kind}, got Valueless"), - } - } - #[track_caller] - pub fn into_value_unwrap(self) -> T::Value { - let Self::Value(v) = self else { - self.unwrap_invalid("Value"); - }; - v - } - #[track_caller] - pub fn into_sim_value_unwrap(self) -> T::SimValue { - let Self::SimValue(v) = self else { - self.unwrap_invalid("SimValue"); - }; - v - } - #[track_caller] - pub fn into_expr_unwrap(self) -> T::Expr { - let Self::Expr(v) = self else { - self.unwrap_invalid("Expr"); - }; - v - } - #[track_caller] - pub fn into_valueless_unwrap(self) -> T::Valueless { - let Self::Valueless(v) = self else { - self.unwrap_invalid("Valueless"); - }; - v - } - pub fn ty(&self) -> T::Type { - match self { - Self::Value(v) => v.ty(), - Self::SimValue(v) => v.ty(), - Self::Expr(v) => v.ty(), - Self::Valueless(v) => v.ty(), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - type Identity = T; - - macro_rules! check_categories { - ($($Categories:ident,)+) => { - check_categories!([] [$($Categories,)+]); - }; - ([$($Categories:ident,)*] []) => {}; - ([$($WeakerCategories:ident,)*] [$Category:ident, $($StrongerCategories:ident,)*]) => { - $(const _: $Category = Identity::<<$WeakerCategories as ValueCategoryCommon<($Category,)>>::Common> {}; - const _: $Category = Identity::<<$Category as ValueCategoryCommon<($WeakerCategories,)>>::Common> {};)* - const _: $Category = Identity::<<$Category as ValueCategoryCommon<($Category,)>>::Common> {}; - check_categories!([$($WeakerCategories,)* $Category,] [$($StrongerCategories,)*]); - }; - } - - check_categories!( - ValueCategoryValue, - ValueCategorySimValue, - ValueCategoryExpr, - ValueCategoryValueless, - ); -} diff --git a/crates/fayalite/src/firrtl.rs b/crates/fayalite/src/firrtl.rs index 383bd95..b4a1d14 100644 --- a/crates/fayalite/src/firrtl.rs +++ b/crates/fayalite/src/firrtl.rs @@ -4,15 +4,14 @@ use crate::{ annotations::{ Annotation, BlackBoxInlineAnnotation, BlackBoxPathAnnotation, CustomFirrtlAnnotation, - DocStringAnnotation, DontTouchAnnotation, SVAttributeAnnotation, TargetedAnnotation, + DocStringAnnotation, DontTouchAnnotation, SVAttributeAnnotation, }, array::Array, - build::{ToArgs, WriteArgs}, bundle::{Bundle, BundleField, BundleType}, clock::Clock, enum_::{Enum, EnumType, EnumVariant}, expr::{ - CastBitsTo, Expr, ExprEnum, ToExpr, ValueType, + CastBitsTo, Expr, ExprEnum, ops::{self, VariantAccess}, target::{ Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, @@ -24,9 +23,9 @@ use crate::{ memory::{Mem, PortKind, PortName, ReadUnderWrite}, module::{ AnnotatedModuleIO, Block, ExternModuleBody, ExternModuleParameter, - ExternModuleParameterValue, Module, ModuleBody, ModuleIO, NameId, NameOptId, - NormalModuleBody, Stmt, StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, - StmtMatch, StmtReg, StmtWire, + ExternModuleParameterValue, Module, ModuleBody, NameOptId, NormalModuleBody, Stmt, + StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, StmtMatch, StmtReg, + StmtWire, transform::{ simplify_enums::{SimplifyEnumsError, SimplifyEnumsKind, simplify_enums}, simplify_memories::simplify_memories, @@ -39,23 +38,21 @@ use crate::{ BitSliceWriteWithBase, DebugAsRawString, GenericConstBool, HashMap, HashSet, const_str_array_is_strictly_ascending, }, - vendor::xilinx::XilinxAnnotation, }; use bitvec::slice::BitSlice; use clap::value_parser; use num_traits::Signed; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::{ cell::{Cell, RefCell}, cmp::Ordering, collections::{BTreeMap, VecDeque}, error::Error, - ffi::OsString, fmt::{self, Write}, fs, hash::Hash, io, - ops::{ControlFlow, Range}, + ops::Range, path::{Path, PathBuf}, rc::Rc, }; @@ -407,10 +404,10 @@ impl TypeState { self.next_type_name.set(id + 1); Ident(Intern::intern_owned(format!("Ty{id}"))) } - fn get_bundle_field(&mut self, ty: Bundle, name: Interned) -> Result { + fn get_bundle_field(&mut self, ty: Bundle, name: Interned) -> Result { Ok(self.bundle_ns(ty)?.borrow_mut().get(name)) } - fn bundle_def(&self, ty: Bundle) -> Result<(Ident, Rc>), FirrtlError> { + fn bundle_def(&self, ty: Bundle) -> Result<(Ident, Rc>)> { self.bundle_defs.get_or_make(ty, |&ty, definitions| { let mut ns = Namespace::default(); let mut body = String::new(); @@ -431,13 +428,13 @@ impl TypeState { Ok((name, Rc::new(RefCell::new(ns)))) }) } - fn bundle_ty(&self, ty: Bundle) -> Result { + fn bundle_ty(&self, ty: Bundle) -> Result { Ok(self.bundle_def(ty)?.0) } - fn bundle_ns(&self, ty: Bundle) -> Result>, FirrtlError> { + fn bundle_ns(&self, ty: Bundle) -> Result>> { Ok(self.bundle_def(ty)?.1) } - fn enum_def(&self, ty: Enum) -> Result<(Ident, Rc), FirrtlError> { + fn enum_def(&self, ty: Enum) -> Result<(Ident, Rc)> { self.enum_defs.get_or_make(ty, |&ty, definitions| { let mut variants = Namespace::default(); let mut body = String::new(); @@ -464,13 +461,13 @@ impl TypeState { )) }) } - fn enum_ty(&self, ty: Enum) -> Result { + fn enum_ty(&self, ty: Enum) -> Result { Ok(self.enum_def(ty)?.0) } - fn get_enum_variant(&mut self, ty: Enum, name: Interned) -> Result { + fn get_enum_variant(&mut self, ty: Enum, name: Interned) -> Result { Ok(self.enum_def(ty)?.1.variants.borrow_mut().get(name)) } - fn ty(&self, ty: T) -> Result { + fn ty(&self, ty: T) -> Result { Ok(match ty.canonical() { CanonicalType::Bundle(ty) => self.bundle_ty(ty)?.to_string(), CanonicalType::Enum(ty) => self.enum_ty(ty)?.to_string(), @@ -488,7 +485,7 @@ impl TypeState { CanonicalType::Reset(Reset {}) => "Reset".into(), CanonicalType::PhantomConst(_) => "{}".into(), CanonicalType::DynSimOnly(_) => { - return Err(FirrtlError::SimOnlyValuesAreNotPermitted); + return Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()); } }) } @@ -877,7 +874,7 @@ impl<'a> Exporter<'a> { definitions: &RcDefinitions, const_ty: bool, ) -> Result { - let from_ty = value.ty(); + let from_ty = Expr::ty(value); let mut value = self.expr(Expr::canonical(value), definitions, const_ty)?; if from_ty.width().checked_add(1) == Some(to_ty.width()) && !FromTy::Signed::VALUE @@ -926,7 +923,7 @@ impl<'a> Exporter<'a> { definitions: &RcDefinitions, const_ty: bool, ) -> Result { - let base_width = base.ty().width(); + let base_width = Expr::ty(base).width(); let base = self.expr(Expr::canonical(base), definitions, const_ty)?; if range.is_empty() { Ok(format!("tail({base}, {base_width})")) @@ -1209,7 +1206,9 @@ impl<'a> Exporter<'a> { | CanonicalType::AsyncReset(_) | CanonicalType::Reset(_) => Ok(format!("asUInt({value_str})")), CanonicalType::PhantomConst(_) => Ok("UInt<0>(0)".into()), - CanonicalType::DynSimOnly(_) => Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()), + CanonicalType::DynSimOnly(_) => { + Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()) + } } } fn expr_cast_bits_to_bundle( @@ -1430,7 +1429,9 @@ impl<'a> Exporter<'a> { definitions.add_definition_line(format_args!("{extra_indent}invalidate {retval}")); return Ok(retval.to_string()); } - CanonicalType::DynSimOnly(_) => Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()), + CanonicalType::DynSimOnly(_) => { + Err(FirrtlError::SimOnlyValuesAreNotPermitted.into()) + } } } fn expr_unary( @@ -1470,7 +1471,7 @@ impl<'a> Exporter<'a> { ExprEnum::SIntLiteral(literal) => Ok(self.sint_literal(&literal)), ExprEnum::BoolLiteral(literal) => Ok(self.bool_literal(literal)), ExprEnum::PhantomConst(ty) => self.expr( - UInt[0].zero().to_expr().cast_bits_to(ty.canonical()), + UInt[0].zero().cast_bits_to(ty.canonical()), definitions, const_ty, ), @@ -1653,7 +1654,7 @@ impl<'a> Exporter<'a> { let value_str = self.expr(expr.arg(), definitions, const_ty)?; self.expr_cast_to_bits( value_str, - expr.arg().ty(), + Expr::ty(expr.arg()), definitions, Indent { indent_depth: &Cell::new(0), @@ -1776,7 +1777,7 @@ impl<'a> Exporter<'a> { let mut out = self.expr(Expr::canonical(expr.base()), definitions, const_ty)?; let name = self .type_state - .get_bundle_field(expr.base().ty(), expr.field_name())?; + .get_bundle_field(Expr::ty(expr.base()), expr.field_name())?; write!(out, ".{name}").unwrap(); Ok(out) } @@ -1883,11 +1884,7 @@ impl<'a> Exporter<'a> { } fn annotation(&mut self, path: AnnotationTargetPath, annotation: &Annotation) { let data = match annotation { - Annotation::DontTouch(DontTouchAnnotation {}) => { - // TODO: error if the annotated thing was renamed because of a naming conflict, - // unless Target::base() is one of the ports of the top-level module since that's handled by ScalarizedModuleABI - AnnotationData::DontTouch - } + Annotation::DontTouch(DontTouchAnnotation {}) => AnnotationData::DontTouch, Annotation::SVAttribute(SVAttributeAnnotation { text }) => { AnnotationData::AttributeAnnotation { description: *text } } @@ -1910,9 +1907,6 @@ impl<'a> Exporter<'a> { class: str::to_string(class), additional_fields: (*additional_fields).into(), }, - Annotation::Xilinx(XilinxAnnotation::XdcLocation(_)) - | Annotation::Xilinx(XilinxAnnotation::XdcIOStandard(_)) - | Annotation::Xilinx(XilinxAnnotation::XdcCreateClock(_)) => return, }; self.annotations.push(FirrtlAnnotation { data, @@ -2101,12 +2095,12 @@ impl<'a> Exporter<'a> { rhs, source_location, }) => { - if lhs.ty() != rhs.ty() { + if Expr::ty(lhs) != Expr::ty(rhs) { writeln!( body, "{indent}; connect different types:\n{indent}; lhs: {:?}\n{indent}; rhs: {:?}", - lhs.ty(), - rhs.ty(), + Expr::ty(lhs), + Expr::ty(rhs), ) .unwrap(); } @@ -2200,7 +2194,7 @@ impl<'a> Exporter<'a> { FileInfo::new(source_location), ) .unwrap(); - let enum_ty = expr.ty(); + let enum_ty = Expr::ty(expr); let match_arms_indent = indent.push(); for ((variant_index, variant), match_arm_block) in enum_ty.variants().iter().enumerate().zip(blocks) @@ -2326,7 +2320,6 @@ impl<'a> Exporter<'a> { ModuleBody::Extern(ExternModuleBody { verilog_name, parameters, - clocks_for_past: _, simulation: _, }) => { let verilog_name = Ident(verilog_name); @@ -2461,7 +2454,7 @@ impl FileBackendTrait for &'_ mut T { pub struct FileBackend { pub dir_path: PathBuf, pub circuit_name: Option, - pub top_fir_file_stem: Option, + pub top_fir_file_stem: Option, } impl FileBackend { @@ -2510,7 +2503,7 @@ impl FileBackendTrait for FileBackend { ) -> Result<(), Self::Error> { let top_fir_file_stem = self .top_fir_file_stem - .get_or_insert_with(|| circuit_name.clone().into()); + .get_or_insert_with(|| circuit_name.clone()); self.circuit_name = Some(circuit_name); let mut path = self.dir_path.join(top_fir_file_stem); if let Some(parent) = path.parent().filter(|v| !v.as_os_str().is_empty()) { @@ -2684,12 +2677,21 @@ impl FileBackendTrait for TestBackend { fn export_impl( file_backend: &mut dyn WrappedFileBackendTrait, - top_module: Interned>, + mut top_module: Interned>, options: ExportOptions, ) -> Result<(), WrappedError> { - let top_module = options - .prepare_top_module(top_module) - .map_err(|e| file_backend.simplify_enums_error(e))?; + let ExportOptions { + simplify_memories: do_simplify_memories, + simplify_enums: do_simplify_enums, + __private: _, + } = options; + if let Some(kind) = do_simplify_enums { + top_module = + simplify_enums(top_module, kind).map_err(|e| file_backend.simplify_enums_error(e))?; + } + if do_simplify_memories { + top_module = simplify_memories(top_module); + } let indent_depth = Cell::new(0); let mut global_ns = Namespace::default(); let circuit_name = global_ns.get(top_module.name_id()); @@ -2751,23 +2753,14 @@ impl clap::builder::TypedValueParser for OptionSimplifyEnumsKindValueParser { #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct ExportOptionsPrivate(()); -impl ExportOptionsPrivate { - fn private_new() -> Self { - Self(()) - } -} - -#[derive(clap::Parser, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(clap::Parser, Copy, Clone, PartialEq, Eq, Hash)] pub struct ExportOptions { #[clap(long = "no-simplify-memories", action = clap::ArgAction::SetFalse)] - #[serde(default = "ExportOptions::default_simplify_memories")] pub simplify_memories: bool, #[clap(long, value_parser = OptionSimplifyEnumsKindValueParser, default_value = "replace-with-bundle-of-uints")] - #[serde(default = "ExportOptions::default_simplify_enums")] - pub simplify_enums: std::option::Option, // use std::option::Option instead of Option to avoid clap mis-parsing + pub simplify_enums: std::option::Option, #[doc(hidden)] #[clap(skip = ExportOptionsPrivate(()))] - #[serde(skip, default = "ExportOptionsPrivate::private_new")] /// `#[non_exhaustive]` except allowing struct update syntax pub __private: ExportOptionsPrivate, } @@ -2778,34 +2771,7 @@ impl fmt::Debug for ExportOptions { } } -impl ToArgs for ExportOptions { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { - simplify_memories, - simplify_enums, - __private: ExportOptionsPrivate(()), - } = *self; - if !simplify_memories { - args.write_arg("--no-simplify-memories"); - } - let simplify_enums = simplify_enums.map(|v| { - clap::ValueEnum::to_possible_value(&v).expect("there are no skipped variants") - }); - let simplify_enums = match &simplify_enums { - None => OptionSimplifyEnumsKindValueParser::NONE_NAME, - Some(v) => v.get_name(), - }; - args.write_long_option_eq("simplify-enums", simplify_enums); - } -} - impl ExportOptions { - fn default_simplify_memories() -> bool { - true - } - fn default_simplify_enums() -> Option { - Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts) - } fn debug_fmt( &self, f: &mut fmt::Formatter<'_>, @@ -2857,47 +2823,18 @@ impl ExportOptions { if f.alternate() { "\n}" } else { " }" } ) } - fn prepare_top_module_helper( - self, - mut top_module: Interned>, - ) -> Result>, SimplifyEnumsError> { - let Self { - simplify_memories: do_simplify_memories, - simplify_enums: do_simplify_enums, - __private: _, - } = self; - if let Some(kind) = do_simplify_enums { - top_module = simplify_enums(top_module, kind)?; - } - if do_simplify_memories { - top_module = simplify_memories(top_module); - } - Ok(top_module) - } - pub fn prepare_top_module( - self, - top_module: impl AsRef>, - ) -> Result>, SimplifyEnumsError> { - self.prepare_top_module_helper(top_module.as_ref().canonical().intern()) - } } impl Default for ExportOptions { fn default() -> Self { Self { - simplify_memories: Self::default_simplify_memories(), - simplify_enums: Self::default_simplify_enums(), + simplify_memories: true, + simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts), __private: ExportOptionsPrivate(()), } } } -pub fn get_circuit_name(top_module_name_id: NameId) -> Interned { - let mut global_ns = Namespace::default(); - let circuit_name = global_ns.get(top_module_name_id); - circuit_name.0 -} - pub fn export( file_backend: B, top_module: &Module, @@ -2909,497 +2846,6 @@ pub fn export( }) } -#[derive(Debug)] -#[non_exhaustive] -pub enum ScalarizedModuleABIError { - SimOnlyValuesAreNotPermitted, - SimplifyEnumsError(SimplifyEnumsError), -} - -impl fmt::Display for ScalarizedModuleABIError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - ScalarizedModuleABIError::SimOnlyValuesAreNotPermitted => { - FirrtlError::SimOnlyValuesAreNotPermitted.fmt(f) - } - ScalarizedModuleABIError::SimplifyEnumsError(e) => e.fmt(f), - } - } -} - -impl std::error::Error for ScalarizedModuleABIError {} - -impl From for ScalarizedModuleABIError { - fn from(value: SimplifyEnumsError) -> Self { - Self::SimplifyEnumsError(value) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub enum ScalarizedModuleABIPortItem { - Group(ScalarizedModuleABIPortGroup), - Port(ScalarizedModuleABIPort), -} - -impl ScalarizedModuleABIPortItem { - pub fn module_io(self) -> ModuleIO { - *self - .target() - .base() - .module_io() - .expect("known to be ModuleIO") - } - pub fn target(self) -> Interned { - match self { - Self::Group(v) => v.target(), - Self::Port(v) => v.target(), - } - } - fn for_each_port_and_annotations_helper< - F: for<'a> FnMut( - &'a ScalarizedModuleABIPort, - ScalarizedModuleABIAnnotations<'a>, - ) -> ControlFlow, - B, - >( - &self, - parent: Option<&ScalarizedModuleABIAnnotations<'_>>, - f: &mut F, - ) -> ControlFlow { - match self { - Self::Group(v) => v.for_each_port_and_annotations_helper(parent, f), - Self::Port(port) => f( - port, - ScalarizedModuleABIAnnotations::new(parent, port.annotations.iter()), - ), - } - } - pub fn for_each_port_and_annotations< - F: for<'a> FnMut( - &'a ScalarizedModuleABIPort, - ScalarizedModuleABIAnnotations<'a>, - ) -> ControlFlow, - B, - >( - self, - mut f: F, - ) -> ControlFlow { - self.for_each_port_and_annotations_helper(None, &mut f) - } -} - -impl fmt::Debug for ScalarizedModuleABIPortItem { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Group(v) => v.fmt(f), - Self::Port(v) => v.fmt(f), - } - } -} - -#[derive(Debug, Clone)] -pub struct ScalarizedModuleABIAnnotations<'a> { - parent: Option<&'a ScalarizedModuleABIAnnotations<'a>>, - parent_len: usize, - annotations: std::slice::Iter<'a, TargetedAnnotation>, -} - -impl<'a> ScalarizedModuleABIAnnotations<'a> { - fn new( - parent: Option<&'a ScalarizedModuleABIAnnotations<'a>>, - annotations: std::slice::Iter<'a, TargetedAnnotation>, - ) -> Self { - Self { - parent, - parent_len: parent.map_or(0, |parent| parent.len()), - annotations, - } - } -} - -impl<'a> Default for ScalarizedModuleABIAnnotations<'a> { - fn default() -> Self { - Self { - parent: None, - parent_len: 0, - annotations: Default::default(), - } - } -} - -impl<'a> Iterator for ScalarizedModuleABIAnnotations<'a> { - type Item = &'a TargetedAnnotation; - - fn next(&mut self) -> Option { - loop { - if let retval @ Some(_) = self.annotations.next() { - break retval; - } - *self = self.parent?.clone(); - } - } - - fn size_hint(&self) -> (usize, Option) { - let len = self.len(); - (len, Some(len)) - } - - fn fold(mut self, mut init: B, mut f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - loop { - let Self { - parent, - parent_len: _, - annotations, - } = self; - init = annotations.fold(init, &mut f); - let Some(next) = parent else { - break; - }; - self = next.clone(); - } - init - } -} - -impl std::iter::FusedIterator for ScalarizedModuleABIAnnotations<'_> {} - -impl ExactSizeIterator for ScalarizedModuleABIAnnotations<'_> { - fn len(&self) -> usize { - self.parent_len + self.annotations.len() - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ScalarizedModuleABIPortGroup { - target: Interned, - common_annotations: Interned<[TargetedAnnotation]>, - children: Interned<[ScalarizedModuleABIPortItem]>, -} - -impl ScalarizedModuleABIPortGroup { - pub fn module_io(self) -> ModuleIO { - *self - .target - .base() - .module_io() - .expect("known to be ModuleIO") - } - pub fn target(self) -> Interned { - self.target - } - pub fn common_annotations(self) -> Interned<[TargetedAnnotation]> { - self.common_annotations - } - pub fn children(self) -> Interned<[ScalarizedModuleABIPortItem]> { - self.children - } - fn for_each_port_and_annotations_helper< - F: for<'a> FnMut( - &'a ScalarizedModuleABIPort, - ScalarizedModuleABIAnnotations<'a>, - ) -> ControlFlow, - B, - >( - &self, - parent: Option<&ScalarizedModuleABIAnnotations<'_>>, - f: &mut F, - ) -> ControlFlow { - let parent = ScalarizedModuleABIAnnotations::new(parent, self.common_annotations.iter()); - for item in &self.children { - item.for_each_port_and_annotations_helper(Some(&parent), f)?; - } - ControlFlow::Continue(()) - } - pub fn for_each_port_and_annotations< - F: for<'a> FnMut( - &'a ScalarizedModuleABIPort, - ScalarizedModuleABIAnnotations<'a>, - ) -> ControlFlow, - B, - >( - self, - mut f: F, - ) -> ControlFlow { - self.for_each_port_and_annotations_helper(None, &mut f) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ScalarizedModuleABIPort { - target: Interned, - annotations: Interned<[TargetedAnnotation]>, - scalarized_name: Interned, -} - -impl ScalarizedModuleABIPort { - pub fn module_io(self) -> ModuleIO { - *self - .target - .base() - .module_io() - .expect("known to be ModuleIO") - } - pub fn target(self) -> Interned { - self.target - } - pub fn annotations(self) -> Interned<[TargetedAnnotation]> { - self.annotations - } - pub fn scalarized_name(self) -> Interned { - self.scalarized_name - } -} - -enum ScalarizeTreeNodeBody { - Leaf { - scalarized_name: Interned, - }, - Bundle { - ty: Bundle, - fields: Vec, - }, - Array { - elements: Vec, - }, -} - -struct ScalarizeTreeNode { - target: Interned, - annotations: Vec, - body: ScalarizeTreeNodeBody, -} - -impl ScalarizeTreeNode { - #[track_caller] - fn find_target(&mut self, annotation_target: Interned) -> &mut Self { - match *annotation_target { - Target::Base(_) => { - assert_eq!( - annotation_target, self.target, - "annotation not on correct ModuleIO", - ); - self - } - Target::Child(target_child) => { - let parent = self.find_target(target_child.parent()); - match *target_child.path_element() { - TargetPathElement::BundleField(TargetPathBundleField { name }) => { - match parent.body { - ScalarizeTreeNodeBody::Leaf { .. } => parent, - ScalarizeTreeNodeBody::Bundle { ty, ref mut fields } => { - &mut fields[ty.name_indexes()[&name]] - } - ScalarizeTreeNodeBody::Array { .. } => { - unreachable!("types are known to match") - } - } - } - TargetPathElement::ArrayElement(TargetPathArrayElement { index }) => { - match parent.body { - ScalarizeTreeNodeBody::Leaf { .. } => parent, - ScalarizeTreeNodeBody::Bundle { .. } => { - unreachable!("types are known to match") - } - ScalarizeTreeNodeBody::Array { ref mut elements } => { - &mut elements[index] - } - } - } - TargetPathElement::DynArrayElement(_) => { - unreachable!("annotations are only on static targets"); - } - } - } - } - } - fn into_scalarized_item(self) -> ScalarizedModuleABIPortItem { - let Self { - target, - annotations, - body, - } = self; - match body { - ScalarizeTreeNodeBody::Leaf { scalarized_name } => { - ScalarizedModuleABIPortItem::Port(ScalarizedModuleABIPort { - target, - annotations: Intern::intern_owned(annotations), - scalarized_name, - }) - } - ScalarizeTreeNodeBody::Bundle { fields: items, .. } - | ScalarizeTreeNodeBody::Array { elements: items } => { - ScalarizedModuleABIPortItem::Group(ScalarizedModuleABIPortGroup { - target, - common_annotations: Intern::intern_owned(annotations), - children: Interned::from_iter( - items.into_iter().map(Self::into_scalarized_item), - ), - }) - } - } - } -} - -#[derive(Default)] -struct ScalarizeTreeBuilder { - scalarized_ns: Namespace, - type_state: TypeState, - name: String, -} - -impl ScalarizeTreeBuilder { - #[track_caller] - fn build_bundle( - &mut self, - target: Interned, - ty: Bundle, - ) -> Result { - let mut fields = Vec::with_capacity(ty.fields().len()); - let original_len = self.name.len(); - for BundleField { name, .. } in ty.fields() { - let firrtl_name = self - .type_state - .get_bundle_field(ty, name) - .map_err(|e| match e { - FirrtlError::SimOnlyValuesAreNotPermitted => { - ScalarizedModuleABIError::SimOnlyValuesAreNotPermitted - } - })? - .0; - write!(self.name, "_{firrtl_name}").expect("writing to String is infallible"); - fields.push( - self.build( - target - .join(TargetPathElement::intern_sized( - TargetPathBundleField { name }.into(), - )) - .intern_sized(), - )?, - ); - self.name.truncate(original_len); - } - Ok(ScalarizeTreeNode { - target, - annotations: Vec::new(), - body: ScalarizeTreeNodeBody::Bundle { ty, fields }, - }) - } - #[track_caller] - fn build( - &mut self, - target: Interned, - ) -> Result { - Ok(match target.canonical_ty() { - CanonicalType::UInt(_) - | CanonicalType::SInt(_) - | CanonicalType::Bool(_) - | CanonicalType::Enum(_) - | CanonicalType::AsyncReset(_) - | CanonicalType::SyncReset(_) - | CanonicalType::Reset(_) - | CanonicalType::Clock(_) => { - let scalarized_name = self.scalarized_ns.get(str::intern(&self.name)).0; - ScalarizeTreeNode { - target, - annotations: Vec::new(), - body: ScalarizeTreeNodeBody::Leaf { scalarized_name }, - } - } - CanonicalType::Array(ty) => { - let mut elements = Vec::with_capacity(ty.len()); - let original_len = self.name.len(); - for index in 0..ty.len() { - write!(self.name, "_{index}").expect("writing to String is infallible"); - elements.push( - self.build( - target - .join(TargetPathElement::intern_sized( - TargetPathArrayElement { index }.into(), - )) - .intern_sized(), - )?, - ); - self.name.truncate(original_len); - } - ScalarizeTreeNode { - target, - annotations: Vec::new(), - body: ScalarizeTreeNodeBody::Array { elements }, - } - } - CanonicalType::Bundle(ty) => self.build_bundle(target, ty)?, - CanonicalType::PhantomConst(_) => { - self.build_bundle(target, Bundle::new(Interned::default()))? - } - CanonicalType::DynSimOnly(_) => { - return Err(ScalarizedModuleABIError::SimOnlyValuesAreNotPermitted); - } - }) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ScalarizedModuleABI { - module_io: Interned<[AnnotatedModuleIO]>, - items: Interned<[ScalarizedModuleABIPortItem]>, -} - -impl ScalarizedModuleABI { - #[track_caller] - fn from_io(module_io: Interned<[AnnotatedModuleIO]>) -> Result { - let mut firrtl_ns = Namespace::default(); - let mut tree_builder = ScalarizeTreeBuilder::default(); - let mut items = Vec::new(); - for module_io in module_io { - let firrtl_name = firrtl_ns.get(module_io.module_io.name_id()); - tree_builder.name.clear(); - tree_builder.name.push_str(&firrtl_name.0); - let mut tree = tree_builder.build(Target::from(module_io.module_io).intern_sized())?; - for annotation in module_io.annotations { - tree.find_target(annotation.target()) - .annotations - .push(annotation); - } - items.push(tree.into_scalarized_item()); - } - Ok(Self { - module_io, - items: Intern::intern_owned(items), - }) - } - #[track_caller] - pub fn new( - module: impl AsRef>, - options: ExportOptions, - ) -> Result { - Self::from_io(options.prepare_top_module(module)?.module_io()) - } - pub fn module_io(&self) -> Interned<[AnnotatedModuleIO]> { - self.module_io - } - pub fn items(&self) -> Interned<[ScalarizedModuleABIPortItem]> { - self.items - } - pub fn for_each_port_and_annotations< - F: for<'a> FnMut( - &'a ScalarizedModuleABIPort, - ScalarizedModuleABIAnnotations<'a>, - ) -> ControlFlow, - B, - >( - self, - mut f: F, - ) -> ControlFlow { - for item in &self.items { - item.for_each_port_and_annotations_helper(None, &mut f)?; - } - ControlFlow::Continue(()) - } -} - #[doc(hidden)] #[track_caller] pub fn assert_export_firrtl_impl(top_module: &Module, expected: TestBackend) { diff --git a/crates/fayalite/src/int.rs b/crates/fayalite/src/int.rs index 2d1f6d2..7fa77ce 100644 --- a/crates/fayalite/src/int.rs +++ b/crates/fayalite/src/int.rs @@ -4,19 +4,16 @@ use crate::{ array::ArrayType, expr::{ - Expr, NotALiteralExpr, ToExpr, ToLiteralBits, ToSimValueInner, ToValueless, ValueType, - Valueless, + Expr, NotALiteralExpr, ToExpr, ToLiteralBits, target::{GetTarget, Target}, - value_category::ValueCategoryValue, }, hdl, intern::{Intern, Interned, Memoize}, sim::value::{SimValue, ToSimValueWithType}, source_location::SourceLocation, ty::{ - CanonicalType, FillInDefaultedGenerics, OpaqueSimValueSize, OpaqueSimValueSlice, - OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type, TypeProperties, - impl_match_variant_as_self, + CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter, + OpaqueSimValueWritten, StaticType, Type, TypeProperties, impl_match_variant_as_self, }, util::{ConstBool, ConstUsize, GenericConstBool, GenericConstUsize, interned_bit, slice_range}, }; @@ -34,7 +31,7 @@ use std::{ num::NonZero, ops::{Index, Not, Range, RangeBounds, RangeInclusive}, str::FromStr, - sync::{Arc, OnceLock}, + sync::Arc, }; mod uint_in_range; @@ -63,62 +60,8 @@ mod sealed { pub const DYN_SIZE: usize = !0; pub type DynSize = ConstUsize; -trait KnownSizeBaseSealed {} - -impl KnownSizeBaseSealed for [(); N] {} - -#[expect(private_bounds)] -pub trait KnownSizeBase: KnownSizeBaseSealed {} - -macro_rules! impl_known_size_base { - ($($size:literal),* $(,)?) => { - $(impl KnownSizeBase for [(); $size] {})* - }; -} - -#[rustfmt::skip] -impl_known_size_base! { - 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00A, 0x00B, 0x00C, 0x00D, 0x00E, 0x00F, - 0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x019, 0x01A, 0x01B, 0x01C, 0x01D, 0x01E, 0x01F, - 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027, 0x028, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x02E, 0x02F, - 0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, 0x03F, - 0x040, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, 0x047, 0x048, 0x049, 0x04A, 0x04B, 0x04C, 0x04D, 0x04E, 0x04F, - 0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057, 0x058, 0x059, 0x05A, 0x05B, 0x05C, 0x05D, 0x05E, 0x05F, - 0x060, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06A, 0x06B, 0x06C, 0x06D, 0x06E, 0x06F, - 0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x077, 0x078, 0x079, 0x07A, 0x07B, 0x07C, 0x07D, 0x07E, 0x07F, - 0x080, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089, 0x08A, 0x08B, 0x08C, 0x08D, 0x08E, 0x08F, - 0x090, 0x091, 0x092, 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09A, 0x09B, 0x09C, 0x09D, 0x09E, 0x09F, - 0x0A0, 0x0A1, 0x0A2, 0x0A3, 0x0A4, 0x0A5, 0x0A6, 0x0A7, 0x0A8, 0x0A9, 0x0AA, 0x0AB, 0x0AC, 0x0AD, 0x0AE, 0x0AF, - 0x0B0, 0x0B1, 0x0B2, 0x0B3, 0x0B4, 0x0B5, 0x0B6, 0x0B7, 0x0B8, 0x0B9, 0x0BA, 0x0BB, 0x0BC, 0x0BD, 0x0BE, 0x0BF, - 0x0C0, 0x0C1, 0x0C2, 0x0C3, 0x0C4, 0x0C5, 0x0C6, 0x0C7, 0x0C8, 0x0C9, 0x0CA, 0x0CB, 0x0CC, 0x0CD, 0x0CE, 0x0CF, - 0x0D0, 0x0D1, 0x0D2, 0x0D3, 0x0D4, 0x0D5, 0x0D6, 0x0D7, 0x0D8, 0x0D9, 0x0DA, 0x0DB, 0x0DC, 0x0DD, 0x0DE, 0x0DF, - 0x0E0, 0x0E1, 0x0E2, 0x0E3, 0x0E4, 0x0E5, 0x0E6, 0x0E7, 0x0E8, 0x0E9, 0x0EA, 0x0EB, 0x0EC, 0x0ED, 0x0EE, 0x0EF, - 0x0F0, 0x0F1, 0x0F2, 0x0F3, 0x0F4, 0x0F5, 0x0F6, 0x0F7, 0x0F8, 0x0F9, 0x0FA, 0x0FB, 0x0FC, 0x0FD, 0x0FE, 0x0FF, - 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10A, 0x10B, 0x10C, 0x10D, 0x10E, 0x10F, - 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 0x119, 0x11A, 0x11B, 0x11C, 0x11D, 0x11E, 0x11F, - 0x120, 0x121, 0x122, 0x123, 0x124, 0x125, 0x126, 0x127, 0x128, 0x129, 0x12A, 0x12B, 0x12C, 0x12D, 0x12E, 0x12F, - 0x130, 0x131, 0x132, 0x133, 0x134, 0x135, 0x136, 0x137, 0x138, 0x139, 0x13A, 0x13B, 0x13C, 0x13D, 0x13E, 0x13F, - 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, 0x148, 0x149, 0x14A, 0x14B, 0x14C, 0x14D, 0x14E, 0x14F, - 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, 0x158, 0x159, 0x15A, 0x15B, 0x15C, 0x15D, 0x15E, 0x15F, - 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167, 0x168, 0x169, 0x16A, 0x16B, 0x16C, 0x16D, 0x16E, 0x16F, - 0x170, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0x177, 0x178, 0x179, 0x17A, 0x17B, 0x17C, 0x17D, 0x17E, 0x17F, - 0x180, 0x181, 0x182, 0x183, 0x184, 0x185, 0x186, 0x187, 0x188, 0x189, 0x18A, 0x18B, 0x18C, 0x18D, 0x18E, 0x18F, - 0x190, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, 0x199, 0x19A, 0x19B, 0x19C, 0x19D, 0x19E, 0x19F, - 0x1A0, 0x1A1, 0x1A2, 0x1A3, 0x1A4, 0x1A5, 0x1A6, 0x1A7, 0x1A8, 0x1A9, 0x1AA, 0x1AB, 0x1AC, 0x1AD, 0x1AE, 0x1AF, - 0x1B0, 0x1B1, 0x1B2, 0x1B3, 0x1B4, 0x1B5, 0x1B6, 0x1B7, 0x1B8, 0x1B9, 0x1BA, 0x1BB, 0x1BC, 0x1BD, 0x1BE, 0x1BF, - 0x1C0, 0x1C1, 0x1C2, 0x1C3, 0x1C4, 0x1C5, 0x1C6, 0x1C7, 0x1C8, 0x1C9, 0x1CA, 0x1CB, 0x1CC, 0x1CD, 0x1CE, 0x1CF, - 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x1D4, 0x1D5, 0x1D6, 0x1D7, 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, 0x1DD, 0x1DE, 0x1DF, - 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E4, 0x1E5, 0x1E6, 0x1E7, 0x1E8, 0x1E9, 0x1EA, 0x1EB, 0x1EC, 0x1ED, 0x1EE, 0x1EF, - 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, 0x1F5, 0x1F6, 0x1F7, 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, 0x1FD, 0x1FE, 0x1FF, - 0x200, -} - pub trait KnownSize: - GenericConstUsize - + sealed::SizeTypeSealed - + sealed::SizeSealed - + Default - + FillInDefaultedGenerics + GenericConstUsize + sealed::SizeTypeSealed + sealed::SizeSealed + Default { const SIZE: Self; type ArrayMatch: AsRef<[Expr]> @@ -146,15 +89,35 @@ pub trait KnownSize: + ToSimValueWithType>; } -impl KnownSize for ConstUsize -where - [(); N]: KnownSizeBase, -{ - const SIZE: Self = Self; - type ArrayMatch = [Expr; N]; - type ArraySimValue = [SimValue; N]; +macro_rules! known_widths { + ([] $($bits:literal)+) => { + impl KnownSize for ConstUsize<{ + let v = 0; + $(let v = v * 2 + $bits;)* + v + }> { + const SIZE: Self = Self; + type ArrayMatch = [Expr; Self::VALUE]; + type ArraySimValue = [SimValue; Self::VALUE]; + } + }; + ([2 $($rest:tt)*] $($bits:literal)+) => { + known_widths!([$($rest)*] $($bits)* 0); + known_widths!([$($rest)*] $($bits)* 1); + }; + ([2 $($rest:tt)*]) => { + known_widths!([$($rest)*] 0); + known_widths!([$($rest)*] 1); + impl KnownSize for ConstUsize<{2 $(* $rest)*}> { + const SIZE: Self = Self; + type ArrayMatch = [Expr; Self::VALUE]; + type ArraySimValue = [SimValue; Self::VALUE]; + } + }; } +known_widths!([2 2 2 2 2 2 2 2 2]); + pub trait SizeType: sealed::SizeTypeSealed + Copy @@ -166,7 +129,6 @@ pub trait SizeType: + 'static + Serialize + DeserializeOwned - + FillInDefaultedGenerics { type Size: Size; } @@ -568,23 +530,6 @@ fn deserialize_int_value<'de, D: Deserializer<'de>>( }) } -macro_rules! impl_valueless_op_forward { - ( - #[forward_to = $ForwardTrait:path] - impl<$($G:ident: $Bound:path),*> $TraitPath:ident$(::$TraitPathRest:ident)+<$($Rhs:ty)?> for $SelfTy:ty { - $($(type $Output:ident;)? - use $forward_fn:path as $fn:ident($self:ident $(, $rhs:ident)?);)? - } - ) => { - impl<$($G: $Bound),*> $TraitPath$(::$TraitPathRest)+<$($Rhs)?> for $SelfTy { - $($(type $Output = <$SelfTy as $ForwardTrait>::$Output;)? - fn $fn($self $(, $rhs: $Rhs)?) $(-> Self::$Output)? { - $forward_fn($self $(, $rhs)?) - })? - } - }; -} - macro_rules! impl_int { ($pretty_name:ident, $name:ident, $generic_name:ident, $value:ident, $SIGNED:literal) => { #[derive(Copy, Clone, PartialEq, Eq, Hash)] @@ -637,176 +582,6 @@ macro_rules! impl_int { } } - impl std::ops::Add>> - for Valueless<$name> - { - type Output = Valueless<$name>; - - fn add(self, rhs: Valueless<$name>) -> Self::Output { - Valueless::new($name::new_dyn( - self.ty() - .width() - .max(rhs.ty().width()) - .checked_add(1) - .expect("width too big"), - )) - } - } - - impl_valueless_op_forward! { - #[forward_to = std::ops::Add>>] - impl std::ops::Sub>> - for Valueless<$name> - { - type Output; - - use std::ops::Add::>>::add as sub(self, rhs); - } - } - - impl std::ops::BitOr>> - for Valueless<$name> - { - type Output = Valueless; - - fn bitor(self, rhs: Valueless<$name>) -> Self::Output { - Valueless::new(UInt::new_dyn(self.ty().width().max(rhs.ty().width()))) - } - } - - impl_valueless_op_forward! { - #[forward_to = std::ops::BitOr>>] - impl std::ops::BitAnd>> - for Valueless<$name> - { - type Output; - - use std::ops::BitOr::>>::bitor as bitand(self, rhs); - } - } - - impl_valueless_op_forward! { - #[forward_to = std::ops::BitOr>>] - impl std::ops::BitXor>> - for Valueless<$name> - { - type Output; - - use std::ops::BitOr::>>::bitor as bitxor(self, rhs); - } - } - - impl std::ops::Not for Valueless<$name> { - type Output = Valueless>; - - fn not(self) -> Self::Output { - Valueless::new(self.ty().as_same_width_uint()) - } - } - - impl std::ops::Not for $value { - type Output = UIntValue; - - fn not(mut self) -> Self::Output { - // modifies in-place despite using `Not::not` - let _ = Not::not(self.bits_mut()); - UIntValue::new(self.into_bits()) - } - } - - impl std::ops::Not for &'_ $value { - type Output = UIntValue; - - fn not(self) -> Self::Output { - $value::not(self.clone()) - } - } - - impl std::ops::Mul>> - for Valueless<$name> - { - type Output = Valueless<$name>; - - fn mul(self, rhs: Valueless<$name>) -> Self::Output { - Valueless::new($name::new_dyn( - self.ty() - .width() - .checked_add(rhs.ty().width()) - .expect("width too big"), - )) - } - } - - impl std::ops::Rem>> - for Valueless<$name> - { - type Output = Valueless<$name>; - - fn rem(self, rhs: Valueless<$name>) -> Self::Output { - Valueless::new($name::new_dyn(self.ty().width().min(rhs.ty().width()))) - } - } - - impl std::ops::Shl>> - for Valueless<$name> - { - type Output = Valueless<$name>; - - #[track_caller] - fn shl(self, rhs: Valueless>) -> Self::Output { - let Some(pow2_rhs_width) = rhs - .ty() - .width() - .try_into() - .ok() - .and_then(|v| 2usize.checked_pow(v)) - else { - panic!( - "dynamic left-shift amount's bit-width is too big, try casting the shift \ - amount to a smaller bit-width before shifting" - ); - }; - Valueless::new($name::new_dyn( - (pow2_rhs_width - 1) - .checked_add(self.ty().width()) - .expect("width too big"), - )) - } - } - - impl std::ops::Shr>> - for Valueless<$name> - { - type Output = Valueless<$name>; - - fn shr(self, _rhs: Valueless>) -> Self::Output { - self - } - } - - impl std::ops::Shl for Valueless<$name> { - type Output = Valueless<$name>; - - fn shl(self, rhs: usize) -> Self::Output { - Valueless::new($name::new_dyn( - self.ty().width().checked_add(rhs).expect("width too big"), - )) - } - } - - impl std::ops::Shr for Valueless<$name> { - type Output = Valueless<$name>; - - fn shr(self, rhs: usize) -> Self::Output { - let width = self.ty().width().saturating_sub(rhs); - Valueless::new($name::new_dyn(if $SIGNED && width == 0 { - 1 - } else { - width - })) - } - } - impl sealed::BoolOrIntTypeSealed for $name {} impl BoolOrIntType for $name { @@ -1068,12 +843,6 @@ macro_rules! impl_int { } } - impl<'a, Width: Size> From<&'a $value> for BigInt { - fn from(v: &'a $value) -> BigInt { - v.to_bigint() - } - } - impl $value { pub fn width(&self) -> usize { if let Some(retval) = Width::KNOWN_VALUE { @@ -1092,6 +861,11 @@ macro_rules! impl_int { pub fn into_bits(self) -> Arc { self.bits } + pub fn ty(&self) -> $name { + $name { + width: Width::from_usize(self.width()), + } + } pub fn as_dyn_int(self) -> $value { $value { bits: self.bits, @@ -1104,38 +878,6 @@ macro_rules! impl_int { pub fn bits_mut(&mut self) -> &mut BitSlice { Arc::::make_mut(&mut self.bits) } - pub fn hdl_cmp(&self, other: &$value) -> std::cmp::Ordering { - self.to_bigint().cmp(&other.to_bigint()) - } - } - - impl ValueType for $value { - type Type = $name; - type ValueCategory = ValueCategoryValue; - - fn ty(&self) -> Self::Type { - $name { - width: Width::from_usize(self.width()), - } - } - } - - impl<'a, Width: Size> ToSimValueInner<'a> for $value { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - Cow::Borrowed(this) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - Cow::Owned(this) - } - } - - impl<'a, Width: Size> ToSimValueInner<'a> for &'a $value { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - Cow::Borrowed(&**this) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - Cow::Borrowed(this) - } } impl ToLiteralBits for $value { @@ -1273,58 +1015,11 @@ impl SInt { } } -impl std::ops::Div>> - for Valueless> -{ - type Output = Self; - - fn div(self, _rhs: Valueless>) -> Self::Output { - self - } -} - -impl std::ops::Div>> - for Valueless> -{ - type Output = Valueless; - - fn div(self, _rhs: Valueless>) -> Self::Output { - Valueless::new(SInt::new_dyn( - self.ty().width().checked_add(1).expect("width too big"), - )) - } -} - -impl std::ops::Neg for Valueless> { - type Output = Valueless; - fn neg(self) -> Self::Output { - Valueless::new(SInt::new_dyn( - self.ty().width().checked_add(1).expect("width too big"), - )) - } -} - -impl std::ops::Neg for SIntValue { - type Output = SIntValue; - fn neg(self) -> Self::Output { - -&self - } -} - -impl std::ops::Neg for &'_ SIntValue { - type Output = SIntValue; - fn neg(self) -> Self::Output { - let ty = self.to_valueless().neg().ty(); - ty.from_bigint_wrapping(&-self.to_bigint()) - } -} - -macro_rules! impl_prim_int_to_expr { +macro_rules! impl_prim_int { ( $(#[$meta:meta])* $prim_int:ident, $ty:ty ) => { - $(#[$meta])* impl From<$prim_int> for <$ty as BoolOrIntType>::Value { fn from(v: $prim_int) -> Self { <$ty>::le_bytes_to_value_wrapping( @@ -1333,32 +1028,15 @@ macro_rules! impl_prim_int_to_expr { ) } } - $(#[$meta])* impl From> for <$ty as BoolOrIntType>::Value { fn from(v: NonZero<$prim_int>) -> Self { v.get().into() } } $(#[$meta])* - impl<'a> ToSimValueInner<'a> for $prim_int { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - Self::into_sim_value_inner(*this) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - Cow::Owned(this.into()) - } - } - $(#[$meta])* - impl ValueType for $prim_int { - type Type = $ty; - type ValueCategory = ValueCategoryValue; - - fn ty(&self) -> Self::Type { - StaticType::TYPE - } - } - $(#[$meta])* impl ToExpr for $prim_int { + type Type = $ty; + fn to_expr(&self) -> Expr { <$ty>::le_bytes_to_expr_wrapping( &self.to_le_bytes(), @@ -1367,25 +1045,9 @@ macro_rules! impl_prim_int_to_expr { } } $(#[$meta])* - impl<'a> ToSimValueInner<'a> for NonZero<$prim_int> { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - Self::into_sim_value_inner(*this) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - Cow::Owned(this.into()) - } - } - $(#[$meta])* - impl ValueType for NonZero<$prim_int> { - type Type = $ty; - type ValueCategory = ValueCategoryValue; - - fn ty(&self) -> Self::Type { - StaticType::TYPE - } - } - $(#[$meta])* impl ToExpr for NonZero<$prim_int> { + type Type = $ty; + fn to_expr(&self) -> Expr { self.get().to_expr() } @@ -1393,208 +1055,28 @@ macro_rules! impl_prim_int_to_expr { }; } -macro_rules! impl_for_all_prim_uints { - ( - #[size =, $(rest:tt)*] - $m:ident!() - ) => { - impl_for_all_prim_uints!( - #[usize =, $($rest)*] - $m!() - ); - }; - ( - #[size = size, $(rest:tt)*] - $m:ident!() - ) => { - impl_for_all_prim_uints!( - #[usize = usize, $($rest)*] - $m!() - ); - }; - ( - #[usize = $($usize:ident)?, NonZero = $NonZero:ident] - $m:ident!() - ) => { - impl_for_all_prim_uints!( - #[usize = $($usize)?, NonZero = $NonZero, NonZero = $((NonZero<$usize>))?] - $m!() - ); - }; - ( - #[usize = $($usize:ident)?, NonZero =] - $m:ident!() - ) => { - impl_for_all_prim_uints!( - #[usize = $($usize)?, NonZero =, NonZero =] - $m!() - ); - }; - ( - #[usize = $($usize:ident)?, NonZero = $($NonZero:ident)?, NonZero = $(($($NonZeroUsize:tt)*))?] - $m:ident!() - ) => { - $m!(u8, UInt<8>); - $m!(u16, UInt<16>); - $m!(u32, UInt<32>); - $m!(u64, UInt<64>); - $m!(u128, UInt<128>); - $($m!($NonZero, UInt<8>);)? - $($m!($NonZero, UInt<16>);)? - $($m!($NonZero, UInt<32>);)? - $($m!($NonZero, UInt<64>);)? - $($m!($NonZero, UInt<128>);)? - $($m!( - /// for portability reasons, [`usize`] always translates to [`UInt<64>`][type@UInt] - $usize, UInt<64> - );)? - $($m!( - /// for portability reasons, [`usize`] always translates to [`UInt<64>`][type@UInt] - $($NonZeroUsize)*, UInt<64> - );)? - }; -} +impl_prim_int!(u8, UInt<8>); +impl_prim_int!(u16, UInt<16>); +impl_prim_int!(u32, UInt<32>); +impl_prim_int!(u64, UInt<64>); +impl_prim_int!(u128, UInt<128>); +impl_prim_int!(i8, SInt<8>); +impl_prim_int!(i16, SInt<16>); +impl_prim_int!(i32, SInt<32>); +impl_prim_int!(i64, SInt<64>); +impl_prim_int!(i128, SInt<128>); -macro_rules! impl_for_all_prim_sints { - ( - #[size =, $(rest:tt)*] - $m:ident!() - ) => { - impl_for_all_prim_sints!( - #[isize =, $($rest)*] - $m!() - ); - }; - ( - #[size = size, $(rest:tt)*] - $m:ident!() - ) => { - impl_for_all_prim_sints!( - #[isize = isize, $($rest)*] - $m!() - ); - }; - ( - #[isize = $($isize:ident)?, NonZero = $NonZero:ident] - $m:ident!() - ) => { - impl_for_all_prim_sints!( - #[isize = $($isize)?, NonZero = $NonZero, NonZero = $((NonZero<$isize>))?] - $m!() - ); - }; - ( - #[isize = $($isize:ident)?, NonZero =] - $m:ident!() - ) => { - impl_for_all_prim_sints!( - #[isize = $($isize)?, NonZero =, NonZero =] - $m!() - ); - }; - ( - #[isize = $($isize:ident)?, NonZero = $($NonZero:ident)?, NonZero = $(($($NonZeroIsize:tt)*))?] - $m:ident!() - ) => { - $m!(i8, SInt<8>); - $m!(i16, SInt<16>); - $m!(i32, SInt<32>); - $m!(i64, SInt<64>); - $m!(i128, SInt<128>); - $($m!($NonZero, SInt<8>);)? - $($m!($NonZero, SInt<16>);)? - $($m!($NonZero, SInt<32>);)? - $($m!($NonZero, SInt<64>);)? - $($m!($NonZero, SInt<128>);)? - $($m!( - /// for portability reasons, [`isize`] always translates to [`SInt<64>`][type@SInt] - $isize, SInt<64> - );)? - $($m!( - /// for portability reasons, [`isize`] always translates to [`SInt<64>`][type@SInt] - $($NonZeroIsize)*, SInt<64> - );)? - }; -} - -impl_for_all_prim_uints!( - #[usize = usize, NonZero =] - impl_prim_int_to_expr!() +impl_prim_int!( + /// for portability reasons, [`usize`] always translates to [`UInt<64>`][type@UInt] + usize, UInt<64> ); -impl_for_all_prim_sints!( - #[isize = isize, NonZero =] - impl_prim_int_to_expr!() +impl_prim_int!( + /// for portability reasons, [`isize`] always translates to [`SInt<64>`][type@SInt] + isize, SInt<64> ); -macro_rules! impl_prim_int_from_value { - ($prim_int:ident, UInt<$width:literal>) => { - impl_prim_int_from_value!($prim_int, UInt<$width>, UIntValue>); - }; - ($prim_int:ident, SInt<$width:literal>) => { - impl_prim_int_from_value!($prim_int, SInt<$width>, SIntValue>); - }; - ($prim_int:ident, $ty:ty, $value:ty) => { - impl From<$value> for $prim_int { - fn from(value: $value) -> Self { - value.as_int() - } - } - - impl<'a> From<&'a mut $value> for $prim_int { - fn from(value: &'a mut $value) -> Self { - value.as_int() - } - } - - impl From> for $prim_int { - fn from(value: SimValue<$ty>) -> Self { - value.as_int() - } - } - - impl<'a> From<&'a mut SimValue<$ty>> for $prim_int { - fn from(value: &'a mut SimValue<$ty>) -> Self { - value.as_int() - } - } - - impl<'a> From<&'a SimValue<$ty>> for $prim_int { - fn from(value: &'a SimValue<$ty>) -> Self { - value.as_int() - } - } - - impl<'a> From<&'a $value> for $prim_int { - fn from(value: &'a $value) -> Self { - value.as_int() - } - } - - impl $value { - pub fn as_int(&self) -> $prim_int { - let mut le_bytes = (0 as $prim_int).to_le_bytes(); - let bitslice = BitSlice::::from_slice_mut(&mut le_bytes); - bitslice.clone_from_bitslice(self.bits()); - $prim_int::from_le_bytes(le_bytes) - } - } - }; -} - -impl_for_all_prim_uints!( - #[usize =, NonZero =] - impl_prim_int_from_value!() -); - -impl_for_all_prim_sints!( - #[isize =, NonZero =] - impl_prim_int_from_value!() -); - -pub trait BoolOrIntType: - Type::Value> + sealed::BoolOrIntTypeSealed -{ +pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed { type Width: Size; type Signed: GenericConstBool; type Value: Clone @@ -1819,80 +1301,12 @@ impl StaticType for Bool { const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES; } -impl From for UIntValue> { - fn from(value: bool) -> Self { - static VALUES: OnceLock<[UIntValue>; 2]> = OnceLock::new(); - let values = VALUES - .get_or_init(|| std::array::from_fn(|i| UInt::<1>::new_static().from_int_wrapping(i))); - values[value as usize].clone() - } -} - -impl From for SIntValue> { - fn from(value: bool) -> Self { - SIntValue::new(UIntValue::>::from(value).into_bits()) - } -} - -impl From for UIntValue { - fn from(value: bool) -> Self { - UIntValue::new(UIntValue::>::from(value).into_bits()) - } -} - -impl From for SIntValue { - fn from(value: bool) -> Self { - SIntValue::new(UIntValue::>::from(value).into_bits()) - } -} - impl ToLiteralBits for bool { fn to_literal_bits(&self) -> Result, NotALiteralExpr> { Ok(interned_bit(*self)) } } -impl<'a> ToSimValueInner<'a> for bool { - fn to_sim_value_inner(this: &Self) -> Cow<'_, ::SimValue> { - Cow::Owned(*this) - } - fn into_sim_value_inner(this: Self) -> Cow<'a, ::SimValue> { - Cow::Owned(this) - } -} - -impl std::ops::Not for Valueless { - type Output = Valueless; - - fn not(self) -> Self::Output { - self - } -} - -impl std::ops::BitAnd for Valueless { - type Output = Valueless; - - fn bitand(self, _rhs: Valueless) -> Self::Output { - self - } -} - -impl std::ops::BitOr for Valueless { - type Output = Valueless; - - fn bitor(self, _rhs: Valueless) -> Self::Output { - self - } -} - -impl std::ops::BitXor for Valueless { - type Output = Valueless; - - fn bitxor(self, _rhs: Valueless) -> Self::Output { - self - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/fayalite/src/int/uint_in_range.rs b/crates/fayalite/src/int/uint_in_range.rs index acf2fec..5ddd38c 100644 --- a/crates/fayalite/src/int/uint_in_range.rs +++ b/crates/fayalite/src/int/uint_in_range.rs @@ -4,13 +4,13 @@ use crate::{ bundle::{Bundle, BundleField, BundleType, BundleTypePropertiesBuilder, NoBuilder}, expr::{ - CastBitsTo, CastTo, CastToBits, CastToImpl, Expr, HdlPartialEq, HdlPartialEqImpl, - HdlPartialOrd, HdlPartialOrdImpl, + CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, + ops::{ExprCastTo, ExprPartialEq, ExprPartialOrd}, }, - int::{Bool, DynSize, KnownSize, Size, SizeType, UInt, UIntType, UIntValue}, - intern::{Intern, InternSlice, Interned}, + int::{Bool, DynSize, KnownSize, Size, SizeType, UInt, UIntType}, + intern::{Intern, Interned}, phantom_const::PhantomConst, - sim::value::{SimValue, ToSimValueWithType}, + sim::value::{SimValue, SimValuePartialEq, ToSimValueWithType}, source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, @@ -22,7 +22,7 @@ use serde::{ Deserialize, Deserializer, Serialize, Serializer, de::{Error, Visitor, value::UsizeDeserializer}, }; -use std::{borrow::Cow, fmt, marker::PhantomData, ops::Index}; +use std::{fmt, marker::PhantomData, ops::Index}; const UINT_IN_RANGE_TYPE_FIELD_NAMES: [&'static str; 2] = ["value", "range"]; @@ -96,6 +96,7 @@ impl Type for UIntInRangeMaskType { 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; @@ -111,8 +112,8 @@ impl BundleType for UIntInRangeMaskType { flipped: false, ty: range.canonical(), }, - ] - .intern_slice() + ][..] + .intern() } } @@ -135,60 +136,33 @@ impl ToSimValueWithType for bool { } } -impl CastToImpl for UIntInRangeMaskType { - type ValueOutput = bool; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - _to_type: Bool, - ) -> Self::ValueOutput { - *value - } - - fn cast_expr_to(value: Expr, to_type: Bool) -> Expr { - value.cast_to_bits().cast_to(to_type) +impl ExprCastTo for UIntInRangeMaskType { + fn cast_to(src: Expr, to_type: Bool) -> Expr { + src.cast_to_bits().cast_to(to_type) } } -impl CastToImpl for Bool { - type ValueOutput = SimValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: UIntInRangeMaskType, - ) -> Self::ValueOutput { - SimValue::from_value(to_type, *value) - } - - fn cast_expr_to(value: Expr, to_type: UIntInRangeMaskType) -> Expr { - value.cast_to_static::>().cast_bits_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 HdlPartialEqImpl for UIntInRangeMaskType { - #[track_caller] - fn cmp_value_eq( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: Self, - rhs_value: Cow<'_, Self::SimValue>, - ) -> bool { - *lhs_value == *rhs_value - } - - #[track_caller] - fn cmp_expr_eq(lhs: Expr, rhs: Expr) -> Expr { +impl ExprPartialEq for UIntInRangeMaskType { + fn cmp_eq(lhs: Expr, rhs: Expr) -> Expr { lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits()) } - - #[track_caller] - fn cmp_expr_ne(lhs: Expr, rhs: Expr) -> Expr { + 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)] @@ -326,16 +300,9 @@ macro_rules! define_uint_in_range_type { } } pub fn new(start: Start::SizeType, end: End::SizeType) -> Self { - Self::from_phantom_const_range(PhantomConst::new_sized($SerdeRange { start, end })) - } - pub fn bit_width(self) -> usize { - self.value.width() - } - pub fn start(self) -> Start::SizeType { - self.range.get().start - } - pub fn end(self) -> End::SizeType { - self.range.get().end + Self::from_phantom_const_range(PhantomConst::new( + $SerdeRange { start, end }.intern_sized(), + )) } } @@ -426,6 +393,7 @@ macro_rules! define_uint_in_range_type { 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; @@ -441,8 +409,8 @@ macro_rules! define_uint_in_range_type { flipped: false, ty: range.canonical(), }, - ] - .intern_slice() + ][..] + .intern() } } @@ -509,64 +477,32 @@ macro_rules! define_uint_in_range_type { } } - impl CastToImpl> - for $UIntInRangeType - { - type ValueOutput = UIntValue; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: UIntType, - ) -> Self::ValueOutput { - value.cast_to(to_type) - } - - fn cast_expr_to(value: Expr, to_type: UIntType) -> Expr> { - value.cast_to_bits().cast_to(to_type) + impl ExprCastTo for $UIntInRangeType { + fn cast_to(src: Expr, to_type: UInt) -> Expr { + src.cast_to_bits().cast_to(to_type) } } - impl CastToImpl<$UIntInRangeType> - for UIntType - { - type ValueOutput = SimValue<$UIntInRangeType>; - - fn cast_value_to( - _this: Self, - value: Cow<'_, Self::SimValue>, - to_type: $UIntInRangeType, - ) -> Self::ValueOutput { - value.cast_to(to_type.value).cast_bits_to(to_type) - } - - fn cast_expr_to( - value: Expr, + impl ExprCastTo<$UIntInRangeType> for UInt { + fn cast_to( + src: Expr, to_type: $UIntInRangeType, ) -> Expr<$UIntInRangeType> { - value.cast_to(to_type.value).cast_bits_to(to_type) + src.cast_bits_to(to_type) } } impl - HdlPartialEqImpl<$UIntInRangeType> + ExprPartialEq<$UIntInRangeType> for $UIntInRangeType { - fn cmp_value_eq( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - *lhs_value == *rhs_value - } - fn cmp_expr_eq( + fn cmp_eq( lhs: Expr, rhs: Expr<$UIntInRangeType>, ) -> Expr { lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits()) } - fn cmp_expr_ne( + fn cmp_ne( lhs: Expr, rhs: Expr<$UIntInRangeType>, ) -> Expr { @@ -575,60 +511,28 @@ macro_rules! define_uint_in_range_type { } impl - HdlPartialOrdImpl<$UIntInRangeType> + ExprPartialOrd<$UIntInRangeType> for $UIntInRangeType { - fn cmp_value_lt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - PartialOrd::lt(&*lhs_value, &*rhs_value) - } - fn cmp_value_le( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - PartialOrd::le(&*lhs_value, &*rhs_value) - } - fn cmp_value_gt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - PartialOrd::gt(&*lhs_value, &*rhs_value) - } - fn cmp_value_ge( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - PartialOrd::ge(&*lhs_value, &*rhs_value) - } - fn cmp_expr_lt( + fn cmp_lt( lhs: Expr, rhs: Expr<$UIntInRangeType>, ) -> Expr { lhs.cast_to_bits().cmp_lt(rhs.cast_to_bits()) } - fn cmp_expr_le( + fn cmp_le( lhs: Expr, rhs: Expr<$UIntInRangeType>, ) -> Expr { lhs.cast_to_bits().cmp_le(rhs.cast_to_bits()) } - fn cmp_expr_gt( + fn cmp_gt( lhs: Expr, rhs: Expr<$UIntInRangeType>, ) -> Expr { lhs.cast_to_bits().cmp_gt(rhs.cast_to_bits()) } - fn cmp_expr_ge( + fn cmp_ge( lhs: Expr, rhs: Expr<$UIntInRangeType>, ) -> Expr { @@ -636,138 +540,70 @@ macro_rules! define_uint_in_range_type { } } - impl HdlPartialEqImpl> + impl + SimValuePartialEq<$UIntInRangeType> + for $UIntInRangeType + { + fn sim_value_eq( + this: &SimValue, + other: &SimValue<$UIntInRangeType>, + ) -> bool { + **this == **other + } + } + + impl ExprPartialEq> for $UIntInRangeType { - fn cmp_value_eq( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: UIntType, - rhs_value: Cow<'_, UIntValue>, - ) -> bool { - HdlPartialEq::cmp_eq(&*lhs_value, &*rhs_value) - } - fn cmp_expr_eq(lhs: Expr, rhs: Expr>) -> Expr { + fn cmp_eq(lhs: Expr, rhs: Expr>) -> Expr { lhs.cast_to_bits().cmp_eq(rhs) } - fn cmp_expr_ne(lhs: Expr, rhs: Expr>) -> Expr { + fn cmp_ne(lhs: Expr, rhs: Expr>) -> Expr { lhs.cast_to_bits().cmp_ne(rhs) } } - impl HdlPartialEqImpl<$UIntInRangeType> + impl ExprPartialEq<$UIntInRangeType> for UIntType { - fn cmp_value_eq( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - HdlPartialEq::cmp_eq(&*lhs_value, *rhs_value) - } - fn cmp_expr_eq(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { + fn cmp_eq(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { lhs.cmp_eq(rhs.cast_to_bits()) } - fn cmp_expr_ne(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { + fn cmp_ne(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { lhs.cmp_ne(rhs.cast_to_bits()) } } - impl HdlPartialOrdImpl> + impl ExprPartialOrd> for $UIntInRangeType { - fn cmp_value_lt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: UIntType, - rhs_value: Cow<'_, UIntValue>, - ) -> bool { - HdlPartialOrd::cmp_lt(&*lhs_value, &*rhs_value) - } - fn cmp_value_le( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: UIntType, - rhs_value: Cow<'_, UIntValue>, - ) -> bool { - HdlPartialOrd::cmp_le(&*lhs_value, &*rhs_value) - } - fn cmp_value_gt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: UIntType, - rhs_value: Cow<'_, UIntValue>, - ) -> bool { - HdlPartialOrd::cmp_gt(&*lhs_value, &*rhs_value) - } - fn cmp_value_ge( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: UIntType, - rhs_value: Cow<'_, UIntValue>, - ) -> bool { - HdlPartialOrd::cmp_ge(&*lhs_value, &*rhs_value) - } - fn cmp_expr_lt(lhs: Expr, rhs: Expr>) -> Expr { + fn cmp_lt(lhs: Expr, rhs: Expr>) -> Expr { lhs.cast_to_bits().cmp_lt(rhs) } - fn cmp_expr_le(lhs: Expr, rhs: Expr>) -> Expr { + fn cmp_le(lhs: Expr, rhs: Expr>) -> Expr { lhs.cast_to_bits().cmp_le(rhs) } - fn cmp_expr_gt(lhs: Expr, rhs: Expr>) -> Expr { + fn cmp_gt(lhs: Expr, rhs: Expr>) -> Expr { lhs.cast_to_bits().cmp_gt(rhs) } - fn cmp_expr_ge(lhs: Expr, rhs: Expr>) -> Expr { + fn cmp_ge(lhs: Expr, rhs: Expr>) -> Expr { lhs.cast_to_bits().cmp_ge(rhs) } } - impl HdlPartialOrdImpl<$UIntInRangeType> + impl ExprPartialOrd<$UIntInRangeType> for UIntType { - fn cmp_value_lt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - HdlPartialOrd::cmp_lt(&*lhs_value, *rhs_value) - } - fn cmp_value_le( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - HdlPartialOrd::cmp_le(&*lhs_value, *rhs_value) - } - fn cmp_value_gt( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - HdlPartialOrd::cmp_gt(&*lhs_value, *rhs_value) - } - fn cmp_value_ge( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: $UIntInRangeType, - rhs_value: Cow<'_, <$UIntInRangeType as Type>::SimValue>, - ) -> bool { - HdlPartialOrd::cmp_ge(&*lhs_value, *rhs_value) - } - fn cmp_expr_lt(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { + fn cmp_lt(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { lhs.cmp_lt(rhs.cast_to_bits()) } - fn cmp_expr_le(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { + fn cmp_le(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { lhs.cmp_le(rhs.cast_to_bits()) } - fn cmp_expr_gt(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { + fn cmp_gt(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { lhs.cmp_gt(rhs.cast_to_bits()) } - fn cmp_expr_ge(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { + fn cmp_ge(lhs: Expr, rhs: Expr<$UIntInRangeType>) -> Expr { lhs.cmp_ge(rhs.cast_to_bits()) } } diff --git a/crates/fayalite/src/intern.rs b/crates/fayalite/src/intern.rs index b68140b..af91f0a 100644 --- a/crates/fayalite/src/intern.rs +++ b/crates/fayalite/src/intern.rs @@ -9,13 +9,11 @@ use std::{ any::{Any, TypeId}, borrow::{Borrow, Cow}, cmp::Ordering, - ffi::{OsStr, OsString}, fmt, hash::{BuildHasher, Hash, Hasher}, iter::FusedIterator, marker::PhantomData, ops::Deref, - path::{Path, PathBuf}, sync::{Mutex, RwLock}, }; @@ -289,266 +287,15 @@ impl InternedCompare for BitSlice { } } -/// Safety: `as_bytes` and `from_bytes_unchecked` must return the same pointer as the input. -/// all values returned by `as_bytes` must be valid to pass to `from_bytes_unchecked`. -/// `into_bytes` must return the exact same thing as `as_bytes`. -/// `Interned` must contain the exact same references as `Interned<[u8]>`, -/// so they can be safely interconverted without needing re-interning. -unsafe trait InternStrLike: ToOwned { - fn as_bytes(this: &Self) -> &[u8]; - fn into_bytes(this: Self::Owned) -> Vec; - /// Safety: `bytes` must be a valid sequence of bytes for this type. All UTF-8 sequences are valid. - unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self; -} - -macro_rules! impl_intern_str_like { - ($ty:ty, owned = $Owned:ty) => { - impl InternedCompare for $ty { - type InternedCompareKey = PtrEqWithMetadata<[u8]>; - fn interned_compare_key_ref(this: &Self) -> Self::InternedCompareKey { - PtrEqWithMetadata(InternStrLike::as_bytes(this)) - } - } - impl Intern for $ty { - fn intern(&self) -> Interned { - Self::intern_cow(Cow::Borrowed(self)) - } - fn intern_cow(this: Cow<'_, Self>) -> Interned { - Interned::cast_unchecked( - <[u8]>::intern_cow(match this { - Cow::Borrowed(v) => Cow::Borrowed(::as_bytes(v)), - Cow::Owned(v) => { - // verify $Owned is correct - let v: $Owned = v; - Cow::Owned(::into_bytes(v)) - } - }), - // Safety: guaranteed safe because we got the bytes from `as_bytes`/`into_bytes` - |v| unsafe { ::from_bytes_unchecked(v) }, - ) - } - } - impl Default for Interned<$ty> { - fn default() -> Self { - // Safety: safe because the empty sequence is valid UTF-8 - unsafe { <$ty as InternStrLike>::from_bytes_unchecked(&[]) }.intern() - } - } - impl<'de> Deserialize<'de> for Interned<$ty> { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - Cow::<'de, $ty>::deserialize(deserializer).map(Intern::intern_cow) - } - } - impl From<$Owned> for Interned<$ty> { - fn from(v: $Owned) -> Self { - v.intern_deref() - } - } - impl From> for $Owned { - fn from(v: Interned<$ty>) -> Self { - Interned::into_inner(v).into() - } - } - impl From> for Box<$ty> { - fn from(v: Interned<$ty>) -> Self { - Interned::into_inner(v).into() - } - } - }; -} - -// Safety: satisfies `InternStrLike`'s requirements where the valid sequences for `from_bytes_unchecked` matches `str` -unsafe impl InternStrLike for str { - fn as_bytes(this: &Self) -> &[u8] { - this.as_bytes() - } - fn into_bytes(this: Self::Owned) -> Vec { - this.into_bytes() - } - unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { - // Safety: `bytes` is guaranteed UTF-8 by the caller - unsafe { str::from_utf8_unchecked(bytes) } - } -} - -impl_intern_str_like!(str, owned = String); - -// Safety: satisfies `InternStrLike`'s requirements where the valid sequences for `from_bytes_unchecked` matches `OsStr` -unsafe impl InternStrLike for OsStr { - fn as_bytes(this: &Self) -> &[u8] { - this.as_encoded_bytes() - } - fn into_bytes(this: Self::Owned) -> Vec { - this.into_encoded_bytes() - } - unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { - // Safety: `bytes` is guaranteed valid for `OsStr` by the caller - unsafe { OsStr::from_encoded_bytes_unchecked(bytes) } - } -} - -impl_intern_str_like!(OsStr, owned = OsString); - -// Safety: satisfies `InternStrLike`'s requirements where the valid sequences for `from_bytes_unchecked` matches `OsStr` -unsafe impl InternStrLike for Path { - fn as_bytes(this: &Self) -> &[u8] { - this.as_os_str().as_encoded_bytes() - } - fn into_bytes(this: Self::Owned) -> Vec { - this.into_os_string().into_encoded_bytes() - } - unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { - // Safety: `bytes` is guaranteed valid for `OsStr` by the caller - unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(bytes)) } - } -} - -impl_intern_str_like!(Path, owned = PathBuf); - -impl Interned { - pub fn from_utf8(v: Interned<[u8]>) -> Result { - Interned::try_cast_unchecked(v, str::from_utf8) - } - pub fn as_interned_bytes(self) -> Interned<[u8]> { - Interned::cast_unchecked(self, str::as_bytes) - } - pub fn as_interned_os_str(self) -> Interned { - Interned::cast_unchecked(self, AsRef::as_ref) - } - pub fn as_interned_path(self) -> Interned { - Interned::cast_unchecked(self, AsRef::as_ref) - } -} - -impl From> for Interned { - fn from(value: Interned) -> Self { - value.as_interned_os_str() - } -} - -impl From> for Interned { - fn from(value: Interned) -> Self { - value.as_interned_path() - } -} - -impl Interned { - pub fn as_interned_encoded_bytes(self) -> Interned<[u8]> { - Interned::cast_unchecked(self, OsStr::as_encoded_bytes) - } - pub fn to_interned_str(self) -> Option> { - Interned::try_cast_unchecked(self, |v| v.to_str().ok_or(())).ok() - } - pub fn display(self) -> std::ffi::os_str::Display<'static> { - Self::into_inner(self).display() - } - pub fn as_interned_path(self) -> Interned { - Interned::cast_unchecked(self, AsRef::as_ref) - } -} - -impl From> for Interned { - fn from(value: Interned) -> Self { - value.as_interned_path() - } -} - -impl Interned { - pub fn as_interned_os_str(self) -> Interned { - Interned::cast_unchecked(self, AsRef::as_ref) - } - pub fn to_interned_str(self) -> Option> { - Interned::try_cast_unchecked(self, |v| v.to_str().ok_or(())).ok() - } - pub fn display(self) -> std::path::Display<'static> { - Self::into_inner(self).display() - } - pub fn interned_file_name(self) -> Option> { - Some(self.file_name()?.intern()) - } -} - -impl From> for Interned { - fn from(value: Interned) -> Self { - value.as_interned_os_str() - } -} - -pub trait InternSlice: Sized { - type Element: 'static + Send + Sync + Clone + Hash + Eq; - fn intern_slice(self) -> Interned<[Self::Element]>; -} - -impl InternSlice for Box<[T]> { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - self.into_vec().intern_slice() - } -} - -impl InternSlice for Vec { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - self.intern_deref() - } -} - -impl InternSlice for &'_ [T] { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - self.intern() - } -} - -impl InternSlice for &'_ mut [T] { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - self.intern() - } -} - -impl InternSlice for [T; N] { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - (&self).intern_slice() - } -} - -impl InternSlice for Box<[T; N]> { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - let this: Box<[T]> = self; - this.intern_slice() - } -} - -impl InternSlice for &'_ [T; N] { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - let this: &[T] = self; - this.intern() - } -} - -impl InternSlice for &'_ mut [T; N] { - type Element = T; - fn intern_slice(self) -> Interned<[Self::Element]> { - let this: &[T] = self; - this.intern() +impl InternedCompare for str { + type InternedCompareKey = PtrEqWithMetadata; + fn interned_compare_key_ref(this: &Self) -> Self::InternedCompareKey { + PtrEqWithMetadata(this) } } pub trait Intern: Any + Send + Sync { fn intern(&self) -> Interned; - fn intern_deref(self) -> Interned - where - Self: Sized + Deref>, - { - Self::Target::intern_owned(self) - } fn intern_sized(self) -> Interned where Self: Clone, @@ -569,30 +316,6 @@ pub trait Intern: Any + Send + Sync { } } -impl From> for Interned { - fn from(value: Cow<'_, T>) -> Self { - Intern::intern_cow(value) - } -} - -impl From<&'_ T> for Interned { - fn from(value: &'_ T) -> Self { - Intern::intern(value) - } -} - -impl From for Interned { - fn from(value: T) -> Self { - Intern::intern_sized(value) - } -} - -impl From> for Cow<'_, T> { - fn from(value: Interned) -> Self { - Cow::Borrowed(Interned::into_inner(value)) - } -} - struct InternerState { table: HashTable<&'static T>, hasher: DefaultBuildHasher, @@ -658,6 +381,12 @@ impl Interner { } } +impl Interner { + fn intern_str(&self, value: Cow<'_, str>) -> Interned { + self.intern(|value| value.into_owned().leak(), value) + } +} + pub struct Interned { inner: &'static T, } @@ -687,12 +416,6 @@ forward_fmt_trait!(Pointer); forward_fmt_trait!(UpperExp); forward_fmt_trait!(UpperHex); -impl, U: ?Sized> AsRef for Interned { - fn as_ref(&self) -> &U { - T::as_ref(self) - } -} - #[derive(Clone, Debug)] pub struct InternedSliceIter { slice: Interned<[T]>, @@ -762,57 +485,6 @@ where } } -impl FromIterator for Interned -where - String: FromIterator, -{ - fn from_iter>(iter: T) -> Self { - String::from_iter(iter).intern_deref() - } -} - -impl FromIterator for Interned -where - PathBuf: FromIterator, -{ - fn from_iter>(iter: T) -> Self { - PathBuf::from_iter(iter).intern_deref() - } -} - -impl FromIterator for Interned -where - OsString: FromIterator, -{ - fn from_iter>(iter: T) -> Self { - OsString::from_iter(iter).intern_deref() - } -} - -impl From> for clap::builder::Str { - fn from(value: Interned) -> Self { - Interned::into_inner(value).into() - } -} - -impl From> for clap::builder::OsStr { - fn from(value: Interned) -> Self { - Interned::into_inner(value).into() - } -} - -impl From> for clap::builder::StyledStr { - fn from(value: Interned) -> Self { - Interned::into_inner(value).into() - } -} - -impl From> for clap::Id { - fn from(value: Interned) -> Self { - Interned::into_inner(value).into() - } -} - impl From> for Vec { fn from(value: Interned<[T]>) -> Self { Vec::from(&*value) @@ -825,12 +497,24 @@ impl From> for Box<[T]> { } } +impl From> for String { + fn from(value: Interned) -> Self { + String::from(&*value) + } +} + impl Default for Interned<[I]> where [I]: Intern, { fn default() -> Self { - Intern::intern(&[]) + [][..].intern() + } +} + +impl Default for Interned { + fn default() -> Self { + "".intern() } } @@ -961,6 +645,15 @@ impl<'de> Deserialize<'de> for Interned { } } +impl<'de> Deserialize<'de> for Interned { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + String::deserialize(deserializer).map(Intern::intern_owned) + } +} + impl Intern for T { fn intern(&self) -> Interned { Self::intern_cow(Cow::Borrowed(self)) @@ -1021,6 +714,26 @@ impl Intern for BitSlice { } } +impl Intern for str { + fn intern(&self) -> Interned { + Self::intern_cow(Cow::Borrowed(self)) + } + + fn intern_owned(this: ::Owned) -> Interned + where + Self: ToOwned, + { + Self::intern_cow(Cow::Owned(this)) + } + + fn intern_cow(this: Cow<'_, Self>) -> Interned + where + Self: ToOwned, + { + Interner::get().intern_str(this) + } +} + pub trait MemoizeGeneric: 'static + Send + Sync + Hash + Eq + Copy { type InputRef<'a>: 'a + Send + Sync + Hash + Copy; type InputOwned: 'static + Send + Sync; diff --git a/crates/fayalite/src/lib.rs b/crates/fayalite/src/lib.rs index 156aeed..932464b 100644 --- a/crates/fayalite/src/lib.rs +++ b/crates/fayalite/src/lib.rs @@ -4,18 +4,6 @@ // TODO: enable: // #![warn(missing_docs)] -#![deny( - rustdoc::bare_urls, - rustdoc::broken_intra_doc_links, - rustdoc::invalid_codeblock_attributes, - rustdoc::invalid_html_tags, - rustdoc::invalid_rust_codeblocks, - rustdoc::private_doc_tests, - rustdoc::private_intra_doc_links, - rustdoc::redundant_explicit_links, - rustdoc::unescaped_backticks -)] - //! [Main Documentation][_docs] extern crate self as fayalite; @@ -86,135 +74,6 @@ macro_rules! __cfg_expansion_helper { pub use fayalite_proc_macros::hdl_module; #[doc(inline)] -/// The `#[hdl]` attribute is supported on several different kinds of [Rust Items](https://doc.rust-lang.org/reference/items.html): -/// -/// # Functions and Methods -/// Enable's the stuff that you can use inside a [module's body](crate::_docs::modules::module_bodies), -/// but without being a module or changing the function's signature. -/// The only exception is that you can't use stuff that requires the automatically-provided `m` variable. -/// -/// # Structs -// TODO: expand on struct docs -/// e.g.: -/// ``` -/// # use fayalite::prelude::*; -/// # #[hdl] -/// # pub struct OtherStruct {} -/// #[hdl] -/// pub struct MyStruct { -/// #[hdl(flip)] -/// pub a: UInt<5>, -/// pub b: Bool, -/// #[hdl(flip)] -/// pub c: OtherStruct, -/// } -/// ``` -/// -/// # Enums -// TODO: expand on enum docs -/// e.g.: -/// ``` -/// # use fayalite::prelude::*; -/// # #[hdl] -/// # pub struct MyStruct {} -/// #[hdl] -/// pub enum MyEnum { -/// A(UInt<3>), -/// B, -/// C(MyStruct), -/// } -/// ``` -/// -/// # Type Aliases -/// -/// There's three different ways you can create a type alias: -/// -/// # Normal Type Alias -/// -/// This works exactly how you'd expect: -/// ``` -/// # use fayalite::prelude::*; -/// # #[hdl] -/// # pub struct MyStruct { -/// # v: T, -/// # } -/// #[hdl] -/// pub type MyType = MyStruct; -/// -/// // you can then use Fayalite's standard syntax for creating dynamic types at runtime: -/// -/// let ty = MyType[UInt[3]]; -/// assert_eq!(ty, MyStruct[UInt[3]]); -/// ``` -/// -/// # Type Alias that gets a [`Type`] from a [`PhantomConst`] -/// -/// This allows you to use some computed property of a [`PhantomConst`] to get a [`Type`] that you can use in other #[hdl] types. -/// -/// ``` -/// # use fayalite::prelude::*; -/// #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)] -/// pub struct Config { -/// pub foo: usize, -/// pub bar: Bundle, -/// } -/// -/// // the expression inside `get` is called with `Interned` and returns `Array` -/// #[hdl(get(|config| Array[config.bar][config.foo]))] -/// pub type GetMyArray> = Array; -/// -/// // you can then use it in other types: -/// -/// #[hdl(no_static)] -/// pub struct WrapMyArray> { -/// pub my_array: GetMyArray

, -/// } -/// -/// // you can then use Fayalite's standard syntax for creating dynamic types at runtime: -/// let bar = Bundle::new(Default::default()); -/// let config = PhantomConst::new_sized(Config { foo: 12, bar }); -/// let ty = WrapMyArray[config]; -/// assert_eq!(ty.my_array, Array[bar][12]); -/// ``` -/// -/// # Type Alias that gets a [`Size`] from a [`PhantomConst`] -/// -/// This allows you to use some computed property of a [`PhantomConst`] to get a [`Size`] that you can use in other #[hdl] types. -/// -/// ``` -/// # use fayalite::prelude::*; -/// # #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)] -/// # pub struct ConfigItem {} -/// # impl ConfigItem { -/// # pub fn new() -> Self { -/// # Self {} -/// # } -/// # } -/// #[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)] -/// pub struct Config { -/// pub items: Vec, -/// } -/// -/// // the expression inside `get` is called with `Interned` and returns `usize` (not DynSize) -/// #[hdl(get(|config| config.items.len()))] -/// pub type GetItemsLen> = DynSize; // must be DynSize -/// -/// // you can then use it in other types: -/// -/// #[hdl(no_static)] -/// pub struct FlagPerItem> { -/// pub flags: ArrayType>, -/// } -/// -/// // you can then use Fayalite's standard syntax for creating dynamic types at runtime: -/// let config = PhantomConst::new_sized(Config { items: vec![ConfigItem::new(); 5] }); -/// let ty = FlagPerItem[config]; -/// assert_eq!(ty.flags, Array[Bool][5]); -/// ``` -/// -/// [`PhantomConst`]: crate::phantom_const::PhantomConst -/// [`Size`]: crate::int::Size -/// [`Type`]: crate::ty::Type pub use fayalite_proc_macros::hdl; pub use bitvec; @@ -228,8 +87,8 @@ pub mod _docs; pub mod annotations; pub mod array; -pub mod build; pub mod bundle; +pub mod cli; pub mod clock; pub mod enum_; pub mod expr; @@ -240,7 +99,6 @@ pub mod intern; pub mod memory; pub mod module; pub mod phantom_const; -pub mod platform; pub mod prelude; pub mod reg; pub mod reset; @@ -249,5 +107,4 @@ pub mod source_location; pub mod testing; pub mod ty; pub mod util; -pub mod vendor; pub mod wire; diff --git a/crates/fayalite/src/memory.rs b/crates/fayalite/src/memory.rs index 83e7437..46eb59b 100644 --- a/crates/fayalite/src/memory.rs +++ b/crates/fayalite/src/memory.rs @@ -7,10 +7,7 @@ use crate::{ array::{Array, ArrayType}, bundle::{Bundle, BundleType}, clock::Clock, - expr::{ - Expr, Flow, ToExpr, ToLiteralBits, ValueType, ops::BundleLiteral, repeat, - value_category::ValueCategoryExpr, - }, + expr::{Expr, Flow, ToExpr, ToLiteralBits, ops::BundleLiteral, repeat}, hdl, int::{Bool, DynSize, Size, UInt, UIntType}, intern::{Intern, Interned}, @@ -369,16 +366,10 @@ impl fmt::Debug for MemPort { } } -impl ValueType for MemPort { - type Type = T::Port; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> T::Port { +impl MemPort { + pub fn ty(&self) -> T::Port { T::port_ty(self) } -} - -impl MemPort { pub fn source_location(&self) -> SourceLocation { self.source_location } @@ -839,7 +830,7 @@ impl MemBuilder { depth: Option, initial_value: Expr, ) -> Interned { - let initial_value_ty = initial_value.ty(); + let initial_value_ty = Expr::ty(initial_value); assert_eq!( *mem_element_type, Element::from_canonical(initial_value_ty.element()), @@ -1020,7 +1011,7 @@ impl MemBuilder { target.depth, initial_value, )); - target.depth = Some(initial_value.ty().len()); + target.depth = Some(Expr::ty(initial_value).len()); } #[track_caller] pub fn initial_value_bit_slice(&mut self, initial_value: Interned) { diff --git a/crates/fayalite/src/module.rs b/crates/fayalite/src/module.rs index 9d1a0e7..a81893d 100644 --- a/crates/fayalite/src/module.rs +++ b/crates/fayalite/src/module.rs @@ -8,19 +8,17 @@ use crate::{ clock::{Clock, ClockDomain}, enum_::{Enum, EnumMatchVariantsIter, EnumType}, expr::{ - Expr, Flow, ToExpr, ValueType, + Expr, Flow, ToExpr, ops::VariantAccess, target::{ GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, }, - value_category::ValueCategoryExpr, }, formal::FormalKind, int::{Bool, DynSize, Size}, intern::{Intern, Interned}, memory::{Mem, MemBuilder, MemBuilderTarget, PortName}, - platform::PlatformIOBuilder, reg::Reg, reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset}, sim::{ExternModuleSimGenerator, ExternModuleSimulation}, @@ -42,6 +40,7 @@ use std::{ marker::PhantomData, mem, num::NonZeroU64, + ops::Deref, rc::Rc, sync::atomic::AtomicU64, }; @@ -67,8 +66,6 @@ pub trait ModuleBuildingStatus: type ModuleBody: fmt::Debug; type StmtAnnotations: 'static + Send + Sync + Copy + Eq + Hash + fmt::Debug; type ModuleIOAnnotations; - type ExternModuleParameters: fmt::Debug; - type ExternModuleClocksForPast: fmt::Debug; } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] @@ -81,8 +78,6 @@ impl ModuleBuildingStatus for ModuleBuilt { type ModuleBody = Block; type StmtAnnotations = Interned<[TargetedAnnotation]>; type ModuleIOAnnotations = Interned<[TargetedAnnotation]>; - type ExternModuleParameters = Interned<[ExternModuleParameter]>; - type ExternModuleClocksForPast = Interned<[Target]>; } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] @@ -95,8 +90,6 @@ impl ModuleBuildingStatus for ModuleBuilding { type ModuleBody = BuilderModuleBody; type StmtAnnotations = (); type ModuleIOAnnotations = Vec; - type ExternModuleParameters = Vec; - type ExternModuleClocksForPast = Vec; } #[derive(Debug)] @@ -206,7 +199,7 @@ impl StmtConnect { source_location, } = *self; assert!( - lhs.ty().can_connect(rhs.ty()), + Expr::ty(lhs).can_connect(Expr::ty(rhs)), "can't connect types that are not equivalent:\nlhs type:\n{lhs_orig_ty:?}\nrhs type:\n{rhs_orig_ty:?}\nat: {source_location}", ); assert!( @@ -220,14 +213,14 @@ impl StmtConnect { match Expr::flow(rhs) { Flow::Source | Flow::Duplex => {} Flow::Sink => assert!( - rhs.ty().is_passive(), + Expr::ty(rhs).is_passive(), "can't connect from sink with non-passive type\nat: {source_location}" ), } } #[track_caller] fn assert_validity(&self) { - self.assert_validity_with_original_types(self.lhs.ty(), self.rhs.ty()); + self.assert_validity_with_original_types(Expr::ty(self.lhs), Expr::ty(self.rhs)); } } @@ -332,7 +325,7 @@ impl Copy for StmtMatch {} impl StmtMatch { #[track_caller] fn assert_validity(&self) { - assert_eq!(self.expr.ty().variants().len(), self.blocks.len()); + assert_eq!(Expr::ty(self.expr).variants().len(), self.blocks.len()); } } @@ -766,15 +759,6 @@ impl fmt::Debug for Instance { } } -impl ValueType for Instance { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> T { - self.instantiated.io_ty() - } -} - impl Instance { pub fn canonical(self) -> Instance { let Self { @@ -838,6 +822,9 @@ impl Instance { pub fn must_connect_to(&self) -> bool { true } + pub fn ty(&self) -> T { + self.instantiated.io_ty() + } } #[derive(Clone, PartialEq, Eq, Hash, Debug)] @@ -846,8 +833,6 @@ pub struct AnnotatedModuleIO { pub module_io: ModuleIO, } -impl Copy for AnnotatedModuleIO {} - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum ModuleKind { Extern, @@ -1092,65 +1077,26 @@ impl From for ModuleBody { } } -#[track_caller] -fn validate_clock_for_past( - clock_for_past: Option, - module_io: &[AnnotatedModuleIO], -) -> Target { - if let Some(clock_for_past) = clock_for_past { - assert_eq!( - clock_for_past.canonical_ty(), - Clock.canonical(), - "clock_for_past: clock is not of type Clock", - ); - if clock_for_past - .base() - .module_io() - .is_some_and(|v| module_io.iter().any(|module_io| module_io.module_io == *v)) - { - let mut target = clock_for_past; - while let Target::Child(child) = target { - match *child.path_element() { - TargetPathElement::BundleField(_) | TargetPathElement::ArrayElement(_) => {} - TargetPathElement::DynArrayElement(_) => { - panic!( - "clock_for_past: clock must be a static target (you can't use `Expr` array indexes):\n{clock_for_past:?}" - ); - } - } - target = *child.parent(); - } - return clock_for_past; - } - } - panic!("clock_for_past: clock must be some part of this module's I/O:\n{clock_for_past:?}"); -} - #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] -pub struct ExternModuleBody { +pub struct ExternModuleBody< + P: Deref = Interned<[ExternModuleParameter]>, +> { pub verilog_name: Interned, - pub parameters: S::ExternModuleParameters, - /// [`Clock`]s that the [`Simulation`] will store the past values of all [`ModuleIO`] for. - /// - /// [`Simulation`]: crate::sim::Simulation - pub clocks_for_past: S::ExternModuleClocksForPast, + pub parameters: P, pub simulation: Option, } -impl From> for ExternModuleBody { - fn from(value: ExternModuleBody) -> Self { +impl From>> for ExternModuleBody { + fn from(value: ExternModuleBody>) -> Self { let ExternModuleBody { verilog_name, parameters, - clocks_for_past, simulation, } = value; let parameters = Intern::intern_owned(parameters); - let clocks_for_past = Intern::intern_owned(clocks_for_past); Self { verilog_name, parameters, - clocks_for_past, simulation, } } @@ -1163,12 +1109,15 @@ impl From for ModuleBody { } #[derive(Debug)] -pub enum ModuleBody { +pub enum ModuleBody< + S: ModuleBuildingStatus = ModuleBuilt, + P: Deref = Interned<[ExternModuleParameter]>, +> { Normal(NormalModuleBody), - Extern(ExternModuleBody), + Extern(ExternModuleBody

), } -pub(crate) type ModuleBodyBuilding = ModuleBody; +pub(crate) type ModuleBodyBuilding = ModuleBody>; impl ModuleBodyBuilding { pub(crate) fn builder_normal_body_opt( @@ -1189,7 +1138,9 @@ impl ModuleBodyBuilding { } } #[track_caller] - pub(crate) fn builder_extern_body(&mut self) -> &mut ExternModuleBody { + pub(crate) fn builder_extern_body( + &mut self, + ) -> &mut ExternModuleBody> { if let Self::Extern(v) = self { v } else { @@ -1261,12 +1212,6 @@ pub struct Module { module_annotations: Interned<[Annotation]>, } -impl AsRef for Module { - fn as_ref(&self) -> &Self { - self - } -} - #[derive(Default)] struct DebugFmtModulesState { seen: HashSet, @@ -1343,13 +1288,11 @@ impl fmt::Debug for DebugModuleBody { ModuleBody::Extern(ExternModuleBody { verilog_name, parameters, - clocks_for_past, simulation, }) => { debug_struct .field("verilog_name", verilog_name) .field("parameters", parameters) - .field("clocks_for_past", clocks_for_past) .field("simulation", simulation); } } @@ -1828,13 +1771,8 @@ impl AssertValidityState { ModuleBody::Extern(ExternModuleBody { verilog_name: _, parameters: _, - clocks_for_past, simulation: _, - }) => { - for clock_for_past in clocks_for_past { - validate_clock_for_past(Some(clock_for_past), &self.module.module_io); - } - } + }) => {} ModuleBody::Normal(NormalModuleBody { body }) => { let body = self.make_block_index(body); assert_eq!(body, 0); @@ -1864,17 +1802,9 @@ impl Module { match &mut body { ModuleBody::Normal(_) => {} ModuleBody::Extern(ExternModuleBody { - verilog_name: _, - parameters: _, - clocks_for_past, simulation: Some(simulation), + .. }) => { - let mut clocks_for_past_set = HashSet::default(); - *clocks_for_past = clocks_for_past - .iter() - .copied() - .filter(|clock_for_past| clocks_for_past_set.insert(*clock_for_past)) - .collect(); if module_io.iter().any(|io| { !simulation .sim_io_to_generator_map @@ -2035,7 +1965,7 @@ impl RegBuilder { init: _, ty: _, } = self; - let ty = init.ty(); + let ty = Expr::ty(init); RegBuilder { name, source_location, @@ -2181,27 +2111,6 @@ impl ModuleBuilder { self.output_with_loc(implicit_name.0, SourceLocation::caller(), ty) } #[track_caller] - pub fn add_platform_io_with_loc( - &self, - name: &str, - source_location: SourceLocation, - platform_io_builder: PlatformIOBuilder<'_>, - ) -> Expr { - platform_io_builder.add_platform_io(name, source_location, self) - } - #[track_caller] - pub fn add_platform_io( - &self, - implicit_name: ImplicitName<'_>, - platform_io_builder: PlatformIOBuilder<'_>, - ) -> Expr { - self.add_platform_io_with_loc( - implicit_name.0, - SourceLocation::caller(), - platform_io_builder, - ) - } - #[track_caller] pub fn run( name: &str, module_kind: ModuleKind, @@ -2247,7 +2156,6 @@ impl ModuleBuilder { ModuleKind::Extern => ModuleBody::Extern(ExternModuleBody { verilog_name: name.0, parameters: vec![], - clocks_for_past: vec![], simulation: None, }), ModuleKind::Normal => ModuleBody::Normal(NormalModuleBody { @@ -2370,20 +2278,6 @@ impl ModuleBuilder { value: ExternModuleParameterValue::RawVerilog(raw_verilog.intern()), }); } - /// registers a [`Clock`] so you can use it with the [`ExternModuleSimulationState::read_past()`] family of functions. - /// - /// [`ExternModuleSimulationState::read_past()`]: crate::sim::ExternModuleSimulationState::read_past() - #[track_caller] - pub fn register_clock_for_past(&self, clock_for_past: impl ToExpr) { - let clock_for_past = clock_for_past.to_expr().target().as_deref().copied(); - let mut impl_ = self.impl_.borrow_mut(); - let clock_for_past = validate_clock_for_past(clock_for_past, &impl_.io); - impl_ - .body - .builder_extern_body() - .clocks_for_past - .push(clock_for_past); - } #[track_caller] pub fn extern_module_simulation(&self, generator: G) { let mut impl_ = self.impl_.borrow_mut(); @@ -2604,7 +2498,7 @@ pub fn enum_match_variants_helper( ModuleBuilder::with(|m| { let mut impl_ = m.impl_.borrow_mut(); let body = impl_.body.builder_normal_body(); - let enum_ty = base.ty(); + let enum_ty = Expr::ty(base); let outer_block: BlockId = m.block_stack.top(); let blocks = Interned::from_iter(enum_ty.variants().iter().map(|_| body.new_block())); body.block(outer_block).stmts.push( @@ -2656,7 +2550,7 @@ pub fn connect_any_with_loc( rhs, source_location, }; - connect.assert_validity_with_original_types(lhs_orig.ty(), rhs_orig.ty()); + connect.assert_validity_with_original_types(Expr::ty(lhs_orig), Expr::ty(rhs_orig)); ModuleBuilder::with(|m| { m.impl_ .borrow_mut() @@ -2771,7 +2665,7 @@ pub fn memory_with_init_and_loc( source_location: SourceLocation, ) -> MemBuilder { let initial_value = initial_value.to_expr(); - let mut retval = memory_array_with_loc(name, initial_value.ty(), source_location); + let mut retval = memory_array_with_loc(name, Expr::ty(initial_value), source_location); retval.initial_value(initial_value); retval } @@ -2814,15 +2708,6 @@ pub struct ModuleIO { source_location: SourceLocation, } -impl ValueType for ModuleIO { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } -} - impl fmt::Debug for ModuleIO { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ModuleIO") @@ -2850,22 +2735,6 @@ impl ModuleIO { source_location, } } - pub fn from_canonical(canonical_module_io: ModuleIO) -> Self { - let ModuleIO { - containing_module_name, - bundle_field, - id, - ty, - source_location, - } = canonical_module_io; - Self { - containing_module_name, - bundle_field, - id, - ty: T::from_canonical(ty), - source_location, - } - } pub fn bundle_field(&self) -> BundleField { self.bundle_field } @@ -2924,6 +2793,9 @@ impl ModuleIO { unreachable!() } } + pub fn ty(&self) -> T { + self.ty + } } #[derive(PartialEq, Eq, Hash, Clone, Copy)] diff --git a/crates/fayalite/src/module/transform/deduce_resets.rs b/crates/fayalite/src/module/transform/deduce_resets.rs index 61167fd..57197ad 100644 --- a/crates/fayalite/src/module/transform/deduce_resets.rs +++ b/crates/fayalite/src/module/transform/deduce_resets.rs @@ -6,7 +6,7 @@ use crate::{ bundle::{BundleField, BundleType}, enum_::{EnumType, EnumVariant}, expr::{ - ExprEnum, ValueType, + ExprEnum, ops::{self, ArrayLiteral}, target::{ Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField, @@ -521,7 +521,7 @@ impl State { Entry::Vacant(entry) => ( *entry.insert(Resets::with_new_nodes( &mut self.reset_graph, - expr.ty(), + Expr::ty(expr), source_location, )), true, @@ -1020,7 +1020,7 @@ fn cast_bit_op( } macro_rules! match_arg_ty { ($($Variant:ident),*) => { - *match arg.ty() { + *match Expr::ty(arg) { CanonicalType::Array(_) | CanonicalType::Enum(_) | CanonicalType::Bundle(_) @@ -1660,8 +1660,7 @@ impl RunPassDispatch for AnyReg { let clock_domain = Expr::::from_canonical( Expr::canonical(reg.clock_domain()).run_pass(pass_args)?.0, ); - match clock_domain - .ty() + match Expr::ty(clock_domain) .field_by_name("rst".intern()) .expect("ClockDomain has rst field") .ty @@ -1803,7 +1802,6 @@ impl_run_pass_clone!([] ExternModuleParameter); impl_run_pass_clone!([] SIntValue); impl_run_pass_clone!([] std::ops::Range); impl_run_pass_clone!([] UIntValue); -impl_run_pass_clone!([] crate::vendor::xilinx::XilinxAnnotation); impl_run_pass_copy!([] BlackBoxInlineAnnotation); impl_run_pass_copy!([] BlackBoxPathAnnotation); impl_run_pass_copy!([] bool); @@ -2074,7 +2072,6 @@ impl_run_pass_for_struct! { impl[] RunPass for ExternModuleBody { verilog_name: _, parameters: _, - clocks_for_past: _, simulation: _, } } @@ -2220,7 +2217,6 @@ impl_run_pass_for_enum! { BlackBoxPath(v), DocString(v), CustomFirrtl(v), - Xilinx(v), } } diff --git a/crates/fayalite/src/module/transform/simplify_enums.rs b/crates/fayalite/src/module/transform/simplify_enums.rs index 8902921..ccdecf6 100644 --- a/crates/fayalite/src/module/transform/simplify_enums.rs +++ b/crates/fayalite/src/module/transform/simplify_enums.rs @@ -5,12 +5,12 @@ use crate::{ bundle::{Bundle, BundleField, BundleType}, enum_::{Enum, EnumType, EnumVariant}, expr::{ - CastBitsTo, CastTo, CastToBits, Expr, ExprEnum, HdlPartialEq, ToExpr, ValueType, + CastBitsTo, CastTo, CastToBits, Expr, ExprEnum, HdlPartialEq, ToExpr, ops::{self, EnumLiteral}, }, hdl, int::UInt, - intern::{Intern, InternSlice, Interned, Memoize}, + intern::{Intern, Interned, Memoize}, memory::{DynPortType, Mem, MemPort}, module::{ Block, Id, Module, NameId, ScopedNameId, Stmt, StmtConnect, StmtIf, StmtMatch, StmtWire, @@ -22,7 +22,6 @@ use crate::{ wire::Wire, }; use core::fmt; -use serde::{Deserialize, Serialize}; #[derive(Debug)] pub enum SimplifyEnumsError { @@ -528,7 +527,7 @@ fn connect_port( rhs: Expr, source_location: SourceLocation, ) { - if lhs.ty() == rhs.ty() { + if Expr::ty(lhs) == Expr::ty(rhs) { stmts.push( StmtConnect { lhs, @@ -539,7 +538,7 @@ fn connect_port( ); return; } - match (lhs.ty(), rhs.ty()) { + match (Expr::ty(lhs), Expr::ty(rhs)) { (CanonicalType::Bundle(lhs_type), CanonicalType::UInt(_) | CanonicalType::Bool(_)) => { let lhs = Expr::::from_canonical(lhs); for field in lhs_type.fields() { @@ -586,8 +585,8 @@ fn connect_port( | (CanonicalType::PhantomConst(_), _) | (CanonicalType::DynSimOnly(_), _) => unreachable!( "trying to connect memory ports:\n{:?}\n{:?}", - lhs.ty(), - rhs.ty(), + Expr::ty(lhs), + Expr::ty(rhs), ), } } @@ -607,23 +606,20 @@ fn match_int_tag( }; }; let mut retval = StmtIf { - cond: int_tag_expr.cmp_eq( - int_tag_expr - .ty() - .from_int_wrapping(next_to_last_variant_index), - ), + cond: int_tag_expr + .cmp_eq(Expr::ty(int_tag_expr).from_int_wrapping(next_to_last_variant_index)), source_location, blocks: [next_to_last_block, last_block], }; for (variant_index, block) in blocks_iter.rev() { retval = StmtIf { - cond: int_tag_expr.cmp_eq(int_tag_expr.ty().from_int_wrapping(variant_index)), + cond: int_tag_expr.cmp_eq(Expr::ty(int_tag_expr).from_int_wrapping(variant_index)), source_location, blocks: [ block, Block { memories: Default::default(), - stmts: [Stmt::from(retval)].intern_slice(), + stmts: [Stmt::from(retval)][..].intern(), }, ], }; @@ -660,7 +656,7 @@ impl Folder for State { ExprEnum::VariantAccess(op) => { let folded_base_expr = Expr::canonical(op.base()).fold(self)?; Ok(*Expr::expr_enum(self.handle_variant_access( - op.base().ty(), + Expr::ty(op.base()), folded_base_expr, op.variant_index(), )?)) @@ -870,7 +866,7 @@ impl Folder for State { }) => { let folded_expr = Expr::canonical(expr).fold(self)?; let folded_blocks = blocks.fold(self)?; - self.handle_match(expr.ty(), folded_expr, source_location, &folded_blocks) + self.handle_match(Expr::ty(expr), folded_expr, source_location, &folded_blocks) } Stmt::Connect(StmtConnect { lhs, @@ -881,8 +877,8 @@ impl Folder for State { let folded_rhs = rhs.fold(self)?; let mut output_stmts = vec![]; self.handle_stmt_connect( - lhs.ty(), - rhs.ty(), + Expr::ty(lhs), + Expr::ty(rhs), folded_lhs, folded_rhs, source_location, @@ -959,15 +955,12 @@ impl Folder for State { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, clap::ValueEnum, Serialize, Deserialize)] -#[serde(rename_all = "kebab-case")] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, clap::ValueEnum)] pub enum SimplifyEnumsKind { SimplifyToEnumsWithNoBody, #[clap(name = "replace-with-bundle-of-uints")] - #[serde(rename = "replace-with-bundle-of-uints")] ReplaceWithBundleOfUInts, #[clap(name = "replace-with-uint")] - #[serde(rename = "replace-with-uint")] ReplaceWithUInt, } diff --git a/crates/fayalite/src/module/transform/simplify_memories.rs b/crates/fayalite/src/module/transform/simplify_memories.rs index d741836..35f186d 100644 --- a/crates/fayalite/src/module/transform/simplify_memories.rs +++ b/crates/fayalite/src/module/transform/simplify_memories.rs @@ -4,7 +4,7 @@ use crate::{ annotations::TargetedAnnotation, array::Array, bundle::{Bundle, BundleType}, - expr::{CastBitsTo, CastToBits, Expr, ExprEnum, ToExpr, ValueType}, + expr::{CastBitsTo, CastToBits, Expr, ExprEnum, ToExpr}, int::{Bool, SInt, Size, UInt}, intern::{Intern, Interned}, memory::{Mem, MemPort, PortType}, @@ -530,7 +530,7 @@ impl ModuleState { connect_read( output_stmts, wire_read, - Expr::::from_canonical(port_read).cast_bits_to(wire_read.ty()), + Expr::::from_canonical(port_read).cast_bits_to(Expr::ty(wire_read)), ); }; let connect_write_enum = diff --git a/crates/fayalite/src/module/transform/visit.rs b/crates/fayalite/src/module/transform/visit.rs index 2869a49..44aabc3 100644 --- a/crates/fayalite/src/module/transform/visit.rs +++ b/crates/fayalite/src/module/transform/visit.rs @@ -11,7 +11,7 @@ use crate::{ clock::Clock, enum_::{Enum, EnumType, EnumVariant}, expr::{ - Expr, ExprEnum, ValueType, ops, + Expr, ExprEnum, ops, target::{ Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField, TargetPathDynArrayElement, TargetPathElement, @@ -33,9 +33,6 @@ use crate::{ sim::{ExternModuleSimulation, value::DynSimOnly}, source_location::SourceLocation, ty::{CanonicalType, Type}, - vendor::xilinx::{ - XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation, - }, wire::Wire, }; use num_bigint::{BigInt, BigUint}; diff --git a/crates/fayalite/src/phantom_const.rs b/crates/fayalite/src/phantom_const.rs index 32e9d6b..b852056 100644 --- a/crates/fayalite/src/phantom_const.rs +++ b/crates/fayalite/src/phantom_const.rs @@ -2,10 +2,13 @@ // See Notices.txt for copyright information use crate::{ - expr::{Expr, HdlPartialEqImpl, HdlPartialOrdImpl, ToExpr, ValueType}, + expr::{ + Expr, ToExpr, + ops::{ExprPartialEq, ExprPartialOrd}, + }, int::Bool, intern::{Intern, Interned, InternedCompare, LazyInterned, LazyInternedTrait, Memoize}, - sim::value::{SimValue, ToSimValue, ToSimValueWithType}, + sim::value::{SimValue, SimValuePartialEq, ToSimValue, ToSimValueWithType}, source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, @@ -19,7 +22,6 @@ use serde::{ }; use std::{ any::Any, - borrow::Cow, fmt, hash::{Hash, Hasher}, marker::PhantomData, @@ -129,7 +131,7 @@ impl Index for PhantomConstWithoutGenerics { type Output = PhantomConst; fn index(&self, value: T) -> &Self::Output { - Interned::into_inner(PhantomConst::new(&value).intern_sized()) + Interned::into_inner(PhantomConst::new(value.intern()).intern_sized()) } } @@ -220,26 +222,11 @@ impl Memoize for PhantomConstCanonicalMemoize PhantomConst { - pub fn new_interned(value: Interned) -> Self { + pub fn new(value: Interned) -> Self { Self { value: LazyInterned::Interned(value), } } - pub fn new_sized(value: T) -> Self - where - T: Clone, - { - Self::new_interned(value.intern_sized()) - } - pub fn new(value: &T) -> Self { - Self::new_interned(value.intern()) - } - pub fn new_deref>(value: U) -> Self - where - T: ToOwned, - { - Self::new_interned(value.intern_deref()) - } pub const fn new_lazy(v: &'static dyn LazyInternedTrait) -> Self { Self { value: LazyInterned::new_lazy(v), @@ -258,7 +245,7 @@ impl PhantomConst { if let Some(&retval) = ::downcast_ref::(&self) { return retval; } - ::new_interned( + ::new( PhantomConstCanonicalMemoize::(PhantomData).get_owned(self.get()), ) } @@ -266,7 +253,7 @@ impl PhantomConst { if let Some(&retval) = ::downcast_ref::(&canonical_type) { return retval; } - Self::new_interned( + Self::new( PhantomConstCanonicalMemoize::(PhantomData).get_owned(canonical_type.get()), ) } @@ -359,9 +346,7 @@ impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for PhantomConst { D: Deserializer<'de>, { match SerdeType::::deserialize(deserializer)? { - SerdeCanonicalType::PhantomConst(SerdePhantomConst(value)) => { - Ok(Self::new_interned(value)) - } + SerdeCanonicalType::PhantomConst(SerdePhantomConst(value)) => Ok(Self::new(value)), ty => Err(Error::invalid_value( serde::de::Unexpected::Other(ty.as_serde_unexpected_str()), &"a PhantomConst", @@ -370,102 +355,50 @@ impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for PhantomConst { } } -impl HdlPartialEqImpl for PhantomConst { - #[track_caller] - fn cmp_value_eq( - lhs: Self, - _lhs_value: Cow<'_, Self::SimValue>, - rhs: Self, - _rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - assert_eq!(lhs, rhs); - true - } - - #[track_caller] - fn cmp_expr_eq(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(lhs.ty(), rhs.ty()); +impl ExprPartialEq for PhantomConst { + fn cmp_eq(lhs: Expr, rhs: Expr) -> Expr { + assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); true.to_expr() } - #[track_caller] - fn cmp_expr_ne(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(lhs.ty(), rhs.ty()); + fn cmp_ne(lhs: Expr, rhs: Expr) -> Expr { + assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); false.to_expr() } } -impl HdlPartialOrdImpl for PhantomConst { - #[track_caller] - fn cmp_value_lt( - lhs: Self, - _lhs_value: Cow<'_, Self::SimValue>, - rhs: Self, - _rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - assert_eq!(lhs, rhs); - false - } - - #[track_caller] - fn cmp_value_le( - lhs: Self, - _lhs_value: Cow<'_, Self::SimValue>, - rhs: Self, - _rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - assert_eq!(lhs, rhs); - true - } - - #[track_caller] - fn cmp_value_gt( - lhs: Self, - _lhs_value: Cow<'_, Self::SimValue>, - rhs: Self, - _rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - assert_eq!(lhs, rhs); - false - } - - #[track_caller] - fn cmp_value_ge( - lhs: Self, - _lhs_value: Cow<'_, Self::SimValue>, - rhs: Self, - _rhs_value: Cow<'_, ::SimValue>, - ) -> bool { - assert_eq!(lhs, rhs); - true - } - - #[track_caller] - fn cmp_expr_lt(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(lhs.ty(), rhs.ty()); +impl ExprPartialOrd for PhantomConst { + fn cmp_lt(lhs: Expr, rhs: Expr) -> Expr { + assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); false.to_expr() } - #[track_caller] - fn cmp_expr_le(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(lhs.ty(), rhs.ty()); + fn cmp_le(lhs: Expr, rhs: Expr) -> Expr { + assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); true.to_expr() } - #[track_caller] - fn cmp_expr_gt(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(lhs.ty(), rhs.ty()); + fn cmp_gt(lhs: Expr, rhs: Expr) -> Expr { + assert_eq!(Expr::ty(lhs), Expr::ty(rhs)); false.to_expr() } - #[track_caller] - fn cmp_expr_ge(lhs: Expr, rhs: Expr) -> Expr { - assert_eq!(lhs.ty(), rhs.ty()); + 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) } @@ -482,71 +415,3 @@ impl ToSimValueWithType for Phanto SimValue::into_canonical(SimValue::from_value(Self::from_canonical(ty), *self)) } } - -mod sealed { - pub trait Sealed {} -} - -pub trait PhantomConstGet: sealed::Sealed { - fn get(&self) -> Interned; -} - -impl>> - sealed::Sealed for This -{ -} - -impl>> - PhantomConstGet for This -{ - fn get(&self) -> Interned { - This::Target::get(&**self) - } -} - -macro_rules! impl_phantom_const_get { - ( - impl PhantomConstGet<$T:ident> for $ty:ty { - fn $get:ident(&$get_self:ident) -> _ $get_body:block - } - ) => { - impl<$T: ?Sized + PhantomConstValue> sealed::Sealed<$T> for $ty {} - - impl<$T: ?Sized + PhantomConstValue> PhantomConstGet<$T> for $ty { - fn $get(&$get_self) -> Interned<$T> $get_body - } - }; -} - -impl_phantom_const_get! { - impl PhantomConstGet for PhantomConst { - fn get(&self) -> _ { - PhantomConst::get(*self) - } - } -} - -impl_phantom_const_get! { - impl PhantomConstGet for Expr> { - fn get(&self) -> _ { - PhantomConst::get(self.ty()) - } - } -} - -#[doc(hidden)] -pub trait ReturnSelfUnchanged { - type Type: ?Sized; -} - -impl ReturnSelfUnchanged for This { - type Type = This; -} - -#[doc(hidden)] -pub fn type_alias_phantom_const_get_helper( - param: impl PhantomConstGet, - get: impl FnOnce(Interned) -> R, -) -> &'static R { - Interned::into_inner(get(param.get()).intern_sized()) -} diff --git a/crates/fayalite/src/platform.rs b/crates/fayalite/src/platform.rs deleted file mode 100644 index c6901cf..0000000 --- a/crates/fayalite/src/platform.rs +++ /dev/null @@ -1,1923 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - bundle::{Bundle, BundleField, BundleType}, - expr::{Expr, ExprEnum, ValueType}, - intern::{Intern, Interned}, - module::{Module, ModuleBuilder, ModuleIO, connect_with_loc, instance_with_loc, wire_with_loc}, - source_location::SourceLocation, - ty::{CanonicalType, Type}, - util::{HashMap, HashSet, InternedStrCompareAsStr}, -}; -use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error}; -use std::{ - any::{Any, TypeId}, - borrow::Cow, - cmp::Ordering, - collections::{BTreeMap, BTreeSet}, - convert::Infallible, - fmt, - hash::{Hash, Hasher}, - iter::FusedIterator, - marker::PhantomData, - mem, - sync::{Arc, Mutex, MutexGuard, OnceLock, RwLock, RwLockWriteGuard}, -}; - -pub mod peripherals; - -trait DynPlatformTrait: 'static + Send + Sync + fmt::Debug { - fn as_any(&self) -> &dyn Any; - fn eq_dyn(&self, other: &dyn DynPlatformTrait) -> bool; - fn hash_dyn(&self, state: &mut dyn Hasher); - fn name_dyn(&self) -> Interned; - fn new_peripherals_dyn<'builder>( - &self, - builder_factory: PeripheralsBuilderFactory<'builder>, - ) -> (DynPeripherals, PeripheralsBuilderFinished<'builder>); - fn source_location_dyn(&self) -> SourceLocation; - #[track_caller] - fn add_peripherals_in_wrapper_module_dyn(&self, m: &ModuleBuilder, peripherals: DynPeripherals); - fn aspects_dyn(&self) -> PlatformAspectSet; -} - -impl DynPlatformTrait for T { - fn as_any(&self) -> &dyn Any { - self - } - - fn eq_dyn(&self, other: &dyn DynPlatformTrait) -> bool { - other - .as_any() - .downcast_ref::() - .is_some_and(|other| self == other) - } - - fn hash_dyn(&self, mut state: &mut dyn Hasher) { - self.hash(&mut state); - } - - fn name_dyn(&self) -> Interned { - self.name() - } - - fn new_peripherals_dyn<'builder>( - &self, - builder_factory: PeripheralsBuilderFactory<'builder>, - ) -> (DynPeripherals, PeripheralsBuilderFinished<'builder>) { - let (peripherals, finished) = self.new_peripherals(builder_factory); - (DynPeripherals(Box::new(peripherals)), finished) - } - - fn source_location_dyn(&self) -> SourceLocation { - self.source_location() - } - - #[track_caller] - fn add_peripherals_in_wrapper_module_dyn( - &self, - m: &ModuleBuilder, - peripherals: DynPeripherals, - ) { - if DynPeripheralsTrait::type_id(&*peripherals.0) != TypeId::of::() { - panic!( - "wrong DynPeripherals value type, expected type: <{}>::Peripherals, got value:\n{peripherals:?}", - std::any::type_name::() - ); - } - let Ok(peripherals) = peripherals.0.into_box_any().downcast() else { - unreachable!(); - }; - self.add_peripherals_in_wrapper_module(m, *peripherals) - } - - fn aspects_dyn(&self) -> PlatformAspectSet { - self.aspects() - } -} - -#[derive(Clone)] -pub struct DynPlatform(Arc); - -impl PartialEq for DynPlatform { - fn eq(&self, other: &Self) -> bool { - DynPlatformTrait::eq_dyn(&*self.0, &*other.0) - } -} - -impl Eq for DynPlatform {} - -impl Hash for DynPlatform { - fn hash(&self, state: &mut H) { - DynPlatformTrait::hash_dyn(&*self.0, state); - } -} - -impl fmt::Debug for DynPlatform { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl DynPlatform { - pub fn new(platform: T) -> Self { - if let Some(platform) = ::downcast_ref::(&platform) { - platform.clone() - } else { - Self(Arc::new(platform)) - } - } -} - -trait DynPeripheralsTrait: fmt::Debug + 'static + Send + Sync { - fn type_id(&self) -> TypeId; - fn into_box_any(self: Box) -> Box; - fn append_peripherals_dyn<'a>( - &'a self, - peripherals: &mut Vec>, - ); -} - -impl DynPeripheralsTrait for T { - fn type_id(&self) -> TypeId { - TypeId::of::() - } - fn into_box_any(self: Box) -> Box { - self - } - fn append_peripherals_dyn<'a>( - &'a self, - peripherals: &mut Vec>, - ) { - self.append_peripherals(peripherals); - } -} - -pub struct DynPeripherals(Box); - -impl fmt::Debug for DynPeripherals { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl Peripherals for DynPeripherals { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - self.0.append_peripherals_dyn(peripherals); - } -} - -impl Platform for DynPlatform { - type Peripherals = DynPeripherals; - fn name(&self) -> Interned { - DynPlatformTrait::name_dyn(&*self.0) - } - fn new_peripherals<'a>( - &self, - builder_factory: PeripheralsBuilderFactory<'a>, - ) -> (Self::Peripherals, PeripheralsBuilderFinished<'a>) { - DynPlatformTrait::new_peripherals_dyn(&*self.0, builder_factory) - } - fn source_location(&self) -> SourceLocation { - DynPlatformTrait::source_location_dyn(&*self.0) - } - #[track_caller] - fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals) { - DynPlatformTrait::add_peripherals_in_wrapper_module_dyn(&*self.0, m, peripherals); - } - fn aspects(&self) -> PlatformAspectSet { - DynPlatformTrait::aspects_dyn(&*self.0) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct PeripheralId { - pub name: Interned, -} - -impl PartialOrd for PeripheralId { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for PeripheralId { - fn cmp(&self, other: &Self) -> Ordering { - if self == other { - Ordering::Equal - } else { - let Self { name } = self; - str::cmp(name, &other.name) - } - } -} - -struct CollectingPeripherals { - conflicts_graph: BTreeMap>, - on_use_state: PeripheralsOnUseState, -} - -pub trait PeripheralsOnUseSharedState: 'static + Send + fmt::Debug { - fn as_any(&mut self) -> &mut dyn Any; -} - -impl PeripheralsOnUseSharedState for T { - fn as_any(&mut self) -> &mut dyn Any { - self - } -} - -type DynPeripheralsOnUse = dyn FnOnce( - &mut dyn PeripheralsOnUseSharedState, - PeripheralRef<'_, CanonicalType>, - Expr, - ) + Send - + 'static; - -struct PeripheralsOnUseState { - shared_state: Box, - main_module_io_fields: Vec, - main_module_io_wires: Vec>, - on_use_functions: BTreeMap>, -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub enum PeripheralAvailability { - Available, - Used, - ConflictsWithUsed(PeripheralId), -} - -impl PeripheralAvailability { - pub fn is_available(self) -> bool { - matches!(self, Self::Available) - } - pub fn is_used(&self) -> bool { - matches!(self, Self::Used) - } -} - -struct PeripheralsStateBuildingModule { - conflicts_graph: Interned>>>, - availabilities: Mutex>, - on_use_state: Mutex, -} - -impl From for PeripheralsStateBuildingModule { - fn from(value: CollectingPeripherals) -> Self { - let CollectingPeripherals { - conflicts_graph, - on_use_state, - } = value; - let conflicts_graph = BTreeMap::from_iter( - conflicts_graph - .into_iter() - .map(|(k, v)| (k, v.intern_sized())), - ) - .intern_sized(); - Self { - conflicts_graph, - availabilities: Mutex::new( - on_use_state - .on_use_functions - .keys() - .map(|&id| (id, PeripheralAvailability::Available)) - .collect(), - ), - on_use_state: Mutex::new(on_use_state), - } - } -} - -struct PeripheralsStateBuildingWrapperModule { - output_module_io: ModuleIO, - output: Option>, -} - -enum PeripheralsStateEnum { - Initial, - CollectingPeripherals(CollectingPeripherals), - BuildingModule, - BuildingWrapperModule(PeripheralsStateBuildingWrapperModule), -} - -struct PeripheralsState { - will_build_wrapper: bool, - state: Mutex, - building_module: OnceLock, -} - -impl PeripheralsState { - fn finish_collecting_peripherals(&self) { - let mut state = self.state.lock().expect("shouldn't be poison"); - let building_module = match mem::replace(&mut *state, PeripheralsStateEnum::BuildingModule) - { - PeripheralsStateEnum::CollectingPeripherals(v) => v.into(), - PeripheralsStateEnum::Initial - | PeripheralsStateEnum::BuildingModule - | PeripheralsStateEnum::BuildingWrapperModule(_) => unreachable!(), - }; - self.building_module.get_or_init(|| building_module); - } -} - -struct PeripheralCommon { - type_id: TypeId, - id: PeripheralId, - is_input: bool, - peripherals_state: Arc, -} - -#[must_use] -pub struct PeripheralsBuilderFactory<'a> { - peripherals_state: Arc, - _phantom: PhantomData &'a ()>, -} - -impl fmt::Debug for PeripheralsBuilderFactory<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("PeripheralsBuilderFactory") - .finish_non_exhaustive() - } -} - -impl PeripheralsBuilderFactory<'_> { - fn new(will_build_wrapper: bool) -> Self { - Self { - peripherals_state: Arc::new(PeripheralsState { - will_build_wrapper, - state: Mutex::new(PeripheralsStateEnum::Initial), - building_module: OnceLock::new(), - }), - _phantom: PhantomData, - } - } -} - -impl<'a> PeripheralsBuilderFactory<'a> { - pub fn builder(self) -> PeripheralsBuilder<'a> { - self.builder_with_default_state() - } - pub fn builder_with_default_state( - self, - ) -> PeripheralsBuilder<'a, S> { - self.builder_with_boxed_state(Box::default()) - } - pub fn builder_with_state( - self, - shared_state: S, - ) -> PeripheralsBuilder<'a, S> { - self.builder_with_boxed_state(Box::new(shared_state)) - } - pub fn builder_with_boxed_state( - self, - shared_state: Box, - ) -> PeripheralsBuilder<'a, S> { - let Self { - peripherals_state, - _phantom: PhantomData, - } = self; - match *peripherals_state.state.lock().expect("shouldn't be poison") { - ref mut state @ PeripheralsStateEnum::Initial => { - *state = PeripheralsStateEnum::CollectingPeripherals(CollectingPeripherals { - conflicts_graph: BTreeMap::new(), - on_use_state: PeripheralsOnUseState { - shared_state, - main_module_io_fields: Vec::new(), - main_module_io_wires: Vec::new(), - on_use_functions: BTreeMap::new(), - }, - }) - } - PeripheralsStateEnum::CollectingPeripherals(_) - | PeripheralsStateEnum::BuildingModule - | PeripheralsStateEnum::BuildingWrapperModule(_) => unreachable!(), - } - PeripheralsBuilder { - peripherals_state, - _phantom: PhantomData, - } - } -} - -#[must_use] -pub struct PeripheralsBuilder<'a, S: PeripheralsOnUseSharedState = ()> { - peripherals_state: Arc, - _phantom: PhantomData<(Arc, fn(&'a ()) -> &'a ())>, -} - -#[must_use] -pub struct PeripheralsBuilderFinished<'a> { - _private: PhantomData &'a ()>, -} - -impl fmt::Debug for PeripheralsBuilderFinished<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("PeripheralsBuilderFinished") - .finish_non_exhaustive() - } -} - -impl<'a, S: PeripheralsOnUseSharedState> PeripheralsBuilder<'a, S> { - fn state_enum(&mut self) -> MutexGuard<'_, PeripheralsStateEnum> { - self.peripherals_state - .state - .lock() - .expect("shouldn't be poison") - } - #[track_caller] - pub fn peripheral( - &mut self, - id_name: impl AsRef, - is_input: bool, - ty: T, - ) -> Peripheral { - self.peripheral_with_on_use(id_name, is_input, ty, |_, _, _| {}) - } - #[track_caller] - pub fn peripheral_with_on_use( - &mut self, - id_name: impl AsRef, - is_input: bool, - ty: T, - on_use: impl FnOnce(&mut S, PeripheralRef<'_, T>, Expr) + Send + 'static, - ) -> Peripheral { - let mut state_enum = self.state_enum(); - let PeripheralsStateEnum::CollectingPeripherals(CollectingPeripherals { - conflicts_graph, - on_use_state: - PeripheralsOnUseState { - shared_state: _, - main_module_io_fields: _, - main_module_io_wires: _, - on_use_functions, - }, - }) = &mut *state_enum - else { - unreachable!(); - }; - let id = PeripheralId { - name: id_name.as_ref().intern(), - }; - let std::collections::btree_map::Entry::Vacant(entry) = conflicts_graph.entry(id) else { - drop(state_enum); // don't poison - panic!("duplicate peripheral: {id:?}"); - }; - entry.insert(BTreeSet::new()); - on_use_functions.insert( - id, - Box::new(move |state, peripheral_ref, wire| { - on_use( - ::downcast_mut::(PeripheralsOnUseSharedState::as_any(state)) - .expect("known to be correct type"), - PeripheralRef::from_canonical(peripheral_ref), - Expr::from_canonical(wire), - ) - }), - ); - drop(state_enum); - Peripheral { - ty, - common: PeripheralCommon { - type_id: TypeId::of::(), - id, - is_input, - peripherals_state: self.peripherals_state.clone(), - }, - } - } - #[track_caller] - pub fn input_peripheral_with_on_use( - &mut self, - id_name: impl AsRef, - ty: T, - on_use: impl FnOnce(&mut S, PeripheralRef<'_, T>, Expr) + Send + 'static, - ) -> Peripheral { - self.peripheral_with_on_use(id_name, true, ty, on_use) - } - #[track_caller] - pub fn output_peripheral_with_on_use( - &mut self, - id_name: impl AsRef, - ty: T, - on_use: impl FnOnce(&mut S, PeripheralRef<'_, T>, Expr) + Send + 'static, - ) -> Peripheral { - self.peripheral_with_on_use(id_name, false, ty, on_use) - } - #[track_caller] - pub fn input_peripheral(&mut self, id_name: impl AsRef, ty: T) -> Peripheral { - self.peripheral(id_name, true, ty) - } - #[track_caller] - pub fn output_peripheral(&mut self, id_name: impl AsRef, ty: T) -> Peripheral { - self.peripheral(id_name, false, ty) - } - #[track_caller] - pub fn add_conflicts(&mut self, conflicts: impl AsRef<[PeripheralId]>) { - let mut state_enum = self.state_enum(); - let PeripheralsStateEnum::CollectingPeripherals(collecting_peripherals) = &mut *state_enum - else { - unreachable!(); - }; - let conflicts = conflicts.as_ref(); - for &id in conflicts { - let Some(conflicts_for_id) = collecting_peripherals.conflicts_graph.get_mut(&id) else { - drop(state_enum); // don't poison - panic!("unknown peripheral: {id:?}"); - }; - conflicts_for_id.extend(conflicts.iter().copied().filter(|&v| v != id)); - } - } - pub fn finish(self) -> PeripheralsBuilderFinished<'a> { - self.peripherals_state.finish_collecting_peripherals(); - PeripheralsBuilderFinished { - _private: PhantomData, - } - } -} - -#[must_use] -pub struct Peripheral { - ty: T, - common: PeripheralCommon, -} - -impl Peripheral { - pub fn as_ref<'a>(&'a self) -> PeripheralRef<'a, T> { - let Self { ty, ref common } = *self; - PeripheralRef { ty, common } - } - pub fn ty(&self) -> T { - self.as_ref().ty() - } - pub fn id(&self) -> PeripheralId { - self.as_ref().id() - } - pub fn name(&self) -> Interned { - self.as_ref().name() - } - pub fn is_input(&self) -> bool { - self.as_ref().is_input() - } - pub fn is_output(&self) -> bool { - self.as_ref().is_output() - } - pub fn conflicts_with(&self) -> Interned> { - self.as_ref().conflicts_with() - } - pub fn availability(&self) -> PeripheralAvailability { - self.as_ref().availability() - } - pub fn is_available(&self) -> bool { - self.as_ref().is_available() - } - pub fn is_used(&self) -> bool { - self.as_ref().is_used() - } - pub fn try_into_used(self) -> Result, Self> { - let Some(building_module) = self.common.peripherals_state.building_module.get() else { - return Err(self); - }; - let building_module = building_module - .availabilities - .lock() - .expect("shouldn't be poison"); - match building_module[&self.common.id] { - PeripheralAvailability::Used => {} - PeripheralAvailability::Available | PeripheralAvailability::ConflictsWithUsed(_) => { - drop(building_module); - return Err(self); - } - } - drop(building_module); - let state = self - .common - .peripherals_state - .state - .lock() - .expect("shouldn't be poison"); - let output = match *state { - PeripheralsStateEnum::Initial | PeripheralsStateEnum::CollectingPeripherals(_) => { - unreachable!() - } - PeripheralsStateEnum::BuildingModule => { - drop(state); - return Err(self); - } - PeripheralsStateEnum::BuildingWrapperModule( - PeripheralsStateBuildingWrapperModule { - output: Some(output), - .. - }, - ) => output, - PeripheralsStateEnum::BuildingWrapperModule(_) => unreachable!(), - }; - drop(state); - let Self { ty, common } = self; - let instance_io_field = Expr::field::(output, &common.id.name); - assert_eq!(ty, instance_io_field.ty()); - Ok(UsedPeripheral { - instance_io_field, - common, - }) - } - pub fn into_used(self) -> Option> { - self.try_into_used().ok() - } -} - -impl fmt::Debug for Peripheral { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_ref().debug_common_fields("Peripheral", f).finish() - } -} - -pub struct UsedPeripheral { - instance_io_field: Expr, - common: PeripheralCommon, -} - -impl fmt::Debug for UsedPeripheral { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.as_ref() - .debug_common_fields("UsedPeripheral", f) - .field("instance_io_field", &self.instance_io_field()) - .finish() - } -} - -impl UsedPeripheral { - pub fn as_ref<'a>(&'a self) -> PeripheralRef<'a, T> { - let Self { - instance_io_field, - ref common, - } = *self; - PeripheralRef { - ty: instance_io_field.ty(), - common, - } - } - pub fn instance_io_field(&self) -> Expr { - self.instance_io_field - } - pub fn ty(&self) -> T { - self.as_ref().ty() - } - pub fn id(&self) -> PeripheralId { - self.as_ref().id() - } - pub fn name(&self) -> Interned { - self.as_ref().name() - } - pub fn is_input(&self) -> bool { - self.as_ref().is_input() - } - pub fn is_output(&self) -> bool { - self.as_ref().is_output() - } - pub fn conflicts_with(&self) -> Interned> { - self.as_ref().conflicts_with() - } -} - -#[derive(Copy, Clone)] -pub struct PeripheralRef<'a, T: Type> { - ty: T, - common: &'a PeripheralCommon, -} - -impl<'a, T: Type> fmt::Debug for PeripheralRef<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.debug_common_fields("PeripheralRef", f).finish() - } -} - -#[derive(Debug, Clone)] -pub enum PeripheralUnavailableError { - PeripheralAlreadyUsed { - id: PeripheralId, - }, - PeripheralConflict { - id: PeripheralId, - conflicting_id: PeripheralId, - }, - PeripheralsWillNotBeUsedToBuildWrapper, -} - -impl fmt::Display for PeripheralUnavailableError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::PeripheralAlreadyUsed { id } => { - write!(f, "peripherals can only be used once: {id:?}") - } - Self::PeripheralConflict { id, conflicting_id } => { - write!(f, "peripheral {id:?} conflicts with {conflicting_id:?}") - } - Self::PeripheralsWillNotBeUsedToBuildWrapper => { - write!(f, "peripherals will not be used to build wrapper") - } - } - } -} - -impl std::error::Error for PeripheralUnavailableError {} - -impl<'a, T: Type> PeripheralRef<'a, T> { - fn debug_common_fields<'f1, 'f2>( - &self, - struct_name: &str, - f: &'f1 mut fmt::Formatter<'f2>, - ) -> fmt::DebugStruct<'f1, 'f2> { - let Self { - ty, - common: - PeripheralCommon { - type_id: _, - id, - is_input, - peripherals_state: _, - }, - } = self; - let mut retval = f.debug_struct(struct_name); - retval - .field("ty", ty) - .field("id", id) - .field("is_input", is_input) - .field("availability", &self.availability()); - retval - } - pub fn ty(&self) -> T { - self.ty - } - pub fn id(&self) -> PeripheralId { - self.common.id - } - pub fn name(&self) -> Interned { - self.id().name - } - pub fn is_input(&self) -> bool { - self.common.is_input - } - pub fn is_output(&self) -> bool { - !self.common.is_input - } - pub fn conflicts_with(&self) -> Interned> { - match self.common.peripherals_state.building_module.get() { - Some(building_module) => building_module.conflicts_graph[&self.common.id], - None => match &*self - .common - .peripherals_state - .state - .lock() - .expect("shouldn't be poison") - { - PeripheralsStateEnum::CollectingPeripherals(v) => { - v.conflicts_graph[&self.common.id].intern() - } - PeripheralsStateEnum::Initial - | PeripheralsStateEnum::BuildingModule - | PeripheralsStateEnum::BuildingWrapperModule(_) => unreachable!(), - }, - } - } - pub fn availability(&self) -> PeripheralAvailability { - match self.common.peripherals_state.building_module.get() { - None => PeripheralAvailability::Available, - Some(building_module) => building_module - .availabilities - .lock() - .expect("shouldn't be poison")[&self.common.id], - } - } - pub fn is_available(&self) -> bool { - match self.common.peripherals_state.building_module.get() { - None => true, - Some(building_module) => match building_module - .availabilities - .lock() - .expect("shouldn't be poison")[&self.common.id] - { - PeripheralAvailability::Available => true, - PeripheralAvailability::Used | PeripheralAvailability::ConflictsWithUsed(_) => { - false - } - }, - } - } - pub fn is_used(&self) -> bool { - match self.common.peripherals_state.building_module.get() { - None => false, - Some(building_module) => match building_module - .availabilities - .lock() - .expect("shouldn't be poison")[&self.common.id] - { - PeripheralAvailability::Used => true, - PeripheralAvailability::Available - | PeripheralAvailability::ConflictsWithUsed(_) => false, - }, - } - } - pub fn canonical(self) -> PeripheralRef<'a, CanonicalType> { - let Self { ty, common } = self; - PeripheralRef { - ty: ty.canonical(), - common, - } - } - pub fn from_canonical(peripheral_ref: PeripheralRef<'a, CanonicalType>) -> Self { - let PeripheralRef { ty, common } = peripheral_ref; - Self { - ty: T::from_canonical(ty), - common, - } - } - #[track_caller] - pub fn try_use_peripheral(self) -> Result, PeripheralUnavailableError> { - self.try_use_peripheral_with_loc(SourceLocation::caller()) - } - #[track_caller] - pub fn try_use_peripheral_with_loc( - self, - source_location: SourceLocation, - ) -> Result, PeripheralUnavailableError> { - let PeripheralsState { - will_build_wrapper, - ref state, - ref building_module, - } = *self.common.peripherals_state; - if !will_build_wrapper { - return Err(PeripheralUnavailableError::PeripheralsWillNotBeUsedToBuildWrapper); - } - let Some(PeripheralsStateBuildingModule { - conflicts_graph, - availabilities, - on_use_state, - }) = building_module.get() - else { - panic!("can't use peripherals in a module before the PeripheralsBuilder is finished"); - }; - let state = state.lock().expect("shouldn't be poison"); - match *state { - PeripheralsStateEnum::Initial | PeripheralsStateEnum::CollectingPeripherals(_) => { - unreachable!() - } - PeripheralsStateEnum::BuildingModule => {} - PeripheralsStateEnum::BuildingWrapperModule(_) => { - panic!("can't add new peripherals after calling m.add_platform_io()") - } - } - drop(state); - let mut availabilities = availabilities.lock().expect("shouldn't be poison"); - let Some(availability) = availabilities.get_mut(&self.common.id) else { - unreachable!(); - }; - match *availability { - PeripheralAvailability::Available => { - *availability = PeripheralAvailability::Used; - } - PeripheralAvailability::Used => { - return Err(PeripheralUnavailableError::PeripheralAlreadyUsed { - id: self.common.id, - }); - } - PeripheralAvailability::ConflictsWithUsed(conflicting_id) => { - return Err(PeripheralUnavailableError::PeripheralConflict { - id: self.common.id, - conflicting_id, - }); - } - } - for conflict in conflicts_graph[&self.common.id].iter() { - let Some(availability) = availabilities.get_mut(conflict) else { - unreachable!(); - }; - *availability = PeripheralAvailability::ConflictsWithUsed(self.common.id); - } - drop(availabilities); - let wire = wire_with_loc(&self.name(), source_location, self.ty()); - let mut on_use_state = on_use_state.lock().expect("shouldn't be poison"); - let PeripheralsOnUseState { - shared_state, - main_module_io_fields, - main_module_io_wires, - on_use_functions, - } = &mut *on_use_state; - let Some(on_use_function) = on_use_functions.remove(&self.common.id) else { - unreachable!(); - }; - for conflict in conflicts_graph[&self.common.id].iter() { - on_use_functions.remove(conflict); - } - let canonical_wire = Expr::canonical(wire); - main_module_io_wires.push(canonical_wire); - main_module_io_fields.push(BundleField { - name: self.name(), - flipped: self.is_input(), - ty: canonical_wire.ty(), - }); - on_use_function(&mut **shared_state, self.canonical(), canonical_wire); - drop(on_use_state); - Ok(wire) - } - #[track_caller] - pub fn use_peripheral_with_loc(self, source_location: SourceLocation) -> Expr { - match self.try_use_peripheral_with_loc(source_location) { - Ok(wire) => wire, - Err(e) => panic!("{e}"), - } - } - #[track_caller] - pub fn use_peripheral(self) -> Expr { - match self.try_use_peripheral() { - Ok(wire) => wire, - Err(e) => panic!("{e}"), - } - } -} - -pub trait Peripherals: 'static + Send + Sync + fmt::Debug { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>); - fn to_peripherals_vec<'a>(&'a self) -> Vec> { - let mut peripherals = Vec::new(); - self.append_peripherals(&mut peripherals); - peripherals - } -} - -impl Peripherals for Peripheral { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - peripherals.push(self.as_ref().canonical()); - } -} - -impl Peripherals for Vec { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - for v in self { - v.append_peripherals(peripherals); - } - } -} - -impl Peripherals for Box { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - T::append_peripherals(self, peripherals); - } -} - -impl Peripherals for [T] { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - for v in self { - v.append_peripherals(peripherals); - } - } -} - -impl Peripherals for [T; N] { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - for v in self { - v.append_peripherals(peripherals); - } - } -} - -macro_rules! impl_peripherals { - (@impl $(($v:ident: $T:ident),)*) => { - impl<$($T: Peripherals),*> Peripherals for ($($T,)*) { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - #![allow(unused_variables)] - let ($($v,)*) = self; - $(Peripherals::append_peripherals($v, peripherals);)* - } - } - }; - ($($first:tt, $($rest:tt,)*)?) => { - impl_peripherals!(@impl $($first, $($rest,)*)?); - $(impl_peripherals!($($rest,)*);)? - }; -} - -impl_peripherals! { - (v0: T0), - (v1: T1), - (v2: T2), - (v3: T3), - (v4: T4), - (v5: T5), - (v6: T6), - (v7: T7), - (v8: T8), - (v9: T9), - (v10: T10), - (v11: T11), -} - -pub struct PlatformIOBuilder<'a> { - peripherals: Vec>, - peripherals_by_type_id: HashMap>>, - peripherals_by_id: BTreeMap>, - peripherals_state: &'a PeripheralsState, -} - -impl<'a> PlatformIOBuilder<'a> { - pub fn peripherals(&self) -> &[PeripheralRef<'a, CanonicalType>] { - &self.peripherals - } - pub fn peripherals_with_type(&self) -> Vec> { - let Some(peripherals) = self.peripherals_by_type_id.get(&TypeId::of::()) else { - return Vec::new(); - }; - peripherals - .iter() - .map(|&peripheral_ref| PeripheralRef::from_canonical(peripheral_ref)) - .collect() - } - pub fn peripherals_by_id(&self) -> &BTreeMap> { - &self.peripherals_by_id - } - #[track_caller] - pub(crate) fn add_platform_io( - self, - name: &str, - source_location: SourceLocation, - m: &ModuleBuilder, - ) -> Expr { - if !ModuleBuilder::with(|m2| std::ptr::eq(m, m2)) { - panic!("m.add_platform_io() must be called in the same module as m"); - } - let PeripheralsState { - will_build_wrapper: _, - state, - building_module, - } = self.peripherals_state; - let building_module = building_module.get().expect("shouldn't be None"); - let mut on_use_state = building_module - .on_use_state - .lock() - .expect("shouldn't be poison"); - let output_ty = - Bundle::new(mem::take(&mut on_use_state.main_module_io_fields).intern_deref()); - let main_module_wires = mem::take(&mut on_use_state.main_module_io_wires); - drop(on_use_state); - let output = m.output_with_loc(name, source_location, output_ty); - for (field, wire_expr) in output_ty.fields().iter().zip(main_module_wires) { - let ExprEnum::Wire(wire) = *Expr::expr_enum(wire_expr) else { - unreachable!(); - }; - let field_expr = Expr::field(output, &field.name); - if field.flipped { - connect_with_loc(wire, field_expr, wire.source_location()); - } else { - connect_with_loc(field_expr, wire, wire.source_location()); - } - } - let ExprEnum::ModuleIO(output_module_io) = *Expr::expr_enum(output) else { - unreachable!(); - }; - *state.lock().expect("shouldn't be poison") = - PeripheralsStateEnum::BuildingWrapperModule(PeripheralsStateBuildingWrapperModule { - output_module_io, - output: None, - }); - output - } -} - -impl<'a> fmt::Debug for PlatformIOBuilder<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - peripherals, - peripherals_by_type_id: _, - peripherals_by_id: _, - peripherals_state: _, - } = self; - f.debug_struct("PlatformIOBuilder") - .field("peripherals", peripherals) - .finish_non_exhaustive() - } -} - -trait PlatformAspectTrait: 'static + Send + Sync + fmt::Debug { - fn any_ref(&self) -> &dyn Any; - fn any_arc(self: Arc) -> Arc; - fn eq_dyn(&self, other: &dyn PlatformAspectTrait) -> bool; - fn hash_dyn(&self, state: &mut dyn Hasher); -} - -impl PlatformAspectTrait for T { - fn any_ref(&self) -> &dyn Any { - self - } - - fn any_arc(self: Arc) -> Arc { - self - } - - fn eq_dyn(&self, other: &dyn PlatformAspectTrait) -> bool { - other - .any_ref() - .downcast_ref::() - .is_some_and(|other| self == other) - } - - fn hash_dyn(&self, mut state: &mut dyn Hasher) { - self.hash(&mut state); - } -} - -#[derive(Clone)] -pub struct PlatformAspect { - type_id: TypeId, - type_name: &'static str, - value: Arc, -} - -impl Hash for PlatformAspect { - fn hash(&self, state: &mut H) { - PlatformAspectTrait::hash_dyn(&*self.value, state); - } -} - -impl Eq for PlatformAspect {} - -impl PartialEq for PlatformAspect { - fn eq(&self, other: &Self) -> bool { - self.type_id == other.type_id && PlatformAspectTrait::eq_dyn(&*self.value, &*other.value) - } -} - -impl fmt::Debug for PlatformAspect { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - type_id: _, - type_name, - value, - } = self; - write!(f, "PlatformAspect<{type_name}>")?; - f.debug_tuple("").field(value).finish() - } -} - -impl PlatformAspect { - pub fn new_arc(value: Arc) -> Self { - Self { - type_id: TypeId::of::(), - type_name: std::any::type_name::(), - value, - } - } - pub fn new(value: T) -> Self { - Self::new_arc(Arc::new(value)) - } - pub fn type_id(&self) -> TypeId { - self.type_id - } - pub fn downcast_arc(self) -> Result, Self> { - if self.type_id == TypeId::of::() { - let Ok(retval) = self.value.any_arc().downcast() else { - unreachable!(); - }; - Ok(retval) - } else { - Err(self) - } - } - pub fn downcast_unwrap_or_clone( - self, - ) -> Result { - Ok(Arc::unwrap_or_clone(self.downcast_arc()?)) - } - pub fn downcast_ref(&self) -> Option<&T> { - PlatformAspectTrait::any_ref(&*self.value).downcast_ref() - } -} - -#[derive(Clone, Default)] -pub struct PlatformAspectSet { - aspects_by_type_id: Arc>>, - aspects: Arc>, -} - -impl PlatformAspectSet { - pub fn new() -> Self { - Self::default() - } - pub fn insert_new( - &mut self, - value: T, - ) -> bool { - self.insert(PlatformAspect::new(value)) - } - pub fn insert_new_arc( - &mut self, - value: Arc, - ) -> bool { - self.insert(PlatformAspect::new_arc(value)) - } - fn insert_inner( - aspects_by_type_id: &mut HashMap>, - aspects: &mut Vec, - value: PlatformAspect, - ) -> bool { - if aspects_by_type_id - .entry(value.type_id) - .or_default() - .insert(value.clone()) - { - aspects.push(value); - true - } else { - false - } - } - pub fn insert(&mut self, value: PlatformAspect) -> bool { - Self::insert_inner( - Arc::make_mut(&mut self.aspects_by_type_id), - Arc::make_mut(&mut self.aspects), - value, - ) - } - pub fn contains(&self, value: &PlatformAspect) -> bool { - self.aspects_by_type_id - .get(&value.type_id) - .is_some_and(|aspects| aspects.contains(value)) - } - pub fn get_aspects_by_type<'a, T: 'static + Send + Sync + fmt::Debug + Hash + Eq>( - &'a self, - ) -> impl Clone + Iterator + FusedIterator + ExactSizeIterator + 'a - { - self.aspects_by_type_id - .get(&TypeId::of::()) - .map(|aspects| aspects.iter()) - .unwrap_or_default() - } - pub fn get_by_type<'a, T: 'static + Send + Sync + fmt::Debug + Hash + Eq>( - &'a self, - ) -> impl Clone + Iterator + FusedIterator + ExactSizeIterator + 'a { - self.get_aspects_by_type::() - .map(|aspect| aspect.downcast_ref().expect("already checked type")) - } - pub fn get_single_by_type<'a, T: 'static + Send + Sync + fmt::Debug + Hash + Eq>( - &'a self, - ) -> Option<&'a T> { - let mut aspects = self.get_by_type::(); - if aspects.len() == 1 { - aspects.next() - } else { - None - } - } - pub fn get_arcs_by_type<'a, T: 'static + Send + Sync + fmt::Debug + Hash + Eq>( - &'a self, - ) -> impl Clone + Iterator> + FusedIterator + ExactSizeIterator + 'a { - self.get_aspects_by_type::().map(|aspect| { - aspect - .clone() - .downcast_arc() - .ok() - .expect("already checked type") - }) - } -} - -impl<'a> Extend<&'a PlatformAspect> for PlatformAspectSet { - fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().cloned()); - } -} - -impl Extend for PlatformAspectSet { - fn extend>(&mut self, iter: T) { - let Self { - aspects_by_type_id, - aspects, - } = self; - let aspects_by_type_id = Arc::make_mut(aspects_by_type_id); - let aspects = Arc::make_mut(aspects); - iter.into_iter().for_each(|value| { - Self::insert_inner(aspects_by_type_id, aspects, value); - }); - } -} - -impl<'a> FromIterator<&'a PlatformAspect> for PlatformAspectSet { - fn from_iter>(iter: T) -> Self { - let mut retval = Self::default(); - retval.extend(iter); - retval - } -} - -impl FromIterator for PlatformAspectSet { - fn from_iter>(iter: T) -> Self { - let mut retval = Self::default(); - retval.extend(iter); - retval - } -} - -impl std::ops::Deref for PlatformAspectSet { - type Target = [PlatformAspect]; - - fn deref(&self) -> &Self::Target { - &self.aspects - } -} - -impl fmt::Debug for PlatformAspectSet { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_set().entries(self).finish() - } -} - -impl IntoIterator for PlatformAspectSet { - type Item = PlatformAspect; - type IntoIter = PlatformAspectsIntoIter; - - fn into_iter(self) -> Self::IntoIter { - PlatformAspectsIntoIter { - indexes: 0..self.aspects.len(), - aspects: self.aspects, - } - } -} - -impl<'a> IntoIterator for &'a PlatformAspectSet { - type Item = &'a PlatformAspect; - type IntoIter = std::slice::Iter<'a, PlatformAspect>; - - fn into_iter(self) -> Self::IntoIter { - self.aspects.iter() - } -} - -#[derive(Clone, Debug)] -pub struct PlatformAspectsIntoIter { - aspects: Arc>, - indexes: std::ops::Range, -} - -impl Iterator for PlatformAspectsIntoIter { - type Item = PlatformAspect; - - fn next(&mut self) -> Option { - self.indexes.next().map(|index| self.aspects[index].clone()) - } - - fn size_hint(&self) -> (usize, Option) { - self.indexes.size_hint() - } - - fn count(self) -> usize { - self.indexes.len() - } - - fn last(mut self) -> Option { - self.next_back() - } - - fn nth(&mut self, n: usize) -> Option { - self.indexes.nth(n).map(|index| self.aspects[index].clone()) - } - - fn fold(self, init: B, mut f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.indexes - .fold(init, |v, index| f(v, self.aspects[index].clone())) - } -} - -impl FusedIterator for PlatformAspectsIntoIter {} - -impl ExactSizeIterator for PlatformAspectsIntoIter {} - -impl DoubleEndedIterator for PlatformAspectsIntoIter { - fn next_back(&mut self) -> Option { - self.indexes - .next_back() - .map(|index| self.aspects[index].clone()) - } - - fn nth_back(&mut self, n: usize) -> Option { - self.indexes - .nth_back(n) - .map(|index| self.aspects[index].clone()) - } - - fn rfold(self, init: B, mut f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.indexes - .rfold(init, |v, index| f(v, self.aspects[index].clone())) - } -} - -pub trait Platform: Clone + 'static + Send + Sync + fmt::Debug + Hash + Eq { - type Peripherals: Peripherals; - fn name(&self) -> Interned; - fn new_peripherals<'builder>( - &self, - builder_factory: PeripheralsBuilderFactory<'builder>, - ) -> (Self::Peripherals, PeripheralsBuilderFinished<'builder>); - /// gets peripherals that can be used for inspecting them, but not for building a main module - fn get_peripherals(&self) -> Self::Peripherals { - let ( - retval, - PeripheralsBuilderFinished { - _private: PhantomData, - }, - ) = self.new_peripherals(PeripheralsBuilderFactory::new(false)); - retval - } - fn source_location(&self) -> SourceLocation; - fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals); - #[track_caller] - fn try_wrap_main_module< - T: BundleType, - E, - M: AsRef>, - F: for<'a> FnOnce(PlatformIOBuilder<'a>) -> Result, - >( - &self, - make_main_module: F, - ) -> Result>, E> { - let builder_factory = PeripheralsBuilderFactory::new(true); - let peripherals_state = builder_factory.peripherals_state.clone(); - let ( - peripherals, - PeripheralsBuilderFinished { - _private: PhantomData, - }, - ) = self.new_peripherals(builder_factory); - let peripherals_vec = peripherals.to_peripherals_vec(); - let mut peripherals_by_id = BTreeMap::new(); - let mut peripherals_by_type_id = HashMap::<_, Vec<_>>::default(); - for &peripheral in &peripherals_vec { - peripherals_by_id.insert(peripheral.id(), peripheral); - peripherals_by_type_id - .entry(peripheral.common.type_id) - .or_default() - .push(peripheral); - } - let main_module = Module::canonical( - *make_main_module(PlatformIOBuilder { - peripherals: peripherals_vec, - peripherals_by_type_id, - peripherals_by_id, - peripherals_state: &peripherals_state, - })? - .as_ref(), - ); - let state = peripherals_state.state.lock().expect("shouldn't be poison"); - let PeripheralsStateEnum::BuildingWrapperModule(PeripheralsStateBuildingWrapperModule { - output_module_io, - output: _, - }) = *state - else { - drop(state); - panic!( - "you need to call m.add_platform_io() inside the main module you're trying to use peripherals in.\nat: {}", - main_module.source_location() - ); - }; - drop(state); - for module_io in main_module.module_io() { - if module_io.module_io != output_module_io { - panic!( - "when you're using m.add_platform_io(), you can't have any other inputs/outputs.\nat: {}", - module_io.module_io.source_location() - ); - } - } - Ok(ModuleBuilder::run_with_loc( - &main_module.name(), - self.source_location(), - crate::module::ModuleKind::Normal, - |m| { - let instance = - instance_with_loc("main", main_module.intern(), self.source_location()); - let output_expr = Expr::field(instance, &output_module_io.bundle_field().name); - let mut state = peripherals_state.state.lock().expect("shouldn't be poison"); - let PeripheralsStateEnum::BuildingWrapperModule( - PeripheralsStateBuildingWrapperModule { - output_module_io: _, - output, - }, - ) = &mut *state - else { - unreachable!(); - }; - *output = Some(output_expr); - drop(state); - self.add_peripherals_in_wrapper_module(m, peripherals) - }, - )) - } - #[track_caller] - fn wrap_main_module< - T: BundleType, - M: AsRef>, - F: for<'a> FnOnce(PlatformIOBuilder<'a>) -> M, - >( - &self, - make_main_module: F, - ) -> Interned> { - self.try_wrap_main_module(|p| Ok(make_main_module(p))) - .unwrap_or_else(|e: Infallible| match e {}) - } - fn aspects(&self) -> PlatformAspectSet; -} - -impl DynPlatform { - pub fn registry() -> PlatformRegistrySnapshot { - PlatformRegistrySnapshot(PlatformRegistry::get()) - } - #[track_caller] - pub fn register(self) { - PlatformRegistry::register(PlatformRegistry::lock(), self); - } -} - -#[derive(Clone, Debug)] -struct PlatformRegistry { - platforms: BTreeMap, -} - -enum PlatformRegisterError { - SameName { - name: InternedStrCompareAsStr, - old_platform: DynPlatform, - new_platform: DynPlatform, - }, -} - -impl fmt::Display for PlatformRegisterError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::SameName { - name, - old_platform, - new_platform, - } => write!( - f, - "two different `Platform` can't share the same name:\n\ - {name:?}\n\ - old platform:\n\ - {old_platform:?}\n\ - new platform:\n\ - {new_platform:?}", - ), - } - } -} - -trait PlatformRegistryRegisterLock { - type Locked; - fn lock(self) -> Self::Locked; - fn make_mut(locked: &mut Self::Locked) -> &mut PlatformRegistry; -} - -impl PlatformRegistryRegisterLock for &'static RwLock> { - type Locked = RwLockWriteGuard<'static, Arc>; - fn lock(self) -> Self::Locked { - self.write().expect("shouldn't be poisoned") - } - fn make_mut(locked: &mut Self::Locked) -> &mut PlatformRegistry { - Arc::make_mut(locked) - } -} - -impl PlatformRegistryRegisterLock for &'_ mut PlatformRegistry { - type Locked = Self; - - fn lock(self) -> Self::Locked { - self - } - - fn make_mut(locked: &mut Self::Locked) -> &mut PlatformRegistry { - locked - } -} - -impl PlatformRegistry { - fn lock() -> &'static RwLock> { - static REGISTRY: OnceLock>> = OnceLock::new(); - REGISTRY.get_or_init(Default::default) - } - fn try_register( - lock: L, - platform: DynPlatform, - ) -> Result<(), PlatformRegisterError> { - use std::collections::btree_map::Entry; - let name = InternedStrCompareAsStr(platform.name()); - // run user code only outside of lock - let mut locked = lock.lock(); - let this = L::make_mut(&mut locked); - let result = match this.platforms.entry(name) { - Entry::Occupied(entry) => Err(PlatformRegisterError::SameName { - name, - old_platform: entry.get().clone(), - new_platform: platform, - }), - Entry::Vacant(entry) => { - entry.insert(platform); - Ok(()) - } - }; - drop(locked); - // outside of lock now, so we can test if it's the same DynPlatform - match result { - Err(PlatformRegisterError::SameName { - name: _, - old_platform, - new_platform, - }) if old_platform == new_platform => Ok(()), - result => result, - } - } - #[track_caller] - fn register(lock: L, platform: DynPlatform) { - match Self::try_register(lock, platform) { - Err(e) => panic!("{e}"), - Ok(()) => {} - } - } - fn get() -> Arc { - Self::lock().read().expect("shouldn't be poisoned").clone() - } -} - -impl Default for PlatformRegistry { - fn default() -> Self { - let mut retval = Self { - platforms: BTreeMap::new(), - }; - for platform in built_in_platforms() { - Self::register(&mut retval, platform); - } - retval - } -} - -#[derive(Clone, Debug)] -pub struct PlatformRegistrySnapshot(Arc); - -impl PlatformRegistrySnapshot { - pub fn get() -> Self { - PlatformRegistrySnapshot(PlatformRegistry::get()) - } - pub fn get_by_name<'a>(&'a self, name: &str) -> Option<&'a DynPlatform> { - self.0.platforms.get(name) - } - pub fn iter_with_names(&self) -> PlatformRegistryIterWithNames<'_> { - PlatformRegistryIterWithNames(self.0.platforms.iter()) - } - pub fn iter(&self) -> PlatformRegistryIter<'_> { - PlatformRegistryIter(self.0.platforms.values()) - } -} - -impl<'a> IntoIterator for &'a PlatformRegistrySnapshot { - type Item = &'a DynPlatform; - type IntoIter = PlatformRegistryIter<'a>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -impl<'a> IntoIterator for &'a mut PlatformRegistrySnapshot { - type Item = &'a DynPlatform; - type IntoIter = PlatformRegistryIter<'a>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -#[derive(Clone, Debug)] -pub struct PlatformRegistryIter<'a>( - std::collections::btree_map::Values<'a, InternedStrCompareAsStr, DynPlatform>, -); - -impl<'a> Iterator for PlatformRegistryIter<'a> { - type Item = &'a DynPlatform; - - fn next(&mut self) -> Option { - self.0.next() - } - - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } - - fn count(self) -> usize - where - Self: Sized, - { - self.0.count() - } - - fn last(self) -> Option { - self.0.last() - } - - fn nth(&mut self, n: usize) -> Option { - self.0.nth(n) - } - - fn fold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0.fold(init, f) - } -} - -impl<'a> std::iter::FusedIterator for PlatformRegistryIter<'a> {} - -impl<'a> ExactSizeIterator for PlatformRegistryIter<'a> {} - -impl<'a> DoubleEndedIterator for PlatformRegistryIter<'a> { - fn next_back(&mut self) -> Option { - self.0.next_back() - } - - fn nth_back(&mut self, n: usize) -> Option { - self.0.nth_back(n) - } - - fn rfold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0.rfold(init, f) - } -} - -#[derive(Clone, Debug)] -pub struct PlatformRegistryIterWithNames<'a>( - std::collections::btree_map::Iter<'a, InternedStrCompareAsStr, DynPlatform>, -); - -impl<'a> Iterator for PlatformRegistryIterWithNames<'a> { - type Item = (Interned, &'a DynPlatform); - - fn next(&mut self) -> Option { - self.0.next().map(|(name, platform)| (name.0, platform)) - } - - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } - - fn count(self) -> usize - where - Self: Sized, - { - self.0.count() - } - - fn last(self) -> Option { - self.0.last().map(|(name, platform)| (name.0, platform)) - } - - fn nth(&mut self, n: usize) -> Option { - self.0.nth(n).map(|(name, platform)| (name.0, platform)) - } - - fn fold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0 - .map(|(name, platform)| (name.0, platform)) - .fold(init, f) - } -} - -impl<'a> std::iter::FusedIterator for PlatformRegistryIterWithNames<'a> {} - -impl<'a> ExactSizeIterator for PlatformRegistryIterWithNames<'a> {} - -impl<'a> DoubleEndedIterator for PlatformRegistryIterWithNames<'a> { - fn next_back(&mut self) -> Option { - self.0 - .next_back() - .map(|(name, platform)| (name.0, platform)) - } - - fn nth_back(&mut self, n: usize) -> Option { - self.0 - .nth_back(n) - .map(|(name, platform)| (name.0, platform)) - } - - fn rfold(self, init: B, f: F) -> B - where - F: FnMut(B, Self::Item) -> B, - { - self.0 - .map(|(name, platform)| (name.0, platform)) - .rfold(init, f) - } -} - -#[track_caller] -pub fn register_platform(kind: K) { - DynPlatform::new(kind).register(); -} - -impl Serialize for DynPlatform { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.name().serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for DynPlatform { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let name = Cow::::deserialize(deserializer)?; - match Self::registry().get_by_name(&name) { - Some(retval) => Ok(retval.clone()), - None => Err(D::Error::custom(format_args!( - "unknown platform: name not found in registry: {name:?}" - ))), - } - } -} - -#[derive(Copy, Clone, Debug, Default)] -pub struct DynPlatformValueParser; - -#[derive(Clone, PartialEq, Eq, Hash)] -struct DynPlatformValueEnum { - name: Interned, - platform: DynPlatform, -} - -impl clap::ValueEnum for DynPlatformValueEnum { - fn value_variants<'a>() -> &'a [Self] { - Interned::into_inner( - PlatformRegistrySnapshot::get() - .iter_with_names() - .map(|(name, platform)| Self { - name, - platform: platform.clone(), - }) - .collect(), - ) - } - - fn to_possible_value(&self) -> Option { - Some(clap::builder::PossibleValue::new(Interned::into_inner( - self.name, - ))) - } -} - -impl clap::builder::TypedValueParser for DynPlatformValueParser { - type Value = DynPlatform; - - fn parse_ref( - &self, - cmd: &clap::Command, - arg: Option<&clap::Arg>, - value: &std::ffi::OsStr, - ) -> clap::error::Result { - clap::builder::EnumValueParser::::new() - .parse_ref(cmd, arg, value) - .map(|v| v.platform) - } - - fn possible_values( - &self, - ) -> Option + '_>> { - static ENUM_VALUE_PARSER: OnceLock> = - OnceLock::new(); - ENUM_VALUE_PARSER - .get_or_init(clap::builder::EnumValueParser::::new) - .possible_values() - } -} - -impl clap::builder::ValueParserFactory for DynPlatform { - type Parser = DynPlatformValueParser; - - fn value_parser() -> Self::Parser { - DynPlatformValueParser::default() - } -} - -pub(crate) fn built_in_platforms() -> impl IntoIterator { - crate::vendor::built_in_platforms() -} diff --git a/crates/fayalite/src/platform/peripherals.rs b/crates/fayalite/src/platform/peripherals.rs deleted file mode 100644 index 387142d..0000000 --- a/crates/fayalite/src/platform/peripherals.rs +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::prelude::*; -use ordered_float::NotNan; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] -#[non_exhaustive] -pub struct ClockInputProperties { - pub frequency: NotNan, -} - -#[hdl(no_runtime_generics, no_static)] -pub struct ClockInput { - pub clk: Clock, - pub properties: PhantomConst, -} - -impl ClockInput { - #[track_caller] - pub fn new(frequency: f64) -> Self { - assert!( - frequency > 0.0 && frequency.is_finite(), - "invalid clock frequency: {frequency}" - ); - Self { - clk: Clock, - properties: PhantomConst::new_sized(ClockInputProperties { - frequency: NotNan::new(frequency).expect("just checked"), - }), - } - } - pub fn frequency(self) -> f64 { - self.properties.get().frequency.into_inner() - } -} - -#[hdl] -pub struct Led { - pub on: Bool, -} - -#[hdl] -pub struct RgbLed { - pub r: Bool, - pub g: Bool, - pub b: Bool, -} - -#[hdl] -/// UART, used as an output from the FPGA -pub struct Uart { - /// transmit from the FPGA's perspective - pub tx: Bool, - /// receive from the FPGA's perspective - #[hdl(flip)] - pub rx: Bool, -} diff --git a/crates/fayalite/src/prelude.rs b/crates/fayalite/src/prelude.rs index 4c5bfdf..4fca2ad 100644 --- a/crates/fayalite/src/prelude.rs +++ b/crates/fayalite/src/prelude.rs @@ -7,13 +7,13 @@ pub use crate::{ DocStringAnnotation, DontTouchAnnotation, SVAttributeAnnotation, }, array::{Array, ArrayType}, - build::{BuildCli, JobParams, RunBuild}, bundle::Bundle, + cli::Cli, clock::{Clock, ClockDomain, ToClock}, enum_::{Enum, HdlNone, HdlOption, HdlSome}, expr::{ CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr, - ReduceBits, ToExpr, ValueType, repeat, + ReduceBits, ToExpr, repeat, }, formal::{ MakeFormalExpr, all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset, @@ -27,8 +27,7 @@ pub use crate::{ Instance, Module, ModuleBuilder, annotate, connect, connect_any, incomplete_wire, instance, memory, memory_array, memory_with_init, reg_builder, wire, }, - phantom_const::{PhantomConst, PhantomConstGet}, - platform::{DynPlatform, Platform, PlatformIOBuilder, peripherals}, + phantom_const::PhantomConst, reg::Reg, reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset}, sim::{ @@ -37,7 +36,6 @@ pub use crate::{ value::{SimOnly, SimOnlyValue, SimValue, ToSimValue, ToSimValueWithType}, }, source_location::SourceLocation, - testing::{FormalMode, assert_formal}, ty::{AsMask, CanonicalType, Type}, util::{ConstUsize, GenericConstUsize}, wire::Wire, diff --git a/crates/fayalite/src/reg.rs b/crates/fayalite/src/reg.rs index 7f50655..20e0b94 100644 --- a/crates/fayalite/src/reg.rs +++ b/crates/fayalite/src/reg.rs @@ -2,7 +2,7 @@ // See Notices.txt for copyright information use crate::{ clock::ClockDomain, - expr::{Expr, Flow, ValueType, value_category::ValueCategoryExpr}, + expr::{Expr, Flow}, intern::Interned, module::{NameId, ScopedNameId}, reset::{Reset, ResetType}, @@ -20,16 +20,7 @@ pub struct Reg { init: Option>, } -impl ValueType for Reg { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } -} - -impl fmt::Debug for Reg { +impl fmt::Debug for Reg { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { name, @@ -77,7 +68,7 @@ impl Reg { "register type must be a storable type" ); if let Some(init) = init { - assert_eq!(ty, init.ty(), "register's type must match init type"); + assert_eq!(ty, Expr::ty(init), "register's type must match init type"); } Self { name: scoped_name, @@ -87,6 +78,9 @@ impl Reg { init, } } + pub fn ty(&self) -> T { + self.ty + } pub fn source_location(&self) -> SourceLocation { self.source_location } diff --git a/crates/fayalite/src/reset.rs b/crates/fayalite/src/reset.rs index 13273ac..5dff278 100644 --- a/crates/fayalite/src/reset.rs +++ b/crates/fayalite/src/reset.rs @@ -2,15 +2,13 @@ // See Notices.txt for copyright information use crate::{ clock::Clock, - expr::{CastToImpl, Expr, ValueType}, - int::{Bool, SInt, SIntValue, UInt, UIntValue}, - sim::value::SimValue, + expr::{Expr, ToExpr, ops}, + int::{Bool, SInt, UInt}, source_location::SourceLocation, ty::{ CanonicalType, OpaqueSimValueSize, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten, StaticType, Type, TypeProperties, impl_match_variant_as_self, }, - util::ConstUsize, }; use bitvec::{bits, order::Lsb0}; @@ -21,15 +19,15 @@ mod sealed { pub trait ResetType: StaticType + sealed::ResetTypeSealed - + CastToImpl - + CastToImpl> - + CastToImpl> - + CastToImpl> - + CastToImpl> - + CastToImpl, ValueOutput = UIntValue>> - + CastToImpl, ValueOutput = SIntValue>> - + CastToImpl - + CastToImpl + + ops::ExprCastTo + + ops::ExprCastTo + + ops::ExprCastTo + + ops::ExprCastTo + + ops::ExprCastTo + + ops::ExprCastTo> + + ops::ExprCastTo> + + ops::ExprCastTo + + ops::ExprCastTo { fn dispatch(input: D::Input, dispatch: D) -> D::Output; } @@ -134,34 +132,29 @@ macro_rules! reset_type { } pub trait $Trait { - type Output: ValueType; - fn $trait_fn(&self) -> Self::Output; + fn $trait_fn(&self) -> Expr<$name>; } impl $Trait for &'_ T { - type Output = T::Output; - fn $trait_fn(&self) -> Self::Output { + fn $trait_fn(&self) -> Expr<$name> { (**self).$trait_fn() } } impl $Trait for &'_ mut T { - type Output = T::Output; - fn $trait_fn(&self) -> Self::Output { + fn $trait_fn(&self) -> Expr<$name> { (**self).$trait_fn() } } impl $Trait for Box { - type Output = T::Output; - fn $trait_fn(&self) -> Self::Output { + fn $trait_fn(&self) -> Expr<$name> { (**self).$trait_fn() } } $($impl_trait $Trait for Expr<$name> { - type Output = Expr<$name>; - fn $trait_fn(&self) -> Self::Output { + fn $trait_fn(&self) -> Expr<$name> { *self } })? @@ -178,15 +171,13 @@ reset_type!( ); impl ToSyncReset for bool { - type Output = SimValue; - fn to_sync_reset(&self) -> Self::Output { - SimValue::from_value(SyncReset, *self) + fn to_sync_reset(&self) -> Expr { + self.to_expr().to_sync_reset() } } impl ToAsyncReset for bool { - type Output = SimValue; - fn to_async_reset(&self) -> Self::Output { - SimValue::from_value(AsyncReset, *self) + fn to_async_reset(&self) -> Expr { + self.to_expr().to_async_reset() } } diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 7068e44..1717aec 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -6,15 +6,13 @@ use crate::{ bundle::{BundleField, BundleType}, expr::{ - Flow, + Flow, ToLiteralBits, target::{ GetTarget, Target, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, }, }, int::BoolOrIntType, - intern::{ - Intern, InternSlice, Interned, InternedCompare, PtrEqWithTypeId, SupportsPtrEqWithTypeId, - }, + intern::{Intern, Interned, InternedCompare, PtrEqWithTypeId, SupportsPtrEqWithTypeId}, module::{ ModuleIO, transform::visit::{Fold, Folder, Visit, Visitor}, @@ -24,7 +22,7 @@ use crate::{ sim::{ compiler::{ Compiled, CompiledBundleField, CompiledExternModule, CompiledTypeLayoutBody, - CompiledValue, ExternModuleClockForPast, + CompiledValue, }, interpreter::{ BreakAction, BreakpointsSet, RunResult, SmallUInt, State, @@ -47,18 +45,18 @@ use num_bigint::BigInt; use num_traits::{Signed, Zero}; use std::{ any::Any, - cell::{Cell, RefCell}, - collections::{BTreeMap, BTreeSet}, + borrow::Cow, + cell::RefCell, + collections::BTreeMap, fmt, future::{Future, IntoFuture}, hash::Hash, mem, - pin::{Pin, pin}, + pin::Pin, ptr, rc::Rc, - sync::{Arc, Mutex, MutexGuard}, + sync::Arc, task::Poll, - usize, }; pub mod compiler; @@ -264,7 +262,7 @@ impl_trace_decl! { }), Instance(TraceInstance { fn children(self) -> _ { - [self.instance_io.into(), self.module.into()].intern_slice() + [self.instance_io.into(), self.module.into()][..].intern() } name: Interned, instance_io: TraceBundle, @@ -284,7 +282,7 @@ impl_trace_decl! { }), MemPort(TraceMemPort { fn children(self) -> _ { - [self.bundle.into()].intern_slice() + [self.bundle.into()][..].intern() } name: Interned, bundle: TraceBundle, @@ -292,7 +290,7 @@ impl_trace_decl! { }), Wire(TraceWire { fn children(self) -> _ { - [*self.child].intern_slice() + [*self.child][..].intern() } name: Interned, child: Interned, @@ -300,7 +298,7 @@ impl_trace_decl! { }), Reg(TraceReg { fn children(self) -> _ { - [*self.child].intern_slice() + [*self.child][..].intern() } name: Interned, child: Interned, @@ -308,7 +306,7 @@ impl_trace_decl! { }), ModuleIO(TraceModuleIO { fn children(self) -> _ { - [*self.child].intern_slice() + [*self.child][..].intern() } name: Interned, child: Interned, @@ -415,15 +413,6 @@ impl_trace_decl! { name: Interned, flow: Flow, }), - PhantomConst(TracePhantomConst { - fn location(self) -> _ { - self.location - } - location: TraceLocation, - name: Interned, - ty: PhantomConst, - flow: Flow, - }), SimOnly(TraceSimOnly { fn location(self) -> _ { self.location @@ -534,11 +523,6 @@ pub trait TraceWriter: fmt::Debug + 'static { variant_index: usize, ty: Enum, ) -> Result<(), Self::Error>; - fn set_signal_phantom_const( - &mut self, - id: TraceScalarId, - ty: PhantomConst, - ) -> Result<(), Self::Error>; fn set_signal_sim_only_value( &mut self, id: TraceScalarId, @@ -598,11 +582,6 @@ trait TraceWriterDynTrait: fmt::Debug + 'static { variant_index: usize, ty: Enum, ) -> std::io::Result<()>; - fn set_signal_phantom_const_dyn( - &mut self, - id: TraceScalarId, - ty: PhantomConst, - ) -> std::io::Result<()>; fn set_signal_sim_only_value_dyn( &mut self, id: TraceScalarId, @@ -667,13 +646,6 @@ impl TraceWriterDynTrait for T { .map_err(err_into_io)?, ) } - fn set_signal_phantom_const_dyn( - &mut self, - id: TraceScalarId, - ty: PhantomConst, - ) -> std::io::Result<()> { - Ok(TraceWriter::set_signal_phantom_const(self, id, ty).map_err(err_into_io)?) - } fn set_signal_sim_only_value_dyn( &mut self, id: TraceScalarId, @@ -745,13 +717,6 @@ impl TraceWriter for DynTraceWriter { self.0 .set_signal_enum_discriminant_dyn(id, variant_index, ty) } - fn set_signal_phantom_const( - &mut self, - id: TraceScalarId, - ty: PhantomConst, - ) -> Result<(), Self::Error> { - self.0.set_signal_phantom_const_dyn(id, ty) - } fn set_signal_sim_only_value( &mut self, id: TraceScalarId, @@ -927,16 +892,12 @@ pub(crate) enum SimTraceKind { index: StatePartIndex, ty: DynSimOnly, }, - PhantomConst { - ty: PhantomConst, - }, } #[derive(PartialEq, Eq)] pub(crate) enum SimTraceState { Bits(BitVec), SimOnly(DynSimOnlyValue), - PhantomConst, } impl Clone for SimTraceState { @@ -944,7 +905,6 @@ impl Clone for SimTraceState { match self { Self::Bits(v) => Self::Bits(v.clone()), Self::SimOnly(v) => Self::SimOnly(v.clone()), - Self::PhantomConst => Self::PhantomConst, } } fn clone_from(&mut self, source: &Self) { @@ -993,7 +953,6 @@ impl fmt::Debug for SimTraceState { match self { SimTraceState::Bits(v) => BitSliceWriteWithBase(v).fmt(f), SimTraceState::SimOnly(v) => v.fmt(f), - SimTraceState::PhantomConst => f.debug_tuple("PhantomConst").finish(), } } } @@ -1020,7 +979,6 @@ impl SimTraceKind { SimTraceKind::EnumDiscriminant { index: _, ty } => { SimTraceState::Bits(BitVec::repeat(false, ty.discriminant_bit_width())) } - SimTraceKind::PhantomConst { .. } => SimTraceState::PhantomConst, SimTraceKind::SimOnly { index: _, ty } => SimTraceState::SimOnly(ty.default_value()), } } @@ -1039,12 +997,6 @@ impl MaybeNeedsSettle { MaybeNeedsSettle::NoSettleNeeded(v) => MaybeNeedsSettle::NoSettleNeeded(f(v)), } } - fn into_inner(self) -> T { - match self { - MaybeNeedsSettle::NeedsSettle(v) => v, - MaybeNeedsSettle::NoSettleNeeded(v) => v, - } - } } // workaround implementing FnOnce not being stable @@ -1079,7 +1031,6 @@ struct SimulationModuleState { uninitialized_ios: HashMap>, io_targets: HashMap>, did_initial_settle: bool, - clocks_for_past: HashMap, SimulationExternModuleClockForPast>, } impl fmt::Debug for SimulationModuleState { @@ -1089,37 +1040,23 @@ impl fmt::Debug for SimulationModuleState { uninitialized_ios, io_targets, did_initial_settle, - clocks_for_past, } = 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) - .field("clocks_for_past", &SortedMapDebug(clocks_for_past)) .finish() } } impl SimulationModuleState { - fn new( - base_targets: impl IntoIterator)>, - clocks_for_past: &[ExternModuleClockForPast], - ) -> Self { + 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, - clocks_for_past: clocks_for_past - .iter() - .map(|clock_for_past| { - ( - clock_for_past.clock_for_past, - SimulationExternModuleClockForPast::new(clock_for_past), - ) - }) - .collect(), }; for (base_target, value) in base_targets { retval.base_targets.push(base_target); @@ -1157,7 +1094,6 @@ impl SimulationModuleState { true } } - CompiledTypeLayoutBody::PhantomConst => false, CompiledTypeLayoutBody::Bundle { .. } => { let value = value.map_ty(Bundle::from_canonical); let mut sub_targets = Vec::new(); @@ -1248,34 +1184,7 @@ impl SimulationModuleState { } } #[track_caller] - fn is_reset_async(&self, io: Expr, which_module: WhichModule) -> bool { - 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" - ), - } - }; - match self.get_io(*target, which_module).layout.ty { - CanonicalType::UInt(_) - | CanonicalType::SInt(_) - | CanonicalType::Bool(_) - | CanonicalType::Array(_) - | CanonicalType::Enum(_) - | CanonicalType::Bundle(_) - | CanonicalType::Reset(_) - | CanonicalType::Clock(_) - | CanonicalType::PhantomConst(_) - | CanonicalType::DynSimOnly(_) => unreachable!(), - CanonicalType::AsyncReset(_) => true, - CanonicalType::SyncReset(_) => false, - } - } - #[track_caller] - fn read_helper_current( + fn read_helper( &self, io: Expr, which_module: WhichModule, @@ -1320,33 +1229,6 @@ impl SimulationModuleState { } } #[track_caller] - fn read_helper( - &self, - io: Expr, - read_time: ReadTime, - which_module: WhichModule, - ) -> MaybeNeedsSettle> { - match read_time { - ReadTime::Current => self.read_helper_current(io, which_module), - ReadTime::Past { clock_for_past } => { - let current = self.read_helper_current(io, which_module); - let clock_for_past_value = self - .read_helper_current(Expr::canonical(clock_for_past), which_module) - .into_inner() - .map_ty(Clock::from_canonical); - let Some(clock_for_past) = self.clocks_for_past.get(&clock_for_past_value) else { - panic!( - "In order to use the `read_past()` family of functions,\n\ - you must call `m.register_clock_for_past(my_io.clk)`\n\ - in the module's body for every clock you use as the\n\ - second argument of the `read_past()` family." - ); - }; - current.map(|current| clock_for_past.current_to_past_map[¤t]) - } - } - } - #[track_caller] fn write_helper( &mut self, io: Expr, @@ -1378,71 +1260,149 @@ impl SimulationModuleState { } } -struct SimulationExternModuleClockForPast { - current_to_past_map: HashMap, CompiledValue>, +#[derive(Copy, Clone, Debug)] +enum WaitTarget { + Settle, + Instant(SimInstant), + Change { key: ChangeKey, value: ChangeValue }, } -impl fmt::Debug for SimulationExternModuleClockForPast { +#[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 { - let Self { - current_to_past_map, - } = self; - f.debug_struct("SimulationExternModuleClockForPast") - .field("current_to_past_map", &SortedMapDebug(current_to_past_map)) - .finish() + f.debug_set().entries(self.iter()).finish() } } -impl SimulationExternModuleClockForPast { - fn new(clock_for_past: &ExternModuleClockForPast) -> Self { - let mut retval = Self { - current_to_past_map: HashMap::default(), - }; - for (current, past) in clock_for_past.current_to_past_map { - retval.add_current_to_past_mapping(current, past); +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 } - fn add_current_to_past_mapping( - &mut self, - current: CompiledValue, - past: CompiledValue, - ) { - self.current_to_past_map.insert(current, past); - match current.layout.body { - CompiledTypeLayoutBody::Scalar | CompiledTypeLayoutBody::PhantomConst => {} - CompiledTypeLayoutBody::Array { .. } => { - let current = current.map_ty(Array::from_canonical); - let past = past.map_ty(Array::from_canonical); - for index in 0..current.layout.ty.len() { - self.add_current_to_past_mapping(current.element(index), past.element(index)); - } - } - CompiledTypeLayoutBody::Bundle { .. } => { - let current = current.map_ty(Bundle::from_canonical); - let past = past.map_ty(Bundle::from_canonical); - for BundleField { name, .. } in current.layout.ty.fields() { - self.add_current_to_past_mapping( - current.field_by_name(name), - past.field_by_name(name), - ); - } - } - } - } -} - -enum ReadTime { - Current, - Past { clock_for_past: Expr }, } struct SimulationExternModuleState { module_state: SimulationModuleState, sim: ExternModuleSimulation, running_generator: Option + 'static>>>, - waker: Arc, - debug_name: Interned, + wait_targets: EarliestWaitTargets, } impl fmt::Debug for SimulationExternModuleState { @@ -1451,8 +1411,7 @@ impl fmt::Debug for SimulationExternModuleState { module_state, sim, running_generator, - waker: _, - debug_name: _, + wait_targets, } = self; f.debug_struct("SimulationExternModuleState") .field("module_state", module_state) @@ -1461,6 +1420,7 @@ impl fmt::Debug for SimulationExternModuleState { "running_generator", &running_generator.as_ref().map(|_| DebugAsDisplay("...")), ) + .field("wait_targets", wait_targets) .finish() } } @@ -1503,10 +1463,9 @@ impl MaybeNeedsSettleFn<&'_ mut interpreter::State> for ReadBo fn call(self, state: &mut interpreter::State) -> Self::Output { let Self { compiled_value, io } = self; match compiled_value.range.len().as_single() { - Some(TypeLenSingle::SmallSlot) => io - .ty() + Some(TypeLenSingle::SmallSlot) => Expr::ty(io) .value_from_int_wrapping(state.small_slots[compiled_value.range.small_slots.start]), - Some(TypeLenSingle::BigSlot) => io.ty().value_from_int_wrapping( + Some(TypeLenSingle::BigSlot) => Expr::ty(io).value_from_int_wrapping( state.big_slots[compiled_value.range.big_slots.start].clone(), ), Some(TypeLenSingle::SimOnlySlot) | None => unreachable!(), @@ -1528,350 +1487,28 @@ impl MaybeNeedsSettleFn<&'_ mut interpreter::State> for ReadFn { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -enum EventKind { - State, - ExternModule(usize), -} +struct GeneratorWaker; -impl PartialOrd for EventKind { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for EventKind { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - match (self, other) { - (Self::State, Self::State) => std::cmp::Ordering::Equal, - (Self::State, Self::ExternModule(_)) => std::cmp::Ordering::Less, - (Self::ExternModule(_), Self::State) => std::cmp::Ordering::Greater, - (Self::ExternModule(this), Self::ExternModule(other)) => this.cmp(other), - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -struct Event { - instant: SimInstant, - kind: EventKind, -} - -impl PartialOrd for Event { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Event { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - let Self { instant, kind } = other; - self.instant.cmp(instant).then(self.kind.cmp(kind)) - } -} - -struct HashableWaker(std::task::Waker); - -impl Clone for HashableWaker { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - - fn clone_from(&mut self, source: &Self) { - self.0.clone_from(&source.0); - } -} - -impl PartialEq for HashableWaker { - fn eq(&self, other: &Self) -> bool { - self.0.will_wake(&other.0) - } -} - -impl Eq for HashableWaker {} - -impl Hash for HashableWaker { - fn hash(&self, state: &mut H) { - self.0.data().hash(state); - let vtable: *const std::task::RawWakerVTable = self.0.vtable(); - vtable.hash(state); - } -} - -enum EventWakers { - Wakers(HashSet), - CurrentlyWaking, -} - -impl EventWakers { - fn start_waking(&mut self) -> HashSet { - match std::mem::replace(self, Self::CurrentlyWaking) { - Self::Wakers(retval) => retval, - Self::CurrentlyWaking => unreachable!(), - } - } -} - -impl fmt::Debug for EventWakers { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Wakers(wakers) => f.debug_tuple("Wakers").field(&wakers.len()).finish(), - Self::CurrentlyWaking => write!(f, "CurrentlyWaking"), - } - } -} - -struct EventQueueData { - instant: SimInstant, - events: BTreeMap, - trace: bool, -} - -impl fmt::Debug for EventQueueData { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - instant, - events, - trace: _, - } = self; - f.debug_struct("EventQueueData") - .field("instant", instant) - .field("events", events) - .finish() - } -} - -struct EventQueueFirstEvent<'a> { - event_queue: Arc, - event_queue_lock: MutexGuard<'a, EventQueueData>, -} - -impl<'a> EventQueueFirstEvent<'a> { - fn event(&self) -> &Event { - self.event_queue_lock - .events - .first_key_value() - .expect("known to be non-empty") - .0 - } - fn remove_and_wake_all_wakers(self) { - let Self { - event_queue, - mut event_queue_lock, - } = self; - let trace = event_queue_lock.trace; - let mut entry = event_queue_lock - .events - .first_entry() - .expect("known to be non-empty"); - let wakers = entry.get_mut().start_waking(); - let event = *entry.key(); - if wakers.is_empty() { - entry.remove(); - if trace { - println!( - "EventQueue first_event remove_and_wake_all_wakers(): event={event:?} no wakers", - ); - } - drop(event_queue_lock); - return; - } - drop(event_queue_lock); - if trace { - println!( - "EventQueue first_event remove_and_wake_all_wakers(): event={event:?} wakers_len={}", - wakers.len() - ); - } - for waker in wakers { - waker.0.wake(); - } - event_queue.lock().events.remove(&event); - if trace { - println!( - "EventQueue first_event remove_and_wake_all_wakers(): event={event:?} finished waking", - ); - } - } - fn into_event_queue_lock(self) -> MutexGuard<'a, EventQueueData> { - self.event_queue_lock - } -} - -impl EventQueueData { - fn new(instant: SimInstant, trace: bool) -> Self { - Self { - instant, - events: BTreeMap::new(), - trace, - } - } - fn instant(&self) -> SimInstant { - self.instant - } - fn set_instant(&mut self, instant: SimInstant) { - if self.trace { - println!("EventQueue set_instant({instant:?})"); - } - self.instant = instant; - } - fn add_event( - &mut self, - mut event: Event, - waker: Option, - ) -> Result<(), std::task::Waker> { - event.instant = event.instant.max(self.instant); - let wakers = self - .events - .entry(event) - .or_insert_with(|| EventWakers::Wakers(HashSet::default())); - let EventWakers::Wakers(wakers) = wakers else { - return match waker { - Some(waker) => Err(waker), - None => Ok(()), - }; - }; - if self.trace { - println!( - "EventQueue add_event({event:?}, {:?})", - waker.is_some().then_some(format_args!("")) - ); - } - wakers.extend(waker.map(HashableWaker)); - Ok(()) - } - fn add_event_for_now(&mut self, kind: EventKind) { - self.add_event( - Event { - instant: self.instant, - kind, - }, - None, - ) - .expect("no waker passed in") - } - fn first_event<'a>( - this: MutexGuard<'a, EventQueueData>, - event_queue: Arc, - ) -> Result, MutexGuard<'a, EventQueueData>> { - if this.events.is_empty() { - Err(this) - } else { - Ok(EventQueueFirstEvent { - event_queue, - event_queue_lock: this, - }) - } - } - fn peek_first_event(&self) -> Option { - Some(*self.events.first_key_value()?.0) - } - fn peek_first_event_for_now(&self) -> Option { - self.peek_first_event() - .filter(|event| event.instant <= self.instant) - } -} - -struct EventQueue(Mutex); - -impl fmt::Debug for EventQueue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("EventQueue(")?; - if let Ok(data) = self.0.try_lock() { - (*data).fmt(f)?; - } else { - f.write_str("")?; - } - f.write_str(")") - } -} - -impl EventQueue { - fn new(data: EventQueueData) -> Self { - Self(Mutex::new(data)) - } - fn lock(&self) -> MutexGuard<'_, EventQueueData> { - self.0.lock().expect("not poisoned") - } - fn add_event_for_now(&self, kind: EventKind) { - self.lock().add_event_for_now(kind); - } - fn peek_first_event_for_now(&self) -> Option { - self.lock().peek_first_event_for_now() - } -} - -struct ExternModuleGeneratorWaker { - event_queue: std::sync::Weak, - module_index: usize, -} - -impl std::task::Wake for ExternModuleGeneratorWaker { +impl std::task::Wake for GeneratorWaker { fn wake(self: Arc) { - self.wake_by_ref(); - } - fn wake_by_ref(self: &Arc) { - if let Some(event_queue) = self.event_queue.upgrade() { - event_queue.add_event_for_now(EventKind::ExternModule(self.module_index)); - } + panic!("can't await other kinds of futures in function passed to ExternalModuleSimulation"); } } -struct SensitivitySet { - debug_id: u64, - compiled_values: HashSet>>, - values: Vec<( - Rc>, - Rc>, - )>, - waker: RefCell, - changed: Cell, +#[derive(Default)] +struct ReadyToRunSet { + state_ready_to_run: bool, + extern_modules_ready_to_run: Vec, } -struct SensitivitySetJustId<'a>(&'a SensitivitySet); - -impl fmt::Debug for SensitivitySetJustId<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.debug_fmt(true, f) - } -} - -impl fmt::Debug for SensitivitySet { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.debug_fmt(false, f) - } -} - -impl SensitivitySet { - fn debug_fmt(&self, just_id: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl ReadyToRunSet { + fn clear(&mut self) { let Self { - debug_id, - compiled_values: _, - values, - waker: _, - changed, + state_ready_to_run, + extern_modules_ready_to_run, } = self; - struct DebugValues<'a>( - &'a [( - Rc>, - Rc>, - )], - ); - impl<'a> fmt::Debug for DebugValues<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_map() - .entries(self.0.iter().map(|(k, v)| (k, v))) - .finish() - } - } - let mut debug_struct = f.debug_struct("SensitivitySet"); - debug_struct.field("id", debug_id); - if !just_id { - debug_struct - .field("values", &DebugValues(values)) - .field("changed", changed); - } - debug_struct.finish_non_exhaustive() + *state_ready_to_run = false; + extern_modules_ready_to_run.clear(); } } @@ -1880,22 +1517,15 @@ struct SimulationImpl { io: Expr, main_module: SimulationModuleState, extern_modules: Box<[SimulationExternModuleState]>, + state_ready_to_run: bool, trace_decls: TraceModule, traces: SimTraces]>>, - trace_memories: BTreeMap, TraceMem>, + trace_memories: HashMap, TraceMem>, trace_writers: Vec>, + instant: SimInstant, clocks_triggered: Interned<[StatePartIndex]>, breakpoints: Option, - event_queue: Arc, - next_sensitivity_set_debug_id: u64, - waiting_sensitivity_sets_by_compiled_value: HashMap< - Rc>, - ( - Rc>, - HashMap<*const SensitivitySet, Rc>, - ), - >, - waiting_sensitivity_sets_by_address: HashMap<*const SensitivitySet, Rc>, + generator_waker: std::task::Waker, } impl fmt::Debug for SimulationImpl { @@ -1904,70 +1534,6 @@ impl fmt::Debug for SimulationImpl { } } -struct DebugSensitivitySetsByAddress<'a> { - sensitivity_sets: &'a HashMap<*const SensitivitySet, Rc>, - just_id: bool, -} - -impl<'a> fmt::Debug for DebugSensitivitySetsByAddress<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - sensitivity_sets, - just_id, - } = *self; - let mut values: Vec<_> = sensitivity_sets.values().collect(); - values.sort_by_key(|v| v.debug_id); - if just_id { - f.debug_set() - .entries( - values - .iter() - .map(|sensitivity_set| SensitivitySetJustId(sensitivity_set)), - ) - .finish() - } else { - f.debug_set().entries(values).finish() - } - } -} - -struct DebugSensitivitySetsByCompiledValue<'a>( - &'a HashMap< - Rc>, - ( - Rc>, - HashMap<*const SensitivitySet, Rc>, - ), - >, -); - -impl<'a> fmt::Debug for DebugSensitivitySetsByCompiledValue<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut values: Vec<_> = self - .0 - .iter() - .map(|(compiled_value, (sim_value, sensitivity_sets))| { - ( - DebugAsDisplay(if f.alternate() { - format!("{compiled_value:#?}") - } else { - format!("{compiled_value:?}") - }), - ( - sim_value, - DebugSensitivitySetsByAddress { - sensitivity_sets, - just_id: true, - }, - ), - ) - }) - .collect(); - values.sort_by(|l, r| l.0.0.cmp(&r.0.0)); - f.debug_map().entries(values).finish() - } -} - impl SimulationImpl { fn debug_fmt(&self, io: Option<&dyn fmt::Debug>, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { @@ -1975,75 +1541,48 @@ impl SimulationImpl { io: self_io, main_module, extern_modules, + state_ready_to_run, trace_decls, traces, trace_memories, trace_writers, + instant, clocks_triggered, breakpoints: _, - event_queue, - next_sensitivity_set_debug_id: _, - waiting_sensitivity_sets_by_compiled_value, - waiting_sensitivity_sets_by_address, + 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) - .field("event_queue", event_queue) - .field( - "waiting_sensitivity_sets_by_address", - &DebugSensitivitySetsByAddress { - sensitivity_sets: waiting_sensitivity_sets_by_address, - just_id: false, - }, - ) - .field( - "waiting_sensitivity_sets_by_compiled_value", - &DebugSensitivitySetsByCompiledValue(waiting_sensitivity_sets_by_compiled_value), - ) .finish_non_exhaustive() } fn new(compiled: Compiled) -> Self { let io_target = Target::from(compiled.io); - let mut event_queue = EventQueueData::new(SimInstant::START, false); - event_queue.add_event_for_now(EventKind::State); - for module_index in 0..compiled.extern_modules.len() { - event_queue.add_event_for_now(EventKind::ExternModule(module_index)); - } - let event_queue = Arc::new(EventQueue::new(event_queue)); - let extern_modules = Box::from_iter(compiled.extern_modules.iter().enumerate().map( - |( - module_index, - &CompiledExternModule { - module_io_targets, - module_io, - clocks_for_past, - simulation, - debug_name, - }, - )| { + 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()), - &clocks_for_past, ), sim: simulation, running_generator: None, - waker: Arc::new(ExternModuleGeneratorWaker { - event_queue: Arc::downgrade(&event_queue), - module_index, - }), - debug_name, + wait_targets: EarliestWaitTargets::settle(), } }, )); @@ -2066,9 +1605,9 @@ impl SimulationImpl { value, ) }), - &[], ), extern_modules, + state_ready_to_run: true, trace_decls: compiled.base_module.trace_decls, traces: SimTraces(Box::from_iter(compiled.traces.0.iter().map( |&SimTrace { @@ -2081,14 +1620,12 @@ impl SimulationImpl { last_state: kind.make_state(), }, ))), - trace_memories: BTreeMap::from_iter(compiled.trace_memories.iter().copied()), + trace_memories: HashMap::from_iter(compiled.trace_memories.iter().copied()), trace_writers: vec![], + instant: SimInstant::START, clocks_triggered: compiled.clocks_triggered, breakpoints: None, - event_queue, - next_sensitivity_set_debug_id: 0, - waiting_sensitivity_sets_by_compiled_value: HashMap::default(), - waiting_sensitivity_sets_by_address: HashMap::default(), + generator_waker: Arc::new(GeneratorWaker).into(), } } fn write_traces( @@ -2160,9 +1697,6 @@ impl SimulationImpl { ty, )?; } - SimTraceKind::PhantomConst { ty } => { - trace_writer.set_signal_phantom_const(id, ty)? - } SimTraceKind::SimOnly { .. } => { trace_writer.set_signal_sim_only_value(id, state.unwrap_sim_only_ref())? } @@ -2233,7 +1767,6 @@ impl SimulationImpl { .unwrap_bits_mut() .set(0, self.state.small_slots[index] != 0); } - SimTraceKind::PhantomConst { .. } => {} SimTraceKind::SimOnly { index, ty: _ } => { state .unwrap_sim_only_mut() @@ -2247,198 +1780,137 @@ impl SimulationImpl { } #[track_caller] fn advance_time(this_ref: &Rc>, duration: SimDuration) { - Self::run_until(this_ref, &mut |instant| instant.checked_add(duration)); + let run_target = this_ref.borrow().instant + duration; + Self::run_until(this_ref, run_target); } - fn wake_after_change(&mut self, sensitivity_set: Rc) { - let None = self - .waiting_sensitivity_sets_by_address - .insert(Rc::as_ptr(&sensitivity_set), sensitivity_set.clone()) - else { - // already added - return; - }; - if self.breakpoints.as_ref().is_some_and(|v| v.trace) { - println!("SimulationImpl::wake_after_change:\n{sensitivity_set:#?}"); - } - let SensitivitySet { - debug_id: _, - compiled_values: _, - values, - waker: _, - changed: _, - } = &*sensitivity_set; - for (compiled_value, sim_value) in values { - self.waiting_sensitivity_sets_by_compiled_value - .entry(compiled_value.clone()) - .or_insert_with(|| (sim_value.clone(), HashMap::default())) - .1 - .insert(Rc::as_ptr(&sensitivity_set), sensitivity_set.clone()); - } - } - fn cancel_wake_after_change(&mut self, sensitivity_set: &Rc) { - let Some(_) = self - .waiting_sensitivity_sets_by_address - .remove(&Rc::as_ptr(&sensitivity_set)) - else { - return; - }; - if self.breakpoints.as_ref().is_some_and(|v| v.trace) { - println!("SimulationImpl::cancel_wake_after_change:\n{sensitivity_set:#?}"); - } - let SensitivitySet { - debug_id: _, - compiled_values: _, - values, - waker: _, - changed: _, - } = &**sensitivity_set; - for (compiled_value, _) in values { - if let hashbrown::hash_map::Entry::Occupied(mut entry) = self - .waiting_sensitivity_sets_by_compiled_value - .entry(compiled_value.clone()) - { - entry.get_mut().1.remove(&Rc::as_ptr(&sensitivity_set)); - if entry.get().1.is_empty() { - entry.remove(); - } - } - } - } - fn try_wake_at_instant( - &mut self, + /// clears `targets` + #[must_use] + fn yield_wait<'a>( + this: Rc>, module_index: usize, - instant: &mut dyn FnMut(SimInstant) -> Option, - waker: std::task::Waker, - ) -> Result<(), std::task::Waker> { - let mut event_queue = self.event_queue.lock(); - let Some(instant) = instant(event_queue.instant()) else { - return Err(waker); - }; - match event_queue.add_event( - Event { - instant, - kind: EventKind::ExternModule(module_index), - }, - Some(waker), - ) { - Ok(()) => {} - Err(waker) => { - drop(event_queue); - waker.wake(); + 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 } } - Ok(()) + MyGenerator { + sim: this, + yielded_at_all: false, + module_index, + targets, + } } async fn yield_advance_time_or_settle( - this: &RefCell, + this: Rc>, module_index: usize, duration: Option, ) { - let mut target_instant = None; - std::future::poll_fn(|cx| { - match this.borrow_mut().try_wake_at_instant( - module_index, - &mut |instant| match target_instant { - Some(target_instant) => { - // already waited at least once - if instant < target_instant { - Some(target_instant) - } else { - None - } - } - None => { - target_instant = instant.checked_add(duration.unwrap_or(SimDuration::ZERO)); - target_instant - } - }, - cx.waker().clone(), - ) { - Ok(()) => Poll::Pending, - Err(_waker) => { - if target_instant.is_none() { - // don't panic in try_wait_at_instant to avoid poisoning the lock - panic!("SimInstant overflow"); - } - Poll::Ready(()) - } - } - }) - .await + let mut targets = duration.map_or(EarliestWaitTargets::settle(), |duration| { + EarliestWaitTargets::instant(this.borrow().instant + duration) + }); + Self::yield_wait(this, module_index, &mut targets).await; } - async fn yield_wait_for_changes( - this: &RefCell, - module_index: usize, - sensitivity_set: SensitivitySet, - timeout: Option, - ) { - if let Some(timeout) = timeout { - if timeout == SimDuration::ZERO { - return Self::yield_advance_time_or_settle(this, module_index, None).await; - } - } - let sensitivity_set = Rc::new(sensitivity_set); - struct CancelOnDrop<'a> { - this: &'a RefCell, - sensitivity_set: &'a Rc, - } - impl Drop for CancelOnDrop<'_> { - fn drop(&mut self) { - let Self { - this, - sensitivity_set, - } = self; - this.borrow_mut().cancel_wake_after_change(&sensitivity_set); - } - } - let _cancel_on_drop = CancelOnDrop { - this, - sensitivity_set: &sensitivity_set, - }; - let mut timeout_instant = None; - std::future::poll_fn(|cx| { - if sensitivity_set.changed.get() { - return Poll::Ready(()); - } - sensitivity_set.waker.borrow_mut().clone_from(cx.waker()); - let mut this = this.borrow_mut(); - this.wake_after_change(sensitivity_set.clone()); - if let Some(timeout) = timeout { - match this.try_wake_at_instant( - module_index, - &mut |instant| match timeout_instant { - Some(timeout_instant) => { - if instant < timeout_instant { - Some(timeout_instant) - } else { - None - } - } - None => { - timeout_instant = instant.checked_add(timeout); - timeout_instant - } - }, - cx.waker().clone(), - ) { - Ok(()) => Poll::Pending, - Err(_waker) => { - if timeout_instant.is_none() { - // don't panic in try_wait_at_instant to avoid poisoning the lock - panic!("SimInstant overflow"); - } - Poll::Ready(()) + 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::opaque(value)) { + 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 { - Poll::Pending + retval = Some(instant); } - }) - .await; + 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; + self.for_each_trace_writer_storing_error(|this, mut trace_writer_state| { + match &mut trace_writer_state { + TraceWriterState::Decls(_) | TraceWriterState::Init(_) => unreachable!(), + TraceWriterState::Running(trace_writer) => { + trace_writer.change_time_to(this.instant)?; + } + TraceWriterState::Errored(_) => {} + } + Ok(trace_writer_state) + }); } #[must_use] #[track_caller] - fn run_state_settle_cycle(&mut self) { + 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 { @@ -2469,213 +1941,138 @@ impl SimulationImpl { .iter() .any(|i| self.state.small_slots[*i] != 0) { - if self.breakpoints.as_ref().is_some_and(|v| v.trace) { - println!("SimulationImpl clocks triggered"); - } - self.event_queue.add_event_for_now(EventKind::State); + self.state_ready_to_run = true; + true + } else { + false } } #[track_caller] - fn run_extern_module(this_ref: &Rc>, module_index: usize) { - let mut this = this_ref.borrow_mut(); - let trace = this.breakpoints.as_ref().is_some_and(|v| v.trace); - let extern_module = &mut this.extern_modules[module_index]; - let debug_name = extern_module.debug_name; - let waker = std::task::Waker::from(extern_module.waker.clone()); - let mut generator = if !extern_module.module_state.did_initial_settle { - let sim = extern_module.sim; - drop(this); - if trace { - println!("{debug_name}: start"); - } - Box::into_pin(sim.run(ExternModuleSimulationState { - sim_impl: this_ref.clone(), - module_index, - })) - } else if let Some(generator) = extern_module.running_generator.take() { - drop(this); - generator - } else { - return; - }; - if trace { - println!("{debug_name}: poll"); - } - let poll_result = generator - .as_mut() - .poll(&mut std::task::Context::from_waker(&waker)); - let generator = match poll_result { - Poll::Ready(()) => None, - Poll::Pending => Some(generator), - }; - if trace { - println!("{debug_name}: poll returned {poll_result:?}"); - } - 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; - } - fn check_waiting_sensitivity_sets(&mut self) { - if let Some(Event { - instant: _, - kind: EventKind::State, - }) = self.event_queue.peek_first_event_for_now() - { - return; - } - let mut triggered = HashMap::<*const SensitivitySet, Rc>::default(); - for (compiled_value, (sim_value, sensitivity_sets)) in - &self.waiting_sensitivity_sets_by_compiled_value - { - if Self::value_changed( - &mut self.state, - **compiled_value, - SimValue::opaque(sim_value), - ) { - triggered.extend(sensitivity_sets.iter().map(|(&k, v)| (k, v.clone()))); - } - } - for sensitivity_set in triggered.into_values() { - sensitivity_set.changed.set(true); - sensitivity_set.waker.borrow().wake_by_ref(); - self.cancel_wake_after_change(&sensitivity_set); - } - } - fn write_traces_after_event(&mut self) { - if let Some(Event { - instant: _, - kind: EventKind::State, - }) = self.event_queue.peek_first_event_for_now() - { - return; - } - if self.main_module.did_initial_settle { - self.read_traces::(); - } else { - self.read_traces::(); - } - self.state.memory_write_log.sort_unstable(); - self.state.memory_write_log.dedup(); - self.main_module.did_initial_settle = true; - 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( - this.trace_decls, - this.traces.0.len(), - this.trace_memories.len(), - )?)?, - ), - TraceWriterState::Init(trace_writer) => { - TraceWriterState::Running(this.init_trace_writer(trace_writer)?) - } - TraceWriterState::Running(trace_writer) => { - TraceWriterState::Running(this.update_trace_writer(trace_writer)?) - } - TraceWriterState::Errored(e) => TraceWriterState::Errored(e), - }) - }); - self.state.memory_write_log.clear(); - } - fn write_traces_change_time_to(&mut self, new_instant: SimInstant) { - self.for_each_trace_writer_storing_error(|_this, mut trace_writer_state| { - match &mut trace_writer_state { - TraceWriterState::Decls(_) | TraceWriterState::Init(_) => unreachable!(), - TraceWriterState::Running(trace_writer) => { - trace_writer.change_time_to(new_instant)?; - } - TraceWriterState::Errored(_) => {} - } - Ok(trace_writer_state) - }); - } - #[track_caller] - fn run_until( + fn run_extern_modules_cycle( this_ref: &Rc>, - run_target: &mut dyn FnMut(SimInstant) -> Option, + 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(); assert!( this.main_module.uninitialized_ios.is_empty(), "didn't initialize all inputs", ); - this.check_waiting_sensitivity_sets(); - let arc_event_queue = this.event_queue.clone(); // avoid borrow errors - let mut event_queue = arc_event_queue.lock(); - let Some(run_target) = run_target(event_queue.instant()) else { - drop(event_queue); - panic!("SimInstant overflowed"); - }; - let run_target = run_target.max(event_queue.instant()); + let run_target = run_target.max(this.instant); let mut settle_cycle = 0; + let mut run_extern_modules = true; loop { - if settle_cycle >= 100000 { - drop(event_queue); - panic!("settle(): took too many steps"); - } + assert!(settle_cycle < 100000, "settle(): took too many steps"); settle_cycle += 1; - let event_queue_instant = event_queue.instant(); - let mut changed_time = false; - let first_entry = EventQueueData::first_event(event_queue, arc_event_queue.clone()) - .map_err(|mut event_queue| { - changed_time = event_queue_instant != run_target; - event_queue.set_instant(run_target); - drop(event_queue); - }); - let Ok(first_entry) = first_entry else { - if changed_time { - this.write_traces_change_time_to(run_target); - } - return; + 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, }; - let Event { - instant: event_instant, - kind: event_kind, - } = *first_entry.event(); - if event_instant <= event_queue_instant { - first_entry.remove_and_wake_all_wakers(); - match event_kind { - EventKind::State => this.run_state_settle_cycle(), - EventKind::ExternModule(module_index) => { - drop(this); - Self::run_extern_module(this_ref, module_index); - this = this_ref.borrow_mut(); - } - } - this.write_traces_after_event(); - this.check_waiting_sensitivity_sets(); - } else { - event_queue = first_entry.into_event_queue_lock(); - let new_instant = event_instant.min(run_target); - let changed_time = event_queue_instant != new_instant; - event_queue.set_instant(new_instant); - drop(event_queue); - if changed_time { - this.write_traces_change_time_to(new_instant); - } - if event_instant > run_target { - return; + if next_wait_target > this.instant { + settle_cycle = 0; + this.set_instant_no_sim(next_wait_target); + } + 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; } } - event_queue = arc_event_queue.lock(); + if this.main_module.did_initial_settle { + this.read_traces::(); + } else { + this.read_traces::(); + } + 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| { + Ok(match trace_writer_state { + TraceWriterState::Decls(trace_writer_decls) => TraceWriterState::Running( + this.init_trace_writer(trace_writer_decls.write_decls( + this.trace_decls, + this.traces.0.len(), + this.trace_memories.len(), + )?)?, + ), + TraceWriterState::Init(trace_writer) => { + TraceWriterState::Running(this.init_trace_writer(trace_writer)?) + } + TraceWriterState::Running(trace_writer) => { + TraceWriterState::Running(this.update_trace_writer(trace_writer)?) + } + TraceWriterState::Errored(e) => TraceWriterState::Errored(e), + }) + }); + this.state.memory_write_log.clear(); + } + if run_target > this.instant { + this.set_instant_no_sim(run_target); } } #[track_caller] fn settle(this_ref: &Rc>) { - Self::run_until(this_ref, &mut Some); + 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 { @@ -2695,11 +2092,10 @@ impl SimulationImpl { fn read_bit( &mut self, io: Expr, - read_time: ReadTime, which_module: WhichModule, ) -> MaybeNeedsSettle { self.get_module(which_module) - .read_helper(Expr::canonical(io), read_time, which_module) + .read_helper(Expr::canonical(io), which_module) .map(|compiled_value| ReadBitFn { compiled_value }) .apply_no_settle(&mut self.state) } @@ -2708,7 +2104,7 @@ impl SimulationImpl { let compiled_value = self .get_module_mut(which_module) .write_helper(io, which_module); - self.event_queue.add_event_for_now(EventKind::State); + self.state_ready_to_run = true; match compiled_value.range.len().as_single() { Some(TypeLenSingle::SmallSlot) => { self.state.small_slots[compiled_value.range.small_slots.start] = value as _; @@ -2718,17 +2114,15 @@ impl SimulationImpl { } Some(TypeLenSingle::SimOnlySlot) | None => unreachable!(), } - self.debug_write(compiled_value); } #[track_caller] fn read_bool_or_int( &mut self, io: Expr, - read_time: ReadTime, which_module: WhichModule, ) -> MaybeNeedsSettle, I::Value> { self.get_module(which_module) - .read_helper(Expr::canonical(io), read_time, which_module) + .read_helper(Expr::canonical(io), which_module) .map(|compiled_value| ReadBoolOrIntFn { compiled_value, io }) .apply_no_settle(&mut self.state) } @@ -2742,7 +2136,7 @@ impl SimulationImpl { let compiled_value = self .get_module_mut(which_module) .write_helper(Expr::canonical(io), which_module); - self.event_queue.add_event_for_now(EventKind::State); + self.state_ready_to_run = true; let value: BigInt = value.into(); match compiled_value.range.len().as_single() { Some(TypeLenSingle::SmallSlot) => { @@ -2757,7 +2151,6 @@ impl SimulationImpl { } Some(TypeLenSingle::SimOnlySlot) | None => unreachable!(), } - self.debug_write(compiled_value); } #[track_caller] fn read_write_sim_value_helper( @@ -2810,18 +2203,17 @@ impl SimulationImpl { None => unreachable!(), } } - CompiledTypeLayoutBody::Array { elements_non_empty } => { + CompiledTypeLayoutBody::Array { element } => { let ty = ::from_canonical(compiled_value.layout.ty); let element_size = ty.element().size(); for element_index in 0..ty.len() { Self::read_write_sim_value_helper( state, CompiledValue { - layout: elements_non_empty[element_index], - range: compiled_value.range.index_array( - elements_non_empty[element_index].layout.len(), - element_index, - ), + layout: *element, + range: compiled_value + .range + .index_array(element.layout.len(), element_index), write: None, }, start_index + element_index * element_size, @@ -2832,7 +2224,6 @@ impl SimulationImpl { ); } } - CompiledTypeLayoutBody::PhantomConst => {} CompiledTypeLayoutBody::Bundle { fields } => { let ty = Bundle::from_canonical(compiled_value.layout.ty); for ( @@ -2889,7 +2280,7 @@ impl SimulationImpl { }, ); } - let size = io.ty().size(); + let size = Expr::ty(io).size(); let mut opaque = OpaqueSimValue::with_capacity(size); opaque.rewrite_with(size, |mut writer| { SimulationImpl::read_write_sim_value_helper( @@ -2922,7 +2313,7 @@ impl SimulationImpl { ); writer.fill_cloned_from_slice(OpaqueSimValueSlice::empty()) }); - SimValue::from_opaque(io.ty(), opaque) + SimValue::from_opaque(Expr::ty(io), opaque) } /// doesn't modify `opaque` fn value_changed( @@ -2959,23 +2350,15 @@ impl SimulationImpl { any_change.get() } #[track_caller] - fn is_reset_async(&self, io: Expr, which_module: WhichModule) -> bool { - self.get_module(which_module) - .is_reset_async(io, which_module) - } - #[track_caller] fn read( &mut self, io: Expr, - read_time: ReadTime, which_module: WhichModule, ) -> ( CompiledValue, MaybeNeedsSettle>, ) { - let compiled_value = self - .get_module(which_module) - .read_helper(io, read_time, which_module); + 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); @@ -2983,18 +2366,6 @@ impl SimulationImpl { | MaybeNeedsSettle::NoSettleNeeded(compiled_value)) = compiled_value; (compiled_value, value) } - fn debug_write(&self, compiled_value: CompiledValue) { - if self.breakpoints.as_ref().is_some_and(|v| v.trace) { - println!( - "wrote: {:#?}", - compiler::DebugCompiledValueStateAsMap { - compiled_value, - state_layout: self.state.insns.state_layout(), - state: &self.state, - }, - ); - } - } #[track_caller] fn write( &mut self, @@ -3005,8 +2376,8 @@ impl SimulationImpl { let compiled_value = self .get_module_mut(which_module) .write_helper(io, which_module); - self.event_queue.add_event_for_now(EventKind::State); - assert_eq!(io.ty(), value.ty()); + self.state_ready_to_run = true; + assert_eq!(Expr::ty(io), SimValue::ty(value)); Self::read_write_sim_value_helper( &mut self.state, compiled_value, @@ -3038,7 +2409,6 @@ impl SimulationImpl { value.clone_from(&opaque.sim_only_values()[index]); }, ); - self.debug_write(compiled_value); } #[track_caller] fn settle_if_needed(this_ref: &Rc>, v: MaybeNeedsSettle) -> O @@ -3054,7 +2424,7 @@ impl SimulationImpl { } } async fn yield_settle_if_needed( - this_ref: &RefCell, + this_ref: &Rc>, module_index: usize, v: MaybeNeedsSettle, ) -> O @@ -3063,7 +2433,7 @@ impl SimulationImpl { { match v { MaybeNeedsSettle::NeedsSettle(v) => { - Self::yield_advance_time_or_settle(this_ref, module_index, None).await; + 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, @@ -3204,14 +2574,11 @@ impl fmt::Debug for SortedSetDebug<'_, T, V> { } } -struct SortedMapDebug<'a, T>(&'a T); +struct SortedMapDebug<'a, K: 'static + Send + Sync, V>(&'a BTreeMap, V>); -impl<'a, K: fmt::Debug + 'a, V: fmt::Debug + 'a, T> fmt::Debug for SortedMapDebug<'a, T> -where - &'a T: IntoIterator, -{ +impl fmt::Debug for SortedMapDebug<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut entries = Vec::from_iter(self.0.into_iter().map(|(k, v)| { + let mut entries = Vec::from_iter(self.0.iter().map(|(k, v)| { if f.alternate() { (format!("{k:#?}"), format!("{v:#?}")) } else { @@ -3262,19 +2629,23 @@ macro_rules! impl_simulation_methods { let retval = $self .sim_impl .borrow_mut() - .read_bool_or_int(io, ReadTime::Current, $which_module); + .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 ToSimValueWithType, + value: impl ToExpr, ) { - let value = value.to_sim_value_with_type(io.ty()); + 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, - SimValue::into_value(value), + I::bits_to_value(Cow::Borrowed(&value)), $which_module, ); } @@ -3289,7 +2660,7 @@ macro_rules! impl_simulation_methods { let retval = $self .sim_impl .borrow_mut() - .read_bit(Expr::canonical(io), ReadTime::Current, $which_module); + .read_bit(Expr::canonical(io), $which_module); $self.settle_if_needed(retval)$(.$await)? } $(#[$track_caller])? @@ -3303,7 +2674,7 @@ macro_rules! impl_simulation_methods { let retval = $self .sim_impl .borrow_mut() - .read_bit(Expr::canonical(io), ReadTime::Current, $which_module); + .read_bit(Expr::canonical(io), $which_module); $self.settle_if_needed(retval)$(.$await)? } $(#[$track_caller])? @@ -3317,29 +2688,22 @@ macro_rules! impl_simulation_methods { let retval = $self .sim_impl .borrow_mut() - .read_bit(Expr::canonical(io), ReadTime::Current, $which_module); + .read_bit(Expr::canonical(io), $which_module); $self.settle_if_needed(retval)$(.$await)? } - #[track_caller] - pub fn is_reset_async(&$self, io: Expr) -> bool { - $self - .sim_impl - .borrow_mut() - .is_reset_async(Expr::canonical(io), $which_module) - } $(#[$track_caller])? pub $($async)? fn read(&mut $self, io: Expr) -> SimValue { let retval = $self .sim_impl .borrow_mut() - .read(Expr::canonical(io), ReadTime::Current, $which_module).1; + .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(io.ty())), + &SimValue::into_canonical(value.into_sim_value_with_type(Expr::ty(io))), $which_module, ); } @@ -3409,19 +2773,18 @@ impl Simulation { #[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) { - let mut sim_impl = self.sim_impl.borrow_mut(); - sim_impl.breakpoints = Some(BreakpointsSet { + self.sim_impl.borrow_mut().breakpoints = Some(BreakpointsSet { last_was_break: false, set: pcs, trace, }); - sim_impl.event_queue.lock().trace = trace; } } pub struct ExternModuleSimulationState { sim_impl: Rc>, module_index: usize, + wait_for_changes_wait_targets: EarliestWaitTargets, } impl fmt::Debug for ExternModuleSimulationState { @@ -3429,6 +2792,7 @@ impl fmt::Debug for ExternModuleSimulationState { let Self { sim_impl: _, module_index, + wait_for_changes_wait_targets: _, } = self; f.debug_struct("ExternModuleSimulationState") .field("sim_impl", &DebugAsDisplay("...")) @@ -3439,11 +2803,12 @@ impl fmt::Debug for ExternModuleSimulationState { impl ExternModuleSimulationState { pub async fn settle(&mut self) { - SimulationImpl::yield_advance_time_or_settle(&self.sim_impl, self.module_index, None).await + 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, + self.sim_impl.clone(), self.module_index, Some(duration), ) @@ -3454,39 +2819,27 @@ impl ExternModuleSimulationState { iter: I, timeout: Option, ) { - let mut sim_impl = self.sim_impl.borrow_mut(); - let mut sensitivity_set = SensitivitySet { - debug_id: sim_impl.next_sensitivity_set_debug_id, - compiled_values: HashSet::default(), - values: Vec::new(), - waker: RefCell::new(std::task::Waker::noop().clone()), - changed: Cell::new(false), - }; - sim_impl.next_sensitivity_set_debug_id = - sim_impl.next_sensitivity_set_debug_id.wrapping_add(1); - drop(sim_impl); + 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, ReadTime::Current, which_module); + let (key, value) = self.sim_impl.borrow_mut().read(io, which_module); let value = self.settle_if_needed(value).await; - let key = Rc::new(key); - if sensitivity_set.compiled_values.insert(key.clone()) { - sensitivity_set.values.push((key, Rc::new(value))); - } + self.wait_for_changes_wait_targets + .insert(WaitTarget::Change { key, value }); } - SimulationImpl::yield_wait_for_changes( - &self.sim_impl, + 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, - sensitivity_set, - timeout, + &mut self.wait_for_changes_wait_targets, ) - .await + .await; } pub async fn wait_for_clock_edge(&mut self, clk: impl ToExpr) { let clk = clk.to_expr(); @@ -3503,330 +2856,6 @@ impl ExternModuleSimulationState { { SimulationImpl::yield_settle_if_needed(&self.sim_impl, self.module_index, v).await } - pub async fn fork_join(&mut self, futures: F) -> F::Output { - F::fork_join(futures, self).await - } - async fn resettable_helper( - &mut self, - cancellable: &Cell, - wait_for_reset: impl AsyncFn(Self), - main: impl AsyncFn(Self), - ) -> ! { - let mut wait_for_reset_invocation = pin!(Some(wait_for_reset(self.forked_state()))); - let mut main_invocation = pin!(Some(main(self.forked_state()))); - std::future::poll_fn(|cx: &mut std::task::Context<'_>| { - loop { - if cancellable.get() && wait_for_reset_invocation.is_none() { - cancellable.set(false); - main_invocation.set(Some(main(self.forked_state()))); - wait_for_reset_invocation.set(Some(wait_for_reset(self.forked_state()))) - } - match main_invocation.as_mut().as_pin_mut().map(|f| f.poll(cx)) { - None | Some(Poll::Pending) => {} - Some(Poll::Ready(())) => { - main_invocation.set(None); - continue; - } - } - match wait_for_reset_invocation - .as_mut() - .as_pin_mut() - .map(|f| f.poll(cx)) - { - None | Some(Poll::Pending) => {} - Some(Poll::Ready(())) => { - wait_for_reset_invocation.set(None); - continue; - } - } - return Poll::Pending; - } - }) - .await - } - /// When `cd.rst` is deduced to be an [`AsyncReset`]: - /// * when `cd.rst` is asserted or when first called, `reset` is invoked and any running `run` invocation is cancelled. - /// * when `cd.rst` is de-asserted and when `reset` finishes, `run` is invoked. - /// - /// When `cd.rst` is deduced to be a [`SyncReset`]: - /// * when there's a positive-going clock edge on `cd.clk` and `cd.rst` is asserted or when first called, `reset` is invoked and any running `run` invocation is cancelled. - /// * when `reset` finishes, `run` is invoked. - pub async fn resettable( - &mut self, - cd: impl ToExpr>, - reset: impl AsyncFn(Self) -> T, - run: impl AsyncFn(Self, T), - ) -> ! { - let cd = cd.to_expr(); - let rst = cd.rst; - if self.is_reset_async(rst) { - let cancellable = Cell::new(false); - let wait_for_reset = |mut this: Self| async move { - while this.read_reset(rst).await { - this.wait_for_changes([rst], None).await; - } - while !this.read_reset(rst).await { - this.wait_for_changes([rst], None).await; - } - }; - let main = |mut this: Self| async { - let run_arg = reset(this.forked_state()).await; - cancellable.set(true); - while this.read_reset(rst).await { - this.wait_for_changes([rst], None).await; - } - run(this, run_arg).await - }; - self.resettable_helper(&cancellable, wait_for_reset, main) - .await - } else { - let clk = cd.clk; - let wait_for_reset = |mut this: Self| async move { - loop { - this.wait_for_clock_edge(clk).await; - if this.read_reset(rst).await { - return; - } - } - }; - let cancellable = Cell::new(false); - let main = |this: Self| async { - let run_arg = reset(this.forked_state()).await; - cancellable.set(true); - run(this, run_arg).await - }; - self.resettable_helper(&cancellable, wait_for_reset, main) - .await - } - } - fn forked_state(&self) -> Self { - let Self { - ref sim_impl, - module_index, - } = *self; - Self { - sim_impl: sim_impl.clone(), - module_index, - } - } - pub async fn fork_join_scope<'env, F, Fut>( - &mut self, - in_scope: F, - ) -> ::Output - where - F: FnOnce(ForkJoinScope<'env>, ExternModuleSimulationState) -> Fut, - Fut: IntoFuture>, - { - let scope = ForkJoinScope { - new_tasks: Rc::new(RefCell::new(vec![])), - sim: self.forked_state(), - }; - let join_handle = scope.spawn(in_scope); - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] - struct TaskId(u64); - struct TasksStateInner { - next_task_id: u64, - ready_tasks: BTreeSet, - not_ready_tasks: BTreeSet, - base_waker: std::task::Waker, - } - impl Default for TasksStateInner { - fn default() -> Self { - Self { - next_task_id: Default::default(), - ready_tasks: Default::default(), - not_ready_tasks: Default::default(), - base_waker: std::task::Waker::noop().clone(), - } - } - } - #[derive(Default)] - struct TasksState { - inner: Mutex, - } - #[derive(Clone)] - struct TaskWaker { - state: std::sync::Weak, - task: TaskId, - } - impl std::task::Wake for TaskWaker { - fn wake(self: Arc) { - self.wake_by_ref(); - } - fn wake_by_ref(self: &Arc) { - let Some(state) = self.state.upgrade() else { - return; - }; - let mut inner = state.inner.lock().expect("not poisoned"); - if inner.not_ready_tasks.remove(&self.task) { - inner.ready_tasks.insert(self.task); - inner.base_waker.wake_by_ref(); - } - } - } - struct Task<'env> { - task: Pin + 'env>>, - waker: std::task::Waker, - } - let mut tasks: BTreeMap = BTreeMap::new(); - let tasks_state = Arc::new(TasksState::default()); - std::future::poll_fn(move |cx: &mut std::task::Context<'_>| { - let mut state_inner = tasks_state.inner.lock().expect("not poisoned"); - state_inner.base_waker.clone_from(cx.waker()); - loop { - for new_task in scope.new_tasks.borrow_mut().drain(..) { - let task_id = TaskId(state_inner.next_task_id); - let Some(next_task_id) = state_inner.next_task_id.checked_add(1) else { - drop(state_inner); - panic!("spawned too many tasks"); - }; - state_inner.next_task_id = next_task_id; - state_inner.ready_tasks.insert(task_id); - tasks.insert( - task_id, - Task { - task: new_task, - waker: Arc::new(TaskWaker { - state: Arc::downgrade(&tasks_state), - task: task_id, - }) - .into(), - }, - ); - } - let Some(task_id) = state_inner.ready_tasks.pop_first() else { - if state_inner.not_ready_tasks.is_empty() { - return Poll::Ready(()); - } else { - return Poll::Pending; - }; - }; - state_inner.not_ready_tasks.insert(task_id); // task can be woken while we're running poll - drop(state_inner); - let std::collections::btree_map::Entry::Occupied(mut entry) = tasks.entry(task_id) - else { - unreachable!(); - }; - let Task { task, waker } = entry.get_mut(); - match task.as_mut().poll(&mut std::task::Context::from_waker( - &std::task::Waker::from(waker.clone()), - )) { - Poll::Pending => { - state_inner = tasks_state.inner.lock().expect("not poisoned"); - continue; - } - Poll::Ready(()) => {} - } - drop(entry.remove()); // drop outside lock - state_inner = tasks_state.inner.lock().expect("not poisoned"); - state_inner.not_ready_tasks.remove(&task_id); - state_inner.ready_tasks.remove(&task_id); - } - }) - .await; - match &mut *join_handle.state.borrow_mut() { - JoinHandleState::Running(_) => unreachable!(), - JoinHandleState::Finished(state) => state - .take() - .expect("filled by running all futures to completion"), - } - } - /// Reads the value of `io` from right before the last clock edge of `clock_for_past`. - /// - /// In order to use the `read_past()` family of functions, you must call [`m.register_clock_for_past(my_io.clk)`] - /// in the module's body for every clock you use as the second argument of the `read_past()` family. - /// - /// [`m.register_clock_for_past(my_io.clk)`]: crate::module::ModuleBuilder::register_clock_for_past - pub async fn read_past_bool_or_int( - &mut self, - io: Expr, - clock_for_past: Expr, - ) -> I::Value { - let retval = self.sim_impl.borrow_mut().read_bool_or_int( - io, - ReadTime::Past { clock_for_past }, - WhichModule::Extern { - module_index: self.module_index, - }, - ); - self.settle_if_needed(retval).await - } - /// Reads the value of `io` from right before the last clock edge of `clock_for_past`. - /// - /// In order to use the `read_past()` family of functions, you must call [`m.register_clock_for_past(my_io.clk)`] - /// in the module's body for every clock you use as the second argument of the `read_past()` family. - /// - /// [`m.register_clock_for_past(my_io.clk)`]: crate::module::ModuleBuilder::register_clock_for_past - pub async fn read_past_clock(&mut self, io: Expr, clock_for_past: Expr) -> bool { - let retval = self.sim_impl.borrow_mut().read_bit( - Expr::canonical(io), - ReadTime::Past { clock_for_past }, - WhichModule::Extern { - module_index: self.module_index, - }, - ); - self.settle_if_needed(retval).await - } - /// Reads the value of `io` from right before the last clock edge of `clock_for_past`. - /// - /// In order to use the `read_past()` family of functions, you must call [`m.register_clock_for_past(my_io.clk)`] - /// in the module's body for every clock you use as the second argument of the `read_past()` family. - /// - /// [`m.register_clock_for_past(my_io.clk)`]: crate::module::ModuleBuilder::register_clock_for_past - pub async fn read_past_bool(&mut self, io: Expr, clock_for_past: Expr) -> bool { - let retval = self.sim_impl.borrow_mut().read_bit( - Expr::canonical(io), - ReadTime::Past { clock_for_past }, - WhichModule::Extern { - module_index: self.module_index, - }, - ); - self.settle_if_needed(retval).await - } - /// Reads the value of `io` from right before the last clock edge of `clock_for_past`. - /// - /// In order to use the `read_past()` family of functions, you must call [`m.register_clock_for_past(my_io.clk)`] - /// in the module's body for every clock you use as the second argument of the `read_past()` family. - /// - /// [`m.register_clock_for_past(my_io.clk)`]: crate::module::ModuleBuilder::register_clock_for_past - pub async fn read_past_reset( - &mut self, - io: Expr, - clock_for_past: Expr, - ) -> bool { - let retval = self.sim_impl.borrow_mut().read_bit( - Expr::canonical(io), - ReadTime::Past { clock_for_past }, - WhichModule::Extern { - module_index: self.module_index, - }, - ); - self.settle_if_needed(retval).await - } - /// Reads the value of `io` from right before the last clock edge of `clock_for_past`. - /// - /// In order to use the `read_past()` family of functions, you must call [`m.register_clock_for_past(my_io.clk)`] - /// in the module's body for every clock you use as the second argument of the `read_past()` family. - /// - /// [`m.register_clock_for_past(my_io.clk)`]: crate::module::ModuleBuilder::register_clock_for_past - pub async fn read_past( - &mut self, - io: Expr, - clock_for_past: Expr, - ) -> SimValue { - let retval = self - .sim_impl - .borrow_mut() - .read( - Expr::canonical(io), - ReadTime::Past { clock_for_past }, - WhichModule::Extern { - module_index: self.module_index, - }, - ) - .1; - SimValue::from_canonical(self.settle_if_needed(retval).await) - } impl_simulation_methods!( async_await = (async, await), track_caller = (), @@ -3834,233 +2863,6 @@ impl ExternModuleSimulationState { ); } -pub struct ForkJoinScope<'env> { - new_tasks: Rc + 'env>>>>>, - sim: ExternModuleSimulationState, -} - -impl<'env> Clone for ForkJoinScope<'env> { - fn clone(&self) -> Self { - Self { - new_tasks: self.new_tasks.clone(), - sim: self.sim.forked_state(), - } - } -} - -impl<'env> ForkJoinScope<'env> { - fn spawn_inner(&self, fut: Pin + 'env>>) { - self.new_tasks.borrow_mut().push(fut); - } - pub fn spawn_detached_future( - &self, - fut: impl IntoFuture>, - ) { - self.spawn_inner(Box::pin(fut.into_future())); - } - pub fn spawn_detached(&self, f: F) - where - F: FnOnce(ForkJoinScope<'env>, ExternModuleSimulationState) -> Fut, - Fut: IntoFuture>, - { - self.spawn_detached_future(f(self.clone(), self.sim.forked_state())); - } - pub fn spawn(&self, f: F) -> JoinHandle - where - F: FnOnce(ForkJoinScope<'env>, ExternModuleSimulationState) -> Fut, - Fut: IntoFuture>, - { - let join_handle = JoinHandle { - state: Default::default(), - }; - let state = Rc::downgrade(&join_handle.state); - let fut = f(self.clone(), self.sim.forked_state()).into_future(); - self.spawn_detached_future(async move { - let result = fut.await; - let Some(state) = state.upgrade() else { return }; - let mut state = state.borrow_mut(); - let waker = match &mut *state { - JoinHandleState::Running(waker) => waker.take(), - JoinHandleState::Finished(_) => unreachable!(), - }; - *state = JoinHandleState::Finished(Some(result)); - drop(state); - let Some(waker) = waker else { return }; - waker.wake(); - }); - join_handle - } -} - -enum JoinHandleState { - Running(Option), - Finished(Option), -} - -impl Default for JoinHandleState { - fn default() -> Self { - Self::Running(None) - } -} - -pub struct JoinHandle { - state: Rc>>, -} - -impl JoinHandle { - pub fn is_finished(&self) -> bool { - matches!(*self.state.borrow(), JoinHandleState::Finished(_)) - } - pub fn try_join(self) -> Result { - let mut state = self.state.borrow_mut(); - match &mut *state { - JoinHandleState::Running(_) => { - drop(state); - Err(self) - } - JoinHandleState::Finished(retval) => { - let Some(retval) = retval.take() else { - panic!("already returned the value in poll"); - }; - Ok(retval) - } - } - } - pub async fn join(self) -> T { - self.await - } -} - -impl Future for JoinHandle { - type Output = T; - - fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { - match &mut *self.state.borrow_mut() { - JoinHandleState::Running(waker) => { - match waker { - None => *waker = Some(cx.waker().clone()), - Some(waker) => waker.clone_from(cx.waker()), - } - Poll::Pending - } - JoinHandleState::Finished(retval) => { - let Some(retval) = retval.take() else { - panic!("already returned Poll::Ready"); - }; - Poll::Ready(retval) - } - } - } -} - -struct ForkJoinImpl<'a> { - futures: Vec + 'a>>>, -} - -impl Future for ForkJoinImpl<'_> { - type Output = (); - fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { - let Self { futures } = self.get_mut(); - futures.retain_mut(|future| future.as_mut().poll(cx).is_pending()); - if futures.is_empty() { - Poll::Ready(()) - } else { - Poll::Pending - } - } -} - -pub trait ForkJoin { - type Output; - #[allow(async_fn_in_trait, reason = "no auto traits needed")] - async fn fork_join(this: Self, sim_state: &mut ExternModuleSimulationState) -> Self::Output; -} - -impl O, O, const N: usize> ForkJoin for [F; N] { - type Output = [O; N]; - async fn fork_join(this: Self, sim_state: &mut ExternModuleSimulationState) -> Self::Output { - let mut temp = [const { None }; N]; - ForkJoinImpl { - futures: this - .into_iter() - .zip(&mut temp) - .map(|(future, temp)| -> Pin + '_>> { - Box::pin(async { *temp = Some(future(sim_state.forked_state()).await) }) - }) - .collect(), - } - .await; - temp.map(|output| output.expect("set to Some above")) - } -} - -impl O, O> ForkJoin for Vec { - type Output = Vec; - async fn fork_join(this: Self, sim_state: &mut ExternModuleSimulationState) -> Self::Output { - let mut temp = Vec::with_capacity(this.len()); - for _ in 0..this.len() { - temp.push(None); - } - ForkJoinImpl { - futures: this - .into_iter() - .zip(&mut temp) - .map(|(future, temp)| -> Pin + '_>> { - Box::pin(async { *temp = Some(future(sim_state.forked_state()).await) }) - }) - .collect(), - } - .await; - temp.into_iter() - .map(|output| output.expect("set to Some above")) - .collect() - } -} - -impl O, O> ForkJoin for Box<[F]> { - type Output = Box<[O]>; - async fn fork_join(this: Self, sim_state: &mut ExternModuleSimulationState) -> Self::Output { - Vec::fork_join(this.into(), sim_state) - .await - .into_boxed_slice() - } -} - -impl ForkJoin for Box { - type Output = Box; - async fn fork_join(this: Self, sim_state: &mut ExternModuleSimulationState) -> Self::Output { - Box::new(T::fork_join(*this, sim_state).await) - } -} - -macro_rules! impl_fork_join_tuples { - (@impl $(($f:ident: $F:ident => $o:ident: $O:ident)),*) => { - impl<$($F: AsyncFnOnce(ExternModuleSimulationState) -> $O, $O,)*> ForkJoin for ($($F,)*) { - type Output = ($($O,)*); - async fn fork_join(this: Self, sim_state: &mut ExternModuleSimulationState) -> Self::Output { - #![allow(unused_variables)] - let ($($f,)*) = this; - $(let mut $o = None;)* - ForkJoinImpl { - futures: vec![ - $(Box::pin(async { $o = Some($f(sim_state.forked_state()).await) }),)* - ], - }.await; - ($($o.expect("set to Some above"),)*) - } - } - }; - (($($first:tt)*) $(, $rest:tt)* $(,)?) => { - impl_fork_join_tuples!(@impl ($($first)*) $(, $rest)*); - impl_fork_join_tuples!($($rest),*); - }; - () => { - impl_fork_join_tuples!(@impl); - }; -} - -impl_fork_join_tuples!((f0: F0 => o0: O0), (f1: F1 => o1: O1), (f2: F2 => o2: O2), (f3: F3 => o3: O3), (f4: F4 => o4: O4), (f5: F5 => o5: O5), (f6: F6 => o6: O6), (f7: F7 => o7: O7), (f8: F8 => o8: O8), (f9: F9 => o9: O9), (f10: F10 => o10: O10), (f11: F11 => o11: O11),); - pub trait ExternModuleSimGenerator: Clone + Eq + Hash + Any + Send + Sync + fmt::Debug { fn run<'a>(&'a self, sim: ExternModuleSimulationState) -> impl IntoFuture + 'a; } @@ -4161,7 +2963,7 @@ impl fmt::Debug for ExternModuleSimulation { .field("generator", &self.generator) .field( "sim_io_to_generator_map", - &SortedMapDebug(&*self.sim_io_to_generator_map), + &SortedMapDebug(&self.sim_io_to_generator_map), ) .field("source_location", &self.source_location) .finish() diff --git a/crates/fayalite/src/sim/compiler.rs b/crates/fayalite/src/sim/compiler.rs index 07621c5..2b291be 100644 --- a/crates/fayalite/src/sim/compiler.rs +++ b/crates/fayalite/src/sim/compiler.rs @@ -7,14 +7,14 @@ use crate::{ bundle::{BundleField, BundleType}, enum_::{EnumType, EnumVariant}, expr::{ - ExprEnum, Flow, ValueType, ops, + ExprEnum, Flow, ops, target::{ GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, }, }, int::BoolOrIntType, - intern::{Intern, InternSlice, Interned, Memoize}, + intern::{Intern, Interned, Memoize}, memory::PortKind, module::{ AnnotatedModuleIO, Block, ExternModuleBody, Id, InstantiatedModule, ModuleBody, NameId, @@ -28,12 +28,12 @@ use crate::{ ExternModuleSimulation, SimTrace, SimTraceKind, SimTraces, TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl, TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, - TraceMemoryLocation, TraceModule, TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt, - TraceScalarId, TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, + TraceMemoryLocation, TraceModule, TraceModuleIO, TraceReg, TraceSInt, TraceScalarId, + TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, interpreter::{ - self, Insn, InsnField, InsnFieldKind, InsnFieldType, InsnOrLabel, Insns, InsnsBuilding, - InsnsBuildingDone, InsnsBuildingKind, Label, PrefixLinesWrapper, SmallUInt, - StatePartArrayIndex, StatePartArrayIndexed, + Insn, InsnField, InsnFieldKind, InsnFieldType, InsnOrLabel, Insns, InsnsBuilding, + InsnsBuildingDone, InsnsBuildingKind, Label, SmallUInt, StatePartArrayIndex, + StatePartArrayIndexed, parts::{ MemoryData, SlotDebugData, StatePartIndex, StatePartIndexRange, StatePartKind, StatePartKindBigSlots, StatePartKindMemories, StatePartKindSimOnlySlots, @@ -82,73 +82,19 @@ pub(crate) struct CompiledBundleField { pub(crate) ty: CompiledTypeLayout, } -impl CompiledBundleField { - fn with_prefixed_debug_names(self, prefix: &str) -> Self { - let Self { offset, ty } = self; - Self { - offset, - ty: ty.with_prefixed_debug_names(prefix), - } - } - fn with_anonymized_debug_info(self) -> Self { - let Self { offset, ty } = self; - Self { - offset, - ty: ty.with_anonymized_debug_info(), - } - } -} - #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] pub(crate) enum CompiledTypeLayoutBody { Scalar, - PhantomConst, Array { - /// always has at least one element even for zero-sized arrays - elements_non_empty: Interned<[CompiledTypeLayout]>, + /// debug names are ignored, use parent's layout instead + element: Interned>, }, Bundle { + /// debug names are ignored, use parent's layout instead fields: Interned<[CompiledBundleField]>, }, } -impl CompiledTypeLayoutBody { - fn with_prefixed_debug_names(self, prefix: &str) -> Self { - match self { - CompiledTypeLayoutBody::Scalar | CompiledTypeLayoutBody::PhantomConst => self, - CompiledTypeLayoutBody::Array { elements_non_empty } => CompiledTypeLayoutBody::Array { - elements_non_empty: elements_non_empty - .iter() - .map(|element| element.with_prefixed_debug_names(prefix)) - .collect(), - }, - CompiledTypeLayoutBody::Bundle { fields } => CompiledTypeLayoutBody::Bundle { - fields: fields - .iter() - .map(|field| field.with_prefixed_debug_names(prefix)) - .collect(), - }, - } - } - fn with_anonymized_debug_info(self) -> Self { - match self { - CompiledTypeLayoutBody::Scalar | CompiledTypeLayoutBody::PhantomConst => self, - CompiledTypeLayoutBody::Array { elements_non_empty } => CompiledTypeLayoutBody::Array { - elements_non_empty: elements_non_empty - .iter() - .map(|element| element.with_anonymized_debug_info()) - .collect(), - }, - CompiledTypeLayoutBody::Bundle { fields } => CompiledTypeLayoutBody::Bundle { - fields: fields - .iter() - .map(|field| field.with_anonymized_debug_info()) - .collect(), - }, - } - } -} - #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] pub(crate) struct CompiledTypeLayout { pub(crate) ty: T, @@ -162,7 +108,7 @@ impl CompiledTypeLayout { Self { ty, layout: layout.with_prefixed_debug_names(prefix), - body: body.with_prefixed_debug_names(prefix), + body, } } fn with_anonymized_debug_info(self) -> Self { @@ -170,7 +116,7 @@ impl CompiledTypeLayout { Self { ty, layout: layout.with_anonymized_debug_info(), - body: body.with_anonymized_debug_info(), + body, } } fn get(ty: T) -> Self { @@ -205,29 +151,28 @@ impl CompiledTypeLayout { } CanonicalType::Array(array) => { let mut layout = TypeLayout::empty(); - let element = CompiledTypeLayout::get(array.element()); - let mut elements_non_empty = vec![]; + let element = CompiledTypeLayout::get(array.element()).intern_sized(); for index in 0..array.len() { - let element = element.with_prefixed_debug_names(&format!("[{index}]")); - layout.allocate(&element.layout); - elements_non_empty.push(element); - } - if array.is_empty() { - elements_non_empty.push(element.with_prefixed_debug_names("[]")); + layout.allocate( + &element + .layout + .with_prefixed_debug_names(&format!("[{index}]")), + ); } CompiledTypeLayout { ty: *input, layout: layout.into(), - body: CompiledTypeLayoutBody::Array { - elements_non_empty: elements_non_empty.intern_deref(), - }, + body: CompiledTypeLayoutBody::Array { element }, + } + } + CanonicalType::PhantomConst(_) => { + let unit_layout = CompiledTypeLayout::get(()); + CompiledTypeLayout { + ty: *input, + layout: unit_layout.layout, + body: unit_layout.body, } } - CanonicalType::PhantomConst(_) => CompiledTypeLayout { - ty: *input, - layout: TypeLayout::empty(), - body: CompiledTypeLayoutBody::PhantomConst, - }, CanonicalType::Bundle(bundle) => { let mut layout = TypeLayout::empty(); let fields = bundle @@ -239,9 +184,13 @@ impl CompiledTypeLayout { flipped: _, ty, }| { - let ty = CompiledTypeLayout::get(*ty) - .with_prefixed_debug_names(&format!(".{name}")); - let offset = layout.allocate(&ty.layout).start(); + let ty = CompiledTypeLayout::get(*ty); + let offset = layout + .allocate( + &ty.layout + .with_prefixed_debug_names(&format!(".{name}")), + ) + .start(); CompiledBundleField { offset, ty } }, ) @@ -324,39 +273,6 @@ impl CompiledValue { } } -pub(crate) struct DebugCompiledValueStateAsMap<'a> { - pub(crate) compiled_value: CompiledValue, - pub(crate) state_layout: &'a interpreter::parts::StateLayout, - pub(crate) state: &'a interpreter::State, -} - -impl fmt::Debug for DebugCompiledValueStateAsMap<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use fmt::Write; - if self.compiled_value.range.is_empty() { - return f.write_str("{}"); - } - writeln!(f, "{{")?; - let mut f = PrefixLinesWrapper::new(f, true, " "); - macro_rules! debug_fmt { - ( - type_plural_fields = [$($type_plural_field:ident,)*]; - ) => { - $(for slot in self.compiled_value.range.$type_plural_field.iter() { - slot.debug_fmt(&mut f, ":", " ", " ", "", Some(self.state_layout), Some(self.state))?; - writeln!(f, ",")?; - })* - }; - } - get_state_part_kinds! { - debug_fmt! { - type_plural_fields; - } - } - write!(f.into_inner(), "}}") - } -} - impl CompiledValue { fn field_by_index(self, field_index: usize) -> CompiledValue { self.map(|layout, range| { @@ -385,13 +301,10 @@ impl CompiledValue { impl CompiledValue { pub(crate) fn element(self, index: usize) -> CompiledValue { self.map(|layout, range| { - let CompiledTypeLayoutBody::Array { elements_non_empty } = layout.body else { + let CompiledTypeLayoutBody::Array { element } = layout.body else { unreachable!(); }; - ( - elements_non_empty[index], - range.index_array(elements_non_empty[index].layout.len(), index), - ) + (*element, range.index_array(element.layout.len(), index)) }) } fn element_dyn( @@ -644,11 +557,10 @@ impl CompiledExpr { self, index_slot: StatePartIndex, ) -> CompiledExpr { - let CompiledTypeLayoutBody::Array { elements_non_empty } = self.static_part.layout.body - else { + let CompiledTypeLayoutBody::Array { element } = self.static_part.layout.body else { unreachable!(); }; - let stride = elements_non_empty[0].layout.len(); + let stride = element.layout.len(); let indexes = self.indexes.join(TypeArrayIndex::from_parts( index_slot, self.static_part.layout.ty.len(), @@ -656,10 +568,10 @@ impl CompiledExpr { )); CompiledExpr { static_part: self.static_part.map(|layout, range| { - let CompiledTypeLayoutBody::Array { elements_non_empty } = layout.body else { + let CompiledTypeLayoutBody::Array { element } = layout.body else { unreachable!(); }; - (elements_non_empty[0], range.index_array(stride, 0)) + (*element, range.index_array(stride, 0)) }), indexes, } @@ -1638,13 +1550,6 @@ struct ClockTrigger { source_location: SourceLocation, } -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] -pub(crate) struct ExternModuleClockForPast { - pub(crate) clock_for_past: CompiledValue, - pub(crate) current_to_past_map: - Interned<[(CompiledValue, CompiledValue)]>, -} - #[derive(Debug)] struct Register { value: CompiledValue, @@ -1714,7 +1619,7 @@ impl MakeTraceDeclTarget { } fn ty(self) -> CanonicalType { match self { - MakeTraceDeclTarget::Expr(expr) => expr.ty(), + MakeTraceDeclTarget::Expr(expr) => Expr::ty(expr), MakeTraceDeclTarget::Memory { ty, .. } => ty, } } @@ -1732,9 +1637,7 @@ impl fmt::Debug for DebugOpaque { pub(crate) struct CompiledExternModule { pub(crate) module_io_targets: Interned<[Target]>, pub(crate) module_io: Interned<[CompiledValue]>, - pub(crate) clocks_for_past: Interned<[ExternModuleClockForPast]>, pub(crate) simulation: ExternModuleSimulation, - pub(crate) debug_name: Interned, } #[derive(Debug)] @@ -1778,23 +1681,18 @@ macro_rules! impl_compiler { instantiated_module: InstantiatedModule, target: MakeTraceDeclTarget, source_location: SourceLocation, - empty_kind: impl FnOnce() -> SimTraceKind, $($type_singular_field: impl FnOnce(StatePartIndex<$type_kind>) -> SimTraceKind,)* ) -> TraceLocation { match target { MakeTraceDeclTarget::Expr(target) => { let compiled_value = self.compile_expr(instantiated_module, target); let compiled_value = self.compiled_expr_to_value(compiled_value, source_location); - if compiled_value.range.is_empty() { - TraceLocation::Scalar(self.new_sim_trace(empty_kind())) - } else { - TraceLocation::Scalar(self.new_sim_trace(match compiled_value.range.len().as_single() { - $(Some(TypeLenSingle::$type_singular_variant) => { - $type_singular_field(compiled_value.range.$type_plural_field.start) - })* - None => unreachable!(), - })) - } + TraceLocation::Scalar(self.new_sim_trace(match compiled_value.range.len().as_single() { + $(Some(TypeLenSingle::$type_singular_variant) => { + $type_singular_field(compiled_value.range.$type_plural_field.start) + })* + None => unreachable!(), + })) } MakeTraceDeclTarget::Memory { id, @@ -1825,10 +1723,9 @@ macro_rules! impl_compiler { instantiated_module, target, source_location, - || unreachable!(), |index| SimTraceKind::SmallUInt { index, ty }, |index| SimTraceKind::BigUInt { index, ty }, - |_| unreachable!(), + |_| unreachable!(""), ), name, ty, @@ -1840,10 +1737,9 @@ macro_rules! impl_compiler { instantiated_module, target, source_location, - || unreachable!(), |index| SimTraceKind::SmallSInt { index, ty }, |index| SimTraceKind::BigSInt { index, ty }, - |_| unreachable!(), + |_| unreachable!(""), ), name, ty, @@ -1855,10 +1751,9 @@ macro_rules! impl_compiler { instantiated_module, target, source_location, - || unreachable!(), |index| SimTraceKind::SmallBool { index }, |index| SimTraceKind::BigBool { index }, - |_| unreachable!(), + |_| unreachable!(""), ), name, flow, @@ -1903,16 +1798,15 @@ macro_rules! impl_compiler { } .into() } - CanonicalType::Bundle(_) => unreachable!(), + CanonicalType::Bundle(_) | CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::AsyncReset(_) => TraceAsyncReset { location: self.make_trace_scalar_helper( instantiated_module, target, source_location, - || unreachable!(), |index| SimTraceKind::SmallAsyncReset { index }, |index| SimTraceKind::BigAsyncReset { index }, - |_| unreachable!(), + |_| unreachable!(""), ), name, flow, @@ -1923,10 +1817,9 @@ macro_rules! impl_compiler { instantiated_module, target, source_location, - || unreachable!(), |index| SimTraceKind::SmallSyncReset { index }, |index| SimTraceKind::BigSyncReset { index }, - |_| unreachable!(), + |_| unreachable!(""), ), name, flow, @@ -1938,38 +1831,21 @@ macro_rules! impl_compiler { instantiated_module, target, source_location, - || unreachable!(), |index| SimTraceKind::SmallClock { index }, |index| SimTraceKind::BigClock { index }, - |_| unreachable!(), + |_| unreachable!(""), ), name, flow, } .into(), - CanonicalType::PhantomConst(ty) => TracePhantomConst { - location: self.make_trace_scalar_helper( - instantiated_module, - target, - source_location, - || SimTraceKind::PhantomConst { ty }, - |_| unreachable!(), - |_| unreachable!(), - |_| unreachable!(), - ), - name, - ty, - flow, - } - .into(), CanonicalType::DynSimOnly(ty) => TraceSimOnly { location: self.make_trace_scalar_helper( instantiated_module, target, source_location, - || unreachable!(), - |_| unreachable!(), - |_| unreachable!(), + |_| unreachable!(""), + |_| unreachable!(""), |index| SimTraceKind::SimOnly { index, ty }, ), name, @@ -2419,10 +2295,16 @@ impl Compiler { | CanonicalType::SyncReset(_) | CanonicalType::Reset(_) | CanonicalType::Clock(_) - | CanonicalType::DynSimOnly(_) - | CanonicalType::PhantomConst(_) => { + | CanonicalType::DynSimOnly(_) => { 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( @@ -2771,7 +2653,7 @@ impl Compiler { let retval = parts .into_iter() .map(|part| part.cast_to_bits()) - .reduce(|accumulator, part| accumulator | (part << accumulator.ty().width)) + .reduce(|accumulator, part| accumulator | (part << Expr::ty(accumulator).width)) .unwrap_or_else(|| UInt[0].zero().to_expr()); let retval = self.compile_expr(instantiated_module, Expr::canonical(retval)); let retval = self @@ -2783,7 +2665,7 @@ impl Compiler { instantiated_module: InstantiatedModule, expr: ops::CastToBits, ) -> CompiledValue { - match expr.arg().ty() { + match Expr::ty(expr.arg()) { CanonicalType::UInt(_) => { self.compile_cast_scalar_to_bits(instantiated_module, expr.arg(), |arg| arg) } @@ -2949,7 +2831,7 @@ impl Compiler { return retval; } let mut cast_bit = |arg: Expr| { - let src_signed = match arg.ty() { + let src_signed = match Expr::ty(arg) { CanonicalType::UInt(_) => false, CanonicalType::SInt(_) => true, CanonicalType::Bool(_) => false, @@ -2963,7 +2845,7 @@ impl Compiler { CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::DynSimOnly(_) => unreachable!(), }; - let dest_signed = match expr.ty() { + let dest_signed = match Expr::ty(expr) { CanonicalType::UInt(_) => false, CanonicalType::SInt(_) => true, CanonicalType::Bool(_) => false, @@ -2977,23 +2859,22 @@ impl Compiler { CanonicalType::PhantomConst(_) => unreachable!(), CanonicalType::DynSimOnly(_) => unreachable!(), }; - self.simple_nary_big_expr(instantiated_module, expr.ty(), [arg], |dest, [src]| match ( - src_signed, - dest_signed, - ) { - (false, false) | (true, true) => { - vec![Insn::Copy { dest, src }] + self.simple_nary_big_expr(instantiated_module, Expr::ty(expr), [arg], |dest, [src]| { + match (src_signed, dest_signed) { + (false, false) | (true, true) => { + vec![Insn::Copy { dest, src }] + } + (false, true) => vec![Insn::CastToSInt { + dest, + src, + dest_width: 1, + }], + (true, false) => vec![Insn::CastToUInt { + dest, + src, + dest_width: 1, + }], } - (false, true) => vec![Insn::CastToSInt { - dest, - src, - dest_width: 1, - }], - (true, false) => vec![Insn::CastToUInt { - dest, - src, - dest_width: 1, - }], }) .into() }; @@ -3033,13 +2914,21 @@ impl Compiler { }) .into(), ExprEnum::PhantomConst(_) => self - .compile_aggregate_literal(instantiated_module, expr.ty(), Interned::default()) + .compile_aggregate_literal(instantiated_module, Expr::ty(expr), Interned::default()) .into(), ExprEnum::BundleLiteral(literal) => self - .compile_aggregate_literal(instantiated_module, expr.ty(), literal.field_values()) + .compile_aggregate_literal( + instantiated_module, + Expr::ty(expr), + literal.field_values(), + ) .into(), ExprEnum::ArrayLiteral(literal) => self - .compile_aggregate_literal(instantiated_module, expr.ty(), literal.element_values()) + .compile_aggregate_literal( + instantiated_module, + Expr::ty(expr), + literal.element_values(), + ) .into(), ExprEnum::EnumLiteral(expr) => { let enum_bits_ty = UInt[expr.ty().type_properties().bit_width]; @@ -3067,13 +2956,13 @@ impl Compiler { ExprEnum::NotU(expr) => self .simple_nary_big_expr( instantiated_module, - expr.arg().ty().canonical(), + Expr::ty(expr.arg()).canonical(), [Expr::canonical(expr.arg())], |dest, [src]| { vec![Insn::NotU { dest, src, - width: expr.arg().ty().width(), + width: Expr::ty(expr.arg()).width(), }] }, ) @@ -3081,7 +2970,7 @@ impl Compiler { ExprEnum::NotS(expr) => self .simple_nary_big_expr( instantiated_module, - expr.arg().ty().canonical(), + Expr::ty(expr.arg()).canonical(), [Expr::canonical(expr.arg())], |dest, [src]| vec![Insn::NotS { dest, src }], ) @@ -3089,7 +2978,7 @@ impl Compiler { ExprEnum::NotB(expr) => self .simple_nary_big_expr( instantiated_module, - expr.arg().ty().canonical(), + Expr::ty(expr.arg()).canonical(), [Expr::canonical(expr.arg())], |dest, [src]| { vec![Insn::NotU { @@ -3593,12 +3482,12 @@ impl Compiler { .map_ty(Bundle::from_canonical) .field_by_index(expr.field_index()), ExprEnum::VariantAccess(variant_access) => { - let start = variant_access.base().ty().discriminant_bit_width(); - let len = expr.ty().bit_width(); + let start = Expr::ty(variant_access.base()).discriminant_bit_width(); + let len = Expr::ty(expr).bit_width(); self.compile_expr( instantiated_module, variant_access.base().cast_to_bits()[start..start + len] - .cast_bits_to(expr.ty()), + .cast_bits_to(Expr::ty(expr)), ) } ExprEnum::ArrayIndex(expr) => self @@ -3620,39 +3509,45 @@ impl Compiler { .map_ty(Array::from_canonical) .element_dyn(index_slot) } - ExprEnum::ReduceBitAndU(expr) => if expr.arg().ty().width() == 0 { + ExprEnum::ReduceBitAndU(expr) => if Expr::ty(expr.arg()).width() == 0 { self.compile_expr(instantiated_module, Expr::canonical(true.to_expr())) } else { self.compile_expr( instantiated_module, - Expr::canonical(expr.arg().cmp_eq(expr.arg().ty().from_int_wrapping(-1))), + Expr::canonical( + expr.arg() + .cmp_eq(Expr::ty(expr.arg()).from_int_wrapping(-1)), + ), ) } .into(), - ExprEnum::ReduceBitAndS(expr) => if expr.arg().ty().width() == 0 { + ExprEnum::ReduceBitAndS(expr) => if Expr::ty(expr.arg()).width() == 0 { self.compile_expr(instantiated_module, Expr::canonical(true.to_expr())) } else { self.compile_expr( instantiated_module, - Expr::canonical(expr.arg().cmp_eq(expr.arg().ty().from_int_wrapping(-1))), + Expr::canonical( + expr.arg() + .cmp_eq(Expr::ty(expr.arg()).from_int_wrapping(-1)), + ), ) } .into(), - ExprEnum::ReduceBitOrU(expr) => if expr.arg().ty().width() == 0 { + ExprEnum::ReduceBitOrU(expr) => if Expr::ty(expr.arg()).width() == 0 { self.compile_expr(instantiated_module, Expr::canonical(false.to_expr())) } else { self.compile_expr( instantiated_module, - Expr::canonical(expr.arg().cmp_ne(expr.arg().ty().from_int_wrapping(0))), + Expr::canonical(expr.arg().cmp_ne(Expr::ty(expr.arg()).from_int_wrapping(0))), ) } .into(), - ExprEnum::ReduceBitOrS(expr) => if expr.arg().ty().width() == 0 { + ExprEnum::ReduceBitOrS(expr) => if Expr::ty(expr.arg()).width() == 0 { self.compile_expr(instantiated_module, Expr::canonical(false.to_expr())) } else { self.compile_expr( instantiated_module, - Expr::canonical(expr.arg().cmp_ne(expr.arg().ty().from_int_wrapping(0))), + Expr::canonical(expr.arg().cmp_ne(Expr::ty(expr.arg()).from_int_wrapping(0))), ) } .into(), @@ -3665,7 +3560,7 @@ impl Compiler { vec![Insn::ReduceBitXor { dest, src, - input_width: expr.arg().ty().width(), + input_width: Expr::ty(expr.arg()).width(), }] }, ) @@ -3679,7 +3574,7 @@ impl Compiler { vec![Insn::ReduceBitXor { dest, src, - input_width: expr.arg().ty().width(), + input_width: Expr::ty(expr.arg()).width(), }] }, ) @@ -3777,8 +3672,8 @@ impl Compiler { mut rhs: Expr, source_location: SourceLocation, ) { - if lhs.ty() != rhs.ty() || !lhs.ty().is_passive() { - match lhs.ty() { + if Expr::ty(lhs) != Expr::ty(rhs) || !Expr::ty(lhs).is_passive() { + match Expr::ty(lhs) { CanonicalType::UInt(lhs_ty) => { rhs = Expr::canonical(Expr::::from_canonical(rhs).cast_to(lhs_ty)); } @@ -3787,7 +3682,7 @@ impl Compiler { } CanonicalType::Bool(_) => unreachable!(), CanonicalType::Array(lhs_ty) => { - let CanonicalType::Array(rhs_ty) = rhs.ty() else { + let CanonicalType::Array(rhs_ty) = Expr::ty(rhs) else { unreachable!(); }; assert_eq!(lhs_ty.len(), rhs_ty.len()); @@ -3807,13 +3702,13 @@ impl Compiler { return; } CanonicalType::Enum(lhs_ty) => { - let CanonicalType::Enum(rhs_ty) = rhs.ty() else { + let CanonicalType::Enum(rhs_ty) = Expr::ty(rhs) else { unreachable!(); }; todo!("handle connect with different enum types"); } CanonicalType::Bundle(lhs_ty) => { - let CanonicalType::Bundle(rhs_ty) = rhs.ty() else { + let CanonicalType::Bundle(rhs_ty) = Expr::ty(rhs) else { unreachable!(); }; assert_eq!(lhs_ty.fields().len(), rhs_ty.fields().len()); @@ -4001,15 +3896,18 @@ impl Compiler { self.enum_discriminants.insert(enum_value, retval); retval } - fn compile_reg( + fn compile_stmt_reg( &mut self, - clk: CompiledValue, - reset_and_init: Option<(Expr, CompiledValue)>, - source_location: SourceLocation, + stmt_reg: StmtReg, instantiated_module: InstantiatedModule, value: CompiledValue, ) { - let clk = self.compile_clock(clk, source_location); + let StmtReg { annotations, reg } = stmt_reg; + let clk = self.compile_expr(instantiated_module, Expr::canonical(reg.clock_domain().clk)); + let clk = self + .compiled_expr_to_value(clk, reg.source_location()) + .map_ty(Clock::from_canonical); + let clk = self.compile_clock(clk, reg.source_location()); struct Dispatch; impl ResetTypeDispatch for Dispatch { type Input = (); @@ -4028,15 +3926,18 @@ impl Compiler { true } } - let reset = if let Some((rst_expr, init)) = reset_and_init { - let rst = self.compile_expr(instantiated_module, Expr::canonical(rst_expr)); - let rst = self.compiled_expr_to_value(rst, source_location); - let rst = self.compiled_value_bool_dest_is_small(rst, source_location); + let reset = if let Some(init) = reg.init() { + let init = self.compile_expr(instantiated_module, init); + let init = self.compiled_expr_to_value(init, reg.source_location()); + let rst = + self.compile_expr(instantiated_module, Expr::canonical(reg.clock_domain().rst)); + let rst = self.compiled_expr_to_value(rst, reg.source_location()); + let rst = self.compiled_value_bool_dest_is_small(rst, reg.source_location()); let is_async = R::dispatch((), Dispatch); if is_async { - let cond = Expr::canonical(rst_expr.cast_to(Bool)); + let cond = Expr::canonical(reg.clock_domain().rst.cast_to(Bool)); let cond = self.compile_expr(instantiated_module, cond); - let cond = self.compiled_expr_to_value(cond, source_location); + let cond = self.compiled_expr_to_value(cond, reg.source_location()); let cond = cond.map_ty(Bool::from_canonical); // write to the register's current value since asynchronous reset is combinational let lhs = CompiledValue { @@ -4048,12 +3949,12 @@ impl Compiler { self.compile_simple_connect( [Cond { body: CondBody::IfTrue { cond }, - source_location: source_location, - }] - .intern_slice(), + source_location: reg.source_location(), + }][..] + .intern(), lhs, init, - source_location, + reg.source_location(), ); } Some(RegisterReset { @@ -4068,33 +3969,9 @@ impl Compiler { value, clk_triggered: clk.clk_triggered, reset, - source_location, + source_location: reg.source_location(), }); } - fn compile_stmt_reg( - &mut self, - stmt_reg: StmtReg, - instantiated_module: InstantiatedModule, - value: CompiledValue, - ) { - let StmtReg { annotations, reg } = stmt_reg; - let clk = self.compile_expr(instantiated_module, Expr::canonical(reg.clock_domain().clk)); - let clk = self - .compiled_expr_to_value(clk, reg.source_location()) - .map_ty(Clock::from_canonical); - let reset_and_init = reg.init().map(|init| { - let init = self.compile_expr(instantiated_module, init); - let init = self.compiled_expr_to_value(init, reg.source_location()); - (reg.clock_domain().rst, init) - }); - self.compile_reg( - clk, - reset_and_init, - reg.source_location(), - instantiated_module, - value, - ); - } fn compile_declaration( &mut self, declaration: StmtDeclaration, @@ -4360,24 +4237,24 @@ impl Compiler { insns.push(end_label.into()); } } - CompiledTypeLayoutBody::Array { elements_non_empty } => { + CompiledTypeLayoutBody::Array { element } => { let CompiledTypeLayoutBody::Array { - elements_non_empty: mask_elements_non_empty, + element: mask_element, } = mask_layout.body else { unreachable!(); }; let ty = ::from_canonical(data_layout.ty); let element_bit_width = ty.element().bit_width(); - let element_size = elements_non_empty[0].layout.len(); - let mask_element_size = mask_elements_non_empty[0].layout.len(); + let element_size = element.layout.len(); + let mask_element_size = mask_element.layout.len(); for element_index in 0..ty.len() { self.compile_memory_port_rw_helper( memory, stride, start, - elements_non_empty[element_index], - mask_elements_non_empty[element_index], + *element, + *mask_element, read.as_mut().map( |MemoryPortReadInsns { addr, @@ -4416,7 +4293,6 @@ impl Compiler { start += element_bit_width; } } - CompiledTypeLayoutBody::PhantomConst => {} CompiledTypeLayoutBody::Bundle { fields } => { let CompiledTypeLayoutBody::Bundle { fields: mask_fields, @@ -4984,88 +4860,6 @@ impl Compiler { } } } - fn compile_extern_module_clock_for_past( - &mut self, - instantiated_module: InstantiatedModule, - clock_for_past: Target, - ) -> ExternModuleClockForPast { - let clock_for_past = TargetInInstantiatedModule { - instantiated_module, - target: clock_for_past, - }; - let clock_for_past = self - .compile_value(clock_for_past) - .map_ty(Clock::from_canonical); - let clock_for_past_debug_name = match clock_for_past - .range - .len() - .as_single() - .expect("Clock is a single slot") - { - TypeLenSingle::BigSlot => { - self.insns - .state_layout - .ty - .big_slots - .debug_data(clock_for_past.range.start().big_slots) - .name - } - TypeLenSingle::SmallSlot => { - self.insns - .state_layout - .ty - .small_slots - .debug_data(clock_for_past.range.start().small_slots) - .name - } - TypeLenSingle::SimOnlySlot => { - unreachable!() - } - }; - let module_prefix = format!("{instantiated_module:?}."); - let trimmed_clock_for_past_debug_name = clock_for_past_debug_name - .strip_prefix(&module_prefix) - .unwrap_or(&clock_for_past_debug_name); - let current_to_past_map = instantiated_module - .leaf_module() - .module_io() - .iter() - .map( - |&AnnotatedModuleIO { - annotations: _, - module_io, - }| { - let target_base = TargetBase::from(module_io); - let current = self.compile_value(TargetInInstantiatedModule { - instantiated_module, - target: target_base.into(), - }); - let unprefixed_layout = CompiledTypeLayout::get(module_io.ty()); - let past_layout = unprefixed_layout.with_prefixed_debug_names(&format!( - "{module_prefix}{:?}$past({trimmed_clock_for_past_debug_name})", - target_base.target_name(), - )); - let past = CompiledValue { - range: self.insns.allocate_variable(&past_layout.layout), - layout: past_layout, - write: Some((current.layout, current.range)), - }; - self.compile_reg::( - clock_for_past, - None, - module_io.source_location(), - instantiated_module, - past, - ); - (current, past) - }, - ) - .collect(); - ExternModuleClockForPast { - clock_for_past, - current_to_past_map, - } - } fn compile_module(&mut self, module: Interned) -> &CompiledModule { let mut trace_decls = Vec::new(); let module_io = module @@ -5094,7 +4888,6 @@ impl Compiler { ModuleBody::Extern(ExternModuleBody { verilog_name: _, parameters: _, - clocks_for_past, simulation, }) => { let Some(simulation) = simulation else { @@ -5111,18 +4904,10 @@ impl Compiler { Target::from(*simulation.sim_io_to_generator_map[&v.module_io.intern()]) }) .collect(); - let clocks_for_past = clocks_for_past - .iter() - .map(|clock_for_past| { - self.compile_extern_module_clock_for_past(*module, *clock_for_past) - }) - .collect(); self.extern_modules.push(CompiledExternModule { module_io_targets, module_io, - clocks_for_past, simulation, - debug_name: format!("{module:?}").intern_deref(), }); } } diff --git a/crates/fayalite/src/sim/interpreter.rs b/crates/fayalite/src/sim/interpreter.rs index 2b121b5..1a6c269 100644 --- a/crates/fayalite/src/sim/interpreter.rs +++ b/crates/fayalite/src/sim/interpreter.rs @@ -2,7 +2,6 @@ // See Notices.txt for copyright information use crate::{ - expr::ValueType, int::{BoolOrIntType, SInt, UInt}, intern::{Intern, Interned, Memoize}, sim::interpreter::parts::{ @@ -197,27 +196,13 @@ impl fmt::Debug for Insn { } } -pub(crate) struct PrefixLinesWrapper<'a, W> { +struct PrefixLinesWrapper<'a, W> { writer: W, at_beginning_of_line: bool, blank_line_prefix: &'a str, line_prefix: &'a str, } -impl<'a, W> PrefixLinesWrapper<'a, W> { - pub(crate) fn new(writer: W, at_beginning_of_line: bool, line_prefix: &'a str) -> Self { - Self { - writer, - at_beginning_of_line, - blank_line_prefix: line_prefix.trim_end(), - line_prefix, - } - } - pub(crate) fn into_inner(self) -> W { - self.writer - } -} - impl fmt::Write for PrefixLinesWrapper<'_, T> { fn write_str(&mut self, input: &str) -> fmt::Result { for part in input.split_inclusive('\n') { @@ -254,7 +239,12 @@ impl Insn { if fields.len() == 0 { return Ok(()); } - let mut f = PrefixLinesWrapper::new(f, false, " "); + let mut f = PrefixLinesWrapper { + writer: f, + at_beginning_of_line: false, + blank_line_prefix: "", + line_prefix: " ", + }; writeln!(f, " {{")?; for (field_name, field) in fields { write!(f, "{field_name}: ")?; @@ -330,7 +320,7 @@ impl Insn { } writeln!(f, ",")?; } - write!(f.into_inner(), "}}") + write!(f.writer, "}}") } } diff --git a/crates/fayalite/src/sim/interpreter/parts.rs b/crates/fayalite/src/sim/interpreter/parts.rs index 75427c9..8732146 100644 --- a/crates/fayalite/src/sim/interpreter/parts.rs +++ b/crates/fayalite/src/sim/interpreter/parts.rs @@ -9,7 +9,7 @@ use crate::{ Insn, InsnsBuilding, InsnsBuildingDone, InsnsBuildingKind, PrefixLinesWrapper, SmallSInt, SmallUInt, State, }, - value::{DynSimOnly, DynSimOnlyValue}, + value::{DynSimOnlyValue, DynSimOnly}, }, ty::CanonicalType, util::{chain, const_str_cmp}, @@ -435,7 +435,12 @@ impl StatePartIndex { if state.is_some() || debug_data.is_some() { f.write_str(comment_start)?; } - let mut f = PrefixLinesWrapper::new(f, false, comment_line_start); + let mut f = PrefixLinesWrapper { + writer: f, + at_beginning_of_line: false, + blank_line_prefix: comment_line_start.trim_end(), + line_prefix: comment_line_start, + }; if let Some(state) = state { f.write_str("(")?; K::debug_fmt_state_value(state, *self, &mut f)?; @@ -448,7 +453,7 @@ impl StatePartIndex { write!(f, "{debug_data:?}")?; } if state.is_some() || debug_data.is_some() { - f.into_inner().write_str(comment_end)?; + f.writer.write_str(comment_end)?; } Ok(()) } diff --git a/crates/fayalite/src/sim/value.rs b/crates/fayalite/src/sim/value.rs index def2ae3..9717417 100644 --- a/crates/fayalite/src/sim/value.rs +++ b/crates/fayalite/src/sim/value.rs @@ -6,10 +6,7 @@ use crate::{ bundle::{Bundle, BundleType}, clock::Clock, enum_::{Enum, EnumType}, - expr::{ - CastBitsTo, Expr, HdlPartialEq, HdlPartialEqImpl, HdlPartialOrd, ToExpr, ValueType, - value_category::{ValueCategorySimValue, ValueCategoryValue}, - }, + expr::{CastBitsTo, Expr, ToExpr}, int::{Bool, IntType, KnownSize, SInt, SIntType, SIntValue, Size, UInt, UIntType, UIntValue}, reset::{AsyncReset, Reset, SyncReset}, source_location::SourceLocation, @@ -26,11 +23,10 @@ use bitvec::{slice::BitSlice, vec::BitVec}; use hashbrown::hash_map::Entry; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _}; use std::{ - borrow::{Borrow, BorrowMut, Cow}, + borrow::Cow, fmt::{self, Write}, hash::{BuildHasher, Hash, Hasher, RandomState}, - num::NonZero, - ops::{Deref, DerefMut, Index, IndexMut}, + ops::{Deref, DerefMut}, sync::{Arc, Mutex}, }; @@ -140,7 +136,7 @@ impl + Serialize> Serialize for SimValue { S: Serializer, { SerdeSimValue { - ty: self.ty(), + ty: SimValue::ty(self), value: std::borrow::Cow::Borrowed(&*self), } .serialize(serializer) @@ -161,22 +157,7 @@ pub struct SimValue { inner: AlternatingCell>, } -impl ValueType for SimValue { - type Type = T; - type ValueCategory = ValueCategorySimValue; - - fn ty(&self) -> Self::Type { - self.inner.share().ty - } -} - -impl> fmt::Display for SimValue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - T::SimValue::fmt(self, f) - } -} - -impl Clone for SimValue { +impl Clone for SimValue { fn clone(&self) -> Self { Self { inner: AlternatingCell::new_unique(self.inner.share().clone()), @@ -231,6 +212,9 @@ impl SimValue { inner: AlternatingCell::new_unique(inner), } } + pub fn ty(this: &Self) -> T { + this.inner.share().ty + } pub fn into_opaque(this: Self) -> OpaqueSimValue { this.inner.into_inner().into_opaque() } @@ -269,7 +253,7 @@ impl SimValue { SimValue::from_opaque(ty.canonical(), opaque) } pub fn canonical(this: &Self) -> SimValue { - SimValue::from_opaque(this.ty().canonical(), Self::opaque(this).clone()) + SimValue::from_opaque(Self::ty(this).canonical(), Self::opaque(this).clone()) } #[track_caller] pub fn from_dyn_int(v: SimValue) -> Self @@ -290,7 +274,7 @@ impl SimValue { where T: IntType, { - SimValue::from_opaque(this.ty().as_dyn_int(), Self::opaque(&this).clone()) + SimValue::from_opaque(Self::ty(this).as_dyn_int(), Self::opaque(&this).clone()) } #[track_caller] pub fn from_bundle(v: SimValue) -> Self @@ -312,7 +296,7 @@ impl SimValue { T: BundleType, { SimValue::from_opaque( - Bundle::from_canonical(this.ty().canonical()), + Bundle::from_canonical(Self::ty(this).canonical()), Self::opaque(&this).clone(), ) } @@ -336,7 +320,7 @@ impl SimValue { T: EnumType, { SimValue::from_opaque( - Enum::from_canonical(this.ty().canonical()), + Enum::from_canonical(Self::ty(this).canonical()), Self::opaque(&this).clone(), ) } @@ -367,6 +351,8 @@ impl fmt::Debug for SimValue { } impl ToExpr for SimValue { + type Type = T; + #[track_caller] fn to_expr(&self) -> Expr { let inner = self.inner.share(); @@ -374,297 +360,43 @@ impl ToExpr for SimValue { inner.sim_only_values_len, 0, "can't convert sim-only values to Expr" ); - inner.opaque.bits().to_expr().cast_bits_to(inner.ty) + inner.opaque.bits().cast_bits_to(inner.ty) } } -impl Index for SimValue> -where - [SimValue]: Index, -{ - type Output = <[SimValue] as Index>::Output; - - fn index(&self, index: I) -> &Self::Output { - (**self).borrow().index(index) - } +pub trait SimValuePartialEq: Type { + #[track_caller] + fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool; } -impl IndexMut for SimValue> -where - [SimValue]: IndexMut, -{ - fn index_mut(&mut self, index: I) -> &mut Self::Output { - (**self).borrow_mut().index_mut(index) - } -} - -impl SimValue> { - pub fn iter(&self) -> std::slice::Iter<'_, SimValue> { - (**self).borrow().iter() - } - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, SimValue> { - (**self).borrow_mut().iter_mut() - } -} - -impl IntoIterator for SimValue> { - type Item = SimValue; - type IntoIter = std::vec::IntoIter>; - - fn into_iter(self) -> Self::IntoIter { - Vec::into_iter(Self::into_value(self).into()) - } -} - -impl<'a, T: Type, Len: Size> IntoIterator for &'a SimValue> { - type Item = &'a SimValue; - type IntoIter = std::slice::Iter<'a, SimValue>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -impl<'a, T: Type, Len: Size> IntoIterator for &'a mut SimValue> { - type Item = &'a mut SimValue; - type IntoIter = std::slice::IterMut<'a, SimValue>; - - fn into_iter(self) -> Self::IntoIter { - self.iter_mut() - } -} - -impl AsRef<[SimValue]> for SimValue> { - fn as_ref(&self) -> &[SimValue] { - (**self).as_ref() - } -} - -impl AsMut<[SimValue]> for SimValue> { - fn as_mut(&mut self) -> &mut [SimValue] { - (**self).as_mut() - } -} - -impl PartialEq> for SimValue -where - Self: for<'a> HdlPartialEq<&'a SimValue, Output = SimValue>, -{ +impl, U: Type> PartialEq> for SimValue { #[track_caller] fn eq(&self, other: &SimValue) -> bool { - *self.cmp_eq(other) - } - #[track_caller] - fn ne(&self, other: &SimValue) -> bool { - *self.cmp_ne(other) + T::sim_value_eq(self, other) } } -pub trait SimValueEq: Type -where - for<'a> SimValue: HdlPartialEq<&'a SimValue, Output = SimValue>, -{ -} - -impl Eq for SimValue where - for<'a> SimValue: HdlPartialEq<&'a SimValue, Output = SimValue> -{ -} - -impl PartialOrd> for SimValue -where - Self: for<'a> HdlPartialOrd<&'a SimValue, Output = SimValue>, -{ - #[track_caller] - fn partial_cmp(&self, other: &SimValue) -> Option { - if *self.cmp_eq(other) { - Some(std::cmp::Ordering::Equal) - } else if *self.cmp_lt(other) { - Some(std::cmp::Ordering::Less) - } else if *self.cmp_gt(other) { - Some(std::cmp::Ordering::Greater) - } else { - None - } - } - - #[track_caller] - fn lt(&self, other: &SimValue) -> bool { - *self.cmp_lt(other) - } - - #[track_caller] - fn le(&self, other: &SimValue) -> bool { - *self.cmp_le(other) - } - - #[track_caller] - fn gt(&self, other: &SimValue) -> bool { - *self.cmp_gt(other) - } - - #[track_caller] - fn ge(&self, other: &SimValue) -> bool { - *self.cmp_ge(other) +impl SimValuePartialEq for UIntType { + fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { + **this == **other } } -pub trait SimValueOrd: SimValueEq -where - for<'a> SimValue: HdlPartialOrd<&'a SimValue, Output = SimValue>, -{ -} - -impl Ord for SimValue -where - for<'a> SimValue: HdlPartialOrd<&'a SimValue, Output = SimValue>, -{ - #[track_caller] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - if *self.cmp_eq(other) { - std::cmp::Ordering::Equal - } else if *self.cmp_lt(other) { - std::cmp::Ordering::Less - } else { - std::cmp::Ordering::Greater - } +impl SimValuePartialEq for SIntType { + fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { + **this == **other } } -impl SimValueEq for UIntType {} - -impl SimValueOrd for UIntType {} - -impl SimValueEq for SIntType {} - -impl SimValueOrd for SIntType {} - -macro_rules! impl_sim_value_cmp_as_bool { - ($ty:ident) => { - impl SimValueEq for $ty {} - - impl SimValueOrd for $ty {} - }; -} - -impl_sim_value_cmp_as_bool!(Bool); -impl_sim_value_cmp_as_bool!(Clock); -impl_sim_value_cmp_as_bool!(Reset); -impl_sim_value_cmp_as_bool!(SyncReset); -impl_sim_value_cmp_as_bool!(AsyncReset); - -#[doc(hidden)] -pub mod match_sim_value { - use crate::{ - sim::value::{SimValue, ToSimValue}, - ty::Type, - }; - - #[doc(hidden)] - pub struct MatchSimValueHelper(Option); - - impl MatchSimValueHelper { - pub fn new(v: T) -> Self { - Self(Some(v)) - } - } - - #[doc(hidden)] - pub trait MatchSimValue { - type MatchValue; - - /// use `self` so it comes first in the method resolution order - fn __fayalite_match_sim_value(self) -> Self::MatchValue - where - Self: Sized; - } - - impl MatchSimValue for MatchSimValueHelper> { - type MatchValue = T::SimValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - SimValue::into_value(self.0.expect("should be Some")) - } - } - - impl<'a, T: Type> MatchSimValue for MatchSimValueHelper<&'a SimValue> { - type MatchValue = &'a T::SimValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - SimValue::value(self.0.expect("should be Some")) - } - } - - impl<'a, T: Type> MatchSimValue for MatchSimValueHelper<&'a mut SimValue> { - type MatchValue = &'a mut T::SimValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - SimValue::value_mut(self.0.expect("should be Some")) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'_ &'a T> - where - MatchSimValueHelper<&'a T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| *v))) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'_ mut &'a T> - where - MatchSimValueHelper<&'a T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| *v))) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'a &'_ mut T> - where - MatchSimValueHelper<&'a T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| &**v))) - } - } - - impl<'a, T> MatchSimValue for MatchSimValueHelper<&'a mut &'_ mut T> - where - MatchSimValueHelper<&'a mut T>: MatchSimValue, - { - type MatchValue = as MatchSimValue>::MatchValue; - - fn __fayalite_match_sim_value(self) -> Self::MatchValue { - MatchSimValue::__fayalite_match_sim_value(MatchSimValueHelper(self.0.map(|v| &mut **v))) - } - } - - #[doc(hidden)] - pub trait MatchSimValueFallback { - type MatchValue; - - /// use `&mut self` so it comes later in the method resolution order than MatchSimValue - fn __fayalite_match_sim_value(&mut self) -> Self::MatchValue; - } - - impl MatchSimValueFallback for MatchSimValueHelper { - type MatchValue = ::SimValue; - - fn __fayalite_match_sim_value(&mut self) -> Self::MatchValue { - SimValue::into_value(self.0.take().expect("should be Some").into_sim_value()) - } +impl SimValuePartialEq for Bool { + fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { + **this == **other } } -pub trait ToSimValue: ToSimValueWithType<::Type> + ValueType { +pub trait ToSimValue: ToSimValueWithType<::Type> { + type Type: Type; + #[track_caller] fn to_sim_value(&self) -> SimValue; #[track_caller] @@ -706,31 +438,31 @@ pub trait ToSimValueWithType { 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> { + 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!(retval.ty(), ty); + assert_eq!(SimValue::ty(&retval), ty); retval } #[track_caller] - fn into_sim_value_with_type(self, ty: ::Type) -> SimValue<::Type> + fn into_sim_value_with_type(self, ty: ::Type) -> SimValue<::Type> where Self: Sized, { let retval = Self::into_sim_value(self); - assert_eq!(retval.ty(), ty); + assert_eq!(SimValue::ty(&retval), ty); retval } #[track_caller] - fn arc_into_sim_value_with_type(self: Arc, ty: ::Type) -> SimValue<::Type> { + fn arc_into_sim_value_with_type(self: Arc, ty: ::Type) -> SimValue<::Type> { let retval = Self::arc_into_sim_value(self); - assert_eq!(retval.ty(), ty); + assert_eq!(SimValue::ty(&retval), ty); retval } #[track_caller] - fn arc_to_sim_value_with_type(self: &Arc, ty: ::Type) -> SimValue<::Type> { + fn arc_to_sim_value_with_type(self: &Arc, ty: ::Type) -> SimValue<::Type> { let retval = Self::arc_to_sim_value(self); - assert_eq!(retval.ty(), ty); + assert_eq!(SimValue::ty(&retval), ty); retval } } @@ -738,6 +470,7 @@ macro_rules! forward_to_sim_value_with_type { } impl ToSimValue for SimValue { + type Type = T; fn to_sim_value(&self) -> SimValue { self.clone() } @@ -793,7 +526,9 @@ impl ToSimValueWithType for BitSlice { } } -impl<'a, This: ?Sized + ToSimValue> ToSimValue for &'a This { +impl ToSimValue for &'_ This { + type Type = This::Type; + fn to_sim_value(&self) -> SimValue { This::to_sim_value(self) } @@ -806,6 +541,8 @@ impl, T: Type> ToSimValueWithType for &' } impl ToSimValue for &'_ mut This { + type Type = This::Type; + fn to_sim_value(&self) -> SimValue { This::to_sim_value(self) } @@ -818,6 +555,8 @@ impl, T: Type> ToSimValueWithType for &' } impl ToSimValue for Arc { + type Type = This::Type; + fn to_sim_value(&self) -> SimValue { This::arc_to_sim_value(self) } @@ -838,6 +577,7 @@ impl, T: Type> ToSimValueWithType for Ar impl ToSimValue for crate::intern::Interned { + type Type = This::Type; fn to_sim_value(&self) -> SimValue { This::to_sim_value(self) } @@ -852,6 +592,8 @@ impl + Send + Sync + 'static, T: Type> ToSi } impl ToSimValue for Box { + type Type = This::Type; + fn to_sim_value(&self) -> SimValue { This::to_sim_value(self) } @@ -894,6 +636,8 @@ impl, T: Type> ToSimValueWithType> for [ } 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) @@ -929,6 +673,8 @@ impl, const N: usize> ToSimValue for [Elem where ConstUsize: KnownSize, { + type Type = Array; + fn to_sim_value(&self) -> SimValue { SimValue::from_array_elements(StaticType::TYPE, self) } @@ -982,6 +728,8 @@ impl, T: Type> ToSimValueWithType> for V } 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) } @@ -1022,6 +770,8 @@ impl, T: Type> ToSimValueWithType> for B } 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) } @@ -1051,10 +801,11 @@ impl> ToSimValueWithType ToSimValue for Expr { + type Type = T; #[track_caller] fn to_sim_value(&self) -> SimValue { SimValue::from_bitslice( - self.ty(), + Expr::ty(*self), &crate::expr::ToLiteralBits::to_literal_bits(self) .expect("must be a literal expression"), ) @@ -1074,6 +825,8 @@ macro_rules! impl_to_sim_value_for_bool_like { } impl ToSimValue for bool { + type Type = Bool; + fn to_sim_value(&self) -> SimValue { SimValue::from_value(Bool, *self) } @@ -1111,8 +864,10 @@ impl ToSimValueWithType for bool { } macro_rules! impl_to_sim_value_for_primitive_int { - ($prim:ty) => { + ($prim:ident) => { impl ToSimValue for $prim { + type Type = <$prim as ToExpr>::Type; + #[track_caller] fn to_sim_value( &self, @@ -1123,15 +878,15 @@ macro_rules! impl_to_sim_value_for_primitive_int { forward_to_sim_value_with_type!([] $prim); - impl ToSimValueWithType<<<$prim as ValueType>::Type as IntType>::Dyn> for $prim { + impl ToSimValueWithType<<<$prim as ToExpr>::Type as IntType>::Dyn> for $prim { #[track_caller] fn to_sim_value_with_type( &self, - ty: <<$prim as ValueType>::Type as IntType>::Dyn, - ) -> SimValue<<<$prim as ValueType>::Type as IntType>::Dyn> { + ty: <<$prim as ToExpr>::Type as IntType>::Dyn, + ) -> SimValue<<<$prim as ToExpr>::Type as IntType>::Dyn> { SimValue::from_value( ty, - <<$prim as ValueType>::Type as Type>::SimValue::from(*self).as_dyn_int(), + <<$prim as ToExpr>::Type as Type>::SimValue::from(*self).as_dyn_int(), ) } } @@ -1139,7 +894,7 @@ macro_rules! impl_to_sim_value_for_primitive_int { impl ToSimValueWithType for $prim { #[track_caller] fn to_sim_value_with_type(&self, ty: CanonicalType) -> SimValue { - let ty: <<$prim as ValueType>::Type as IntType>::Dyn = Type::from_canonical(ty); + let ty: <<$prim as ToExpr>::Type as IntType>::Dyn = Type::from_canonical(ty); SimValue::into_canonical(self.to_sim_value_with_type(ty)) } } @@ -1158,22 +913,12 @@ 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); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); -impl_to_sim_value_for_primitive_int!(NonZero); 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()) } @@ -1534,6 +1279,8 @@ impl ToSimValueWithType> for SimOnlyValue { } impl ToSimValue for DynSimOnlyValue { + type Type = DynSimOnly; + fn to_sim_value(&self) -> SimValue { SimValue::from_value(self.ty(), self.clone()) } @@ -1543,58 +1290,15 @@ impl ToSimValue for DynSimOnlyValue { } } -impl ValueType for SimOnlyValue { - type Type = SimOnly; - type ValueCategory = ValueCategoryValue; - - fn ty(&self) -> Self::Type { - SimOnly::new() - } -} - impl ToSimValue for SimOnlyValue { + type Type = SimOnly; + fn to_sim_value(&self) -> SimValue { - SimValue::from_value(self.ty(), self.clone()) + SimValue::from_value(Default::default(), self.clone()) } fn into_sim_value(self) -> SimValue { - SimValue::from_value(self.ty(), self) - } -} - -impl HdlPartialEqImpl for DynSimOnly { - #[track_caller] - fn cmp_value_eq( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: Self, - rhs_value: Cow<'_, Self::SimValue>, - ) -> bool { - *lhs_value == *rhs_value - } - - #[track_caller] - fn cmp_expr_eq(_lhs: Expr, _rhs: Expr) -> Expr { - panic!("can't compare Expr"); - } -} - -impl, R: SimOnlyValueTrait> HdlPartialEqImpl> - for SimOnly -{ - #[track_caller] - fn cmp_value_eq( - _lhs: Self, - lhs_value: Cow<'_, Self::SimValue>, - _rhs: SimOnly, - rhs_value: Cow<'_, as Type>::SimValue>, - ) -> bool { - **lhs_value == **rhs_value - } - - #[track_caller] - fn cmp_expr_eq(_lhs: Expr, _rhs: Expr>) -> Expr { - panic!("can't compare Expr>"); + SimValue::from_value(Default::default(), self) } } diff --git a/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs b/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs index 2424c03..98a199c 100644 --- a/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs +++ b/crates/fayalite/src/sim/value/sim_only_value_unsafe.rs @@ -3,7 +3,6 @@ //! `unsafe` parts of [`DynSimOnlyValue`] -use crate::expr::{ValueType, value_category::ValueCategoryValue}; use serde::{Serialize, de::DeserializeOwned}; use std::{ any::{self, TypeId}, @@ -207,25 +206,9 @@ impl Default for SimOnly { } /// a value that can only be used in a Fayalite simulation, it can't be converted to FIRRTL -#[derive(Clone, Eq, Hash, Default, Ord)] +#[derive(Clone, Eq, PartialEq, Hash, Default, PartialOrd, Ord)] pub struct SimOnlyValue(Rc); -impl, U: SimOnlyValueTrait> PartialEq> - for SimOnlyValue -{ - fn eq(&self, other: &SimOnlyValue) -> bool { - >::eq(self, other) - } -} - -impl, U: SimOnlyValueTrait> PartialOrd> - for SimOnlyValue -{ - fn partial_cmp(&self, other: &SimOnlyValue) -> Option { - >::partial_cmp(self, other) - } -} - impl SimOnlyValue { pub fn with_dyn_ref R, R>(&self, f: F) -> R { // Safety: creating a copied `Rc` is safe as long as the copy isn't dropped and isn't changed @@ -296,16 +279,10 @@ impl From> for DynSimOnlyValue { } } -impl ValueType for DynSimOnlyValue { - type Type = DynSimOnly; - type ValueCategory = ValueCategoryValue; - - fn ty(&self) -> Self::Type { +impl DynSimOnlyValue { + pub fn ty(&self) -> DynSimOnly { self.0.ty() } -} - -impl DynSimOnlyValue { pub fn type_id(&self) -> TypeId { self.0.type_id_dyn() } diff --git a/crates/fayalite/src/sim/vcd.rs b/crates/fayalite/src/sim/vcd.rs index 6ba37b3..e66c3ee 100644 --- a/crates/fayalite/src/sim/vcd.rs +++ b/crates/fayalite/src/sim/vcd.rs @@ -6,14 +6,12 @@ use crate::{ expr::Flow, int::UInt, intern::{Intern, Interned}, - prelude::PhantomConst, sim::{ TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl, TraceEnumDiscriminant, TraceEnumWithFields, TraceFieldlessEnum, TraceInstance, TraceLocation, TraceMem, TraceMemPort, TraceMemoryId, TraceMemoryLocation, TraceModule, - TraceModuleIO, TracePhantomConst, TraceReg, TraceSInt, TraceScalar, TraceScalarId, - TraceScope, TraceSimOnly, TraceSyncReset, TraceUInt, TraceWire, TraceWriter, - TraceWriterDecls, + TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, TraceScope, TraceSimOnly, + TraceSyncReset, TraceUInt, TraceWire, TraceWriter, TraceWriterDecls, time::{SimDuration, SimInstant}, value::DynSimOnlyValue, }, @@ -285,7 +283,6 @@ impl WriteTrace for TraceScalar { Self::Clock(v) => v.write_trace(writer, arg), Self::SyncReset(v) => v.write_trace(writer, arg), Self::AsyncReset(v) => v.write_trace(writer, arg), - Self::PhantomConst(v) => v.write_trace(writer, arg), Self::SimOnly(v) => v.write_trace(writer, arg), } } @@ -552,33 +549,6 @@ impl WriteTrace for TraceAsyncReset { } } -impl WriteTrace for TracePhantomConst { - fn write_trace(self, writer: &mut W, mut arg: A) -> io::Result<()> { - let ArgInType { - source_var_type: _, - sink_var_type: _, - duplex_var_type: _, - properties, - scope, - } = arg.in_type(); - let Self { - location, - name, - ty: _, - flow: _, - } = self; - write_vcd_var( - properties, - MemoryElementPartBody::Scalar, - writer, - "string", - 1, - location, - scope.new_identifier(name), - ) - } -} - impl WriteTrace for TraceSimOnly { fn write_trace(self, writer: &mut W, mut arg: A) -> io::Result<()> { let ArgInType { @@ -1121,16 +1091,6 @@ impl TraceWriter for VcdWriter { write_enum_discriminant_value_change(&mut self.writer, variant_index, ty, id.as_usize()) } - fn set_signal_phantom_const( - &mut self, - id: TraceScalarId, - ty: PhantomConst, - ) -> Result<(), Self::Error> { - // avoid multi-line strings because GTKWave can't display them properly: - // https://github.com/gtkwave/gtkwave/issues/460 - write_string_value_change(&mut self.writer, format_args!("{ty:?}"), id.as_usize()) - } - fn set_signal_sim_only_value( &mut self, id: TraceScalarId, diff --git a/crates/fayalite/src/testing.rs b/crates/fayalite/src/testing.rs index bc7a0b1..b81bc3f 100644 --- a/crates/fayalite/src/testing.rs +++ b/crates/fayalite/src/testing.rs @@ -1,54 +1,25 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information use crate::{ - build::{ - BaseJobArgs, BaseJobKind, GlobalParams, JobArgsAndDependencies, JobKindAndArgs, JobParams, - NoArgs, RunBuild, - external::{ExternalCommandArgs, ExternalCommandJobKind}, - firrtl::{FirrtlArgs, FirrtlJobKind}, - formal::{Formal, FormalAdditionalArgs, FormalArgs, WriteSbyFileJobKind}, - verilog::{UnadjustedVerilogArgs, VerilogJobArgs, VerilogJobKind}, - }, - bundle::BundleType, + cli::{FormalArgs, FormalMode, FormalOutput, RunPhase}, firrtl::ExportOptions, - module::Module, util::HashMap, }; -use serde::{Deserialize, Serialize}; +use clap::Parser; +use serde::Deserialize; use std::{ - fmt::{self, Write}, + fmt::Write, path::{Path, PathBuf}, process::Command, sync::{Mutex, OnceLock}, }; -#[derive( - clap::ValueEnum, Copy, Clone, Debug, PartialEq, Eq, Hash, Default, Deserialize, Serialize, -)] -#[non_exhaustive] -pub enum FormalMode { - #[default] - BMC, - Prove, - Live, - Cover, -} - -impl FormalMode { - pub fn as_str(self) -> &'static str { - match self { - FormalMode::BMC => "bmc", - FormalMode::Prove => "prove", - FormalMode::Live => "live", - FormalMode::Cover => "cover", - } - } -} - -impl fmt::Display for FormalMode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } +fn assert_formal_helper() -> FormalArgs { + static FORMAL_ARGS: OnceLock = OnceLock::new(); + // ensure we only run parsing once, so errors from env vars don't produce overlapping output if we're called on multiple threads + FORMAL_ARGS + .get_or_init(|| FormalArgs::parse_from(["fayalite::testing::assert_formal"])) + .clone() } #[derive(Deserialize)] @@ -126,99 +97,26 @@ fn get_assert_formal_target_path(test_name: &dyn std::fmt::Display) -> PathBuf { .join(dir) } -fn make_assert_formal_args( - test_name: &dyn std::fmt::Display, - formal_mode: FormalMode, - formal_depth: u64, - solver: Option<&str>, - export_options: ExportOptions, -) -> eyre::Result>> { - let args = JobKindAndArgs { - kind: BaseJobKind, - args: BaseJobArgs::from_output_dir_and_env(get_assert_formal_target_path(&test_name), None), - }; - let dependencies = JobArgsAndDependencies { - args, - dependencies: (), - }; - let args = JobKindAndArgs { - kind: FirrtlJobKind, - args: FirrtlArgs { export_options }, - }; - let dependencies = JobArgsAndDependencies { args, dependencies }; - let args = JobKindAndArgs { - kind: ExternalCommandJobKind::new(), - args: ExternalCommandArgs::resolve_program_path( - None, - UnadjustedVerilogArgs { - firtool_extra_args: vec![], - verilog_dialect: None, - verilog_debug: true, - }, - )?, - }; - let dependencies = JobArgsAndDependencies { args, dependencies }; - let args = JobKindAndArgs { - kind: VerilogJobKind, - args: VerilogJobArgs {}, - }; - let dependencies = JobArgsAndDependencies { args, dependencies }; - let args = JobKindAndArgs { - kind: WriteSbyFileJobKind, - args: FormalArgs { - sby_extra_args: vec![], - formal_mode, - formal_depth, - formal_solver: solver.unwrap_or(FormalArgs::DEFAULT_SOLVER).into(), - smtbmc_extra_args: vec![], - }, - }; - let dependencies = JobArgsAndDependencies { args, dependencies }; - let args = JobKindAndArgs { - kind: ExternalCommandJobKind::new(), - args: ExternalCommandArgs::resolve_program_path(None, FormalAdditionalArgs {})?, - }; - Ok(JobArgsAndDependencies { args, dependencies }) -} - -pub fn try_assert_formal>, T: BundleType>( - test_name: impl std::fmt::Display, - module: M, - formal_mode: FormalMode, - formal_depth: u64, - solver: Option<&str>, - export_options: ExportOptions, -) -> eyre::Result<()> { - const APP_NAME: &'static str = "fayalite::testing::assert_formal"; - make_assert_formal_args( - &test_name, - formal_mode, - formal_depth, - solver, - export_options, - )? - .run_without_platform( - |NoArgs {}| Ok(JobParams::new(module)), - &GlobalParams::new(None, APP_NAME), - ) -} - #[track_caller] -pub fn assert_formal>, T: BundleType>( +pub fn assert_formal( test_name: impl std::fmt::Display, module: M, - formal_mode: FormalMode, - formal_depth: u64, + mode: FormalMode, + depth: u64, solver: Option<&str>, export_options: ExportOptions, -) { - try_assert_formal( - test_name, - module, - formal_mode, - formal_depth, - solver, - export_options, - ) - .expect("testing::assert_formal() failed"); +) where + FormalArgs: RunPhase, +{ + let mut args = assert_formal_helper(); + args.verilog.firrtl.base.redirect_output_for_rust_test = true; + args.verilog.firrtl.base.output = Some(get_assert_formal_target_path(&test_name)); + args.verilog.firrtl.export_options = export_options; + args.verilog.debug = true; + args.mode = mode; + args.depth = depth; + if let Some(solver) = solver { + args.solver = solver.into(); + } + args.run(module).expect("testing::assert_formal() failed"); } diff --git a/crates/fayalite/src/ty.rs b/crates/fayalite/src/ty.rs index 76c0955..d9ea6b2 100644 --- a/crates/fayalite/src/ty.rs +++ b/crates/fayalite/src/ty.rs @@ -11,7 +11,7 @@ use crate::{ intern::{Intern, Interned}, phantom_const::PhantomConst, reset::{AsyncReset, Reset, SyncReset}, - sim::value::{DynSimOnly, DynSimOnlyValue, SimValue, ToSimValueWithType}, + sim::value::{DynSimOnlyValue, DynSimOnly, SimValue, ToSimValueWithType}, source_location::SourceLocation, util::{ConstUsize, slice_range, try_slice_range}, }; diff --git a/crates/fayalite/src/ty/serde_impls.rs b/crates/fayalite/src/ty/serde_impls.rs index af324f9..1ca916b 100644 --- a/crates/fayalite/src/ty/serde_impls.rs +++ b/crates/fayalite/src/ty/serde_impls.rs @@ -127,7 +127,7 @@ impl From for CanonicalType { SerdeCanonicalType::Reset => Self::Reset(Reset), SerdeCanonicalType::Clock => Self::Clock(Clock), SerdeCanonicalType::PhantomConst(value) => { - Self::PhantomConst(PhantomConst::new_interned(value.0)) + Self::PhantomConst(PhantomConst::new(value.0)) } SerdeCanonicalType::DynSimOnly(value) => Self::DynSimOnly(value), } diff --git a/crates/fayalite/src/util.rs b/crates/fayalite/src/util.rs index 9796488..e85bc9c 100644 --- a/crates/fayalite/src/util.rs +++ b/crates/fayalite/src/util.rs @@ -33,15 +33,12 @@ pub use const_cmp::{ #[doc(inline)] pub use scoped_ref::ScopedRef; +pub(crate) use misc::chain; #[doc(inline)] pub use misc::{ - BitSliceWriteWithBase, DebugAsDisplay, DebugAsRawString, MakeMutSlice, RcWriter, - SerdeJsonEscapeIf, SerdeJsonEscapeIfFormatter, SerdeJsonEscapeIfTest, - SerdeJsonEscapeIfTestResult, interned_bit, iter_eq_by, os_str_strip_prefix, - os_str_strip_suffix, serialize_to_json_ascii, serialize_to_json_ascii_pretty, - serialize_to_json_ascii_pretty_with_indent, slice_range, try_slice_range, + BitSliceWriteWithBase, DebugAsDisplay, DebugAsRawString, MakeMutSlice, RcWriter, interned_bit, + iter_eq_by, slice_range, try_slice_range, }; -pub(crate) use misc::{InternedStrCompareAsStr, chain}; pub mod job_server; pub mod prefix_sum; diff --git a/crates/fayalite/src/util/job_server.rs b/crates/fayalite/src/util/job_server.rs index e58bba8..376ddc0 100644 --- a/crates/fayalite/src/util/job_server.rs +++ b/crates/fayalite/src/util/job_server.rs @@ -1,156 +1,192 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information -use ctor::{ctor, dtor}; -use jobslot::Client; +use ctor::ctor; +use jobslot::{Acquired, Client}; use std::{ ffi::OsString, - io, mem, + mem, num::NonZeroUsize, - sync::{Mutex, MutexGuard}, + sync::{Condvar, Mutex, Once, OnceLock}, + thread::spawn, }; -#[ctor] -static CLIENT: Mutex>> = unsafe { Mutex::new(Some(Client::from_env())) }; - -#[dtor] -fn drop_client() { - drop( - match CLIENT.lock() { - Ok(v) => v, - Err(e) => e.into_inner(), +fn get_or_make_client() -> &'static Client { + #[ctor] + static CLIENT: OnceLock = unsafe { + match Client::from_env() { + Some(client) => OnceLock::from(client), + None => OnceLock::new(), } - .take(), - ); -} + }; -fn get_or_make_client() -> Client { - CLIENT - .lock() - .expect("shouldn't have panicked") - .as_mut() - .expect("shutting down") - .get_or_insert_with(|| { - let mut available_parallelism = None; - let mut args = std::env::args_os().skip(1); - while let Some(arg) = args.next() { - const TEST_THREADS_OPTION: &'static [u8] = b"--test-threads"; - if arg.as_encoded_bytes().starts_with(TEST_THREADS_OPTION) { - match arg.as_encoded_bytes().get(TEST_THREADS_OPTION.len()) { - Some(b'=') => { - let mut arg = arg.into_encoded_bytes(); - arg.drain(..=TEST_THREADS_OPTION.len()); - available_parallelism = Some(arg); - break; - } - None => { - available_parallelism = args.next().map(OsString::into_encoded_bytes); - break; - } - _ => {} + CLIENT.get_or_init(|| { + let mut available_parallelism = None; + let mut args = std::env::args_os().skip(1); + while let Some(arg) = args.next() { + const TEST_THREADS_OPTION: &'static [u8] = b"--test-threads"; + if arg.as_encoded_bytes().starts_with(TEST_THREADS_OPTION) { + match arg.as_encoded_bytes().get(TEST_THREADS_OPTION.len()) { + Some(b'=') => { + let mut arg = arg.into_encoded_bytes(); + arg.drain(..=TEST_THREADS_OPTION.len()); + available_parallelism = Some(arg); + break; } + None => { + available_parallelism = args.next().map(OsString::into_encoded_bytes); + break; + } + _ => {} } } - let available_parallelism = if let Some(available_parallelism) = available_parallelism - .as_deref() - .and_then(|v| std::str::from_utf8(v).ok()) - .and_then(|v| v.parse().ok()) - { - available_parallelism - } else if let Ok(available_parallelism) = std::thread::available_parallelism() { - available_parallelism - } else { - NonZeroUsize::new(1).unwrap() - }; - Client::new_with_fifo(available_parallelism.get() - 1) - .expect("failed to create job server") - }) - .clone() + } + let available_parallelism = if let Some(available_parallelism) = available_parallelism + .as_deref() + .and_then(|v| std::str::from_utf8(v).ok()) + .and_then(|v| v.parse().ok()) + { + available_parallelism + } else if let Ok(available_parallelism) = std::thread::available_parallelism() { + available_parallelism + } else { + NonZeroUsize::new(1).unwrap() + }; + Client::new_with_fifo(available_parallelism.get() - 1).expect("failed to create job server") + }) } struct State { - obtained_count: usize, waiting_count: usize, + available: Vec, + implicit_available: bool, +} + +impl State { + fn total_available(&self) -> usize { + self.available.len() + self.implicit_available as usize + } + fn additional_waiting(&self) -> usize { + self.waiting_count.saturating_sub(self.total_available()) + } } static STATE: Mutex = Mutex::new(State { - obtained_count: 0, waiting_count: 0, + available: Vec::new(), + implicit_available: true, }); +static COND_VAR: Condvar = Condvar::new(); + +#[derive(Debug)] +enum AcquiredJobInner { + FromJobServer(Acquired), + ImplicitJob, +} #[derive(Debug)] pub struct AcquiredJob { - client: Client, + job: AcquiredJobInner, } impl AcquiredJob { - pub fn acquire() -> io::Result { - let client = get_or_make_client(); - struct Waiting {} - - impl Waiting { - fn done(self) -> MutexGuard<'static, State> { - mem::forget(self); + fn start_acquire_thread() { + static STARTED_THREAD: Once = Once::new(); + STARTED_THREAD.call_once(|| { + spawn(|| { + let mut acquired = None; + let client = get_or_make_client(); let mut state = STATE.lock().unwrap(); - state.waiting_count -= 1; - state - } - } - impl Drop for Waiting { - fn drop(&mut self) { - STATE.lock().unwrap().waiting_count -= 1; - } - } + loop { + state = if state.additional_waiting() == 0 { + if acquired.is_some() { + drop(state); + drop(acquired.take()); // drop Acquired outside of lock + STATE.lock().unwrap() + } else { + COND_VAR.wait(state).unwrap() + } + } else if acquired.is_some() { + // allocate space before moving Acquired to ensure we + // drop Acquired outside of the lock on panic + state.available.reserve(1); + state.available.push(acquired.take().unwrap()); + COND_VAR.notify_all(); + state + } else { + drop(state); + acquired = Some( + client + .acquire() + .expect("can't acquire token from job server"), + ); + STATE.lock().unwrap() + }; + } + }); + }); + } + fn acquire_inner(block: bool) -> Option { + Self::start_acquire_thread(); let mut state = STATE.lock().unwrap(); - if state.obtained_count == 0 && state.waiting_count == 0 { - state.obtained_count = 1; // get implicit token - return Ok(Self { client }); + loop { + if let Some(acquired) = state.available.pop() { + return Some(Self { + job: AcquiredJobInner::FromJobServer(acquired), + }); + } + if state.implicit_available { + state.implicit_available = false; + return Some(Self { + job: AcquiredJobInner::ImplicitJob, + }); + } + if !block { + return None; + } + state.waiting_count += 1; + state = COND_VAR.wait(state).unwrap(); + state.waiting_count -= 1; } - state.waiting_count += 1; - drop(state); - let waiting = Waiting {}; - client.acquire_raw()?; - state = waiting.done(); - state.obtained_count = state - .obtained_count - .checked_add(1) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "obtained_count overflowed"))?; - drop(state); - Ok(Self { client }) + } + pub fn try_acquire() -> Option { + Self::acquire_inner(false) + } + pub fn acquire() -> Self { + Self::acquire_inner(true).expect("failed to acquire token") } pub fn run_command( &mut self, cmd: std::process::Command, f: impl FnOnce(&mut std::process::Command) -> std::io::Result, ) -> std::io::Result { - self.client.configure_make_and_run_with_fifo(cmd, f) + get_or_make_client().configure_make_and_run_with_fifo(cmd, f) } } impl Drop for AcquiredJob { fn drop(&mut self) { let mut state = STATE.lock().unwrap(); - match &mut *state { - State { - obtained_count: 0, .. - } => unreachable!(), - State { - obtained_count: obtained_count @ 1, - waiting_count, - } => { - *obtained_count = 0; // drop implicit token - let any_waiting = *waiting_count != 0; - drop(state); - if any_waiting { - // we have the implicit token, but some other thread is trying to acquire a token, - // release the implicit token so they can acquire it. - let _ = self.client.release_raw(); // we're in drop, just ignore errors since we at least tried + match &self.job { + AcquiredJobInner::FromJobServer(_) => { + if state.waiting_count > state.available.len() + state.implicit_available as usize { + // allocate space before moving Acquired to ensure we + // drop Acquired outside of the lock on panic + state.available.reserve(1); + let AcquiredJobInner::FromJobServer(acquired) = + mem::replace(&mut self.job, AcquiredJobInner::ImplicitJob) + else { + unreachable!() + }; + state.available.push(acquired); + COND_VAR.notify_all(); } } - State { obtained_count, .. } => { - *obtained_count = obtained_count.saturating_sub(1); - drop(state); - let _ = self.client.release_raw(); // we're in drop, just ignore errors since we at least tried + AcquiredJobInner::ImplicitJob => { + state.implicit_available = true; + if state.waiting_count > state.available.len() { + COND_VAR.notify_all(); + } } } } diff --git a/crates/fayalite/src/util/misc.rs b/crates/fayalite/src/util/misc.rs index 165ab3a..cebbceb 100644 --- a/crates/fayalite/src/util/misc.rs +++ b/crates/fayalite/src/util/misc.rs @@ -4,9 +4,7 @@ use crate::intern::{Intern, Interned}; use bitvec::{bits, order::Lsb0, slice::BitSlice, view::BitView}; use std::{ cell::Cell, - ffi::OsStr, fmt::{self, Debug, Write}, - io, ops::{Bound, Range, RangeBounds}, rc::Rc, sync::{Arc, OnceLock}, @@ -245,370 +243,3 @@ pub fn try_slice_range>(range: R, size: usize) -> Option>(range: R, size: usize) -> Range { try_slice_range(range, size).expect("range out of bounds") } - -pub trait SerdeJsonEscapeIfTest { - fn char_needs_escape(&mut self, ch: char) -> serde_json::Result; -} - -pub trait SerdeJsonEscapeIfTestResult { - fn to_result(self) -> serde_json::Result; -} - -impl SerdeJsonEscapeIfTestResult for bool { - fn to_result(self) -> serde_json::Result { - Ok(self) - } -} - -impl> SerdeJsonEscapeIfTestResult for Result { - fn to_result(self) -> serde_json::Result { - self.map_err(Into::into) - } -} - -impl R, R: SerdeJsonEscapeIfTestResult> SerdeJsonEscapeIfTest for T { - fn char_needs_escape(&mut self, ch: char) -> serde_json::Result { - self(ch).to_result() - } -} - -pub trait SerdeJsonEscapeIfFormatter: serde_json::ser::Formatter { - fn write_unicode_escape(&mut self, writer: &mut W, ch: char) -> io::Result<()> - where - W: ?Sized + io::Write, - { - for utf16 in ch.encode_utf16(&mut [0; 2]) { - write!(writer, "\\u{utf16:04x}")?; - } - Ok(()) - } -} - -impl SerdeJsonEscapeIfFormatter for serde_json::ser::CompactFormatter {} -impl SerdeJsonEscapeIfFormatter for serde_json::ser::PrettyFormatter<'_> {} - -pub struct SerdeJsonEscapeIf { - pub base: Base, - pub test: Test, -} - -impl serde_json::ser::Formatter - for SerdeJsonEscapeIf -{ - fn write_null(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_null(writer) - } - - fn write_bool(&mut self, writer: &mut W, value: bool) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_bool(writer, value) - } - - fn write_i8(&mut self, writer: &mut W, value: i8) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_i8(writer, value) - } - - fn write_i16(&mut self, writer: &mut W, value: i16) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_i16(writer, value) - } - - fn write_i32(&mut self, writer: &mut W, value: i32) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_i32(writer, value) - } - - fn write_i64(&mut self, writer: &mut W, value: i64) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_i64(writer, value) - } - - fn write_i128(&mut self, writer: &mut W, value: i128) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_i128(writer, value) - } - - fn write_u8(&mut self, writer: &mut W, value: u8) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_u8(writer, value) - } - - fn write_u16(&mut self, writer: &mut W, value: u16) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_u16(writer, value) - } - - fn write_u32(&mut self, writer: &mut W, value: u32) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_u32(writer, value) - } - - fn write_u64(&mut self, writer: &mut W, value: u64) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_u64(writer, value) - } - - fn write_u128(&mut self, writer: &mut W, value: u128) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_u128(writer, value) - } - - fn write_f32(&mut self, writer: &mut W, value: f32) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_f32(writer, value) - } - - fn write_f64(&mut self, writer: &mut W, value: f64) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_f64(writer, value) - } - - fn write_number_str(&mut self, writer: &mut W, value: &str) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_number_str(writer, value) - } - - fn begin_string(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.begin_string(writer) - } - - fn end_string(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.end_string(writer) - } - - fn write_string_fragment(&mut self, writer: &mut W, mut fragment: &str) -> io::Result<()> - where - W: ?Sized + io::Write, - { - while let Some((next_escape_index, next_escape_char)) = fragment - .char_indices() - .find_map(|(index, ch)| match self.test.char_needs_escape(ch) { - Ok(false) => None, - Ok(true) => Some(Ok((index, ch))), - Err(e) => Some(Err(e)), - }) - .transpose()? - { - let (no_escapes, rest) = fragment.split_at(next_escape_index); - fragment = &rest[next_escape_char.len_utf8()..]; - self.base.write_string_fragment(writer, no_escapes)?; - self.base.write_unicode_escape(writer, next_escape_char)?; - } - self.base.write_string_fragment(writer, fragment) - } - - fn write_char_escape( - &mut self, - writer: &mut W, - char_escape: serde_json::ser::CharEscape, - ) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_char_escape(writer, char_escape) - } - - fn write_byte_array(&mut self, writer: &mut W, value: &[u8]) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_byte_array(writer, value) - } - - fn begin_array(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.begin_array(writer) - } - - fn end_array(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.end_array(writer) - } - - fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.begin_array_value(writer, first) - } - - fn end_array_value(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.end_array_value(writer) - } - - fn begin_object(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.begin_object(writer) - } - - fn end_object(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.end_object(writer) - } - - fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.begin_object_key(writer, first) - } - - fn end_object_key(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.end_object_key(writer) - } - - fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.begin_object_value(writer) - } - - fn end_object_value(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.end_object_value(writer) - } - - fn write_raw_fragment(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.base.write_raw_fragment(writer, fragment) - } -} - -fn serialize_to_json_ascii_helper( - v: &S, - base: F, -) -> serde_json::Result { - let mut retval = Vec::new(); - v.serialize(&mut serde_json::ser::Serializer::with_formatter( - &mut retval, - SerdeJsonEscapeIf { - base, - test: |ch| ch < '\x20' || ch > '\x7F', - }, - ))?; - String::from_utf8(retval).map_err(|_| serde::ser::Error::custom("invalid UTF-8")) -} - -pub fn serialize_to_json_ascii(v: &T) -> serde_json::Result { - serialize_to_json_ascii_helper(v, serde_json::ser::CompactFormatter) -} - -pub fn serialize_to_json_ascii_pretty( - v: &T, -) -> serde_json::Result { - serialize_to_json_ascii_helper(v, serde_json::ser::PrettyFormatter::new()) -} - -pub fn serialize_to_json_ascii_pretty_with_indent( - v: &T, - indent: &str, -) -> serde_json::Result { - serialize_to_json_ascii_helper( - v, - serde_json::ser::PrettyFormatter::with_indent(indent.as_bytes()), - ) -} - -pub fn os_str_strip_prefix<'a>(os_str: &'a OsStr, prefix: impl AsRef) -> Option<&'a OsStr> { - os_str - .as_encoded_bytes() - .strip_prefix(prefix.as_ref().as_bytes()) - .map(|bytes| { - // Safety: we removed a UTF-8 prefix so bytes starts with a valid boundary - unsafe { OsStr::from_encoded_bytes_unchecked(bytes) } - }) -} - -pub fn os_str_strip_suffix<'a>(os_str: &'a OsStr, suffix: impl AsRef) -> Option<&'a OsStr> { - os_str - .as_encoded_bytes() - .strip_suffix(suffix.as_ref().as_bytes()) - .map(|bytes| { - // Safety: we removed a UTF-8 suffix so bytes ends with a valid boundary - unsafe { OsStr::from_encoded_bytes_unchecked(bytes) } - }) -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub(crate) struct InternedStrCompareAsStr(pub(crate) Interned); - -impl fmt::Debug for InternedStrCompareAsStr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl Ord for InternedStrCompareAsStr { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - str::cmp(&self.0, &other.0) - } -} - -impl PartialOrd for InternedStrCompareAsStr { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl std::borrow::Borrow for InternedStrCompareAsStr { - fn borrow(&self) -> &str { - &self.0 - } -} diff --git a/crates/fayalite/src/util/ready_valid.rs b/crates/fayalite/src/util/ready_valid.rs index a15b837..ac08a64 100644 --- a/crates/fayalite/src/util/ready_valid.rs +++ b/crates/fayalite/src/util/ready_valid.rs @@ -25,7 +25,7 @@ impl ReadyValid { #[hdl] pub fn firing_data(expr: impl ToExpr) -> Expr> { let expr = expr.to_expr(); - let option_ty = expr.ty().data; + let option_ty = Expr::ty(expr).data; #[hdl] let firing_data = wire(option_ty); connect(firing_data, option_ty.HdlNone()); @@ -42,7 +42,7 @@ impl ReadyValid { ) -> Expr> { let data = HdlOption::map(expr.data, f); #[hdl] - let mapped = wire(ReadyValid[data.ty().HdlSome]); + let mapped = wire(ReadyValid[Expr::ty(data).HdlSome]); connect(mapped.data, data); connect(expr.ready, mapped.ready); mapped @@ -81,7 +81,7 @@ pub fn queue( let count: UInt = m.output(count_ty); #[hdl] - let inp_index_reg: UInt = reg_builder().clock_domain(cd).reset(0.cast_to(index_ty)); + let inp_index_reg = reg_builder().clock_domain(cd).reset(0.cast_to(index_ty)); #[hdl] let out_index_reg = reg_builder().clock_domain(cd).reset(0.cast_to(index_ty)); #[hdl] @@ -212,7 +212,9 @@ pub fn queue( mod tests { use super::*; use crate::{ - firrtl::ExportOptions, module::transform::simplify_enums::SimplifyEnumsKind, ty::StaticType, + cli::FormalMode, firrtl::ExportOptions, + module::transform::simplify_enums::SimplifyEnumsKind, testing::assert_formal, + ty::StaticType, }; use std::num::NonZero; diff --git a/crates/fayalite/src/vendor.rs b/crates/fayalite/src/vendor.rs deleted file mode 100644 index cdf302d..0000000 --- a/crates/fayalite/src/vendor.rs +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -pub mod xilinx; - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - xilinx::built_in_job_kinds() -} - -pub(crate) fn built_in_platforms() -> impl IntoIterator { - xilinx::built_in_platforms() -} diff --git a/crates/fayalite/src/vendor/xilinx.rs b/crates/fayalite/src/vendor/xilinx.rs deleted file mode 100644 index d80f388..0000000 --- a/crates/fayalite/src/vendor/xilinx.rs +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - annotations::make_annotation_enum, - build::{GlobalParams, ToArgs, WriteArgs}, - intern::Interned, - prelude::{DynPlatform, Platform}, -}; -use clap::ValueEnum; -use ordered_float::NotNan; -use serde::{Deserialize, Serialize}; -use std::fmt; - -pub mod arty_a7; -pub mod primitives; -pub mod yosys_nextpnr_prjxray; - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct XdcIOStandardAnnotation { - pub value: Interned, -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct XdcLocationAnnotation { - pub location: Interned, -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct XdcCreateClockAnnotation { - /// clock period in nanoseconds - pub period: NotNan, -} - -make_annotation_enum! { - #[non_exhaustive] - pub enum XilinxAnnotation { - XdcIOStandard(XdcIOStandardAnnotation), - XdcLocation(XdcLocationAnnotation), - XdcCreateClock(XdcCreateClockAnnotation), - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -pub struct XilinxArgs { - #[arg(long)] - pub device: Option, -} - -impl XilinxArgs { - pub fn require_device( - &self, - platform: Option<&DynPlatform>, - global_params: &GlobalParams, - ) -> clap::error::Result { - if let Some(device) = self.device { - return Ok(device); - } - if let Some(device) = - platform.and_then(|platform| platform.aspects().get_single_by_type::().copied()) - { - return Ok(device); - } - Err(global_params.clap_error( - clap::error::ErrorKind::MissingRequiredArgument, - "missing --device option", - )) - } -} - -impl ToArgs for XilinxArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - if let Some(device) = self.device { - args.write_long_option_eq("device", device.as_str()); - } - } -} - -macro_rules! make_device_enum { - ($vis:vis enum $Device:ident { - $( - #[ - name = $name:literal, - xray_part = $xray_part:literal, - xray_device = $xray_device:literal, - xray_family = $xray_family:literal, - ] - $variant:ident, - )* - }) => { - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, ValueEnum)] - $vis enum $Device { - $( - #[value(name = $name, alias = $xray_part)] - $variant, - )* - } - - impl $Device { - $vis fn as_str(self) -> &'static str { - match self { - $(Self::$variant => $name,)* - } - } - $vis fn xray_part(self) -> &'static str { - match self { - $(Self::$variant => $xray_part,)* - } - } - $vis fn xray_device(self) -> &'static str { - match self { - $(Self::$variant => $xray_device,)* - } - } - $vis fn xray_family(self) -> &'static str { - match self { - $(Self::$variant => $xray_family,)* - } - } - } - - struct DeviceVisitor; - - impl<'de> serde::de::Visitor<'de> for DeviceVisitor { - type Value = $Device; - - fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("a Xilinx device string") - } - - fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, - { - match $Device::from_str(v, false) { - Ok(v) => Ok(v), - Err(_) => Err(E::invalid_value(serde::de::Unexpected::Str(v), &self)), - } - } - - fn visit_bytes(self, v: &[u8]) -> Result - where - E: serde::de::Error, - { - match str::from_utf8(v).ok().and_then(|v| $Device::from_str(v, false).ok()) { - Some(v) => Ok(v), - None => Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self)), - } - } - } - - impl<'de> Deserialize<'de> for $Device { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_string(DeviceVisitor) - } - } - - impl Serialize for $Device { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.as_str().serialize(serializer) - } - } - }; -} - -make_device_enum! { - pub enum Device { - #[ - name = "xc7a35ticsg324-1L", - xray_part = "xc7a35tcsg324-1", - xray_device = "xc7a35t", - xray_family = "artix7", - ] - Xc7a35ticsg324_1l, - #[ - name = "xc7a100ticsg324-1L", - xray_part = "xc7a100tcsg324-1", - xray_device = "xc7a100t", - xray_family = "artix7", - ] - Xc7a100ticsg324_1l, - } -} - -impl fmt::Display for Device { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } -} - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - arty_a7::built_in_job_kinds() - .into_iter() - .chain(yosys_nextpnr_prjxray::built_in_job_kinds()) -} - -pub(crate) fn built_in_platforms() -> impl IntoIterator { - arty_a7::built_in_platforms() - .into_iter() - .chain(yosys_nextpnr_prjxray::built_in_platforms()) -} diff --git a/crates/fayalite/src/vendor/xilinx/arty_a7.rs b/crates/fayalite/src/vendor/xilinx/arty_a7.rs deleted file mode 100644 index 552eb4a..0000000 --- a/crates/fayalite/src/vendor/xilinx/arty_a7.rs +++ /dev/null @@ -1,404 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - intern::{Intern, Interned}, - module::{instance_with_loc, reg_builder_with_loc, wire_with_loc}, - platform::{ - DynPlatform, Peripheral, PeripheralRef, Peripherals, PeripheralsBuilderFactory, - PeripheralsBuilderFinished, Platform, PlatformAspectSet, - peripherals::{ClockInput, Led, RgbLed, Uart}, - }, - prelude::*, - vendor::xilinx::{ - Device, XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation, - primitives, - }, -}; -use ordered_float::NotNan; -use std::sync::OnceLock; - -macro_rules! arty_a7_platform { - ( - $vis:vis enum $ArtyA7Platform:ident { - $(#[name = $name:literal, device = $device:ident] - $Variant:ident,)* - } - ) => { - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] - #[non_exhaustive] - $vis enum $ArtyA7Platform { - $($Variant,)* - } - - impl $ArtyA7Platform { - $vis const VARIANTS: &'static [Self] = &[$(Self::$Variant,)*]; - $vis fn device(self) -> Device { - match self { - $(Self::$Variant => Device::$device,)* - } - } - $vis const fn as_str(self) -> &'static str { - match self { - $(Self::$Variant => $name,)* - } - } - fn get_aspects(self) -> &'static PlatformAspectSet { - match self { - $(Self::$Variant => { - static ASPECTS_SET: OnceLock = OnceLock::new(); - ASPECTS_SET.get_or_init(|| self.make_aspects()) - })* - } - } - } - }; -} - -arty_a7_platform! { - pub enum ArtyA7Platform { - #[name = "arty-a7-35t", device = Xc7a35ticsg324_1l] - ArtyA7_35T, - #[name = "arty-a7-100t", device = Xc7a100ticsg324_1l] - ArtyA7_100T, - } -} - -#[derive(Debug)] -pub struct ArtyA7Peripherals { - clk100_div_pow2: [Peripheral; 4], - rst: Peripheral, - rst_sync: Peripheral, - ld0: Peripheral, - ld1: Peripheral, - ld2: Peripheral, - ld3: Peripheral, - ld4: Peripheral, - ld5: Peripheral, - ld6: Peripheral, - ld7: Peripheral, - uart: Peripheral, - // TODO: add rest of peripherals when we need them -} - -impl Peripherals for ArtyA7Peripherals { - fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { - let Self { - clk100_div_pow2, - rst, - rst_sync, - ld0, - ld1, - ld2, - ld3, - ld4, - ld5, - ld6, - ld7, - uart, - } = self; - clk100_div_pow2.append_peripherals(peripherals); - rst.append_peripherals(peripherals); - rst_sync.append_peripherals(peripherals); - ld0.append_peripherals(peripherals); - ld1.append_peripherals(peripherals); - ld2.append_peripherals(peripherals); - ld3.append_peripherals(peripherals); - ld4.append_peripherals(peripherals); - ld5.append_peripherals(peripherals); - ld6.append_peripherals(peripherals); - ld7.append_peripherals(peripherals); - uart.append_peripherals(peripherals); - } -} - -impl ArtyA7Platform { - fn make_aspects(self) -> PlatformAspectSet { - let mut retval = PlatformAspectSet::new(); - retval.insert_new(self.device()); - retval - } -} - -#[hdl_module(extern)] -fn reset_sync() { - #[hdl] - let clk: Clock = m.input(); - #[hdl] - let inp: Bool = m.input(); - #[hdl] - let out: SyncReset = m.output(); - m.annotate_module(BlackBoxInlineAnnotation { - path: "fayalite_arty_a7_reset_sync.v".intern(), - text: r#"module __fayalite_arty_a7_reset_sync(input clk, input inp, output out); - wire reset_0_out; - (* ASYNC_REG = "TRUE" *) - FDPE #( - .INIT(1'b1) - ) reset_0 ( - .Q(reset_0_out), - .C(clk), - .CE(1'b1), - .PRE(inp), - .D(1'b0) - ); - (* ASYNC_REG = "TRUE" *) - FDPE #( - .INIT(1'b1) - ) reset_1 ( - .Q(out), - .C(clk), - .CE(1'b1), - .PRE(inp), - .D(reset_0_out) - ); -endmodule -"# - .intern(), - }); - m.verilog_name("__fayalite_arty_a7_reset_sync"); -} - -impl Platform for ArtyA7Platform { - type Peripherals = ArtyA7Peripherals; - - fn name(&self) -> Interned { - self.as_str().intern() - } - - fn new_peripherals<'builder>( - &self, - builder_factory: PeripheralsBuilderFactory<'builder>, - ) -> (Self::Peripherals, PeripheralsBuilderFinished<'builder>) { - let mut builder = builder_factory.builder(); - - let clk100_div_pow2 = std::array::from_fn(|log2_divisor| { - let divisor = 1u64 << log2_divisor; - let name = if divisor != 1 { - format!("clk100_div_{divisor}") - } else { - "clk100".into() - }; - builder.input_peripheral(name, ClockInput::new(100e6 / divisor as f64)) - }); - builder.add_conflicts(Vec::from_iter(clk100_div_pow2.iter().map(|v| v.id()))); - ( - ArtyA7Peripherals { - clk100_div_pow2, - rst: builder.input_peripheral("rst", Reset), - rst_sync: builder.input_peripheral("rst_sync", SyncReset), - ld0: builder.output_peripheral("ld0", RgbLed), - ld1: builder.output_peripheral("ld1", RgbLed), - ld2: builder.output_peripheral("ld2", RgbLed), - ld3: builder.output_peripheral("ld3", RgbLed), - ld4: builder.output_peripheral("ld4", Led), - ld5: builder.output_peripheral("ld5", Led), - ld6: builder.output_peripheral("ld6", Led), - ld7: builder.output_peripheral("ld7", Led), - uart: builder.output_peripheral("uart", Uart), - }, - builder.finish(), - ) - } - - fn source_location(&self) -> SourceLocation { - SourceLocation::builtin() - } - - fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals) { - let ArtyA7Peripherals { - clk100_div_pow2, - rst, - rst_sync, - ld0, - ld1, - ld2, - ld3, - ld4, - ld5, - ld6, - ld7, - uart, - } = peripherals; - let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| { - let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool); - annotate( - pin, - XdcLocationAnnotation { - location: location.intern(), - }, - ); - annotate( - pin, - XdcIOStandardAnnotation { - value: io_standard.intern(), - }, - ); - let buf = instance_with_loc( - &format!("{name}_buf"), - primitives::IBUF(), - SourceLocation::builtin(), - ); - connect(buf.I, pin); - if invert { !buf.O } else { buf.O } - }; - let make_buffered_output = |name: &str, location: &str, io_standard: &str| { - let pin = m.output_with_loc(name, SourceLocation::builtin(), Bool); - annotate( - pin, - XdcLocationAnnotation { - location: location.intern(), - }, - ); - annotate( - pin, - XdcIOStandardAnnotation { - value: io_standard.intern(), - }, - ); - let buf = instance_with_loc( - &format!("{name}_buf"), - primitives::OBUFT(), - SourceLocation::builtin(), - ); - connect(pin, buf.O); - connect(buf.T, false); - buf.I - }; - let mut frequency = clk100_div_pow2[0].ty().frequency(); - let mut log2_divisor = 0; - let mut clk = None; - for (cur_log2_divisor, p) in clk100_div_pow2.into_iter().enumerate() { - let Some(p) = p.into_used() else { - continue; - }; - debug_assert!( - clk.is_none(), - "conflict-handling logic should ensure at most one clock is used", - ); - frequency = p.ty().frequency(); - clk = Some(p); - log2_divisor = cur_log2_divisor; - } - let clk100_buf = make_buffered_input("clk100", "E3", "LVCMOS33", false); - let startup = instance_with_loc( - "startup", - primitives::STARTUPE2_default_inputs(), - SourceLocation::builtin(), - ); - let clk_global_buf = instance_with_loc( - "clk_global_buf", - primitives::BUFGCE(), - SourceLocation::builtin(), - ); - connect(clk_global_buf.CE, startup.EOS); - let mut clk_global_buf_in = clk100_buf.to_clock(); - for prev_log2_divisor in 0..log2_divisor { - let prev_divisor = 1u64 << prev_log2_divisor; - let clk_in = wire_with_loc( - &format!("clk_div_{prev_divisor}"), - SourceLocation::builtin(), - Clock, - ); - connect(clk_in, clk_global_buf_in); - annotate( - clk_in, - XdcCreateClockAnnotation { - period: NotNan::new(1e9 / (100e6 / prev_divisor as f64)) - .expect("known to be valid"), - }, - ); - annotate(clk_in, DontTouchAnnotation); - let cd = wire_with_loc( - &format!("clk_div_{prev_divisor}_in"), - SourceLocation::builtin(), - ClockDomain[AsyncReset], - ); - connect(cd.clk, clk_in); - connect(cd.rst, (!startup.EOS).to_async_reset()); - let divider = reg_builder_with_loc("divider", SourceLocation::builtin()) - .clock_domain(cd) - .reset(false) - .build(); - connect(divider, !divider); - clk_global_buf_in = divider.to_clock(); - } - connect(clk_global_buf.I, clk_global_buf_in); - let clk_out = wire_with_loc("clk_out", SourceLocation::builtin(), Clock); - connect(clk_out, clk_global_buf.O); - annotate( - clk_out, - XdcCreateClockAnnotation { - period: NotNan::new(1e9 / frequency).expect("known to be valid"), - }, - ); - annotate(clk_out, DontTouchAnnotation); - if let Some(clk) = clk { - connect(clk.instance_io_field().clk, clk_out); - } - let rst_value = { - let rst_buf = make_buffered_input("rst", "C2", "LVCMOS33", true); - let rst_sync = instance_with_loc("rst_sync", reset_sync(), SourceLocation::builtin()); - connect(rst_sync.clk, clk_out); - connect(rst_sync.inp, rst_buf | !startup.EOS); - rst_sync.out - }; - if let Some(rst) = rst.into_used() { - connect(rst.instance_io_field(), rst_value.to_reset()); - } - if let Some(rst_sync) = rst_sync.into_used() { - connect(rst_sync.instance_io_field(), rst_value); - } - let rgb_leds = [ - (ld0, ("G6", "F6", "E1")), - (ld1, ("G3", "J4", "G4")), - (ld2, ("J3", "J2", "H4")), - (ld3, ("K1", "H6", "K2")), - ]; - for (rgb_led, (r_loc, g_loc, b_loc)) in rgb_leds { - let r = make_buffered_output(&format!("{}_r", rgb_led.name()), r_loc, "LVCMOS33"); - let g = make_buffered_output(&format!("{}_g", rgb_led.name()), g_loc, "LVCMOS33"); - let b = make_buffered_output(&format!("{}_b", rgb_led.name()), b_loc, "LVCMOS33"); - if let Some(rgb_led) = rgb_led.into_used() { - connect(r, rgb_led.instance_io_field().r); - connect(g, rgb_led.instance_io_field().g); - connect(b, rgb_led.instance_io_field().b); - } else { - connect(r, false); - connect(g, false); - connect(b, false); - } - } - let leds = [(ld4, "H5"), (ld5, "J5"), (ld6, "T9"), (ld7, "T10")]; - for (led, loc) in leds { - let o = make_buffered_output(&led.name(), loc, "LVCMOS33"); - if let Some(led) = led.into_used() { - connect(o, led.instance_io_field().on); - } else { - connect(o, false); - } - } - let uart_tx = make_buffered_output("uart_tx", "D10", "LVCMOS33"); - let uart_rx = make_buffered_input("uart_rx", "A9", "LVCMOS33", false); - if let Some(uart) = uart.into_used() { - connect(uart_tx, uart.instance_io_field().tx); - connect(uart.instance_io_field().rx, uart_rx); - } else { - connect(uart_tx, true); // idle - } - } - - fn aspects(&self) -> PlatformAspectSet { - self.get_aspects().clone() - } -} - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - [] -} - -pub(crate) fn built_in_platforms() -> impl IntoIterator { - ArtyA7Platform::VARIANTS - .iter() - .map(|&v| DynPlatform::new(v)) -} diff --git a/crates/fayalite/src/vendor/xilinx/primitives.rs b/crates/fayalite/src/vendor/xilinx/primitives.rs deleted file mode 100644 index 9e22d26..0000000 --- a/crates/fayalite/src/vendor/xilinx/primitives.rs +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -#![allow(non_snake_case)] - -use crate::prelude::*; - -#[hdl_module(extern)] -pub fn IBUF() { - m.verilog_name("IBUF"); - #[hdl] - let O: Bool = m.output(); - #[hdl] - let I: Bool = m.input(); -} - -#[hdl_module(extern)] -pub fn OBUFT() { - m.verilog_name("OBUFT"); - #[hdl] - let O: Bool = m.output(); - #[hdl] - let I: Bool = m.input(); - #[hdl] - let T: Bool = m.input(); -} - -#[hdl_module(extern)] -pub fn BUFGCE() { - m.verilog_name("BUFGCE"); - #[hdl] - let O: Clock = m.output(); - #[hdl] - let CE: Bool = m.input(); - #[hdl] - let I: Clock = m.input(); -} - -#[hdl_module(extern)] -pub fn STARTUPE2_default_inputs() { - m.verilog_name("STARTUPE2"); - #[hdl] - let CFGCLK: Clock = m.output(); - #[hdl] - let CFGMCLK: Clock = m.output(); - #[hdl] - let EOS: Bool = m.output(); - #[hdl] - let PREQ: Bool = m.output(); -} diff --git a/crates/fayalite/src/vendor/xilinx/yosys_nextpnr_prjxray.rs b/crates/fayalite/src/vendor/xilinx/yosys_nextpnr_prjxray.rs deleted file mode 100644 index 3e1ac0c..0000000 --- a/crates/fayalite/src/vendor/xilinx/yosys_nextpnr_prjxray.rs +++ /dev/null @@ -1,1043 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// See Notices.txt for copyright information - -use crate::{ - annotations::{Annotation, TargetedAnnotation}, - build::{ - BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GlobalParams, - JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind, - JobKindAndDependencies, ToArgs, WriteArgs, - external::{ - ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait, - }, - verilog::{UnadjustedVerilog, VerilogDialect, VerilogJob, VerilogJobKind}, - }, - bundle::{Bundle, BundleType}, - expr::target::{Target, TargetBase}, - firrtl::{ScalarizedModuleABI, ScalarizedModuleABIAnnotations, ScalarizedModuleABIPort}, - intern::{Intern, InternSlice, Interned}, - module::{ - NameId, ScopedNameId, TargetName, - transform::visit::{Visit, Visitor}, - }, - prelude::*, - source_location::SourceLocation, - util::{HashSet, job_server::AcquiredJob}, - vendor::xilinx::{ - Device, XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation, - XilinxAnnotation, XilinxArgs, - }, -}; -use eyre::Context; -use serde::{Deserialize, Serialize}; -use std::{ - convert::Infallible, - ffi::{OsStr, OsString}, - fmt::{self, Write}, - ops::ControlFlow, - path::{Path, PathBuf}, -}; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] -pub struct YosysNextpnrXrayWriteYsFileJobKind; - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -pub struct YosysNextpnrXrayWriteYsFileArgs {} - -impl ToArgs for YosysNextpnrXrayWriteYsFileArgs { - fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { - let Self {} = self; - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] -pub struct YosysNextpnrXrayWriteYsFile { - main_verilog_file: Interned, - ys_file: Interned, - json_file: Interned, - json_file_name: Interned, -} - -impl YosysNextpnrXrayWriteYsFile { - pub fn main_verilog_file(&self) -> Interned { - self.main_verilog_file - } - pub fn ys_file(&self) -> Interned { - self.ys_file - } - pub fn json_file(&self) -> Interned { - self.json_file - } - pub fn json_file_name(&self) -> Interned { - self.json_file_name - } - fn write_ys( - &self, - output: &mut OsString, - additional_files: &[Interned], - main_module_name_id: NameId, - ) -> eyre::Result<()> { - let Self { - main_verilog_file, - ys_file: _, - json_file: _, - json_file_name, - } = self; - for verilog_file in VerilogJob::all_verilog_files(*main_verilog_file, additional_files)? { - output.push("read_verilog -sv \""); - output.push(verilog_file); - output.push("\"\n"); - } - let circuit_name = crate::firrtl::get_circuit_name(main_module_name_id); - writeln!( - output, - "synth_xilinx -flatten -abc9 -nobram -arch xc7 -top {circuit_name}" - ) - .expect("writing to OsString can't fail"); - output.push("write_json \""); - output.push(json_file_name); - output.push("\"\n"); - Ok(()) - } -} - -impl JobKind for YosysNextpnrXrayWriteYsFileJobKind { - type Args = YosysNextpnrXrayWriteYsFileArgs; - type Job = YosysNextpnrXrayWriteYsFile; - type Dependencies = JobKindAndDependencies; - - fn dependencies(self) -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - mut args: JobArgsAndDependencies, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - args.dependencies - .dependencies - .args - .args - .additional_args - .verilog_dialect - .get_or_insert(VerilogDialect::Yosys); - args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { - let YosysNextpnrXrayWriteYsFileArgs {} = args; - let base_job = dependencies.get_job::(); - let verilog_job = dependencies.get_job::(); - let json_file = base_job.file_with_ext("json"); - Ok(YosysNextpnrXrayWriteYsFile { - main_verilog_file: verilog_job.main_verilog_file(), - ys_file: base_job.file_with_ext("ys"), - json_file, - json_file_name: json_file - .interned_file_name() - .expect("known to have file name"), - }) - }) - } - - fn inputs(self, _job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::DynamicPaths { - source_job_name: VerilogJobKind.name(), - }] - .intern_slice() - } - - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { path: job.ys_file }].intern_slice() - } - - fn name(self) -> Interned { - "yosys-nextpnr-xray-write-ys-file".intern() - } - - fn external_command_params(self, _job: &Self::Job) -> Option { - None - } - - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - params: &JobParams, - _global_params: &GlobalParams, - _acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job))); - let [additional_files] = inputs else { - unreachable!(); - }; - let additional_files = VerilogJob::unwrap_additional_files(additional_files); - let mut contents = OsString::new(); - job.write_ys( - &mut contents, - additional_files, - params.main_module().name_id(), - )?; - let path = job.ys_file; - std::fs::write(path, contents.as_encoded_bytes()) - .wrap_err_with(|| format!("writing {path:?} failed"))?; - Ok(vec![JobItem::Path { path }]) - } - - fn subcommand_hidden(self) -> bool { - true - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -pub struct YosysNextpnrXraySynthArgs {} - -impl ToArgs for YosysNextpnrXraySynthArgs { - fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { - let Self {} = self; - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] -pub struct YosysNextpnrXraySynth { - #[serde(flatten)] - write_ys_file: YosysNextpnrXrayWriteYsFile, - ys_file_name: Interned, -} - -impl fmt::Debug for YosysNextpnrXraySynth { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { - write_ys_file: - YosysNextpnrXrayWriteYsFile { - main_verilog_file, - ys_file, - json_file, - json_file_name, - }, - ys_file_name, - } = self; - f.debug_struct("YosysNextpnrXraySynth") - .field("main_verilog_file", main_verilog_file) - .field("ys_file", ys_file) - .field("ys_file_name", ys_file_name) - .field("json_file", json_file) - .field("json_file_name", json_file_name) - .finish() - } -} - -impl YosysNextpnrXraySynth { - pub fn main_verilog_file(&self) -> Interned { - self.write_ys_file.main_verilog_file() - } - pub fn ys_file(&self) -> Interned { - self.write_ys_file.ys_file() - } - pub fn ys_file_name(&self) -> Interned { - self.ys_file_name - } - pub fn json_file(&self) -> Interned { - self.write_ys_file.json_file() - } - pub fn json_file_name(&self) -> Interned { - self.write_ys_file.json_file_name() - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] -pub struct Yosys; - -impl ExternalProgramTrait for Yosys { - fn default_program_name() -> Interned { - "yosys".intern() - } -} - -impl ExternalCommand for YosysNextpnrXraySynth { - type AdditionalArgs = YosysNextpnrXraySynthArgs; - type AdditionalJobData = Self; - type BaseJobPosition = GetJobPositionDependencies< - GetJobPositionDependencies< - GetJobPositionDependencies<::BaseJobPosition>, - >, - >; - type Dependencies = JobKindAndDependencies; - type ExternalProgram = Yosys; - - fn dependencies() -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - args: JobArgsAndDependencies>, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<( - Self::AdditionalJobData, - ::JobsAndKinds, - )> { - args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { - let YosysNextpnrXraySynthArgs {} = args.additional_args; - Ok(Self { - write_ys_file: dependencies.job.job.clone(), - ys_file_name: dependencies - .job - .job - .ys_file() - .interned_file_name() - .expect("known to have file name"), - }) - }) - } - - fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { - [ - JobItemName::Path { - path: job.additional_job_data().ys_file(), - }, - JobItemName::Path { - path: job.additional_job_data().main_verilog_file(), - }, - JobItemName::DynamicPaths { - source_job_name: VerilogJobKind.name(), - }, - ] - .intern_slice() - } - - fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]> { - [job.additional_job_data().json_file()].intern_slice() - } - - fn command_line_args(job: &ExternalCommandJob, args: &mut W) { - args.write_arg("-s"); - args.write_interned_arg(job.additional_job_data().ys_file_name()); - } - - fn current_dir(job: &ExternalCommandJob) -> Option> { - Some(job.output_dir()) - } - - fn job_kind_name() -> Interned { - "yosys-nextpnr-xray-synth".intern() - } - - fn subcommand_hidden() -> bool { - true - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] -pub struct YosysNextpnrXrayWriteXdcFileJobKind; - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -pub struct YosysNextpnrXrayWriteXdcFileArgs {} - -impl ToArgs for YosysNextpnrXrayWriteXdcFileArgs { - fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { - let Self {} = self; - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] -pub struct YosysNextpnrXrayWriteXdcFile { - firrtl_export_options: crate::firrtl::ExportOptions, - output_dir: Interned, - xdc_file: Interned, -} - -struct WriteXdcContentsError(eyre::Report); - -impl From for WriteXdcContentsError { - fn from(v: eyre::Report) -> Self { - Self(v) - } -} - -impl From for WriteXdcContentsError { - fn from(_v: fmt::Error) -> Self { - unreachable!("String write can't fail") - } -} - -fn tcl_escape(s: impl AsRef) -> String { - let s = s.as_ref(); - if !s.contains(|ch: char| !ch.is_alphanumeric() && ch != '_') { - return s.into(); - } - let mut retval = String::with_capacity(s.len().saturating_add(2)); - retval.push('"'); - for ch in s.chars() { - if let '$' | '\\' | '[' = ch { - retval.push('\\'); - } - retval.push(ch); - } - retval.push('"'); - retval -} - -#[derive(Copy, Clone, Debug)] -enum AnnotationTarget { - None, - Module(Module), - Mem(Mem), - Target(Interned), -} - -impl AnnotationTarget { - fn source_location(self) -> SourceLocation { - match self { - AnnotationTarget::None => unreachable!(), - AnnotationTarget::Module(module) => module.source_location(), - AnnotationTarget::Mem(mem) => mem.source_location(), - AnnotationTarget::Target(target) => target.base().source_location(), - } - } -} - -struct XdcFileWriter { - output: W, - module_depth: usize, - annotation_target: AnnotationTarget, - dont_touch_targets: HashSet>, - required_dont_touch_targets: HashSet>, -} - -impl XdcFileWriter { - fn run(output: W, top_module: Module) -> Result<(), WriteXdcContentsError> { - let mut this = Self { - output, - module_depth: 0, - annotation_target: AnnotationTarget::None, - dont_touch_targets: HashSet::default(), - required_dont_touch_targets: HashSet::default(), - }; - top_module.visit(&mut this)?; - let Self { - output: _, - module_depth: _, - annotation_target: _, - dont_touch_targets, - required_dont_touch_targets, - } = this; - for &target in required_dont_touch_targets.difference(&dont_touch_targets) { - return Err(eyre::eyre!( - "a DontTouchAnnotation is required since the target is also annotated with a XilinxAnnotation:\ntarget: {target:?}\nat: {}", - target.base().source_location(), - ).into()); - } - Ok(()) - } - fn default_visit_with>( - &mut self, - module_depth: usize, - annotation_target: AnnotationTarget, - v: &T, - ) -> Result<(), WriteXdcContentsError> { - let Self { - output: _, - module_depth: old_module_depth, - annotation_target: old_annotation_target, - dont_touch_targets: _, - required_dont_touch_targets: _, - } = *self; - self.module_depth = module_depth; - self.annotation_target = annotation_target; - let retval = v.default_visit(self); - self.module_depth = old_module_depth; - self.annotation_target = old_annotation_target; - retval - } -} - -impl Visitor for XdcFileWriter { - type Error = WriteXdcContentsError; - - fn visit_targeted_annotation(&mut self, v: &TargetedAnnotation) -> Result<(), Self::Error> { - self.default_visit_with(self.module_depth, AnnotationTarget::Target(v.target()), v) - } - - fn visit_module(&mut self, v: &Module) -> Result<(), Self::Error> { - self.default_visit_with( - self.module_depth + 1, - AnnotationTarget::Module(v.canonical()), - v, - ) - } - - fn visit_mem( - &mut self, - v: &Mem, - ) -> Result<(), Self::Error> - where - Element: Visit, - { - self.default_visit_with( - self.module_depth + 1, - AnnotationTarget::Mem(v.canonical()), - v, - ) - } - - fn visit_dont_touch_annotation(&mut self, _v: &DontTouchAnnotation) -> Result<(), Self::Error> { - if let AnnotationTarget::Target(target) = self.annotation_target { - self.dont_touch_targets.insert(target); - } - Ok(()) - } - - fn visit_xilinx_annotation(&mut self, v: &XilinxAnnotation) -> Result<(), Self::Error> { - fn todo( - msg: &str, - annotation: &XilinxAnnotation, - source_location: SourceLocation, - ) -> Result { - Err(WriteXdcContentsError(eyre::eyre!( - "{msg}\nannotation: {annotation:?}\nat: {source_location}" - ))) - } - if self.module_depth != 1 { - match todo( - "annotations are not yet supported outside of the top module since the logic to figure out the correct name isn't implemented", - v, - self.annotation_target.source_location(), - )? {} - } - match self.annotation_target { - AnnotationTarget::None => unreachable!(), - AnnotationTarget::Module(module) => match v { - XilinxAnnotation::XdcIOStandard(_) - | XilinxAnnotation::XdcLocation(_) - | XilinxAnnotation::XdcCreateClock(_) => { - return Err(WriteXdcContentsError(eyre::eyre!( - "annotation not allowed on a module: {v:?}\nat: {}", - module.source_location(), - ))); - } - }, - AnnotationTarget::Mem(mem) => match todo( - "xilinx annotations are not yet supported on memories since the logic to figure out the correct name isn't implemented", - v, - mem.source_location(), - )? {}, - AnnotationTarget::Target(target) => { - let base = target.base(); - match *base { - TargetBase::ModuleIO(_) => { - // already handled by write_xdc_contents handling the main module's ScalarizedModuleABI - Ok(()) - } - TargetBase::MemPort(mem_port) => { - match todo( - "xilinx annotations are not yet supported on memory ports since the logic to figure out the correct name isn't implemented", - v, - mem_port.source_location(), - )? {} - } - TargetBase::Reg(_) - | TargetBase::RegSync(_) - | TargetBase::RegAsync(_) - | TargetBase::Wire(_) => { - match *target { - Target::Base(_) => {} - Target::Child(_) => match todo( - "xilinx annotations are not yet supported on parts of registers/wires since the logic to figure out the correct name isn't implemented", - v, - base.source_location(), - )? {}, - } - match base.canonical_ty() { - CanonicalType::UInt(_) - | CanonicalType::SInt(_) - | CanonicalType::Bool(_) - | CanonicalType::AsyncReset(_) - | CanonicalType::SyncReset(_) - | CanonicalType::Reset(_) - | CanonicalType::Clock(_) => {} - CanonicalType::Enum(_) - | CanonicalType::Array(_) - | CanonicalType::Bundle(_) - | CanonicalType::PhantomConst(_) - | CanonicalType::DynSimOnly(_) => match todo( - "xilinx annotations are not yet supported on types other than integers, Bool, resets, or Clock since the logic to figure out the correct name isn't implemented", - v, - base.source_location(), - )? {}, - } - self.required_dont_touch_targets.insert(target); - match v { - XilinxAnnotation::XdcIOStandard(_) - | XilinxAnnotation::XdcLocation(_) => { - return Err(WriteXdcContentsError(eyre::eyre!( - "annotation must be on a ModuleIO: {v:?}\nat: {}", - base.source_location(), - ))); - } - XilinxAnnotation::XdcCreateClock(XdcCreateClockAnnotation { - period, - }) => { - let TargetName(ScopedNameId(_, NameId(name, _)), _) = - base.target_name(); - writeln!( - self.output, - "create_clock -period {period} [get_nets {}]", - tcl_escape(name), - )?; - Ok(()) - } - } - } - TargetBase::Instance(instance) => match todo( - "xilinx annotations are not yet supported on instances' IO since the logic to figure out the correct name isn't implemented", - v, - instance.source_location(), - )? {}, - } - } - } - } -} - -impl YosysNextpnrXrayWriteXdcFile { - fn write_xdc_contents_for_port_and_annotations( - &self, - output: &mut impl fmt::Write, - port: &ScalarizedModuleABIPort, - annotations: ScalarizedModuleABIAnnotations<'_>, - ) -> Result<(), WriteXdcContentsError> { - for annotation in annotations { - match annotation.annotation() { - Annotation::DontTouch(_) - | Annotation::SVAttribute(_) - | Annotation::BlackBoxInline(_) - | Annotation::BlackBoxPath(_) - | Annotation::DocString(_) - | Annotation::CustomFirrtl(_) => {} - Annotation::Xilinx(XilinxAnnotation::XdcLocation(XdcLocationAnnotation { - location, - })) => writeln!( - output, - "set_property LOC {} [get_ports {}]", - tcl_escape(location), - tcl_escape(port.scalarized_name()), - )?, - Annotation::Xilinx(XilinxAnnotation::XdcIOStandard(XdcIOStandardAnnotation { - value, - })) => writeln!( - output, - "set_property IOSTANDARD {} [get_ports {}]", - tcl_escape(value), - tcl_escape(port.scalarized_name()), - )?, - Annotation::Xilinx(XilinxAnnotation::XdcCreateClock( - XdcCreateClockAnnotation { period }, - )) => writeln!( - output, - "create_clock -period {period} [get_ports {}]", - tcl_escape(port.scalarized_name()), - )?, - } - } - Ok(()) - } - fn write_xdc_contents( - &self, - output: &mut String, - top_module: &Module, - ) -> eyre::Result<()> { - let scalarized_module_abi = - ScalarizedModuleABI::new(top_module, self.firrtl_export_options) - .map_err(eyre::Report::from)?; - match scalarized_module_abi.for_each_port_and_annotations(|port, annotations| { - match self.write_xdc_contents_for_port_and_annotations(output, port, annotations) { - Ok(()) => ControlFlow::Continue(()), - Err(e) => ControlFlow::Break(e), - } - }) { - ControlFlow::Continue(()) => {} - ControlFlow::Break(e) => return Err(e.0), - } - XdcFileWriter::run(output, *top_module).map_err(|e| e.0) - } -} - -impl JobKind for YosysNextpnrXrayWriteXdcFileJobKind { - type Args = YosysNextpnrXrayWriteXdcFileArgs; - type Job = YosysNextpnrXrayWriteXdcFile; - type Dependencies = JobKindAndDependencies>; - - fn dependencies(self) -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - args: JobArgsAndDependencies, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result> { - let firrtl_export_options = args - .dependencies - .dependencies - .dependencies - .dependencies - .dependencies - .args - .args - .export_options; - args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { - let YosysNextpnrXrayWriteXdcFileArgs {} = args; - let base_job = dependencies.get_job::(); - Ok(YosysNextpnrXrayWriteXdcFile { - firrtl_export_options, - output_dir: base_job.output_dir(), - xdc_file: base_job.file_with_ext("xdc"), - }) - }) - } - - fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { - path: job.output_dir, - }] - .intern_slice() - } - - fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { - [JobItemName::Path { path: job.xdc_file }].intern_slice() - } - - fn name(self) -> Interned { - "yosys-nextpnr-xray-write-xdc-file".intern() - } - - fn external_command_params(self, _job: &Self::Job) -> Option { - None - } - - fn run( - self, - job: &Self::Job, - inputs: &[JobItem], - params: &JobParams, - _global_params: &GlobalParams, - _acquired_job: &mut AcquiredJob, - ) -> eyre::Result> { - assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job))); - let mut xdc = String::new(); - job.write_xdc_contents(&mut xdc, params.main_module())?; - std::fs::write(job.xdc_file, xdc)?; - Ok(vec![JobItem::Path { path: job.xdc_file }]) - } - - fn subcommand_hidden(self) -> bool { - true - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] -pub struct NextpnrXilinx; - -impl ExternalProgramTrait for NextpnrXilinx { - fn default_program_name() -> Interned { - "nextpnr-xilinx".intern() - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -pub struct YosysNextpnrXrayRunNextpnrArgs { - #[command(flatten)] - pub common: XilinxArgs, - #[arg(long, env = "CHIPDB_DIR", value_hint = clap::ValueHint::DirPath)] - pub nextpnr_xilinx_chipdb_dir: PathBuf, - #[arg(long, default_value_t = 0)] - pub nextpnr_xilinx_seed: i32, -} - -impl ToArgs for YosysNextpnrXrayRunNextpnrArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { - common, - nextpnr_xilinx_chipdb_dir, - nextpnr_xilinx_seed, - } = self; - common.to_args(args); - args.write_long_option_eq("nextpnr-xilinx-chipdb-dir", nextpnr_xilinx_chipdb_dir); - args.write_display_arg(format_args!("--nextpnr-xilinx-seed={nextpnr_xilinx_seed}")); - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] -pub struct YosysNextpnrXrayRunNextpnr { - nextpnr_xilinx_chipdb_dir: Interned, - device: Device, - nextpnr_xilinx_seed: i32, - xdc_file: Interned, - xdc_file_name: Interned, - json_file: Interned, - json_file_name: Interned, - routed_json_file: Interned, - routed_json_file_name: Interned, - fasm_file: Interned, - fasm_file_name: Interned, -} - -impl YosysNextpnrXrayRunNextpnr { - fn chipdb_file(&self) -> Interned { - let mut retval = self - .nextpnr_xilinx_chipdb_dir - .join(self.device.xray_device()); - retval.set_extension("bin"); - retval.intern_deref() - } -} - -impl ExternalCommand for YosysNextpnrXrayRunNextpnr { - type AdditionalArgs = YosysNextpnrXrayRunNextpnrArgs; - type AdditionalJobData = Self; - type BaseJobPosition = GetJobPositionDependencies< - GetJobPositionDependencies<::BaseJobPosition>, - >; - type Dependencies = JobKindAndDependencies; - type ExternalProgram = NextpnrXilinx; - - fn dependencies() -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - args: JobArgsAndDependencies>, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<( - Self::AdditionalJobData, - ::JobsAndKinds, - )> { - args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { - let YosysNextpnrXrayRunNextpnrArgs { - common, - nextpnr_xilinx_chipdb_dir, - nextpnr_xilinx_seed, - } = args.additional_args; - let base_job = dependencies.get_job::(); - let write_xdc_file = dependencies.get_job::(); - let synth = dependencies.get_job::, _>(); - let routed_json_file = base_job.file_with_ext("routed.json"); - let fasm_file = base_job.file_with_ext("fasm"); - Ok(Self { - nextpnr_xilinx_chipdb_dir: nextpnr_xilinx_chipdb_dir.intern_deref(), - device: common.require_device(base_job.platform(), global_params)?, - nextpnr_xilinx_seed, - xdc_file: write_xdc_file.xdc_file, - xdc_file_name: write_xdc_file - .xdc_file - .interned_file_name() - .expect("known to have file name"), - json_file: synth.additional_job_data().json_file(), - json_file_name: synth.additional_job_data().json_file_name(), - routed_json_file, - routed_json_file_name: routed_json_file - .interned_file_name() - .expect("known to have file name"), - fasm_file, - fasm_file_name: fasm_file - .interned_file_name() - .expect("known to have file name"), - }) - }) - } - - fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { - [ - JobItemName::Path { - path: job.additional_job_data().json_file, - }, - JobItemName::Path { - path: job.additional_job_data().xdc_file, - }, - ] - .intern_slice() - } - - fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]> { - [ - job.additional_job_data().routed_json_file, - job.additional_job_data().fasm_file, - ] - .intern_slice() - } - - fn command_line_args(job: &ExternalCommandJob, args: &mut W) { - let job_data @ YosysNextpnrXrayRunNextpnr { - nextpnr_xilinx_seed, - xdc_file_name, - json_file_name, - routed_json_file_name, - fasm_file_name, - .. - } = job.additional_job_data(); - args.write_long_option_eq("chipdb", job_data.chipdb_file()); - args.write_long_option_eq("xdc", xdc_file_name); - args.write_long_option_eq("json", json_file_name); - args.write_long_option_eq("write", routed_json_file_name); - args.write_long_option_eq("fasm", fasm_file_name); - args.write_display_arg(format_args!("--seed={nextpnr_xilinx_seed}")); - } - - fn current_dir(job: &ExternalCommandJob) -> Option> { - Some(job.output_dir()) - } - - fn job_kind_name() -> Interned { - "yosys-nextpnr-xray-run-nextpnr".intern() - } - - fn subcommand_hidden() -> bool { - true - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] -pub struct Xcfasm; - -impl ExternalProgramTrait for Xcfasm { - fn default_program_name() -> Interned { - "xcfasm".intern() - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] -pub struct YosysNextpnrXrayArgs { - #[arg(long, env = "DB_DIR", value_hint = clap::ValueHint::DirPath)] - pub prjxray_db_dir: PathBuf, -} - -impl ToArgs for YosysNextpnrXrayArgs { - fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { - let Self { prjxray_db_dir } = self; - args.write_long_option_eq("prjxray-db-dir", prjxray_db_dir); - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] -pub struct YosysNextpnrXray { - prjxray_db_dir: Interned, - device: Device, - fasm_file: Interned, - fasm_file_name: Interned, - frames_file: Interned, - frames_file_name: Interned, - bit_file: Interned, - bit_file_name: Interned, -} - -impl YosysNextpnrXray { - fn db_root(&self) -> Interned { - self.prjxray_db_dir - .join(self.device.xray_family()) - .intern_deref() - } - fn part_file(&self) -> Interned { - let mut retval = self.prjxray_db_dir.join(self.device.xray_family()); - retval.push(self.device.xray_part()); - retval.push("part.yaml"); - retval.intern_deref() - } -} - -impl ExternalCommand for YosysNextpnrXray { - type AdditionalArgs = YosysNextpnrXrayArgs; - type AdditionalJobData = Self; - type BaseJobPosition = GetJobPositionDependencies< - ::BaseJobPosition, - >; - type Dependencies = JobKindAndDependencies>; - type ExternalProgram = Xcfasm; - - fn dependencies() -> Self::Dependencies { - Default::default() - } - - fn args_to_jobs( - args: JobArgsAndDependencies>, - params: &JobParams, - global_params: &GlobalParams, - ) -> eyre::Result<( - Self::AdditionalJobData, - ::JobsAndKinds, - )> { - args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { - let YosysNextpnrXrayArgs { prjxray_db_dir } = args.additional_args; - let base_job = dependencies.get_job::(); - let frames_file = base_job.file_with_ext("frames"); - let bit_file = base_job.file_with_ext("bit"); - Ok(Self { - prjxray_db_dir: prjxray_db_dir.intern_deref(), - device: dependencies.job.job.additional_job_data().device, - fasm_file: dependencies.job.job.additional_job_data().fasm_file, - fasm_file_name: dependencies.job.job.additional_job_data().fasm_file_name, - frames_file, - frames_file_name: frames_file - .interned_file_name() - .expect("known to have file name"), - bit_file, - bit_file_name: bit_file - .interned_file_name() - .expect("known to have file name"), - }) - }) - } - - fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { - [JobItemName::Path { - path: job.additional_job_data().fasm_file, - }] - .intern_slice() - } - - fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]> { - [ - job.additional_job_data().frames_file, - job.additional_job_data().bit_file, - ] - .intern_slice() - } - - fn command_line_args(job: &ExternalCommandJob, args: &mut W) { - let job_data @ YosysNextpnrXray { - device, - fasm_file_name, - frames_file_name, - bit_file_name, - .. - } = job.additional_job_data(); - args.write_arg("--sparse"); - args.write_long_option_eq("db-root", job_data.db_root()); - args.write_long_option_eq("part", device.xray_part()); - args.write_long_option_eq("part_file", job_data.part_file()); - args.write_long_option_eq("fn_in", fasm_file_name); - args.write_long_option_eq("frm_out", frames_file_name); - args.write_long_option_eq("bit_out", bit_file_name); - } - - fn current_dir(job: &ExternalCommandJob) -> Option> { - Some(job.output_dir()) - } - - fn job_kind_name() -> Interned { - "yosys-nextpnr-xray".intern() - } -} - -pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - [ - DynJobKind::new(YosysNextpnrXrayWriteYsFileJobKind), - DynJobKind::new(ExternalCommandJobKind::::new()), - DynJobKind::new(YosysNextpnrXrayWriteXdcFileJobKind), - DynJobKind::new(ExternalCommandJobKind::::new()), - DynJobKind::new(ExternalCommandJobKind::::new()), - ] -} - -pub(crate) fn built_in_platforms() -> impl IntoIterator { - [] -} diff --git a/crates/fayalite/src/wire.rs b/crates/fayalite/src/wire.rs index a350d9a..51f8cf7 100644 --- a/crates/fayalite/src/wire.rs +++ b/crates/fayalite/src/wire.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information use crate::{ - expr::{Expr, Flow, ToExpr, ValueType, value_category::ValueCategoryExpr}, + expr::{Expr, Flow, ToExpr}, intern::Interned, module::{IncompleteDeclaration, NameId, ScopedNameId, StmtDeclaration, StmtWire}, source_location::SourceLocation, @@ -16,16 +16,7 @@ pub struct Wire { ty: T, } -impl ValueType for Wire { - type Type = T; - type ValueCategory = ValueCategoryExpr; - - fn ty(&self) -> Self::Type { - self.ty - } -} - -impl fmt::Debug for Wire { +impl fmt::Debug for Wire { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Wire({:?}: ", self.name)?; self.ty.fmt(f)?; @@ -58,6 +49,9 @@ impl Wire { ty: T::from_canonical(ty), } } + pub fn ty(&self) -> T { + self.ty + } pub fn new_unchecked( scoped_name: ScopedNameId, source_location: SourceLocation, diff --git a/crates/fayalite/tests/formal.rs b/crates/fayalite/tests/formal.rs index cb78d1d..65264dc 100644 --- a/crates/fayalite/tests/formal.rs +++ b/crates/fayalite/tests/formal.rs @@ -2,7 +2,19 @@ // See Notices.txt for copyright information //! Formal tests in Fayalite -use fayalite::prelude::*; +use fayalite::{ + cli::FormalMode, + clock::{Clock, ClockDomain}, + expr::{CastTo, HdlPartialEq}, + firrtl::ExportOptions, + formal::{any_const, any_seq, formal_reset, hdl_assert, hdl_assume}, + hdl, hdl_module, + int::{Bool, DynSize, Size, UInt, UIntType}, + module::{connect, connect_any, instance, memory, reg_builder, wire}, + reset::ToReset, + testing::assert_formal, + ty::StaticType, +}; /// Test hidden state /// @@ -107,7 +119,7 @@ mod hidden_state { FormalMode::Prove, 16, None, - Default::default(), + ExportOptions::default(), ); // here a couple of cycles is enough assert_formal( @@ -116,7 +128,7 @@ mod hidden_state { FormalMode::Prove, 2, None, - Default::default(), + ExportOptions::default(), ); } } @@ -230,7 +242,7 @@ mod memory { #[hdl] let wr: WritePort = wire(WritePort[n]); connect(wr.addr, any_seq(UInt[n])); - connect(wr.data, any_seq(UInt::<8>::new_static())); + connect(wr.data, any_seq(UInt::<8>::TYPE)); connect(wr.en, any_seq(Bool)); #[hdl] let dut = instance(example_sram(n)); @@ -277,7 +289,7 @@ mod memory { FormalMode::Prove, 2, None, - Default::default(), + ExportOptions::default(), ); } } diff --git a/crates/fayalite/tests/hdl_types.rs b/crates/fayalite/tests/hdl_types.rs index 5030282..8802fd4 100644 --- a/crates/fayalite/tests/hdl_types.rs +++ b/crates/fayalite/tests/hdl_types.rs @@ -4,6 +4,7 @@ use fayalite::{ bundle::BundleType, enum_::EnumType, int::{BoolOrIntType, IntType}, + phantom_const::PhantomConst, prelude::*, ty::StaticType, }; @@ -196,51 +197,3 @@ check_bounds!(CheckBoundsTTT2<#[a, Type] A: BundleType +, #[b, Type] B: Type +, check_bounds!(CheckBoundsTTT3<#[a, Type] A: EnumType +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTT4<#[a, Type] A: IntType +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTT5<#[a, Type] A: StaticType +, #[b, Type] B: Type +, #[c, Type] C: Type +>); - -#[derive(Clone, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)] -pub struct MyPhantomConstInner { - pub a: usize, - pub b: UInt, -} - -#[hdl(outline_generated, get(|v| v.a))] -pub type GetA> = DynSize; - -#[hdl(outline_generated, get(|v| v.b))] -pub type GetB> = UInt; - -#[hdl(outline_generated, no_static)] -pub struct MyTypeWithPhantomConstParameter> { - pub a: ArrayType>, - pub b: HdlOption>, -} - -#[hdl(outline_generated)] -struct MyPrivateType {} - -#[hdl(outline_generated)] -pub(crate) struct MyPubCrateType {} - -#[hdl(outline_generated)] -pub struct MyTypeWithPrivateMembers { - a: MyPrivateType, - pub(crate) b: MyPubCrateType, - pub c: Bool, -} - -#[hdl(outline_generated)] -struct MyPrivateTypeWithArg { - v: T, -} - -#[hdl(outline_generated)] -pub(crate) struct MyPubCrateTypeWithArg { - v: T, -} - -#[hdl(outline_generated)] -pub struct MyTypeWithPrivateMembersWithArg { - a: MyPrivateTypeWithArg, - pub(crate) b: MyPubCrateTypeWithArg, - pub c: T, -} diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index 2761cba..c2dc24e 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -6,7 +6,6 @@ use fayalite::{ int::{UIntInRange, UIntInRangeInclusive}, intern::Intern, module::transform::simplify_enums::SimplifyEnumsKind, - platform::PlatformIOBuilder, prelude::*, reset::ResetType, ty::StaticType, @@ -215,7 +214,7 @@ where let o: Array = m.output(); let bytes = v.to_string().as_bytes().to_expr(); #[hdl] - let o2: Array> = m.output(bytes.ty()); + let o2: Array> = m.output(Expr::ty(bytes)); connect( o, #[hdl] @@ -1176,7 +1175,7 @@ pub fn check_memory_init() { let waddr2: UInt<4> = m.input(); #[hdl] let wdata2: UInt<31> = m.input(); - let mem_init2 = Vec::from_iter((0..0x10u32).map(|i| (i * i * i).cast_to_static::>())); + let mem_init2 = Vec::from_iter((0..0x10u32).map(|i| (i * i * i).cast_to_static())); #[hdl] let mut mem2 = memory_with_init(mem_init2); let read_port2 = mem2.new_read_port(); @@ -1784,7 +1783,7 @@ pub fn check_memory_of_bundle_of_arrays() { [(i * i).wrapping_mul(2), (i * i).wrapping_mul(3)], [(i * i).wrapping_mul(i), i * 2], ], - i.cast_to_static::>(), + i.cast_to_static(), ) })); #[hdl] @@ -1954,9 +1953,9 @@ pub fn check_memory_of_array_of_bundle() { let clk: Clock = m.input(); let mem_init = Vec::from_iter((0..0x10u8).map(|i| { [ - (i, i.cast_to_static::>()), - ((i * i), (i / 2).cast_to_static::>()), - ((i * i).wrapping_mul(i), (i / 4).cast_to_static::>()), + (i, i.cast_to_static()), + ((i * i), (i / 2).cast_to_static()), + ((i * i).wrapping_mul(i), (i / 4).cast_to_static()), ] })); #[hdl] @@ -2269,8 +2268,7 @@ pub fn check_memory_of_bundle() { let wmask: (Bool, Bool) = m.input(); #[hdl] let clk: Clock = m.input(); - let mem_init = - Vec::from_iter((0..0x10u8).map(|i| (i ^ 3, (i ^ (i / 2)).cast_to_static::>()))); + let mem_init = Vec::from_iter((0..0x10u8).map(|i| (i ^ 3, (i ^ (i / 2)).cast_to_static()))); #[hdl] let mut mem = memory_with_init(mem_init); let read_port = mem.new_read_port(); @@ -4633,55 +4631,3 @@ circuit check_uint_in_range: ", }; } - -#[hdl_module(outline_generated)] -pub fn check_platform_io(platform_io_builder: PlatformIOBuilder<'_>) { - #[hdl] - let io = m.add_platform_io(platform_io_builder); -} - -#[cfg(todo)] -#[test] -fn test_platform_io() { - let _n = SourceLocation::normalize_files_for_tests(); - let m = check_platform_io(todo!()); - dbg!(m); - #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 - assert_export_firrtl! { - m => - "/test/check_platform_io.fir": r"FIRRTL version 3.2.0 -circuit check_platform_io: - 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_platform_io: @[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 cbe0b58..b9c6a80 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -3,7 +3,7 @@ use fayalite::{ memory::{ReadStruct, ReadWriteStruct, WriteStruct}, - module::{instance_with_loc, memory_with_init_and_loc, reg_builder_with_loc}, + module::{instance_with_loc, reg_builder_with_loc}, prelude::*, reset::ResetType, sim::vcd::VcdWriterDecls, @@ -86,7 +86,7 @@ pub fn mod1() { #[hdl] let child = instance(mod1_child()); #[hdl] - let o: mod1_child = m.output(child.ty()); + let o: mod1_child = m.output(Expr::ty(child)); connect(o, child); } @@ -506,10 +506,10 @@ fn test_enums() { 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); + } = 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::<_> { en, @@ -528,7 +528,7 @@ fn test_enums() { ); // make sure matching on SimValue works #[hdl(sim)] - match &io.b_out { + match io.b_out { HdlNone => println!("io.b_out is HdlNone"), HdlSome(v) => println!("io.b_out is HdlSome(({:?}, {:?}))", *v.0, *v.1), } @@ -706,13 +706,13 @@ 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); + } = 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 { r_addr, @@ -979,10 +979,10 @@ fn test_memories2() { }, ) in io_cycles.into_iter().enumerate() { - sim.write_bool_or_int(sim.io().rw.addr, addr.cast_to_static::>()); + sim.write_bool_or_int(sim.io().rw.addr, addr.cast_to_static()); sim.write_bool(sim.io().rw.en, en); sim.write_bool(sim.io().rw.wmode, wmode); - sim.write_bool_or_int(sim.io().rw.wdata, wdata.cast_to_static::>()); + sim.write_bool_or_int(sim.io().rw.wdata, wdata.cast_to_static()); sim.write_bool(sim.io().rw.wmask, wmask); sim.advance_time(SimDuration::from_nanos(250)); sim.write_clock(sim.io().rw.clk, true); @@ -1195,9 +1195,9 @@ fn test_memories3() { w_data: [0; 8], w_mask: [false; 8], }); - sim.write_bool_or_int(sim.io().r.addr, r_addr.cast_to_static::>()); + 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_or_int(sim.io().w.addr, w_addr.cast_to_static()); sim.write_bool(sim.io().w.en, w_en); for (i, v) in w_data.into_iter().enumerate() { sim.write_bool_or_int(sim.io().w.data[i], v); @@ -1261,310 +1261,6 @@ fn test_memories3() { } } -#[hdl_module(outline_generated)] -pub fn many_memories() { - #[hdl] - let r: Array>, 8> = m.input(); - #[hdl] - let w: Array>, 8> = m.input(); - for (mem_index, (r, w)) in r.into_iter().zip(w).enumerate() { - let mut mem = memory_with_init_and_loc( - &format!("mem_{mem_index}"), - (0..16) - .map(|bit_index| mem_index.pow(5).to_expr()[bit_index]) - .collect::>(), - SourceLocation::caller(), - ); - connect_any(mem.new_read_port(), r); - connect_any(mem.new_write_port(), w); - } -} - -#[hdl] -#[test] -fn test_many_memories() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(many_memories()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - for r in sim.io().r { - sim.write_clock(r.clk, false); - } - for w in sim.io().w { - sim.write_clock(w.clk, false); - } - #[hdl(cmp_eq)] - struct IO { - r_addr: UInt<4>, - r_en: Bool, - r_data: Array, - w_addr: UInt<4>, - w_en: Bool, - w_data: Array, - w_mask: Array, - } - let io_cycles = [ - #[hdl(sim)] - IO { - r_addr: 0_hdl_u4, - r_en: false, - r_data: [false; 8], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [false; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0_hdl_u4, - r_en: true, - r_data: [false, true, false, true, false, true, false, true], - w_addr: 0_hdl_u4, - w_en: true, - w_data: [true; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0_hdl_u4, - r_en: true, - r_data: [true; 8], - w_addr: 0_hdl_u4, - w_en: true, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0_hdl_u4, - r_en: true, - r_data: [false; 8], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 1_hdl_u4, - r_en: true, - r_data: [false, false, false, true, false, false, false, true], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 2_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, true, false, true], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 3_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, false, false, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 4_hdl_u4, - r_en: true, - r_data: [false, false, false, true, false, true, false, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 5_hdl_u4, - r_en: true, - r_data: [false, false, true, true, false, true, true, true], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 6_hdl_u4, - r_en: true, - r_data: [false, false, false, true, false, false, true, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 7_hdl_u4, - r_en: true, - r_data: [false, false, false, true, false, false, false, true], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 8_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, false, false, true], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 9_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, false, true, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0xA_hdl_u4, - r_en: true, - r_data: [false, false, false, false, true, true, true, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0xB_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, true, true, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0xC_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, false, true, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0xD_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, false, false, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0xE_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, false, false, true], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - #[hdl(sim)] - IO { - r_addr: 0xF_hdl_u4, - r_en: true, - r_data: [false, false, false, false, false, false, false, false], - w_addr: 0_hdl_u4, - w_en: false, - w_data: [false; 8], - w_mask: [true; 8], - }, - ]; - for (cycle, expected) in io_cycles.into_iter().enumerate() { - #[hdl(sim)] - let IO { - r_addr, - r_en, - r_data: _, - w_addr, - w_en, - w_data, - w_mask, - } = &expected; - for (((r, w), w_data), w_mask) in sim - .io() - .r - .into_iter() - .zip(sim.io().w) - .zip(w_data.iter()) - .zip(w_mask.iter()) - { - sim.write(r.addr, r_addr); - sim.write(r.en, r_en); - sim.write(w.addr, w_addr); - sim.write(w.en, w_en); - sim.write(w.data, w_data); - sim.write(w.mask, w_mask); - } - let io = #[hdl(sim)] - IO { - r_addr, - r_en, - r_data: std::array::from_fn(|i| sim.read(sim.io().r[i].data)), - w_addr, - w_en, - w_data, - w_mask, - }; - assert_eq!( - expected, - io, - "vcd:\n{}\ncycle: {cycle}", - String::from_utf8(writer.take()).unwrap(), - ); - sim.advance_time(SimDuration::from_micros(1)); - for r in sim.io().r { - sim.write_clock(r.clk, true); - } - for w in sim.io().w { - sim.write_clock(w.clk, true); - } - sim.advance_time(SimDuration::from_micros(1)); - for r in sim.io().r { - sim.write_clock(r.clk, false); - } - for w in sim.io().w { - sim.write_clock(w.clk, false); - } - } - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/many_memories.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/many_memories.txt") { - panic!(); - } -} - #[hdl_module(outline_generated)] pub fn duplicate_names() { #[hdl] @@ -2026,472 +1722,3 @@ fn test_sim_only_connects() { panic!(); } } - -#[hdl_module(outline_generated, extern)] -pub fn sim_fork_join() -where - ConstUsize: KnownSize, -{ - #[hdl] - let clocks: Array = m.input(); - #[hdl] - let outputs: Array, N> = m.output(); - m.extern_module_simulation_fn((clocks, outputs), |(clocks, outputs), mut sim| async move { - sim.write(outputs, [0u8; N]).await; - loop { - sim.fork_join( - clocks - .into_iter() - .zip(outputs) - .map(|(clock, output)| { - move |mut sim: ExternModuleSimulationState| async move { - sim.wait_for_clock_edge(clock).await; - let v = sim - .read_bool_or_int(output) - .await - .to_bigint() - .try_into() - .expect("known to be in range"); - sim.write(output, 1u8.wrapping_add(v)).await; - } - }) - .collect::>(), - ) - .await; - } - }); -} - -#[test] -fn test_sim_fork_join() { - let _n = SourceLocation::normalize_files_for_tests(); - const N: usize = 3; - let mut sim = Simulation::new(sim_fork_join::()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - sim.write(sim.io().clocks, [false; N]); - let mut clocks_triggered = [false; N]; - let mut expected = [0u8; N]; - for i0 in 0..N { - for i1 in 0..N { - for i2 in 0..N { - for i3 in 0..N { - let indexes = [i0, i1, i2, i3]; - for i in indexes { - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clocks[i], true); - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clocks[i], false); - if !clocks_triggered[i] { - expected[i] = expected[i].wrapping_add(1); - } - clocks_triggered[i] = true; - if clocks_triggered == [true; N] { - clocks_triggered = [false; N]; - } - let output = sim.read(sim.io().outputs); - assert_eq!(output, expected.to_sim_value(), "indexes={indexes:?} i={i}"); - } - } - } - } - } - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/sim_fork_join.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/sim_fork_join.txt") { - panic!(); - } -} - -#[hdl_module(outline_generated, extern)] -pub fn sim_fork_join_scope() -where - ConstUsize: KnownSize, -{ - #[hdl] - let clocks: Array = m.input(); - #[hdl] - let outputs: Array, N> = m.output(); - m.extern_module_simulation_fn((clocks, outputs), |(clocks, outputs), mut sim| async move { - sim.write(outputs, [0u8; N]).await; - loop { - let written = vec![std::cell::Cell::new(false); N]; // test shared scope - let written = &written; // work around move in async move - sim.fork_join_scope(|scope, _| async move { - let mut spawned = vec![]; - for i in 0..N { - let join_handle = - scope.spawn(move |_, mut sim: ExternModuleSimulationState| async move { - sim.wait_for_clock_edge(clocks[i]).await; - let v = sim - .read_bool_or_int(outputs[i]) - .await - .to_bigint() - .try_into() - .expect("known to be in range"); - sim.write(outputs[i], 1u8.wrapping_add(v)).await; - written[i].set(true); - i - }); - if i % 2 == 0 && i < N - 1 { - spawned.push((i, join_handle)); - } - } - for (i, join_handle) in spawned { - assert_eq!(i, join_handle.join().await); - } - }) - .await; - for written in written { - assert!(written.get()); - } - } - }); -} - -#[test] -fn test_sim_fork_join_scope() { - let _n = SourceLocation::normalize_files_for_tests(); - const N: usize = 3; - let mut sim = Simulation::new(sim_fork_join_scope::()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - sim.write(sim.io().clocks, [false; N]); - let mut clocks_triggered = [false; N]; - let mut expected = [0u8; N]; - for i0 in 0..N { - for i1 in 0..N { - for i2 in 0..N { - for i3 in 0..N { - let indexes = [i0, i1, i2, i3]; - for i in indexes { - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clocks[i], true); - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clocks[i], false); - if !clocks_triggered[i] { - expected[i] = expected[i].wrapping_add(1); - } - clocks_triggered[i] = true; - if clocks_triggered == [true; N] { - clocks_triggered = [false; N]; - } - let output = sim.read(sim.io().outputs); - assert_eq!(output, expected.to_sim_value(), "indexes={indexes:?} i={i}"); - } - } - } - } - } - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/sim_fork_join_scope.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/sim_fork_join_scope.txt") { - panic!(); - } -} - -#[hdl_module(outline_generated, extern)] -pub fn sim_resettable_counter() { - #[hdl] - let cd: ClockDomain = m.input(); - #[hdl] - let out: UInt<8> = m.output(); - m.extern_module_simulation_fn((cd, out), |(cd, out), mut sim| async move { - sim.resettable( - cd, - |mut sim: ExternModuleSimulationState| async move { - sim.write(out, 0u8).await; - }, - |mut sim: ExternModuleSimulationState, ()| async move { - loop { - sim.wait_for_clock_edge(cd.clk).await; - let v: u8 = sim - .read(out) - .await - .to_bigint() - .try_into() - .expect("known to be in range"); - sim.write(out, v.wrapping_add(1)).await; - } - }, - ) - .await - }); -} - -fn test_sim_resettable_counter_helper( - sim: &mut Simulation>, - immediate_reset: bool, -) { - sim.write_clock(sim.io().cd.clk, false); - sim.write_reset(sim.io().cd.rst, immediate_reset); - for _ in 0..2 { - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, true); - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, false); - sim.write_reset(sim.io().cd.rst, true); - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, true); - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, false); - sim.write_reset(sim.io().cd.rst, false); - for expected in 0..3u8 { - assert_eq!(sim.read(sim.io().out), expected.to_sim_value()); - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, true); - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, false); - } - } -} - -#[test] -fn test_sim_resettable_counter_sync() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(sim_resettable_counter::()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - test_sim_resettable_counter_helper(&mut sim, false); - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/sim_resettable_counter_sync.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/sim_resettable_counter_sync.txt") { - panic!(); - } -} - -#[test] -fn test_sim_resettable_counter_sync_immediate_reset() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(sim_resettable_counter::()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - test_sim_resettable_counter_helper(&mut sim, true); - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/sim_resettable_counter_sync_immediate_reset.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/sim_resettable_counter_sync_immediate_reset.txt") { - panic!(); - } -} - -#[test] -fn test_sim_resettable_counter_async() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(sim_resettable_counter::()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - test_sim_resettable_counter_helper(&mut sim, false); - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/sim_resettable_counter_async.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/sim_resettable_counter_async.txt") { - panic!(); - } -} - -#[test] -fn test_sim_resettable_counter_async_immediate_reset() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(sim_resettable_counter::()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - test_sim_resettable_counter_helper(&mut sim, true); - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/sim_resettable_counter_async_immediate_reset.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/sim_resettable_counter_async_immediate_reset.txt") { - panic!(); - } -} - -#[hdl_module(outline_generated)] -pub fn phantom_const() { - #[hdl] - let out: Array>, 2> = - m.output(Array::new_static(PhantomConst::new_sized(vec![ - "a".into(), - "b".into(), - ]))); - let _ = out; - #[hdl] - let mut mem = memory(PhantomConst::new("mem_element")); - mem.depth(1); - let port = mem.new_read_port(); - connect_any(port.addr, 0u8); - connect(port.clk, false.to_clock()); - connect(port.en, false); -} - -#[test] -fn test_phantom_const() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(phantom_const()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - 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/phantom_const.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/phantom_const.txt") { - panic!(); - } -} - -#[hdl_module(outline_generated, extern)] -pub fn sim_read_past() -where - ConstUsize: KnownSize, -{ - #[hdl] - let clocks: Array = m.input(); - #[hdl] - let outputs: Array, N> = m.output(); - #[hdl] - let past_clocks: Array = m.output(); - #[hdl] - let past_outputs: Array, N> = m.output(); - for clock in clocks { - m.register_clock_for_past(clock); - } - m.extern_module_simulation_fn( - (clocks, outputs, past_clocks, past_outputs), - |(clocks, outputs, past_clocks, past_outputs), mut sim| async move { - sim.write(outputs, [0u8; N]).await; - sim.write(past_clocks, [false; N]).await; - sim.write(past_outputs, [0u8; N]).await; - loop { - sim.fork_join_scope(|scope, _| async move { - for (clock, output) in clocks.into_iter().zip(outputs) { - scope.spawn_detached( - move |_, mut sim: ExternModuleSimulationState| async move { - sim.wait_for_clock_edge(clock).await; - dbg!(clock); - let v = sim - .read_bool_or_int(output) - .await - .to_bigint() - .try_into() - .expect("known to be in range"); - sim.write(output, 1u8.wrapping_add(v)).await; - let past_outputs_v = sim.read_past(outputs, clock).await; - dbg!(&past_outputs_v); - sim.write(past_outputs, past_outputs_v).await; - let past_clocks_v = sim.read_past(clocks, clock).await; - dbg!(&past_clocks_v); - sim.write(past_clocks, past_clocks_v).await; - }, - ); - } - }) - .await; - } - }, - ); -} - -#[test] -fn test_sim_read_past() { - let _n = SourceLocation::normalize_files_for_tests(); - const N: usize = 3; - let mut sim = Simulation::new(sim_read_past::()); - // sim.set_breakpoints_unstable(Default::default(), true); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - sim.write(sim.io().clocks, [false; N]); - let mut clocks_triggered = [false; N]; - let mut expected = [0u8; N]; - let mut past_clocks_expected = [false; N]; - let mut past_expected = expected; - for i0 in 0..N { - for i1 in 0..N { - for i2 in 0..N { - for i3 in 0..N { - let indexes = [i0, i1, i2, i3]; - for i in indexes { - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clocks[i], true); - sim.advance_time(SimDuration::from_micros(1)); - sim.write(sim.io().clocks[i], false); - if !clocks_triggered[i] { - past_expected = expected; - expected[i] = expected[i].wrapping_add(1); - past_clocks_expected = [false; N]; - past_clocks_expected[i] = true; - } - dbg!(past_expected); - clocks_triggered[i] = true; - if clocks_triggered == [true; N] { - clocks_triggered = [false; N]; - } - let output = sim.read(sim.io().outputs); - assert_eq!(output, expected.to_sim_value(), "indexes={indexes:?} i={i}"); - let past_clocks = sim.read(sim.io().past_clocks); - assert_eq!( - past_clocks, - past_clocks_expected - .to_sim_value_with_type(Array::::default()), - "indexes={indexes:?} i={i}" - ); - let past_outputs = sim.read(sim.io().past_outputs); - dbg!(&past_outputs); - assert_eq!( - past_outputs, - past_expected.to_sim_value(), - "indexes={indexes:?} i={i}" - ); - } - } - } - } - } - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/sim_read_past.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/sim_read_past.txt") { - panic!(); - } -} diff --git a/crates/fayalite/tests/sim/expected/array_rw.txt b/crates/fayalite/tests/sim/expected/array_rw.txt index 27b040d..12e86f3 100644 --- a/crates/fayalite/tests/sim/expected/array_rw.txt +++ b/crates/fayalite/tests/sim/expected/array_rw.txt @@ -826,9 +826,9 @@ Simulation { }.write_index, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "array_rw", children: [ @@ -1699,12 +1699,7 @@ Simulation { }, ), ], + instant: 34 μs, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 34 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt b/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt index d470792..58b2d20 100644 --- a/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt +++ b/crates/fayalite/tests/sim/expected/conditional_assignment_last.txt @@ -122,9 +122,9 @@ Simulation { }.i, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "conditional_assignment_last", children: [ @@ -177,12 +177,7 @@ Simulation { }, ), ], + instant: 2 μs, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 2 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/connect_const.txt b/crates/fayalite/tests/sim/expected/connect_const.txt index 56ea4ad..182ed84 100644 --- a/crates/fayalite/tests/sim/expected/connect_const.txt +++ b/crates/fayalite/tests/sim/expected/connect_const.txt @@ -98,9 +98,9 @@ Simulation { }.o, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "connect_const", children: [ @@ -130,12 +130,7 @@ Simulation { ], trace_memories: {}, trace_writers: [], + instant: 0 s, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 0 s, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/connect_const_reset.txt b/crates/fayalite/tests/sim/expected/connect_const_reset.txt index 6b5814a..f56a6b4 100644 --- a/crates/fayalite/tests/sim/expected/connect_const_reset.txt +++ b/crates/fayalite/tests/sim/expected/connect_const_reset.txt @@ -21,7 +21,7 @@ Simulation { }, SlotDebugData { name: "", - ty: UInt<1>, + ty: Bool, }, SlotDebugData { name: "", @@ -51,12 +51,12 @@ Simulation { insns: [ // at: module-XXXXXXXXXX.rs:1:1 0: Const { - dest: StatePartIndex(2), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + dest: StatePartIndex(2), // (0x1) SlotDebugData { name: "", ty: Bool }, value: 0x1, }, 1: Copy { dest: StatePartIndex(3), // (0x1) SlotDebugData { name: "", ty: AsyncReset }, - src: StatePartIndex(2), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(2), // (0x1) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:4:1 2: Copy { @@ -141,9 +141,9 @@ Simulation { }.reset_out, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "connect_const_reset", children: [ @@ -197,12 +197,7 @@ Simulation { }, ), ], + instant: 1 μs, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 1 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/counter_async.txt b/crates/fayalite/tests/sim/expected/counter_async.txt index 86bde88..8c8809a 100644 --- a/crates/fayalite/tests/sim/expected/counter_async.txt +++ b/crates/fayalite/tests/sim/expected/counter_async.txt @@ -100,51 +100,51 @@ Simulation { dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: AsyncReset }, }, - 3: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, - }, - 4: 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 - 5: Const { + 3: Const { dest: StatePartIndex(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, value: 0x3, }, // at: module-XXXXXXXXXX.rs:3:1 - 6: BranchIfZero { - target: 8, + 4: BranchIfZero { + target: 6, value: StatePartIndex(6), // (0x0) SlotDebugData { name: "", ty: Bool }, }, - 7: Copy { + 5: Copy { dest: StatePartIndex(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, src: StatePartIndex(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, }, // at: module-XXXXXXXXXX.rs:1:1 - 8: Add { + 6: Add { dest: StatePartIndex(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, lhs: StatePartIndex(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, rhs: StatePartIndex(7), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, - 9: CastToUInt { + 7: CastToUInt { dest: StatePartIndex(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, src: StatePartIndex(8), // (0x4) SlotDebugData { name: "", ty: UInt<5> }, dest_width: 4, }, // at: module-XXXXXXXXXX.rs:4:1 - 10: Copy { + 8: Copy { dest: StatePartIndex(4), // (0x4) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg$next", ty: UInt<4> }, src: StatePartIndex(9), // (0x4) SlotDebugData { name: "", ty: UInt<4> }, }, // at: module-XXXXXXXXXX.rs:6:1 - 11: Copy { + 9: Copy { dest: StatePartIndex(2), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count", ty: UInt<4> }, src: StatePartIndex(3), // (0x3) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::count_reg", ty: UInt<4> }, }, // at: module-XXXXXXXXXX.rs:3:1 + 10: IsNonZeroDestIsSmall { + dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, + }, + 11: 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 }, + }, 12: BranchIfSmallNonZero { target: 16, value: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, @@ -261,9 +261,9 @@ Simulation { }.count, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "counter", children: [ @@ -329,7 +329,7 @@ Simulation { index: StatePartIndex(0), }, state: 0x1, - last_state: 0x0, + last_state: 0x1, }, SimTrace { id: TraceScalarId(1), @@ -355,7 +355,7 @@ Simulation { ty: UInt<4>, }, state: 0x3, - last_state: 0x2, + last_state: 0x3, }, ], trace_memories: {}, @@ -368,14 +368,9 @@ Simulation { }, ), ], + instant: 66 μs, clocks_triggered: [ StatePartIndex(1), ], - event_queue: EventQueue(EventQueueData { - instant: 66 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/counter_async.vcd b/crates/fayalite/tests/sim/expected/counter_async.vcd index dab690f..a4b2ee9 100644 --- a/crates/fayalite/tests/sim/expected/counter_async.vcd +++ b/crates/fayalite/tests/sim/expected/counter_async.vcd @@ -26,192 +26,192 @@ b11 $ 0! #3000000 1! -b100 # b100 $ +b100 # #4000000 0! #5000000 1! -b101 # b101 $ +b101 # #6000000 0! #7000000 1! -b110 # b110 $ +b110 # #8000000 0! #9000000 1! -b111 # b111 $ +b111 # #10000000 0! #11000000 1! -b1000 # b1000 $ +b1000 # #12000000 0! #13000000 1! -b1001 # b1001 $ +b1001 # #14000000 0! #15000000 1! -b1010 # b1010 $ +b1010 # #16000000 0! #17000000 1! -b1011 # b1011 $ +b1011 # #18000000 0! #19000000 1! -b1100 # b1100 $ +b1100 # #20000000 0! #21000000 1! -b1101 # b1101 $ +b1101 # #22000000 0! #23000000 1! -b1110 # b1110 $ +b1110 # #24000000 0! #25000000 1! -b1111 # b1111 $ +b1111 # #26000000 0! #27000000 1! -b0 # b0 $ +b0 # #28000000 0! #29000000 1! -b1 # b1 $ +b1 # #30000000 0! #31000000 1! -b10 # b10 $ +b10 # #32000000 0! #33000000 1! -b11 # b11 $ +b11 # #34000000 0! #35000000 1! -b100 # b100 $ +b100 # #36000000 0! #37000000 1! -b101 # b101 $ +b101 # #38000000 0! #39000000 1! -b110 # b110 $ +b110 # #40000000 0! #41000000 1! -b111 # b111 $ +b111 # #42000000 0! #43000000 1! -b1000 # b1000 $ +b1000 # #44000000 0! #45000000 1! -b1001 # b1001 $ +b1001 # #46000000 0! #47000000 1! -b1010 # b1010 $ +b1010 # #48000000 0! #49000000 1! -b1011 # b1011 $ +b1011 # #50000000 0! #51000000 1! -b1100 # b1100 $ +b1100 # #52000000 0! #53000000 1! -b1101 # b1101 $ +b1101 # #54000000 0! #55000000 1! -b1110 # b1110 $ +b1110 # #56000000 0! #57000000 1! -b1111 # b1111 $ +b1111 # #58000000 0! #59000000 1! -b0 # b0 $ +b0 # #60000000 0! #61000000 1! -b1 # b1 $ +b1 # #62000000 0! #63000000 1! -b10 # b10 $ +b10 # #64000000 0! #65000000 1! -b11 # b11 $ +b11 # #66000000 diff --git a/crates/fayalite/tests/sim/expected/counter_sync.txt b/crates/fayalite/tests/sim/expected/counter_sync.txt index 0a7517e..1d975b3 100644 --- a/crates/fayalite/tests/sim/expected/counter_sync.txt +++ b/crates/fayalite/tests/sim/expected/counter_sync.txt @@ -112,21 +112,21 @@ Simulation { dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.rst", ty: SyncReset }, }, - 6: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, - }, - 7: 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 - 8: Const { + 6: Const { dest: StatePartIndex(5), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, value: 0x3, }, // at: module-XXXXXXXXXX.rs:3:1 + 7: IsNonZeroDestIsSmall { + dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(counter: counter).counter::cd.clk", ty: Clock }, + }, + 8: 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 }, + }, 9: BranchIfSmallZero { target: 14, value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, @@ -242,9 +242,9 @@ Simulation { }.count, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "counter", children: [ @@ -310,7 +310,7 @@ Simulation { index: StatePartIndex(0), }, state: 0x1, - last_state: 0x0, + last_state: 0x1, }, SimTrace { id: TraceScalarId(1), @@ -336,7 +336,7 @@ Simulation { ty: UInt<4>, }, state: 0x3, - last_state: 0x2, + last_state: 0x3, }, ], trace_memories: {}, @@ -349,14 +349,9 @@ Simulation { }, ), ], + instant: 66 μs, clocks_triggered: [ StatePartIndex(1), ], - event_queue: EventQueue(EventQueueData { - instant: 66 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/counter_sync.vcd b/crates/fayalite/tests/sim/expected/counter_sync.vcd index 9504a30..bf6249e 100644 --- a/crates/fayalite/tests/sim/expected/counter_sync.vcd +++ b/crates/fayalite/tests/sim/expected/counter_sync.vcd @@ -16,199 +16,199 @@ b0 $ $end #1000000 1! -b11 # b11 $ +b11 # 0" #2000000 0! #3000000 1! -b100 # b100 $ +b100 # #4000000 0! #5000000 1! -b101 # b101 $ +b101 # #6000000 0! #7000000 1! -b110 # b110 $ +b110 # #8000000 0! #9000000 1! -b111 # b111 $ +b111 # #10000000 0! #11000000 1! -b1000 # b1000 $ +b1000 # #12000000 0! #13000000 1! -b1001 # b1001 $ +b1001 # #14000000 0! #15000000 1! -b1010 # b1010 $ +b1010 # #16000000 0! #17000000 1! -b1011 # b1011 $ +b1011 # #18000000 0! #19000000 1! -b1100 # b1100 $ +b1100 # #20000000 0! #21000000 1! -b1101 # b1101 $ +b1101 # #22000000 0! #23000000 1! -b1110 # b1110 $ +b1110 # #24000000 0! #25000000 1! -b1111 # b1111 $ +b1111 # #26000000 0! #27000000 1! -b0 # b0 $ +b0 # #28000000 0! #29000000 1! -b1 # b1 $ +b1 # #30000000 0! #31000000 1! -b10 # b10 $ +b10 # #32000000 0! #33000000 1! -b11 # b11 $ +b11 # #34000000 0! #35000000 1! -b100 # b100 $ +b100 # #36000000 0! #37000000 1! -b101 # b101 $ +b101 # #38000000 0! #39000000 1! -b110 # b110 $ +b110 # #40000000 0! #41000000 1! -b111 # b111 $ +b111 # #42000000 0! #43000000 1! -b1000 # b1000 $ +b1000 # #44000000 0! #45000000 1! -b1001 # b1001 $ +b1001 # #46000000 0! #47000000 1! -b1010 # b1010 $ +b1010 # #48000000 0! #49000000 1! -b1011 # b1011 $ +b1011 # #50000000 0! #51000000 1! -b1100 # b1100 $ +b1100 # #52000000 0! #53000000 1! -b1101 # b1101 $ +b1101 # #54000000 0! #55000000 1! -b1110 # b1110 $ +b1110 # #56000000 0! #57000000 1! -b1111 # b1111 $ +b1111 # #58000000 0! #59000000 1! -b0 # b0 $ +b0 # #60000000 0! #61000000 1! -b1 # b1 $ +b1 # #62000000 0! #63000000 1! -b10 # b10 $ +b10 # #64000000 0! #65000000 1! -b11 # b11 $ +b11 # #66000000 diff --git a/crates/fayalite/tests/sim/expected/duplicate_names.txt b/crates/fayalite/tests/sim/expected/duplicate_names.txt index 64bbbe6..4c54aa8 100644 --- a/crates/fayalite/tests/sim/expected/duplicate_names.txt +++ b/crates/fayalite/tests/sim/expected/duplicate_names.txt @@ -102,9 +102,9 @@ Simulation { uninitialized_ios: {}, io_targets: {}, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "duplicate_names", children: [ @@ -160,12 +160,7 @@ Simulation { }, ), ], + instant: 1 μs, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 1 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/enums.txt b/crates/fayalite/tests/sim/expected/enums.txt index a193e92..4850a21 100644 --- a/crates/fayalite/tests/sim/expected/enums.txt +++ b/crates/fayalite/tests/sim/expected/enums.txt @@ -1003,64 +1003,65 @@ Simulation { dest: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.rst", ty: SyncReset }, }, - 97: IsNonZeroDestIsSmall { - dest: StatePartIndex(4), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.clk", ty: Clock }, - }, - 98: 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 }, - }, // at: module-XXXXXXXXXX.rs:1:1 - 99: Const { + 97: Const { dest: StatePartIndex(25), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, value: 0x0, }, - 100: Copy { + 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> }, }, // at: module-XXXXXXXXXX.rs:12:1 - 101: BranchIfZero { - target: 109, + 99: BranchIfZero { + target: 107, value: StatePartIndex(2), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::en", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:13:1 - 102: BranchIfZero { - target: 104, + 100: BranchIfZero { + target: 102, value: StatePartIndex(46), // (0x0) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:14:1 - 103: Copy { + 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 - 104: BranchIfNonZero { - target: 109, + 102: BranchIfNonZero { + target: 107, value: StatePartIndex(46), // (0x0) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:15:1 - 105: BranchIfZero { - target: 107, + 103: BranchIfZero { + target: 105, value: StatePartIndex(48), // (0x0) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:16:1 - 106: Copy { + 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 - 107: BranchIfNonZero { - target: 109, + 105: BranchIfNonZero { + target: 107, value: StatePartIndex(48), // (0x0) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:17:1 - 108: Copy { + 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>})} }, }, + // at: module-XXXXXXXXXX.rs:11:1 + 107: IsNonZeroDestIsSmall { + dest: StatePartIndex(4), // (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 }, + }, // at: module-XXXXXXXXXX.rs:10: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})} }, @@ -1453,9 +1454,9 @@ Simulation { }.which_out, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "enums", children: [ @@ -1743,7 +1744,7 @@ Simulation { index: StatePartIndex(0), }, state: 0x1, - last_state: 0x0, + last_state: 0x1, }, SimTrace { id: TraceScalarId(1), @@ -1923,14 +1924,9 @@ Simulation { }, ), ], + instant: 16 μs, clocks_triggered: [ StatePartIndex(3), ], - event_queue: EventQueue(EventQueueData { - instant: 16 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/extern_module.txt b/crates/fayalite/tests/sim/expected/extern_module.txt index f49106f..e09a767 100644 --- a/crates/fayalite/tests/sim/expected/extern_module.txt +++ b/crates/fayalite/tests/sim/expected/extern_module.txt @@ -102,7 +102,6 @@ Simulation { }.o, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [ SimulationExternModuleState { @@ -137,7 +136,6 @@ Simulation { }, }, did_initial_settle: true, - clocks_for_past: {}, }, sim: ExternModuleSimulation { generator: SimGeneratorFn { @@ -188,8 +186,14 @@ Simulation { running_generator: Some( ..., ), + wait_targets: { + Instant( + 20.500000000000 μs, + ), + }, }, ], + state_ready_to_run: false, trace_decls: TraceModule { name: "extern_module", children: [ @@ -230,7 +234,7 @@ Simulation { index: StatePartIndex(1), }, state: 0x1, - last_state: 0x0, + last_state: 0x1, }, ], trace_memories: {}, @@ -243,21 +247,7 @@ Simulation { }, ), ], + instant: 20 μs, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 20 μs, - events: { - Event { - instant: 20.500000000000 μs, - kind: ExternModule( - 0, - ), - }: Wakers( - 1, - ), - }, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/extern_module.vcd b/crates/fayalite/tests/sim/expected/extern_module.vcd index 5d6a0bc..e026a50 100644 --- a/crates/fayalite/tests/sim/expected/extern_module.vcd +++ b/crates/fayalite/tests/sim/expected/extern_module.vcd @@ -6,9 +6,8 @@ $upscope $end $enddefinitions $end $dumpvars 0! -0" -$end 1" +$end #500000 #1500000 0" diff --git a/crates/fayalite/tests/sim/expected/extern_module2.txt b/crates/fayalite/tests/sim/expected/extern_module2.txt index fa6e767..1023b2b 100644 --- a/crates/fayalite/tests/sim/expected/extern_module2.txt +++ b/crates/fayalite/tests/sim/expected/extern_module2.txt @@ -121,7 +121,6 @@ Simulation { }.o, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [ SimulationExternModuleState { @@ -168,7 +167,6 @@ Simulation { }, }, did_initial_settle: true, - clocks_for_past: {}, }, sim: ExternModuleSimulation { generator: SimGeneratorFn { @@ -236,8 +234,55 @@ Simulation { 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, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + write: None, + }, + value: SimValue { + ty: Clock, + value: OpaqueSimValue { + bits: 0x1_u1, + sim_only_values: [], + }, + }, + }, + }, }, ], + state_ready_to_run: false, trace_decls: TraceModule { name: "extern_module2", children: [ @@ -311,113 +356,7 @@ Simulation { }, ), ], + instant: 60 μs, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 60 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 59, - values: { - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x1_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x1_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 59, - .. - }, - }, - ), - }, .. } \ 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 index 4204567..464f4bd 100644 --- a/crates/fayalite/tests/sim/expected/extern_module2.vcd +++ b/crates/fayalite/tests/sim/expected/extern_module2.vcd @@ -8,9 +8,8 @@ $enddefinitions $end $dumpvars 1! 0" -b0 # -$end b1001000 # +$end #1000000 1" b1100101 # diff --git a/crates/fayalite/tests/sim/expected/many_memories.txt b/crates/fayalite/tests/sim/expected/many_memories.txt deleted file mode 100644 index c521d72..0000000 --- a/crates/fayalite/tests/sim/expected/many_memories.txt +++ /dev/null @@ -1,7787 +0,0 @@ -Simulation { - state: State { - insns: Insns { - state_layout: StateLayout { - ty: TypeLayout { - small_slots: StatePartLayout { - len: 96, - debug_data: [ - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: UInt<4>, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - ], - .. - }, - big_slots: StatePartLayout { - len: 160, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].mask", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.addr", - ty: UInt<4>, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.data", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.mask", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 8, - debug_data: [ - (), - (), - (), - (), - (), - (), - (), - (), - ], - layout_data: [ - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x0, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x1, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x0, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x1, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x1, - [0x1]: 0x1, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x1, - [0x5]: 0x1, - [0x6]: 0x1, - [0x7]: 0x1, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x0, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x1, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x1, - [0x1]: 0x0, - [0x2]: 0x1, - [0x3]: 0x0, - [0x4]: 0x1, - [0x5]: 0x1, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x1, - [0xb]: 0x1, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x1, - [0x6]: 0x1, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x1, - [0xa]: 0x1, - [0xb]: 0x1, - [0xc]: 0x1, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x1, - [0x1]: 0x1, - [0x2]: 0x1, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x1, - [0x6]: 0x0, - [0x7]: 0x1, - [0x8]: 0x1, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x1, - [0xf]: 0x0, - ], - }, - ], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:8:1 - 0: Copy { - dest: StatePartIndex(153), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.addr", ty: UInt<4> }, - src: StatePartIndex(67), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].addr", ty: UInt<4> }, - }, - 1: Copy { - dest: StatePartIndex(154), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.en", ty: Bool }, - src: StatePartIndex(68), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].en", ty: Bool }, - }, - 2: Copy { - dest: StatePartIndex(155), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.clk", ty: Clock }, - src: StatePartIndex(69), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].clk", ty: Clock }, - }, - 3: Copy { - dest: StatePartIndex(156), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.data", ty: Bool }, - src: StatePartIndex(70), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].data", ty: Bool }, - }, - 4: Copy { - dest: StatePartIndex(157), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.mask", ty: Bool }, - src: StatePartIndex(71), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[7].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 5: Copy { - dest: StatePartIndex(151), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.clk", ty: Clock }, - src: StatePartIndex(30), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].clk", ty: Clock }, - }, - 6: Copy { - dest: StatePartIndex(150), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.en", ty: Bool }, - src: StatePartIndex(29), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].en", ty: Bool }, - }, - 7: Copy { - dest: StatePartIndex(149), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.addr", ty: UInt<4> }, - src: StatePartIndex(28), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 8: Copy { - dest: StatePartIndex(142), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.addr", ty: UInt<4> }, - src: StatePartIndex(62), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].addr", ty: UInt<4> }, - }, - 9: Copy { - dest: StatePartIndex(143), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.en", ty: Bool }, - src: StatePartIndex(63), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].en", ty: Bool }, - }, - 10: Copy { - dest: StatePartIndex(144), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.clk", ty: Clock }, - src: StatePartIndex(64), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].clk", ty: Clock }, - }, - 11: Copy { - dest: StatePartIndex(145), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.data", ty: Bool }, - src: StatePartIndex(65), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].data", ty: Bool }, - }, - 12: Copy { - dest: StatePartIndex(146), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.mask", ty: Bool }, - src: StatePartIndex(66), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[6].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 13: Copy { - dest: StatePartIndex(140), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.clk", ty: Clock }, - src: StatePartIndex(26), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].clk", ty: Clock }, - }, - 14: Copy { - dest: StatePartIndex(139), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.en", ty: Bool }, - src: StatePartIndex(25), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].en", ty: Bool }, - }, - 15: Copy { - dest: StatePartIndex(138), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.addr", ty: UInt<4> }, - src: StatePartIndex(24), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 16: Copy { - dest: StatePartIndex(131), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.addr", ty: UInt<4> }, - src: StatePartIndex(57), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].addr", ty: UInt<4> }, - }, - 17: Copy { - dest: StatePartIndex(132), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.en", ty: Bool }, - src: StatePartIndex(58), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].en", ty: Bool }, - }, - 18: Copy { - dest: StatePartIndex(133), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.clk", ty: Clock }, - src: StatePartIndex(59), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].clk", ty: Clock }, - }, - 19: Copy { - dest: StatePartIndex(134), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.data", ty: Bool }, - src: StatePartIndex(60), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].data", ty: Bool }, - }, - 20: Copy { - dest: StatePartIndex(135), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.mask", ty: Bool }, - src: StatePartIndex(61), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[5].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 21: Copy { - dest: StatePartIndex(129), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.clk", ty: Clock }, - src: StatePartIndex(22), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].clk", ty: Clock }, - }, - 22: Copy { - dest: StatePartIndex(128), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.en", ty: Bool }, - src: StatePartIndex(21), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].en", ty: Bool }, - }, - 23: Copy { - dest: StatePartIndex(127), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.addr", ty: UInt<4> }, - src: StatePartIndex(20), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 24: Copy { - dest: StatePartIndex(120), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.addr", ty: UInt<4> }, - src: StatePartIndex(52), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].addr", ty: UInt<4> }, - }, - 25: Copy { - dest: StatePartIndex(121), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.en", ty: Bool }, - src: StatePartIndex(53), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].en", ty: Bool }, - }, - 26: Copy { - dest: StatePartIndex(122), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.clk", ty: Clock }, - src: StatePartIndex(54), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].clk", ty: Clock }, - }, - 27: Copy { - dest: StatePartIndex(123), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.data", ty: Bool }, - src: StatePartIndex(55), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].data", ty: Bool }, - }, - 28: Copy { - dest: StatePartIndex(124), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.mask", ty: Bool }, - src: StatePartIndex(56), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[4].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 29: Copy { - dest: StatePartIndex(118), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.clk", ty: Clock }, - src: StatePartIndex(18), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].clk", ty: Clock }, - }, - 30: Copy { - dest: StatePartIndex(117), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.en", ty: Bool }, - src: StatePartIndex(17), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].en", ty: Bool }, - }, - 31: Copy { - dest: StatePartIndex(116), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.addr", ty: UInt<4> }, - src: StatePartIndex(16), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 32: Copy { - dest: StatePartIndex(109), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.addr", ty: UInt<4> }, - src: StatePartIndex(47), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].addr", ty: UInt<4> }, - }, - 33: Copy { - dest: StatePartIndex(110), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.en", ty: Bool }, - src: StatePartIndex(48), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].en", ty: Bool }, - }, - 34: Copy { - dest: StatePartIndex(111), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.clk", ty: Clock }, - src: StatePartIndex(49), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].clk", ty: Clock }, - }, - 35: Copy { - dest: StatePartIndex(112), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.data", ty: Bool }, - src: StatePartIndex(50), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].data", ty: Bool }, - }, - 36: Copy { - dest: StatePartIndex(113), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.mask", ty: Bool }, - src: StatePartIndex(51), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[3].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 37: Copy { - dest: StatePartIndex(107), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.clk", ty: Clock }, - src: StatePartIndex(14), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].clk", ty: Clock }, - }, - 38: Copy { - dest: StatePartIndex(106), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.en", ty: Bool }, - src: StatePartIndex(13), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].en", ty: Bool }, - }, - 39: Copy { - dest: StatePartIndex(105), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.addr", ty: UInt<4> }, - src: StatePartIndex(12), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 40: Copy { - dest: StatePartIndex(98), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.addr", ty: UInt<4> }, - src: StatePartIndex(42), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].addr", ty: UInt<4> }, - }, - 41: Copy { - dest: StatePartIndex(99), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.en", ty: Bool }, - src: StatePartIndex(43), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].en", ty: Bool }, - }, - 42: Copy { - dest: StatePartIndex(100), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.clk", ty: Clock }, - src: StatePartIndex(44), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].clk", ty: Clock }, - }, - 43: Copy { - dest: StatePartIndex(101), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.data", ty: Bool }, - src: StatePartIndex(45), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].data", ty: Bool }, - }, - 44: Copy { - dest: StatePartIndex(102), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.mask", ty: Bool }, - src: StatePartIndex(46), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[2].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 45: Copy { - dest: StatePartIndex(96), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.clk", ty: Clock }, - src: StatePartIndex(10), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].clk", ty: Clock }, - }, - 46: Copy { - dest: StatePartIndex(95), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.en", ty: Bool }, - src: StatePartIndex(9), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].en", ty: Bool }, - }, - 47: Copy { - dest: StatePartIndex(94), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.addr", ty: UInt<4> }, - src: StatePartIndex(8), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 48: Copy { - dest: StatePartIndex(87), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.addr", ty: UInt<4> }, - src: StatePartIndex(37), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].addr", ty: UInt<4> }, - }, - 49: Copy { - dest: StatePartIndex(88), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.en", ty: Bool }, - src: StatePartIndex(38), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].en", ty: Bool }, - }, - 50: Copy { - dest: StatePartIndex(89), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.clk", ty: Clock }, - src: StatePartIndex(39), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].clk", ty: Clock }, - }, - 51: Copy { - dest: StatePartIndex(90), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.data", ty: Bool }, - src: StatePartIndex(40), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].data", ty: Bool }, - }, - 52: Copy { - dest: StatePartIndex(91), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.mask", ty: Bool }, - src: StatePartIndex(41), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[1].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 53: Copy { - dest: StatePartIndex(85), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.clk", ty: Clock }, - src: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].clk", ty: Clock }, - }, - 54: Copy { - dest: StatePartIndex(84), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.en", ty: Bool }, - src: StatePartIndex(5), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].en", ty: Bool }, - }, - 55: Copy { - dest: StatePartIndex(83), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.addr", ty: UInt<4> }, - src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:8:1 - 56: Copy { - dest: StatePartIndex(76), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.addr", ty: UInt<4> }, - src: StatePartIndex(32), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].addr", ty: UInt<4> }, - }, - 57: Copy { - dest: StatePartIndex(77), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.en", ty: Bool }, - src: StatePartIndex(33), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].en", ty: Bool }, - }, - 58: Copy { - dest: StatePartIndex(78), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.clk", ty: Clock }, - src: StatePartIndex(34), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].clk", ty: Clock }, - }, - 59: Copy { - dest: StatePartIndex(79), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.data", ty: Bool }, - src: StatePartIndex(35), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].data", ty: Bool }, - }, - 60: Copy { - dest: StatePartIndex(80), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.mask", ty: Bool }, - src: StatePartIndex(36), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::w[0].mask", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 61: Copy { - dest: StatePartIndex(74), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.clk", ty: Clock }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].clk", ty: Clock }, - }, - 62: Copy { - dest: StatePartIndex(73), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.en", ty: Bool }, - src: StatePartIndex(1), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].en", ty: Bool }, - }, - 63: Copy { - dest: StatePartIndex(72), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.addr", ty: UInt<4> }, - src: StatePartIndex(0), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].addr", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 64: CastBigToArrayIndex { - dest: StatePartIndex(93), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(153), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.addr", ty: UInt<4> }, - }, - 65: IsNonZeroDestIsSmall { - dest: StatePartIndex(92), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(154), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.en", ty: Bool }, - }, - 66: IsNonZeroDestIsSmall { - dest: StatePartIndex(91), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(155), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.clk", ty: Clock }, - }, - 67: AndSmall { - dest: StatePartIndex(90), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(91), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(89), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 68: CastBigToArrayIndex { - dest: StatePartIndex(88), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(149), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.addr", ty: UInt<4> }, - }, - 69: IsNonZeroDestIsSmall { - dest: StatePartIndex(87), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(150), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.en", ty: Bool }, - }, - 70: BranchIfSmallZero { - target: 73, - value: StatePartIndex(87), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 71: MemoryReadUInt { - dest: StatePartIndex(152), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.data", ty: Bool }, - memory: StatePartIndex(7), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x1, - // [0x2]: 0x1, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x1, - // [0x6]: 0x0, - // [0x7]: 0x1, - // [0x8]: 0x1, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x1, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(88), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 72: Branch { - target: 74, - }, - 73: Const { - dest: StatePartIndex(152), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 74: Copy { - dest: StatePartIndex(31), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[7].data", ty: Bool }, - src: StatePartIndex(152), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 75: IsNonZeroDestIsSmall { - dest: StatePartIndex(86), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(151), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::r0.clk", ty: Clock }, - }, - 76: AndSmall { - dest: StatePartIndex(85), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(86), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(84), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 77: CastBigToArrayIndex { - dest: StatePartIndex(81), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(142), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.addr", ty: UInt<4> }, - }, - 78: IsNonZeroDestIsSmall { - dest: StatePartIndex(80), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(143), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.en", ty: Bool }, - }, - 79: IsNonZeroDestIsSmall { - dest: StatePartIndex(79), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(144), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.clk", ty: Clock }, - }, - 80: AndSmall { - dest: StatePartIndex(78), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(79), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(77), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 81: CastBigToArrayIndex { - dest: StatePartIndex(76), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(138), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.addr", ty: UInt<4> }, - }, - 82: IsNonZeroDestIsSmall { - dest: StatePartIndex(75), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(139), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.en", ty: Bool }, - }, - 83: BranchIfSmallZero { - target: 86, - value: StatePartIndex(75), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 84: MemoryReadUInt { - dest: StatePartIndex(141), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.data", ty: Bool }, - memory: StatePartIndex(6), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x1, - // [0x6]: 0x1, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x1, - // [0xa]: 0x1, - // [0xb]: 0x1, - // [0xc]: 0x1, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(76), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 85: Branch { - target: 87, - }, - 86: Const { - dest: StatePartIndex(141), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 87: Copy { - dest: StatePartIndex(27), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[6].data", ty: Bool }, - src: StatePartIndex(141), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 88: IsNonZeroDestIsSmall { - dest: StatePartIndex(74), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(140), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::r0.clk", ty: Clock }, - }, - 89: AndSmall { - dest: StatePartIndex(73), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(74), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(72), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 90: CastBigToArrayIndex { - dest: StatePartIndex(69), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(131), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.addr", ty: UInt<4> }, - }, - 91: IsNonZeroDestIsSmall { - dest: StatePartIndex(68), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(132), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.en", ty: Bool }, - }, - 92: IsNonZeroDestIsSmall { - dest: StatePartIndex(67), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(133), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.clk", ty: Clock }, - }, - 93: AndSmall { - dest: StatePartIndex(66), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(67), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(65), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 94: CastBigToArrayIndex { - dest: StatePartIndex(64), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(127), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.addr", ty: UInt<4> }, - }, - 95: IsNonZeroDestIsSmall { - dest: StatePartIndex(63), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(128), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.en", ty: Bool }, - }, - 96: BranchIfSmallZero { - target: 99, - value: StatePartIndex(63), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 97: MemoryReadUInt { - dest: StatePartIndex(130), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.data", ty: Bool }, - memory: StatePartIndex(5), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x1, - // [0x3]: 0x0, - // [0x4]: 0x1, - // [0x5]: 0x1, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x1, - // [0xb]: 0x1, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(64), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 98: Branch { - target: 100, - }, - 99: Const { - dest: StatePartIndex(130), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 100: Copy { - dest: StatePartIndex(23), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[5].data", ty: Bool }, - src: StatePartIndex(130), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 101: IsNonZeroDestIsSmall { - dest: StatePartIndex(62), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(129), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::r0.clk", ty: Clock }, - }, - 102: AndSmall { - dest: StatePartIndex(61), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(62), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(60), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 103: CastBigToArrayIndex { - dest: StatePartIndex(57), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(120), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.addr", ty: UInt<4> }, - }, - 104: IsNonZeroDestIsSmall { - dest: StatePartIndex(56), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(121), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.en", ty: Bool }, - }, - 105: IsNonZeroDestIsSmall { - dest: StatePartIndex(55), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(122), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.clk", ty: Clock }, - }, - 106: AndSmall { - dest: StatePartIndex(54), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(55), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(53), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 107: CastBigToArrayIndex { - dest: StatePartIndex(52), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(116), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.addr", ty: UInt<4> }, - }, - 108: IsNonZeroDestIsSmall { - dest: StatePartIndex(51), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(117), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.en", ty: Bool }, - }, - 109: BranchIfSmallZero { - target: 112, - value: StatePartIndex(51), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 110: MemoryReadUInt { - dest: StatePartIndex(119), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.data", ty: Bool }, - memory: StatePartIndex(4), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x0, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x1, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(52), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 111: Branch { - target: 113, - }, - 112: Const { - dest: StatePartIndex(119), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 113: Copy { - dest: StatePartIndex(19), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[4].data", ty: Bool }, - src: StatePartIndex(119), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 114: IsNonZeroDestIsSmall { - dest: StatePartIndex(50), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(118), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::r0.clk", ty: Clock }, - }, - 115: AndSmall { - dest: StatePartIndex(49), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(50), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(48), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 116: CastBigToArrayIndex { - dest: StatePartIndex(45), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(109), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.addr", ty: UInt<4> }, - }, - 117: IsNonZeroDestIsSmall { - dest: StatePartIndex(44), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(110), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.en", ty: Bool }, - }, - 118: IsNonZeroDestIsSmall { - dest: StatePartIndex(43), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(111), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.clk", ty: Clock }, - }, - 119: AndSmall { - dest: StatePartIndex(42), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(43), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(41), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 120: CastBigToArrayIndex { - dest: StatePartIndex(40), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(105), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.addr", ty: UInt<4> }, - }, - 121: IsNonZeroDestIsSmall { - dest: StatePartIndex(39), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(106), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.en", ty: Bool }, - }, - 122: BranchIfSmallZero { - target: 125, - value: StatePartIndex(39), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 123: MemoryReadUInt { - dest: StatePartIndex(108), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.data", ty: Bool }, - memory: StatePartIndex(3), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x1, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x1, - // [0x5]: 0x1, - // [0x6]: 0x1, - // [0x7]: 0x1, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(40), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 124: Branch { - target: 126, - }, - 125: Const { - dest: StatePartIndex(108), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 126: Copy { - dest: StatePartIndex(15), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[3].data", ty: Bool }, - src: StatePartIndex(108), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 127: IsNonZeroDestIsSmall { - dest: StatePartIndex(38), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(107), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::r0.clk", ty: Clock }, - }, - 128: AndSmall { - dest: StatePartIndex(37), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(38), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(36), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 129: CastBigToArrayIndex { - dest: StatePartIndex(33), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(98), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.addr", ty: UInt<4> }, - }, - 130: IsNonZeroDestIsSmall { - dest: StatePartIndex(32), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(99), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.en", ty: Bool }, - }, - 131: IsNonZeroDestIsSmall { - dest: StatePartIndex(31), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(100), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.clk", ty: Clock }, - }, - 132: AndSmall { - dest: StatePartIndex(30), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(31), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(29), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 133: CastBigToArrayIndex { - dest: StatePartIndex(28), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(94), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.addr", ty: UInt<4> }, - }, - 134: IsNonZeroDestIsSmall { - dest: StatePartIndex(27), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(95), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.en", ty: Bool }, - }, - 135: BranchIfSmallZero { - target: 138, - value: StatePartIndex(27), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 136: MemoryReadUInt { - dest: StatePartIndex(97), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.data", ty: Bool }, - memory: StatePartIndex(2), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x1, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(28), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 137: Branch { - target: 139, - }, - 138: Const { - dest: StatePartIndex(97), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 139: Copy { - dest: StatePartIndex(11), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[2].data", ty: Bool }, - src: StatePartIndex(97), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 140: IsNonZeroDestIsSmall { - dest: StatePartIndex(26), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(96), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::r0.clk", ty: Clock }, - }, - 141: AndSmall { - dest: StatePartIndex(25), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(26), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(24), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 142: CastBigToArrayIndex { - dest: StatePartIndex(21), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(87), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.addr", ty: UInt<4> }, - }, - 143: IsNonZeroDestIsSmall { - dest: StatePartIndex(20), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(88), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.en", ty: Bool }, - }, - 144: IsNonZeroDestIsSmall { - dest: StatePartIndex(19), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(89), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.clk", ty: Clock }, - }, - 145: AndSmall { - dest: StatePartIndex(18), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(19), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(17), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 146: CastBigToArrayIndex { - dest: StatePartIndex(16), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(83), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.addr", ty: UInt<4> }, - }, - 147: IsNonZeroDestIsSmall { - dest: StatePartIndex(15), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(84), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.en", ty: Bool }, - }, - 148: BranchIfSmallZero { - target: 151, - value: StatePartIndex(15), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 149: MemoryReadUInt { - dest: StatePartIndex(86), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.data", ty: Bool }, - memory: StatePartIndex(1), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x0, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(16), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 150: Branch { - target: 152, - }, - 151: Const { - dest: StatePartIndex(86), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 152: Copy { - dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[1].data", ty: Bool }, - src: StatePartIndex(86), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 153: IsNonZeroDestIsSmall { - dest: StatePartIndex(14), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(85), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::r0.clk", ty: Clock }, - }, - 154: AndSmall { - dest: StatePartIndex(13), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(14), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(12), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 155: CastBigToArrayIndex { - dest: StatePartIndex(9), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(76), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.addr", ty: UInt<4> }, - }, - 156: IsNonZeroDestIsSmall { - dest: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(77), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.en", ty: Bool }, - }, - 157: IsNonZeroDestIsSmall { - dest: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(78), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.clk", ty: Clock }, - }, - 158: AndSmall { - dest: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(5), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 159: CastBigToArrayIndex { - dest: StatePartIndex(4), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(72), // (0xf) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.addr", ty: UInt<4> }, - }, - 160: IsNonZeroDestIsSmall { - dest: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(73), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.en", ty: Bool }, - }, - 161: BranchIfSmallZero { - target: 164, - value: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 162: MemoryReadUInt { - dest: StatePartIndex(75), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.data", ty: Bool }, - memory: StatePartIndex(0), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x0, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(4), // (0xf 15) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 163: Branch { - target: 165, - }, - 164: Const { - dest: StatePartIndex(75), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.data", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 165: Copy { - dest: StatePartIndex(3), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::r[0].data", ty: Bool }, - src: StatePartIndex(75), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.data", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 166: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(74), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::r0.clk", ty: Clock }, - }, - 167: AndSmall { - dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 168: BranchIfSmallZero { - target: 169, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 169: BranchIfSmallZero { - target: 177, - value: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 170: CopySmall { - dest: StatePartIndex(10), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(9), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 171: CopySmall { - dest: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 172: Copy { - dest: StatePartIndex(81), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(79), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.data", ty: Bool }, - }, - 173: Copy { - dest: StatePartIndex(82), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(80), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_0::w1.mask", ty: Bool }, - }, - 174: BranchIfSmallZero { - target: 177, - value: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 175: BranchIfZero { - target: 177, - value: StatePartIndex(82), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 176: MemoryWriteUInt { - value: StatePartIndex(81), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(0), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x0, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(10), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 177: BranchIfSmallZero { - target: 178, - value: StatePartIndex(13), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 178: BranchIfSmallZero { - target: 186, - value: StatePartIndex(18), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 179: CopySmall { - dest: StatePartIndex(22), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(21), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 180: CopySmall { - dest: StatePartIndex(23), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(20), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 181: Copy { - dest: StatePartIndex(92), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(90), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.data", ty: Bool }, - }, - 182: Copy { - dest: StatePartIndex(93), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(91), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_1::w1.mask", ty: Bool }, - }, - 183: BranchIfSmallZero { - target: 186, - value: StatePartIndex(23), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 184: BranchIfZero { - target: 186, - value: StatePartIndex(93), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 185: MemoryWriteUInt { - value: StatePartIndex(92), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(1), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x0, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(22), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 186: BranchIfSmallZero { - target: 187, - value: StatePartIndex(25), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 187: BranchIfSmallZero { - target: 195, - value: StatePartIndex(30), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 188: CopySmall { - dest: StatePartIndex(34), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(33), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 189: CopySmall { - dest: StatePartIndex(35), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(32), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 190: Copy { - dest: StatePartIndex(103), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(101), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.data", ty: Bool }, - }, - 191: Copy { - dest: StatePartIndex(104), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(102), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_2::w1.mask", ty: Bool }, - }, - 192: BranchIfSmallZero { - target: 195, - value: StatePartIndex(35), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 193: BranchIfZero { - target: 195, - value: StatePartIndex(104), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 194: MemoryWriteUInt { - value: StatePartIndex(103), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(2), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x1, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(34), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 195: BranchIfSmallZero { - target: 196, - value: StatePartIndex(37), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 196: BranchIfSmallZero { - target: 204, - value: StatePartIndex(42), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 197: CopySmall { - dest: StatePartIndex(46), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(45), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 198: CopySmall { - dest: StatePartIndex(47), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(44), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 199: Copy { - dest: StatePartIndex(114), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(112), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.data", ty: Bool }, - }, - 200: Copy { - dest: StatePartIndex(115), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(113), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_3::w1.mask", ty: Bool }, - }, - 201: BranchIfSmallZero { - target: 204, - value: StatePartIndex(47), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 202: BranchIfZero { - target: 204, - value: StatePartIndex(115), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 203: MemoryWriteUInt { - value: StatePartIndex(114), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(3), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x1, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x1, - // [0x5]: 0x1, - // [0x6]: 0x1, - // [0x7]: 0x1, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(46), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 204: BranchIfSmallZero { - target: 205, - value: StatePartIndex(49), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 205: BranchIfSmallZero { - target: 213, - value: StatePartIndex(54), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 206: CopySmall { - dest: StatePartIndex(58), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(57), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 207: CopySmall { - dest: StatePartIndex(59), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(56), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 208: Copy { - dest: StatePartIndex(125), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(123), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.data", ty: Bool }, - }, - 209: Copy { - dest: StatePartIndex(126), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(124), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_4::w1.mask", ty: Bool }, - }, - 210: BranchIfSmallZero { - target: 213, - value: StatePartIndex(59), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 211: BranchIfZero { - target: 213, - value: StatePartIndex(126), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 212: MemoryWriteUInt { - value: StatePartIndex(125), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(4), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x0, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x1, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(58), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 213: BranchIfSmallZero { - target: 214, - value: StatePartIndex(61), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 214: BranchIfSmallZero { - target: 222, - value: StatePartIndex(66), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 215: CopySmall { - dest: StatePartIndex(70), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(69), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 216: CopySmall { - dest: StatePartIndex(71), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(68), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 217: Copy { - dest: StatePartIndex(136), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(134), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.data", ty: Bool }, - }, - 218: Copy { - dest: StatePartIndex(137), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(135), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_5::w1.mask", ty: Bool }, - }, - 219: BranchIfSmallZero { - target: 222, - value: StatePartIndex(71), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 220: BranchIfZero { - target: 222, - value: StatePartIndex(137), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 221: MemoryWriteUInt { - value: StatePartIndex(136), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(5), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x1, - // [0x3]: 0x0, - // [0x4]: 0x1, - // [0x5]: 0x1, - // [0x6]: 0x0, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x0, - // [0xa]: 0x1, - // [0xb]: 0x1, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(70), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 222: BranchIfSmallZero { - target: 223, - value: StatePartIndex(73), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 223: BranchIfSmallZero { - target: 231, - value: StatePartIndex(78), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 224: CopySmall { - dest: StatePartIndex(82), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(81), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 225: CopySmall { - dest: StatePartIndex(83), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(80), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 226: Copy { - dest: StatePartIndex(147), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(145), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.data", ty: Bool }, - }, - 227: Copy { - dest: StatePartIndex(148), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(146), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_6::w1.mask", ty: Bool }, - }, - 228: BranchIfSmallZero { - target: 231, - value: StatePartIndex(83), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 229: BranchIfZero { - target: 231, - value: StatePartIndex(148), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 230: MemoryWriteUInt { - value: StatePartIndex(147), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(6), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x0, - // [0x2]: 0x0, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x1, - // [0x6]: 0x1, - // [0x7]: 0x0, - // [0x8]: 0x0, - // [0x9]: 0x1, - // [0xa]: 0x1, - // [0xb]: 0x1, - // [0xc]: 0x1, - // [0xd]: 0x0, - // [0xe]: 0x0, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(82), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 231: BranchIfSmallZero { - target: 232, - value: StatePartIndex(85), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 232: BranchIfSmallZero { - target: 240, - value: StatePartIndex(90), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 233: CopySmall { - dest: StatePartIndex(94), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(93), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - }, - 234: CopySmall { - dest: StatePartIndex(95), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(92), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 235: Copy { - dest: StatePartIndex(158), // (0x0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(156), // (0x0) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.data", ty: Bool }, - }, - 236: Copy { - dest: StatePartIndex(159), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(157), // (0x1) SlotDebugData { name: "InstantiatedModule(many_memories: many_memories).many_memories::mem_7::w1.mask", ty: Bool }, - }, - 237: BranchIfSmallZero { - target: 240, - value: StatePartIndex(95), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 238: BranchIfZero { - target: 240, - value: StatePartIndex(159), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 239: MemoryWriteUInt { - value: StatePartIndex(158), // (0x0) SlotDebugData { name: "", ty: Bool }, - memory: StatePartIndex(7), // (MemoryData { - // array_type: Array, - // data: [ - // // len = 0x10 - // [0x0]: 0x0, - // [0x1]: 0x1, - // [0x2]: 0x1, - // [0x3]: 0x0, - // [0x4]: 0x0, - // [0x5]: 0x1, - // [0x6]: 0x0, - // [0x7]: 0x1, - // [0x8]: 0x1, - // [0x9]: 0x0, - // [0xa]: 0x0, - // [0xb]: 0x0, - // [0xc]: 0x0, - // [0xd]: 0x0, - // [0xe]: 0x1, - // [0xf]: 0x0, - // ], - // }) (), - addr: StatePartIndex(94), // (0x0 0) SlotDebugData { name: "", ty: UInt<4> }, - stride: 1, - start: 0, - width: 1, - }, - 240: XorSmallImmediate { - dest: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 241: XorSmallImmediate { - dest: StatePartIndex(5), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 242: XorSmallImmediate { - dest: StatePartIndex(12), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(14), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 243: XorSmallImmediate { - dest: StatePartIndex(17), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(19), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 244: XorSmallImmediate { - dest: StatePartIndex(24), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(26), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 245: XorSmallImmediate { - dest: StatePartIndex(29), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(31), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 246: XorSmallImmediate { - dest: StatePartIndex(36), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(38), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 247: XorSmallImmediate { - dest: StatePartIndex(41), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(43), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 248: XorSmallImmediate { - dest: StatePartIndex(48), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(50), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 249: XorSmallImmediate { - dest: StatePartIndex(53), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(55), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 250: XorSmallImmediate { - dest: StatePartIndex(60), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(62), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 251: XorSmallImmediate { - dest: StatePartIndex(65), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(67), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 252: XorSmallImmediate { - dest: StatePartIndex(72), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(74), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 253: XorSmallImmediate { - dest: StatePartIndex(77), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(79), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 254: XorSmallImmediate { - dest: StatePartIndex(84), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(86), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 255: XorSmallImmediate { - dest: StatePartIndex(89), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(91), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 256: Return, - ], - .. - }, - pc: 256, - memory_write_log: [], - memories: StatePart { - value: [ - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x0, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x0, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x1, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x1, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x1, - [0x5]: 0x1, - [0x6]: 0x1, - [0x7]: 0x1, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x0, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x1, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x1, - [0x3]: 0x0, - [0x4]: 0x1, - [0x5]: 0x1, - [0x6]: 0x0, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x0, - [0xa]: 0x1, - [0xb]: 0x1, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x0, - [0x2]: 0x0, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x1, - [0x6]: 0x1, - [0x7]: 0x0, - [0x8]: 0x0, - [0x9]: 0x1, - [0xa]: 0x1, - [0xb]: 0x1, - [0xc]: 0x1, - [0xd]: 0x0, - [0xe]: 0x0, - [0xf]: 0x0, - ], - }, - MemoryData { - array_type: Array, - data: [ - // len = 0x10 - [0x0]: 0x0, - [0x1]: 0x1, - [0x2]: 0x1, - [0x3]: 0x0, - [0x4]: 0x0, - [0x5]: 0x1, - [0x6]: 0x0, - [0x7]: 0x1, - [0x8]: 0x1, - [0x9]: 0x0, - [0xa]: 0x0, - [0xb]: 0x0, - [0xc]: 0x0, - [0xd]: 0x0, - [0xe]: 0x1, - [0xf]: 0x0, - ], - }, - ], - }, - small_slots: StatePart { - value: [ - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - ], - }, - big_slots: StatePart { - value: [ - 15, - 1, - 0, - 0, - 15, - 1, - 0, - 0, - 15, - 1, - 0, - 0, - 15, - 1, - 0, - 0, - 15, - 1, - 0, - 0, - 15, - 1, - 0, - 0, - 15, - 1, - 0, - 0, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 15, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[0], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[0].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[0].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[0].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[0].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[1], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[1].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[1].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[1].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[1].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[2], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[2].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[2].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[2].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[2].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[3], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[3].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[3].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[3].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[3].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[4], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[4].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[4].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[4].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[4].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[5], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[5].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[5].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[5].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[5].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[6], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[6].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[6].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[6].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[6].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[7], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[7].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[7].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[7].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.r[7].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[0], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[0].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[0].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[0].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[0].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[0].mask, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[1], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[1].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[1].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[1].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[1].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[1].mask, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[2], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[2].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[2].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[2].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[2].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[2].mask, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[3], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[3].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[3].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[3].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[3].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[3].mask, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[4], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[4].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[4].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[4].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[4].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[4].mask, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[5], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[5].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[5].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[5].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[5].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[5].mask, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[6], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[6].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[6].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[6].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[6].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[6].mask, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[7], - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[7].addr, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[7].clk, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[7].data, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[7].en, - Instance { - name: ::many_memories, - instantiated: Module { - name: many_memories, - .. - }, - }.w[7].mask, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [], - trace_decls: TraceModule { - name: "many_memories", - children: [ - TraceModuleIO { - name: "r", - child: TraceArray { - name: "r", - elements: [ - TraceBundle { - name: "[0]", - fields: [ - TraceUInt { - location: TraceScalarId(0), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(1), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(2), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(3), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[1]", - fields: [ - TraceUInt { - location: TraceScalarId(4), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(5), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(6), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(7), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[2]", - fields: [ - TraceUInt { - location: TraceScalarId(8), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(9), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(10), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(11), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[3]", - fields: [ - TraceUInt { - location: TraceScalarId(12), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(13), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(14), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(15), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[4]", - fields: [ - TraceUInt { - location: TraceScalarId(16), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(17), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(18), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(19), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[5]", - fields: [ - TraceUInt { - location: TraceScalarId(20), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(21), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(22), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(23), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[6]", - fields: [ - TraceUInt { - location: TraceScalarId(24), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(25), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(26), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(27), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[7]", - fields: [ - TraceUInt { - location: TraceScalarId(28), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(29), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(30), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(31), - name: "data", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Source, - }, - ], - ty: Array, en: Bool, clk: Clock, #[hdl(flip)] data: Bool}, 8>, - flow: Source, - }, - ty: Array, en: Bool, clk: Clock, #[hdl(flip)] data: Bool}, 8>, - flow: Source, - }, - TraceModuleIO { - name: "w", - child: TraceArray { - name: "w", - elements: [ - TraceBundle { - name: "[0]", - fields: [ - TraceUInt { - location: TraceScalarId(32), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(33), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(34), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(35), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(36), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[1]", - fields: [ - TraceUInt { - location: TraceScalarId(37), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(38), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(39), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(40), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(41), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[2]", - fields: [ - TraceUInt { - location: TraceScalarId(42), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(43), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(44), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(45), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(46), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[3]", - fields: [ - TraceUInt { - location: TraceScalarId(47), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(48), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(49), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(50), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(51), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[4]", - fields: [ - TraceUInt { - location: TraceScalarId(52), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(53), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(54), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(55), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(56), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[5]", - fields: [ - TraceUInt { - location: TraceScalarId(57), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(58), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(59), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(60), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(61), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[6]", - fields: [ - TraceUInt { - location: TraceScalarId(62), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(63), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(64), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(65), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(66), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - TraceBundle { - name: "[7]", - fields: [ - TraceUInt { - location: TraceScalarId(67), - name: "addr", - ty: UInt<4>, - flow: Source, - }, - TraceBool { - location: TraceScalarId(68), - name: "en", - flow: Source, - }, - TraceClock { - location: TraceScalarId(69), - name: "clk", - flow: Source, - }, - TraceBool { - location: TraceScalarId(70), - name: "data", - flow: Source, - }, - TraceBool { - location: TraceScalarId(71), - name: "mask", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Source, - }, - ], - ty: Array, en: Bool, clk: Clock, data: Bool, mask: Bool}, 8>, - flow: Source, - }, - ty: Array, en: Bool, clk: Clock, data: Bool, mask: Bool}, 8>, - flow: Source, - }, - TraceMem { - id: TraceMemoryId(0), - name: "mem_0", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(0), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_0", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(72), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(73), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(74), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(75), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(76), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(77), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(78), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(79), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(80), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - TraceMem { - id: TraceMemoryId(1), - name: "mem_1", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(1), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_1", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(81), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(82), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(83), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(84), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(85), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(86), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(87), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(88), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(89), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - TraceMem { - id: TraceMemoryId(2), - name: "mem_2", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(2), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_2", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(90), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(91), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(92), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(93), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(94), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(95), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(96), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(97), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(98), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - TraceMem { - id: TraceMemoryId(3), - name: "mem_3", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(3), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_3", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(99), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(100), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(101), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(102), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(103), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(104), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(105), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(106), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(107), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - TraceMem { - id: TraceMemoryId(4), - name: "mem_4", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(4), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_4", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(108), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(109), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(110), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(111), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(112), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(113), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(114), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(115), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(116), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - TraceMem { - id: TraceMemoryId(5), - name: "mem_5", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(5), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_5", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(117), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(118), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(119), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(120), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(121), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(122), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(123), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(124), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(125), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - TraceMem { - id: TraceMemoryId(6), - name: "mem_6", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(6), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_6", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(126), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(127), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(128), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(129), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(130), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(131), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(132), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(133), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(134), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - TraceMem { - id: TraceMemoryId(7), - name: "mem_7", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(7), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_7", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(135), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(136), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(137), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(138), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(139), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(140), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(141), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(142), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(143), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigUInt { - index: StatePartIndex(0), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigBool { - index: StatePartIndex(1), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigClock { - index: StatePartIndex(2), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(3), - kind: BigBool { - index: StatePartIndex(3), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(4), - kind: BigUInt { - index: StatePartIndex(4), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(5), - kind: BigBool { - index: StatePartIndex(5), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(6), - kind: BigClock { - index: StatePartIndex(6), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(7), - kind: BigBool { - index: StatePartIndex(7), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(8), - kind: BigUInt { - index: StatePartIndex(8), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(9), - kind: BigBool { - index: StatePartIndex(9), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(10), - kind: BigClock { - index: StatePartIndex(10), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(11), - kind: BigBool { - index: StatePartIndex(11), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(12), - kind: BigUInt { - index: StatePartIndex(12), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(13), - kind: BigBool { - index: StatePartIndex(13), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(14), - kind: BigClock { - index: StatePartIndex(14), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(15), - kind: BigBool { - index: StatePartIndex(15), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(16), - kind: BigUInt { - index: StatePartIndex(16), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(17), - kind: BigBool { - index: StatePartIndex(17), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(18), - kind: BigClock { - index: StatePartIndex(18), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(19), - kind: BigBool { - index: StatePartIndex(19), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(20), - kind: BigUInt { - index: StatePartIndex(20), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(21), - kind: BigBool { - index: StatePartIndex(21), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(22), - kind: BigClock { - index: StatePartIndex(22), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(23), - kind: BigBool { - index: StatePartIndex(23), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(24), - kind: BigUInt { - index: StatePartIndex(24), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(25), - kind: BigBool { - index: StatePartIndex(25), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(26), - kind: BigClock { - index: StatePartIndex(26), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(27), - kind: BigBool { - index: StatePartIndex(27), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(28), - kind: BigUInt { - index: StatePartIndex(28), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(29), - kind: BigBool { - index: StatePartIndex(29), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(30), - kind: BigClock { - index: StatePartIndex(30), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(31), - kind: BigBool { - index: StatePartIndex(31), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(32), - kind: BigUInt { - index: StatePartIndex(32), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(33), - kind: BigBool { - index: StatePartIndex(33), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(34), - kind: BigClock { - index: StatePartIndex(34), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(35), - kind: BigBool { - index: StatePartIndex(35), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(36), - kind: BigBool { - index: StatePartIndex(36), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(37), - kind: BigUInt { - index: StatePartIndex(37), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(38), - kind: BigBool { - index: StatePartIndex(38), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(39), - kind: BigClock { - index: StatePartIndex(39), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(40), - kind: BigBool { - index: StatePartIndex(40), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(41), - kind: BigBool { - index: StatePartIndex(41), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(42), - kind: BigUInt { - index: StatePartIndex(42), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(43), - kind: BigBool { - index: StatePartIndex(43), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(44), - kind: BigClock { - index: StatePartIndex(44), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(45), - kind: BigBool { - index: StatePartIndex(45), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(46), - kind: BigBool { - index: StatePartIndex(46), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(47), - kind: BigUInt { - index: StatePartIndex(47), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(48), - kind: BigBool { - index: StatePartIndex(48), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(49), - kind: BigClock { - index: StatePartIndex(49), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(50), - kind: BigBool { - index: StatePartIndex(50), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(51), - kind: BigBool { - index: StatePartIndex(51), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(52), - kind: BigUInt { - index: StatePartIndex(52), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(53), - kind: BigBool { - index: StatePartIndex(53), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(54), - kind: BigClock { - index: StatePartIndex(54), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(55), - kind: BigBool { - index: StatePartIndex(55), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(56), - kind: BigBool { - index: StatePartIndex(56), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(57), - kind: BigUInt { - index: StatePartIndex(57), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(58), - kind: BigBool { - index: StatePartIndex(58), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(59), - kind: BigClock { - index: StatePartIndex(59), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(60), - kind: BigBool { - index: StatePartIndex(60), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(61), - kind: BigBool { - index: StatePartIndex(61), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(62), - kind: BigUInt { - index: StatePartIndex(62), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(63), - kind: BigBool { - index: StatePartIndex(63), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(64), - kind: BigClock { - index: StatePartIndex(64), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(65), - kind: BigBool { - index: StatePartIndex(65), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(66), - kind: BigBool { - index: StatePartIndex(66), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(67), - kind: BigUInt { - index: StatePartIndex(67), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(68), - kind: BigBool { - index: StatePartIndex(68), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(69), - kind: BigClock { - index: StatePartIndex(69), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(70), - kind: BigBool { - index: StatePartIndex(70), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(71), - kind: BigBool { - index: StatePartIndex(71), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(72), - kind: BigUInt { - index: StatePartIndex(72), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(73), - kind: BigBool { - index: StatePartIndex(73), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(74), - kind: BigClock { - index: StatePartIndex(74), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(75), - kind: BigBool { - index: StatePartIndex(75), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(76), - kind: BigUInt { - index: StatePartIndex(76), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(77), - kind: BigBool { - index: StatePartIndex(77), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(78), - kind: BigClock { - index: StatePartIndex(78), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(79), - kind: BigBool { - index: StatePartIndex(79), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(80), - kind: BigBool { - index: StatePartIndex(80), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(81), - kind: BigUInt { - index: StatePartIndex(83), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(82), - kind: BigBool { - index: StatePartIndex(84), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(83), - kind: BigClock { - index: StatePartIndex(85), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(84), - kind: BigBool { - index: StatePartIndex(86), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(85), - kind: BigUInt { - index: StatePartIndex(87), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(86), - kind: BigBool { - index: StatePartIndex(88), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(87), - kind: BigClock { - index: StatePartIndex(89), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(88), - kind: BigBool { - index: StatePartIndex(90), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(89), - kind: BigBool { - index: StatePartIndex(91), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(90), - kind: BigUInt { - index: StatePartIndex(94), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(91), - kind: BigBool { - index: StatePartIndex(95), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(92), - kind: BigClock { - index: StatePartIndex(96), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(93), - kind: BigBool { - index: StatePartIndex(97), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(94), - kind: BigUInt { - index: StatePartIndex(98), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(95), - kind: BigBool { - index: StatePartIndex(99), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(96), - kind: BigClock { - index: StatePartIndex(100), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(97), - kind: BigBool { - index: StatePartIndex(101), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(98), - kind: BigBool { - index: StatePartIndex(102), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(99), - kind: BigUInt { - index: StatePartIndex(105), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(100), - kind: BigBool { - index: StatePartIndex(106), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(101), - kind: BigClock { - index: StatePartIndex(107), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(102), - kind: BigBool { - index: StatePartIndex(108), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(103), - kind: BigUInt { - index: StatePartIndex(109), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(104), - kind: BigBool { - index: StatePartIndex(110), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(105), - kind: BigClock { - index: StatePartIndex(111), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(106), - kind: BigBool { - index: StatePartIndex(112), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(107), - kind: BigBool { - index: StatePartIndex(113), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(108), - kind: BigUInt { - index: StatePartIndex(116), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(109), - kind: BigBool { - index: StatePartIndex(117), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(110), - kind: BigClock { - index: StatePartIndex(118), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(111), - kind: BigBool { - index: StatePartIndex(119), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(112), - kind: BigUInt { - index: StatePartIndex(120), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(113), - kind: BigBool { - index: StatePartIndex(121), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(114), - kind: BigClock { - index: StatePartIndex(122), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(115), - kind: BigBool { - index: StatePartIndex(123), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(116), - kind: BigBool { - index: StatePartIndex(124), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(117), - kind: BigUInt { - index: StatePartIndex(127), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(118), - kind: BigBool { - index: StatePartIndex(128), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(119), - kind: BigClock { - index: StatePartIndex(129), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(120), - kind: BigBool { - index: StatePartIndex(130), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(121), - kind: BigUInt { - index: StatePartIndex(131), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(122), - kind: BigBool { - index: StatePartIndex(132), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(123), - kind: BigClock { - index: StatePartIndex(133), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(124), - kind: BigBool { - index: StatePartIndex(134), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(125), - kind: BigBool { - index: StatePartIndex(135), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(126), - kind: BigUInt { - index: StatePartIndex(138), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(127), - kind: BigBool { - index: StatePartIndex(139), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(128), - kind: BigClock { - index: StatePartIndex(140), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(129), - kind: BigBool { - index: StatePartIndex(141), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(130), - kind: BigUInt { - index: StatePartIndex(142), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(131), - kind: BigBool { - index: StatePartIndex(143), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(132), - kind: BigClock { - index: StatePartIndex(144), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(133), - kind: BigBool { - index: StatePartIndex(145), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(134), - kind: BigBool { - index: StatePartIndex(146), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(135), - kind: BigUInt { - index: StatePartIndex(149), - ty: UInt<4>, - }, - state: 0xf, - last_state: 0xf, - }, - SimTrace { - id: TraceScalarId(136), - kind: BigBool { - index: StatePartIndex(150), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(137), - kind: BigClock { - index: StatePartIndex(151), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(138), - kind: BigBool { - index: StatePartIndex(152), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(139), - kind: BigUInt { - index: StatePartIndex(153), - ty: UInt<4>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(140), - kind: BigBool { - index: StatePartIndex(154), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(141), - kind: BigClock { - index: StatePartIndex(155), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(142), - kind: BigBool { - index: StatePartIndex(156), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(143), - kind: BigBool { - index: StatePartIndex(157), - }, - state: 0x1, - last_state: 0x1, - }, - ], - trace_memories: { - StatePartIndex(0): TraceMem { - id: TraceMemoryId(0), - name: "mem_0", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(0), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_0", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(72), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(73), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(74), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(75), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(76), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(77), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(78), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(79), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(80), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - StatePartIndex(1): TraceMem { - id: TraceMemoryId(1), - name: "mem_1", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(1), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_1", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(81), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(82), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(83), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(84), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(85), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(86), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(87), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(88), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(89), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - StatePartIndex(2): TraceMem { - id: TraceMemoryId(2), - name: "mem_2", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(2), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_2", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(90), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(91), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(92), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(93), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(94), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(95), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(96), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(97), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(98), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - StatePartIndex(3): TraceMem { - id: TraceMemoryId(3), - name: "mem_3", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(3), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_3", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(99), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(100), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(101), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(102), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(103), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(104), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(105), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(106), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(107), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - StatePartIndex(4): TraceMem { - id: TraceMemoryId(4), - name: "mem_4", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(4), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_4", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(108), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(109), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(110), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(111), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(112), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(113), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(114), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(115), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(116), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - StatePartIndex(5): TraceMem { - id: TraceMemoryId(5), - name: "mem_5", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(5), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_5", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(117), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(118), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(119), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(120), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(121), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(122), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(123), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(124), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(125), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - StatePartIndex(6): TraceMem { - id: TraceMemoryId(6), - name: "mem_6", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(6), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_6", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(126), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(127), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(128), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(129), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(130), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(131), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(132), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(133), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(134), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - StatePartIndex(7): TraceMem { - id: TraceMemoryId(7), - name: "mem_7", - stride: 1, - element_type: TraceBool { - location: TraceMemoryLocation { - id: TraceMemoryId(7), - depth: 16, - stride: 1, - start: 0, - len: 1, - }, - name: "mem_7", - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(135), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(136), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(137), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(138), - name: "data", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - #[hdl(flip)] /* offset = 6 */ - data: Bool, - }, - }, - TraceMemPort { - name: "w1", - bundle: TraceBundle { - name: "w1", - fields: [ - TraceUInt { - location: TraceScalarId(139), - name: "addr", - ty: UInt<4>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(140), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(141), - name: "clk", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(142), - name: "data", - flow: Sink, - }, - TraceBool { - location: TraceScalarId(143), - name: "mask", - flow: Sink, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<4>, - /* offset = 4 */ - en: Bool, - /* offset = 5 */ - clk: Clock, - /* offset = 6 */ - data: Bool, - /* offset = 7 */ - mask: Bool, - }, - }, - ], - array_type: Array, - }, - }, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [ - StatePartIndex(1), - StatePartIndex(6), - StatePartIndex(13), - StatePartIndex(18), - StatePartIndex(25), - StatePartIndex(30), - StatePartIndex(37), - StatePartIndex(42), - StatePartIndex(49), - StatePartIndex(54), - StatePartIndex(61), - StatePartIndex(66), - StatePartIndex(73), - StatePartIndex(78), - StatePartIndex(85), - StatePartIndex(90), - ], - event_queue: EventQueue(EventQueueData { - instant: 38 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/many_memories.vcd b/crates/fayalite/tests/sim/expected/many_memories.vcd deleted file mode 100644 index 77d1447..0000000 --- a/crates/fayalite/tests/sim/expected/many_memories.vcd +++ /dev/null @@ -1,2596 +0,0 @@ -$timescale 1 ps $end -$scope module many_memories $end -$scope struct r $end -$scope struct \[0] $end -$var wire 4 ! addr $end -$var wire 1 " en $end -$var wire 1 # clk $end -$var wire 1 $ data $end -$upscope $end -$scope struct \[1] $end -$var wire 4 % addr $end -$var wire 1 & en $end -$var wire 1 ' clk $end -$var wire 1 ( data $end -$upscope $end -$scope struct \[2] $end -$var wire 4 ) addr $end -$var wire 1 * en $end -$var wire 1 + clk $end -$var wire 1 , data $end -$upscope $end -$scope struct \[3] $end -$var wire 4 - addr $end -$var wire 1 . en $end -$var wire 1 / clk $end -$var wire 1 0 data $end -$upscope $end -$scope struct \[4] $end -$var wire 4 1 addr $end -$var wire 1 2 en $end -$var wire 1 3 clk $end -$var wire 1 4 data $end -$upscope $end -$scope struct \[5] $end -$var wire 4 5 addr $end -$var wire 1 6 en $end -$var wire 1 7 clk $end -$var wire 1 8 data $end -$upscope $end -$scope struct \[6] $end -$var wire 4 9 addr $end -$var wire 1 : en $end -$var wire 1 ; clk $end -$var wire 1 < data $end -$upscope $end -$scope struct \[7] $end -$var wire 4 = addr $end -$var wire 1 > en $end -$var wire 1 ? clk $end -$var wire 1 @ data $end -$upscope $end -$upscope $end -$scope struct w $end -$scope struct \[0] $end -$var wire 4 A addr $end -$var wire 1 B en $end -$var wire 1 C clk $end -$var wire 1 D data $end -$var wire 1 E mask $end -$upscope $end -$scope struct \[1] $end -$var wire 4 F addr $end -$var wire 1 G en $end -$var wire 1 H clk $end -$var wire 1 I data $end -$var wire 1 J mask $end -$upscope $end -$scope struct \[2] $end -$var wire 4 K addr $end -$var wire 1 L en $end -$var wire 1 M clk $end -$var wire 1 N data $end -$var wire 1 O mask $end -$upscope $end -$scope struct \[3] $end -$var wire 4 P addr $end -$var wire 1 Q en $end -$var wire 1 R clk $end -$var wire 1 S data $end -$var wire 1 T mask $end -$upscope $end -$scope struct \[4] $end -$var wire 4 U addr $end -$var wire 1 V en $end -$var wire 1 W clk $end -$var wire 1 X data $end -$var wire 1 Y mask $end -$upscope $end -$scope struct \[5] $end -$var wire 4 Z addr $end -$var wire 1 [ en $end -$var wire 1 \ clk $end -$var wire 1 ] data $end -$var wire 1 ^ mask $end -$upscope $end -$scope struct \[6] $end -$var wire 4 _ addr $end -$var wire 1 ` en $end -$var wire 1 a clk $end -$var wire 1 b data $end -$var wire 1 c mask $end -$upscope $end -$scope struct \[7] $end -$var wire 4 d addr $end -$var wire 1 e en $end -$var wire 1 f clk $end -$var wire 1 g data $end -$var wire 1 h mask $end -$upscope $end -$upscope $end -$scope struct mem_0 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 S" mem_0 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 T" mem_0 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 U" mem_0 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 V" mem_0 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 W" mem_0 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 X" mem_0 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 Y" mem_0 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 Z" mem_0 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 [" mem_0 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 \" mem_0 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 ]" mem_0 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 ^" mem_0 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 _" mem_0 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 `" mem_0 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 a" mem_0 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 b" mem_0 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 i addr $end -$var wire 1 j en $end -$var wire 1 k clk $end -$var wire 1 l data $end -$upscope $end -$scope struct w1 $end -$var wire 4 m addr $end -$var wire 1 n en $end -$var wire 1 o clk $end -$var wire 1 p data $end -$var wire 1 q mask $end -$upscope $end -$upscope $end -$scope struct mem_1 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 c" mem_1 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 d" mem_1 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 e" mem_1 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 f" mem_1 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 g" mem_1 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 h" mem_1 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 i" mem_1 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 j" mem_1 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 k" mem_1 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 l" mem_1 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 m" mem_1 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 n" mem_1 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 o" mem_1 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 p" mem_1 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 q" mem_1 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 r" mem_1 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 r addr $end -$var wire 1 s en $end -$var wire 1 t clk $end -$var wire 1 u data $end -$upscope $end -$scope struct w1 $end -$var wire 4 v addr $end -$var wire 1 w en $end -$var wire 1 x clk $end -$var wire 1 y data $end -$var wire 1 z mask $end -$upscope $end -$upscope $end -$scope struct mem_2 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 s" mem_2 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 t" mem_2 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 u" mem_2 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 v" mem_2 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 w" mem_2 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 x" mem_2 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 y" mem_2 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 z" mem_2 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 {" mem_2 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 |" mem_2 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 }" mem_2 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 ~" mem_2 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 !# mem_2 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 "# mem_2 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 ## mem_2 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 $# mem_2 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 { addr $end -$var wire 1 | en $end -$var wire 1 } clk $end -$var wire 1 ~ data $end -$upscope $end -$scope struct w1 $end -$var wire 4 !" addr $end -$var wire 1 "" en $end -$var wire 1 #" clk $end -$var wire 1 $" data $end -$var wire 1 %" mask $end -$upscope $end -$upscope $end -$scope struct mem_3 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 %# mem_3 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 &# mem_3 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 '# mem_3 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 (# mem_3 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 )# mem_3 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 *# mem_3 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 +# mem_3 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 ,# mem_3 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 -# mem_3 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 .# mem_3 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 /# mem_3 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 0# mem_3 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 1# mem_3 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 2# mem_3 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 3# mem_3 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 4# mem_3 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 &" addr $end -$var wire 1 '" en $end -$var wire 1 (" clk $end -$var wire 1 )" data $end -$upscope $end -$scope struct w1 $end -$var wire 4 *" addr $end -$var wire 1 +" en $end -$var wire 1 ," clk $end -$var wire 1 -" data $end -$var wire 1 ." mask $end -$upscope $end -$upscope $end -$scope struct mem_4 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 5# mem_4 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 6# mem_4 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 7# mem_4 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 8# mem_4 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 9# mem_4 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 :# mem_4 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 ;# mem_4 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 <# mem_4 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 =# mem_4 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 ># mem_4 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 ?# mem_4 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 @# mem_4 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 A# mem_4 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 B# mem_4 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 C# mem_4 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 D# mem_4 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 /" addr $end -$var wire 1 0" en $end -$var wire 1 1" clk $end -$var wire 1 2" data $end -$upscope $end -$scope struct w1 $end -$var wire 4 3" addr $end -$var wire 1 4" en $end -$var wire 1 5" clk $end -$var wire 1 6" data $end -$var wire 1 7" mask $end -$upscope $end -$upscope $end -$scope struct mem_5 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 E# mem_5 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 F# mem_5 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 G# mem_5 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 H# mem_5 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 I# mem_5 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 J# mem_5 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 K# mem_5 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 L# mem_5 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 M# mem_5 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 N# mem_5 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 O# mem_5 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 P# mem_5 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 Q# mem_5 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 R# mem_5 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 S# mem_5 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 T# mem_5 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 8" addr $end -$var wire 1 9" en $end -$var wire 1 :" clk $end -$var wire 1 ;" data $end -$upscope $end -$scope struct w1 $end -$var wire 4 <" addr $end -$var wire 1 =" en $end -$var wire 1 >" clk $end -$var wire 1 ?" data $end -$var wire 1 @" mask $end -$upscope $end -$upscope $end -$scope struct mem_6 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 U# mem_6 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 V# mem_6 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 W# mem_6 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 X# mem_6 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 Y# mem_6 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 Z# mem_6 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 [# mem_6 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 \# mem_6 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 ]# mem_6 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 ^# mem_6 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 _# mem_6 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 `# mem_6 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 a# mem_6 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 b# mem_6 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 c# mem_6 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 d# mem_6 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 A" addr $end -$var wire 1 B" en $end -$var wire 1 C" clk $end -$var wire 1 D" data $end -$upscope $end -$scope struct w1 $end -$var wire 4 E" addr $end -$var wire 1 F" en $end -$var wire 1 G" clk $end -$var wire 1 H" data $end -$var wire 1 I" mask $end -$upscope $end -$upscope $end -$scope struct mem_7 $end -$scope struct contents $end -$scope struct \[0] $end -$var reg 1 e# mem_7 $end -$upscope $end -$scope struct \[1] $end -$var reg 1 f# mem_7 $end -$upscope $end -$scope struct \[2] $end -$var reg 1 g# mem_7 $end -$upscope $end -$scope struct \[3] $end -$var reg 1 h# mem_7 $end -$upscope $end -$scope struct \[4] $end -$var reg 1 i# mem_7 $end -$upscope $end -$scope struct \[5] $end -$var reg 1 j# mem_7 $end -$upscope $end -$scope struct \[6] $end -$var reg 1 k# mem_7 $end -$upscope $end -$scope struct \[7] $end -$var reg 1 l# mem_7 $end -$upscope $end -$scope struct \[8] $end -$var reg 1 m# mem_7 $end -$upscope $end -$scope struct \[9] $end -$var reg 1 n# mem_7 $end -$upscope $end -$scope struct \[10] $end -$var reg 1 o# mem_7 $end -$upscope $end -$scope struct \[11] $end -$var reg 1 p# mem_7 $end -$upscope $end -$scope struct \[12] $end -$var reg 1 q# mem_7 $end -$upscope $end -$scope struct \[13] $end -$var reg 1 r# mem_7 $end -$upscope $end -$scope struct \[14] $end -$var reg 1 s# mem_7 $end -$upscope $end -$scope struct \[15] $end -$var reg 1 t# mem_7 $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var wire 4 J" addr $end -$var wire 1 K" en $end -$var wire 1 L" clk $end -$var wire 1 M" data $end -$upscope $end -$scope struct w1 $end -$var wire 4 N" addr $end -$var wire 1 O" en $end -$var wire 1 P" clk $end -$var wire 1 Q" data $end -$var wire 1 R" mask $end -$upscope $end -$upscope $end -$upscope $end -$enddefinitions $end -$dumpvars -0S" -0T" -0U" -0V" -0W" -0X" -0Y" -0Z" -0[" -0\" -0]" -0^" -0_" -0`" -0a" -0b" -1c" -0d" -0e" -0f" -0g" -0h" -0i" -0j" -0k" -0l" -0m" -0n" -0o" -0p" -0q" -0r" -0s" -0t" -0u" -0v" -0w" -1x" -0y" -0z" -0{" -0|" -0}" -0~" -0!# -0"# -0## -0$# -1%# -1&# -0'# -0(# -1)# -1*# -1+# -1,# -0-# -0.# -0/# -00# -01# -02# -03# -04# -05# -06# -07# -08# -09# -0:# -0;# -0<# -0=# -0># -1?# -0@# -0A# -0B# -0C# -0D# -1E# -0F# -1G# -0H# -1I# -1J# -0K# -0L# -0M# -0N# -1O# -1P# -0Q# -0R# -0S# -0T# -0U# -0V# -0W# -0X# -0Y# -1Z# -1[# -0\# -0]# -1^# -1_# -1`# -1a# -0b# -0c# -0d# -1e# -1f# -1g# -0h# -0i# -1j# -0k# -1l# -1m# -0n# -0o# -0p# -0q# -0r# -1s# -0t# -b0 ! -0" -0# -0$ -b0 % -0& -0' -0( -b0 ) -0* -0+ -0, -b0 - -0. -0/ -00 -b0 1 -02 -03 -04 -b0 5 -06 -07 -08 -b0 9 -0: -0; -0< -b0 = -0> -0? -0@ -b0 A -0B -0C -0D -0E -b0 F -0G -0H -0I -0J -b0 K -0L -0M -0N -0O -b0 P -0Q -0R -0S -0T -b0 U -0V -0W -0X -0Y -b0 Z -0[ -0\ -0] -0^ -b0 _ -0` -0a -0b -0c -b0 d -0e -0f -0g -0h -b0 i -0j -0k -0l -b0 m -0n -0o -0p -0q -b0 r -0s -0t -0u -b0 v -0w -0x -0y -0z -b0 { -0| -0} -0~ -b0 !" -0"" -0#" -0$" -0%" -b0 &" -0'" -0(" -0)" -b0 *" -0+" -0," -0-" -0." -b0 /" -00" -01" -02" -b0 3" -04" -05" -06" -07" -b0 8" -09" -0:" -0;" -b0 <" -0=" -0>" -0?" -0@" -b0 A" -0B" -0C" -0D" -b0 E" -0F" -0G" -0H" -0I" -b0 J" -0K" -0L" -0M" -b0 N" -0O" -0P" -0Q" -0R" -$end -#1000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#2000000 -1" -0# -1& -0' -1( -1* -0+ -1. -0/ -10 -12 -03 -16 -07 -18 -1: -0; -1> -0? -1@ -1B -0C -1D -1E -1G -0H -1I -1J -1L -0M -1N -1O -1Q -0R -1S -1T -1V -0W -1X -1Y -1[ -0\ -1] -1^ -1` -0a -1b -1c -1e -0f -1g -1h -1j -0k -1n -0o -1p -1q -1s -0t -1u -1w -0x -1y -1z -1| -0} -1"" -0#" -1$" -1%" -1'" -0(" -1)" -1+" -0," -1-" -1." -10" -01" -14" -05" -16" -17" -19" -0:" -1;" -1=" -0>" -1?" -1@" -1B" -0C" -1F" -0G" -1H" -1I" -1K" -0L" -1M" -1O" -0P" -1Q" -1R" -#3000000 -1S" -1c" -1s" -1%# -15# -1E# -1U# -1e# -1# -1$ -1' -1+ -1, -1/ -13 -14 -17 -1; -1< -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1l -1o -1t -1x -1} -1~ -1#" -1(" -1," -11" -12" -15" -1:" -1>" -1C" -1D" -1G" -1L" -1P" -#4000000 -0# -0' -0+ -0/ -03 -07 -0; -0? -0C -0D -0H -0I -0M -0N -0R -0S -0W -0X -0\ -0] -0a -0b -0f -0g -0k -0o -0p -0t -0x -0y -0} -0#" -0$" -0(" -0," -0-" -01" -05" -06" -0:" -0>" -0?" -0C" -0G" -0H" -0L" -0P" -0Q" -#5000000 -0S" -0c" -0s" -0%# -05# -0E# -0U# -0e# -1# -0$ -1' -0( -1+ -0, -1/ -00 -13 -04 -17 -08 -1; -0< -1? -0@ -1C -1H -1M -1R -1W -1\ -1a -1f -1k -0l -1o -1t -0u -1x -1} -0~ -1#" -1(" -0)" -1," -11" -02" -15" -1:" -0;" -1>" -1C" -0D" -1G" -1L" -0M" -1P" -#6000000 -0# -0' -0+ -0/ -03 -07 -0; -0? -0B -0C -0G -0H -0L -0M -0Q -0R -0V -0W -0[ -0\ -0` -0a -0e -0f -0k -0n -0o -0t -0w -0x -0} -0"" -0#" -0(" -0+" -0," -01" -04" -05" -0:" -0=" -0>" -0C" -0F" -0G" -0L" -0O" -0P" -#7000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#8000000 -b1 ! -0# -b1 % -0' -b1 ) -0+ -b1 - -0/ -10 -b1 1 -03 -b1 5 -07 -b1 9 -0; -b1 = -0? -1@ -0C -0H -0M -0R -0W -0\ -0a -0f -b1 i -0k -0o -b1 r -0t -0x -b1 { -0} -0#" -b1 &" -0(" -1)" -0," -b1 /" -01" -05" -b1 8" -0:" -0>" -b1 A" -0C" -0G" -b1 J" -0L" -1M" -0P" -#9000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#10000000 -b10 ! -0# -b10 % -0' -b10 ) -0+ -b10 - -0/ -00 -b10 1 -03 -b10 5 -07 -18 -b10 9 -0; -b10 = -0? -0C -0H -0M -0R -0W -0\ -0a -0f -b10 i -0k -0o -b10 r -0t -0x -b10 { -0} -0#" -b10 &" -0(" -0)" -0," -b10 /" -01" -05" -b10 8" -0:" -1;" -0>" -b10 A" -0C" -0G" -b10 J" -0L" -0P" -#11000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#12000000 -b11 ! -0# -b11 % -0' -b11 ) -0+ -b11 - -0/ -b11 1 -03 -b11 5 -07 -08 -b11 9 -0; -b11 = -0? -0@ -0C -0H -0M -0R -0W -0\ -0a -0f -b11 i -0k -0o -b11 r -0t -0x -b11 { -0} -0#" -b11 &" -0(" -0," -b11 /" -01" -05" -b11 8" -0:" -0;" -0>" -b11 A" -0C" -0G" -b11 J" -0L" -0M" -0P" -#13000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#14000000 -b100 ! -0# -b100 % -0' -b100 ) -0+ -b100 - -0/ -10 -b100 1 -03 -b100 5 -07 -18 -b100 9 -0; -b100 = -0? -0C -0H -0M -0R -0W -0\ -0a -0f -b100 i -0k -0o -b100 r -0t -0x -b100 { -0} -0#" -b100 &" -0(" -1)" -0," -b100 /" -01" -05" -b100 8" -0:" -1;" -0>" -b100 A" -0C" -0G" -b100 J" -0L" -0P" -#15000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#16000000 -b101 ! -0# -b101 % -0' -b101 ) -0+ -1, -b101 - -0/ -b101 1 -03 -b101 5 -07 -b101 9 -0; -1< -b101 = -0? -1@ -0C -0H -0M -0R -0W -0\ -0a -0f -b101 i -0k -0o -b101 r -0t -0x -b101 { -0} -1~ -0#" -b101 &" -0(" -0," -b101 /" -01" -05" -b101 8" -0:" -0>" -b101 A" -0C" -1D" -0G" -b101 J" -0L" -1M" -0P" -#17000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#18000000 -b110 ! -0# -b110 % -0' -b110 ) -0+ -0, -b110 - -0/ -b110 1 -03 -b110 5 -07 -08 -b110 9 -0; -b110 = -0? -0@ -0C -0H -0M -0R -0W -0\ -0a -0f -b110 i -0k -0o -b110 r -0t -0x -b110 { -0} -0~ -0#" -b110 &" -0(" -0," -b110 /" -01" -05" -b110 8" -0:" -0;" -0>" -b110 A" -0C" -0G" -b110 J" -0L" -0M" -0P" -#19000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#20000000 -b111 ! -0# -b111 % -0' -b111 ) -0+ -b111 - -0/ -b111 1 -03 -b111 5 -07 -b111 9 -0; -0< -b111 = -0? -1@ -0C -0H -0M -0R -0W -0\ -0a -0f -b111 i -0k -0o -b111 r -0t -0x -b111 { -0} -0#" -b111 &" -0(" -0," -b111 /" -01" -05" -b111 8" -0:" -0>" -b111 A" -0C" -0D" -0G" -b111 J" -0L" -1M" -0P" -#21000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#22000000 -b1000 ! -0# -b1000 % -0' -b1000 ) -0+ -b1000 - -0/ -00 -b1000 1 -03 -b1000 5 -07 -b1000 9 -0; -b1000 = -0? -0C -0H -0M -0R -0W -0\ -0a -0f -b1000 i -0k -0o -b1000 r -0t -0x -b1000 { -0} -0#" -b1000 &" -0(" -0)" -0," -b1000 /" -01" -05" -b1000 8" -0:" -0>" -b1000 A" -0C" -0G" -b1000 J" -0L" -0P" -#23000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#24000000 -b1001 ! -0# -b1001 % -0' -b1001 ) -0+ -b1001 - -0/ -b1001 1 -03 -b1001 5 -07 -b1001 9 -0; -1< -b1001 = -0? -0@ -0C -0H -0M -0R -0W -0\ -0a -0f -b1001 i -0k -0o -b1001 r -0t -0x -b1001 { -0} -0#" -b1001 &" -0(" -0," -b1001 /" -01" -05" -b1001 8" -0:" -0>" -b1001 A" -0C" -1D" -0G" -b1001 J" -0L" -0M" -0P" -#25000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#26000000 -b1010 ! -0# -b1010 % -0' -b1010 ) -0+ -b1010 - -0/ -b1010 1 -03 -14 -b1010 5 -07 -18 -b1010 9 -0; -b1010 = -0? -0C -0H -0M -0R -0W -0\ -0a -0f -b1010 i -0k -0o -b1010 r -0t -0x -b1010 { -0} -0#" -b1010 &" -0(" -0," -b1010 /" -01" -12" -05" -b1010 8" -0:" -1;" -0>" -b1010 A" -0C" -0G" -b1010 J" -0L" -0P" -#27000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#28000000 -b1011 ! -0# -b1011 % -0' -b1011 ) -0+ -b1011 - -0/ -b1011 1 -03 -04 -b1011 5 -07 -b1011 9 -0; -b1011 = -0? -0C -0H -0M -0R -0W -0\ -0a -0f -b1011 i -0k -0o -b1011 r -0t -0x -b1011 { -0} -0#" -b1011 &" -0(" -0," -b1011 /" -01" -02" -05" -b1011 8" -0:" -0>" -b1011 A" -0C" -0G" -b1011 J" -0L" -0P" -#29000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#30000000 -b1100 ! -0# -b1100 % -0' -b1100 ) -0+ -b1100 - -0/ -b1100 1 -03 -b1100 5 -07 -08 -b1100 9 -0; -b1100 = -0? -0C -0H -0M -0R -0W -0\ -0a -0f -b1100 i -0k -0o -b1100 r -0t -0x -b1100 { -0} -0#" -b1100 &" -0(" -0," -b1100 /" -01" -05" -b1100 8" -0:" -0;" -0>" -b1100 A" -0C" -0G" -b1100 J" -0L" -0P" -#31000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#32000000 -b1101 ! -0# -b1101 % -0' -b1101 ) -0+ -b1101 - -0/ -b1101 1 -03 -b1101 5 -07 -b1101 9 -0; -0< -b1101 = -0? -0C -0H -0M -0R -0W -0\ -0a -0f -b1101 i -0k -0o -b1101 r -0t -0x -b1101 { -0} -0#" -b1101 &" -0(" -0," -b1101 /" -01" -05" -b1101 8" -0:" -0>" -b1101 A" -0C" -0D" -0G" -b1101 J" -0L" -0P" -#33000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#34000000 -b1110 ! -0# -b1110 % -0' -b1110 ) -0+ -b1110 - -0/ -b1110 1 -03 -b1110 5 -07 -b1110 9 -0; -b1110 = -0? -1@ -0C -0H -0M -0R -0W -0\ -0a -0f -b1110 i -0k -0o -b1110 r -0t -0x -b1110 { -0} -0#" -b1110 &" -0(" -0," -b1110 /" -01" -05" -b1110 8" -0:" -0>" -b1110 A" -0C" -0G" -b1110 J" -0L" -1M" -0P" -#35000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#36000000 -b1111 ! -0# -b1111 % -0' -b1111 ) -0+ -b1111 - -0/ -b1111 1 -03 -b1111 5 -07 -b1111 9 -0; -b1111 = -0? -0@ -0C -0H -0M -0R -0W -0\ -0a -0f -b1111 i -0k -0o -b1111 r -0t -0x -b1111 { -0} -0#" -b1111 &" -0(" -0," -b1111 /" -01" -05" -b1111 8" -0:" -0>" -b1111 A" -0C" -0G" -b1111 J" -0L" -0M" -0P" -#37000000 -1# -1' -1+ -1/ -13 -17 -1; -1? -1C -1H -1M -1R -1W -1\ -1a -1f -1k -1o -1t -1x -1} -1#" -1(" -1," -11" -15" -1:" -1>" -1C" -1G" -1L" -1P" -#38000000 -0# -0' -0+ -0/ -03 -07 -0; -0? -0C -0H -0M -0R -0W -0\ -0a -0f -0k -0o -0t -0x -0} -0#" -0(" -0," -01" -05" -0:" -0>" -0C" -0G" -0L" -0P" diff --git a/crates/fayalite/tests/sim/expected/memories.txt b/crates/fayalite/tests/sim/expected/memories.txt index 0358bb3..f7f88e3 100644 --- a/crates/fayalite/tests/sim/expected/memories.txt +++ b/crates/fayalite/tests/sim/expected/memories.txt @@ -719,9 +719,9 @@ Simulation { }.w.mask.1, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "memories", children: [ @@ -1616,15 +1616,10 @@ Simulation { }, ), ], + instant: 22 μs, clocks_triggered: [ StatePartIndex(1), StatePartIndex(6), ], - event_queue: EventQueue(EventQueueData { - instant: 22 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/memories.vcd b/crates/fayalite/tests/sim/expected/memories.vcd index d8f5817..bedc354 100644 --- a/crates/fayalite/tests/sim/expected/memories.vcd +++ b/crates/fayalite/tests/sim/expected/memories.vcd @@ -234,13 +234,13 @@ b100000 6 b10000 9 b100000 I 1# -b10000 $ -b100000 % 1( 1/ +14 +b10000 $ +b100000 % b10000 0 b100000 1 -14 #4000000 0# 0( @@ -256,11 +256,11 @@ b1000000 6 b10000 9 b1000000 I 1# -b1000000 % 1( 1/ -b1000000 1 14 +b1000000 % +b1000000 1 #6000000 0# 0( @@ -278,11 +278,11 @@ b1100000 6 b1010000 9 b1000000 I 1# -b1010000 $ 1( 1/ -b1010000 0 14 +b1010000 $ +b1010000 0 #8000000 0# 0( diff --git a/crates/fayalite/tests/sim/expected/memories2.txt b/crates/fayalite/tests/sim/expected/memories2.txt index b4041ba..c216104 100644 --- a/crates/fayalite/tests/sim/expected/memories2.txt +++ b/crates/fayalite/tests/sim/expected/memories2.txt @@ -677,9 +677,9 @@ Simulation { }.rw.wmode, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "memories2", children: [ @@ -1260,14 +1260,9 @@ Simulation { }, ), ], + instant: 22 μs, clocks_triggered: [ StatePartIndex(3), ], - event_queue: EventQueue(EventQueueData { - instant: 22 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/memories2.vcd b/crates/fayalite/tests/sim/expected/memories2.vcd index 0ac20f1..4039754 100644 --- a/crates/fayalite/tests/sim/expected/memories2.vcd +++ b/crates/fayalite/tests/sim/expected/memories2.vcd @@ -100,8 +100,8 @@ $end 1) #1250000 1# -b11 $ 1* +b11 $ sHdlSome\x20(1) + 1, #1500000 @@ -113,8 +113,8 @@ sHdlSome\x20(1) + 0) #2250000 1# -b0 $ 1* +b0 $ sHdlNone\x20(0) + 0, #2500000 @@ -303,8 +303,8 @@ b11 ! b11 ( #17250000 1# -b11 $ 1* +b11 $ sHdlSome\x20(1) + 1, #17500000 @@ -316,8 +316,8 @@ b10 ! b10 ( #18250000 1# -b0 $ 1* +b0 $ sHdlNone\x20(0) + 0, #18500000 @@ -339,8 +339,8 @@ b1 ! b1 ( #20250000 1# -b1 $ 1* +b1 $ sHdlSome\x20(1) + #20500000 #20750000 @@ -353,8 +353,8 @@ b0 ( 0) #21250000 1# -b0 $ 1* +b0 $ sHdlNone\x20(0) + #21500000 #21750000 diff --git a/crates/fayalite/tests/sim/expected/memories3.txt b/crates/fayalite/tests/sim/expected/memories3.txt index 2213912..8114c7e 100644 --- a/crates/fayalite/tests/sim/expected/memories3.txt +++ b/crates/fayalite/tests/sim/expected/memories3.txt @@ -1761,9 +1761,9 @@ Simulation { }.w.mask[7], }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "memories3", children: [ @@ -3275,15 +3275,10 @@ Simulation { }, ), ], + instant: 15 μs, clocks_triggered: [ StatePartIndex(1), StatePartIndex(6), ], - event_queue: EventQueue(EventQueueData { - instant: 15 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/memories3.vcd b/crates/fayalite/tests/sim/expected/memories3.vcd index 32ee75e..5768560 100644 --- a/crates/fayalite/tests/sim/expected/memories3.vcd +++ b/crates/fayalite/tests/sim/expected/memories3.vcd @@ -420,10 +420,6 @@ b10000 T 1\ #3250000 1# -b110100 % -b1111000 ' -b10011010 ( -b11110000 + 1. 1A b110100 C @@ -431,6 +427,10 @@ b1111000 E b10011010 F b11110000 I 1L +b110100 % +b1111000 ' +b10011010 ( +b11110000 + #3500000 #3750000 0# @@ -508,14 +508,6 @@ b1010100 '" b110010 /" b10000 7" 1# -b11111110 $ -b11011100 % -b10111010 & -b10011000 ' -b1110110 ( -b1010100 ) -b110010 * -b10000 + 1. 1A b11111110 B @@ -527,6 +519,14 @@ b1010100 G b110010 H b10000 I 1L +b11111110 $ +b11011100 % +b10111010 & +b10011000 ' +b1110110 ( +b1010100 ) +b110010 * +b10000 + #6500000 #6750000 0# @@ -562,14 +562,6 @@ b1000110 (" b10001010 0" b11001110 8" 1# -b0 $ -b0 % -b0 & -b0 ' -b0 ( -b0 ) -b0 * -b0 + 1. 1A b0 B @@ -581,6 +573,14 @@ b0 G b0 H b0 I 1L +b0 $ +b0 % +b0 & +b0 ' +b0 ( +b0 ) +b0 * +b0 + #7500000 #7750000 0# @@ -688,14 +688,6 @@ b1 ! b1 ? #10250000 1# -b11111110 $ -b11011100 % -b10111010 & -b10011000 ' -b1110110 ( -b1010100 ) -b110010 * -b10000 + 1. 1A b11111110 B @@ -707,6 +699,14 @@ b1010100 G b110010 H b10000 I 1L +b11111110 $ +b11011100 % +b10111010 & +b10011000 ' +b1110110 ( +b1010100 ) +b110010 * +b10000 + #10500000 #10750000 0# @@ -718,14 +718,6 @@ b10 ! b10 ? #11250000 1# -b10011 $ -b1010111 % -b10011011 & -b11011111 ' -b10 ( -b1000110 ) -b10001010 * -b11001110 + 1. 1A b10011 B @@ -737,6 +729,14 @@ b1000110 G b10001010 H b11001110 I 1L +b10011 $ +b1010111 % +b10011011 & +b11011111 ' +b10 ( +b1000110 ) +b10001010 * +b11001110 + #11500000 #11750000 0# @@ -748,14 +748,6 @@ b11 ! b11 ? #12250000 1# -b1110100 $ -b1100101 % -b1110011 & -b1110100 ' -b1101001 ( -b1101110 ) -b1100111 * -b100001 + 1. 1A b1110100 B @@ -767,6 +759,14 @@ b1101110 G b1100111 H b100001 I 1L +b1110100 $ +b1100101 % +b1110011 & +b1110100 ' +b1101001 ( +b1101110 ) +b1100111 * +b100001 + #12500000 #12750000 0# @@ -780,14 +780,6 @@ b0 ? 0@ #13250000 1# -b1101101 $ -b1101111 % -b1110010 & -b1100101 ' -b100000 ( -b1110100 ) -b1110011 * -b1110100 + 1. 1A b1101101 B @@ -799,6 +791,14 @@ b1110100 G b1110011 H b1110100 I 1L +b1101101 $ +b1101111 % +b1110010 & +b1100101 ' +b100000 ( +b1110100 ) +b1110011 * +b1110100 + #13500000 #13750000 0# @@ -808,14 +808,6 @@ b1110100 I #14000000 #14250000 1# -b0 $ -b0 % -b0 & -b0 ' -b0 ( -b0 ) -b0 * -b0 + 1. 1A b0 B @@ -827,6 +819,14 @@ b0 G b0 H b0 I 1L +b0 $ +b0 % +b0 & +b0 ' +b0 ( +b0 ) +b0 * +b0 + #14500000 #14750000 0# diff --git a/crates/fayalite/tests/sim/expected/mod1.txt b/crates/fayalite/tests/sim/expected/mod1.txt index 3f7a55e..4ef02b2 100644 --- a/crates/fayalite/tests/sim/expected/mod1.txt +++ b/crates/fayalite/tests/sim/expected/mod1.txt @@ -274,9 +274,9 @@ Simulation { }.o.o2, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "mod1", children: [ @@ -558,12 +558,7 @@ Simulation { }, ), ], + instant: 2 μs, clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 2 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/phantom_const.txt b/crates/fayalite/tests/sim/expected/phantom_const.txt deleted file mode 100644 index 94072ac..0000000 --- a/crates/fayalite/tests/sim/expected/phantom_const.txt +++ /dev/null @@ -1,525 +0,0 @@ -Simulation { - state: State { - insns: Insns { - state_layout: StateLayout { - ty: TypeLayout { - small_slots: StatePartLayout { - len: 5, - debug_data: [ - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - SlotDebugData { - name: "", - ty: UInt<0>, - }, - ], - .. - }, - big_slots: StatePartLayout { - len: 8, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.addr", - ty: UInt<0>, - }, - SlotDebugData { - name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.en", - ty: Bool, - }, - SlotDebugData { - name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.clk", - ty: Clock, - }, - SlotDebugData { - name: "", - ty: UInt<8>, - }, - SlotDebugData { - name: "", - ty: UInt<0>, - }, - SlotDebugData { - name: "", - ty: UInt<1>, - }, - SlotDebugData { - name: "", - ty: Clock, - }, - SlotDebugData { - name: "", - ty: Bool, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 1, - debug_data: [ - (), - ], - layout_data: [ - MemoryData { - array_type: Array, - data: [ - // len = 0x1 - [0x0]: 0x0, - ], - }, - ], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Const { - dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "", ty: Bool }, - value: 0x0, - }, - // at: module-XXXXXXXXXX.rs:7:1 - 1: Copy { - dest: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.en", ty: Bool }, - src: StatePartIndex(7), // (0x0) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 2: Const { - dest: StatePartIndex(5), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - value: 0x0, - }, - 3: Copy { - dest: StatePartIndex(6), // (0x0) SlotDebugData { name: "", ty: Clock }, - src: StatePartIndex(5), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, - }, - // at: module-XXXXXXXXXX.rs:6:1 - 4: Copy { - dest: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.clk", ty: Clock }, - src: StatePartIndex(6), // (0x0) SlotDebugData { name: "", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 5: Const { - dest: StatePartIndex(3), // (0x0) SlotDebugData { name: "", ty: UInt<8> }, - value: 0x0, - }, - 6: CastToUInt { - dest: StatePartIndex(4), // (0x0) SlotDebugData { name: "", ty: UInt<0> }, - src: StatePartIndex(3), // (0x0) SlotDebugData { name: "", ty: UInt<8> }, - dest_width: 0, - }, - // at: module-XXXXXXXXXX.rs:5:1 - 7: Copy { - dest: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.addr", ty: UInt<0> }, - src: StatePartIndex(4), // (0x0) SlotDebugData { name: "", ty: UInt<0> }, - }, - // at: module-XXXXXXXXXX.rs:3:1 - 8: CastBigToArrayIndex { - dest: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<0> }, - src: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.addr", ty: UInt<0> }, - }, - 9: IsNonZeroDestIsSmall { - dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.en", ty: Bool }, - }, - 10: BranchIfSmallZero { - target: 12, - value: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 11: Branch { - target: 12, - }, - 12: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(phantom_const: phantom_const).phantom_const::mem::r0.clk", ty: Clock }, - }, - 13: AndSmall { - dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 14: BranchIfSmallZero { - target: 15, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 15: XorSmallImmediate { - dest: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - // at: module-XXXXXXXXXX.rs:1:1 - 16: Return, - ], - .. - }, - pc: 16, - memory_write_log: [], - memories: StatePart { - value: [ - MemoryData { - array_type: Array, - data: [ - // len = 0x1 - [0x0]: 0x0, - ], - }, - ], - }, - small_slots: StatePart { - value: [ - 1, - 0, - 0, - 0, - 0, - ], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::phantom_const, - instantiated: Module { - name: phantom_const, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::phantom_const, - instantiated: Module { - name: phantom_const, - .. - }, - }.out, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::phantom_const, - instantiated: Module { - name: phantom_const, - .. - }, - }.out, - Instance { - name: ::phantom_const, - instantiated: Module { - name: phantom_const, - .. - }, - }.out[0], - Instance { - name: ::phantom_const, - instantiated: Module { - name: phantom_const, - .. - }, - }.out[1], - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [], - trace_decls: TraceModule { - name: "phantom_const", - children: [ - TraceModuleIO { - name: "out", - child: TraceArray { - name: "out", - elements: [ - TracePhantomConst { - location: TraceScalarId(0), - name: "[0]", - ty: PhantomConst( - ["a","b"], - ), - flow: Sink, - }, - TracePhantomConst { - location: TraceScalarId(1), - name: "[1]", - ty: PhantomConst( - ["a","b"], - ), - flow: Sink, - }, - ], - ty: Array, - flow: Sink, - }, - ty: Array, - flow: Sink, - }, - TraceMem { - id: TraceMemoryId(0), - name: "mem", - stride: 0, - element_type: TracePhantomConst { - location: TraceMemoryLocation { - id: TraceMemoryId(0), - depth: 1, - stride: 0, - start: 0, - len: 0, - }, - name: "mem", - ty: PhantomConst( - "mem_element", - ), - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(2), - name: "addr", - ty: UInt<0>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(3), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(4), - name: "clk", - flow: Sink, - }, - TracePhantomConst { - location: TraceScalarId(5), - name: "data", - ty: PhantomConst( - "mem_element", - ), - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<0>, - /* offset = 0 */ - en: Bool, - /* offset = 1 */ - clk: Clock, - #[hdl(flip)] /* offset = 2 */ - data: PhantomConst( - "mem_element", - ), - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<0>, - /* offset = 0 */ - en: Bool, - /* offset = 1 */ - clk: Clock, - #[hdl(flip)] /* offset = 2 */ - data: PhantomConst( - "mem_element", - ), - }, - }, - ], - array_type: Array, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: PhantomConst { - ty: PhantomConst( - ["a","b"], - ), - }, - state: PhantomConst, - last_state: PhantomConst, - }, - SimTrace { - id: TraceScalarId(1), - kind: PhantomConst { - ty: PhantomConst( - ["a","b"], - ), - }, - state: PhantomConst, - last_state: PhantomConst, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigUInt { - index: StatePartIndex(0), - ty: UInt<0>, - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(3), - kind: BigBool { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(4), - kind: BigClock { - index: StatePartIndex(2), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(5), - kind: PhantomConst { - ty: PhantomConst( - "mem_element", - ), - }, - state: PhantomConst, - last_state: PhantomConst, - }, - ], - trace_memories: { - StatePartIndex(0): TraceMem { - id: TraceMemoryId(0), - name: "mem", - stride: 0, - element_type: TracePhantomConst { - location: TraceMemoryLocation { - id: TraceMemoryId(0), - depth: 1, - stride: 0, - start: 0, - len: 0, - }, - name: "mem", - ty: PhantomConst( - "mem_element", - ), - flow: Duplex, - }, - ports: [ - TraceMemPort { - name: "r0", - bundle: TraceBundle { - name: "r0", - fields: [ - TraceUInt { - location: TraceScalarId(2), - name: "addr", - ty: UInt<0>, - flow: Sink, - }, - TraceBool { - location: TraceScalarId(3), - name: "en", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(4), - name: "clk", - flow: Sink, - }, - TracePhantomConst { - location: TraceScalarId(5), - name: "data", - ty: PhantomConst( - "mem_element", - ), - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - addr: UInt<0>, - /* offset = 0 */ - en: Bool, - /* offset = 1 */ - clk: Clock, - #[hdl(flip)] /* offset = 2 */ - data: PhantomConst( - "mem_element", - ), - }, - flow: Sink, - }, - ty: Bundle { - /* offset = 0 */ - addr: UInt<0>, - /* offset = 0 */ - en: Bool, - /* offset = 1 */ - clk: Clock, - #[hdl(flip)] /* offset = 2 */ - data: PhantomConst( - "mem_element", - ), - }, - }, - ], - array_type: Array, - }, - }, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [ - StatePartIndex(1), - ], - event_queue: EventQueue(EventQueueData { - instant: 1 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/phantom_const.vcd b/crates/fayalite/tests/sim/expected/phantom_const.vcd deleted file mode 100644 index ba3869b..0000000 --- a/crates/fayalite/tests/sim/expected/phantom_const.vcd +++ /dev/null @@ -1,31 +0,0 @@ -$timescale 1 ps $end -$scope module phantom_const $end -$scope struct out $end -$var string 1 ! \[0] $end -$var string 1 " \[1] $end -$upscope $end -$scope struct mem $end -$scope struct contents $end -$scope struct \[0] $end -$var string 1 ' mem $end -$upscope $end -$upscope $end -$scope struct r0 $end -$var string 0 # addr $end -$var wire 1 $ en $end -$var wire 1 % clk $end -$var string 1 & data $end -$upscope $end -$upscope $end -$upscope $end -$enddefinitions $end -$dumpvars -s0 ' -sPhantomConst([\"a\",\"b\"]) ! -sPhantomConst([\"a\",\"b\"]) " -s0 # -0$ -0% -sPhantomConst(\"mem_element\") & -$end -#1000000 diff --git a/crates/fayalite/tests/sim/expected/ripple_counter.txt b/crates/fayalite/tests/sim/expected/ripple_counter.txt index 9cc5f02..9e4e0d1 100644 --- a/crates/fayalite/tests/sim/expected/ripple_counter.txt +++ b/crates/fayalite/tests/sim/expected/ripple_counter.txt @@ -162,7 +162,7 @@ Simulation { }, SlotDebugData { name: "", - ty: UInt<1>, + ty: Bool, }, SlotDebugData { name: "", @@ -429,12 +429,12 @@ Simulation { }, // at: module-XXXXXXXXXX.rs:1:1 26: Const { - dest: StatePartIndex(28), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + 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: UInt<1> }, + src: StatePartIndex(28), // (0x0) SlotDebugData { name: "", ty: Bool }, }, 28: Copy { dest: StatePartIndex(26), // (0x1) SlotDebugData { name: ".clk", ty: Clock }, @@ -743,7 +743,6 @@ Simulation { }.o, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [ SimulationExternModuleState { @@ -778,7 +777,6 @@ Simulation { }, }, did_initial_settle: true, - clocks_for_past: {}, }, sim: ExternModuleSimulation { generator: SimGeneratorFn { @@ -829,6 +827,52 @@ Simulation { 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, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 3, len: 0 }, + big_slots: StatePartIndexRange { start: 33, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + write: None, + }, + value: SimValue { + ty: Clock, + value: OpaqueSimValue { + bits: 0x0_u1, + sim_only_values: [], + }, + }, + }, + }, }, SimulationExternModuleState { module_state: SimulationModuleState { @@ -862,7 +906,6 @@ Simulation { }, }, did_initial_settle: true, - clocks_for_past: {}, }, sim: ExternModuleSimulation { generator: SimGeneratorFn { @@ -913,6 +956,52 @@ Simulation { 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, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 6, len: 0 }, + big_slots: StatePartIndexRange { start: 44, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + write: None, + }, + value: SimValue { + ty: Clock, + value: OpaqueSimValue { + bits: 0x0_u1, + sim_only_values: [], + }, + }, + }, + }, }, SimulationExternModuleState { module_state: SimulationModuleState { @@ -946,7 +1035,6 @@ Simulation { }, }, did_initial_settle: true, - clocks_for_past: {}, }, sim: ExternModuleSimulation { generator: SimGeneratorFn { @@ -997,8 +1085,55 @@ Simulation { 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, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 9, len: 0 }, + big_slots: StatePartIndexRange { start: 55, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, + }, + write: None, + }, + value: SimValue { + ty: Clock, + value: OpaqueSimValue { + bits: 0x0_u1, + sim_only_values: [], + }, + }, + }, + }, }, ], + state_ready_to_run: false, trace_decls: TraceModule { name: "ripple_counter", children: [ @@ -1458,315 +1593,11 @@ Simulation { }, ), ], + instant: 256 μs, clocks_triggered: [ StatePartIndex(1), StatePartIndex(4), StatePartIndex(7), ], - event_queue: EventQueue(EventQueueData { - instant: 256 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 152, - values: { - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 55, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - SensitivitySet { - id: 167, - values: { - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 44, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - SensitivitySet { - id: 170, - values: { - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 33, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 33, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 170, - .. - }, - }, - ), - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 44, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 167, - .. - }, - }, - ), - 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, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 55, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 152, - .. - }, - }, - ), - }, .. } \ 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 index 550205f..6f14a8e 100644 --- a/crates/fayalite/tests/sim/expected/ripple_counter.vcd +++ b/crates/fayalite/tests/sim/expected/ripple_counter.vcd @@ -66,1648 +66,1688 @@ b0 " $end #1000000 1! +1) b1 " 1# -1) 1* 1, -b111 " -1$ -1% 1+ +b11 " +1$ 1- 1. +b111 " +1% 1/ 11 -b11111 " -1& -1' 10 +b1111 " +1& 12 13 +b11111 " +1' 14 16 +15 b111111 " 1( -15 17 #2000000 0! #3000000 1! +0) b111110 " 0# -0) 0* 0, #4000000 0! #5000000 1! +1) b111111 " 1# -1) 1* 1, +0+ b111101 " 0$ -0+ 0- #6000000 0! #7000000 1! +0) b111100 " 0# -0) 0* 0, #8000000 0! #9000000 1! +1) b111101 " 1# -1) 1* 1, -b111011 " -1$ -0% 1+ +b111111 " +1$ 1- 0. +b111011 " +0% 0/ 01 #10000000 0! #11000000 1! +0) b111010 " 0# -0) 0* 0, #12000000 0! #13000000 1! +1) b111011 " 1# -1) 1* 1, +0+ b111001 " 0$ -0+ 0- #14000000 0! #15000000 1! +0) b111000 " 0# -0) 0* 0, #16000000 0! #17000000 1! +1) b111001 " 1# -1) 1* 1, -b111111 " -1$ -1% 1+ +b111011 " +1$ 1- 1. +b111111 " +1% 1/ 11 +00 b110111 " 0& -00 02 #18000000 0! #19000000 1! +0) b110110 " 0# -0) 0* 0, #20000000 0! #21000000 1! +1) b110111 " 1# -1) 1* 1, +0+ b110101 " 0$ -0+ 0- #22000000 0! #23000000 1! +0) b110100 " 0# -0) 0* 0, #24000000 0! #25000000 1! +1) b110101 " 1# -1) 1* 1, -b110011 " -1$ -0% 1+ +b110111 " +1$ 1- 0. +b110011 " +0% 0/ 01 #26000000 0! #27000000 1! +0) b110010 " 0# -0) 0* 0, #28000000 0! #29000000 1! +1) b110011 " 1# -1) 1* 1, +0+ b110001 " 0$ -0+ 0- #30000000 0! #31000000 1! +0) b110000 " 0# -0) 0* 0, #32000000 0! #33000000 1! +1) b110001 " 1# -1) 1* 1, -b110111 " -1$ -1% 1+ +b110011 " +1$ 1- 1. +b110111 " +1% 1/ 11 -b101111 " -1& -0' 10 +b111111 " +1& 12 03 +b101111 " +0' 04 06 #34000000 0! #35000000 1! +0) b101110 " 0# -0) 0* 0, #36000000 0! #37000000 1! +1) b101111 " 1# -1) 1* 1, +0+ b101101 " 0$ -0+ 0- #38000000 0! #39000000 1! +0) b101100 " 0# -0) 0* 0, #40000000 0! #41000000 1! +1) b101101 " 1# -1) 1* 1, -b101011 " -1$ -0% 1+ +b101111 " +1$ 1- 0. +b101011 " +0% 0/ 01 #42000000 0! #43000000 1! +0) b101010 " 0# -0) 0* 0, #44000000 0! #45000000 1! +1) b101011 " 1# -1) 1* 1, +0+ b101001 " 0$ -0+ 0- #46000000 0! #47000000 1! +0) b101000 " 0# -0) 0* 0, #48000000 0! #49000000 1! +1) b101001 " 1# -1) 1* 1, -b101111 " -1$ -1% 1+ +b101011 " +1$ 1- 1. +b101111 " +1% 1/ 11 +00 b100111 " 0& -00 02 #50000000 0! #51000000 1! +0) b100110 " 0# -0) 0* 0, #52000000 0! #53000000 1! +1) b100111 " 1# -1) 1* 1, +0+ b100101 " 0$ -0+ 0- #54000000 0! #55000000 1! +0) b100100 " 0# -0) 0* 0, #56000000 0! #57000000 1! +1) b100101 " 1# -1) 1* 1, -b100011 " -1$ -0% 1+ +b100111 " +1$ 1- 0. +b100011 " +0% 0/ 01 #58000000 0! #59000000 1! +0) b100010 " 0# -0) 0* 0, #60000000 0! #61000000 1! +1) b100011 " 1# -1) 1* 1, +0+ b100001 " 0$ -0+ 0- #62000000 0! #63000000 1! +0) b100000 " 0# -0) 0* 0, #64000000 0! #65000000 1! +1) b100001 " 1# -1) 1* 1, -b100111 " -1$ -1% 1+ +b100011 " +1$ 1- 1. +b100111 " +1% 1/ 11 -b111111 " -1& -1' 10 +b101111 " +1& 12 13 +b111111 " +1' 14 16 +05 b11111 " 0( -05 07 #66000000 0! #67000000 1! +0) b11110 " 0# -0) 0* 0, #68000000 0! #69000000 1! +1) b11111 " 1# -1) 1* 1, +0+ b11101 " 0$ -0+ 0- #70000000 0! #71000000 1! +0) b11100 " 0# -0) 0* 0, #72000000 0! #73000000 1! +1) b11101 " 1# -1) 1* 1, -b11011 " -1$ -0% 1+ +b11111 " +1$ 1- 0. +b11011 " +0% 0/ 01 #74000000 0! #75000000 1! +0) b11010 " 0# -0) 0* 0, #76000000 0! #77000000 1! +1) b11011 " 1# -1) 1* 1, +0+ b11001 " 0$ -0+ 0- #78000000 0! #79000000 1! +0) b11000 " 0# -0) 0* 0, #80000000 0! #81000000 1! +1) b11001 " 1# -1) 1* 1, -b11111 " -1$ -1% 1+ +b11011 " +1$ 1- 1. +b11111 " +1% 1/ 11 +00 b10111 " 0& -00 02 #82000000 0! #83000000 1! +0) b10110 " 0# -0) 0* 0, #84000000 0! #85000000 1! +1) b10111 " 1# -1) 1* 1, +0+ b10101 " 0$ -0+ 0- #86000000 0! #87000000 1! +0) b10100 " 0# -0) 0* 0, #88000000 0! #89000000 1! +1) b10101 " 1# -1) 1* 1, -b10011 " -1$ -0% 1+ +b10111 " +1$ 1- 0. +b10011 " +0% 0/ 01 #90000000 0! #91000000 1! +0) b10010 " 0# -0) 0* 0, #92000000 0! #93000000 1! +1) b10011 " 1# -1) 1* 1, +0+ b10001 " 0$ -0+ 0- #94000000 0! #95000000 1! +0) b10000 " 0# -0) 0* 0, #96000000 0! #97000000 1! +1) b10001 " 1# -1) 1* 1, -b10111 " -1$ -1% 1+ +b10011 " +1$ 1- 1. +b10111 " +1% 1/ 11 -b1111 " -1& -0' 10 +b11111 " +1& 12 03 +b1111 " +0' 04 06 #98000000 0! #99000000 1! +0) b1110 " 0# -0) 0* 0, #100000000 0! #101000000 1! +1) b1111 " 1# -1) 1* 1, +0+ b1101 " 0$ -0+ 0- #102000000 0! #103000000 1! +0) b1100 " 0# -0) 0* 0, #104000000 0! #105000000 1! +1) b1101 " 1# -1) 1* 1, -b1011 " -1$ -0% 1+ +b1111 " +1$ 1- 0. +b1011 " +0% 0/ 01 #106000000 0! #107000000 1! +0) b1010 " 0# -0) 0* 0, #108000000 0! #109000000 1! +1) b1011 " 1# -1) 1* 1, +0+ b1001 " 0$ -0+ 0- #110000000 0! #111000000 1! +0) b1000 " 0# -0) 0* 0, #112000000 0! #113000000 1! +1) b1001 " 1# -1) 1* 1, -b1111 " -1$ -1% 1+ +b1011 " +1$ 1- 1. +b1111 " +1% 1/ 11 +00 b111 " 0& -00 02 #114000000 0! #115000000 1! +0) b110 " 0# -0) 0* 0, #116000000 0! #117000000 1! +1) b111 " 1# -1) 1* 1, +0+ b101 " 0$ -0+ 0- #118000000 0! #119000000 1! +0) b100 " 0# -0) 0* 0, #120000000 0! #121000000 1! +1) b101 " 1# -1) 1* 1, -b11 " -1$ -0% 1+ +b111 " +1$ 1- 0. +b11 " +0% 0/ 01 #122000000 0! #123000000 1! +0) b10 " 0# -0) 0* 0, #124000000 0! #125000000 1! +1) b11 " 1# -1) 1* 1, +0+ b1 " 0$ -0+ 0- #126000000 0! #127000000 1! +0) b0 " 0# -0) 0* 0, #128000000 0! #129000000 1! +1) b1 " 1# -1) 1* 1, -b111 " -1$ -1% 1+ +b11 " +1$ 1- 1. +b111 " +1% 1/ 11 -b11111 " -1& -1' 10 +b1111 " +1& 12 13 +b11111 " +1' 14 16 +15 b111111 " 1( -15 17 #130000000 0! #131000000 1! +0) b111110 " 0# -0) 0* 0, #132000000 0! #133000000 1! +1) b111111 " 1# -1) 1* 1, +0+ b111101 " 0$ -0+ 0- #134000000 0! #135000000 1! +0) b111100 " 0# -0) 0* 0, #136000000 0! #137000000 1! +1) b111101 " 1# -1) 1* 1, -b111011 " -1$ -0% 1+ +b111111 " +1$ 1- 0. +b111011 " +0% 0/ 01 #138000000 0! #139000000 1! +0) b111010 " 0# -0) 0* 0, #140000000 0! #141000000 1! +1) b111011 " 1# -1) 1* 1, +0+ b111001 " 0$ -0+ 0- #142000000 0! #143000000 1! +0) b111000 " 0# -0) 0* 0, #144000000 0! #145000000 1! +1) b111001 " 1# -1) 1* 1, -b111111 " -1$ -1% 1+ +b111011 " +1$ 1- 1. +b111111 " +1% 1/ 11 +00 b110111 " 0& -00 02 #146000000 0! #147000000 1! +0) b110110 " 0# -0) 0* 0, #148000000 0! #149000000 1! +1) b110111 " 1# -1) 1* 1, +0+ b110101 " 0$ -0+ 0- #150000000 0! #151000000 1! +0) b110100 " 0# -0) 0* 0, #152000000 0! #153000000 1! +1) b110101 " 1# -1) 1* 1, -b110011 " -1$ -0% 1+ +b110111 " +1$ 1- 0. +b110011 " +0% 0/ 01 #154000000 0! #155000000 1! +0) b110010 " 0# -0) 0* 0, #156000000 0! #157000000 1! +1) b110011 " 1# -1) 1* 1, +0+ b110001 " 0$ -0+ 0- #158000000 0! #159000000 1! +0) b110000 " 0# -0) 0* 0, #160000000 0! #161000000 1! +1) b110001 " 1# -1) 1* 1, -b110111 " -1$ -1% 1+ +b110011 " +1$ 1- 1. +b110111 " +1% 1/ 11 -b101111 " -1& -0' 10 +b111111 " +1& 12 03 +b101111 " +0' 04 06 #162000000 0! #163000000 1! +0) b101110 " 0# -0) 0* 0, #164000000 0! #165000000 1! +1) b101111 " 1# -1) 1* 1, +0+ b101101 " 0$ -0+ 0- #166000000 0! #167000000 1! +0) b101100 " 0# -0) 0* 0, #168000000 0! #169000000 1! +1) b101101 " 1# -1) 1* 1, -b101011 " -1$ -0% 1+ +b101111 " +1$ 1- 0. +b101011 " +0% 0/ 01 #170000000 0! #171000000 1! +0) b101010 " 0# -0) 0* 0, #172000000 0! #173000000 1! +1) b101011 " 1# -1) 1* 1, +0+ b101001 " 0$ -0+ 0- #174000000 0! #175000000 1! +0) b101000 " 0# -0) 0* 0, #176000000 0! #177000000 1! +1) b101001 " 1# -1) 1* 1, -b101111 " -1$ -1% 1+ +b101011 " +1$ 1- 1. +b101111 " +1% 1/ 11 +00 b100111 " 0& -00 02 #178000000 0! #179000000 1! +0) b100110 " 0# -0) 0* 0, #180000000 0! #181000000 1! +1) b100111 " 1# -1) 1* 1, +0+ b100101 " 0$ -0+ 0- #182000000 0! #183000000 1! +0) b100100 " 0# -0) 0* 0, #184000000 0! #185000000 1! +1) b100101 " 1# -1) 1* 1, -b100011 " -1$ -0% 1+ +b100111 " +1$ 1- 0. +b100011 " +0% 0/ 01 #186000000 0! #187000000 1! +0) b100010 " 0# -0) 0* 0, #188000000 0! #189000000 1! +1) b100011 " 1# -1) 1* 1, +0+ b100001 " 0$ -0+ 0- #190000000 0! #191000000 1! +0) b100000 " 0# -0) 0* 0, #192000000 0! #193000000 1! +1) b100001 " 1# -1) 1* 1, -b100111 " -1$ -1% 1+ +b100011 " +1$ 1- 1. +b100111 " +1% 1/ 11 -b111111 " -1& -1' 10 +b101111 " +1& 12 13 +b111111 " +1' 14 16 +05 b11111 " 0( -05 07 #194000000 0! #195000000 1! +0) b11110 " 0# -0) 0* 0, #196000000 0! #197000000 1! +1) b11111 " 1# -1) 1* 1, +0+ b11101 " 0$ -0+ 0- #198000000 0! #199000000 1! +0) b11100 " 0# -0) 0* 0, #200000000 0! #201000000 1! +1) b11101 " 1# -1) 1* 1, -b11011 " -1$ -0% 1+ +b11111 " +1$ 1- 0. +b11011 " +0% 0/ 01 #202000000 0! #203000000 1! +0) b11010 " 0# -0) 0* 0, #204000000 0! #205000000 1! +1) b11011 " 1# -1) 1* 1, +0+ b11001 " 0$ -0+ 0- #206000000 0! #207000000 1! +0) b11000 " 0# -0) 0* 0, #208000000 0! #209000000 1! +1) b11001 " 1# -1) 1* 1, -b11111 " -1$ -1% 1+ +b11011 " +1$ 1- 1. +b11111 " +1% 1/ 11 +00 b10111 " 0& -00 02 #210000000 0! #211000000 1! +0) b10110 " 0# -0) 0* 0, #212000000 0! #213000000 1! +1) b10111 " 1# -1) 1* 1, +0+ b10101 " 0$ -0+ 0- #214000000 0! #215000000 1! +0) b10100 " 0# -0) 0* 0, #216000000 0! #217000000 1! +1) b10101 " 1# -1) 1* 1, -b10011 " -1$ -0% 1+ +b10111 " +1$ 1- 0. +b10011 " +0% 0/ 01 #218000000 0! #219000000 1! +0) b10010 " 0# -0) 0* 0, #220000000 0! #221000000 1! +1) b10011 " 1# -1) 1* 1, +0+ b10001 " 0$ -0+ 0- #222000000 0! #223000000 1! +0) b10000 " 0# -0) 0* 0, #224000000 0! #225000000 1! +1) b10001 " 1# -1) 1* 1, -b10111 " -1$ -1% 1+ +b10011 " +1$ 1- 1. +b10111 " +1% 1/ 11 -b1111 " -1& -0' 10 +b11111 " +1& 12 03 +b1111 " +0' 04 06 #226000000 0! #227000000 1! +0) b1110 " 0# -0) 0* 0, #228000000 0! #229000000 1! +1) b1111 " 1# -1) 1* 1, +0+ b1101 " 0$ -0+ 0- #230000000 0! #231000000 1! +0) b1100 " 0# -0) 0* 0, #232000000 0! #233000000 1! +1) b1101 " 1# -1) 1* 1, -b1011 " -1$ -0% 1+ +b1111 " +1$ 1- 0. +b1011 " +0% 0/ 01 #234000000 0! #235000000 1! +0) b1010 " 0# -0) 0* 0, #236000000 0! #237000000 1! +1) b1011 " 1# -1) 1* 1, +0+ b1001 " 0$ -0+ 0- #238000000 0! #239000000 1! +0) b1000 " 0# -0) 0* 0, #240000000 0! #241000000 1! +1) b1001 " 1# -1) 1* 1, -b1111 " -1$ -1% 1+ +b1011 " +1$ 1- 1. +b1111 " +1% 1/ 11 +00 b111 " 0& -00 02 #242000000 0! #243000000 1! +0) b110 " 0# -0) 0* 0, #244000000 0! #245000000 1! +1) b111 " 1# -1) 1* 1, +0+ b101 " 0$ -0+ 0- #246000000 0! #247000000 1! +0) b100 " 0# -0) 0* 0, #248000000 0! #249000000 1! +1) b101 " 1# -1) 1* 1, -b11 " -1$ -0% 1+ +b111 " +1$ 1- 0. +b11 " +0% 0/ 01 #250000000 0! #251000000 1! +0) b10 " 0# -0) 0* 0, #252000000 0! #253000000 1! +1) b11 " 1# -1) 1* 1, +0+ b1 " 0$ -0+ 0- #254000000 0! #255000000 1! +0) b0 " 0# -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 7dcf26c..9bab424 100644 --- a/crates/fayalite/tests/sim/expected/shift_register.txt +++ b/crates/fayalite/tests/sim/expected/shift_register.txt @@ -128,21 +128,21 @@ Simulation { dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.rst", ty: SyncReset }, }, - 6: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", ty: Clock }, - }, - 7: 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 - 8: Const { + 6: Const { dest: StatePartIndex(6), // (0x0) SlotDebugData { name: "", ty: Bool }, value: 0x0, }, // at: module-XXXXXXXXXX.rs:5:1 + 7: IsNonZeroDestIsSmall { + dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(shift_register: shift_register).shift_register::cd.clk", ty: Clock }, + }, + 8: 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 }, + }, 9: BranchIfSmallZero { target: 14, value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, @@ -337,9 +337,9 @@ Simulation { }.q, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [], + state_ready_to_run: false, trace_decls: TraceModule { name: "shift_register", children: [ @@ -440,7 +440,7 @@ Simulation { index: StatePartIndex(0), }, state: 0x1, - last_state: 0x0, + last_state: 0x1, }, SimTrace { id: TraceScalarId(1), @@ -509,14 +509,9 @@ Simulation { }, ), ], + instant: 66 μs, clocks_triggered: [ StatePartIndex(1), ], - event_queue: EventQueue(EventQueueData { - instant: 66 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: {}, - waiting_sensitivity_sets_by_compiled_value: {}, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/shift_register.vcd b/crates/fayalite/tests/sim/expected/shift_register.vcd index 26726eb..0b5f429 100644 --- a/crates/fayalite/tests/sim/expected/shift_register.vcd +++ b/crates/fayalite/tests/sim/expected/shift_register.vcd @@ -52,9 +52,9 @@ $end 0! #11000000 1! -1$ 0& 1( +1$ #12000000 0! 1# @@ -67,10 +67,10 @@ $end 0# #15000000 1! -0$ 0% 1& 0( +0$ #16000000 0! 1# @@ -83,23 +83,23 @@ $end 0! #19000000 1! -1$ 1& 0' 1( +1$ #20000000 0! #21000000 1! -0$ 1' 0( +0$ #22000000 0! #23000000 1! -1$ 1( +1$ #24000000 0! 0# @@ -120,8 +120,8 @@ $end 0! #31000000 1! -0$ 0( +0$ #32000000 0! #33000000 diff --git a/crates/fayalite/tests/sim/expected/sim_fork_join.txt b/crates/fayalite/tests/sim/expected/sim_fork_join.txt deleted file mode 100644 index 680fedb..0000000 --- a/crates/fayalite/tests/sim/expected/sim_fork_join.txt +++ /dev/null @@ -1,525 +0,0 @@ -Simulation { - state: State { - insns: Insns { - state_layout: StateLayout { - ty: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 6, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 0, - 49, - 50, - 50, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.clocks, - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.outputs, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.clocks, - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.clocks[0], - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.clocks[1], - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.clocks[2], - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.outputs, - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.outputs[0], - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.outputs[1], - Instance { - name: ::sim_fork_join, - instantiated: Module { - name: sim_fork_join, - .. - }, - }.outputs[2], - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }[0], - ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }[1], - ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }[2], - ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }[0], - ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }[1], - ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }[2], - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ), - f: ..., - }, - sim_io_to_generator_map: { - ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }: ModuleIO { - name: sim_fork_join::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }: ModuleIO { - name: sim_fork_join::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - }, - ], - trace_decls: TraceModule { - name: "sim_fork_join", - children: [ - TraceModuleIO { - name: "clocks", - child: TraceArray { - name: "clocks", - elements: [ - TraceClock { - location: TraceScalarId(0), - name: "[0]", - flow: Source, - }, - TraceClock { - location: TraceScalarId(1), - name: "[1]", - flow: Source, - }, - TraceClock { - location: TraceScalarId(2), - name: "[2]", - flow: Source, - }, - ], - ty: Array, - flow: Source, - }, - ty: Array, - flow: Source, - }, - TraceModuleIO { - name: "outputs", - child: TraceArray { - name: "outputs", - elements: [ - TraceUInt { - location: TraceScalarId(3), - name: "[0]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(4), - name: "[1]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(5), - name: "[2]", - ty: UInt<8>, - flow: Sink, - }, - ], - ty: Array, 3>, - flow: Sink, - }, - ty: Array, 3>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigClock { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigClock { - index: StatePartIndex(2), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(3), - kind: BigUInt { - index: StatePartIndex(3), - ty: UInt<8>, - }, - state: 0x31, - last_state: 0x31, - }, - SimTrace { - id: TraceScalarId(4), - kind: BigUInt { - index: StatePartIndex(4), - ty: UInt<8>, - }, - state: 0x32, - last_state: 0x32, - }, - SimTrace { - id: TraceScalarId(5), - kind: BigUInt { - index: StatePartIndex(5), - ty: UInt<8>, - }, - state: 0x32, - last_state: 0x32, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 648 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 198, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_fork_join: sim_fork_join).sim_fork_join::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 198, - .. - }, - }, - ), - }, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_fork_join.vcd b/crates/fayalite/tests/sim/expected/sim_fork_join.vcd deleted file mode 100644 index a420c2b..0000000 --- a/crates/fayalite/tests/sim/expected/sim_fork_join.vcd +++ /dev/null @@ -1,1467 +0,0 @@ -$timescale 1 ps $end -$scope module sim_fork_join $end -$scope struct clocks $end -$var wire 1 ! \[0] $end -$var wire 1 " \[1] $end -$var wire 1 # \[2] $end -$upscope $end -$scope struct outputs $end -$var wire 8 $ \[0] $end -$var wire 8 % \[1] $end -$var wire 8 & \[2] $end -$upscope $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -0" -0# -b0 $ -b0 % -b0 & -$end -#1000000 -1! -b1 $ -#2000000 -0! -#3000000 -1! -#4000000 -0! -#5000000 -1! -#6000000 -0! -#7000000 -1! -#8000000 -0! -#9000000 -1! -#10000000 -0! -#11000000 -1! -#12000000 -0! -#13000000 -1! -#14000000 -0! -#15000000 -1" -b1 % -#16000000 -0" -#17000000 -1! -#18000000 -0! -#19000000 -1! -#20000000 -0! -#21000000 -1! -#22000000 -0! -#23000000 -1# -b1 & -#24000000 -0# -#25000000 -1! -b10 $ -#26000000 -0! -#27000000 -1! -#28000000 -0! -#29000000 -1" -b10 % -#30000000 -0" -#31000000 -1! -#32000000 -0! -#33000000 -1! -#34000000 -0! -#35000000 -1! -#36000000 -0! -#37000000 -1" -#38000000 -0" -#39000000 -1" -#40000000 -0" -#41000000 -1! -#42000000 -0! -#43000000 -1! -#44000000 -0! -#45000000 -1" -#46000000 -0" -#47000000 -1# -b10 & -#48000000 -0# -#49000000 -1! -b11 $ -#50000000 -0! -#51000000 -1! -#52000000 -0! -#53000000 -1# -b11 & -#54000000 -0# -#55000000 -1! -#56000000 -0! -#57000000 -1! -#58000000 -0! -#59000000 -1! -#60000000 -0! -#61000000 -1# -#62000000 -0# -#63000000 -1" -b11 % -#64000000 -0" -#65000000 -1! -b100 $ -#66000000 -0! -#67000000 -1! -#68000000 -0! -#69000000 -1# -b100 & -#70000000 -0# -#71000000 -1# -#72000000 -0# -#73000000 -1! -#74000000 -0! -#75000000 -1" -b100 % -#76000000 -0" -#77000000 -1! -b101 $ -#78000000 -0! -#79000000 -1! -#80000000 -0! -#81000000 -1! -#82000000 -0! -#83000000 -1" -b101 % -#84000000 -0" -#85000000 -1! -#86000000 -0! -#87000000 -1" -#88000000 -0" -#89000000 -1! -#90000000 -0! -#91000000 -1" -#92000000 -0" -#93000000 -1! -#94000000 -0! -#95000000 -1# -b101 & -#96000000 -0# -#97000000 -1! -b110 $ -#98000000 -0! -#99000000 -1" -b110 % -#100000000 -0" -#101000000 -1" -#102000000 -0" -#103000000 -1! -#104000000 -0! -#105000000 -1! -#106000000 -0! -#107000000 -1" -#108000000 -0" -#109000000 -1" -#110000000 -0" -#111000000 -1" -#112000000 -0" -#113000000 -1! -#114000000 -0! -#115000000 -1" -#116000000 -0" -#117000000 -1" -#118000000 -0" -#119000000 -1# -b110 & -#120000000 -0# -#121000000 -1! -b111 $ -#122000000 -0! -#123000000 -1" -b111 % -#124000000 -0" -#125000000 -1# -b111 & -#126000000 -0# -#127000000 -1! -b1000 $ -#128000000 -0! -#129000000 -1! -#130000000 -0! -#131000000 -1" -b1000 % -#132000000 -0" -#133000000 -1# -b1000 & -#134000000 -0# -#135000000 -1" -b1001 % -#136000000 -0" -#137000000 -1! -b1001 $ -#138000000 -0! -#139000000 -1" -#140000000 -0" -#141000000 -1# -b1001 & -#142000000 -0# -#143000000 -1# -b1010 & -#144000000 -0# -#145000000 -1! -b1010 $ -#146000000 -0! -#147000000 -1# -#148000000 -0# -#149000000 -1! -#150000000 -0! -#151000000 -1! -#152000000 -0! -#153000000 -1! -#154000000 -0! -#155000000 -1# -#156000000 -0# -#157000000 -1! -#158000000 -0! -#159000000 -1" -b1010 % -#160000000 -0" -#161000000 -1! -b1011 $ -#162000000 -0! -#163000000 -1# -b1011 & -#164000000 -0# -#165000000 -1! -#166000000 -0! -#167000000 -1# -#168000000 -0# -#169000000 -1! -#170000000 -0! -#171000000 -1# -#172000000 -0# -#173000000 -1" -b1011 % -#174000000 -0" -#175000000 -1! -b1100 $ -#176000000 -0! -#177000000 -1! -#178000000 -0! -#179000000 -1# -b1100 & -#180000000 -0# -#181000000 -1" -b1100 % -#182000000 -0" -#183000000 -1" -b1101 % -#184000000 -0" -#185000000 -1! -b1101 $ -#186000000 -0! -#187000000 -1# -b1101 & -#188000000 -0# -#189000000 -1" -b1110 % -#190000000 -0" -#191000000 -1# -b1110 & -#192000000 -0# -#193000000 -1! -b1110 $ -#194000000 -0! -#195000000 -1# -b1111 & -#196000000 -0# -#197000000 -1# -#198000000 -0# -#199000000 -1! -b1111 $ -#200000000 -0! -#201000000 -1! -#202000000 -0! -#203000000 -1# -#204000000 -0# -#205000000 -1# -#206000000 -0# -#207000000 -1" -b1111 % -#208000000 -0" -#209000000 -1! -b10000 $ -#210000000 -0! -#211000000 -1# -b10000 & -#212000000 -0# -#213000000 -1# -#214000000 -0# -#215000000 -1# -#216000000 -0# -#217000000 -1" -b10000 % -#218000000 -0" -#219000000 -1! -b10001 $ -#220000000 -0! -#221000000 -1! -#222000000 -0! -#223000000 -1! -#224000000 -0! -#225000000 -1" -b10001 % -#226000000 -0" -#227000000 -1! -#228000000 -0! -#229000000 -1! -#230000000 -0! -#231000000 -1" -#232000000 -0" -#233000000 -1" -#234000000 -0" -#235000000 -1! -#236000000 -0! -#237000000 -1! -#238000000 -0! -#239000000 -1# -b10001 & -#240000000 -0# -#241000000 -1" -b10010 % -#242000000 -0" -#243000000 -1! -b10010 $ -#244000000 -0! -#245000000 -1" -#246000000 -0" -#247000000 -1! -#248000000 -0! -#249000000 -1" -#250000000 -0" -#251000000 -1! -#252000000 -0! -#253000000 -1" -#254000000 -0" -#255000000 -1" -#256000000 -0" -#257000000 -1" -#258000000 -0" -#259000000 -1! -#260000000 -0! -#261000000 -1" -#262000000 -0" -#263000000 -1# -b10010 & -#264000000 -0# -#265000000 -1" -b10011 % -#266000000 -0" -#267000000 -1! -b10011 $ -#268000000 -0! -#269000000 -1# -b10011 & -#270000000 -0# -#271000000 -1! -b10100 $ -#272000000 -0! -#273000000 -1" -b10100 % -#274000000 -0" -#275000000 -1! -#276000000 -0! -#277000000 -1# -b10100 & -#278000000 -0# -#279000000 -1" -b10101 % -#280000000 -0" -#281000000 -1" -#282000000 -0" -#283000000 -1! -b10101 $ -#284000000 -0! -#285000000 -1# -b10101 & -#286000000 -0# -#287000000 -1# -b10110 & -#288000000 -0# -#289000000 -1" -b10110 % -#290000000 -0" -#291000000 -1" -#292000000 -0" -#293000000 -1! -b10110 $ -#294000000 -0! -#295000000 -1! -b10111 $ -#296000000 -0! -#297000000 -1" -b10111 % -#298000000 -0" -#299000000 -1" -#300000000 -0" -#301000000 -1! -#302000000 -0! -#303000000 -1" -#304000000 -0" -#305000000 -1" -#306000000 -0" -#307000000 -1" -#308000000 -0" -#309000000 -1! -#310000000 -0! -#311000000 -1# -b10111 & -#312000000 -0# -#313000000 -1" -b11000 % -#314000000 -0" -#315000000 -1" -#316000000 -0" -#317000000 -1" -#318000000 -0" -#319000000 -1! -b11000 $ -#320000000 -0! -#321000000 -1" -#322000000 -0" -#323000000 -1" -#324000000 -0" -#325000000 -1" -#326000000 -0" -#327000000 -1" -#328000000 -0" -#329000000 -1" -#330000000 -0" -#331000000 -1" -#332000000 -0" -#333000000 -1" -#334000000 -0" -#335000000 -1# -b11000 & -#336000000 -0# -#337000000 -1" -b11001 % -#338000000 -0" -#339000000 -1" -#340000000 -0" -#341000000 -1# -b11001 & -#342000000 -0# -#343000000 -1! -b11001 $ -#344000000 -0! -#345000000 -1" -b11010 % -#346000000 -0" -#347000000 -1" -#348000000 -0" -#349000000 -1# -b11010 & -#350000000 -0# -#351000000 -1" -#352000000 -0" -#353000000 -1" -#354000000 -0" -#355000000 -1" -#356000000 -0" -#357000000 -1# -#358000000 -0# -#359000000 -1# -#360000000 -0# -#361000000 -1" -#362000000 -0" -#363000000 -1# -#364000000 -0# -#365000000 -1! -b11010 $ -#366000000 -0! -#367000000 -1! -b11011 $ -#368000000 -0! -#369000000 -1" -b11011 % -#370000000 -0" -#371000000 -1# -b11011 & -#372000000 -0# -#373000000 -1! -b11100 $ -#374000000 -0! -#375000000 -1" -b11100 % -#376000000 -0" -#377000000 -1" -#378000000 -0" -#379000000 -1# -b11100 & -#380000000 -0# -#381000000 -1! -b11101 $ -#382000000 -0! -#383000000 -1# -b11101 & -#384000000 -0# -#385000000 -1" -b11101 % -#386000000 -0" -#387000000 -1# -b11110 & -#388000000 -0# -#389000000 -1" -b11110 % -#390000000 -0" -#391000000 -1! -b11110 $ -#392000000 -0! -#393000000 -1" -b11111 % -#394000000 -0" -#395000000 -1# -b11111 & -#396000000 -0# -#397000000 -1" -#398000000 -0" -#399000000 -1" -#400000000 -0" -#401000000 -1" -#402000000 -0" -#403000000 -1# -#404000000 -0# -#405000000 -1" -#406000000 -0" -#407000000 -1# -#408000000 -0# -#409000000 -1" -#410000000 -0" -#411000000 -1# -#412000000 -0# -#413000000 -1# -#414000000 -0# -#415000000 -1! -b11111 $ -#416000000 -0! -#417000000 -1" -b100000 % -#418000000 -0" -#419000000 -1# -b100000 & -#420000000 -0# -#421000000 -1# -#422000000 -0# -#423000000 -1" -#424000000 -0" -#425000000 -1" -#426000000 -0" -#427000000 -1# -#428000000 -0# -#429000000 -1# -#430000000 -0# -#431000000 -1# -#432000000 -0# -#433000000 -1# -#434000000 -0# -#435000000 -1! -b100000 $ -#436000000 -0! -#437000000 -1! -b100001 $ -#438000000 -0! -#439000000 -1! -#440000000 -0! -#441000000 -1# -b100001 & -#442000000 -0# -#443000000 -1! -#444000000 -0! -#445000000 -1! -#446000000 -0! -#447000000 -1" -b100001 % -#448000000 -0" -#449000000 -1# -b100010 & -#450000000 -0# -#451000000 -1! -b100010 $ -#452000000 -0! -#453000000 -1! -#454000000 -0! -#455000000 -1# -#456000000 -0# -#457000000 -1# -#458000000 -0# -#459000000 -1! -#460000000 -0! -#461000000 -1" -b100010 % -#462000000 -0" -#463000000 -1! -b100011 $ -#464000000 -0! -#465000000 -1# -b100011 & -#466000000 -0# -#467000000 -1! -#468000000 -0! -#469000000 -1" -b100011 % -#470000000 -0" -#471000000 -1" -b100100 % -#472000000 -0" -#473000000 -1# -b100100 & -#474000000 -0# -#475000000 -1! -b100100 $ -#476000000 -0! -#477000000 -1" -b100101 % -#478000000 -0" -#479000000 -1# -b100101 & -#480000000 -0# -#481000000 -1# -#482000000 -0# -#483000000 -1! -b100101 $ -#484000000 -0! -#485000000 -1# -b100110 & -#486000000 -0# -#487000000 -1! -b100110 $ -#488000000 -0! -#489000000 -1# -#490000000 -0# -#491000000 -1! -#492000000 -0! -#493000000 -1# -#494000000 -0# -#495000000 -1" -b100110 % -#496000000 -0" -#497000000 -1# -b100111 & -#498000000 -0# -#499000000 -1! -b100111 $ -#500000000 -0! -#501000000 -1# -#502000000 -0# -#503000000 -1# -#504000000 -0# -#505000000 -1# -#506000000 -0# -#507000000 -1" -b100111 % -#508000000 -0" -#509000000 -1! -b101000 $ -#510000000 -0! -#511000000 -1! -#512000000 -0! -#513000000 -1# -b101000 & -#514000000 -0# -#515000000 -1" -b101000 % -#516000000 -0" -#517000000 -1! -b101001 $ -#518000000 -0! -#519000000 -1" -b101001 % -#520000000 -0" -#521000000 -1# -b101001 & -#522000000 -0# -#523000000 -1" -b101010 % -#524000000 -0" -#525000000 -1! -b101010 $ -#526000000 -0! -#527000000 -1# -b101010 & -#528000000 -0# -#529000000 -1# -b101011 & -#530000000 -0# -#531000000 -1" -b101011 % -#532000000 -0" -#533000000 -1" -#534000000 -0" -#535000000 -1! -b101011 $ -#536000000 -0! -#537000000 -1# -b101100 & -#538000000 -0# -#539000000 -1" -b101100 % -#540000000 -0" -#541000000 -1" -#542000000 -0" -#543000000 -1" -#544000000 -0" -#545000000 -1# -#546000000 -0# -#547000000 -1" -#548000000 -0" -#549000000 -1" -#550000000 -0" -#551000000 -1# -#552000000 -0# -#553000000 -1# -#554000000 -0# -#555000000 -1" -#556000000 -0" -#557000000 -1# -#558000000 -0# -#559000000 -1! -b101100 $ -#560000000 -0! -#561000000 -1# -b101101 & -#562000000 -0# -#563000000 -1" -b101101 % -#564000000 -0" -#565000000 -1# -#566000000 -0# -#567000000 -1" -#568000000 -0" -#569000000 -1# -#570000000 -0# -#571000000 -1" -#572000000 -0" -#573000000 -1# -#574000000 -0# -#575000000 -1# -#576000000 -0# -#577000000 -1# -#578000000 -0# -#579000000 -1# -#580000000 -0# -#581000000 -1! -b101101 $ -#582000000 -0! -#583000000 -1! -b101110 $ -#584000000 -0! -#585000000 -1# -b101110 & -#586000000 -0# -#587000000 -1# -#588000000 -0# -#589000000 -1! -#590000000 -0! -#591000000 -1" -b101110 % -#592000000 -0" -#593000000 -1# -b101111 & -#594000000 -0# -#595000000 -1# -#596000000 -0# -#597000000 -1! -b101111 $ -#598000000 -0! -#599000000 -1# -#600000000 -0# -#601000000 -1# -#602000000 -0# -#603000000 -1# -#604000000 -0# -#605000000 -1" -b101111 % -#606000000 -0" -#607000000 -1! -b110000 $ -#608000000 -0! -#609000000 -1# -b110000 & -#610000000 -0# -#611000000 -1# -#612000000 -0# -#613000000 -1" -b110000 % -#614000000 -0" -#615000000 -1" -b110001 % -#616000000 -0" -#617000000 -1# -b110001 & -#618000000 -0# -#619000000 -1# -#620000000 -0# -#621000000 -1" -#622000000 -0" -#623000000 -1# -#624000000 -0# -#625000000 -1# -#626000000 -0# -#627000000 -1# -#628000000 -0# -#629000000 -1# -#630000000 -0# -#631000000 -1! -b110001 $ -#632000000 -0! -#633000000 -1# -b110010 & -#634000000 -0# -#635000000 -1# -#636000000 -0# -#637000000 -1# -#638000000 -0# -#639000000 -1" -b110010 % -#640000000 -0" -#641000000 -1# -#642000000 -0# -#643000000 -1# -#644000000 -0# -#645000000 -1# -#646000000 -0# -#647000000 -1# -#648000000 -0# diff --git a/crates/fayalite/tests/sim/expected/sim_fork_join_scope.txt b/crates/fayalite/tests/sim/expected/sim_fork_join_scope.txt deleted file mode 100644 index 40d16a9..0000000 --- a/crates/fayalite/tests/sim/expected/sim_fork_join_scope.txt +++ /dev/null @@ -1,525 +0,0 @@ -Simulation { - state: State { - insns: Insns { - state_layout: StateLayout { - ty: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 6, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 0, - 49, - 50, - 50, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.clocks, - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.outputs, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.clocks, - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.clocks[0], - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.clocks[1], - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.clocks[2], - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.outputs, - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.outputs[0], - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.outputs[1], - Instance { - name: ::sim_fork_join_scope, - instantiated: Module { - name: sim_fork_join_scope, - .. - }, - }.outputs[2], - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }[0], - ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }[1], - ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }[2], - ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }[0], - ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }[1], - ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }[2], - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ), - f: ..., - }, - sim_io_to_generator_map: { - ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }: ModuleIO { - name: sim_fork_join_scope::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }: ModuleIO { - name: sim_fork_join_scope::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - }, - ], - trace_decls: TraceModule { - name: "sim_fork_join_scope", - children: [ - TraceModuleIO { - name: "clocks", - child: TraceArray { - name: "clocks", - elements: [ - TraceClock { - location: TraceScalarId(0), - name: "[0]", - flow: Source, - }, - TraceClock { - location: TraceScalarId(1), - name: "[1]", - flow: Source, - }, - TraceClock { - location: TraceScalarId(2), - name: "[2]", - flow: Source, - }, - ], - ty: Array, - flow: Source, - }, - ty: Array, - flow: Source, - }, - TraceModuleIO { - name: "outputs", - child: TraceArray { - name: "outputs", - elements: [ - TraceUInt { - location: TraceScalarId(3), - name: "[0]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(4), - name: "[1]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(5), - name: "[2]", - ty: UInt<8>, - flow: Sink, - }, - ], - ty: Array, 3>, - flow: Sink, - }, - ty: Array, 3>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigClock { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigClock { - index: StatePartIndex(2), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(3), - kind: BigUInt { - index: StatePartIndex(3), - ty: UInt<8>, - }, - state: 0x31, - last_state: 0x31, - }, - SimTrace { - id: TraceScalarId(4), - kind: BigUInt { - index: StatePartIndex(4), - ty: UInt<8>, - }, - state: 0x32, - last_state: 0x32, - }, - SimTrace { - id: TraceScalarId(5), - kind: BigUInt { - index: StatePartIndex(5), - ty: UInt<8>, - }, - state: 0x32, - last_state: 0x32, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 648 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 198, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_fork_join_scope: sim_fork_join_scope).sim_fork_join_scope::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 198, - .. - }, - }, - ), - }, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_fork_join_scope.vcd b/crates/fayalite/tests/sim/expected/sim_fork_join_scope.vcd deleted file mode 100644 index 555e83e..0000000 --- a/crates/fayalite/tests/sim/expected/sim_fork_join_scope.vcd +++ /dev/null @@ -1,1467 +0,0 @@ -$timescale 1 ps $end -$scope module sim_fork_join_scope $end -$scope struct clocks $end -$var wire 1 ! \[0] $end -$var wire 1 " \[1] $end -$var wire 1 # \[2] $end -$upscope $end -$scope struct outputs $end -$var wire 8 $ \[0] $end -$var wire 8 % \[1] $end -$var wire 8 & \[2] $end -$upscope $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -0" -0# -b0 $ -b0 % -b0 & -$end -#1000000 -1! -b1 $ -#2000000 -0! -#3000000 -1! -#4000000 -0! -#5000000 -1! -#6000000 -0! -#7000000 -1! -#8000000 -0! -#9000000 -1! -#10000000 -0! -#11000000 -1! -#12000000 -0! -#13000000 -1! -#14000000 -0! -#15000000 -1" -b1 % -#16000000 -0" -#17000000 -1! -#18000000 -0! -#19000000 -1! -#20000000 -0! -#21000000 -1! -#22000000 -0! -#23000000 -1# -b1 & -#24000000 -0# -#25000000 -1! -b10 $ -#26000000 -0! -#27000000 -1! -#28000000 -0! -#29000000 -1" -b10 % -#30000000 -0" -#31000000 -1! -#32000000 -0! -#33000000 -1! -#34000000 -0! -#35000000 -1! -#36000000 -0! -#37000000 -1" -#38000000 -0" -#39000000 -1" -#40000000 -0" -#41000000 -1! -#42000000 -0! -#43000000 -1! -#44000000 -0! -#45000000 -1" -#46000000 -0" -#47000000 -1# -b10 & -#48000000 -0# -#49000000 -1! -b11 $ -#50000000 -0! -#51000000 -1! -#52000000 -0! -#53000000 -1# -b11 & -#54000000 -0# -#55000000 -1! -#56000000 -0! -#57000000 -1! -#58000000 -0! -#59000000 -1! -#60000000 -0! -#61000000 -1# -#62000000 -0# -#63000000 -1" -b11 % -#64000000 -0" -#65000000 -1! -b100 $ -#66000000 -0! -#67000000 -1! -#68000000 -0! -#69000000 -1# -b100 & -#70000000 -0# -#71000000 -1# -#72000000 -0# -#73000000 -1! -#74000000 -0! -#75000000 -1" -b100 % -#76000000 -0" -#77000000 -1! -b101 $ -#78000000 -0! -#79000000 -1! -#80000000 -0! -#81000000 -1! -#82000000 -0! -#83000000 -1" -b101 % -#84000000 -0" -#85000000 -1! -#86000000 -0! -#87000000 -1" -#88000000 -0" -#89000000 -1! -#90000000 -0! -#91000000 -1" -#92000000 -0" -#93000000 -1! -#94000000 -0! -#95000000 -1# -b101 & -#96000000 -0# -#97000000 -1! -b110 $ -#98000000 -0! -#99000000 -1" -b110 % -#100000000 -0" -#101000000 -1" -#102000000 -0" -#103000000 -1! -#104000000 -0! -#105000000 -1! -#106000000 -0! -#107000000 -1" -#108000000 -0" -#109000000 -1" -#110000000 -0" -#111000000 -1" -#112000000 -0" -#113000000 -1! -#114000000 -0! -#115000000 -1" -#116000000 -0" -#117000000 -1" -#118000000 -0" -#119000000 -1# -b110 & -#120000000 -0# -#121000000 -1! -b111 $ -#122000000 -0! -#123000000 -1" -b111 % -#124000000 -0" -#125000000 -1# -b111 & -#126000000 -0# -#127000000 -1! -b1000 $ -#128000000 -0! -#129000000 -1! -#130000000 -0! -#131000000 -1" -b1000 % -#132000000 -0" -#133000000 -1# -b1000 & -#134000000 -0# -#135000000 -1" -b1001 % -#136000000 -0" -#137000000 -1! -b1001 $ -#138000000 -0! -#139000000 -1" -#140000000 -0" -#141000000 -1# -b1001 & -#142000000 -0# -#143000000 -1# -b1010 & -#144000000 -0# -#145000000 -1! -b1010 $ -#146000000 -0! -#147000000 -1# -#148000000 -0# -#149000000 -1! -#150000000 -0! -#151000000 -1! -#152000000 -0! -#153000000 -1! -#154000000 -0! -#155000000 -1# -#156000000 -0# -#157000000 -1! -#158000000 -0! -#159000000 -1" -b1010 % -#160000000 -0" -#161000000 -1! -b1011 $ -#162000000 -0! -#163000000 -1# -b1011 & -#164000000 -0# -#165000000 -1! -#166000000 -0! -#167000000 -1# -#168000000 -0# -#169000000 -1! -#170000000 -0! -#171000000 -1# -#172000000 -0# -#173000000 -1" -b1011 % -#174000000 -0" -#175000000 -1! -b1100 $ -#176000000 -0! -#177000000 -1! -#178000000 -0! -#179000000 -1# -b1100 & -#180000000 -0# -#181000000 -1" -b1100 % -#182000000 -0" -#183000000 -1" -b1101 % -#184000000 -0" -#185000000 -1! -b1101 $ -#186000000 -0! -#187000000 -1# -b1101 & -#188000000 -0# -#189000000 -1" -b1110 % -#190000000 -0" -#191000000 -1# -b1110 & -#192000000 -0# -#193000000 -1! -b1110 $ -#194000000 -0! -#195000000 -1# -b1111 & -#196000000 -0# -#197000000 -1# -#198000000 -0# -#199000000 -1! -b1111 $ -#200000000 -0! -#201000000 -1! -#202000000 -0! -#203000000 -1# -#204000000 -0# -#205000000 -1# -#206000000 -0# -#207000000 -1" -b1111 % -#208000000 -0" -#209000000 -1! -b10000 $ -#210000000 -0! -#211000000 -1# -b10000 & -#212000000 -0# -#213000000 -1# -#214000000 -0# -#215000000 -1# -#216000000 -0# -#217000000 -1" -b10000 % -#218000000 -0" -#219000000 -1! -b10001 $ -#220000000 -0! -#221000000 -1! -#222000000 -0! -#223000000 -1! -#224000000 -0! -#225000000 -1" -b10001 % -#226000000 -0" -#227000000 -1! -#228000000 -0! -#229000000 -1! -#230000000 -0! -#231000000 -1" -#232000000 -0" -#233000000 -1" -#234000000 -0" -#235000000 -1! -#236000000 -0! -#237000000 -1! -#238000000 -0! -#239000000 -1# -b10001 & -#240000000 -0# -#241000000 -1" -b10010 % -#242000000 -0" -#243000000 -1! -b10010 $ -#244000000 -0! -#245000000 -1" -#246000000 -0" -#247000000 -1! -#248000000 -0! -#249000000 -1" -#250000000 -0" -#251000000 -1! -#252000000 -0! -#253000000 -1" -#254000000 -0" -#255000000 -1" -#256000000 -0" -#257000000 -1" -#258000000 -0" -#259000000 -1! -#260000000 -0! -#261000000 -1" -#262000000 -0" -#263000000 -1# -b10010 & -#264000000 -0# -#265000000 -1" -b10011 % -#266000000 -0" -#267000000 -1! -b10011 $ -#268000000 -0! -#269000000 -1# -b10011 & -#270000000 -0# -#271000000 -1! -b10100 $ -#272000000 -0! -#273000000 -1" -b10100 % -#274000000 -0" -#275000000 -1! -#276000000 -0! -#277000000 -1# -b10100 & -#278000000 -0# -#279000000 -1" -b10101 % -#280000000 -0" -#281000000 -1" -#282000000 -0" -#283000000 -1! -b10101 $ -#284000000 -0! -#285000000 -1# -b10101 & -#286000000 -0# -#287000000 -1# -b10110 & -#288000000 -0# -#289000000 -1" -b10110 % -#290000000 -0" -#291000000 -1" -#292000000 -0" -#293000000 -1! -b10110 $ -#294000000 -0! -#295000000 -1! -b10111 $ -#296000000 -0! -#297000000 -1" -b10111 % -#298000000 -0" -#299000000 -1" -#300000000 -0" -#301000000 -1! -#302000000 -0! -#303000000 -1" -#304000000 -0" -#305000000 -1" -#306000000 -0" -#307000000 -1" -#308000000 -0" -#309000000 -1! -#310000000 -0! -#311000000 -1# -b10111 & -#312000000 -0# -#313000000 -1" -b11000 % -#314000000 -0" -#315000000 -1" -#316000000 -0" -#317000000 -1" -#318000000 -0" -#319000000 -1! -b11000 $ -#320000000 -0! -#321000000 -1" -#322000000 -0" -#323000000 -1" -#324000000 -0" -#325000000 -1" -#326000000 -0" -#327000000 -1" -#328000000 -0" -#329000000 -1" -#330000000 -0" -#331000000 -1" -#332000000 -0" -#333000000 -1" -#334000000 -0" -#335000000 -1# -b11000 & -#336000000 -0# -#337000000 -1" -b11001 % -#338000000 -0" -#339000000 -1" -#340000000 -0" -#341000000 -1# -b11001 & -#342000000 -0# -#343000000 -1! -b11001 $ -#344000000 -0! -#345000000 -1" -b11010 % -#346000000 -0" -#347000000 -1" -#348000000 -0" -#349000000 -1# -b11010 & -#350000000 -0# -#351000000 -1" -#352000000 -0" -#353000000 -1" -#354000000 -0" -#355000000 -1" -#356000000 -0" -#357000000 -1# -#358000000 -0# -#359000000 -1# -#360000000 -0# -#361000000 -1" -#362000000 -0" -#363000000 -1# -#364000000 -0# -#365000000 -1! -b11010 $ -#366000000 -0! -#367000000 -1! -b11011 $ -#368000000 -0! -#369000000 -1" -b11011 % -#370000000 -0" -#371000000 -1# -b11011 & -#372000000 -0# -#373000000 -1! -b11100 $ -#374000000 -0! -#375000000 -1" -b11100 % -#376000000 -0" -#377000000 -1" -#378000000 -0" -#379000000 -1# -b11100 & -#380000000 -0# -#381000000 -1! -b11101 $ -#382000000 -0! -#383000000 -1# -b11101 & -#384000000 -0# -#385000000 -1" -b11101 % -#386000000 -0" -#387000000 -1# -b11110 & -#388000000 -0# -#389000000 -1" -b11110 % -#390000000 -0" -#391000000 -1! -b11110 $ -#392000000 -0! -#393000000 -1" -b11111 % -#394000000 -0" -#395000000 -1# -b11111 & -#396000000 -0# -#397000000 -1" -#398000000 -0" -#399000000 -1" -#400000000 -0" -#401000000 -1" -#402000000 -0" -#403000000 -1# -#404000000 -0# -#405000000 -1" -#406000000 -0" -#407000000 -1# -#408000000 -0# -#409000000 -1" -#410000000 -0" -#411000000 -1# -#412000000 -0# -#413000000 -1# -#414000000 -0# -#415000000 -1! -b11111 $ -#416000000 -0! -#417000000 -1" -b100000 % -#418000000 -0" -#419000000 -1# -b100000 & -#420000000 -0# -#421000000 -1# -#422000000 -0# -#423000000 -1" -#424000000 -0" -#425000000 -1" -#426000000 -0" -#427000000 -1# -#428000000 -0# -#429000000 -1# -#430000000 -0# -#431000000 -1# -#432000000 -0# -#433000000 -1# -#434000000 -0# -#435000000 -1! -b100000 $ -#436000000 -0! -#437000000 -1! -b100001 $ -#438000000 -0! -#439000000 -1! -#440000000 -0! -#441000000 -1# -b100001 & -#442000000 -0# -#443000000 -1! -#444000000 -0! -#445000000 -1! -#446000000 -0! -#447000000 -1" -b100001 % -#448000000 -0" -#449000000 -1# -b100010 & -#450000000 -0# -#451000000 -1! -b100010 $ -#452000000 -0! -#453000000 -1! -#454000000 -0! -#455000000 -1# -#456000000 -0# -#457000000 -1# -#458000000 -0# -#459000000 -1! -#460000000 -0! -#461000000 -1" -b100010 % -#462000000 -0" -#463000000 -1! -b100011 $ -#464000000 -0! -#465000000 -1# -b100011 & -#466000000 -0# -#467000000 -1! -#468000000 -0! -#469000000 -1" -b100011 % -#470000000 -0" -#471000000 -1" -b100100 % -#472000000 -0" -#473000000 -1# -b100100 & -#474000000 -0# -#475000000 -1! -b100100 $ -#476000000 -0! -#477000000 -1" -b100101 % -#478000000 -0" -#479000000 -1# -b100101 & -#480000000 -0# -#481000000 -1# -#482000000 -0# -#483000000 -1! -b100101 $ -#484000000 -0! -#485000000 -1# -b100110 & -#486000000 -0# -#487000000 -1! -b100110 $ -#488000000 -0! -#489000000 -1# -#490000000 -0# -#491000000 -1! -#492000000 -0! -#493000000 -1# -#494000000 -0# -#495000000 -1" -b100110 % -#496000000 -0" -#497000000 -1# -b100111 & -#498000000 -0# -#499000000 -1! -b100111 $ -#500000000 -0! -#501000000 -1# -#502000000 -0# -#503000000 -1# -#504000000 -0# -#505000000 -1# -#506000000 -0# -#507000000 -1" -b100111 % -#508000000 -0" -#509000000 -1! -b101000 $ -#510000000 -0! -#511000000 -1! -#512000000 -0! -#513000000 -1# -b101000 & -#514000000 -0# -#515000000 -1" -b101000 % -#516000000 -0" -#517000000 -1! -b101001 $ -#518000000 -0! -#519000000 -1" -b101001 % -#520000000 -0" -#521000000 -1# -b101001 & -#522000000 -0# -#523000000 -1" -b101010 % -#524000000 -0" -#525000000 -1! -b101010 $ -#526000000 -0! -#527000000 -1# -b101010 & -#528000000 -0# -#529000000 -1# -b101011 & -#530000000 -0# -#531000000 -1" -b101011 % -#532000000 -0" -#533000000 -1" -#534000000 -0" -#535000000 -1! -b101011 $ -#536000000 -0! -#537000000 -1# -b101100 & -#538000000 -0# -#539000000 -1" -b101100 % -#540000000 -0" -#541000000 -1" -#542000000 -0" -#543000000 -1" -#544000000 -0" -#545000000 -1# -#546000000 -0# -#547000000 -1" -#548000000 -0" -#549000000 -1" -#550000000 -0" -#551000000 -1# -#552000000 -0# -#553000000 -1# -#554000000 -0# -#555000000 -1" -#556000000 -0" -#557000000 -1# -#558000000 -0# -#559000000 -1! -b101100 $ -#560000000 -0! -#561000000 -1# -b101101 & -#562000000 -0# -#563000000 -1" -b101101 % -#564000000 -0" -#565000000 -1# -#566000000 -0# -#567000000 -1" -#568000000 -0" -#569000000 -1# -#570000000 -0# -#571000000 -1" -#572000000 -0" -#573000000 -1# -#574000000 -0# -#575000000 -1# -#576000000 -0# -#577000000 -1# -#578000000 -0# -#579000000 -1# -#580000000 -0# -#581000000 -1! -b101101 $ -#582000000 -0! -#583000000 -1! -b101110 $ -#584000000 -0! -#585000000 -1# -b101110 & -#586000000 -0# -#587000000 -1# -#588000000 -0# -#589000000 -1! -#590000000 -0! -#591000000 -1" -b101110 % -#592000000 -0" -#593000000 -1# -b101111 & -#594000000 -0# -#595000000 -1# -#596000000 -0# -#597000000 -1! -b101111 $ -#598000000 -0! -#599000000 -1# -#600000000 -0# -#601000000 -1# -#602000000 -0# -#603000000 -1# -#604000000 -0# -#605000000 -1" -b101111 % -#606000000 -0" -#607000000 -1! -b110000 $ -#608000000 -0! -#609000000 -1# -b110000 & -#610000000 -0# -#611000000 -1# -#612000000 -0# -#613000000 -1" -b110000 % -#614000000 -0" -#615000000 -1" -b110001 % -#616000000 -0" -#617000000 -1# -b110001 & -#618000000 -0# -#619000000 -1# -#620000000 -0# -#621000000 -1" -#622000000 -0" -#623000000 -1# -#624000000 -0# -#625000000 -1# -#626000000 -0# -#627000000 -1# -#628000000 -0# -#629000000 -1# -#630000000 -0# -#631000000 -1! -b110001 $ -#632000000 -0! -#633000000 -1# -b110010 & -#634000000 -0# -#635000000 -1# -#636000000 -0# -#637000000 -1# -#638000000 -0# -#639000000 -1" -b110010 % -#640000000 -0" -#641000000 -1# -#642000000 -0# -#643000000 -1# -#644000000 -0# -#645000000 -1# -#646000000 -0# -#647000000 -1# -#648000000 -0# diff --git a/crates/fayalite/tests/sim/expected/sim_only_connects.txt b/crates/fayalite/tests/sim/expected/sim_only_connects.txt index 15456d2..114b313 100644 --- a/crates/fayalite/tests/sim/expected/sim_only_connects.txt +++ b/crates/fayalite/tests/sim/expected/sim_only_connects.txt @@ -557,7 +557,6 @@ Simulation { }.out3, }, did_initial_settle: true, - clocks_for_past: {}, }, extern_modules: [ SimulationExternModuleState { @@ -636,7 +635,6 @@ Simulation { }, }, did_initial_settle: true, - clocks_for_past: {}, }, sim: ExternModuleSimulation { generator: SimGeneratorFn { @@ -719,6 +717,52 @@ Simulation { 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: "", + ty: Clock, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 6, len: 0 }, + }, + write: None, + }, + value: SimValue { + ty: Clock, + value: OpaqueSimValue { + bits: 0x1_u1, + sim_only_values: [], + }, + }, + }, + }, }, SimulationExternModuleState { module_state: SimulationModuleState { @@ -796,7 +840,6 @@ Simulation { }, }, did_initial_settle: true, - clocks_for_past: {}, }, sim: ExternModuleSimulation { generator: SimGeneratorFn { @@ -879,8 +922,55 @@ Simulation { 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: "", + ty: Clock, + }, + ], + .. + }, + sim_only_slots: StatePartLayout { + len: 0, + debug_data: [], + layout_data: [], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 4, len: 0 }, + big_slots: StatePartIndexRange { start: 12, len: 1 }, + sim_only_slots: StatePartIndexRange { start: 13, len: 0 }, + }, + write: None, + }, + value: SimValue { + ty: Clock, + value: OpaqueSimValue { + bits: 0x1_u1, + sim_only_values: [], + }, + }, + }, + }, }, ], + state_ready_to_run: false, trace_decls: TraceModule { name: "sim_only_connects", children: [ @@ -1538,214 +1628,9 @@ Simulation { }, ), ], + instant: 16 μs, clocks_triggered: [ StatePartIndex(1), ], - event_queue: EventQueue(EventQueueData { - instant: 16 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 30, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_only_connects.helper1: sim_only_connects_helper).sim_only_connects_helper::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 6, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x1_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - SensitivitySet { - id: 31, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_only_connects.helper2: sim_only_connects_helper).sim_only_connects_helper::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 4, len: 0 }, - big_slots: StatePartIndexRange { start: 12, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 13, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x1_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_only_connects.helper1: sim_only_connects_helper).sim_only_connects_helper::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 6, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x1_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 30, - .. - }, - }, - ), - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_only_connects.helper2: sim_only_connects_helper).sim_only_connects_helper::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 4, len: 0 }, - big_slots: StatePartIndexRange { start: 12, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 13, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x1_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 31, - .. - }, - }, - ), - }, .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_only_connects.vcd b/crates/fayalite/tests/sim/expected/sim_only_connects.vcd index 1e4c249..2f464c0 100644 --- a/crates/fayalite/tests/sim/expected/sim_only_connects.vcd +++ b/crates/fayalite/tests/sim/expected/sim_only_connects.vcd @@ -72,22 +72,22 @@ s{} 8 $end #1000000 1! -s{\"extra\":\x20\"value\"} $ 1' -s{\"extra\":\x20\"value\"} ) 1+ -s{\"extra\":\x20\"value\"} - 10 11 15 -s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} % +s{\"extra\":\x20\"value\"} $ +s{\"extra\":\x20\"value\"} ) +s{\"extra\":\x20\"value\"} - s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} * +s{\"bar\":\x20\"\",\x20\"foo\":\x20\"baz\"} 4 +s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} % +s{\"bar\":\x20\"\",\x20\"foo\":\x20\"baz\"} & s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} . s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 3 s{\"bar\":\x20\"\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 7 -s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} & -s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 4 -s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 8 +s{\"bar\":\x20\"\",\x20\"foo\":\x20\"baz\"} 8 #2000000 0! 0" @@ -107,6 +107,9 @@ s{\"extra\":\x20\"value\"} / 00 11 15 +s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 4 +s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} & +s{\"bar\":\x20\"baz\",\x20\"extra\":\x20\"value\",\x20\"foo\":\x20\"baz\"} 8 #4000000 0! 0' diff --git a/crates/fayalite/tests/sim/expected/sim_read_past.txt b/crates/fayalite/tests/sim/expected/sim_read_past.txt deleted file mode 100644 index 475943e..0000000 --- a/crates/fayalite/tests/sim/expected/sim_read_past.txt +++ /dev/null @@ -1,9724 +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: 48, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:2:1 - 0: IsNonZeroDestIsSmall { - dest: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", ty: Clock }, - }, - 1: 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 }, - }, - 2: IsNonZeroDestIsSmall { - dest: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", ty: Clock }, - }, - 3: 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 }, - }, - 4: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", ty: Clock }, - }, - 5: AndSmall { - dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - }, - 6: BranchIfSmallZero { - target: 10, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 7: Copy { - dest: StatePartIndex(12), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[0]", ty: Clock }, - src: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", ty: Clock }, - }, - 8: Copy { - dest: StatePartIndex(13), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[1]", ty: Clock }, - src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", ty: Clock }, - }, - 9: Copy { - dest: StatePartIndex(14), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[2]", ty: Clock }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:3:1 - 10: BranchIfSmallZero { - target: 14, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 11: Copy { - dest: StatePartIndex(15), // (0x30) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[0]", ty: UInt<8> }, - src: StatePartIndex(3), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", ty: UInt<8> }, - }, - 12: Copy { - dest: StatePartIndex(16), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[1]", ty: UInt<8> }, - src: StatePartIndex(4), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", ty: UInt<8> }, - }, - 13: Copy { - dest: StatePartIndex(17), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[2]", ty: UInt<8> }, - src: StatePartIndex(5), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", ty: UInt<8> }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 14: BranchIfSmallZero { - target: 18, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 15: Copy { - dest: StatePartIndex(18), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[0]", ty: Clock }, - src: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", ty: Clock }, - }, - 16: Copy { - dest: StatePartIndex(19), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[1]", ty: Clock }, - src: StatePartIndex(7), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", ty: Clock }, - }, - 17: Copy { - dest: StatePartIndex(20), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[2]", ty: Clock }, - src: StatePartIndex(8), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:5:1 - 18: BranchIfSmallZero { - target: 22, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 19: Copy { - dest: StatePartIndex(21), // (0x30) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[0]", ty: UInt<8> }, - src: StatePartIndex(9), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", ty: UInt<8> }, - }, - 20: Copy { - dest: StatePartIndex(22), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[1]", ty: UInt<8> }, - src: StatePartIndex(10), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", ty: UInt<8> }, - }, - 21: Copy { - dest: StatePartIndex(23), // (0x30) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[2]", ty: UInt<8> }, - src: StatePartIndex(11), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", ty: UInt<8> }, - }, - // at: module-XXXXXXXXXX.rs:2:1 - 22: BranchIfSmallZero { - target: 26, - value: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 23: Copy { - dest: StatePartIndex(24), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[0]", ty: Clock }, - src: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", ty: Clock }, - }, - 24: Copy { - dest: StatePartIndex(25), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[1]", ty: Clock }, - src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", ty: Clock }, - }, - 25: Copy { - dest: StatePartIndex(26), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[2]", ty: Clock }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:3:1 - 26: BranchIfSmallZero { - target: 30, - value: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 27: Copy { - dest: StatePartIndex(27), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[0]", ty: UInt<8> }, - src: StatePartIndex(3), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", ty: UInt<8> }, - }, - 28: Copy { - dest: StatePartIndex(28), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[1]", ty: UInt<8> }, - src: StatePartIndex(4), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", ty: UInt<8> }, - }, - 29: Copy { - dest: StatePartIndex(29), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[2]", ty: UInt<8> }, - src: StatePartIndex(5), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", ty: UInt<8> }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 30: BranchIfSmallZero { - target: 34, - value: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 31: Copy { - dest: StatePartIndex(30), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[0]", ty: Clock }, - src: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", ty: Clock }, - }, - 32: Copy { - dest: StatePartIndex(31), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[1]", ty: Clock }, - src: StatePartIndex(7), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", ty: Clock }, - }, - 33: Copy { - dest: StatePartIndex(32), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[2]", ty: Clock }, - src: StatePartIndex(8), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:5:1 - 34: BranchIfSmallZero { - target: 38, - value: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 35: Copy { - dest: StatePartIndex(33), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[0]", ty: UInt<8> }, - src: StatePartIndex(9), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", ty: UInt<8> }, - }, - 36: Copy { - dest: StatePartIndex(34), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[1]", ty: UInt<8> }, - src: StatePartIndex(10), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", ty: UInt<8> }, - }, - 37: Copy { - dest: StatePartIndex(35), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[2]", ty: UInt<8> }, - src: StatePartIndex(11), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", ty: UInt<8> }, - }, - // at: module-XXXXXXXXXX.rs:2:1 - 38: BranchIfSmallZero { - target: 42, - value: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 39: Copy { - dest: StatePartIndex(36), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[0]", ty: Clock }, - src: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", ty: Clock }, - }, - 40: Copy { - dest: StatePartIndex(37), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[1]", ty: Clock }, - src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", ty: Clock }, - }, - 41: Copy { - dest: StatePartIndex(38), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[2]", ty: Clock }, - src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:3:1 - 42: BranchIfSmallZero { - target: 46, - value: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 43: Copy { - dest: StatePartIndex(39), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[0]", ty: UInt<8> }, - src: StatePartIndex(3), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", ty: UInt<8> }, - }, - 44: Copy { - dest: StatePartIndex(40), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[1]", ty: UInt<8> }, - src: StatePartIndex(4), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", ty: UInt<8> }, - }, - 45: Copy { - dest: StatePartIndex(41), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[2]", ty: UInt<8> }, - src: StatePartIndex(5), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", ty: UInt<8> }, - }, - // at: module-XXXXXXXXXX.rs:4:1 - 46: BranchIfSmallZero { - target: 50, - value: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 47: Copy { - dest: StatePartIndex(42), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[0]", ty: Clock }, - src: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", ty: Clock }, - }, - 48: Copy { - dest: StatePartIndex(43), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[1]", ty: Clock }, - src: StatePartIndex(7), // (0x1) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", ty: Clock }, - }, - 49: Copy { - dest: StatePartIndex(44), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[2]", ty: Clock }, - src: StatePartIndex(8), // (0x0) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", ty: Clock }, - }, - // at: module-XXXXXXXXXX.rs:5:1 - 50: BranchIfSmallZero { - target: 54, - value: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 51: Copy { - dest: StatePartIndex(45), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[0]", ty: UInt<8> }, - src: StatePartIndex(9), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", ty: UInt<8> }, - }, - 52: Copy { - dest: StatePartIndex(46), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[1]", ty: UInt<8> }, - src: StatePartIndex(10), // (0x31) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", ty: UInt<8> }, - }, - 53: Copy { - dest: StatePartIndex(47), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[2]", ty: UInt<8> }, - src: StatePartIndex(11), // (0x32) SlotDebugData { name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", ty: UInt<8> }, - }, - // at: module-XXXXXXXXXX.rs:2:1 - 54: XorSmallImmediate { - dest: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 55: XorSmallImmediate { - dest: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - rhs: 0x1, - }, - 56: 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 - 57: Return, - ], - .. - }, - pc: 57, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [ - 1, - 0, - 0, - 1, - 0, - 0, - 1, - 0, - 0, - ], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 0, - 49, - 50, - 50, - 0, - 1, - 0, - 49, - 49, - 50, - 1, - 0, - 0, - 48, - 49, - 49, - 0, - 0, - 1, - 48, - 49, - 48, - 0, - 1, - 0, - 49, - 49, - 50, - 0, - 0, - 1, - 49, - 49, - 49, - 0, - 0, - 1, - 49, - 50, - 50, - 0, - 1, - 0, - 49, - 49, - 50, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.clocks, - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.outputs, - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_clocks, - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_outputs, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.clocks, - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.clocks[0], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.clocks[1], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.clocks[2], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.outputs, - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.outputs[0], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.outputs[1], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.outputs[2], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_clocks, - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_clocks[0], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_clocks[1], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_clocks[2], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_outputs, - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_outputs[0], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_outputs[1], - Instance { - name: ::sim_read_past, - instantiated: Module { - name: sim_read_past, - .. - }, - }.past_outputs[2], - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }[0], - ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }[1], - ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }[2], - ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }[0], - ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }[1], - ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }[2], - ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }[0], - ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }[1], - ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }[2], - ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }[0], - ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }[1], - ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }[2], - }, - did_initial_settle: true, - clocks_for_past: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimulationExternModuleClockForPast { - current_to_past_map: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 12, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 18, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 15, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 21, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 12, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 13, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 2, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 14, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 2, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 18, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 7, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 19, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 7, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 8, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[0])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 20, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 8, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 15, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 16, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 5, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 17, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 5, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 21, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 10, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 22, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 10, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 11, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[0])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 23, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 11, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - }, - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimulationExternModuleClockForPast { - current_to_past_map: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 24, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 30, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 27, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 33, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 24, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 25, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 2, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 3, len: 0 }, - big_slots: StatePartIndexRange { start: 26, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 2, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 30, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 7, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 31, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 7, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 8, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[1])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 32, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 8, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 27, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 28, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 5, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 29, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 5, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 33, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 10, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 34, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 10, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 11, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[1])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 35, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 11, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - }, - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 2, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimulationExternModuleClockForPast { - current_to_past_map: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 36, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 42, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 39, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 45, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Array, 3>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 3, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Array { - elements_non_empty: [ - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - ], - }, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 3 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 36, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 37, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 2, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 6, len: 0 }, - big_slots: StatePartIndexRange { start: 38, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 2, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 42, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 6, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 7, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 43, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[1]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 7, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 8, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks$past(sim_read_past::clocks[2])[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 44, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_clocks[2]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 8, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 39, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 3, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 40, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 4, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 5, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 41, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 5, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 45, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[0]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 9, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 10, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 46, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[1]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 10, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 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: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 11, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: 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(sim_read_past: sim_read_past).sim_read_past::past_outputs$past(sim_read_past::clocks[2])[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 9, len: 0 }, - big_slots: StatePartIndexRange { start: 47, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: Some( - ( - CompiledTypeLayout { - ty: UInt<8>, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::past_outputs[2]", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 11, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - ), - ), - }, - }, - }, - }, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ), - f: ..., - }, - sim_io_to_generator_map: { - ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }: ModuleIO { - name: sim_read_past::clocks, - is_input: true, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }: ModuleIO { - name: sim_read_past::outputs, - is_input: false, - ty: Array, 3>, - .. - }, - ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }: ModuleIO { - name: sim_read_past::past_clocks, - is_input: false, - ty: Array, - .. - }, - ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }: ModuleIO { - name: sim_read_past::past_outputs, - is_input: false, - ty: Array, 3>, - .. - }, - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:6:1, - ), - }, - running_generator: Some( - ..., - ), - }, - ], - trace_decls: TraceModule { - name: "sim_read_past", - children: [ - TraceModuleIO { - name: "clocks", - child: TraceArray { - name: "clocks", - elements: [ - TraceClock { - location: TraceScalarId(0), - name: "[0]", - flow: Source, - }, - TraceClock { - location: TraceScalarId(1), - name: "[1]", - flow: Source, - }, - TraceClock { - location: TraceScalarId(2), - name: "[2]", - flow: Source, - }, - ], - ty: Array, - flow: Source, - }, - ty: Array, - flow: Source, - }, - TraceModuleIO { - name: "outputs", - child: TraceArray { - name: "outputs", - elements: [ - TraceUInt { - location: TraceScalarId(3), - name: "[0]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(4), - name: "[1]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(5), - name: "[2]", - ty: UInt<8>, - flow: Sink, - }, - ], - ty: Array, 3>, - flow: Sink, - }, - ty: Array, 3>, - flow: Sink, - }, - TraceModuleIO { - name: "past_clocks", - child: TraceArray { - name: "past_clocks", - elements: [ - TraceClock { - location: TraceScalarId(6), - name: "[0]", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(7), - name: "[1]", - flow: Sink, - }, - TraceClock { - location: TraceScalarId(8), - name: "[2]", - flow: Sink, - }, - ], - ty: Array, - flow: Sink, - }, - ty: Array, - flow: Sink, - }, - TraceModuleIO { - name: "past_outputs", - child: TraceArray { - name: "past_outputs", - elements: [ - TraceUInt { - location: TraceScalarId(9), - name: "[0]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(10), - name: "[1]", - ty: UInt<8>, - flow: Sink, - }, - TraceUInt { - location: TraceScalarId(11), - name: "[2]", - ty: UInt<8>, - flow: Sink, - }, - ], - ty: Array, 3>, - flow: Sink, - }, - ty: Array, 3>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigClock { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigClock { - index: StatePartIndex(2), - }, - state: 0x0, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(3), - kind: BigUInt { - index: StatePartIndex(3), - ty: UInt<8>, - }, - state: 0x31, - last_state: 0x31, - }, - SimTrace { - id: TraceScalarId(4), - kind: BigUInt { - index: StatePartIndex(4), - ty: UInt<8>, - }, - state: 0x32, - last_state: 0x32, - }, - SimTrace { - id: TraceScalarId(5), - kind: BigUInt { - index: StatePartIndex(5), - ty: UInt<8>, - }, - state: 0x32, - last_state: 0x32, - }, - SimTrace { - id: TraceScalarId(6), - kind: BigClock { - index: StatePartIndex(6), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(7), - kind: BigClock { - index: StatePartIndex(7), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(8), - kind: BigClock { - index: StatePartIndex(8), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(9), - kind: BigUInt { - index: StatePartIndex(9), - ty: UInt<8>, - }, - state: 0x31, - last_state: 0x31, - }, - SimTrace { - id: TraceScalarId(10), - kind: BigUInt { - index: StatePartIndex(10), - ty: UInt<8>, - }, - state: 0x31, - last_state: 0x31, - }, - SimTrace { - id: TraceScalarId(11), - kind: BigUInt { - index: StatePartIndex(11), - ty: UInt<8>, - }, - state: 0x32, - last_state: 0x32, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [ - StatePartIndex(1), - StatePartIndex(4), - StatePartIndex(7), - ], - event_queue: EventQueue(EventQueueData { - instant: 648 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 198, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_read_past: sim_read_past).sim_read_past::clocks[0]", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 198, - .. - }, - }, - ), - }, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_read_past.vcd b/crates/fayalite/tests/sim/expected/sim_read_past.vcd deleted file mode 100644 index 5d0a932..0000000 --- a/crates/fayalite/tests/sim/expected/sim_read_past.vcd +++ /dev/null @@ -1,1908 +0,0 @@ -$timescale 1 ps $end -$scope module sim_read_past $end -$scope struct clocks $end -$var wire 1 ! \[0] $end -$var wire 1 " \[1] $end -$var wire 1 # \[2] $end -$upscope $end -$scope struct outputs $end -$var wire 8 $ \[0] $end -$var wire 8 % \[1] $end -$var wire 8 & \[2] $end -$upscope $end -$scope struct past_clocks $end -$var wire 1 ' \[0] $end -$var wire 1 ( \[1] $end -$var wire 1 ) \[2] $end -$upscope $end -$scope struct past_outputs $end -$var wire 8 * \[0] $end -$var wire 8 + \[1] $end -$var wire 8 , \[2] $end -$upscope $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -0" -0# -b0 $ -b0 % -b0 & -0' -0( -0) -b0 * -b0 + -b0 , -$end -#1000000 -1! -b1 $ -1' -#2000000 -0! -#3000000 -1! -#4000000 -0! -#5000000 -1! -#6000000 -0! -#7000000 -1! -#8000000 -0! -#9000000 -1! -#10000000 -0! -#11000000 -1! -#12000000 -0! -#13000000 -1! -#14000000 -0! -#15000000 -1" -b1 % -b1 * -0' -1( -#16000000 -0" -#17000000 -1! -#18000000 -0! -#19000000 -1! -#20000000 -0! -#21000000 -1! -#22000000 -0! -#23000000 -1# -b1 & -b1 + -0( -1) -#24000000 -0# -#25000000 -1! -b10 $ -b1 , -1' -0) -#26000000 -0! -#27000000 -1! -#28000000 -0! -#29000000 -1" -b10 % -b10 * -0' -1( -#30000000 -0" -#31000000 -1! -#32000000 -0! -#33000000 -1! -#34000000 -0! -#35000000 -1! -#36000000 -0! -#37000000 -1" -#38000000 -0" -#39000000 -1" -#40000000 -0" -#41000000 -1! -#42000000 -0! -#43000000 -1! -#44000000 -0! -#45000000 -1" -#46000000 -0" -#47000000 -1# -b10 & -b10 + -0( -1) -#48000000 -0# -#49000000 -1! -b11 $ -b10 , -1' -0) -#50000000 -0! -#51000000 -1! -#52000000 -0! -#53000000 -1# -b11 & -b11 * -0' -1) -#54000000 -0# -#55000000 -1! -#56000000 -0! -#57000000 -1! -#58000000 -0! -#59000000 -1! -#60000000 -0! -#61000000 -1# -#62000000 -0# -#63000000 -1" -b11 % -b11 , -1( -0) -#64000000 -0" -#65000000 -1! -b100 $ -b11 + -1' -0( -#66000000 -0! -#67000000 -1! -#68000000 -0! -#69000000 -1# -b100 & -b100 * -0' -1) -#70000000 -0# -#71000000 -1# -#72000000 -0# -#73000000 -1! -#74000000 -0! -#75000000 -1" -b100 % -b100 , -1( -0) -#76000000 -0" -#77000000 -1! -b101 $ -b100 + -1' -0( -#78000000 -0! -#79000000 -1! -#80000000 -0! -#81000000 -1! -#82000000 -0! -#83000000 -1" -b101 % -b101 * -0' -1( -#84000000 -0" -#85000000 -1! -#86000000 -0! -#87000000 -1" -#88000000 -0" -#89000000 -1! -#90000000 -0! -#91000000 -1" -#92000000 -0" -#93000000 -1! -#94000000 -0! -#95000000 -1# -b101 & -b101 + -0( -1) -#96000000 -0# -#97000000 -1! -b110 $ -b101 , -1' -0) -#98000000 -0! -#99000000 -1" -b110 % -b110 * -0' -1( -#100000000 -0" -#101000000 -1" -#102000000 -0" -#103000000 -1! -#104000000 -0! -#105000000 -1! -#106000000 -0! -#107000000 -1" -#108000000 -0" -#109000000 -1" -#110000000 -0" -#111000000 -1" -#112000000 -0" -#113000000 -1! -#114000000 -0! -#115000000 -1" -#116000000 -0" -#117000000 -1" -#118000000 -0" -#119000000 -1# -b110 & -b110 + -0( -1) -#120000000 -0# -#121000000 -1! -b111 $ -b110 , -1' -0) -#122000000 -0! -#123000000 -1" -b111 % -b111 * -0' -1( -#124000000 -0" -#125000000 -1# -b111 & -b111 + -0( -1) -#126000000 -0# -#127000000 -1! -b1000 $ -b111 , -1' -0) -#128000000 -0! -#129000000 -1! -#130000000 -0! -#131000000 -1" -b1000 % -b1000 * -0' -1( -#132000000 -0" -#133000000 -1# -b1000 & -b1000 + -0( -1) -#134000000 -0# -#135000000 -1" -b1001 % -b1000 , -1( -0) -#136000000 -0" -#137000000 -1! -b1001 $ -b1001 + -1' -0( -#138000000 -0! -#139000000 -1" -#140000000 -0" -#141000000 -1# -b1001 & -b1001 * -0' -1) -#142000000 -0# -#143000000 -1# -b1010 & -b1001 , -#144000000 -0# -#145000000 -1! -b1010 $ -b1010 , -1' -0) -#146000000 -0! -#147000000 -1# -#148000000 -0# -#149000000 -1! -#150000000 -0! -#151000000 -1! -#152000000 -0! -#153000000 -1! -#154000000 -0! -#155000000 -1# -#156000000 -0# -#157000000 -1! -#158000000 -0! -#159000000 -1" -b1010 % -b1010 * -0' -1( -#160000000 -0" -#161000000 -1! -b1011 $ -b1010 + -1' -0( -#162000000 -0! -#163000000 -1# -b1011 & -b1011 * -0' -1) -#164000000 -0# -#165000000 -1! -#166000000 -0! -#167000000 -1# -#168000000 -0# -#169000000 -1! -#170000000 -0! -#171000000 -1# -#172000000 -0# -#173000000 -1" -b1011 % -b1011 , -1( -0) -#174000000 -0" -#175000000 -1! -b1100 $ -b1011 + -1' -0( -#176000000 -0! -#177000000 -1! -#178000000 -0! -#179000000 -1# -b1100 & -b1100 * -0' -1) -#180000000 -0# -#181000000 -1" -b1100 % -b1100 , -1( -0) -#182000000 -0" -#183000000 -1" -b1101 % -b1100 + -#184000000 -0" -#185000000 -1! -b1101 $ -b1101 + -1' -0( -#186000000 -0! -#187000000 -1# -b1101 & -b1101 * -0' -1) -#188000000 -0# -#189000000 -1" -b1110 % -b1101 , -1( -0) -#190000000 -0" -#191000000 -1# -b1110 & -b1110 + -0( -1) -#192000000 -0# -#193000000 -1! -b1110 $ -b1110 , -1' -0) -#194000000 -0! -#195000000 -1# -b1111 & -b1110 * -0' -1) -#196000000 -0# -#197000000 -1# -#198000000 -0# -#199000000 -1! -b1111 $ -b1111 , -1' -0) -#200000000 -0! -#201000000 -1! -#202000000 -0! -#203000000 -1# -#204000000 -0# -#205000000 -1# -#206000000 -0# -#207000000 -1" -b1111 % -b1111 * -0' -1( -#208000000 -0" -#209000000 -1! -b10000 $ -b1111 + -1' -0( -#210000000 -0! -#211000000 -1# -b10000 & -b10000 * -0' -1) -#212000000 -0# -#213000000 -1# -#214000000 -0# -#215000000 -1# -#216000000 -0# -#217000000 -1" -b10000 % -b10000 , -1( -0) -#218000000 -0" -#219000000 -1! -b10001 $ -b10000 + -1' -0( -#220000000 -0! -#221000000 -1! -#222000000 -0! -#223000000 -1! -#224000000 -0! -#225000000 -1" -b10001 % -b10001 * -0' -1( -#226000000 -0" -#227000000 -1! -#228000000 -0! -#229000000 -1! -#230000000 -0! -#231000000 -1" -#232000000 -0" -#233000000 -1" -#234000000 -0" -#235000000 -1! -#236000000 -0! -#237000000 -1! -#238000000 -0! -#239000000 -1# -b10001 & -b10001 + -0( -1) -#240000000 -0# -#241000000 -1" -b10010 % -b10001 , -1( -0) -#242000000 -0" -#243000000 -1! -b10010 $ -b10010 + -1' -0( -#244000000 -0! -#245000000 -1" -#246000000 -0" -#247000000 -1! -#248000000 -0! -#249000000 -1" -#250000000 -0" -#251000000 -1! -#252000000 -0! -#253000000 -1" -#254000000 -0" -#255000000 -1" -#256000000 -0" -#257000000 -1" -#258000000 -0" -#259000000 -1! -#260000000 -0! -#261000000 -1" -#262000000 -0" -#263000000 -1# -b10010 & -b10010 * -0' -1) -#264000000 -0# -#265000000 -1" -b10011 % -b10010 , -1( -0) -#266000000 -0" -#267000000 -1! -b10011 $ -b10011 + -1' -0( -#268000000 -0! -#269000000 -1# -b10011 & -b10011 * -0' -1) -#270000000 -0# -#271000000 -1! -b10100 $ -b10011 , -1' -0) -#272000000 -0! -#273000000 -1" -b10100 % -b10100 * -0' -1( -#274000000 -0" -#275000000 -1! -#276000000 -0! -#277000000 -1# -b10100 & -b10100 + -0( -1) -#278000000 -0# -#279000000 -1" -b10101 % -b10100 , -1( -0) -#280000000 -0" -#281000000 -1" -#282000000 -0" -#283000000 -1! -b10101 $ -b10101 + -1' -0( -#284000000 -0! -#285000000 -1# -b10101 & -b10101 * -0' -1) -#286000000 -0# -#287000000 -1# -b10110 & -b10101 , -#288000000 -0# -#289000000 -1" -b10110 % -b10110 , -1( -0) -#290000000 -0" -#291000000 -1" -#292000000 -0" -#293000000 -1! -b10110 $ -b10110 + -1' -0( -#294000000 -0! -#295000000 -1! -b10111 $ -b10110 * -#296000000 -0! -#297000000 -1" -b10111 % -b10111 * -0' -1( -#298000000 -0" -#299000000 -1" -#300000000 -0" -#301000000 -1! -#302000000 -0! -#303000000 -1" -#304000000 -0" -#305000000 -1" -#306000000 -0" -#307000000 -1" -#308000000 -0" -#309000000 -1! -#310000000 -0! -#311000000 -1# -b10111 & -b10111 + -0( -1) -#312000000 -0# -#313000000 -1" -b11000 % -b10111 , -1( -0) -#314000000 -0" -#315000000 -1" -#316000000 -0" -#317000000 -1" -#318000000 -0" -#319000000 -1! -b11000 $ -b11000 + -1' -0( -#320000000 -0! -#321000000 -1" -#322000000 -0" -#323000000 -1" -#324000000 -0" -#325000000 -1" -#326000000 -0" -#327000000 -1" -#328000000 -0" -#329000000 -1" -#330000000 -0" -#331000000 -1" -#332000000 -0" -#333000000 -1" -#334000000 -0" -#335000000 -1# -b11000 & -b11000 * -0' -1) -#336000000 -0# -#337000000 -1" -b11001 % -b11000 , -1( -0) -#338000000 -0" -#339000000 -1" -#340000000 -0" -#341000000 -1# -b11001 & -b11001 + -0( -1) -#342000000 -0# -#343000000 -1! -b11001 $ -b11001 , -1' -0) -#344000000 -0! -#345000000 -1" -b11010 % -b11001 * -0' -1( -#346000000 -0" -#347000000 -1" -#348000000 -0" -#349000000 -1# -b11010 & -b11010 + -0( -1) -#350000000 -0# -#351000000 -1" -#352000000 -0" -#353000000 -1" -#354000000 -0" -#355000000 -1" -#356000000 -0" -#357000000 -1# -#358000000 -0# -#359000000 -1# -#360000000 -0# -#361000000 -1" -#362000000 -0" -#363000000 -1# -#364000000 -0# -#365000000 -1! -b11010 $ -b11010 , -1' -0) -#366000000 -0! -#367000000 -1! -b11011 $ -b11010 * -#368000000 -0! -#369000000 -1" -b11011 % -b11011 * -0' -1( -#370000000 -0" -#371000000 -1# -b11011 & -b11011 + -0( -1) -#372000000 -0# -#373000000 -1! -b11100 $ -b11011 , -1' -0) -#374000000 -0! -#375000000 -1" -b11100 % -b11100 * -0' -1( -#376000000 -0" -#377000000 -1" -#378000000 -0" -#379000000 -1# -b11100 & -b11100 + -0( -1) -#380000000 -0# -#381000000 -1! -b11101 $ -b11100 , -1' -0) -#382000000 -0! -#383000000 -1# -b11101 & -b11101 * -0' -1) -#384000000 -0# -#385000000 -1" -b11101 % -b11101 , -1( -0) -#386000000 -0" -#387000000 -1# -b11110 & -b11101 + -0( -1) -#388000000 -0# -#389000000 -1" -b11110 % -b11110 , -1( -0) -#390000000 -0" -#391000000 -1! -b11110 $ -b11110 + -1' -0( -#392000000 -0! -#393000000 -1" -b11111 % -b11110 * -0' -1( -#394000000 -0" -#395000000 -1# -b11111 & -b11111 + -0( -1) -#396000000 -0# -#397000000 -1" -#398000000 -0" -#399000000 -1" -#400000000 -0" -#401000000 -1" -#402000000 -0" -#403000000 -1# -#404000000 -0# -#405000000 -1" -#406000000 -0" -#407000000 -1# -#408000000 -0# -#409000000 -1" -#410000000 -0" -#411000000 -1# -#412000000 -0# -#413000000 -1# -#414000000 -0# -#415000000 -1! -b11111 $ -b11111 , -1' -0) -#416000000 -0! -#417000000 -1" -b100000 % -b11111 * -0' -1( -#418000000 -0" -#419000000 -1# -b100000 & -b100000 + -0( -1) -#420000000 -0# -#421000000 -1# -#422000000 -0# -#423000000 -1" -#424000000 -0" -#425000000 -1" -#426000000 -0" -#427000000 -1# -#428000000 -0# -#429000000 -1# -#430000000 -0# -#431000000 -1# -#432000000 -0# -#433000000 -1# -#434000000 -0# -#435000000 -1! -b100000 $ -b100000 , -1' -0) -#436000000 -0! -#437000000 -1! -b100001 $ -b100000 * -#438000000 -0! -#439000000 -1! -#440000000 -0! -#441000000 -1# -b100001 & -b100001 * -0' -1) -#442000000 -0# -#443000000 -1! -#444000000 -0! -#445000000 -1! -#446000000 -0! -#447000000 -1" -b100001 % -b100001 , -1( -0) -#448000000 -0" -#449000000 -1# -b100010 & -b100001 + -0( -1) -#450000000 -0# -#451000000 -1! -b100010 $ -b100010 , -1' -0) -#452000000 -0! -#453000000 -1! -#454000000 -0! -#455000000 -1# -#456000000 -0# -#457000000 -1# -#458000000 -0# -#459000000 -1! -#460000000 -0! -#461000000 -1" -b100010 % -b100010 * -0' -1( -#462000000 -0" -#463000000 -1! -b100011 $ -b100010 + -1' -0( -#464000000 -0! -#465000000 -1# -b100011 & -b100011 * -0' -1) -#466000000 -0# -#467000000 -1! -#468000000 -0! -#469000000 -1" -b100011 % -b100011 , -1( -0) -#470000000 -0" -#471000000 -1" -b100100 % -b100011 + -#472000000 -0" -#473000000 -1# -b100100 & -b100100 + -0( -1) -#474000000 -0# -#475000000 -1! -b100100 $ -b100100 , -1' -0) -#476000000 -0! -#477000000 -1" -b100101 % -b100100 * -0' -1( -#478000000 -0" -#479000000 -1# -b100101 & -b100101 + -0( -1) -#480000000 -0# -#481000000 -1# -#482000000 -0# -#483000000 -1! -b100101 $ -b100101 , -1' -0) -#484000000 -0! -#485000000 -1# -b100110 & -b100101 * -0' -1) -#486000000 -0# -#487000000 -1! -b100110 $ -b100110 , -1' -0) -#488000000 -0! -#489000000 -1# -#490000000 -0# -#491000000 -1! -#492000000 -0! -#493000000 -1# -#494000000 -0# -#495000000 -1" -b100110 % -b100110 * -0' -1( -#496000000 -0" -#497000000 -1# -b100111 & -b100110 + -0( -1) -#498000000 -0# -#499000000 -1! -b100111 $ -b100111 , -1' -0) -#500000000 -0! -#501000000 -1# -#502000000 -0# -#503000000 -1# -#504000000 -0# -#505000000 -1# -#506000000 -0# -#507000000 -1" -b100111 % -b100111 * -0' -1( -#508000000 -0" -#509000000 -1! -b101000 $ -b100111 + -1' -0( -#510000000 -0! -#511000000 -1! -#512000000 -0! -#513000000 -1# -b101000 & -b101000 * -0' -1) -#514000000 -0# -#515000000 -1" -b101000 % -b101000 , -1( -0) -#516000000 -0" -#517000000 -1! -b101001 $ -b101000 + -1' -0( -#518000000 -0! -#519000000 -1" -b101001 % -b101001 * -0' -1( -#520000000 -0" -#521000000 -1# -b101001 & -b101001 + -0( -1) -#522000000 -0# -#523000000 -1" -b101010 % -b101001 , -1( -0) -#524000000 -0" -#525000000 -1! -b101010 $ -b101010 + -1' -0( -#526000000 -0! -#527000000 -1# -b101010 & -b101010 * -0' -1) -#528000000 -0# -#529000000 -1# -b101011 & -b101010 , -#530000000 -0# -#531000000 -1" -b101011 % -b101011 , -1( -0) -#532000000 -0" -#533000000 -1" -#534000000 -0" -#535000000 -1! -b101011 $ -b101011 + -1' -0( -#536000000 -0! -#537000000 -1# -b101100 & -b101011 * -0' -1) -#538000000 -0# -#539000000 -1" -b101100 % -b101100 , -1( -0) -#540000000 -0" -#541000000 -1" -#542000000 -0" -#543000000 -1" -#544000000 -0" -#545000000 -1# -#546000000 -0# -#547000000 -1" -#548000000 -0" -#549000000 -1" -#550000000 -0" -#551000000 -1# -#552000000 -0# -#553000000 -1# -#554000000 -0# -#555000000 -1" -#556000000 -0" -#557000000 -1# -#558000000 -0# -#559000000 -1! -b101100 $ -b101100 + -1' -0( -#560000000 -0! -#561000000 -1# -b101101 & -b101100 * -0' -1) -#562000000 -0# -#563000000 -1" -b101101 % -b101101 , -1( -0) -#564000000 -0" -#565000000 -1# -#566000000 -0# -#567000000 -1" -#568000000 -0" -#569000000 -1# -#570000000 -0# -#571000000 -1" -#572000000 -0" -#573000000 -1# -#574000000 -0# -#575000000 -1# -#576000000 -0# -#577000000 -1# -#578000000 -0# -#579000000 -1# -#580000000 -0# -#581000000 -1! -b101101 $ -b101101 + -1' -0( -#582000000 -0! -#583000000 -1! -b101110 $ -b101101 * -#584000000 -0! -#585000000 -1# -b101110 & -b101110 * -0' -1) -#586000000 -0# -#587000000 -1# -#588000000 -0# -#589000000 -1! -#590000000 -0! -#591000000 -1" -b101110 % -b101110 , -1( -0) -#592000000 -0" -#593000000 -1# -b101111 & -b101110 + -0( -1) -#594000000 -0# -#595000000 -1# -#596000000 -0# -#597000000 -1! -b101111 $ -b101111 , -1' -0) -#598000000 -0! -#599000000 -1# -#600000000 -0# -#601000000 -1# -#602000000 -0# -#603000000 -1# -#604000000 -0# -#605000000 -1" -b101111 % -b101111 * -0' -1( -#606000000 -0" -#607000000 -1! -b110000 $ -b101111 + -1' -0( -#608000000 -0! -#609000000 -1# -b110000 & -b110000 * -0' -1) -#610000000 -0# -#611000000 -1# -#612000000 -0# -#613000000 -1" -b110000 % -b110000 , -1( -0) -#614000000 -0" -#615000000 -1" -b110001 % -b110000 + -#616000000 -0" -#617000000 -1# -b110001 & -b110001 + -0( -1) -#618000000 -0# -#619000000 -1# -#620000000 -0# -#621000000 -1" -#622000000 -0" -#623000000 -1# -#624000000 -0# -#625000000 -1# -#626000000 -0# -#627000000 -1# -#628000000 -0# -#629000000 -1# -#630000000 -0# -#631000000 -1! -b110001 $ -b110001 , -1' -0) -#632000000 -0! -#633000000 -1# -b110010 & -b110001 * -0' -1) -#634000000 -0# -#635000000 -1# -#636000000 -0# -#637000000 -1# -#638000000 -0# -#639000000 -1" -b110010 % -b110010 , -1( -0) -#640000000 -0" -#641000000 -1# -#642000000 -0# -#643000000 -1# -#644000000 -0# -#645000000 -1# -#646000000 -0# -#647000000 -1# -#648000000 -0# diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.txt deleted file mode 100644 index 7b11157..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.txt +++ /dev/null @@ -1,552 +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(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: AsyncReset, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 3, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.clk, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.rst, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }.clk, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }.rst, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ), - f: ..., - }, - sim_io_to_generator_map: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }: ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }: ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - }, - ], - trace_decls: TraceModule { - name: "sim_resettable_counter", - children: [ - TraceModuleIO { - name: "cd", - child: TraceBundle { - name: "cd", - fields: [ - TraceClock { - location: TraceScalarId(0), - name: "clk", - flow: Source, - }, - TraceAsyncReset { - location: TraceScalarId(1), - name: "rst", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - flow: Source, - }, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - flow: Source, - }, - TraceModuleIO { - name: "out", - child: TraceUInt { - location: TraceScalarId(2), - name: "out", - ty: UInt<8>, - flow: Sink, - }, - ty: UInt<8>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigAsyncReset { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigUInt { - index: StatePartIndex(2), - ty: UInt<8>, - }, - state: 0x03, - last_state: 0x03, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 20 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 16, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: AsyncReset, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: AsyncReset, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: AsyncReset, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - SensitivitySet { - id: 23, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: AsyncReset, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: AsyncReset, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: AsyncReset, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 16, - .. - }, - }, - ), - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 23, - .. - }, - }, - ), - }, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.vcd b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.vcd deleted file mode 100644 index f05658f..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async.vcd +++ /dev/null @@ -1,68 +0,0 @@ -$timescale 1 ps $end -$scope module sim_resettable_counter $end -$scope struct cd $end -$var wire 1 ! clk $end -$var wire 1 " rst $end -$upscope $end -$var wire 8 # out $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -0" -b0 # -$end -#1000000 -1! -b1 # -#2000000 -0! -1" -b0 # -#3000000 -1! -#4000000 -0! -0" -#5000000 -1! -b1 # -#6000000 -0! -#7000000 -1! -b10 # -#8000000 -0! -#9000000 -1! -b11 # -#10000000 -0! -#11000000 -1! -b100 # -#12000000 -0! -1" -b0 # -#13000000 -1! -#14000000 -0! -0" -#15000000 -1! -b1 # -#16000000 -0! -#17000000 -1! -b10 # -#18000000 -0! -#19000000 -1! -b11 # -#20000000 -0! diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.txt deleted file mode 100644 index 0ca767a..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.txt +++ /dev/null @@ -1,552 +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(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: AsyncReset, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 3, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.clk, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.rst, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }.clk, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }.rst, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ), - f: ..., - }, - sim_io_to_generator_map: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }: ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }: ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - }, - ], - trace_decls: TraceModule { - name: "sim_resettable_counter", - children: [ - TraceModuleIO { - name: "cd", - child: TraceBundle { - name: "cd", - fields: [ - TraceClock { - location: TraceScalarId(0), - name: "clk", - flow: Source, - }, - TraceAsyncReset { - location: TraceScalarId(1), - name: "rst", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - flow: Source, - }, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: AsyncReset, - }, - flow: Source, - }, - TraceModuleIO { - name: "out", - child: TraceUInt { - location: TraceScalarId(2), - name: "out", - ty: UInt<8>, - flow: Sink, - }, - ty: UInt<8>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigAsyncReset { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigUInt { - index: StatePartIndex(2), - ty: UInt<8>, - }, - state: 0x03, - last_state: 0x03, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 20 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 13, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: AsyncReset, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: AsyncReset, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: AsyncReset, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - SensitivitySet { - id: 20, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: AsyncReset, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: AsyncReset, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 1, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: AsyncReset, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 13, - .. - }, - }, - ), - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 20, - .. - }, - }, - ), - }, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.vcd b/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.vcd deleted file mode 100644 index 99f7b86..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_async_immediate_reset.vcd +++ /dev/null @@ -1,65 +0,0 @@ -$timescale 1 ps $end -$scope module sim_resettable_counter $end -$scope struct cd $end -$var wire 1 ! clk $end -$var wire 1 " rst $end -$upscope $end -$var wire 8 # out $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -1" -b0 # -$end -#1000000 -1! -#2000000 -0! -#3000000 -1! -#4000000 -0! -0" -#5000000 -1! -b1 # -#6000000 -0! -#7000000 -1! -b10 # -#8000000 -0! -#9000000 -1! -b11 # -#10000000 -0! -#11000000 -1! -b100 # -#12000000 -0! -1" -b0 # -#13000000 -1! -#14000000 -0! -0" -#15000000 -1! -b1 # -#16000000 -0! -#17000000 -1! -b10 # -#18000000 -0! -#19000000 -1! -b11 # -#20000000 -0! diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.txt deleted file mode 100644 index 4af2eb6..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.txt +++ /dev/null @@ -1,507 +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(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: SyncReset, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 3, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.clk, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.rst, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }.clk, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }.rst, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ), - f: ..., - }, - sim_io_to_generator_map: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }: ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }: ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - }, - ], - trace_decls: TraceModule { - name: "sim_resettable_counter", - children: [ - TraceModuleIO { - name: "cd", - child: TraceBundle { - name: "cd", - fields: [ - TraceClock { - location: TraceScalarId(0), - name: "clk", - flow: Source, - }, - TraceSyncReset { - location: TraceScalarId(1), - name: "rst", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - flow: Source, - }, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - flow: Source, - }, - TraceModuleIO { - name: "out", - child: TraceUInt { - location: TraceScalarId(2), - name: "out", - ty: UInt<8>, - flow: Sink, - }, - ty: UInt<8>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigSyncReset { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigUInt { - index: StatePartIndex(2), - ty: UInt<8>, - }, - state: 0x03, - last_state: 0x03, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 20 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 42, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - SensitivitySet { - id: 43, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 42, - .. - }, - SensitivitySet { - id: 43, - .. - }, - }, - ), - }, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.vcd b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.vcd deleted file mode 100644 index 39c2641..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync.vcd +++ /dev/null @@ -1,70 +0,0 @@ -$timescale 1 ps $end -$scope module sim_resettable_counter $end -$scope struct cd $end -$var wire 1 ! clk $end -$var wire 1 " rst $end -$upscope $end -$var wire 8 # out $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -0" -b0 # -$end -#1000000 -1! -b1 # -#2000000 -0! -1" -#3000000 -1! -b10 # -b0 # -#4000000 -0! -0" -#5000000 -1! -b1 # -#6000000 -0! -#7000000 -1! -b10 # -#8000000 -0! -#9000000 -1! -b11 # -#10000000 -0! -#11000000 -1! -b100 # -#12000000 -0! -1" -#13000000 -1! -b101 # -b0 # -#14000000 -0! -0" -#15000000 -1! -b1 # -#16000000 -0! -#17000000 -1! -b10 # -#18000000 -0! -#19000000 -1! -b11 # -#20000000 -0! diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.txt b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.txt deleted file mode 100644 index 45f09d2..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.txt +++ /dev/null @@ -1,507 +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(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.rst", - ty: SyncReset, - }, - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::out", - ty: UInt<8>, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - memories: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - insns: [ - // at: module-XXXXXXXXXX.rs:1:1 - 0: Return, - ], - .. - }, - pc: 0, - memory_write_log: [], - memories: StatePart { - value: [], - }, - small_slots: StatePart { - value: [], - }, - big_slots: StatePart { - value: [ - 0, - 0, - 3, - ], - }, - sim_only_slots: StatePart { - value: [], - }, - }, - io: Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }, - main_module: SimulationModuleState { - base_targets: [ - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - ], - uninitialized_ios: {}, - io_targets: { - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.clk, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.cd.rst, - Instance { - name: ::sim_resettable_counter, - instantiated: Module { - name: sim_resettable_counter, - .. - }, - }.out, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - extern_modules: [ - SimulationExternModuleState { - module_state: SimulationModuleState { - base_targets: [ - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ], - uninitialized_ios: {}, - io_targets: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }.clk, - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }.rst, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - did_initial_settle: true, - clocks_for_past: {}, - }, - sim: ExternModuleSimulation { - generator: SimGeneratorFn { - args: ( - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - ), - f: ..., - }, - sim_io_to_generator_map: { - ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }: ModuleIO { - name: sim_resettable_counter::cd, - is_input: true, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - .. - }, - ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }: ModuleIO { - name: sim_resettable_counter::out, - is_input: false, - ty: UInt<8>, - .. - }, - }, - source_location: SourceLocation( - module-XXXXXXXXXX.rs:4:1, - ), - }, - running_generator: Some( - ..., - ), - }, - ], - trace_decls: TraceModule { - name: "sim_resettable_counter", - children: [ - TraceModuleIO { - name: "cd", - child: TraceBundle { - name: "cd", - fields: [ - TraceClock { - location: TraceScalarId(0), - name: "clk", - flow: Source, - }, - TraceSyncReset { - location: TraceScalarId(1), - name: "rst", - flow: Source, - }, - ], - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - flow: Source, - }, - ty: Bundle { - /* offset = 0 */ - clk: Clock, - /* offset = 1 */ - rst: SyncReset, - }, - flow: Source, - }, - TraceModuleIO { - name: "out", - child: TraceUInt { - location: TraceScalarId(2), - name: "out", - ty: UInt<8>, - flow: Sink, - }, - ty: UInt<8>, - flow: Sink, - }, - ], - }, - traces: [ - SimTrace { - id: TraceScalarId(0), - kind: BigClock { - index: StatePartIndex(0), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(1), - kind: BigSyncReset { - index: StatePartIndex(1), - }, - state: 0x0, - last_state: 0x0, - }, - SimTrace { - id: TraceScalarId(2), - kind: BigUInt { - index: StatePartIndex(2), - ty: UInt<8>, - }, - state: 0x03, - last_state: 0x03, - }, - ], - trace_memories: {}, - trace_writers: [ - Running( - VcdWriter { - finished_init: true, - timescale: 1 ps, - .. - }, - ), - ], - clocks_triggered: [], - event_queue: EventQueue(EventQueueData { - instant: 20 μs, - events: {}, - }), - waiting_sensitivity_sets_by_address: { - SensitivitySet { - id: 43, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - SensitivitySet { - id: 44, - values: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - }, - changed: Cell { - value: false, - }, - .. - }, - }, - waiting_sensitivity_sets_by_compiled_value: { - CompiledValue { - layout: CompiledTypeLayout { - ty: Clock, - layout: TypeLayout { - small_slots: StatePartLayout { - len: 0, - debug_data: [], - .. - }, - big_slots: StatePartLayout { - len: 1, - debug_data: [ - SlotDebugData { - name: "InstantiatedModule(sim_resettable_counter: sim_resettable_counter).sim_resettable_counter::cd.clk", - ty: Clock, - }, - ], - .. - }, - sim_only_slots: StatePartLayout { - len: 0, - debug_data: [], - layout_data: [], - .. - }, - }, - body: Scalar, - }, - range: TypeIndexRange { - small_slots: StatePartIndexRange { start: 0, len: 0 }, - big_slots: StatePartIndexRange { start: 0, len: 1 }, - sim_only_slots: StatePartIndexRange { start: 0, len: 0 }, - }, - write: None, - }: ( - SimValue { - ty: Clock, - value: OpaqueSimValue { - bits: 0x0_u1, - sim_only_values: [], - }, - }, - { - SensitivitySet { - id: 43, - .. - }, - SensitivitySet { - id: 44, - .. - }, - }, - ), - }, - .. -} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.vcd b/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.vcd deleted file mode 100644 index 3cb97e2..0000000 --- a/crates/fayalite/tests/sim/expected/sim_resettable_counter_sync_immediate_reset.vcd +++ /dev/null @@ -1,70 +0,0 @@ -$timescale 1 ps $end -$scope module sim_resettable_counter $end -$scope struct cd $end -$var wire 1 ! clk $end -$var wire 1 " rst $end -$upscope $end -$var wire 8 # out $end -$upscope $end -$enddefinitions $end -$dumpvars -0! -1" -b0 # -$end -#1000000 -1! -b1 # -b0 # -#2000000 -0! -#3000000 -1! -b1 # -b0 # -#4000000 -0! -0" -#5000000 -1! -b1 # -#6000000 -0! -#7000000 -1! -b10 # -#8000000 -0! -#9000000 -1! -b11 # -#10000000 -0! -#11000000 -1! -b100 # -#12000000 -0! -1" -#13000000 -1! -b101 # -b0 # -#14000000 -0! -0" -#15000000 -1! -b1 # -#16000000 -0! -#17000000 -1! -b10 # -#18000000 -0! -#19000000 -1! -b11 # -#20000000 -0! diff --git a/crates/fayalite/tests/ui/module.rs b/crates/fayalite/tests/ui/module.rs index ee0f988..36649aa 100644 --- a/crates/fayalite/tests/ui/module.rs +++ b/crates/fayalite/tests/ui/module.rs @@ -11,20 +11,4 @@ pub fn my_module(a: i32, m: u32, (m, _): (i32, u32)) { let o: UInt<8> = m.output(); } -#[hdl_module] -pub fn my_module2(platform_io_builder: PlatformIOBuilder<'_>) { - #[hdl] - let a: UInt<8> = m.input(); - #[hdl] - let b: UInt<8> = m.output(); - #[hdl] - let io = m.add_platform_io(platform_io_builder); - #[hdl] - let c: UInt<8> = m.input(); - #[hdl] - let d: UInt<8> = m.output(); - #[hdl] - let io = m.add_platform_io(platform_io_builder); -} - fn main() {} diff --git a/crates/fayalite/tests/ui/module.stderr b/crates/fayalite/tests/ui/module.stderr index 979e76f..efbd1fe 100644 --- a/crates/fayalite/tests/ui/module.stderr +++ b/crates/fayalite/tests/ui/module.stderr @@ -1,47 +1,17 @@ -error: name conflicts with implicit `m: &ModuleBuilder` +error: name conflicts with implicit `m: &mut ModuleBuilder<_>` --> tests/ui/module.rs:7:26 | 7 | pub fn my_module(a: i32, m: u32, (m, _): (i32, u32)) { | ^ -error: name conflicts with implicit `m: &ModuleBuilder` +error: name conflicts with implicit `m: &mut ModuleBuilder<_>` --> tests/ui/module.rs:7:35 | 7 | pub fn my_module(a: i32, m: u32, (m, _): (i32, u32)) { | ^ -error: name conflicts with implicit `m: &ModuleBuilder` +error: name conflicts with implicit `m: &mut ModuleBuilder<_>` --> tests/ui/module.rs:9:9 | 9 | let m: UInt<8> = m.input(); | ^ - -error: can't have other inputs/outputs in a module using m.add_platform_io() - --> tests/ui/module.rs:17:24 - | -17 | let a: UInt<8> = m.input(); - | ^^^^^ - -error: can't have other inputs/outputs in a module using m.add_platform_io() - --> tests/ui/module.rs:19:24 - | -19 | let b: UInt<8> = m.output(); - | ^^^^^^ - -error: can't have other inputs/outputs in a module using m.add_platform_io() - --> tests/ui/module.rs:23:24 - | -23 | let c: UInt<8> = m.input(); - | ^^^^^ - -error: can't have other inputs/outputs in a module using m.add_platform_io() - --> tests/ui/module.rs:25:24 - | -25 | let d: UInt<8> = m.output(); - | ^^^^^^ - -error: can't use m.add_platform_io() more than once in a single module - --> tests/ui/module.rs:27:16 - | -27 | let io = m.add_platform_io(platform_io_builder); - | ^^^^^^^^^^^^^^^ diff --git a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr index 7191e5e..03c62bf 100644 --- a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr +++ b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr @@ -4,14 +4,14 @@ error[E0277]: `Cell` cannot be shared between thr 11 | fn f(v: SimValue<()>) -> Interned> { | ^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell` = 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 `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -28,13 +28,13 @@ error[E0277]: `UnsafeCell>` cannot be shared between th 11 | fn f(v: SimValue<()>) -> Interned> { | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` 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 `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -51,7 +51,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta 11 | fn f(v: SimValue<()>) -> Interned> { | ^^^^^^^^^^^^^^^^^^^^^^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` + = help: within `SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` note: required because it appears within the type `DynSimOnlyValue` --> src/sim/value/sim_only_value_unsafe.rs | @@ -92,7 +92,7 @@ note: required because it appears within the type `util::alternating_cell::Alter | | pub(crate) struct AlternatingCell { | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -103,15 +103,29 @@ note: required by a bound in `fayalite::intern::Interned` | pub struct Interned { | ^^^^ required by this bound in `Interned` -error[E0277]: the trait bound `fayalite::prelude::SimValue<()>: Intern` is not satisfied +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 `fayalite::prelude::SimValue<()>` + | -------------------- ^ the trait `Hash` is not implemented for `SimValue<()>` | | | required by a bound introduced by this call | - = note: required for `fayalite::prelude::SimValue<()>` to implement `Intern` + = note: required for `SimValue<()>` to implement `Intern` +help: consider dereferencing here + | +12 | Intern::intern_sized(*v) + | + + +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<()>` + | | + | required by a bound introduced by this call + | + = note: required for `SimValue<()>` to implement `Intern` help: consider dereferencing here | 12 | Intern::intern_sized(*v) @@ -125,14 +139,14 @@ error[E0277]: `Cell` cannot be shared between thr | | | required by a bound introduced by this call | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell` = 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 `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -142,7 +156,7 @@ note: required by a bound in `intern_sized` | | 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 help: consider dereferencing here @@ -158,13 +172,13 @@ error[E0277]: `UnsafeCell>` cannot be shared between th | | | required by a bound introduced by this call | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` 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 `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -174,7 +188,7 @@ note: required by a bound in `intern_sized` | | 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 help: consider dereferencing here @@ -190,7 +204,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta | | | required by a bound introduced by this call | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` + = help: within `SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` note: required because it appears within the type `DynSimOnlyValue` --> src/sim/value/sim_only_value_unsafe.rs | @@ -231,7 +245,7 @@ note: required because it appears within the type `util::alternating_cell::Alter | | pub(crate) struct AlternatingCell { | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -241,7 +255,7 @@ note: required by a bound in `intern_sized` | | 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 help: consider dereferencing here @@ -255,14 +269,14 @@ error[E0277]: `Cell` cannot be shared between thr 12 | Intern::intern_sized(v) | ^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell` = 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 `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -279,13 +293,13 @@ error[E0277]: `UnsafeCell>` cannot be shared between th 12 | Intern::intern_sized(v) | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` 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 `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { @@ -302,7 +316,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta 12 | Intern::intern_sized(v) | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` + = help: within `SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` note: required because it appears within the type `DynSimOnlyValue` --> src/sim/value/sim_only_value_unsafe.rs | @@ -343,7 +357,7 @@ note: required because it appears within the type `util::alternating_cell::Alter | | pub(crate) struct AlternatingCell { | ^^^^^^^^^^^^^^^ -note: required because it appears within the type `fayalite::prelude::SimValue<()>` +note: required because it appears within the type `SimValue<()>` --> src/sim/value.rs | | pub struct SimValue { diff --git a/crates/fayalite/visit_types.json b/crates/fayalite/visit_types.json index a74cef9..effbd82 100644 --- a/crates/fayalite/visit_types.json +++ b/crates/fayalite/visit_types.json @@ -162,7 +162,6 @@ "$kind": "Struct", "verilog_name": "Visible", "parameters": "Visible", - "clocks_for_past": "Visible", "simulation": "Visible" } }, @@ -1177,8 +1176,7 @@ "BlackBoxInline": "Visible", "BlackBoxPath": "Visible", "DocString": "Visible", - "CustomFirrtl": "Visible", - "Xilinx": "Visible" + "CustomFirrtl": "Visible" } }, "DontTouchAnnotation": { @@ -1216,29 +1214,6 @@ "$kind": "Opaque" } }, - "XilinxAnnotation": { - "data": { - "$kind": "Enum", - "XdcLocation": "Visible", - "XdcIOStandard": "Visible", - "XdcCreateClock": "Visible" - } - }, - "XdcLocationAnnotation": { - "data": { - "$kind": "Opaque" - } - }, - "XdcIOStandardAnnotation": { - "data": { - "$kind": "Opaque" - } - }, - "XdcCreateClockAnnotation": { - "data": { - "$kind": "Opaque" - } - }, "Target": { "data": { "$kind": "Enum", diff --git a/rocq-demo/rocq_hdl.v b/rocq-demo/rocq_hdl.v deleted file mode 100644 index 7408226..0000000 --- a/rocq-demo/rocq_hdl.v +++ /dev/null @@ -1,171 +0,0 @@ -(* SPDX-License-Identifier: LGPL-3.0-or-later - See Notices.txt for copyright information *) - -(* This file demonstrates converting simple HDL designs into Rocq, as well - as proofs by induction that parallels those of formal verification in - Symbiyosys with the "smtbmc" engine in the "prove" mode. *) - -(* Models a simple register, feeding back to itself. We prove that, - when initialized to zero, it stays always at zero. *) -Module simple_register. - - (* State record. Contains only one boolean variable, which we call "a" *) - Record S := { a: bool }. - (* The above automatically defines an accessor function "a: S->bool", so - we can write "a s" to get the value of "a" in state "s". *) - - (* Defines an "initial" predicate, so "initial s" means - "s is an initial state". In our case, the value of "a" - in the initial state is zero (false) *) - Definition initial (s: S) := - a s = false. - (* As an example, we construct a state where "a" is indeed false, - and prove it is an initial state. The syntax for instantiating - such a record is "{| a := false |}". *) - Example test_initial: initial {| a := false |}. - Proof. reflexivity. Qed. - - (* Defines an "assert" predicate, so "assert s" means "assertions - hold in state s" or equivalently "state s is valid". In our case, - valid states correspond to those where "a" is false. *) - Definition assert (s: S) := - a s = false. - - (* The following proof by induction follows the article "Temporal - Induction by Incremental SAT Solving", - https://doi.org/10.1016/S1571-0661(05)82542-3 *) - (* Proves the base case, with one step: the initial state is a - valid state. *) - Theorem base1: forall s0, initial s0 -> assert s0. - Proof. trivial. Qed. - - (* Defines a "transition" predicate, so "t s1 s2" means: - "s2 can be reached in one step from s1". In our case, - the value of "a" in s2 is the same as in s1. *) - Definition t (s1 s2 : S) := - a s2 = a s1. - - (* Induction principle: for all transitions from a valid state, - we reach a valid state. *) - Theorem induct1: - forall s0 s1, assert s0 -> t s0 s1 -> assert s1. - Proof. - unfold t, assert. - intros s0 s1 A T. - transitivity (a s0). - apply T. apply A. - Qed. - (* Here we have proven the base case and the inductive case, so we - declare success. However, we may want to formalize it from first - principles, something like "All reacheable states from an initial - state are valid", and use the above theorems to prove it (TODO). *) - - (* Example: all states reacheable in one step from the initial state - are valid. *) - Example one_step_valid: - forall s0 s1, initial s0 -> t s0 s1 -> assert s1. - Proof. - unfold initial, t, assert. - intros s0 s1 I T. - transitivity (a s0). - apply T. apply I. - Qed. - (* Same as above, but we prove using only the induction theorems. *) - Example one_step_valid': - forall s0 s1, initial s0 -> t s0 s1 -> assert s1. - Proof. - apply induct1. - Qed. -End simple_register. - -(* The same circuit as above, but with an additional output register. - The output is asserted to be always false, but no such restriction - is made on the inner register, a "hidden" state. It creates a - difficulty for induction: there are unreacheable valid states that - leads to invalid states. A two step induction solves the problem. *) -Module hidden_state. - (* Demonstrate state with several (two) variables. *) - Record S := - { a: bool - ; b: bool - }. - (* Both registers start at zero (false). *) - Definition initial (s: S) := - a s = false /\ b s = false. - (* Just b is constrained to be zero (false) *) - Definition assert (s: S) := - b s = false. - (* "a" keeps its previous value, "b" copies "a". *) - Definition t (s1 s2 : S) := - a s2 = a s1 /\ b s2 = a s1. - (* Base case in one step. *) - Theorem base1: - forall s0, - initial s0 -> assert s0. - Proof. - unfold initial, assert. - intros s0 [_ H]. - apply H. - Qed. - (* Try proving the inductive case in one step. *) - Theorem induct1: - forall s0 s1, - assert s0 -> t s0 s1 -> assert s1. - Proof. - unfold t, assert. - intros s0 s1 A T. - destruct T as [_ Tb]. - transitivity (a s0). apply Tb. - Abort. - (* Ops, we reach a dead-end. Maybe it's not provable after all? - Try proving its negation by finding a counter-example. *) - Theorem not_induct1: - not (forall s0 s1, - assert s0 -> t s0 s1 -> assert s1). - Proof. - unfold not, assert, t. - intros H. - specialize H with (s0 := {|a := true; b := false|}). - simpl in H. - specialize H with (s1 := {|a := true; b := true|}). - simpl in H. - discriminate H. reflexivity. auto. - Qed. - (* Indeed, a valid state where "a" is one (true) leads to - an invalid state. Try one more step. *) - Theorem base2: - forall s0 s1, - initial s0 -> assert s0 -> t s0 s1 -> assert s1. - Proof. - intros s0 s1 [Ia _] _ [_ Tb]. - unfold assert. - transitivity (a s0). apply Tb. - apply Ia. - Qed. - Theorem induct2: - forall s0 s1 s2, - assert s0 -> t s0 s1 -> assert s1 -> t s1 s2 -> assert s2. - Proof. - intros s0 s1 s2 A0 [T0a T0b] A1 [T1a T1b]. - unfold assert in *. - transitivity (a s1). apply T1b. - transitivity (a s0). apply T0a. - transitivity (b s1). symmetry. apply T0b. - apply A1. - Qed. - (* Success! Two steps indeed work. *) - - (* Example: all states reacheable in two steps are valid *) - Example two_steps_valid: - forall s0 s1 s2, - initial s0 -> t s0 s1 -> t s1 s2 -> assert s2. - Proof. - intros s0 s1 s2. - intros Hi T01. - apply induct2 with (s0 := s0). - - apply base1. apply Hi. - - apply T01. - - apply base2 with (s0 := s0). - apply Hi. apply base1. apply Hi. apply T01. - Qed. -End hidden_state. diff --git a/scripts/check-copyright.sh b/scripts/check-copyright.sh index 023cd21..3651931 100755 --- a/scripts/check-copyright.sh +++ b/scripts/check-copyright.sh @@ -32,7 +32,6 @@ POUND_HEADER=('^"# SPDX-License-Identifier: LGPL-3.0-or-later"$' '^"# See Notice SLASH_HEADER=('^"// SPDX-License-Identifier: LGPL-3.0-or-later"$' '^"// See Notices.txt for copyright information"$') MD_HEADER=('^"