From 7ebbedb0509368ce9add24dc5f812e72487923a6 Mon Sep 17 00:00:00 2001 From: Thomas Dybdahl Ahle Date: Thu, 1 Oct 2026 21:13:11 +0000 Subject: [PATCH 1/3] feat: add wide four-state readmem chapter Mechanism: source-bound runnable lesson plus native/reference receipt guard. --- CURRICULUM.md | 5 + artifacts/tutorial/SUMMARY.md | 13 +- artifacts/tutorial/content-census.md | 6 +- artifacts/tutorial/wide-readmem/README.md | 69 +++++++ artifacts/tutorial/wide-readmem/browser-qa.md | 15 ++ .../wide-readmem/solution-compile.log | 188 ++++++++++++++++++ .../tutorial/wide-readmem/solution-import.log | 0 .../wide-readmem/solution-interpret.log | 19 ++ .../wide-readmem/solution-refdiff.json | 1 + .../tutorial/wide-readmem/starter-compile.log | 188 ++++++++++++++++++ .../tutorial/wide-readmem/starter-import.log | 0 .../wide-readmem/starter-interpret.log | 19 ++ .../wide-readmem/starter-refdiff.json | 1 + src/lessons/index.js | 1 + src/lessons/landed-capabilities.test.js | 35 +++- src/lessons/meta.js | 1 + src/lessons/receipt-matrix.test.js | 3 +- src/lessons/sv/wide-readmem/description.html | 11 + .../sv/wide-readmem/wide_readmem.sol.sv | 22 ++ src/lessons/sv/wide-readmem/wide_readmem.sv | 22 ++ 20 files changed, 614 insertions(+), 5 deletions(-) create mode 100644 artifacts/tutorial/wide-readmem/README.md create mode 100644 artifacts/tutorial/wide-readmem/browser-qa.md create mode 100644 artifacts/tutorial/wide-readmem/solution-compile.log create mode 100644 artifacts/tutorial/wide-readmem/solution-import.log create mode 100644 artifacts/tutorial/wide-readmem/solution-interpret.log create mode 100644 artifacts/tutorial/wide-readmem/solution-refdiff.json create mode 100644 artifacts/tutorial/wide-readmem/starter-compile.log create mode 100644 artifacts/tutorial/wide-readmem/starter-import.log create mode 100644 artifacts/tutorial/wide-readmem/starter-interpret.log create mode 100644 artifacts/tutorial/wide-readmem/starter-refdiff.json create mode 100644 src/lessons/sv/wide-readmem/description.html create mode 100644 src/lessons/sv/wide-readmem/wide_readmem.sol.sv create mode 100644 src/lessons/sv/wide-readmem/wide_readmem.sv diff --git a/CURRICULUM.md b/CURRICULUM.md index 00c4999..a9773c6 100644 --- a/CURRICULUM.md +++ b/CURRICULUM.md @@ -63,6 +63,11 @@ Flag numbers identify the weak dimension(s): 1=Concept Focus, 2=Starter Calibrat |---|---|---|---|---|---| | `sv/virtual-provider-closure` | Virtual Method Provider Closure | ✅ | — | `sv/classes` | virtual overrides, base-class handles, and native AOT provider retention | +### Chapter: Wide Four-State Memory Loading (October 2026) +| Slug | Title | Status | Score | Prereqs | Teaches | +|---|---|---|---|---|---| +| `sv/wide-readmem` | Wide Four-State Memory Loading | ✅ | — | `sv/always-ff` | `$readmemh`, address ranges, and non-power-of-two four-state packed words | + ### Chapter: Introduction | Slug | Title | Status | Score | Prereqs | Teaches | |---|---|---|---|---|---| diff --git a/artifacts/tutorial/SUMMARY.md b/artifacts/tutorial/SUMMARY.md index b7f0c7c..096587f 100644 --- a/artifacts/tutorial/SUMMARY.md +++ b/artifacts/tutorial/SUMMARY.md @@ -90,7 +90,7 @@ One commit per issue, each with the test that fails before it and passes after: ### Landed capability chapters -Added six one-lesson chapters for user-facing SystemVerilog capabilities +Added seven one-lesson chapters for user-facing SystemVerilog capabilities landed in Mox between September 22 and October 1, 2026. The UDP chapter tracks landing tip `36b040f6190c`, and the virtual-provider chapter tracks `3bc88e77921e`; the pinned browser WASM remains unchanged. @@ -103,6 +103,7 @@ tracks landing tip `36b040f6190c`, and the virtual-provider chapter tracks | `sv/nested-child-input` | §§23.2.2, 9.4.2 | starter FAIL; solution PASS in interpreter and compile modes | solution PASS; output equal | `artifacts/tutorial/capability-receipts/*nested-child-input*` | | `sv/sequential-udp-init` | §§29.3.2, 29.6, 29.7 | starter FAIL; solution PASS in interpreter and compile modes | starter both_fail; solution PASS; output equal | `artifacts/tutorial/capability-receipts/*sequential-udp-init*` | | `sv/virtual-provider-closure` | §§8.20, 8.22 | starter FAIL; solution PASS in interpreter and compile modes | starter both_fail; solution both_pass; output equal | `artifacts/tutorial/virtual-provider-closure/*` | +| `sv/wide-readmem` | §§21.4, 21.4.1 | starter FAIL; solution PASS in interpreter and compile modes | starter both_fail; solution both_pass; output equal | `artifacts/tutorial/wide-readmem/*` | The capability receipt summaries are in `artifacts/tutorial/capability-receipts/{summary,final-summary}.tsv`. @@ -162,6 +163,16 @@ an expected known failure until a WASM rebuild. The cross-include limitation from the protected-envelope audit is stated in the lesson rather than hidden. Receipts are under `artifacts/tutorial/protected-envelope-boundary/`. +### Wide four-state memory-loading chapter + +`sv/wide-readmem` teaches `$readmemh` address ranges and four-state packed +words whose width is not a power of two. The 64-bit starter fails its check; +the 65-bit solution passes in native interpreter and compile modes. Xcelium +and Mox agree: the starter is `both_fail` and the solution is `both_pass`. +The focused browser run is 1/1 through the pinned interpreter-backed WASM +fallback, not native AOT. Receipts and the Mox landing provenance are under +`artifacts/tutorial/wide-readmem/`. + ## WASM rebuild (done locally, NOT published; release `mox-wasm` is unchanged) Built with emsdk 4.0.21 from Mox main `9c5418532b9` (and landing `ea0fcd2`): mox-verilog, mox-sim, mox-bmc and mox-lec. Mox has no wasm target for mox-run (GAPS TUT-WASM-MOXRUN), so two more commits went in: diff --git a/artifacts/tutorial/content-census.md b/artifacts/tutorial/content-census.md index 2109cd4..886deb3 100644 --- a/artifacts/tutorial/content-census.md +++ b/artifacts/tutorial/content-census.md @@ -15,11 +15,12 @@ repository is now Mox `origin/main` at behavior tip `a0c4488a587d753fa9f26d465814aaa44e77586e` are listed below. The intermediate binary is not evidence that this binary is published; its unqualified readmem change was reverted by `4d6185ae036d939c9b7266fe89a25f92ed9c294e` -before the current source tip, and no lesson source uses readmem. +before the current source tip; the new `sv/wide-readmem` lesson is the +tutorial's runnable coverage for the landed readmem behavior. ## New landed-capability chapters -These eight short chapters correspond to the user-facing Mox capabilities present +These nine short chapters correspond to the user-facing Mox capabilities present on the current `origin/main` by October 1, 2026. The compile-mode status page is listed separately below because it reports qualification status rather than teaching a new language capability. Every solution passes Mox in both @@ -37,6 +38,7 @@ attempts decryption without a key. | `sv/virtual-provider-closure` | `3bc88e77921e5e776411d00e133f2b497c750943`, Mox mapped-vlib provider-closure regression | §§8.20, 8.22: virtual overrides dispatch through a base-class handle to the derived object. | solution PASS; starter FAIL | solution PASS; starter FAIL | both PASS, output equal | added a base-handle/derived-provider dispatch exercise | | `sv/clocking-sampler-retention` | `3b1760ff2030378cfde16ca319e2c1b806ab9d31`, `test/Tools/mox-sim/mq93-m2-clock-sampler.sv` | §§14.3, 14.13: default `1step` samples before the clock event; explicit `#0` samples in Observed and retains the sample through same-slot re-entry. | solution PASS; starter FAIL | solution PASS; starter FAIL | both PASS / both FAIL, output equal | added an explicit-`#0` sampler-retention exercise | | `sv/protected-envelope-boundary` | `c3799f427f1e51abcd389dcf15771150223cae75`, `test/Conversion/ImportVerilog/protected-comment-callback.sv` | §§34.2, 34.3, 34.4, 34.5.3–34.5.4: protected text is transformed before analysis and delimiters close the envelope; this lesson does not claim decryption. | solution PASS; starter FAIL | solution PASS; starter FAIL | `reference_only_fail` for solution; Xcelium attempts unkeyed decryption | added same-buffer opaque callback-boundary exercise | +| `sv/wide-readmem` | `e7da9630dcd`, `test/Tools/mox-sim/aot-readmem-wide-fourstate.sv` | §§21.4, 21.4.1: `$readmemh` accepts optional address bounds and loads packed elements of an unpacked memory, preserving four-state digits. | solution PASS; starter FAIL | solution PASS; starter FAIL | starter `both_fail`; solution `both_pass`, output equal | added a width-calibration readmem exercise | The remaining current-main capability commits are queued for their own short chapters and are not silently folded into an existing lesson: coverage-option diff --git a/artifacts/tutorial/wide-readmem/README.md b/artifacts/tutorial/wide-readmem/README.md new file mode 100644 index 0000000..df24245 --- /dev/null +++ b/artifacts/tutorial/wide-readmem/README.md @@ -0,0 +1,69 @@ +# Wide four-state memory-loading receipt + +This receipt supports `sv/wide-readmem`. The lesson teaches that +`$readmemh` loads packed words into an unpacked memory, including explicit +start and finish addresses and four-state hexadecimal data. The starter uses a +64-bit word for 65-bit file values; the solution uses a 65-bit word. + +## Standard and landing basis + +IEEE 1800-2023 §21.4 defines `$readmemb` and `$readmemh`, including the +optional `start_addr` and `finish_addr` arguments. Section §21.4.1 says these +system tasks support unpacked arrays of packed data and treat each packed +element as the vector equivalent. Section §21.4 also permits `x`, `z`, and +underscores in the hexadecimal numbers. The lesson uses those rules directly; +it does not claim behavior for dynamic or associative arrays. + +The native capability landed in Mox commit `e7da9630dcd` +(`9cd0fcd389e505f9b031a8b99a347888181e9451`), recorded by +`/var/tmp/thomas-ahle/fleet/artifacts/landing/push-e7da9630dcd.md`. Its exact- +tip focused controls passed 3/3 in each of three trials. The native receipt +uses `/var/tmp/thomas-ahle/wt/landing/build-dev-fast` at +`35ec19ea7f9398d76cf704252703ae731dad04d5`, whose parent contains the landed +readmem change. No Mox worktree was modified. + +## Native runs + +The native runs use CPUs `0-79` and a 30-second wall guard. This build has no +`mox-run`, so the runtime uses the `mox-verilog` plus `mox-sim` path. The +committed logs are `starter-import.log`, `starter-interpret.log`, +`starter-compile.log`, `solution-import.log`, `solution-interpret.log`, and +`solution-compile.log`. + +| variant | mode | exit | first result line | +|---|---:|---:|---| +| starter | interpret | 0 | `FAIL: 0123456789abcdef fedcba9876543210 0000000000000000` | +| starter | compile | 0 | `FAIL: 0123456789abcdef fedcba9876543210 0000000000000000` | +| solution | interpret | 0 | `PASS` | +| solution | compile | 0 | `PASS` | + +The solution compile receipt reports `AOT interpreter invocations total: 0`. +The browser asset is older than this landing and therefore the browser result +does not qualify native AOT. + +## Differential runs + +`refdiff` was run on each committed fixture against the same native build: + +```text +/var/tmp/thomas-ahle/fleet/bin/refdiff src/lessons/sv/wide-readmem/wide_readmem.sv --build-dir /var/tmp/thomas-ahle/wt/landing/build-dev-fast +/var/tmp/thomas-ahle/fleet/bin/refdiff src/lessons/sv/wide-readmem/wide_readmem.sol.sv --build-dir /var/tmp/thomas-ahle/wt/landing/build-dev-fast +``` + +- `starter-refdiff.json`: `both_fail`; Xcelium and Mox reject the too-narrow + memory through the test's value check. +- `solution-refdiff.json`: `both_pass`; outputs are equivalent. +- Both JSON receipts bind their `sha256` values to the committed source and + retain their `refdiff_cache_key` values. + +## Browser qualification + +The focused Playwright run passed 1/1: + +```text +npx playwright test e2e/qa-all-lessons.spec.js --grep 'Wide Four-State Memory Loading' --reporter=line +``` + +The route used the pinned interpreter-backed WASM fallback because +`/mox/mox-run.js` is absent. This is browser interpreter qualification only, +not native AOT qualification. diff --git a/artifacts/tutorial/wide-readmem/browser-qa.md b/artifacts/tutorial/wide-readmem/browser-qa.md new file mode 100644 index 0000000..2443589 --- /dev/null +++ b/artifacts/tutorial/wide-readmem/browser-qa.md @@ -0,0 +1,15 @@ +# Browser QA receipt + +Command: + +```text +npx playwright test e2e/qa-all-lessons.spec.js --grep 'Wide Four-State Memory Loading' --reporter=line +``` + +Result: `1 passed` (`e2e/qa-all-lessons.spec.js:66:5`, lesson `[31]`, +`run`), wall time `48.1s`. + +The web server logged a 404 for `/mox/mox-run.js`; this is the expected +toolchain fallback. The route completed through the pinned `mox-verilog` plus +`mox-sim` interpreter path, so this receipt does not qualify browser native +AOT. diff --git a/artifacts/tutorial/wide-readmem/solution-compile.log b/artifacts/tutorial/wide-readmem/solution-compile.log new file mode 100644 index 0000000..e97dae1 --- /dev/null +++ b/artifacts/tutorial/wide-readmem/solution-compile.log @@ -0,0 +1,188 @@ +[mox-sim] Lowering --ir-sim semantic IR to simulation IR +[mox-sim] Stage: semantic-lower (prev: 9ms, total: 9ms) +[mox-sim] Auto-enabling --skip-passes for module marked mox.sim.preprocessed +[mox-sim] Stage: passes (prev: 0ms, total: 9ms) +[mox-sim] Replaying lowered semantic module in fresh mox-sim process +[mox-sim] Stage: passes (prev: 0ms, total: 0ms) +[mox-sim] aot-publication/v2 domain=module-loader-functions expected=0 accounted=0 positive=0 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:14a1ea4827eceb6099f752ac175f21d9feeed50ece269718c7050338ed779cdd +[mox-sim] aot-publication/v2 domain=module-loader-processes expected=1 accounted=1 positive=1 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:dbece0947e8df29c3d674a06bb85a08e2b7bd4a0382cd6522ab2c5fa69007e8e +[mox-sim] aot-publication/v2 domain=module-loader-address-bound-globals expected=32 accounted=32 positive=32 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:17607e7120748f03aaf68b5d0f133fe3ca04d66817f73b472f76f7b036e78d38 +[mox-sim] aot-publication/v2 domain=module-loader-entry-table expected=0 accounted=0 positive=0 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:14a1ea4827eceb6099f752ac175f21d9feeed50ece269718c7050338ed779cdd +[mox-sim] Loaded compiled module '/tmp/mox-scratch/a8e5ccd3bff512bd85be743cbbba161ae06504793c695db14b39d861ac39713b/session-1fb1fd4a014147838134434ee843a6815e7850920bfa88c2bb102ffbfca8a377/mox-sim-autocompile-6d735a.so': 0 functions, 1 processes, 32 address-bound globals (build: mox-sim-abi-v19-x86_64-unknown-linux-gnu-f9af9d42595c7adbd44bd5ac9124b559) +[mox-sim] Address-bound global ownership: role=main, module='/tmp/mox-scratch/a8e5ccd3bff512bd85be743cbbba161ae06504793c695db14b39d861ac39713b/session-1fb1fd4a014147838134434ee843a6815e7850920bfa88c2bb102ffbfca8a377/mox-sim-autocompile-6d735a.so', descriptor-declared=32, retained=32 +[mox-sim] M3 loaded callable union: artifacts=1 raw-rows=0 demand-rows=0 distinct-demand-keys=0 slot-rows=0 provider-rows=0 checked-keys=0 missing=0 duplicate=0 malformed=0 unresolved=0 dropped=0 digest=sha256:d8d233628e5049177e41e82173d962a88232c360616e99ab696e3aa2a22b36e5 status=ok +[mox-sim] Stage: init (prev: 153ms, total: 153ms) +[mox-sim] Pre-aliased 32 address-bound globals to .so storage +[mox-sim] Unmapped native func.call policy: default deny runtime bridges and pointer-typed get_/set_/create_/m_initialize* (allow others) +[mox-sim] Loaded 0 compiled functions: 0 native-dispatched, 0 not-native-dispatched, 0 intercepted +[mox-sim] aot-publication/v2 domain=compiled-function-dispatch expected=0 accounted=0 positive=0 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:14a1ea4827eceb6099f752ac175f21d9feeed50ece269718c7050338ed779cdd +[mox-sim] Address-bound final-LLVM-global probes: 32/32 rows, 590/590 bytes bidirectional, owner-generation=1 +[mox-sim] Compiled process dispatch: 1/1 processes wired +[mox-sim] aot-publication/v2 domain=process-dispatch expected=1 accounted=1 positive=1 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:979054643387faf73ad0f08f4cac05733060ee3d4ac3b9ff2b77a69eefd36c41 +[mox-sim] aot-publication/v2 domain=process-dispatch identity='tb.process_0' outcome=wired polarity=positive reason='' +[mox-sim] Stage: load-compiled (prev: 3ms, total: 157ms) +[mox-sim] Found 1 LLHD processes, 0 LLHD finals, 0 seq.initial blocks, and 0 hw.instance ops (out of 129 total ops) in module +[mox-sim] Registered 4 LLHD signals and 1 LLHD processes/initial blocks +[mox-sim] Receipt: INIT_COMPLETE_OK execution_failure=0 process_dispatches=0 +[mox-sim] Stage: run (prev: 0ms, total: 157ms) +[mox-sim] Starting simulation +PASS +[mox-sim] Simulation terminated at time 0 fs (success=true, verbose=true) +[mox-sim] Main loop exit: shouldContinue()=false at time 0 fs, iter=1, deltas=1 +[mox-sim] Simulation finished at time 0 fs +[mox-sim] Simulation completed at time 0 fs +[mox-sim] === AOT Statistics === +[mox-sim] parse_ms: 0 +[mox-sim] passes_ms: 0 +[mox-sim] init_ms: 156 +[mox-sim] so_load_ms: 1 +[mox-sim] snapshot_restore_ms: 0 +[mox-sim] run_ms: 47 +[mox-sim] total_ms: 205 +[mox-sim] arena_globals: 0 +[mox-sim] arena_size_bytes: 0 +[mox-sim] global_patch_count: 0 +[mox-sim] global_patch_bytes: 0 +[mox-sim] mutable_globals_total: 0 +[mox-sim] mutable_globals_arena: 0 +[mox-sim] mutable_globals_patch: 0 +[mox-sim] mutable_bytes_total: 0 +[mox-sim] mutable_bytes_arena: 0 +[mox-sim] mutable_bytes_patch: 0 +[mox-sim] static_aot_reachability_functions_total: 5 +[mox-sim] static_aot_reachability_functions_native: 0 +[mox-sim] static_aot_reachability_functions_native_root: 0 +[mox-sim] static_aot_reachability_functions_native_closure: 0 +[mox-sim] static_aot_reachability_functions_interp_only: 0 +[mox-sim] static_aot_reachability_functions_unattributed: 5 +[mox-sim] static_aot_reachability_functions_unknown: 0 +[mox-sim] static_aot_reachability_processes_total: 1 +[mox-sim] static_aot_reachability_processes_native: 0 +[mox-sim] static_aot_reachability_processes_native_root: 0 +[mox-sim] static_aot_reachability_processes_native_closure: 0 +[mox-sim] static_aot_reachability_processes_interp_only: 0 +[mox-sim] static_aot_reachability_processes_unattributed: 1 +[mox-sim] static_aot_reachability_processes_unknown: 0 +[mox-sim] dynamic_aot_process_invocations_total: 1 +[mox-sim] dynamic_aot_process_invocations_native: 1 +[mox-sim] dynamic_aot_process_invocations_interpreted: 0 +[mox-sim] dynamic_aot_process_native_pct: 100.00 +[mox-sim] dynamic_aot_callable_invocations_total: 0 +[mox-sim] dynamic_aot_callable_invocations_native: 0 +[mox-sim] dynamic_aot_callable_invocations_interpreted: 0 +[mox-sim] dynamic_aot_callable_native_pct: n/a +[mox-sim] simulated_time_fs: 0 +[mox-sim] process_activations_total: 1 +[mox-sim] delta_cycles_total: 1 +[mox-sim] event_activations_total: 1 +[mox-sim] events_total: 1 +[mox-sim] signal_updates_total: 2 +[mox-sim] edges_detected_total: 2 +[mox-sim] signal_dispatches_total: 0 +[mox-sim] signal_fanout_dispatches_total: 0 +[mox-sim] signal_fanout_candidates_checked_total: 0 +[mox-sim] priority_clocking_sampler_pre_scan_candidates_total: 0 +[mox-sim] process_activations_per_s: 20 +[mox-sim] delta_cycles_per_s: 20 +[mox-sim] event_activations_per_s: 20 +[mox-sim] events_per_s: 20 +[mox-sim] signal_updates_per_s: 41 +[mox-sim] edges_detected_per_s: 41 +[mox-sim] simulated_fs_per_s: 0 +[mox-sim] simulated_ns_per_s: 0 +[mox-sim] Compiled process activations: 1 +[mox-sim] Compiled callback invocations: 1 +[mox-sim] Compiled frame-suspend invocations: 0 +[mox-sim] Compiled coroutine activations: 0 +[mox-sim] Deferred initial compiled process handoffs: 0 +[mox-sim] Init-phase interpreter activations: 0 +[mox-sim] Static-init interpreter activations: 0 +[mox-sim] Static-init one-shot discounts: 0 +[mox-sim] Static-init excess activations: 0 +[mox-sim] Interpreter process invocations: 0 +[mox-sim] Interpreter combinational invocations: 0 +[mox-sim] BEGIN interpreter-edge/v1 +[mox-sim] edge=interpreter-combinational-execution +[mox-sim] operation=llhd.combinational +[mox-sim] status=PRESENT +[mox-sim] event_binding_status=NOT-PROVEN +[mox-sim] event_binding_opened=0 +[mox-sim] event_binding_missing=0 +[mox-sim] event_binding_mismatch=0 +[mox-sim] event_binding_count_mismatch=0 +[mox-sim] event_binding_reason=producer-absent +[mox-sim] calibration=NOT-REQUESTED +[mox-sim] END interpreter-edge/v1 +[mox-sim] Interpreter continuous assignment invocations: 0 +[mox-sim] Initializer interpreter operations: 0 +[mox-sim] Filtered initializer interpreter operations: 0 +[mox-sim] AOT interpreter invocations total: 0 +[mox-sim] native pause ($stop) invocations: 0 +[mox-sim] Compiled function calls: 0 +[mox-sim] AOT reentry trampoline calls: 0 +[mox-sim] Trampoline calls: 0 +[mox-sim] Entry-table native calls: 0 +[mox-sim] Entry-table skipped (depth): 0 +[mox-sim] Entry-table skipped (yield): 0 +[mox-sim] Entry MAY_YIELD skip (non-native-default): 0 +[mox-sim] Entry MAY_YIELD skip (trampoline-default): 0 +[mox-sim] Entry MAY_YIELD skip (native-default): 0 +[mox-sim] Entry MAY_YIELD skip (optin-no-proc): 0 +[mox-sim] Entry MAY_YIELD skip (optin-non-coro): 0 +[mox-sim] Max AOT depth: 0 +[mox-sim] func.call skipped (depth): 0 +[mox-sim] func.call skipped (yield): 0 +[mox-sim] func.call MAY_YIELD skip (default): 0 +[mox-sim] func.call MAY_YIELD skip (optin-no-proc): 0 +[mox-sim] func.call MAY_YIELD skip (optin-non-coro): 0 +[mox-sim] indirect_calls_total: 0 +[mox-sim] indirect_calls_native: 0 +[mox-sim] function_identity_vtable_symbol_dispatches: 0 +[mox-sim] function_identity_vtable_legacy_fallbacks: 0 +[mox-sim] function_identity_vtable_missing_sidecar_fallbacks: 0 +[mox-sim] function_identity_vtable_mismatch_fallbacks: 0 +[mox-sim] function_identity_vtable_dropped_sidecar_rows: 0 +[mox-sim] function_identity_vtable_slot_pointer_rows: 0 +[mox-sim] function_identity_slot_pointer_key_lookups: 0 +[mox-sim] native_dispatch_abi_demotions: 0 +[mox-sim] native_dispatch_tagged_arm: 0 +[mox-sim] native_dispatch_slot_arm: 0 +[mox-sim] direct_calls_native: 0 +[mox-sim] aotDepth_max: 0 +[mox-sim] entry_calls_total: 0 +[mox-sim] entry_calls_native: 0 +[mox-sim] entry_skipped_yield_non_native_default: 0 +[mox-sim] entry_skipped_yield_trampoline_default: 0 +[mox-sim] entry_skipped_yield_native_default: 0 +[mox-sim] entry_skipped_yield_optin_no_proc: 0 +[mox-sim] entry_skipped_yield_optin_non_coro: 0 +[mox-sim] direct_skipped_yield_default: 0 +[mox-sim] direct_skipped_yield_optin_no_proc: 0 +[mox-sim] direct_skipped_yield_optin_non_coro: 0 +[mox-sim] wait_event_count: 0 +[mox-sim] wait_count: 0 +[mox-sim] fork_count: 0 +[mox-sim] join_count: 0 +[mox-sim] yield_count_total: 0 +[mox-sim] Hot native FuncIds (top 50): +[mox-sim] (none) +[mox-sim] Hot uncompiled FuncIds (top 50): +[mox-sim] (none) +[mox-sim] Hot entry-table MAY_YIELD skips (top 50): +[mox-sim] (none) +[mox-sim] Hot func.call MAY_YIELD skips (top 50): +[mox-sim] (none) +[mox-sim] Deferred-initial pre-wait interpreted operations: 0 +[mox-sim] BEGIN interpreter-edge/v1 +[mox-sim] edge=deferred-initial-prewait-operation +[mox-sim] status=PRESENT +[mox-sim] count=0 +[mox-sim] event_binding_status=PROVEN +[mox-sim] event_binding_opened=0 +[mox-sim] event_binding_missing=0 +[mox-sim] event_binding_mismatch=0 +[mox-sim] event_binding_count_mismatch=0 +[mox-sim] event_binding_reason=none +[mox-sim] END interpreter-edge/v1 +[mox-sim] whole-design AOT zero-interpreter gate satisfied: counted process=0 combinational=0 initializer-operation=0 direct-call=0 ABI-demotion=0 deferred-initial-prewait-operation=0 deferred-initial-prewait-binding=PROVEN dpi-export-function-binding=NOT-REQUIRED; residual-compiled-process=false interpreted-continuous-assignment=0 initializer-operation-filtered=0; instrumented-classes=interpreted-process,interpreted-callable,interpreted-continuous-assignment,module-initializer-operation,deferred-initial-prewait-operation measured-classes=interpreted-process,interpreted-callable,interpreted-continuous-assignment,module-initializer-operation,deferred-initial-prewait-operation unavailable-classes=NONE operation-level-other=UNMEASURED +[mox-sim] Simulation completed diff --git a/artifacts/tutorial/wide-readmem/solution-import.log b/artifacts/tutorial/wide-readmem/solution-import.log new file mode 100644 index 0000000..e69de29 diff --git a/artifacts/tutorial/wide-readmem/solution-interpret.log b/artifacts/tutorial/wide-readmem/solution-interpret.log new file mode 100644 index 0000000..76d6416 --- /dev/null +++ b/artifacts/tutorial/wide-readmem/solution-interpret.log @@ -0,0 +1,19 @@ +[mox-sim] Lowering --ir-sim semantic IR to simulation IR +[mox-sim] Stage: semantic-lower (prev: 8ms, total: 8ms) +[mox-sim] Auto-enabling --skip-passes for module marked mox.sim.preprocessed +[mox-sim] Stage: passes (prev: 0ms, total: 8ms) +[mox-sim] Replaying lowered semantic module in fresh mox-sim process +[mox-sim] Stage: passes (prev: 0ms, total: 0ms) +[mox-sim] Stage: init (prev: 0ms, total: 0ms) +[mox-sim] Found 1 LLHD processes, 0 LLHD finals, 0 seq.initial blocks, and 0 hw.instance ops (out of 129 total ops) in module +[mox-sim] Registered 4 LLHD signals and 1 LLHD processes/initial blocks +[mox-sim] Receipt: INIT_COMPLETE_OK execution_failure=0 process_dispatches=0 +[mox-sim] Stage: run (prev: 1ms, total: 1ms) +[mox-sim] Starting simulation +PASS +[mox-sim] sim.terminate triggered in process ID 1 at loc("src/lessons/sv/wide-readmem/wide_readmem.sol.sv":20:5 to :13) +[mox-sim] Simulation terminated at time 0 fs (success=true, verbose=true) +[mox-sim] Main loop exit: shouldContinue()=false at time 0 fs, iter=1, deltas=1 +[mox-sim] Simulation finished at time 0 fs +[mox-sim] Simulation completed at time 0 fs +[mox-sim] Simulation completed diff --git a/artifacts/tutorial/wide-readmem/solution-refdiff.json b/artifacts/tutorial/wide-readmem/solution-refdiff.json new file mode 100644 index 0000000..5730a06 --- /dev/null +++ b/artifacts/tutorial/wide-readmem/solution-refdiff.json @@ -0,0 +1 @@ +{"source":"/var/tmp/thomas-ahle/sv-tutorial/src/lessons/sv/wide-readmem/wide_readmem.sol.sv","sha256":"6bec76990fc02173afa44593a4c04ae0fc05f8dedc31c9bdd8629e199297a7ab","reference_cached":false,"reference":{"verdict":"PASS","exit":0,"final_status":"completed"},"mox":{"verdict":"PASS","exit":0,"phase":"simulate","final_status":"completed"},"category":"both_pass","output_equal":true,"equivalent":true,"metadata":{"_has_pass":true},"build_dir":"/var/tmp/thomas-ahle/wt/landing/build-dev-fast","artifacts":"/var/tmp/thomas-ahle/fleet/sv/sv-harness-k1g1_o58","refdiff_cache_key":"c4b662421c3b46763eaff26ff2bd3e1a3e61f3ff3772b2d8bd58140fb526f3b6"} diff --git a/artifacts/tutorial/wide-readmem/starter-compile.log b/artifacts/tutorial/wide-readmem/starter-compile.log new file mode 100644 index 0000000..87d70f5 --- /dev/null +++ b/artifacts/tutorial/wide-readmem/starter-compile.log @@ -0,0 +1,188 @@ +[mox-sim] Lowering --ir-sim semantic IR to simulation IR +[mox-sim] Stage: semantic-lower (prev: 7ms, total: 7ms) +[mox-sim] Auto-enabling --skip-passes for module marked mox.sim.preprocessed +[mox-sim] Stage: passes (prev: 0ms, total: 7ms) +[mox-sim] Replaying lowered semantic module in fresh mox-sim process +[mox-sim] Stage: passes (prev: 0ms, total: 0ms) +[mox-sim] aot-publication/v2 domain=module-loader-functions expected=0 accounted=0 positive=0 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:14a1ea4827eceb6099f752ac175f21d9feeed50ece269718c7050338ed779cdd +[mox-sim] aot-publication/v2 domain=module-loader-processes expected=1 accounted=1 positive=1 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:dbece0947e8df29c3d674a06bb85a08e2b7bd4a0382cd6522ab2c5fa69007e8e +[mox-sim] aot-publication/v2 domain=module-loader-address-bound-globals expected=27 accounted=27 positive=27 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:cb5ee622e1a6127db7475428b9068dd229fe565e2aecf638d2f74d435ca88b46 +[mox-sim] aot-publication/v2 domain=module-loader-entry-table expected=0 accounted=0 positive=0 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:14a1ea4827eceb6099f752ac175f21d9feeed50ece269718c7050338ed779cdd +[mox-sim] Loaded compiled module '/tmp/mox-scratch/a8e5ccd3bff512bd85be743cbbba161ae06504793c695db14b39d861ac39713b/session-5ebfd8f6450f8d91fd7a59733a03dabcb5ed5a84eb0b5c7aba91848e844c907b/mox-sim-autocompile-773a42.so': 0 functions, 1 processes, 27 address-bound globals (build: mox-sim-abi-v19-x86_64-unknown-linux-gnu-98dac023e75d57bf5c95f78e338944c1) +[mox-sim] Address-bound global ownership: role=main, module='/tmp/mox-scratch/a8e5ccd3bff512bd85be743cbbba161ae06504793c695db14b39d861ac39713b/session-5ebfd8f6450f8d91fd7a59733a03dabcb5ed5a84eb0b5c7aba91848e844c907b/mox-sim-autocompile-773a42.so', descriptor-declared=27, retained=27 +[mox-sim] M3 loaded callable union: artifacts=1 raw-rows=0 demand-rows=0 distinct-demand-keys=0 slot-rows=0 provider-rows=0 checked-keys=0 missing=0 duplicate=0 malformed=0 unresolved=0 dropped=0 digest=sha256:b1a0d307b997051345fe63c467d28dedb51995b8b8d0460dec55e4c069079c65 status=ok +[mox-sim] Stage: init (prev: 224ms, total: 224ms) +[mox-sim] Pre-aliased 27 address-bound globals to .so storage +[mox-sim] Unmapped native func.call policy: default deny runtime bridges and pointer-typed get_/set_/create_/m_initialize* (allow others) +[mox-sim] Loaded 0 compiled functions: 0 native-dispatched, 0 not-native-dispatched, 0 intercepted +[mox-sim] aot-publication/v2 domain=compiled-function-dispatch expected=0 accounted=0 positive=0 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:14a1ea4827eceb6099f752ac175f21d9feeed50ece269718c7050338ed779cdd +[mox-sim] Address-bound final-LLVM-global probes: 27/27 rows, 381/381 bytes bidirectional, owner-generation=1 +[mox-sim] Compiled process dispatch: 1/1 processes wired +[mox-sim] aot-publication/v2 domain=process-dispatch expected=1 accounted=1 positive=1 negative=0 missing=0 duplicate=0 unexpected=0 malformed=0 status=ok digest=sha256:979054643387faf73ad0f08f4cac05733060ee3d4ac3b9ff2b77a69eefd36c41 +[mox-sim] aot-publication/v2 domain=process-dispatch identity='tb.process_0' outcome=wired polarity=positive reason='' +[mox-sim] Stage: load-compiled (prev: 3ms, total: 228ms) +[mox-sim] Found 1 LLHD processes, 0 LLHD finals, 0 seq.initial blocks, and 0 hw.instance ops (out of 92 total ops) in module +[mox-sim] Registered 4 LLHD signals and 1 LLHD processes/initial blocks +[mox-sim] Receipt: INIT_COMPLETE_OK execution_failure=0 process_dispatches=0 +[mox-sim] Stage: run (prev: 0ms, total: 228ms) +[mox-sim] Starting simulation +FAIL: 0123456789abcdef fedcba9876543210 0000000000000000 +[mox-sim] Simulation terminated at time 0 fs (success=true, verbose=true) +[mox-sim] Main loop exit: shouldContinue()=false at time 0 fs, iter=1, deltas=1 +[mox-sim] Simulation finished at time 0 fs +[mox-sim] Simulation completed at time 0 fs +[mox-sim] === AOT Statistics === +[mox-sim] parse_ms: 0 +[mox-sim] passes_ms: 0 +[mox-sim] init_ms: 226 +[mox-sim] so_load_ms: 2 +[mox-sim] snapshot_restore_ms: 0 +[mox-sim] run_ms: 47 +[mox-sim] total_ms: 275 +[mox-sim] arena_globals: 0 +[mox-sim] arena_size_bytes: 0 +[mox-sim] global_patch_count: 0 +[mox-sim] global_patch_bytes: 0 +[mox-sim] mutable_globals_total: 0 +[mox-sim] mutable_globals_arena: 0 +[mox-sim] mutable_globals_patch: 0 +[mox-sim] mutable_bytes_total: 0 +[mox-sim] mutable_bytes_arena: 0 +[mox-sim] mutable_bytes_patch: 0 +[mox-sim] static_aot_reachability_functions_total: 5 +[mox-sim] static_aot_reachability_functions_native: 0 +[mox-sim] static_aot_reachability_functions_native_root: 0 +[mox-sim] static_aot_reachability_functions_native_closure: 0 +[mox-sim] static_aot_reachability_functions_interp_only: 0 +[mox-sim] static_aot_reachability_functions_unattributed: 5 +[mox-sim] static_aot_reachability_functions_unknown: 0 +[mox-sim] static_aot_reachability_processes_total: 1 +[mox-sim] static_aot_reachability_processes_native: 0 +[mox-sim] static_aot_reachability_processes_native_root: 0 +[mox-sim] static_aot_reachability_processes_native_closure: 0 +[mox-sim] static_aot_reachability_processes_interp_only: 0 +[mox-sim] static_aot_reachability_processes_unattributed: 1 +[mox-sim] static_aot_reachability_processes_unknown: 0 +[mox-sim] dynamic_aot_process_invocations_total: 1 +[mox-sim] dynamic_aot_process_invocations_native: 1 +[mox-sim] dynamic_aot_process_invocations_interpreted: 0 +[mox-sim] dynamic_aot_process_native_pct: 100.00 +[mox-sim] dynamic_aot_callable_invocations_total: 0 +[mox-sim] dynamic_aot_callable_invocations_native: 0 +[mox-sim] dynamic_aot_callable_invocations_interpreted: 0 +[mox-sim] dynamic_aot_callable_native_pct: n/a +[mox-sim] simulated_time_fs: 0 +[mox-sim] process_activations_total: 1 +[mox-sim] delta_cycles_total: 1 +[mox-sim] event_activations_total: 1 +[mox-sim] events_total: 1 +[mox-sim] signal_updates_total: 2 +[mox-sim] edges_detected_total: 2 +[mox-sim] signal_dispatches_total: 0 +[mox-sim] signal_fanout_dispatches_total: 0 +[mox-sim] signal_fanout_candidates_checked_total: 0 +[mox-sim] priority_clocking_sampler_pre_scan_candidates_total: 0 +[mox-sim] process_activations_per_s: 21 +[mox-sim] delta_cycles_per_s: 21 +[mox-sim] event_activations_per_s: 21 +[mox-sim] events_per_s: 21 +[mox-sim] signal_updates_per_s: 42 +[mox-sim] edges_detected_per_s: 42 +[mox-sim] simulated_fs_per_s: 0 +[mox-sim] simulated_ns_per_s: 0 +[mox-sim] Compiled process activations: 1 +[mox-sim] Compiled callback invocations: 1 +[mox-sim] Compiled frame-suspend invocations: 0 +[mox-sim] Compiled coroutine activations: 0 +[mox-sim] Deferred initial compiled process handoffs: 0 +[mox-sim] Init-phase interpreter activations: 0 +[mox-sim] Static-init interpreter activations: 0 +[mox-sim] Static-init one-shot discounts: 0 +[mox-sim] Static-init excess activations: 0 +[mox-sim] Interpreter process invocations: 0 +[mox-sim] Interpreter combinational invocations: 0 +[mox-sim] BEGIN interpreter-edge/v1 +[mox-sim] edge=interpreter-combinational-execution +[mox-sim] operation=llhd.combinational +[mox-sim] status=PRESENT +[mox-sim] event_binding_status=NOT-PROVEN +[mox-sim] event_binding_opened=0 +[mox-sim] event_binding_missing=0 +[mox-sim] event_binding_mismatch=0 +[mox-sim] event_binding_count_mismatch=0 +[mox-sim] event_binding_reason=producer-absent +[mox-sim] calibration=NOT-REQUESTED +[mox-sim] END interpreter-edge/v1 +[mox-sim] Interpreter continuous assignment invocations: 0 +[mox-sim] Initializer interpreter operations: 0 +[mox-sim] Filtered initializer interpreter operations: 0 +[mox-sim] AOT interpreter invocations total: 0 +[mox-sim] native pause ($stop) invocations: 0 +[mox-sim] Compiled function calls: 0 +[mox-sim] AOT reentry trampoline calls: 0 +[mox-sim] Trampoline calls: 0 +[mox-sim] Entry-table native calls: 0 +[mox-sim] Entry-table skipped (depth): 0 +[mox-sim] Entry-table skipped (yield): 0 +[mox-sim] Entry MAY_YIELD skip (non-native-default): 0 +[mox-sim] Entry MAY_YIELD skip (trampoline-default): 0 +[mox-sim] Entry MAY_YIELD skip (native-default): 0 +[mox-sim] Entry MAY_YIELD skip (optin-no-proc): 0 +[mox-sim] Entry MAY_YIELD skip (optin-non-coro): 0 +[mox-sim] Max AOT depth: 0 +[mox-sim] func.call skipped (depth): 0 +[mox-sim] func.call skipped (yield): 0 +[mox-sim] func.call MAY_YIELD skip (default): 0 +[mox-sim] func.call MAY_YIELD skip (optin-no-proc): 0 +[mox-sim] func.call MAY_YIELD skip (optin-non-coro): 0 +[mox-sim] indirect_calls_total: 0 +[mox-sim] indirect_calls_native: 0 +[mox-sim] function_identity_vtable_symbol_dispatches: 0 +[mox-sim] function_identity_vtable_legacy_fallbacks: 0 +[mox-sim] function_identity_vtable_missing_sidecar_fallbacks: 0 +[mox-sim] function_identity_vtable_mismatch_fallbacks: 0 +[mox-sim] function_identity_vtable_dropped_sidecar_rows: 0 +[mox-sim] function_identity_vtable_slot_pointer_rows: 0 +[mox-sim] function_identity_slot_pointer_key_lookups: 0 +[mox-sim] native_dispatch_abi_demotions: 0 +[mox-sim] native_dispatch_tagged_arm: 0 +[mox-sim] native_dispatch_slot_arm: 0 +[mox-sim] direct_calls_native: 0 +[mox-sim] aotDepth_max: 0 +[mox-sim] entry_calls_total: 0 +[mox-sim] entry_calls_native: 0 +[mox-sim] entry_skipped_yield_non_native_default: 0 +[mox-sim] entry_skipped_yield_trampoline_default: 0 +[mox-sim] entry_skipped_yield_native_default: 0 +[mox-sim] entry_skipped_yield_optin_no_proc: 0 +[mox-sim] entry_skipped_yield_optin_non_coro: 0 +[mox-sim] direct_skipped_yield_default: 0 +[mox-sim] direct_skipped_yield_optin_no_proc: 0 +[mox-sim] direct_skipped_yield_optin_non_coro: 0 +[mox-sim] wait_event_count: 0 +[mox-sim] wait_count: 0 +[mox-sim] fork_count: 0 +[mox-sim] join_count: 0 +[mox-sim] yield_count_total: 0 +[mox-sim] Hot native FuncIds (top 50): +[mox-sim] (none) +[mox-sim] Hot uncompiled FuncIds (top 50): +[mox-sim] (none) +[mox-sim] Hot entry-table MAY_YIELD skips (top 50): +[mox-sim] (none) +[mox-sim] Hot func.call MAY_YIELD skips (top 50): +[mox-sim] (none) +[mox-sim] Deferred-initial pre-wait interpreted operations: 0 +[mox-sim] BEGIN interpreter-edge/v1 +[mox-sim] edge=deferred-initial-prewait-operation +[mox-sim] status=PRESENT +[mox-sim] count=0 +[mox-sim] event_binding_status=PROVEN +[mox-sim] event_binding_opened=0 +[mox-sim] event_binding_missing=0 +[mox-sim] event_binding_mismatch=0 +[mox-sim] event_binding_count_mismatch=0 +[mox-sim] event_binding_reason=none +[mox-sim] END interpreter-edge/v1 +[mox-sim] whole-design AOT zero-interpreter gate satisfied: counted process=0 combinational=0 initializer-operation=0 direct-call=0 ABI-demotion=0 deferred-initial-prewait-operation=0 deferred-initial-prewait-binding=PROVEN dpi-export-function-binding=NOT-REQUIRED; residual-compiled-process=false interpreted-continuous-assignment=0 initializer-operation-filtered=0; instrumented-classes=interpreted-process,interpreted-callable,interpreted-continuous-assignment,module-initializer-operation,deferred-initial-prewait-operation measured-classes=interpreted-process,interpreted-callable,interpreted-continuous-assignment,module-initializer-operation,deferred-initial-prewait-operation unavailable-classes=NONE operation-level-other=UNMEASURED +[mox-sim] Simulation completed diff --git a/artifacts/tutorial/wide-readmem/starter-import.log b/artifacts/tutorial/wide-readmem/starter-import.log new file mode 100644 index 0000000..e69de29 diff --git a/artifacts/tutorial/wide-readmem/starter-interpret.log b/artifacts/tutorial/wide-readmem/starter-interpret.log new file mode 100644 index 0000000..0d74bbf --- /dev/null +++ b/artifacts/tutorial/wide-readmem/starter-interpret.log @@ -0,0 +1,19 @@ +[mox-sim] Lowering --ir-sim semantic IR to simulation IR +[mox-sim] Stage: semantic-lower (prev: 6ms, total: 6ms) +[mox-sim] Auto-enabling --skip-passes for module marked mox.sim.preprocessed +[mox-sim] Stage: passes (prev: 0ms, total: 6ms) +[mox-sim] Replaying lowered semantic module in fresh mox-sim process +[mox-sim] Stage: passes (prev: 0ms, total: 0ms) +[mox-sim] Stage: init (prev: 0ms, total: 0ms) +[mox-sim] Found 1 LLHD processes, 0 LLHD finals, 0 seq.initial blocks, and 0 hw.instance ops (out of 92 total ops) in module +[mox-sim] Registered 4 LLHD signals and 1 LLHD processes/initial blocks +[mox-sim] Receipt: INIT_COMPLETE_OK execution_failure=0 process_dispatches=0 +[mox-sim] Stage: run (prev: 1ms, total: 1ms) +[mox-sim] Starting simulation +FAIL: 0123456789abcdef fedcba9876543210 0000000000000000 +[mox-sim] sim.terminate triggered in process ID 1 at loc("src/lessons/sv/wide-readmem/wide_readmem.sv":17:7 to :15) +[mox-sim] Simulation terminated at time 0 fs (success=true, verbose=true) +[mox-sim] Main loop exit: shouldContinue()=false at time 0 fs, iter=1, deltas=1 +[mox-sim] Simulation finished at time 0 fs +[mox-sim] Simulation completed at time 0 fs +[mox-sim] Simulation completed diff --git a/artifacts/tutorial/wide-readmem/starter-refdiff.json b/artifacts/tutorial/wide-readmem/starter-refdiff.json new file mode 100644 index 0000000..d31b238 --- /dev/null +++ b/artifacts/tutorial/wide-readmem/starter-refdiff.json @@ -0,0 +1 @@ +{"source":"/var/tmp/thomas-ahle/sv-tutorial/src/lessons/sv/wide-readmem/wide_readmem.sv","sha256":"fb7bf296739ab55018ed7fe4416f0a841c1520f3f69a89258d859dd6b1b88c3b","reference_cached":false,"reference":{"verdict":"FAIL","exit":0,"final_status":"fail"},"mox":{"verdict":"FAIL","exit":0,"phase":"simulate","final_status":"fail"},"category":"both_fail","output_equal":false,"equivalent":false,"metadata":{"_has_pass":true},"build_dir":"/var/tmp/thomas-ahle/wt/landing/build-dev-fast","artifacts":"/var/tmp/thomas-ahle/fleet/sv/sv-harness-7ygz241x","refdiff_cache_key":"2a14f402bccac9b55849b9851878394ddd4ff027354bbb1f472fddd13a1cea9e"} diff --git a/src/lessons/index.js b/src/lessons/index.js index 1e494a5..c3c11a6 100644 --- a/src/lessons/index.js +++ b/src/lessons/index.js @@ -92,6 +92,7 @@ export const parts = [ { title: 'Clocking Sampler Retention', lessons: [L('sv/clocking-sampler-retention')] }, { title: 'Protected Envelope Boundary', lessons: [L('sv/protected-envelope-boundary')] }, { title: 'Virtual Method Provider Closure', lessons: [L('sv/virtual-provider-closure')] }, + { title: 'Wide Four-State Memory Loading', lessons: [L('sv/wide-readmem')] }, ], }, { diff --git a/src/lessons/landed-capabilities.test.js b/src/lessons/landed-capabilities.test.js index ad1356c..0db6ec1 100644 --- a/src/lessons/landed-capabilities.test.js +++ b/src/lessons/landed-capabilities.test.js @@ -10,7 +10,8 @@ const capabilities = [ ['sv/struct-field-refs', 'struct_field'], ['sv/indexed-part-select', 'indexed_part_select'], ['sv/nested-child-input', 'nested_child_input'], - ['sv/sequential-udp-init', 'sequential_udp'] + ['sv/sequential-udp-init', 'sequential_udp'], + ['sv/wide-readmem', 'wide_readmem'] ]; function receiptSourceMatches(receiptSource, sourcePath) { @@ -244,4 +245,36 @@ describe('landed Mox capability lessons and status pages', () => { expect(receipt.refdiff_cache_key).toMatch(/^[0-9a-f]{64}$/); } }); + + it('registers the wide four-state readmem chapter and its landed behavior', () => { + const slug = 'sv/wide-readmem'; + const dir = path.join(root, slug); + const starter = readFileSync(path.join(dir, 'wide_readmem.sv'), 'utf8'); + const solution = readFileSync(path.join(dir, 'wide_readmem.sol.sv'), 'utf8'); + const description = readFileSync(path.join(dir, 'description.html'), 'utf8'); + expect(meta[slug]?.runner ?? 'sim').toBe('sim'); + expect(meta[slug]?.focus).toBe('/src/wide_readmem.sv'); + expect(starter).toContain('logic [63:0] memory [0:2]'); + expect(solution).toContain('logic [64:0] memory [0:2]'); + expect(description).toContain('§21.4.1'); + expect(description).toContain('e7da9630dcd'); + expect(solution).toContain('$display("PASS")'); + + for (const [variant, filename] of [ + ['starter', 'wide_readmem.sv'], + ['solution', 'wide_readmem.sol.sv'] + ]) { + const sourcePath = path.join(dir, filename); + const sourceHash = createHash('sha256') + .update(readFileSync(sourcePath)) + .digest('hex'); + const receipt = JSON.parse(readFileSync( + path.resolve(process.cwd(), `artifacts/tutorial/wide-readmem/${variant}-refdiff.json`), + 'utf8' + )); + expect(receiptSourceMatches(receipt.source, sourcePath)).toBe(true); + expect(receipt.sha256).toBe(sourceHash); + expect(receipt.refdiff_cache_key).toMatch(/^[0-9a-f]{64}$/); + } + }); }); diff --git a/src/lessons/meta.js b/src/lessons/meta.js index 33edbce..262909f 100644 --- a/src/lessons/meta.js +++ b/src/lessons/meta.js @@ -33,6 +33,7 @@ export default { 'sv/clocking-sampler-retention': { title: 'Clocking Sampler Retention', focus: '/src/clocking_sampler.sv', top: 'tb' }, 'sv/protected-envelope-boundary': { title: 'Protected Envelope Boundary', focus: '/src/protected_envelope.sv', top: 'tb' }, 'sv/virtual-provider-closure': { title: 'Virtual Method Provider Closure', focus: '/src/virtual_provider.sv', top: 'tb' }, + 'sv/wide-readmem': { title: 'Wide Four-State Memory Loading', focus: '/src/wide_readmem.sv', top: 'tb' }, // ── SystemVerilog Assertions ─────────────────────────────────────────────── 'sva/concurrent-sim': { title: 'Concurrent Assertions in Simulation', focus: '/src/monitor.sv', runner: null }, diff --git a/src/lessons/receipt-matrix.test.js b/src/lessons/receipt-matrix.test.js index 1537f83..ea12a15 100644 --- a/src/lessons/receipt-matrix.test.js +++ b/src/lessons/receipt-matrix.test.js @@ -25,7 +25,8 @@ describe('tutorial receipt coverage', () => { 'sv/clocking-sampler-retention', 'sv/protected-envelope-boundary', 'sv/struct-field-refs', - 'sv/virtual-provider-closure' + 'sv/virtual-provider-closure', + 'sv/wide-readmem' ]; const covered = new Set([ ...genericReceiptSlugs(), diff --git a/src/lessons/sv/wide-readmem/description.html b/src/lessons/sv/wide-readmem/description.html new file mode 100644 index 0000000..cfbc9ab --- /dev/null +++ b/src/lessons/sv/wide-readmem/description.html @@ -0,0 +1,11 @@ +

