sp1_core_machine/cpu/columns/
mod.rs

1mod instruction;
2
3pub use instruction::*;
4
5use p3_util::indices_arr;
6use sp1_derive::AlignedBorrow;
7use sp1_stark::Word;
8use std::mem::{size_of, transmute};
9
10use crate::memory::{MemoryCols, MemoryReadCols, MemoryReadWriteCols};
11
12pub const NUM_CPU_COLS: usize = size_of::<CpuCols<u8>>();
13
14pub const CPU_COL_MAP: CpuCols<usize> = make_col_map();
15
16/// The column layout for the CPU.
17#[derive(AlignedBorrow, Default, Debug, Clone, Copy)]
18#[repr(C)]
19pub struct CpuCols<T: Copy> {
20    /// The current shard.
21    pub shard: T,
22
23    /// The least significant 16 bit limb of clk.
24    pub clk_16bit_limb: T,
25    /// The most significant 8 bit limb of clk.
26    pub clk_8bit_limb: T,
27
28    /// The shard to send to the opcode specific tables.  This should be 0 for all instructions
29    /// other than the ecall and memory instructions.
30    pub shard_to_send: T,
31    /// The clk to send to the opcode specific tables.  This should be 0 for all instructions other
32    /// than the ecall and memory instructions.
33    pub clk_to_send: T,
34
35    /// The program counter value.
36    pub pc: T,
37
38    /// The expected next program counter value.
39    pub next_pc: T,
40
41    /// Columns related to the instruction.
42    pub instruction: InstructionCols<T>,
43
44    /// Whether op_a should not be changed by the instruction.  This should be true for
45    /// memory store and branch instructions.
46    pub op_a_immutable: T,
47
48    /// Whether this is a memory instruction.
49    pub is_memory: T,
50
51    /// Whether this is a syscall instruction.
52    pub is_syscall: T,
53
54    /// Whether this is a halt instruction.
55    pub is_halt: T,
56
57    /// The number of extra cycles to add to the clk for a syscall instruction.
58    pub num_extra_cycles: T,
59
60    /// Operand values, either from registers or immediate values.
61    pub op_a_access: MemoryReadWriteCols<T>,
62    pub op_b_access: MemoryReadCols<T>,
63    pub op_c_access: MemoryReadCols<T>,
64
65    /// Selector to label whether this row is a non padded row.
66    pub is_real: T,
67}
68
69impl<T: Copy> CpuCols<T> {
70    /// Gets the value of the first operand.
71    pub fn op_a_val(&self) -> Word<T> {
72        *self.op_a_access.value()
73    }
74
75    /// Gets the value of the second operand.
76    pub fn op_b_val(&self) -> Word<T> {
77        *self.op_b_access.value()
78    }
79
80    /// Gets the value of the third operand.
81    pub fn op_c_val(&self) -> Word<T> {
82        *self.op_c_access.value()
83    }
84}
85
86/// Creates the column map for the CPU.
87const fn make_col_map() -> CpuCols<usize> {
88    let indices_arr = indices_arr::<NUM_CPU_COLS>();
89    unsafe { transmute::<[usize; NUM_CPU_COLS], CpuCols<usize>>(indices_arr) }
90}