通过 chip 的 eval()
函数对 trace 表的列添加约束。本文列出每个 chip 的核心约束。
列出如下变量/寄存器
clk
:每条指令运行的时间戳pc
:指令指针,指向当前指令ci
:当前指令,pc
指向的指令mp
:内存指针,执行一个内存单元mv
:内存值,mp
所指内存单元的值
CpuChip
cpu 表的约束如下
- $clk_{i+1} - clk_i - 2 = 0$,因为 clk 代表时间戳,一条指令可能涉及 2 次内存访问,如
+
指令涉及一次读内存和一次写内存,需要用不同的时间戳进行区分,所以 clk 每次递增 2 - 对于非跳转指令,有 $pc_{i+1} - pc_{i} - 1 = 0$
- cpu 表中出现的指令 $ci_i$ 必须和 program 表中的一致,通过 lookup 协议实现
- 内存访问一致性:通过 read write 操作之间的 lookup 协议实现
- 对每条指令进行约束,不过 CpuChip 本身不做该项工作,而是通过 lookup 协议由各个指令的 chip 实现
lookup 细节见:https://aping-dev.com/index.php/archives/811
Instruction
每条指令都应该进行约束,将指令分为四种类型,对应四种 chip,分别为 AluChip, JumpChip, IoChip 和 MemoryInstructionsChip
AluChip
AluChip 对 +
和 -
指令进行约束。
+
指令约束:$mv_{i+1} - mv_i - 1 = 0$
-
指令约束:$mv_{i} - mv_{i+1} - 1 = 0$
JumpChip
JumpChip 对 [
和 ]
指令进行约束。
引入如下变量
inv
:如果mv
为 0,则值为 0,否则为mv
的乘法逆元iszero
:1 - mv * inv
的结果,当mv
为 0 时,它取值为 1,否则为 0
[
指令约束
$(pc_{i+1} - dst) \cdot iszero + (pc_{i+1} - pc_i - 1)mv_i = 0$
表示如果 $mv_i = 0$ 则 $pc_{i+1} -$ 目标指令指针 = 0,进行跳转;否则 $pc_{i+1} - pc_i - 1 = 0$,跳过当前指令 [
]
指令约束
$(pc_{i+1} - dst)mv_i + (pc_{i+1} - pc_i - 1) \cdot iszero = 0$
表示如果 $mv_i \ne 0$ 则 $pc_{i+1} -$ 目标指令指针 = 0,进行跳转;否则 $pc_{i+1} - pc_i - 1 = 0$ ,跳过当前指令 ]
IoChip
IoChip 对 ,
和 .
指令进行约束。
通过 lookup 协议确保和 cpu 表中出现的 I/O 指令保持一致。
MemoryInstructionsChip
MemoryInstructionsChip 对 >
和 <
指令进行约束。
>
指令约束:$mp_{i+1} - mp_i - 1 = 0$
<
指令约束:$mp_{i} - mp_{i+1} - 1 = 0$
MemoryChip
MemoryChip 用于对内存访问一致性进行约束。
MemoryChip 只记录对某个地址的初始化和最终状态的读写操作 $init, final$,而 CpuChip 记录对某个地址的所有读写操作 $read, write$,内存访问一致性需满足该约束:$read \cup final = write \cup init$
没有评论