$readmemh loads hexadecimal words from a text file into an unpacked memory array. The file can contain four-state digits, so x, z, and underscores are meaningful data rather than comments.

+ +

Template

+
logic [<width-1>:0] <memory> [<low>:<high>];
+$readmemh("<file>", <memory>, <start>, <finish>);
+ +

This exercise loads three words into addresses 0 through 2. The first word is 65 bits wide, including a leading 1; the third includes a leading z. Change the starter's packed width so the memory can preserve every bit from the file.

+ +

IEEE 1800-2023 §21.4 defines $readmemb and $readmemh, including optional start and finish addresses. Section §21.4.1 says an unpacked array of packed data is loaded one packed element at a time. The file format permits hexadecimal digits, x, z, and underscores.

+ +

The runnable solution is qualified against Mox landing commit e7da9630dcd, which adds native interpreter and compile-mode support for wide, non-power-of-two four-state readmem values. The pinned browser WASM is older than this landing and is not treated as AOT evidence.

diff --git a/src/lessons/sv/wide-readmem/wide_readmem.sol.sv b/src/lessons/sv/wide-readmem/wide_readmem.sol.sv new file mode 100644 index 0000000..850c795 --- /dev/null +++ b/src/lessons/sv/wide-readmem/wide_readmem.sol.sv @@ -0,0 +1,22 @@ +module tb; + logic [64:0] memory [0:2]; + integer fd; + + initial begin + fd = $fopen("/tmp/sv_tutorial_wide_readmem.hex", "w"); + $fwrite(fd, "1_0123456789abcdef\n"); + $fwrite(fd, "0_fedcba9876543210\n"); + $fwrite(fd, "z_0000000000000000\n"); + $fclose(fd); + $readmemh("/tmp/sv_tutorial_wide_readmem.hex", memory, 0, 2); + + if (memory[0] !== 65'h1_0123456789abcdef || + memory[1] !== 65'h0_fedcba9876543210 || + memory[2] !== 65'hz_0000000000000000) begin + $display("FAIL: %h %h %h", memory[0], memory[1], memory[2]); + $finish; + end + $display("PASS"); + $finish; + end +endmodule diff --git a/src/lessons/sv/wide-readmem/wide_readmem.sv b/src/lessons/sv/wide-readmem/wide_readmem.sv new file mode 100644 index 0000000..306e2c0 --- /dev/null +++ b/src/lessons/sv/wide-readmem/wide_readmem.sv @@ -0,0 +1,22 @@ +module tb; + logic [63:0] memory [0:2]; + integer fd; + + initial begin + fd = $fopen("/tmp/sv_tutorial_wide_readmem.hex", "w"); + $fwrite(fd, "1_0123456789abcdef\n"); + $fwrite(fd, "0_fedcba9876543210\n"); + $fwrite(fd, "z_0000000000000000\n"); + $fclose(fd); + $readmemh("/tmp/sv_tutorial_wide_readmem.hex", memory, 0, 2); + + if (memory[0] !== 65'h1_0123456789abcdef || + memory[1] !== 65'h0_fedcba9876543210 || + memory[2] !== 65'hz_0000000000000000) begin + $display("FAIL: %h %h %h", memory[0], memory[1], memory[2]); + $finish; + end + $display("PASS"); + $finish; + end +endmodule From dfe52be93c144adda99b18bd49a744f52cc90811 Mon Sep 17 00:00:00 2001 From: Thomas Dybdahl Ahle Date: Thu, 1 Oct 2026 21:25:03 +0000 Subject: [PATCH 2/3] docs: clarify readmem digit separators --- src/lessons/sv/wide-readmem/description.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lessons/sv/wide-readmem/description.html b/src/lessons/sv/wide-readmem/description.html index cfbc9ab..e9c6e1b 100644 --- a/src/lessons/sv/wide-readmem/description.html +++ b/src/lessons/sv/wide-readmem/description.html @@ -1,4 +1,4 @@ -

