sp1_core_machine/memory/consistency/
trace.rs1use p3_field::PrimeField32;
2use sp1_core_executor::events::{
3 ByteRecord, MemoryReadRecord, MemoryRecord, MemoryRecordEnum, MemoryWriteRecord,
4};
5
6use super::{MemoryAccessCols, MemoryReadCols, MemoryReadWriteCols, MemoryWriteCols};
7
8impl<F: PrimeField32> MemoryWriteCols<F> {
9 pub fn populate(&mut self, record: MemoryWriteRecord, output: &mut impl ByteRecord) {
10 let current_record =
11 MemoryRecord { value: record.value, shard: record.shard, timestamp: record.timestamp };
12 let prev_record = MemoryRecord {
13 value: record.prev_value,
14 shard: record.prev_shard,
15 timestamp: record.prev_timestamp,
16 };
17 self.prev_value = prev_record.value.into();
18 self.access.populate_access(current_record, prev_record, output);
19 }
20}
21
22impl<F: PrimeField32> MemoryReadCols<F> {
23 pub fn populate(&mut self, record: MemoryReadRecord, output: &mut impl ByteRecord) {
24 let current_record =
25 MemoryRecord { value: record.value, shard: record.shard, timestamp: record.timestamp };
26 let prev_record = MemoryRecord {
27 value: record.value,
28 shard: record.prev_shard,
29 timestamp: record.prev_timestamp,
30 };
31 self.access.populate_access(current_record, prev_record, output);
32 }
33}
34
35impl<F: PrimeField32> MemoryReadWriteCols<F> {
36 pub fn populate(&mut self, record: MemoryRecordEnum, output: &mut impl ByteRecord) {
37 match record {
38 MemoryRecordEnum::Read(read_record) => self.populate_read(read_record, output),
39 MemoryRecordEnum::Write(write_record) => self.populate_write(write_record, output),
40 }
41 }
42
43 pub fn populate_write(&mut self, record: MemoryWriteRecord, output: &mut impl ByteRecord) {
44 let current_record =
45 MemoryRecord { value: record.value, shard: record.shard, timestamp: record.timestamp };
46 let prev_record = MemoryRecord {
47 value: record.prev_value,
48 shard: record.prev_shard,
49 timestamp: record.prev_timestamp,
50 };
51 self.prev_value = prev_record.value.into();
52 self.access.populate_access(current_record, prev_record, output);
53 }
54
55 pub fn populate_read(&mut self, record: MemoryReadRecord, output: &mut impl ByteRecord) {
56 let current_record =
57 MemoryRecord { value: record.value, shard: record.shard, timestamp: record.timestamp };
58 let prev_record = MemoryRecord {
59 value: record.value,
60 shard: record.prev_shard,
61 timestamp: record.prev_timestamp,
62 };
63 self.prev_value = prev_record.value.into();
64 self.access.populate_access(current_record, prev_record, output);
65 }
66}
67
68impl<F: PrimeField32> MemoryAccessCols<F> {
69 pub(crate) fn populate_access(
70 &mut self,
71 current_record: MemoryRecord,
72 prev_record: MemoryRecord,
73 output: &mut impl ByteRecord,
74 ) {
75 self.value = current_record.value.into();
76
77 self.prev_shard = F::from_canonical_u32(prev_record.shard);
78 self.prev_clk = F::from_canonical_u32(prev_record.timestamp);
79
80 let use_clk_comparison = prev_record.shard == current_record.shard;
83 self.compare_clk = F::from_bool(use_clk_comparison);
84 let prev_time_value =
85 if use_clk_comparison { prev_record.timestamp } else { prev_record.shard };
86 let current_time_value =
87 if use_clk_comparison { current_record.timestamp } else { current_record.shard };
88
89 let diff_minus_one = current_time_value - prev_time_value - 1;
90 let diff_16bit_limb = (diff_minus_one & 0xffff) as u16;
91 self.diff_16bit_limb = F::from_canonical_u16(diff_16bit_limb);
92 let diff_8bit_limb = (diff_minus_one >> 16) & 0xff;
93 self.diff_8bit_limb = F::from_canonical_u32(diff_8bit_limb);
94
95 output.add_u16_range_check(diff_16bit_limb);
97
98 output.add_u8_range_check(0, diff_8bit_limb as u8);
100 }
101}