Skip to main content
Version: 0.11 (stable)

Input / output operations

In this section we describe the AIR constraints for Miden VM input / output operations. These operations move values between the stack and other components of the VM such as program code (i.e., decoder), memory, and advice provider.

PUSH

The PUSH operation pushes the provided immediate value onto the stack non-deterministically (i.e., sets the value of s0s_0 register); it is the responsibility of the Op Group Table to ensure that the correct value was pushed on the stack. The semantics of this operation are explained in the decoder section.

The effect of this operation on the rest of the stack is:

  • Right shift starting from position 00.

SDEPTH

Assume aa is the current depth of the stack stored in the stack bookkeeping register b0b_0 (as described here). The SDEPTH pushes aa onto the stack. The diagram below illustrates this graphically.

sdepth

Stack transition for this operation must satisfy the following constraints:

s0b0=0 | degree=1s_0' - b_0 = 0 \text{ | degree} = 1

The effect of this operation on the rest of the stack is:

  • Right shift starting from position 00.

ADVPOP

Assume aa is an element at the top of the advice stack. The ADVPOP operation removes aa from the advice stack and pushes it onto the operand stack. The diagram below illustrates this graphically.

advpop

The ADVPOP operation does not impose any constraints against the first element of the operand stack.

The effect of this operation on the rest of the operand stack is:

  • Right shift starting from position 00.

ADVPOPW

Assume aa, bb, cc, and dd, are the elements at the top of the advice stack (with aa being on top). The ADVPOPW operation removes these elements from the advice stack and puts them onto the operand stack by overwriting the top 44 stack elements. The diagram below illustrates this graphically.

advpopw

The ADVPOPW operation does not impose any constraints against the top 44 elements of the operand stack.

The effect of this operation on the rest of the operand stack is:

  • No change starting from position 44.

Memory access operations

Miden VM exposes several operations for reading from and writing to random access memory. Memory in Miden VM is managed by the Memory chiplet.

Communication between the stack and the memory chiplet is accomplished via the chiplet bus bchipb_{chip}. To make requests to the chiplet bus we need to divide its current value by the value representing memory access request. The structure of memory access request value is described here.

To enforce the correctness of memory access, we can use the following constraint:

bchipumem=bchip | degree=2b_{chip}' \cdot u_{mem} = b_{chip} \text{ | degree} = 2

In the above, umemu_{mem} is the value of memory access request. Thus, to describe AIR constraint for memory operations, it is sufficient to describe how umemu_{mem} is computed. We do this in the following sections.

MLOADW

Assume that the word with elements v0,v1,v2,v3v_0, v_1, v_2, v_3 is located in memory starting at address aa. The MLOADW operation pops an element off the stack, interprets it as a memory address, and replaces the remaining 4 elements at the top of the stack with values located at the specified address. The diagram below illustrates this graphically.

mloadw

To simplify description of the memory access request value, we first define a variable for the value that represents the state of memory after the operation:

v=i=03αi+5s3iv = \sum_{i=0}^3\alpha_{i+5} \cdot s_{3-i}'

Using the above variable, we define the value representing the memory access request as follows:

umem=α0+α1opmem_readword+α2ctx+α3s0+α4clk+vu_{mem} = \alpha_0 + \alpha_1 \cdot op_{mem\_readword} + \alpha_2 \cdot ctx + \alpha_3 \cdot s_0 + \alpha_4 \cdot clk + v

In the above:

  • opmem_readwordop_{mem\_readword} is the unique operation label of the memory "read word" operation.
  • ctxctx is the identifier of the current memory context.
  • s0s_0 is the memory address from which the values are to be loaded onto the stack.
  • clkclk is the current clock cycle of the VM.

The effect of this operation on the rest of the stack is:

  • Left shift starting from position 55.

MLOAD

Assume that the element vv is located in memory at address aa. The MLOAD operation pops an element off the stack, interprets it as a memory address, and pushes the element located at the specified address to the stack. The diagram below illustrates this graphically.

mload

We define the value representing the memory access request as follows:

umem=α0+α1opmem_readelement+α2ctx+α3s0+α4clk+α5vu_{mem} = \alpha_0 + \alpha_1 \cdot op_{mem\_readelement} + \alpha_2 \cdot ctx + \alpha_3 \cdot s_0 + \alpha_4 \cdot clk + \alpha_5 \cdot v

In the above:

  • opmem_readelementop_{mem\_readelement} is the unique operation label of the memory "read element" operation.
  • ctxctx is the identifier of the current memory context.
  • s0s_0 is the memory address from which the value is to be loaded onto the stack.
  • clkclk is the current clock cycle of the VM.

