Memory model

As we are designing a virtual processor we are mostly not bound by physical limitations, so some usual restrictions, introduced by hardware engineering can be lifted. For example for us memory access takes exactly as much time as register access, contrary to physical processors. On the other hand each register costs us columns, which commonly means larger trace and therefore larger prover and verifier costs.

Another stark difference between classical CPUs and zk-friendly virtual ones is availability of stack machines. For zk-friendly processors stack operations (PUSH/POP) are extremely taxing and should be avoided if possible, contrary to ease of implementation of classical ones.

We use native Goldilock Field elements as words, so the word is a 64-bit integer modulo 264232+1 2^{64} - 2^{32} + 1.

In our virtual processor we have only 3 explicit word-sized registers:

  • PC: program counter, which is a pointer to the instruction to be executed. Starts in the '.text' segment.

  • SP: stack pointer, which is intended to be a pointer to the current stack frame, mimicking a C-like runtime. Starts in the '.data' segment.

  • AP: allocation pointer, which is just a general purpose pointer. Starts in the '.data' segment.

There are a number of implicit registers - register-like columns, necessary for internal operations. They are calculated memory addresses op0, op1 and dst, in addition to intermediate value res.

All data (code, stack frames, local and global variables, constants, etc.) is stored in write-once memory and addressed using registers and offsets in each instruction. Generally, memory layout is not directly enforced by VM and developers are free to use any layout applicable, but more memory intensive programs tend to have larger traces.

Last updated