sp1_core_machine/memory/consistency/columns.rs
1use serde::{Deserialize, Serialize};
2use sp1_derive::{AlignedBorrow, IntoShape};
3use sp1_hypercube::Word;
4
5use struct_reflection::{StructReflection, StructReflectionHelper};
6
7use crate::operations::U16toU8Operation;
8
9/// Memory Access Timestamp
10#[derive(AlignedBorrow, StructReflection, Default, Debug, Clone, Copy)]
11#[repr(C)]
12pub struct MemoryAccessTimestamp<T> {
13 /// The previous timestamp's high 24 bits that this memory access is being read from.
14 pub prev_high: T,
15 /// The previous timestamp's low 24 bits that this memory access is being read from.
16 pub prev_low: T,
17 /// This will be true if the top 24 bits do not match.
18 pub compare_low: T,
19 /// The following columns are decomposed limbs for the difference between the current access's
20 /// timestamp and the previous access's timestamp. Note the actual value of the timestamp
21 /// is either the accesses' high or low 24 bits depending on the value of compare_low.
22 ///
23 /// This column is the least significant 16 bit limb of the difference.
24 pub diff_low_limb: T,
25 /// This column is the most significant 8 bit limb of the difference.
26 pub diff_high_limb: T,
27}
28
29/// Memory Access Columns
30#[derive(AlignedBorrow, StructReflection, Default, Debug, Clone, Copy)]
31#[repr(C)]
32pub struct MemoryAccessCols<T> {
33 pub prev_value: Word<T>,
34 pub access_timestamp: MemoryAccessTimestamp<T>,
35}
36
37/// Memory Access Columns for u8 limbs
38#[derive(AlignedBorrow, Default, Debug, Clone, Copy)]
39#[repr(C)]
40pub struct MemoryAccessColsU8<T> {
41 pub memory_access: MemoryAccessCols<T>,
42 pub prev_value_u8: U16toU8Operation<T>,
43}
44
45/// Register Access Timestamp. The register accesses use the same argument as the memory accesses,
46/// and shares the same space as the memory. This structure is used for register accesses in RISC-V.
47/// For optimization, we ensure that all register accesses have the high limb of the timestamp and
48/// previous timestamp to be equal. This is done through adding in a "shadow" read, through the
49/// `MemoryBump` chip. Therefore, only the columns for low limb comparison is needed here.
50#[derive(
51 AlignedBorrow, StructReflection, Default, Debug, Clone, Copy, Serialize, Deserialize, IntoShape,
52)]
53#[repr(C)]
54pub struct RegisterAccessTimestamp<T> {
55 /// The previous timestamp that this memory access is being read from.
56 pub prev_low: T,
57 /// The difference in timestamp's least significant 16 bit limb.
58 pub diff_low_limb: T,
59}
60
61/// Register Access Columns
62#[derive(
63 AlignedBorrow, StructReflection, Default, Debug, Clone, Copy, Serialize, Deserialize, IntoShape,
64)]
65pub struct RegisterAccessCols<T> {
66 pub prev_value: Word<T>,
67 pub access_timestamp: RegisterAccessTimestamp<T>,
68}
69
70/// Page Permission Access Columns, when the shard and previous shard are known to be equal
71#[derive(AlignedBorrow, StructReflection, Default, Debug, Clone, Copy)]
72#[repr(C)]
73pub struct PageProtAccessCols<T> {
74 pub prev_prot_bitmap: T,
75 pub access_timestamp: MemoryAccessTimestamp<T>,
76}