Skip to main content

Module scalar_asm

Module scalar_asm 

Source
Expand description

scalar_asm — assemble a compiled LOGOS program (the register bytecode CompiledProgram) into the instruction words that soft_core_scalar.v executes, so a REAL .lg program can be streamed to the Nexys A7 FPGA over UART and run on silicon (see scripts/run-on-nexys-scalar.sh).

Scope: the FUNCTION-FREE scalar subset the routable core implements — the reversible/adiabatic core (opcodes 0..4), LoadConst/Move, every arithmetic / bitwise / comparison op (through the proven alu.v), the branches, and Show/Halt/FailWith. A strict WHITELIST rejects everything else (user functions — their register-window calling convention needs a translation pass — globals, collections, heap, structs, CRDTs, concurrency), so whatever this encoder accepts is guaranteed to run identically on run_soft_core (the Rust model), on the RTL, and on the chip. The op BYTE is always binisa::opcode(op) — the append-only ISA ABI a hardware decoder keys on — so the encoder can never silently drift from the silicon; it only lays out the operand fields per the decoder’s field usage.

Word layout (matches run_soft_core / soft_core_scalar.v):

general : [opcode:8][dst:8][a:8][b:8]     (dst=bits23:16, a=bits15:8, b=bits7:0)
LoadConst: [opcode:8][dst:8][imm:16]       (imm sign-extends the low 16 bits)
Jump    : [opcode:8][target:8][........]   (target = bits23:16, a 0..255 word index)
JumpIf* : [opcode:8][target:8][cond:8][..] (target=bits23:16, cond=bits15:8)
Show    : [opcode:8][0][src:8][0]          (src=bits15:8)

Locked ≡ VM by rtl.rs::tests::encode_scalar_matches_vm.

Functions§

allocate_scalar_registers
Map a function-free scalar program’s registers onto the core’s sixteen by liveness. The VM numbers registers freely (a fresh one per Let, named values above the temporaries that computed them); the chip needs only as many as are ever live at once. Two registers may share a physical one unless one is live where the other is written (a Move’s source does not count against its destination), and the interference graph is coloured Chaitin–Briggs style — simplify below sixteen neighbours, else optimistically, then colour in reverse — lowest register first, so the result is deterministic.
compile_to_scalar_words
Compile a .lg source string all the way to soft_core_scalar imem words, through the SAME front-end and oracle-driven compiler the VM uses (so the chip runs byte-identically to vm_outcome). Err if it doesn’t parse/compile, or uses anything outside the function-free scalar subset.
encode_soft_core_scalar
Assemble a whole compiled program into soft_core_scalar imem words. Function-free only (a program with user functions returns Err; their calling-convention translation is a separate pass). At most 256 words (the imem depth). Registers are first mapped onto the core’s sixteen by liveness (allocate_scalar_registers).
to_hex
Render imem words as a .hex file body (one 8-hex-digit word per line) for scripts/nexys-host.py.