$readmemh loads hexadecimal words from a text file into an unpacked memory array. The file can contain four-state digits, so x, z, and underscores are meaningful data rather than comments.

+

$readmemh loads hexadecimal words from a text file into an unpacked memory array. The file can contain four-state digits, so x and z preserve unknown and high-impedance values; underscores are legal separators within a number.

Template

logic [<width-1>:0] <memory> [<low>:<high>];

From dd251d172148edf8e8f0e1c4d0a31ccf0f5c5240 Mon Sep 17 00:00:00 2001
From: Thomas Dybdahl Ahle 
Date: Thu, 1 Oct 2026 21:26:07 +0000
Subject: [PATCH 3/3] docs: fold wide-readmem review nits

---
 artifacts/tutorial/wide-readmem/README.md    | 9 +++++++--
 src/lessons/landed-capabilities.test.js      | 1 +
 src/lessons/sv/wide-readmem/description.html | 2 ++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/artifacts/tutorial/wide-readmem/README.md b/artifacts/tutorial/wide-readmem/README.md
index df24245..4c1d5e5 100644
--- a/artifacts/tutorial/wide-readmem/README.md
+++ b/artifacts/tutorial/wide-readmem/README.md
@@ -54,7 +54,8 @@ does not qualify native AOT.
   memory through the test's value check.
 - `solution-refdiff.json`: `both_pass`; outputs are equivalent.
 - Both JSON receipts bind their `sha256` values to the committed source and