The effect of this operation on the rest of the stack is:

  • No change starting from position 11.

MSTOREW

The MSTOREW operation pops an element off the stack, interprets it as a memory address, and writes the remaining 44 elements at the top of the stack into memory starting at the specified address. The stored elements are not removed from the stack. The diagram below illustrates this graphically.

mstorew

After the operation the contents of memory at addresses aa, a+1a+1, a+2a+2, a+3a+3 would be set to v0,v1,v2,v3v_0, v_1, v_2, v_3, respectively.

To simplify description of the memory access request value, we first define a variable for the value that represents the state of memory after the operation:

v=i=03αi+5s3iv = \sum_{i=0}^3\alpha_{i+5} \cdot s_{3-i}'

Using the above variable, we define the value representing the memory access request as follows:

umem=α0+α1opmem_writeword+α2ctx+α3s0+α4clk+vu_{mem} = \alpha_0 + \alpha_1 \cdot op_{mem\_writeword} + \alpha_2 \cdot ctx + \alpha_3 \cdot s_0 + \alpha_4 \cdot clk + v

In the above:

  • opmem_writewordop_{mem\_writeword} is the unique operation label of the memory "write word" operation.
  • ctxctx is the identifier of the current memory context.
  • s0s_0 is the memory address into which the values from the stack are to be saved.
  • clkclk is the current clock cycle of the VM.

The effect of this operation on the rest of the stack is:

  • Left shift starting from position 11.

MSTORE

The MSTORE operation pops an element off the stack, interprets it as a memory address, and writes the remaining element at the top of the stack into memory at the specified memory address. The diagram below illustrates this graphically.

mstore

After the operation the contents of memory at address aa would be set to bb.

We define the value representing the memory access request as follows:

umem=α0+α1opmem_writeelement+α2ctx+α3s0+α4clk+α5vu_{mem} = \alpha_0 + \alpha_1 \cdot op_{mem\_writeelement} + \alpha_2 \cdot ctx + \alpha_3 \cdot s_0 + \alpha_4 \cdot clk + \alpha_5 \cdot v

In the above:

  • op_memwriteelementop\_{mem_writeelement} is the unique operation label of the memory "write element" operation.
  • ctxctx is the identifier of the current memory context.
  • s0s_0 is the memory address into which the value from the stack is to be saved.
  • clkclk is the current clock cycle of the VM.

The effect of this operation on the rest of the stack is:

  • Left shift starting from position 11.

MSTREAM

The MSTREAM operation loads two words from memory, and replaces the top 8 elements of the stack with them, element-wise, in stack order. The start memory address from which the words are loaded is stored in the 13th stack element (position 12). The diagram below illustrates this graphically.

mstream

After the operation, the memory address is incremented by 8.

s12=s12+8s_{12}' = s_{12} + 8

To simplify description of the memory access request value, we first define variables for the values that represent the state of memory after the operation:

v1=i=03αi+5s7iv_1 = \sum_{i=0}^3\alpha_{i+5} \cdot s_{7-i}' v2=i=03αi+5s3iv_2 = \sum_{i=0}^3\alpha_{i+5} \cdot s_{3-i}'

Using the above variables, we define the values representing the memory access request as follows:

umem,1=α0+α1opmem_readword+α2ctx+α3s12+α4clk+v1u_{mem, 1} = \alpha_0 + \alpha_1 \cdot op_{mem\_readword} + \alpha_2 \cdot ctx + \alpha_3 \cdot s_{12} + \alpha_4 \cdot clk + v_1 umem,2=α0+α1opmem_readword+α2ctx+α3(s12+4)+α4clk+v2u_{mem, 2} = \alpha_0 + \alpha_1 \cdot op_{mem\_readword} + \alpha_2 \cdot ctx + \alpha_3 \cdot (s_{12} + 4) + \alpha_4 \cdot clk + v_2 umem=umem,1umem,2u_{mem} = u_{mem, 1} \cdot u_{mem, 2}

In the above:

  • opmem_readwordop_{mem\_readword} is the unique operation label of the memory "read word" operation.
  • ctxctx is the identifier of the current memory context.
  • s12s_{12} and s12+4s_{12} + 4 are the memory addresses from which the words are to be loaded onto the stack.
  • clkclk is the current clock cycle of the VM.

The effect of this operation on the rest of the stack is:

  • No change starting from position 88 except position 1212.