diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b9f30b3d..03a183f36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ #### Changes - Update minimum supported Rust version to 1.84. +- Change Chiplet Fields to Public (#1629). ## 0.12.0 (2025-01-22) diff --git a/miden/src/repl/mod.rs b/miden/src/repl/mod.rs index 037df6e0f..3f7537bf8 100644 --- a/miden/src/repl/mod.rs +++ b/miden/src/repl/mod.rs @@ -331,7 +331,7 @@ fn execute( } // loads the memory at the latest clock cycle. - let mem_state = chiplets.memory().get_state_at(ContextId::root(), system.clk()); + let mem_state = chiplets.memory.get_state_at(ContextId::root(), system.clk()); // loads the stack along with the overflow values at the latest clock cycle. let stack_state = stack.get_state_at(system.clk()); diff --git a/processor/src/chiplets/hasher/mod.rs b/processor/src/chiplets/hasher/mod.rs index eba72ff77..bd22e5e46 100644 --- a/processor/src/chiplets/hasher/mod.rs +++ b/processor/src/chiplets/hasher/mod.rs @@ -77,7 +77,7 @@ impl Hasher { /// /// The returned tuple contains the hasher state after the permutation and the row address of /// the execution trace at which the permutation started. - pub(super) fn permute(&mut self, mut state: HasherState) -> (Felt, HasherState) { + pub fn permute(&mut self, mut state: HasherState) -> (Felt, HasherState) { let addr = self.trace.next_row_addr(); // perform the hash. @@ -91,7 +91,7 @@ impl Hasher { /// /// The returned tuple also contains the row address of the execution trace at which the hash /// computation started. - pub(super) fn hash_control_block( + pub fn hash_control_block( &mut self, h1: Word, h2: Word, @@ -121,7 +121,7 @@ impl Hasher { /// /// The returned tuple also contains the row address of the execution trace at which the hash /// computation started. - pub(super) fn hash_basic_block( + pub fn hash_basic_block( &mut self, op_batches: &[OpBatch], expected_hash: Digest, @@ -202,7 +202,7 @@ impl Hasher { /// Panics if: /// - The provided path does not contain any nodes. /// - The provided index is out of range for the specified path. - pub(super) fn build_merkle_root( + pub fn build_merkle_root( &mut self, value: Word, path: &MerklePath, @@ -225,7 +225,7 @@ impl Hasher { /// Panics if: /// - The provided path does not contain any nodes. /// - The provided index is out of range for the specified path. - pub(super) fn update_merkle_root( + pub fn update_merkle_root( &mut self, old_value: Word, new_value: Word, diff --git a/processor/src/chiplets/mod.rs b/processor/src/chiplets/mod.rs index c36dda194..ca888d629 100644 --- a/processor/src/chiplets/mod.rs +++ b/processor/src/chiplets/mod.rs @@ -114,12 +114,10 @@ mod tests; /// ``` #[derive(Debug)] pub struct Chiplets { - /// Current clock cycle of the VM. - clk: RowIndex, - hasher: Hasher, - bitwise: Bitwise, - memory: Memory, - kernel_rom: KernelRom, + pub hasher: Hasher, + pub bitwise: Bitwise, + pub memory: Memory, + pub kernel_rom: KernelRom, } impl Chiplets { @@ -128,7 +126,6 @@ impl Chiplets { /// Returns a new [Chiplets] component instantiated with the provided Kernel. pub fn new(kernel: Kernel) -> Self { Self { - clk: RowIndex::from(0), hasher: Hasher::default(), bitwise: Bitwise::default(), memory: Memory::default(), @@ -170,153 +167,6 @@ impl Chiplets { self.kernel_rom_start() + self.kernel_rom.trace_len() } - /// Returns the underlying kernel used to initilize this instance. - pub const fn kernel(&self) -> &Kernel { - self.kernel_rom.kernel() - } - - // HASH CHIPLET ACCESSORS FOR OPERATIONS - // -------------------------------------------------------------------------------------------- - - /// Requests a single permutation of the hash function to the provided state from the Hash - /// chiplet. - /// - /// The returned tuple contains the hasher state after the permutation and the row address of - /// the execution trace at which the permutation started. - pub fn permute(&mut self, state: HasherState) -> (Felt, HasherState) { - let (addr, return_state) = self.hasher.permute(state); - - (addr, return_state) - } - - /// Requests a Merkle root computation from the Hash chiplet for the specified path and the node - /// with the specified value. - /// - /// The returned tuple contains the root of the Merkle path and the row address of the - /// execution trace at which the computation started. - /// - /// # Panics - /// Panics if: - /// - The provided path does not contain any nodes. - /// - The provided index is out of range for the specified path. - pub fn build_merkle_root( - &mut self, - value: Word, - path: &MerklePath, - index: Felt, - ) -> (Felt, Word) { - let (addr, root) = self.hasher.build_merkle_root(value, path, index); - - (addr, root) - } - - /// Requests a Merkle root update computation from the Hash chiplet. - /// - /// # Panics - /// Panics if: - /// - The provided path does not contain any nodes. - /// - The provided index is out of range for the specified path. - pub fn update_merkle_root( - &mut self, - old_value: Word, - new_value: Word, - path: &MerklePath, - index: Felt, - ) -> MerkleRootUpdate { - self.hasher.update_merkle_root(old_value, new_value, path, index) - } - - // HASH CHIPLET ACCESSORS FOR CONTROL BLOCK DECODING - // -------------------------------------------------------------------------------------------- - - /// Requests the hash of the provided words from the Hash chiplet and checks the result - /// hash(h1, h2) against the provided `expected_result`. - /// - /// It returns the row address of the execution trace at which the hash computation started. - pub fn hash_control_block( - &mut self, - h1: Word, - h2: Word, - domain: Felt, - expected_hash: Digest, - ) -> Felt { - let (addr, result) = self.hasher.hash_control_block(h1, h2, domain, expected_hash); - - // make sure the result computed by the hasher is the same as the expected block hash - debug_assert_eq!(expected_hash, result.into()); - - addr - } - - /// Requests computation a sequential hash of all operation batches in the list from the Hash - /// chiplet and checks the result against the provided `expected_result`. - /// - /// It returns the row address of the execution trace at which the hash computation started. - pub fn hash_span_block(&mut self, op_batches: &[OpBatch], expected_hash: Digest) -> Felt { - let (addr, result) = self.hasher.hash_basic_block(op_batches, expected_hash); - - // make sure the result computed by the hasher is the same as the expected block hash - debug_assert_eq!(expected_hash, result.into()); - - addr - } - - // BITWISE CHIPLET ACCESSORS - // -------------------------------------------------------------------------------------------- - - /// Requests a bitwise AND of `a` and `b` from the Bitwise chiplet and returns the result. - /// We assume that `a` and `b` are 32-bit values. If that's not the case, the result of the - /// computation is undefined. - pub fn u32and(&mut self, a: Felt, b: Felt) -> Result { - let result = self.bitwise.u32and(a, b)?; - - Ok(result) - } - - /// Requests a bitwise XOR of `a` and `b` from the Bitwise chiplet and returns the result. - /// We assume that `a` and `b` are 32-bit values. If that's not the case, the result of the - /// computation is undefined. - pub fn u32xor(&mut self, a: Felt, b: Felt) -> Result { - let result = self.bitwise.u32xor(a, b)?; - - Ok(result) - } - - // MEMORY CHIPLET ACCESSORS - // -------------------------------------------------------------------------------------------- - - /// Returns a reference to the Memory chiplet. - pub fn memory(&self) -> &Memory { - &self.memory - } - - /// Returns a mutable reference to the Memory chiplet. - pub fn memory_mut(&mut self) -> &mut Memory { - &mut self.memory - } - - // KERNEL ROM ACCESSORS - // -------------------------------------------------------------------------------------------- - - /// Increments access counter for the specified kernel procedure. - /// - /// # Errors - /// Returns an error if the procedure with the specified hash does not exist in the kernel - /// with which the kernel ROM was instantiated. - pub fn access_kernel_proc(&mut self, proc_hash: Digest) -> Result<(), ExecutionError> { - self.kernel_rom.access_proc(proc_hash)?; - - Ok(()) - } - - // CONTEXT MANAGEMENT - // -------------------------------------------------------------------------------------------- - - /// Increments the clock cycle. - pub fn advance_clock(&mut self) { - self.clk += 1; - } - // EXECUTION TRACE // -------------------------------------------------------------------------------------------- @@ -335,7 +185,7 @@ impl Chiplets { // make sure that only padding rows will be overwritten by random values assert!(self.trace_len() + num_rand_rows <= trace_len, "target trace length too small"); - let kernel = self.kernel().clone(); + let kernel = self.kernel_rom.kernel().clone(); // Allocate columns for the trace of the chiplets. let mut trace = (0..CHIPLETS_WIDTH) @@ -367,13 +217,7 @@ impl Chiplets { let kernel_rom_start: usize = self.kernel_rom_start().into(); let padding_start: usize = self.padding_start().into(); - let Chiplets { - clk: _, - hasher, - bitwise, - memory, - kernel_rom, - } = self; + let Chiplets { hasher, bitwise, memory, kernel_rom } = self; // populate external selector columns for all chiplets trace[0][bitwise_start..].fill(ONE); diff --git a/processor/src/debug.rs b/processor/src/debug.rs index 805b7f64a..4826811a8 100644 --- a/processor/src/debug.rs +++ b/processor/src/debug.rs @@ -165,7 +165,7 @@ impl VmStateIterator { asmop, fmp: self.system.get_fmp_at(self.clk), stack: self.stack.get_state_at(self.clk), - memory: self.chiplets.memory().get_state_at(ctx, self.clk), + memory: self.chiplets.memory.get_state_at(ctx, self.clk), }); self.clk -= 1; @@ -235,7 +235,7 @@ impl Iterator for VmStateIterator { asmop, fmp: self.system.get_fmp_at(self.clk), stack: self.stack.get_state_at(self.clk), - memory: self.chiplets.memory().get_state_at(ctx, self.clk), + memory: self.chiplets.memory.get_state_at(ctx, self.clk), })); self.clk += 1; diff --git a/processor/src/decoder/mod.rs b/processor/src/decoder/mod.rs index c7575e5b4..8d791e4b8 100644 --- a/processor/src/decoder/mod.rs +++ b/processor/src/decoder/mod.rs @@ -72,13 +72,15 @@ impl Process { .digest() .into(); - let addr = self.chiplets.hash_control_block( + let (addr, hashed_block) = self.chiplets.hasher.hash_control_block( child1_hash, child2_hash, JoinNode::DOMAIN, node.digest(), ); + debug_assert_eq!(node.digest(), hashed_block.into()); + // start decoding the JOIN block; this appends a row with JOIN operation to the decoder // trace. when JOIN operation is executed, the rest of the VM state does not change self.decoder.start_join(child1_hash, child2_hash, addr); @@ -124,13 +126,15 @@ impl Process { .ok_or(ExecutionError::MastNodeNotFoundInForest { node_id: node.on_false() })? .digest() .into(); - let addr = self.chiplets.hash_control_block( + let (addr, hashed_block) = self.chiplets.hasher.hash_control_block( child1_hash, child2_hash, SplitNode::DOMAIN, node.digest(), ); + debug_assert_eq!(node.digest(), hashed_block.into()); + // start decoding the SPLIT block. this appends a row with SPLIT operation to the decoder // trace. we also pop the value off the top of the stack and return it. self.decoder.start_split(child1_hash, child2_hash, addr); @@ -173,13 +177,16 @@ impl Process { .ok_or(ExecutionError::MastNodeNotFoundInForest { node_id: node.body() })? .digest() .into(); - let addr = self.chiplets.hash_control_block( + + let (addr, hashed_block) = self.chiplets.hasher.hash_control_block( body_hash, EMPTY_WORD, LoopNode::DOMAIN, node.digest(), ); + debug_assert_eq!(node.digest(), hashed_block.into()); + // start decoding the LOOP block; this appends a row with LOOP operation to the decoder // trace, but if the value on the top of the stack is not ONE, the block is not marked // as the loop block, and the hash of the body will not be added to the block hash table. @@ -234,9 +241,15 @@ impl Process { .ok_or(ExecutionError::MastNodeNotFoundInForest { node_id: node.callee() })? .digest() .into(); - let addr = - self.chiplets - .hash_control_block(callee_hash, EMPTY_WORD, node.domain(), node.digest()); + + let (addr, hashed_block) = self.chiplets.hasher.hash_control_block( + callee_hash, + EMPTY_WORD, + node.domain(), + node.digest(), + ); + + debug_assert_eq!(node.digest(), hashed_block.into()); // start new execution context for the operand stack. this has the effect of resetting // stack depth to 16. @@ -320,17 +333,17 @@ impl Process { // The callee hash is stored in memory, and the address is specified on the top of the // stack. let callee_hash = - self.chiplets - .memory_mut() - .read_word(self.system.ctx(), mem_addr, self.system.clk())?; + self.chiplets.memory.read_word(self.system.ctx(), mem_addr, self.system.clk())?; - let addr = self.chiplets.hash_control_block( + let (addr, hashed_block) = self.chiplets.hasher.hash_control_block( EMPTY_WORD, EMPTY_WORD, dyn_node.domain(), dyn_node.digest(), ); + debug_assert_eq!(dyn_node.digest(), hashed_block.into()); + self.decoder.start_dyn(addr, callee_hash); // Pop the memory address off the stack. @@ -354,9 +367,7 @@ impl Process { // The callee hash is stored in memory, and the address is specified on the top of the // stack. let callee_hash = - self.chiplets - .memory_mut() - .read_word(self.system.ctx(), mem_addr, self.system.clk())?; + self.chiplets.memory.read_word(self.system.ctx(), mem_addr, self.system.clk())?; // Note: other functions end in "executing a Noop", which // 1. ensures trace capacity, @@ -368,13 +379,15 @@ impl Process { // refactoring the decoder though to remove this Noop execution pattern. self.ensure_trace_capacity(); - let addr = self.chiplets.hash_control_block( + let (addr, hashed_block) = self.chiplets.hasher.hash_control_block( EMPTY_WORD, EMPTY_WORD, dyn_node.domain(), dyn_node.digest(), ); + debug_assert_eq!(dyn_node.digest(), hashed_block.into()); + let (stack_depth, next_overflow_addr) = self.stack.shift_left_and_start_context(); debug_assert!(stack_depth <= u32::MAX as usize, "stack depth too big"); @@ -455,7 +468,10 @@ impl Process { // hashing operation batches. Thus, the result of the hash is expected to be in row // addr + (num_batches * 8) - 1. let op_batches = basic_block.op_batches(); - let addr = self.chiplets.hash_span_block(op_batches, basic_block.digest()); + let (addr, hashed_block) = + self.chiplets.hasher.hash_basic_block(op_batches, basic_block.digest()); + + debug_assert_eq!(basic_block.digest(), hashed_block.into()); // start decoding the first operation batch; this also appends a row with SPAN operation // to the decoder trace. we also need the total number of operation groups so that we can diff --git a/processor/src/lib.rs b/processor/src/lib.rs index c1acc513a..8f03a9506 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -394,7 +394,7 @@ impl Process { let callee = program.get_node_by_id(call_node.callee()).ok_or_else(|| { ExecutionError::MastNodeNotFoundInForest { node_id: call_node.callee() } })?; - self.chiplets.access_kernel_proc(callee.digest())?; + self.chiplets.kernel_rom.access_proc(callee.digest())?; } self.start_call_node(call_node, program, host)?; @@ -617,7 +617,7 @@ impl Process { // ================================================================================================ pub const fn kernel(&self) -> &Kernel { - self.chiplets.kernel() + self.chiplets.kernel_rom.kernel() } pub fn into_parts(self) -> (System, Decoder, Stack, RangeChecker, Chiplets) { @@ -679,7 +679,7 @@ impl ProcessState<'_> { /// Returns the element located at the specified context/address, or None if the address hasn't /// been accessed previously. pub fn get_mem_value(&self, ctx: ContextId, addr: u32) -> Option { - self.chiplets.memory().get_value(ctx, addr) + self.chiplets.memory.get_value(ctx, addr) } /// Returns the batch of elements starting at the specified context/address. @@ -687,7 +687,7 @@ impl ProcessState<'_> { /// # Errors /// - If the address is not word aligned. pub fn get_mem_word(&self, ctx: ContextId, addr: u32) -> Result, ExecutionError> { - self.chiplets.memory().get_word(ctx, addr) + self.chiplets.memory.get_word(ctx, addr) } /// Returns the entire memory state for the specified execution context at the current clock @@ -696,7 +696,7 @@ impl ProcessState<'_> { /// The state is returned as a vector of (address, value) tuples, and includes addresses which /// have been accessed at least once. pub fn get_mem_state(&self, ctx: ContextId) -> Vec<(u64, Felt)> { - self.chiplets.memory().get_state_at(ctx, self.system.clk()) + self.chiplets.memory.get_state_at(ctx, self.system.clk()) } } diff --git a/processor/src/operations/comb_ops.rs b/processor/src/operations/comb_ops.rs index 3a93a6809..0a204a9be 100644 --- a/processor/src/operations/comb_ops.rs +++ b/processor/src/operations/comb_ops.rs @@ -126,7 +126,7 @@ impl Process { fn get_randomness(&mut self) -> Result { let ctx = self.system.ctx(); let addr = self.stack.get(14); - let word = self.chiplets.memory_mut().read_word(ctx, addr, self.system.clk())?; + let word = self.chiplets.memory.read_word(ctx, addr, self.system.clk())?; let a0 = word[0]; let a1 = word[1]; @@ -137,7 +137,7 @@ impl Process { fn get_ood_values(&mut self) -> Result<[QuadFelt; 2], ExecutionError> { let ctx = self.system.ctx(); let addr = self.stack.get(13); - let word = self.chiplets.memory_mut().read_word(ctx, addr, self.system.clk())?; + let word = self.chiplets.memory.read_word(ctx, addr, self.system.clk())?; Ok([QuadFelt::new(word[0], word[1]), QuadFelt::new(word[2], word[3])]) } @@ -204,7 +204,7 @@ mod tests { let tztgz = rand_array::(); process .chiplets - .memory_mut() + .memory .write_word( ctx, inputs[2].as_int().try_into().expect("Shouldn't fail by construction"), @@ -216,7 +216,7 @@ mod tests { let a = rand_array::(); process .chiplets - .memory_mut() + .memory .write_word( ctx, inputs[1].as_int().try_into().expect("Shouldn't fail by construction"), diff --git a/processor/src/operations/crypto_ops.rs b/processor/src/operations/crypto_ops.rs index 4850cd310..a5f3fe691 100644 --- a/processor/src/operations/crypto_ops.rs +++ b/processor/src/operations/crypto_ops.rs @@ -29,7 +29,7 @@ impl Process { self.stack.get(0), ]; - let (addr, output_state) = self.chiplets.permute(input_state); + let (addr, output_state) = self.chiplets.hasher.permute(input_state); self.decoder.set_user_op_helpers(Operation::HPerm, &[addr]); for (i, &value) in output_state.iter().rev().enumerate() { self.stack.set(i, value); @@ -79,7 +79,7 @@ impl Process { let path = host.advice_provider_mut().get_merkle_path(root, &depth, &index)?; // use hasher to compute the Merkle root of the path - let (addr, computed_root) = self.chiplets.build_merkle_root(node, &path, index); + let (addr, computed_root) = self.chiplets.hasher.build_merkle_root(node, &path, index); // save address(r) of the hasher trace from when the computation starts in the decoder // helper registers. @@ -153,7 +153,8 @@ impl Process { assert_eq!(path.len(), depth.as_int() as usize); - let merkle_tree_update = self.chiplets.update_merkle_root(old_node, new_node, &path, index); + let merkle_tree_update = + self.chiplets.hasher.update_merkle_root(old_node, new_node, &path, index); // Asserts the computed old root of the Merkle path from the advice provider is consistent // with the input root provided via the stack. This will panic only if the advice provider diff --git a/processor/src/operations/io_ops.rs b/processor/src/operations/io_ops.rs index 53cfc6e86..5afcc516d 100644 --- a/processor/src/operations/io_ops.rs +++ b/processor/src/operations/io_ops.rs @@ -37,7 +37,7 @@ impl Process { /// - Returns an error if the address is not aligned to a word boundary. pub(super) fn op_mloadw(&mut self) -> Result<(), ExecutionError> { // get the address from the stack and read the word from current memory context - let mut word = self.chiplets.memory_mut().read_word( + let mut word = self.chiplets.memory.read_word( self.system.ctx(), self.stack.get(0), self.system.clk(), @@ -62,11 +62,10 @@ impl Process { /// ZERO element is returned. /// - The element retrieved from memory is pushed to the top of the stack. pub(super) fn op_mload(&mut self) -> Result<(), ExecutionError> { - let element = self.chiplets.memory_mut().read( - self.system.ctx(), - self.stack.get(0), - self.system.clk(), - )?; + let element = + self.chiplets + .memory + .read(self.system.ctx(), self.stack.get(0), self.system.clk())?; self.stack.set(0, element); self.stack.copy_state(1); @@ -92,9 +91,9 @@ impl Process { // build the word in memory order (reverse of stack order) let word = [self.stack.get(4), self.stack.get(3), self.stack.get(2), self.stack.get(1)]; - // write the word to memory + // write the word to memory and get the previous word self.chiplets - .memory_mut() + .memory .write_word(self.system.ctx(), addr, self.system.clk(), word)?; // reverse the order of the memory word & update the stack state @@ -121,7 +120,7 @@ impl Process { let value = self.stack.get(1); // write the value to the memory and get the previous word - self.chiplets.memory_mut().write(ctx, addr, self.system.clk(), value)?; + self.chiplets.memory.write(ctx, addr, self.system.clk(), value)?; // update the stack state self.stack.shift_left(1); @@ -152,8 +151,8 @@ impl Process { // load two words from memory let words = [ - self.chiplets.memory_mut().read_word(ctx, addr_first_word, clk)?, - self.chiplets.memory_mut().read_word(ctx, addr_second_word, clk)?, + self.chiplets.memory.read_word(ctx, addr_first_word, clk)?, + self.chiplets.memory.read_word(ctx, addr_second_word, clk)?, ]; // replace the stack elements with the elements from memory (in stack order) @@ -203,8 +202,8 @@ impl Process { let words = host.advice_provider_mut().pop_stack_dword(self.into())?; // write the words memory - self.chiplets.memory_mut().write_word(ctx, addr_first_word, clk, words[0])?; - self.chiplets.memory_mut().write_word(ctx, addr_second_word, clk, words[1])?; + self.chiplets.memory.write_word(ctx, addr_first_word, clk, words[0])?; + self.chiplets.memory.write_word(ctx, addr_second_word, clk, words[1])?; // replace the elements on the stack with the word elements (in stack order) for (i, &adv_value) in words.iter().flat_map(|word| word.iter()).rev().enumerate() { @@ -308,7 +307,7 @@ mod tests { fn op_mloadw() { let mut host = DefaultHost::default(); let mut process = Process::new_dummy_with_decoder_helpers_and_empty_stack(); - assert_eq!(0, process.chiplets.memory().num_accessed_words()); + assert_eq!(0, process.chiplets.memory.num_accessed_words()); // push a word onto the stack and save it at address 4 let word = [1, 3, 5, 7].to_elements().try_into().unwrap(); @@ -327,11 +326,8 @@ mod tests { assert_eq!(expected_stack, process.stack.trace_state()); // check memory state - assert_eq!(1, process.chiplets.memory().num_accessed_words()); - assert_eq!( - word, - process.chiplets.memory().get_word(ContextId::root(), 4).unwrap().unwrap() - ); + assert_eq!(1, process.chiplets.memory.num_accessed_words()); + assert_eq!(word, process.chiplets.memory.get_word(ContextId::root(), 4).unwrap().unwrap()); // --- calling MLOADW with address greater than u32::MAX leads to an error ---------------- process.execute_op(Operation::Push(Felt::new(u64::MAX / 2)), &mut host).unwrap(); @@ -346,7 +342,7 @@ mod tests { fn op_mload() { let mut host = DefaultHost::default(); let mut process = Process::new_dummy_with_decoder_helpers_and_empty_stack(); - assert_eq!(0, process.chiplets.memory().num_accessed_words()); + assert_eq!(0, process.chiplets.memory.num_accessed_words()); // push a word onto the stack and save it at address 4 let word = [1, 3, 5, 7].to_elements().try_into().unwrap(); @@ -360,11 +356,8 @@ mod tests { assert_eq!(expected_stack, process.stack.trace_state()); // check memory state - assert_eq!(1, process.chiplets.memory().num_accessed_words()); - assert_eq!( - word, - process.chiplets.memory().get_word(ContextId::root(), 4).unwrap().unwrap() - ); + assert_eq!(1, process.chiplets.memory.num_accessed_words()); + assert_eq!(word, process.chiplets.memory.get_word(ContextId::root(), 4).unwrap().unwrap()); // --- calling MLOAD with address greater than u32::MAX leads to an error ----------------- process.execute_op(Operation::Push(Felt::new(u64::MAX / 2)), &mut host).unwrap(); @@ -389,14 +382,14 @@ mod tests { store_value(&mut process, 8, word2_felts, &mut host); // check memory state - assert_eq!(2, process.chiplets.memory().num_accessed_words()); + assert_eq!(2, process.chiplets.memory.num_accessed_words()); assert_eq!( word1_felts, - process.chiplets.memory().get_word(ContextId::root(), 4).unwrap().unwrap() + process.chiplets.memory.get_word(ContextId::root(), 4).unwrap().unwrap() ); assert_eq!( word2_felts, - process.chiplets.memory().get_word(ContextId::root(), 8).unwrap().unwrap() + process.chiplets.memory.get_word(ContextId::root(), 8).unwrap().unwrap() ); // clear the stack @@ -444,7 +437,7 @@ mod tests { fn op_mstorew() { let mut host = DefaultHost::default(); let mut process = Process::new_dummy_with_decoder_helpers_and_empty_stack(); - assert_eq!(0, process.chiplets.memory().num_accessed_words()); + assert_eq!(0, process.chiplets.memory.num_accessed_words()); // push the first word onto the stack and save it at address 0 let word1 = [1, 3, 5, 7].to_elements().try_into().unwrap(); @@ -455,11 +448,8 @@ mod tests { assert_eq!(expected_stack, process.stack.trace_state()); // check memory state - assert_eq!(1, process.chiplets.memory().num_accessed_words()); - assert_eq!( - word1, - process.chiplets.memory().get_word(ContextId::root(), 0).unwrap().unwrap() - ); + assert_eq!(1, process.chiplets.memory.num_accessed_words()); + assert_eq!(word1, process.chiplets.memory.get_word(ContextId::root(), 0).unwrap().unwrap()); // push the second word onto the stack and save it at address 4 let word2 = [2, 4, 6, 8].to_elements().try_into().unwrap(); @@ -470,15 +460,9 @@ mod tests { assert_eq!(expected_stack, process.stack.trace_state()); // check memory state - assert_eq!(2, process.chiplets.memory().num_accessed_words()); - assert_eq!( - word1, - process.chiplets.memory().get_word(ContextId::root(), 0).unwrap().unwrap() - ); - assert_eq!( - word2, - process.chiplets.memory().get_word(ContextId::root(), 4).unwrap().unwrap() - ); + assert_eq!(2, process.chiplets.memory.num_accessed_words()); + assert_eq!(word1, process.chiplets.memory.get_word(ContextId::root(), 0).unwrap().unwrap()); + assert_eq!(word2, process.chiplets.memory.get_word(ContextId::root(), 4).unwrap().unwrap()); // --- calling MSTOREW with address greater than u32::MAX leads to an error ---------------- process.execute_op(Operation::Push(Felt::new(u64::MAX / 2)), &mut host).unwrap(); @@ -493,7 +477,7 @@ mod tests { fn op_mstore() { let mut host = DefaultHost::default(); let mut process = Process::new_dummy_with_decoder_helpers_and_empty_stack(); - assert_eq!(0, process.chiplets.memory().num_accessed_words()); + assert_eq!(0, process.chiplets.memory.num_accessed_words()); // push new element onto the stack and save it as first element of the word on // uninitialized memory at address 0 @@ -506,11 +490,8 @@ mod tests { // check memory state let mem_0 = [element, ZERO, ZERO, ZERO]; - assert_eq!(1, process.chiplets.memory().num_accessed_words()); - assert_eq!( - mem_0, - process.chiplets.memory().get_word(ContextId::root(), 0).unwrap().unwrap() - ); + assert_eq!(1, process.chiplets.memory.num_accessed_words()); + assert_eq!(mem_0, process.chiplets.memory.get_word(ContextId::root(), 0).unwrap().unwrap()); // push the word onto the stack and save it at address 4 let word_2 = [1, 3, 5, 7].to_elements().try_into().unwrap(); @@ -526,11 +507,8 @@ mod tests { // check memory state to make sure the other 3 elements were not affected let mem_2 = [element, Felt::new(3), Felt::new(5), Felt::new(7)]; - assert_eq!(2, process.chiplets.memory().num_accessed_words()); - assert_eq!( - mem_2, - process.chiplets.memory().get_word(ContextId::root(), 4).unwrap().unwrap() - ); + assert_eq!(2, process.chiplets.memory.num_accessed_words()); + assert_eq!(mem_2, process.chiplets.memory.get_word(ContextId::root(), 4).unwrap().unwrap()); // --- calling MSTORE with address greater than u32::MAX leads to an error ---------------- process.execute_op(Operation::Push(Felt::new(u64::MAX / 2)), &mut host).unwrap(); @@ -572,14 +550,14 @@ mod tests { process.execute_op(Operation::Pipe, &mut host).unwrap(); // check memory state contains the words from the advice stack - assert_eq!(2, process.chiplets.memory().num_accessed_words()); + assert_eq!(2, process.chiplets.memory.num_accessed_words()); assert_eq!( word1_felts, - process.chiplets.memory().get_word(ContextId::root(), 4).unwrap().unwrap() + process.chiplets.memory.get_word(ContextId::root(), 4).unwrap().unwrap() ); assert_eq!( word2_felts, - process.chiplets.memory().get_word(ContextId::root(), 8).unwrap().unwrap() + process.chiplets.memory.get_word(ContextId::root(), 8).unwrap().unwrap() ); // the first 8 values should be the values from the advice stack. the next 4 values should @@ -639,7 +617,7 @@ mod tests { #[test] fn read_and_write_in_same_clock_cycle() { let mut process = Process::new_dummy_with_decoder_helpers_and_empty_stack(); - assert_eq!(0, process.chiplets.memory().num_accessed_words()); + assert_eq!(0, process.chiplets.memory.num_accessed_words()); // emulate reading and writing in the same clock cycle process.ensure_trace_capacity(); @@ -654,7 +632,7 @@ mod tests { #[test] fn write_twice_in_same_clock_cycle() { let mut process = Process::new_dummy_with_decoder_helpers_and_empty_stack(); - assert_eq!(0, process.chiplets.memory().num_accessed_words()); + assert_eq!(0, process.chiplets.memory.num_accessed_words()); // emulate reading and writing in the same clock cycle process.ensure_trace_capacity(); @@ -669,7 +647,7 @@ mod tests { #[test] fn read_twice_in_same_clock_cycle() { let mut process = Process::new_dummy_with_decoder_helpers_and_empty_stack(); - assert_eq!(0, process.chiplets.memory().num_accessed_words()); + assert_eq!(0, process.chiplets.memory.num_accessed_words()); // emulate reading in the same clock cycle process.ensure_trace_capacity(); diff --git a/processor/src/operations/mod.rs b/processor/src/operations/mod.rs index cf97cb596..7a147c3e5 100644 --- a/processor/src/operations/mod.rs +++ b/processor/src/operations/mod.rs @@ -165,7 +165,6 @@ impl Process { pub(super) fn advance_clock(&mut self) -> Result<(), ExecutionError> { self.system.advance_clock(self.max_cycles)?; self.stack.advance_clock(); - self.chiplets.advance_clock(); Ok(()) } diff --git a/processor/src/operations/u32_ops.rs b/processor/src/operations/u32_ops.rs index a7dd1b70f..79a4355ea 100644 --- a/processor/src/operations/u32_ops.rs +++ b/processor/src/operations/u32_ops.rs @@ -178,7 +178,7 @@ impl Process { pub(super) fn op_u32and(&mut self) -> Result<(), ExecutionError> { let b = require_u32_operand!(self.stack, 0); let a = require_u32_operand!(self.stack, 1); - let result = self.chiplets.u32and(a, b)?; + let result = self.chiplets.bitwise.u32and(a, b)?; self.stack.set(0, result); self.stack.shift_left(2); @@ -191,7 +191,7 @@ impl Process { pub(super) fn op_u32xor(&mut self) -> Result<(), ExecutionError> { let b = require_u32_operand!(self.stack, 0); let a = require_u32_operand!(self.stack, 1); - let result = self.chiplets.u32xor(a, b)?; + let result = self.chiplets.bitwise.u32xor(a, b)?; self.stack.set(0, result); self.stack.shift_left(2); diff --git a/stdlib/tests/mem/mod.rs b/stdlib/tests/mem/mod.rs index 9d3fbbb90..ea5475f73 100644 --- a/stdlib/tests/mem/mod.rs +++ b/stdlib/tests/mem/mod.rs @@ -38,53 +38,53 @@ fn test_memcopy_words() { process.execute(&program, &mut host).unwrap(); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 1000).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 1000).unwrap(), Some([ZERO, ZERO, ZERO, ONE]), "Address 1000" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 1004).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 1004).unwrap(), Some([ZERO, ZERO, ONE, ZERO]), "Address 1004" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 1008).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 1008).unwrap(), Some([ZERO, ZERO, ONE, ONE]), "Address 1008" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 1012).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 1012).unwrap(), Some([ZERO, ONE, ZERO, ZERO]), "Address 1012" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 1016).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 1016).unwrap(), Some([ZERO, ONE, ZERO, ONE]), "Address 1016" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 2000).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 2000).unwrap(), Some([ZERO, ZERO, ZERO, ONE]), "Address 2000" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 2004).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 2004).unwrap(), Some([ZERO, ZERO, ONE, ZERO]), "Address 2004" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 2008).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 2008).unwrap(), Some([ZERO, ZERO, ONE, ONE]), "Address 2008" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 2012).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 2012).unwrap(), Some([ZERO, ONE, ZERO, ZERO]), "Address 2012" ); assert_eq!( - process.chiplets.memory().get_word(ContextId::root(), 2016).unwrap(), + process.chiplets.memory.get_word(ContextId::root(), 2016).unwrap(), Some([ZERO, ONE, ZERO, ONE]), "Address 2016" ); diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index d232e7b0c..f5fd3ba85 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -249,7 +249,7 @@ impl Test { { let mem_state = process .chiplets - .memory() + .memory .get_value(ContextId::root(), addr as u32) .unwrap_or(ZERO); assert_eq!(