|
1 | | -import SP1Foundations |
2 | | -import SP1Operations.Operation.AddOperation |
3 | | -import SP1Operations.Reader.CPUState |
4 | | -import SP1Operations.Reader.RTypeReader |
5 | | -import LeanRV64D.RiscvInstsEnd |
6 | | - |
7 | 1 | import SP1Chips.Add.Constraints |
8 | 2 |
|
9 | | -open LeanRV64D.Functions BitVec |
| 3 | +open LeanRV64D.Functions |
10 | 4 |
|
11 | 5 | namespace Add |
12 | 6 |
|
13 | | -variable |
14 | | - (Main : Vector (Fin KB) 34) |
15 | | - (s : SailState) |
16 | | - (cstrs : (constraints Main).allHold) |
17 | | - (h_is_real : Main[33] = 1) |
18 | | - |
19 | | -noncomputable def spec_add (rs2 rs1 rd : regidx) : SailM Unit := do |
20 | | - Sail.writeReg Register.nextPC ((← Sail.readReg Register.PC) + 4#64) |
21 | | - _ ← execute_RTYPE rs2 rs1 rd rop.ADD |
22 | | - pure () |
| 7 | +variable (Main : Vector (Fin KB) 34) |
23 | 8 |
|
| 9 | +-- The input and output values in the SP1 implementation |
24 | 10 | def sp1_op_a : BitVec 5 := BitVec.ofNat 5 Main[6] |
25 | | - |
26 | 11 | def sp1_op_b : BitVec 5 := BitVec.ofNat 5 Main[14] |
27 | | - |
28 | 12 | def sp1_op_c : BitVec 5 := BitVec.ofNat 5 Main[21] |
29 | 13 |
|
30 | | -def sp1_add : SailM Unit := do |
31 | | - let op_a := sp1_op_a Main |
| 14 | +/-- Specification of the ADD operation in sail, while setting the next program counter-/ |
| 15 | +def spec_add (rs2 rs1 rd : regidx) : SailM ExecutionResult := do |
| 16 | + Sail.writeReg Register.nextPC ((← Sail.readReg Register.PC) + 4#64) |
| 17 | + execute_RTYPE rs2 rs1 rd rop.ADD |
| 18 | + |
| 19 | +/-- Behavior of the ADD operation in SP1, writing the given values to registers-/ |
| 20 | +def sp1_add : SailM ExecutionResult := do |
32 | 21 | Sail.writeReg Register.nextPC (Word.toBitVec64 #v[Main[3] + 4, Main[4], Main[5], 0]) |
33 | | - Sail.write_reg op_a (Word.toBitVec64 #v[Main[29], Main[30], Main[31], Main[32]]) |
| 22 | + Sail.write_reg (sp1_op_a Main) (Word.toBitVec64 #v[Main[29], Main[30], Main[31], Main[32]]) |
| 23 | + return RETIRE_SUCCESS |
34 | 24 |
|
35 | 25 | open Sail |
36 | 26 |
|
37 | | -set_option pp.parens true in |
| 27 | +/-- Given that all the constraints hold for the input `Main`, `s` is a machine state with |
| 28 | +registers initialized to appropriate values, and the column is a real column, |
| 29 | +the Sail spec and SP1 implementation behave the same. -/ |
38 | 30 | theorem correct_add |
39 | | - (Main : Vector (Fin KB) 34) |
40 | | - (s : SailState) |
41 | | - (cstrs : (constraints Main).allHold) |
42 | | - (h_is_real : Main[33] = 1) |
43 | | - (state_cstrs : (constraints Main).initialState s) : |
44 | | - let op_c := sp1_op_c Main |
45 | | - let op_b := sp1_op_b Main |
46 | | - let op_a := sp1_op_a Main |
47 | | - (spec_add (.Regidx op_c) (.Regidx op_b) (.Regidx op_a)).run s = (sp1_add Main).run s |
48 | | - := by |
49 | | - simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, List.Forall, AddOperation.constraints, CPUState.constraints, RTypeReader.constraints] at state_cstrs |
50 | | - obtain ⟨read_pc, trusted_instr_state, _, read_op_b, read_op_c⟩ := state_cstrs |
51 | | - simp [constraints] at cstrs |
52 | | - obtain ⟨add_op_cstrs, cpu_cstrs, reader_cstrs, rest⟩ := cstrs |
53 | | - rw [CPUState.allHold_constraints_iff_is_real h_is_real] at cpu_cstrs |
54 | | - rw [RTypeReader.allHold_constraints_iff_is_real h_is_real] at reader_cstrs |
55 | | - simp [Opcode.ofNat, Nat.ble] at reader_cstrs |
56 | | - obtain ⟨ trusted_instr_prop, _, _, _, _, _, _, _, ⟨ ⟨ _, _, ⟨ _, is_U64_b, is_U64_c ⟩ ⟩, _ ⟩⟩ := reader_cstrs |
57 | | - simp [Opcode.ofNat, Nat.ble] at trusted_instr_state trusted_instr_prop |
| 31 | + (Main : Vector (Fin KB) 34) |
| 32 | + (s : SailState) |
| 33 | + (h_cstrs : (constraints Main).allHold) |
| 34 | + (h_is_real : Main[33] = 1) |
| 35 | + (state_cstrs : (constraints Main).initialState s) : |
| 36 | + let op_c := .Regidx (sp1_op_c Main) |
| 37 | + let op_b := .Regidx (sp1_op_b Main) |
| 38 | + let op_a := .Regidx (sp1_op_a Main) |
| 39 | + (spec_add op_c op_b op_a).run s = (sp1_add Main).run s := by |
| 40 | + -- Simplify the main constraints and split them into parts |
| 41 | + simp [constraints] at h_cstrs |
| 42 | + obtain ⟨add_op_cstrs, cpu_cstrs, reader_cstrs, rest⟩ := h_cstrs |
| 43 | + rw [CPUState.allHold_constraints_iff_is_real h_is_real] at cpu_cstrs |
| 44 | + rw [RTypeReader.allHold_constraints_iff_is_real h_is_real] at reader_cstrs |
| 45 | + simp [Opcode.ofNat, Nat.ble] at reader_cstrs |
58 | 46 |
|
59 | | - rw [h_is_real] at * |
60 | | - apply AddOperation.spec is_U64_b is_U64_c at add_op_cstrs |
61 | | - obtain ⟨ is_U64_val, is_add ⟩ := add_op_cstrs |
62 | | - simp [BitVec.ofNatLT_eq_ofNat] at * |
| 47 | + -- Show the write values are all register values (i.e. are 5-bit) |
| 48 | + have h6 : Main[6] < 32 := by aesop |
| 49 | + have h14 : Main[14] < 32 := by aesop |
| 50 | + have h21 : Main[21] < 32 := by aesop |
63 | 51 |
|
64 | | - -- Now the monadic manipulation |
65 | | - simp [spec_add, sp1_add, execute, execute_RTYPE'] |
66 | | - rw [run_readReg, read_pc] |
67 | | - simp [sp1_op_b, read_op_b (by omega)] |
68 | | - simp [sp1_op_c, read_op_c (by omega)] |
69 | | - simp [sp1_op_a] |
70 | | - rw [KoalaBear.add4_into_pc_ofNat (by omega)] |
| 52 | + -- Extract constraints about the initial register states |
| 53 | + simp [SP1ConstraintList.initialState, constraints, SP1Constraint.toStateProp, |
| 54 | + List.Forall, AddOperation.constraints, CPUState.constraints, BitVec.ofNatLT_eq_ofNat, |
| 55 | + RTypeReader.constraints, h6, h14, h21, h_is_real] at state_cstrs |
| 56 | + obtain ⟨read_pc, read_op_a, read_op_b, read_op_c⟩ := state_cstrs |
| 57 | + |
| 58 | + rw [h_is_real] at * |
| 59 | + apply AddOperation.spec (by aesop) (by aesop) at add_op_cstrs |
71 | 60 |
|
72 | | - by_cases h_is_op_a_0 : Main[6] = 0 <;> simp_all |
73 | | - . rw [← is_add] |
74 | | - simp [Word.toBitVec64, Word.toNat] |
75 | | - . rw [if_neg (by simp [← BitVec.toNat_inj]; omega)] |
76 | | - rw [if_neg (by simp [← BitVec.toNat_inj]; omega)] |
77 | | - simp [Word.toBitVec64, Word.toNat] |
78 | | - rfl |
| 61 | + -- Simplify the monadic operations |
| 62 | + simp [spec_add, sp1_add, execute, execute_RTYPE'] |
| 63 | + rw [run_readReg, read_pc] |
| 64 | + simp [sp1_op_b, read_op_b, sp1_op_c, read_op_c, sp1_op_a] |
| 65 | + |
| 66 | + -- Simplify the expressions using the arithmetic constraints |
| 67 | + by_cases h_is_op_a_0 : Main[6] = 0 <;> simp_all |
| 68 | + . rw [← add_op_cstrs.2] |
| 69 | + simp [Word.toBitVec64, Word.toNat] |
| 70 | + rw [KoalaBear.add4_into_pc_ofNat (by omega)] |
| 71 | + . rw [if_neg (by simp [← BitVec.toNat_inj]; omega), if_neg (by simp [← BitVec.toNat_inj]; omega)] |
| 72 | + simp [execute_RTYPE_pure, bitVecToRegidxVal, Word.toBitVec64, Word.toNat] |
| 73 | + rw [KoalaBear.add4_into_pc_ofNat (by omega)] |
| 74 | + simp |
79 | 75 |
|
80 | 76 | end Add |
0 commit comments