openvm_circuit/system/memory/offline_checker/
columns.rs

1//! Defines auxiliary columns for memory operations: `MemoryReadAuxCols`,
2//! `MemoryReadWithImmediateAuxCols`, and `MemoryWriteAuxCols`.
3
4use openvm_circuit_primitives::{
5    is_less_than::LessThanAuxCols, StructReflection, StructReflectionHelper,
6};
7use openvm_circuit_primitives_derive::AlignedBorrow;
8use openvm_stark_backend::p3_field::PrimeField32;
9
10use crate::system::memory::offline_checker::bridge::AUX_LEN;
11
12// repr(C) is needed to make sure that the compiler does not reorder the fields
13// we assume the order of the fields when using borrow or borrow_mut
14/// Base structure for auxiliary memory columns.
15#[repr(C)]
16#[derive(Clone, Copy, Debug, AlignedBorrow, StructReflection)]
17pub struct MemoryBaseAuxCols<T> {
18    /// The previous timestamps in which the cells were accessed.
19    pub prev_timestamp: T,
20    /// The auxiliary columns to perform the less than check.
21    pub timestamp_lt_aux: LessThanAuxCols<T, AUX_LEN>,
22}
23
24impl<F: PrimeField32> MemoryBaseAuxCols<F> {
25    #[inline(always)]
26    pub fn set_prev(&mut self, prev_timestamp: F) {
27        self.prev_timestamp = prev_timestamp;
28    }
29}
30
31#[repr(C)]
32#[derive(Clone, Copy, Debug, AlignedBorrow, StructReflection)]
33pub struct MemoryWriteAuxCols<T, const N: usize> {
34    pub base: MemoryBaseAuxCols<T>,
35    pub prev_data: [T; N],
36}
37
38impl<const N: usize, T> MemoryWriteAuxCols<T, N> {
39    pub fn from_base(base: MemoryBaseAuxCols<T>, prev_data: [T; N]) -> Self {
40        Self { base, prev_data }
41    }
42
43    #[inline(always)]
44    pub fn get_base(self) -> MemoryBaseAuxCols<T> {
45        self.base
46    }
47
48    #[inline(always)]
49    pub fn prev_data(&self) -> &[T; N] {
50        &self.prev_data
51    }
52
53    /// Sets the previous data **without** updating the less than auxiliary columns.
54    #[inline(always)]
55    pub fn set_prev_data(&mut self, data: [T; N]) {
56        self.prev_data = data;
57    }
58}
59
60/// The auxiliary columns for a memory read operation with block size `N`.
61/// These columns should be automatically managed by the memory controller.
62/// To fully constrain a memory read, in addition to these columns,
63/// the address space, pointer, and data must be provided.
64#[repr(C)]
65#[derive(Clone, Copy, Debug, AlignedBorrow, StructReflection)]
66pub struct MemoryReadAuxCols<T> {
67    pub(in crate::system::memory) base: MemoryBaseAuxCols<T>,
68}
69
70impl<F: PrimeField32> MemoryReadAuxCols<F> {
71    pub fn new(prev_timestamp: u32, timestamp_lt_aux: LessThanAuxCols<F, AUX_LEN>) -> Self {
72        Self {
73            base: MemoryBaseAuxCols {
74                prev_timestamp: F::from_u32(prev_timestamp),
75                timestamp_lt_aux,
76            },
77        }
78    }
79
80    #[inline(always)]
81    pub fn get_base(self) -> MemoryBaseAuxCols<F> {
82        self.base
83    }
84
85    /// Sets the previous timestamp **without** updating the less than auxiliary columns.
86    #[inline(always)]
87    pub fn set_prev(&mut self, timestamp: F) {
88        self.base.prev_timestamp = timestamp;
89    }
90}
91
92#[repr(C)]
93#[derive(Clone, Debug, AlignedBorrow, StructReflection)]
94pub struct MemoryReadOrImmediateAuxCols<T> {
95    pub base: MemoryBaseAuxCols<T>,
96    pub is_immediate: T,
97    pub is_zero_aux: T,
98}
99
100impl<T, const N: usize> AsRef<MemoryReadAuxCols<T>> for MemoryWriteAuxCols<T, N> {
101    fn as_ref(&self) -> &MemoryReadAuxCols<T> {
102        // Safety:
103        //  - `MemoryReadAuxCols<T>` is repr(C) and its only field is the first field of
104        //    `MemoryWriteAuxCols<T, N>`.
105        //  - Thus, the memory layout of `MemoryWriteAuxCols<T, N>` begins with a valid
106        //    `MemoryReadAuxCols<T>`.
107        unsafe { &*(self as *const MemoryWriteAuxCols<T, N> as *const MemoryReadAuxCols<T>) }
108    }
109}
110
111impl<T, const N: usize> AsMut<MemoryBaseAuxCols<T>> for MemoryWriteAuxCols<T, N> {
112    fn as_mut(&mut self) -> &mut MemoryBaseAuxCols<T> {
113        &mut self.base
114    }
115}
116
117impl<T> AsMut<MemoryBaseAuxCols<T>> for MemoryReadAuxCols<T> {
118    fn as_mut(&mut self) -> &mut MemoryBaseAuxCols<T> {
119        &mut self.base
120    }
121}
122
123impl<T> AsMut<MemoryBaseAuxCols<T>> for MemoryReadOrImmediateAuxCols<T> {
124    fn as_mut(&mut self) -> &mut MemoryBaseAuxCols<T> {
125        &mut self.base
126    }
127}