-  retain their `refdiff_cache_key` values.
+  retain their `refdiff_cache_key` values. Standing ruling — `general:
+  refdiff_cache_key is receipt provenance, not a runtime performance cache`.
 
 ## Browser qualification
 
@@ -66,4 +67,8 @@ npx playwright test e2e/qa-all-lessons.spec.js --grep 'Wide Four-State Memory Lo
 
 The route used the pinned interpreter-backed WASM fallback because
 `/mox/mox-run.js` is absent. This is browser interpreter qualification only,
-not native AOT qualification.
+not native AOT qualification. Standing ruling — `general: pinned interpreter
+fallback is an explicitly scoped browser compatibility path`.
+
+The lesson writes its input file under `/tmp`; the run environment must provide
+a writable temporary directory, as stated in the lesson itself.
diff --git a/src/lessons/landed-capabilities.test.js b/src/lessons/landed-capabilities.test.js
index 0db6ec1..a4fe9fe 100644
--- a/src/lessons/landed-capabilities.test.js
+++ b/src/lessons/landed-capabilities.test.js
@@ -258,6 +258,7 @@ describe('landed Mox capability lessons and status pages', () => {
     expect(solution).toContain('logic [64:0] memory [0:2]');
     expect(description).toContain('§21.4.1');
     expect(description).toContain('e7da9630dcd');
+    expect(description).toContain('writable temporary directory');
     expect(solution).toContain('$display("PASS")');
 
     for (const [variant, filename] of [
diff --git a/src/lessons/sv/wide-readmem/description.html b/src/lessons/sv/wide-readmem/description.html
index e9c6e1b..0f63b67 100644
--- a/src/lessons/sv/wide-readmem/description.html
+++ b/src/lessons/sv/wide-readmem/description.html
@@ -6,6 +6,8 @@ 

Template

This exercise loads three words into addresses 0 through 2. The first word is 65 bits wide, including a leading 1; the third includes a leading z. Change the starter's packed width so the memory can preserve every bit from the file.

+

The test writes its input file at /tmp/sv_tutorial_wide_readmem.hex, so the run environment must provide a writable temporary directory.

+

IEEE 1800-2023 §21.4 defines $readmemb and $readmemh, including optional start and finish addresses. Section §21.4.1 says an unpacked array of packed data is loaded one packed element at a time. The file format permits hexadecimal digits, x, z, and underscores.

The runnable solution is qualified against Mox landing commit e7da9630dcd, which adds native interpreter and compile-mode support for wide, non-power-of-two four-state readmem values. The pinned browser WASM is older than this landing and is not treated as AOT evidence.