mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-04-20 03:03:25 -04:00
This simulates one approach we could go for when moving registers to
memory. The memory machine remains completely unchanged, but the step is
increased by more than 1 in each step of the main machine. This way,
from the point of view of memory, all the memory operations happen at
different time steps, which allows for:
- Reading from the same address twice
- Writing to the same address that we read from (which from the point of
view of memory should happen *after* the read)
The only downside I see with this approach is that this makes the
differences of time steps between memory accesses bigger: Before it was
at most the degree, now it is some small constant times the degree (in
this example 3). The way the memory machine is currently built, the
difference can be at most $2^{32} - 1$, so I think this is fine in
practice. E.g., for a degree $2^{30}$ machine we could do up to 4
parallel reads / writes.
36 lines
1.2 KiB
Rust
36 lines
1.2 KiB
Rust
use std::machines::memory::Memory;
|
|
|
|
machine Main with
|
|
degree: 65536,
|
|
operation_id: operation_id
|
|
{
|
|
Memory memory;
|
|
|
|
// Read values from ADDR1 & ADDR2, write value3 to ADDR3
|
|
link ACTIVE ~> memory.mload ADDR1, STEP -> value1;
|
|
link ACTIVE ~> memory.mload ADDR2, STEP + 1 -> value2;
|
|
link ACTIVE ~> memory.mstore ADDR3, STEP + 2, value3 ->;
|
|
|
|
// Because we're doing 3 memory operations in each time step, we'll
|
|
// increment the time step by 3
|
|
col fixed STEP(i) {i * 3};
|
|
col fixed ACTIVE = [1, 1, 1, 1] + [0]*;
|
|
col witness value1, value2, value3;
|
|
|
|
// In each row, we set value3 = value1 + value2 + 1
|
|
ACTIVE * (value1 + value2 + 1 - value3) = 0;
|
|
|
|
// Program (with expected memory after each step)
|
|
// - ADDR1 = ADDR2 = ADDR3 = 0 => [1, 0, 0, 0]
|
|
// - ADDR1 = 0, ADDR2 = 1, ADDR3 = 2 => [1, 0, 2, 0]
|
|
// - ADDR1 = 0, ADDR2 = 2, ADDR3 = 0 => [4, 0, 2, 0]
|
|
// - ADDR1 = 0, ADDR2 = 0, ADDR3 = 4 => [4, 0, 2, 9]
|
|
col fixed ADDR1 = [0, 0, 0, 0] + [0]*;
|
|
col fixed ADDR2 = [0, 1, 2, 0] + [0]*;
|
|
col fixed ADDR3 = [0, 2, 0, 4] + [0]*;
|
|
|
|
// So, the last written value should be 9:
|
|
col fixed LAST = [0, 0, 0, 1] + [0]*;
|
|
LAST * (value3 - 9) = 0;
|
|
}
|