openvm_circuit/arch/testing/
mod.rs1mod cpu;
2#[cfg(feature = "cuda")]
3mod cuda;
4pub mod execution;
5pub mod memory;
6pub mod program;
7mod utils;
8
9use std::marker::PhantomData;
10
11pub use cpu::*;
12#[cfg(feature = "cuda")]
13pub use cuda::*;
14pub use execution::ExecutionTester;
15pub use memory::MemoryTester;
16use openvm_circuit_primitives::utils::next_power_of_two_or_zero;
17use openvm_instructions::instruction::Instruction;
18use openvm_stark_backend::{interaction::BusIndex, p3_air::BaseAir};
19use p3_field::Field;
20pub use utils::*;
21
22use crate::arch::{Arena, ExecutionState, MatrixRecordArena, PreflightExecutor, Streams};
23
24pub const EXECUTION_BUS: BusIndex = 0;
25pub const MEMORY_BUS: BusIndex = 1;
26pub const POSEIDON2_DIRECT_BUS: BusIndex = 6;
27pub const READ_INSTRUCTION_BUS: BusIndex = 8;
28pub const BITWISE_OP_LOOKUP_BUS: BusIndex = 9;
29pub const BYTE_XOR_BUS: BusIndex = 10;
30pub const RANGE_TUPLE_CHECKER_BUS: BusIndex = 11;
31pub const MEMORY_MERKLE_BUS: BusIndex = 12;
32
33pub const RANGE_CHECKER_BUS: BusIndex = 4;
34
35pub type ArenaId = usize;
36
37pub struct TestChipHarness<F, E, A, C, RA = MatrixRecordArena<F>> {
38 pub executor: E,
39 pub air: A,
40 pub chip: C,
41 pub arena: RA,
42 phantom: PhantomData<F>,
43}
44
45impl<F, E, A, C, RA> TestChipHarness<F, E, A, C, RA>
46where
47 F: Field,
48 A: BaseAir<F>,
49 RA: Arena,
50{
51 pub fn with_capacity(executor: E, air: A, chip: C, height: usize) -> Self {
52 let width = air.width();
53 let height = next_power_of_two_or_zero(height);
54 let arena = RA::with_capacity(height, width);
55 Self {
56 executor,
57 air,
58 chip,
59 arena,
60 phantom: PhantomData,
61 }
62 }
63}
64
65pub trait TestBuilder<F> {
66 fn execute<E: PreflightExecutor<F, RA>, RA: Arena>(
67 &mut self,
68 executor: &mut E,
69 arena: &mut RA,
70 instruction: &Instruction<F>,
71 );
72
73 fn execute_with_pc<E: PreflightExecutor<F, RA>, RA: Arena>(
74 &mut self,
75 executor: &mut E,
76 arena: &mut RA,
77 instruction: &Instruction<F>,
78 initial_pc: u32,
79 );
80
81 fn write_cell(&mut self, address_space: usize, pointer: usize, value: F);
82 fn read_cell(&mut self, address_space: usize, pointer: usize) -> F;
83
84 fn write<const N: usize>(&mut self, address_space: usize, pointer: usize, value: [F; N]);
85 fn read<const N: usize>(&mut self, address_space: usize, pointer: usize) -> [F; N];
86
87 fn write_usize<const N: usize>(
88 &mut self,
89 address_space: usize,
90 pointer: usize,
91 value: [usize; N],
92 );
93
94 fn address_bits(&self) -> usize;
95
96 fn last_to_pc(&self) -> F;
97 fn last_from_pc(&self) -> F;
98
99 fn execution_final_state(&self) -> ExecutionState<F>;
100 fn streams_mut(&mut self) -> &mut Streams<F>;
101
102 fn get_default_register(&mut self, increment: usize) -> usize;
103 fn get_default_pointer(&mut self, increment: usize) -> usize;
104
105 fn write_heap_pointer_default(
106 &mut self,
107 reg_increment: usize,
108 pointer_increment: usize,
109 ) -> (usize, usize);
110
111 fn write_heap_default<const NUM_LIMBS: usize>(
112 &mut self,
113 reg_increment: usize,
114 pointer_increment: usize,
115 writes: Vec<[F; NUM_LIMBS]>,
116 ) -> (usize, usize);
117}