Expand description
The cycle-accurate Rust model of benchmarks/silicon/soft_core.v — the executable spec of the
LOGOS universal interpreter in silicon. Fetch/decode/execute over a chip-word program
([opcode:8][dst:8][a:8][b:8]; wide/float/heap ops per the doc on run_soft_core_typed),
returning the Show sequence. This is the differential ORACLE the whole spatial-interpreter
campaign checks against: compile_to_full_words -> run_soft_core_typed must equal
compile::vm_outcome for every program, and the iverilog testbenches agree with it. Lifted here
(from rtl.rs’s test module) so both the in-crate RTL tests and the logicaffeine_tests
integration locks share ONE oracle.
Structs§
- Soft
Core Run - A run of the core: everything it showed, and how it failed if it did.
Enums§
- Chip
Failure - How the core stopped with a FAILURE (a trap-halt rather than a clean
Halt). - RegVal
- A VALUE integer register cell — the chip’s exact mirror of the VM’s
Int/BigInttower. The common case is a machine word (Small, the FAST path that keeps the 32-bit oracle byte-identical and the model fast over the 5e8-cycle budget); an integer that overflows the datapath promotes to an exactBig(unboundedBigInt), EXACTLY ascrate::vm::value::Value/RuntimeValue::Intpromotes toRuntimeValue::BigInt. INVARIANT (mirrorsRuntimeValue::from_bigint): aBignever holds a value that fitsi64— every arithmetic result normalizes back toSmallwhen it fits — so a value has one canonical representation and the printed decimal is unique. Pointers, list lengths, map tags, iterator cursors, and register indices staySmall(they are addresses, never over-i64), so the structural heap/pointer machinery reads them throughRegVal::smwith no BigInt on the hot structural path. - ShowVal
- One
Showoutput of the soft-core, tagged by the datapath that produced it: an integerShow(opcode 89, the 32-bit ALU/heap result) or a FLOATShow(opcode 212ShowF, an f64 from the FPU float bank). The chip is dynamically typed at the VM level, but the encoder statically lowers eachShowto the one whose operand type it proved — so the model carries the same distinction andShowVal::fmtrenders each exactly as the VM does (ints bare, floats viafmt_f64).
Functions§
- run_
soft_ core - The integer-differential view of
run_soft_core_typed: theShowsequence as rawi64values. The pure integer programs (the hand-assembled ≡VM differential, the testbench emitter, the silicon demo) never emit a floatShow, so at the 32-bit width this stays value-identical to the pre-FPU model (a 32-bit result carried in the low bits of ani64). A float program usesrun_soft_core_typed+ShowVal::fmtinstead (panics loudly here if one leaks a float). - run_
soft_ core_ outcome - Run
imemand report the failure contract the RTL’sfailed/reasonedports carry: a reasoned trap’s last Text record IS its reason (so it leavesshows); a trap without text isTrap. - run_
soft_ core_ typed - run_
soft_ core_ typed_ preloaded - Run with
preloadseeded into the heap asheap[0..preload.len()]— the model twin of the SoC’s weight DATA phase. Withpreload = [len, w0, w1, …]that is aSeq of Intat pointer 0, so the compiledloaded()(pointer 0) makesitem i of loaded()readheap[i]. The bump allocator continues after it. - run_
soft_ core_ typed_ w - The WIDTH-PARAMETRIC form of
run_soft_core_typed— the real fetch/decode/execute loop. Every integer VALUE is an auto-promotingRegVal(fastSmall(i64)+ exactBig(BigInt)on overflow), so the datapath’sIntis UNBOUNDED exactly like the VM’s — the chip differs NOWHERE from the VM on integers at ANYwidth. This is a REFRAME of the old width toggle:widthno longer masks value arithmetic (a product that overflows i32/i64 PROMOTES, matching the VM, rather than wrapping), sowidth == 32andwidth == 64both equalvm_outcomeon theShowValoutput.widthsurvives as a perf/area knob and the datapath-width parameter for the raw-i64 OUTPUT VIEW (run_soft_core_w, which masks each value towidthbits to model a fixed-width hardware output register). Addresses/iterators stayusize; the float bank stays f64 (width-independent). - run_
soft_ core_ w - The WIDTH-PARAMETRIC integer-differential view of
run_soft_core_typed_w: theShowsequence as rawi64values MASKED to the datapathwidth— the fixed-width tape-out core’s OUTPUT REGISTER view (width == 32truncates each value to i32,width == 64is the full i64 pattern). This is DISTINCT fromrun_soft_core_typed_w, whoseShowValcarries the UNBOUNDED value (VM-exact via BigInt): the typed path is the chip that “differs nowhere from the VM”; this raw view models what awidth-bit hardware output register would show if you read the low bits, so the 32-bit tape-out core’s wrap is still observable here. A value that overflowed toBigcontributes its low-64-bit two’s-complement pattern, then sign-extended towidth. (Float/Text/Word32Shows panic — the pure-integer callers never emit them.) - sign_
extend_ to_ width - Sign-extend the low
widthbits of a value to a full i64 — a fixed-width datapath’s result register.width >= 64is the identity;width == 32reproduces the 32-bit core’sas i32truncation exactly. The SAME logic yields a 32-, 64-, or any-power-of-two-width core — the toggle. - soft_
core_ alu - The Rust model of
alu.v(32-bit), mirroringemit_alu_datapath_verilogexactly (wrapping / signed). Div / ExactDiv / Mod / FloorDiv are NOT here — they route tosoft_core_divider(mirroring the soft-core’sshared_divider). DivPow2 stays (a cheap arithmetic shift). - soft_
core_ alu_ w - Width-parametric model of
alu.v— computes in i64 and sign-extends towidthbits.soft_core_aluis thewidth == 32case (proven equal byalu_width_toggle_is_32bit_faithful_and_64bit_wide). Div/Mod/ FloorDiv route tosoft_core_divider_w, mirroring the shared divider. - soft_
core_ divider - The Rust model of the soft-core’s
shared_dividerunit (truncated signed division): Div / ExactDiv → quotient, Mod → remainder (dividend’s sign), FloorDiv → floor-adjusted quotient; b==0 → 0.run_soft_coreissues opcodes 12/13/14/15 here instead of the combinational ALU, mirroring the RTL (the divider is proven == this by iverilogtb_shared_divider). - soft_
core_ divider_ w - Width-parametric model of the shared divider (truncated signed division), sign-extended to
width.soft_core_divideris thewidth == 32case.