From f23899a4d2b1c3986bda681c2931ad568cbeac26 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Wed, 10 Apr 2024 12:03:29 -0700 Subject: [PATCH 01/13] Add StoreU8. --- assembler/src/lib.rs | 3 ++ basic/src/lib.rs | 11 ++++++-- cpu/src/columns.rs | 3 ++ cpu/src/lib.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++ machine/src/core.rs | 18 ++++++++++++ memory/src/lib.rs | 12 ++++++++ opcodes/src/lib.rs | 7 +++++ 7 files changed, 118 insertions(+), 2 deletions(-) diff --git a/assembler/src/lib.rs b/assembler/src/lib.rs index f24e48f5..5d0c1e96 100644 --- a/assembler/src/lib.rs +++ b/assembler/src/lib.rs @@ -58,7 +58,10 @@ pub fn assemble(input: &str) -> Result, String> { let opcode = match mnemonic { // Core CPU "lw" => LOAD32, + "loadu8" => LOADU8, + "loads8" => LOADS8, "sw" => STORE32, + "storeu8" => STOREU8, "jal" => JAL, "jalv" => JALV, "beq" | "beqi" => BEQ, diff --git a/basic/src/lib.rs b/basic/src/lib.rs index 55fea076..2361c178 100644 --- a/basic/src/lib.rs +++ b/basic/src/lib.rs @@ -37,8 +37,8 @@ use valida_bus::{ }; use valida_cpu::{ BeqInstruction, BneInstruction, Imm32Instruction, JalInstruction, JalvInstruction, - Load32Instruction, LoadFpInstruction, ReadAdviceInstruction, StopInstruction, - Store32Instruction, + Load32Instruction, LoadU8Instruction, LoadS8Instruction, LoadFpInstruction, ReadAdviceInstruction, StopInstruction, + Store32Instruction, StoreU8Instruction }; use valida_cpu::{CpuChip, MachineWithCpuChip}; use valida_machine::__internal::p3_challenger::{CanObserve, FieldChallenger}; @@ -64,6 +64,13 @@ pub struct BasicMachine { // Core instructions load32: Load32Instruction, store32: Store32Instruction, + + loadu8: LoadU8Instruction, + + loads8: LoadS8Instruction, + + storeu8: StoreU8Instruction, + jal: JalInstruction, jalv: JalvInstruction, beq: BeqInstruction, diff --git a/cpu/src/columns.rs b/cpu/src/columns.rs index b19bb1f2..589cb999 100644 --- a/cpu/src/columns.rs +++ b/cpu/src/columns.rs @@ -48,7 +48,10 @@ pub struct OpcodeFlagCols { pub is_bus_op_with_mem: T, pub is_imm_op: T, pub is_load: T, + pub is_load_u8: T, + pub is_load_s8: T, pub is_store: T, + pub is_store_u8: T, pub is_beq: T, pub is_bne: T, pub is_jal: T, diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 2273f2cf..63fd0f96 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -16,6 +16,7 @@ use valida_machine::{ use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation}; use valida_opcodes::{ BEQ, BNE, BYTES_PER_INSTR, IMM32, JAL, JALV, LOAD32, LOADFP, READ_ADVICE, STOP, STORE32, + LOADU8, LOADS8, STOREU8 }; use p3_air::VirtualPairCol; @@ -31,7 +32,10 @@ pub mod stark; #[derive(Clone)] pub enum Operation { Store32, + StoreU8, Load32, + LoadU8, + LoadS8, Jal, Jalv, Beq(Option> /*imm*/), @@ -175,6 +179,15 @@ impl CpuChip { Operation::Load32 => { cols.opcode_flags.is_load = SC::Val::one(); } + Operation::StoreU8 => { + cols.opcode_flags.is_store_u8 = SC::Val::one(); + } + Operation::LoadU8 => { + cols.opcode_flags.is_load_u8 = SC::Val::one(); + } + Operation::LoadS8 => { + cols.opcode_flags.is_load_s8 = SC::Val::one(); + } Operation::Jal => { cols.opcode_flags.is_jal = SC::Val::one(); } @@ -349,7 +362,10 @@ pub trait MachineWithCpuChip: MachineWithMemoryChip { instructions!( Load32Instruction, + LoadU8Instruction, + LoadS8Instruction, Store32Instruction, + StoreU8Instruction, JalInstruction, JalvInstruction, BeqInstruction, @@ -466,6 +482,56 @@ where } } +fn index_of_word(addr: u32) -> usize { + return ((addr & !3) - 1) as usize; +} + +impl Instruction for StoreU8Instruction +where + M: MachineWithCpuChip, + F: Field, +{ + const OPCODE: u32 = STOREU8; + + fn execute(state: &mut M, ops: Operands) { + let opcode = >::OPCODE; + let clk = state.cpu().clock; + let read_addr = (state.cpu().fp as i32 + ops.c()) as u32; + let write_addr_loc = (state.cpu().fp as i32 + ops.b()) as u32; + let pc = state.cpu().pc; + let write_addr = state + .mem_mut() + .read(clk, write_addr_loc.into(), true, pc, opcode, 0, ""); + + // Read the cell from the read address. + let cell = state + .mem_mut() + .read(clk, read_addr, true, pc, opcode, 1, ""); + + // index of the word for the byte to read from + let index_of_read = index_of_word(read_addr); + + // The byte read from the read address. + let cell_read = cell.0; + let cell_byte = cell_read[index_of_read]; + + // Index of the word for the byte to write to + let index_of_write = index_of_word(write_addr.into()); + + // The original content of the cell to write to. + let cell_write = state + .mem_mut() + .read(clk, write_addr.into(), true, pc, opcode, 1, ""); + + // The Word to write, with one byte overwritten to the read byte + let cell_to_write = cell_write.update_byte(cell_byte, index_of_write); + + state.mem_mut().write(clk, write_addr.into(), cell_to_write, true); + state.cpu_mut().pc += 1; + state.cpu_mut().push_op(Operation::StoreU8, opcode, ops); + } +} + impl Instruction for JalInstruction where M: MachineWithCpuChip, diff --git a/machine/src/core.rs b/machine/src/core.rs index e37aabbb..375cc971 100644 --- a/machine/src/core.rs +++ b/machine/src/core.rs @@ -15,6 +15,15 @@ impl Word { } } +impl Word { + pub fn update_byte(self, byte: u8, loc: usize) -> Self { + let mut result: [u8; MEMORY_CELL_BYTES] = self.0; + result[loc] = byte; + Self(result) + } +} + + impl Word { pub fn transform(self, mut f: G) -> Word where @@ -39,6 +48,15 @@ impl Word { } } +impl Word { + pub fn to_u8(self) -> u8 { + let result = self.0; + let byte = result[MEMORY_CELL_BYTES - 1]; + byte + } +} + + impl Into for Word { fn into(self) -> u32 { let mut result = 0u32; diff --git a/memory/src/lib.rs b/memory/src/lib.rs index 0c9725a2..452daebf 100644 --- a/memory/src/lib.rs +++ b/memory/src/lib.rs @@ -110,6 +110,18 @@ impl MemoryChip { self.cells.insert(address, value.into()); } + /// Write a byte value to the least significant byte, and write zeros to the other 3 bytes. + pub fn write_u8(&mut self, clk: u32, address: u32, value: u8, log: bool) { + let value_word = Word::from_u8(value); + if log { + self.operations + .entry(clk) + .or_insert_with(Vec::new) + .push(Operation::Write(address, value_word)); + } + self.cells.insert(address, value_word); + } + pub fn write_static(&mut self, address: u32, value: Word) { self.cells.insert(address, value.clone()); self.static_data.insert(address, value); diff --git a/opcodes/src/lib.rs b/opcodes/src/lib.rs index 161be3f2..5ffd9104 100644 --- a/opcodes/src/lib.rs +++ b/opcodes/src/lib.rs @@ -15,6 +15,10 @@ pub enum Opcode { STOP = 8, READ_ADVICE = 9, LOADFP = 10, + LOADU8 = 11, + LOADS8 = 12, + STOREU8 = 13, + ADD32 = 100, SUB32 = 101, MUL32 = 102, @@ -56,6 +60,9 @@ declare_opcode!(BNE); declare_opcode!(IMM32); declare_opcode!(STOP); declare_opcode!(LOADFP); +declare_opcode!(LOADU8); +declare_opcode!(LOADS8); +declare_opcode!(STOREU8); /// NONDETERMINISTIC declare_opcode!(READ_ADVICE); From 491a669005aeee44d2bc5062c262e3175ba38fe9 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Fri, 12 Apr 2024 11:50:10 -0700 Subject: [PATCH 02/13] Remove write_u8. --- memory/src/lib.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/memory/src/lib.rs b/memory/src/lib.rs index 452daebf..0c9725a2 100644 --- a/memory/src/lib.rs +++ b/memory/src/lib.rs @@ -110,18 +110,6 @@ impl MemoryChip { self.cells.insert(address, value.into()); } - /// Write a byte value to the least significant byte, and write zeros to the other 3 bytes. - pub fn write_u8(&mut self, clk: u32, address: u32, value: u8, log: bool) { - let value_word = Word::from_u8(value); - if log { - self.operations - .entry(clk) - .or_insert_with(Vec::new) - .push(Operation::Write(address, value_word)); - } - self.cells.insert(address, value_word); - } - pub fn write_static(&mut self, address: u32, value: Word) { self.cells.insert(address, value.clone()); self.static_data.insert(address, value); From 4211a3fba479814ff1fd9be18a869ffc97239a79 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Mon, 15 Apr 2024 12:42:34 -0700 Subject: [PATCH 03/13] Remove to_u8. --- basic/src/lib.rs | 4 ++-- cpu/src/lib.rs | 14 ++++++++------ machine/src/core.rs | 10 ---------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/basic/src/lib.rs b/basic/src/lib.rs index 2361c178..db98bdc4 100644 --- a/basic/src/lib.rs +++ b/basic/src/lib.rs @@ -37,8 +37,8 @@ use valida_bus::{ }; use valida_cpu::{ BeqInstruction, BneInstruction, Imm32Instruction, JalInstruction, JalvInstruction, - Load32Instruction, LoadU8Instruction, LoadS8Instruction, LoadFpInstruction, ReadAdviceInstruction, StopInstruction, - Store32Instruction, StoreU8Instruction + Load32Instruction, LoadFpInstruction, LoadS8Instruction, LoadU8Instruction, + ReadAdviceInstruction, StopInstruction, Store32Instruction, StoreU8Instruction, }; use valida_cpu::{CpuChip, MachineWithCpuChip}; use valida_machine::__internal::p3_challenger::{CanObserve, FieldChallenger}; diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 63fd0f96..b575e90f 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -15,8 +15,8 @@ use valida_machine::{ }; use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation}; use valida_opcodes::{ - BEQ, BNE, BYTES_PER_INSTR, IMM32, JAL, JALV, LOAD32, LOADFP, READ_ADVICE, STOP, STORE32, - LOADU8, LOADS8, STOREU8 + BEQ, BNE, BYTES_PER_INSTR, IMM32, JAL, JALV, LOAD32, LOADFP, LOADS8, LOADU8, READ_ADVICE, STOP, + STORE32, STOREU8, }; use p3_air::VirtualPairCol; @@ -520,13 +520,15 @@ where // The original content of the cell to write to. let cell_write = state - .mem_mut() - .read(clk, write_addr.into(), true, pc, opcode, 1, ""); + .mem_mut() + .read(clk, write_addr.into(), true, pc, opcode, 1, ""); // The Word to write, with one byte overwritten to the read byte let cell_to_write = cell_write.update_byte(cell_byte, index_of_write); - - state.mem_mut().write(clk, write_addr.into(), cell_to_write, true); + + state + .mem_mut() + .write(clk, write_addr.into(), cell_to_write, true); state.cpu_mut().pc += 1; state.cpu_mut().push_op(Operation::StoreU8, opcode, ops); } diff --git a/machine/src/core.rs b/machine/src/core.rs index 375cc971..2c907a4c 100644 --- a/machine/src/core.rs +++ b/machine/src/core.rs @@ -23,7 +23,6 @@ impl Word { } } - impl Word { pub fn transform(self, mut f: G) -> Word where @@ -48,15 +47,6 @@ impl Word { } } -impl Word { - pub fn to_u8(self) -> u8 { - let result = self.0; - let byte = result[MEMORY_CELL_BYTES - 1]; - byte - } -} - - impl Into for Word { fn into(self) -> u32 { let mut result = 0u32; From 99f122c58e49a9b4240d956e8adc754b53eb3c10 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Tue, 16 Apr 2024 11:48:55 -0700 Subject: [PATCH 04/13] Add read_or_init to fix read before write error. Tidy up. --- basic/src/lib.rs | 14 +++++-- cpu/src/lib.rs | 96 +++++++++++++++++++++++++++++++++++++++++++---- memory/src/lib.rs | 19 ++++++++++ 3 files changed, 118 insertions(+), 11 deletions(-) diff --git a/basic/src/lib.rs b/basic/src/lib.rs index db98bdc4..67fe80f4 100644 --- a/basic/src/lib.rs +++ b/basic/src/lib.rs @@ -63,12 +63,9 @@ use valida_machine::StarkConfig; pub struct BasicMachine { // Core instructions load32: Load32Instruction, - store32: Store32Instruction, - loadu8: LoadU8Instruction, - loads8: LoadS8Instruction, - + store32: Store32Instruction, storeu8: StoreU8Instruction, jal: JalInstruction, @@ -1078,9 +1075,18 @@ impl Machine for BasicMachine { >::OPCODE => { Load32Instruction::execute_with_advice::(self, ops, advice) } + >::OPCODE => { + LoadU8Instruction::execute_with_advice::(self, ops, advice) + } + >::OPCODE => { + LoadS8Instruction::execute_with_advice::(self, ops, advice) + } >::OPCODE => { Store32Instruction::execute_with_advice::(self, ops, advice) } + >::OPCODE => { + StoreU8Instruction::execute_with_advice::(self, ops, advice) + } >::OPCODE => { JalInstruction::execute_with_advice::(self, ops, advice) } diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index b575e90f..e9c0a735 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -457,6 +457,80 @@ where } } +impl Instruction for LoadU8Instruction +where + M: MachineWithCpuChip, + F: Field, +{ + const OPCODE: u32 = LOADU8; + + fn execute(state: &mut M, ops: Operands) { + let opcode = >::OPCODE; + let clk = state.cpu().clock; + let pc = state.cpu().pc; + let fp = state.cpu().fp; + let read_addr_1 = (fp as i32 + ops.c()) as u32; + let read_addr_2 = state + .mem_mut() + .read(clk, read_addr_1, true, pc, opcode, 0, ""); + let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; + let cell = state.mem_mut().read( + clk, + read_addr_2.into(), + true, + pc, + opcode, + 1, + &format!( + "fp = {}, c = {}, [fp+c] = {:?}", + fp as i32, + ops.c() as u32, + read_addr_2 + ), + ); + state.mem_mut().write(clk, write_addr, cell, true); + state.cpu_mut().pc += 1; + state.cpu_mut().push_op(Operation::Load32, opcode, ops); + } +} + +impl Instruction for LoadS8Instruction +where + M: MachineWithCpuChip, + F: Field, +{ + const OPCODE: u32 = LOADS8; + + fn execute(state: &mut M, ops: Operands) { + let opcode = >::OPCODE; + let clk = state.cpu().clock; + let pc = state.cpu().pc; + let fp = state.cpu().fp; + let read_addr_1 = (fp as i32 + ops.c()) as u32; + let read_addr_2 = state + .mem_mut() + .read(clk, read_addr_1, true, pc, opcode, 0, ""); + let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; + let cell = state.mem_mut().read( + clk, + read_addr_2.into(), + true, + pc, + opcode, + 1, + &format!( + "fp = {}, c = {}, [fp+c] = {:?}", + fp as i32, + ops.c() as u32, + read_addr_2 + ), + ); + state.mem_mut().write(clk, write_addr, cell, true); + state.cpu_mut().pc += 1; + state.cpu_mut().push_op(Operation::Load32, opcode, ops); + } +} + impl Instruction for Store32Instruction where M: MachineWithCpuChip, @@ -482,8 +556,14 @@ where } } +/// Get the index of a byte in a memory cell. fn index_of_word(addr: u32) -> usize { - return ((addr & !3) - 1) as usize; + (addr&3) as usize +} + +/// Get the key to the BTree map of the memory cells. +fn index_to_word(addr: u32) -> u32 { + (addr&!3) as u32 } impl Instruction for StoreU8Instruction @@ -497,6 +577,9 @@ where let opcode = >::OPCODE; let clk = state.cpu().clock; let read_addr = (state.cpu().fp as i32 + ops.c()) as u32; + + // Make sure we get to a non empty map by making it a multiple of 4. + let read_addr_index = index_to_word(read_addr); let write_addr_loc = (state.cpu().fp as i32 + ops.b()) as u32; let pc = state.cpu().pc; let write_addr = state @@ -506,22 +589,21 @@ where // Read the cell from the read address. let cell = state .mem_mut() - .read(clk, read_addr, true, pc, opcode, 1, ""); + .read(clk, read_addr_index, true, pc, opcode, 1, ""); // index of the word for the byte to read from let index_of_read = index_of_word(read_addr); - // The byte read from the read address. + // The word read from the read address. let cell_read = cell.0; + // The byte read from the read address. let cell_byte = cell_read[index_of_read]; // Index of the word for the byte to write to let index_of_write = index_of_word(write_addr.into()); - // The original content of the cell to write to. - let cell_write = state - .mem_mut() - .read(clk, write_addr.into(), true, pc, opcode, 1, ""); + // The original content of the cell to write to. If the cell was empty, initiate it with a default value. + let cell_write = state.mem_mut().read_or_init(clk, write_addr.into(), true); // The Word to write, with one byte overwritten to the read byte let cell_to_write = cell_write.update_byte(cell_byte, index_of_write); diff --git a/memory/src/lib.rs b/memory/src/lib.rs index 0c9725a2..1bb80eac 100644 --- a/memory/src/lib.rs +++ b/memory/src/lib.rs @@ -2,6 +2,8 @@ extern crate alloc; +use valida_machine::MEMORY_CELL_BYTES; + use crate::alloc::string::ToString; use crate::columns::{MemoryCols, MEM_COL_MAP, NUM_MEM_COLS}; use alloc::collections::BTreeMap; @@ -79,6 +81,7 @@ impl MemoryChip { } } + /// Read from a cell. If the cell is empty, panic. pub fn read( &mut self, clk: u32, @@ -100,6 +103,22 @@ impl MemoryChip { value } + /// Read from a cell. If the cell is empty, initialize it with the default values. + pub fn read_or_init(&mut self, clk: u32, address: u32, log: bool) -> Word { + let value = self + .cells + .get(&address.into()) + .copied() + .unwrap_or_else(|| Word([0; MEMORY_CELL_BYTES])); + if log { + self.operations + .entry(clk) + .or_insert_with(Vec::new) + .push(Operation::Read(address.into(), value)); + } + value + } + pub fn write(&mut self, clk: u32, address: u32, value: Word, log: bool) { if log { self.operations From 19ef83fdbb72fb3163e1f7c390c366dcdf35c065 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Tue, 16 Apr 2024 11:49:17 -0700 Subject: [PATCH 05/13] Add more frame stack to REPL. --- basic/src/bin/valida.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basic/src/bin/valida.rs b/basic/src/bin/valida.rs index 71aa70e4..c59b45e1 100644 --- a/basic/src/bin/valida.rs +++ b/basic/src/bin/valida.rs @@ -166,7 +166,7 @@ fn last_frame(_: ArgMatches, context: &mut Context) -> Result> { frame += &format!("Current FP: 0x{:x}\n", fp).as_str(); // print last frame - for i in (-5..(last_size / 4) + 1).rev() { + for i in (-10..(last_size / 4) + 1).rev() { let offset = (i * 4) as i32; let read_addr = (fp + offset) as u32; let string_val = context.machine_.mem().examine(read_addr); From a45cecd12b61cc8e6570221efc3d9373109f2672 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Wed, 17 Apr 2024 09:04:10 -0700 Subject: [PATCH 06/13] Make sure write to address is correct. --- cpu/src/lib.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index e9c0a735..1edcba1c 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -561,7 +561,7 @@ fn index_of_word(addr: u32) -> usize { (addr&3) as usize } -/// Get the key to the BTree map of the memory cells. +/// Get the key to the map of the memory cells which is not empty. fn index_to_word(addr: u32) -> u32 { (addr&!3) as u32 } @@ -578,7 +578,7 @@ where let clk = state.cpu().clock; let read_addr = (state.cpu().fp as i32 + ops.c()) as u32; - // Make sure we get to a non empty map by making it a multiple of 4. + // Make sure we get to the correct and non empty map by making it a multiple of 4. let read_addr_index = index_to_word(read_addr); let write_addr_loc = (state.cpu().fp as i32 + ops.b()) as u32; let pc = state.cpu().pc; @@ -591,7 +591,7 @@ where .mem_mut() .read(clk, read_addr_index, true, pc, opcode, 1, ""); - // index of the word for the byte to read from + // The array index of the word for the byte to read from let index_of_read = index_of_word(read_addr); // The word read from the read address. @@ -599,11 +599,14 @@ where // The byte read from the read address. let cell_byte = cell_read[index_of_read]; - // Index of the word for the byte to write to + // The array index of the word for the byte to write to let index_of_write = index_of_word(write_addr.into()); + // The key to the memory map, converted to a multiple of 4. + let write_addr_index = index_to_word(write_addr.into()); + // The original content of the cell to write to. If the cell was empty, initiate it with a default value. - let cell_write = state.mem_mut().read_or_init(clk, write_addr.into(), true); + let cell_write = state.mem_mut().read_or_init(clk, write_addr_index, true); // The Word to write, with one byte overwritten to the read byte let cell_to_write = cell_write.update_byte(cell_byte, index_of_write); From 02ca1617b03da4567d0e10c425a08da80c87397d Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Wed, 17 Apr 2024 11:58:26 -0700 Subject: [PATCH 07/13] Add sign extended and zero extended load. --- cpu/src/lib.rs | 93 +++++++++++++++++++++++++++++---------------- machine/src/core.rs | 29 ++++++++++++++ 2 files changed, 90 insertions(+), 32 deletions(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 1edcba1c..47583866 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -11,8 +11,7 @@ use core::marker::Sync; use core::mem::transmute; use valida_bus::{MachineWithGeneralBus, MachineWithMemBus, MachineWithProgramBus}; use valida_machine::{ - instructions, AdviceProvider, Chip, Instruction, InstructionWord, Interaction, Operands, Word, -}; + instructions, AdviceProvider, Chip, Instruction, InstructionWord, Interaction, Operands, Word, index_of_word, index_to_word}; use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation}; use valida_opcodes::{ BEQ, BNE, BYTES_PER_INSTR, IMM32, JAL, JALV, LOAD32, LOADFP, LOADS8, LOADU8, READ_ADVICE, STOP, @@ -469,14 +468,18 @@ where let clk = state.cpu().clock; let pc = state.cpu().pc; let fp = state.cpu().fp; - let read_addr_1 = (fp as i32 + ops.c()) as u32; - let read_addr_2 = state + + let read_addr_loc = (fp as i32 + ops.c()) as u32; + + let read_addr = state .mem_mut() - .read(clk, read_addr_1, true, pc, opcode, 0, ""); - let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; + .read(clk, read_addr_loc, true, pc, opcode, 0, ""); + let read_addr_index = index_to_word(read_addr.into()); + + // The word from the read address. let cell = state.mem_mut().read( clk, - read_addr_2.into(), + read_addr_index, true, pc, opcode, @@ -485,12 +488,28 @@ where "fp = {}, c = {}, [fp+c] = {:?}", fp as i32, ops.c() as u32, - read_addr_2 + read_addr_index ), ); - state.mem_mut().write(clk, write_addr, cell, true); + + // The array index of the word for the byte to read from + let index_of_read = index_of_word(read_addr.into()); + // The byte from the read cell. + let cell_byte = cell[index_of_read]; + + let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; + // The key to the memory map, converted to a multiple of 4. + let write_addr_index = index_to_word(write_addr); + + // The array index of the word for the byte to write to + let index_of_write = index_of_word(write_addr.into()); + + // The Word to write, with one byte overwritten to the read byte + let cell_to_write = Word::zero_extend_byte(cell_byte, index_of_write); + + state.mem_mut().write(clk, write_addr_index, cell_to_write, true); state.cpu_mut().pc += 1; - state.cpu_mut().push_op(Operation::Load32, opcode, ops); + state.cpu_mut().push_op(Operation::LoadU8, opcode, ops); } } @@ -506,14 +525,18 @@ where let clk = state.cpu().clock; let pc = state.cpu().pc; let fp = state.cpu().fp; - let read_addr_1 = (fp as i32 + ops.c()) as u32; - let read_addr_2 = state + + let read_addr_loc = (fp as i32 + ops.c()) as u32; + + let read_addr = state .mem_mut() - .read(clk, read_addr_1, true, pc, opcode, 0, ""); - let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; + .read(clk, read_addr_loc, true, pc, opcode, 0, ""); + let read_addr_index = index_to_word(read_addr.into()); + + // The word from the read address. let cell = state.mem_mut().read( clk, - read_addr_2.into(), + read_addr_index, true, pc, opcode, @@ -522,12 +545,28 @@ where "fp = {}, c = {}, [fp+c] = {:?}", fp as i32, ops.c() as u32, - read_addr_2 + read_addr_index ), ); - state.mem_mut().write(clk, write_addr, cell, true); + + // The array index of the word for the byte to read from + let index_of_read = index_of_word(read_addr.into()); + // The byte from the read cell. + let cell_byte = cell[index_of_read]; + + let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; + // The key to the memory map, converted to a multiple of 4. + let write_addr_index = index_to_word(write_addr); + + // The array index of the word for the byte to write to + let index_of_write = index_of_word(write_addr.into()); + + // The Word to write, with one byte overwritten to the read byte + let cell_to_write = Word::sign_extend_byte(cell_byte, index_of_write); + + state.mem_mut().write(clk, write_addr_index, cell_to_write, true); state.cpu_mut().pc += 1; - state.cpu_mut().push_op(Operation::Load32, opcode, ops); + state.cpu_mut().push_op(Operation::LoadS8, opcode, ops); } } @@ -556,16 +595,6 @@ where } } -/// Get the index of a byte in a memory cell. -fn index_of_word(addr: u32) -> usize { - (addr&3) as usize -} - -/// Get the key to the map of the memory cells which is not empty. -fn index_to_word(addr: u32) -> u32 { - (addr&!3) as u32 -} - impl Instruction for StoreU8Instruction where M: MachineWithCpuChip, @@ -578,7 +607,7 @@ where let clk = state.cpu().clock; let read_addr = (state.cpu().fp as i32 + ops.c()) as u32; - // Make sure we get to the correct and non empty map by making it a multiple of 4. + // Make sure we get to the correct and non empty map for the byte. let read_addr_index = index_to_word(read_addr); let write_addr_loc = (state.cpu().fp as i32 + ops.b()) as u32; let pc = state.cpu().pc; @@ -594,9 +623,9 @@ where // The array index of the word for the byte to read from let index_of_read = index_of_word(read_addr); - // The word read from the read address. + // The word from the read address. let cell_read = cell.0; - // The byte read from the read address. + // The byte from the read cell. let cell_byte = cell_read[index_of_read]; // The array index of the word for the byte to write to @@ -605,7 +634,7 @@ where // The key to the memory map, converted to a multiple of 4. let write_addr_index = index_to_word(write_addr.into()); - // The original content of the cell to write to. If the cell was empty, initiate it with a default value. + // The original content of the cell to write to. If the cell is empty, initiate it with a default value. let cell_write = state.mem_mut().read_or_init(clk, write_addr_index, true); // The Word to write, with one byte overwritten to the read byte diff --git a/machine/src/core.rs b/machine/src/core.rs index 2c907a4c..211047ea 100644 --- a/machine/src/core.rs +++ b/machine/src/core.rs @@ -7,6 +7,18 @@ use p3_field::{Field, PrimeField}; #[derive(Copy, Clone, Debug, Default)] pub struct Word(pub [F; MEMORY_CELL_BYTES]); +// Functions for byte manipulations +/// Get the index of a byte in a memory cell. +pub fn index_of_word(addr: u32) -> usize { + (addr&3) as usize +} + +/// Get the key to the map of the memory cells which is not empty. +pub fn index_to_word(addr: u32) -> u32 { + (addr&!3) as u32 +} +//---------------------------------- + impl Word { pub fn from_u8(byte: u8) -> Self { let mut result = [0; MEMORY_CELL_BYTES]; @@ -15,6 +27,23 @@ impl Word { } } +impl Word { + pub fn sign_extend_byte(byte: u8, loc: usize) -> Self { + let sign = byte as i8 >> 7; + let mut result: [u8; MEMORY_CELL_BYTES] = [sign as u8; MEMORY_CELL_BYTES]; + result[loc] = byte; + Self(result) + } +} + +impl Word { + pub fn zero_extend_byte(byte: u8, loc: usize) -> Self { + let mut result: [u8; MEMORY_CELL_BYTES] = [0; MEMORY_CELL_BYTES]; + result[loc] = byte; + Self(result) + } +} + impl Word { pub fn update_byte(self, byte: u8, loc: usize) -> Self { let mut result: [u8; MEMORY_CELL_BYTES] = self.0; From 32b8aec8adece5ebef92903d24b0abaab6a0a33b Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Wed, 17 Apr 2024 12:08:37 -0700 Subject: [PATCH 08/13] Cargo fmt. --- cpu/src/lib.rs | 48 +++++++++++++++++++++++++-------------------- machine/src/core.rs | 11 ++++++----- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 47583866..6f573021 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -11,7 +11,9 @@ use core::marker::Sync; use core::mem::transmute; use valida_bus::{MachineWithGeneralBus, MachineWithMemBus, MachineWithProgramBus}; use valida_machine::{ - instructions, AdviceProvider, Chip, Instruction, InstructionWord, Interaction, Operands, Word, index_of_word, index_to_word}; + index_of_byte, index_to_word, instructions, AdviceProvider, Chip, Instruction, InstructionWord, + Interaction, Operands, Word, +}; use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation}; use valida_opcodes::{ BEQ, BNE, BYTES_PER_INSTR, IMM32, JAL, JALV, LOAD32, LOADFP, LOADS8, LOADU8, READ_ADVICE, STOP, @@ -468,14 +470,14 @@ where let clk = state.cpu().clock; let pc = state.cpu().pc; let fp = state.cpu().fp; - + let read_addr_loc = (fp as i32 + ops.c()) as u32; - + let read_addr = state .mem_mut() .read(clk, read_addr_loc, true, pc, opcode, 0, ""); let read_addr_index = index_to_word(read_addr.into()); - + // The word from the read address. let cell = state.mem_mut().read( clk, @@ -493,21 +495,23 @@ where ); // The array index of the word for the byte to read from - let index_of_read = index_of_word(read_addr.into()); + let index_of_read = index_of_byte(read_addr.into()); // The byte from the read cell. let cell_byte = cell[index_of_read]; let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; - // The key to the memory map, converted to a multiple of 4. + // The address, converted to a multiple of 4. let write_addr_index = index_to_word(write_addr); // The array index of the word for the byte to write to - let index_of_write = index_of_word(write_addr.into()); - + let index_of_write = index_of_byte(write_addr.into()); + // The Word to write, with one byte overwritten to the read byte let cell_to_write = Word::zero_extend_byte(cell_byte, index_of_write); - state.mem_mut().write(clk, write_addr_index, cell_to_write, true); + state + .mem_mut() + .write(clk, write_addr_index, cell_to_write, true); state.cpu_mut().pc += 1; state.cpu_mut().push_op(Operation::LoadU8, opcode, ops); } @@ -525,18 +529,18 @@ where let clk = state.cpu().clock; let pc = state.cpu().pc; let fp = state.cpu().fp; - + let read_addr_loc = (fp as i32 + ops.c()) as u32; - + let read_addr = state .mem_mut() .read(clk, read_addr_loc, true, pc, opcode, 0, ""); let read_addr_index = index_to_word(read_addr.into()); - + // The word from the read address. let cell = state.mem_mut().read( clk, - read_addr_index, + read_addr.into(), //TODO should be read_addr_index but currently it causes read before write error. true, pc, opcode, @@ -550,21 +554,23 @@ where ); // The array index of the word for the byte to read from - let index_of_read = index_of_word(read_addr.into()); + let index_of_read = index_of_byte(read_addr.into()); // The byte from the read cell. let cell_byte = cell[index_of_read]; let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; - // The key to the memory map, converted to a multiple of 4. + // The address, converted to a multiple of 4. let write_addr_index = index_to_word(write_addr); // The array index of the word for the byte to write to - let index_of_write = index_of_word(write_addr.into()); - + let index_of_write = index_of_byte(write_addr.into()); + // The Word to write, with one byte overwritten to the read byte let cell_to_write = Word::sign_extend_byte(cell_byte, index_of_write); - state.mem_mut().write(clk, write_addr_index, cell_to_write, true); + state + .mem_mut() + .write(clk, write_addr_index, cell_to_write, true); state.cpu_mut().pc += 1; state.cpu_mut().push_op(Operation::LoadS8, opcode, ops); } @@ -621,7 +627,7 @@ where .read(clk, read_addr_index, true, pc, opcode, 1, ""); // The array index of the word for the byte to read from - let index_of_read = index_of_word(read_addr); + let index_of_read = index_of_byte(read_addr); // The word from the read address. let cell_read = cell.0; @@ -629,11 +635,11 @@ where let cell_byte = cell_read[index_of_read]; // The array index of the word for the byte to write to - let index_of_write = index_of_word(write_addr.into()); + let index_of_write = index_of_byte(write_addr.into()); // The key to the memory map, converted to a multiple of 4. let write_addr_index = index_to_word(write_addr.into()); - + // The original content of the cell to write to. If the cell is empty, initiate it with a default value. let cell_write = state.mem_mut().read_or_init(clk, write_addr_index, true); diff --git a/machine/src/core.rs b/machine/src/core.rs index 211047ea..2bdd9146 100644 --- a/machine/src/core.rs +++ b/machine/src/core.rs @@ -9,13 +9,13 @@ pub struct Word(pub [F; MEMORY_CELL_BYTES]); // Functions for byte manipulations /// Get the index of a byte in a memory cell. -pub fn index_of_word(addr: u32) -> usize { - (addr&3) as usize +pub fn index_of_byte(addr: u32) -> usize { + (addr & 3) as usize } -/// Get the key to the map of the memory cells which is not empty. +/// Get the address of the memory cells which is not empty (a multiple of 4). pub fn index_to_word(addr: u32) -> u32 { - (addr&!3) as u32 + (addr & !3) as u32 } //---------------------------------- @@ -28,8 +28,9 @@ impl Word { } impl Word { + //TODO if the byte isn't the lowest byte then this doesn't make sense? pub fn sign_extend_byte(byte: u8, loc: usize) -> Self { - let sign = byte as i8 >> 7; + let sign = byte as i8 >> 7; let mut result: [u8; MEMORY_CELL_BYTES] = [sign as u8; MEMORY_CELL_BYTES]; result[loc] = byte; Self(result) From d0d82496dd57b8c492f57df84ad76a7a2008a3c2 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Wed, 17 Apr 2024 12:45:38 -0700 Subject: [PATCH 09/13] Put byte at the end. --- cpu/src/lib.rs | 10 ++-------- machine/src/core.rs | 9 ++++----- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 6f573021..417d15c9 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -503,11 +503,8 @@ where // The address, converted to a multiple of 4. let write_addr_index = index_to_word(write_addr); - // The array index of the word for the byte to write to - let index_of_write = index_of_byte(write_addr.into()); - // The Word to write, with one byte overwritten to the read byte - let cell_to_write = Word::zero_extend_byte(cell_byte, index_of_write); + let cell_to_write = Word::zero_extend_byte(cell_byte); state .mem_mut() @@ -562,11 +559,8 @@ where // The address, converted to a multiple of 4. let write_addr_index = index_to_word(write_addr); - // The array index of the word for the byte to write to - let index_of_write = index_of_byte(write_addr.into()); - // The Word to write, with one byte overwritten to the read byte - let cell_to_write = Word::sign_extend_byte(cell_byte, index_of_write); + let cell_to_write = Word::sign_extend_byte(cell_byte); state .mem_mut() diff --git a/machine/src/core.rs b/machine/src/core.rs index 2bdd9146..f507c4fc 100644 --- a/machine/src/core.rs +++ b/machine/src/core.rs @@ -28,19 +28,18 @@ impl Word { } impl Word { - //TODO if the byte isn't the lowest byte then this doesn't make sense? - pub fn sign_extend_byte(byte: u8, loc: usize) -> Self { + pub fn sign_extend_byte(byte: u8) -> Self { let sign = byte as i8 >> 7; let mut result: [u8; MEMORY_CELL_BYTES] = [sign as u8; MEMORY_CELL_BYTES]; - result[loc] = byte; + result[3] = byte; Self(result) } } impl Word { - pub fn zero_extend_byte(byte: u8, loc: usize) -> Self { + pub fn zero_extend_byte(byte: u8) -> Self { let mut result: [u8; MEMORY_CELL_BYTES] = [0; MEMORY_CELL_BYTES]; - result[loc] = byte; + result[3] = byte; Self(result) } } From 0436bffc0bc84ba256fabd57703f56115b578b04 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Thu, 18 Apr 2024 09:35:00 -0700 Subject: [PATCH 10/13] Fix read before write bug. --- cpu/src/lib.rs | 23 ++++++++++++----------- machine/src/core.rs | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 417d15c9..6af95dcb 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -11,7 +11,7 @@ use core::marker::Sync; use core::mem::transmute; use valida_bus::{MachineWithGeneralBus, MachineWithMemBus, MachineWithProgramBus}; use valida_machine::{ - index_of_byte, index_to_word, instructions, AdviceProvider, Chip, Instruction, InstructionWord, + index_of_byte, addr_of_word, instructions, AdviceProvider, Chip, Instruction, InstructionWord, Interaction, Operands, Word, }; use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation}; @@ -476,7 +476,7 @@ where let read_addr = state .mem_mut() .read(clk, read_addr_loc, true, pc, opcode, 0, ""); - let read_addr_index = index_to_word(read_addr.into()); + let read_addr_index = addr_of_word(read_addr.into()); // The word from the read address. let cell = state.mem_mut().read( @@ -501,7 +501,7 @@ where let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; // The address, converted to a multiple of 4. - let write_addr_index = index_to_word(write_addr); + let write_addr_index = addr_of_word(write_addr); // The Word to write, with one byte overwritten to the read byte let cell_to_write = Word::zero_extend_byte(cell_byte); @@ -532,12 +532,13 @@ where let read_addr = state .mem_mut() .read(clk, read_addr_loc, true, pc, opcode, 0, ""); - let read_addr_index = index_to_word(read_addr.into()); - + + let read_addr_index = addr_of_word(read_addr.into()); + // The word from the read address. let cell = state.mem_mut().read( clk, - read_addr.into(), //TODO should be read_addr_index but currently it causes read before write error. + read_addr_index, true, pc, opcode, @@ -557,7 +558,7 @@ where let write_addr = (state.cpu().fp as i32 + ops.a()) as u32; // The address, converted to a multiple of 4. - let write_addr_index = index_to_word(write_addr); + let write_addr_index = addr_of_word(write_addr); // The Word to write, with one byte overwritten to the read byte let cell_to_write = Word::sign_extend_byte(cell_byte); @@ -585,7 +586,7 @@ where let pc = state.cpu().pc; let write_addr = state .mem_mut() - .read(clk, write_addr_loc.into(), true, pc, opcode, 0, ""); + .read(clk, write_addr_loc, true, pc, opcode, 0, ""); let cell = state .mem_mut() .read(clk, read_addr, true, pc, opcode, 1, ""); @@ -608,7 +609,7 @@ where let read_addr = (state.cpu().fp as i32 + ops.c()) as u32; // Make sure we get to the correct and non empty map for the byte. - let read_addr_index = index_to_word(read_addr); + let read_addr_index = addr_of_word(read_addr); let write_addr_loc = (state.cpu().fp as i32 + ops.b()) as u32; let pc = state.cpu().pc; let write_addr = state @@ -632,7 +633,7 @@ where let index_of_write = index_of_byte(write_addr.into()); // The key to the memory map, converted to a multiple of 4. - let write_addr_index = index_to_word(write_addr.into()); + let write_addr_index = addr_of_word(write_addr.into()); // The original content of the cell to write to. If the cell is empty, initiate it with a default value. let cell_write = state.mem_mut().read_or_init(clk, write_addr_index, true); @@ -642,7 +643,7 @@ where state .mem_mut() - .write(clk, write_addr.into(), cell_to_write, true); + .write(clk, write_addr_index, cell_to_write, true); state.cpu_mut().pc += 1; state.cpu_mut().push_op(Operation::StoreU8, opcode, ops); } diff --git a/machine/src/core.rs b/machine/src/core.rs index f507c4fc..f09d6f89 100644 --- a/machine/src/core.rs +++ b/machine/src/core.rs @@ -14,7 +14,7 @@ pub fn index_of_byte(addr: u32) -> usize { } /// Get the address of the memory cells which is not empty (a multiple of 4). -pub fn index_to_word(addr: u32) -> u32 { +pub fn addr_of_word(addr: u32) -> u32 { (addr & !3) as u32 } //---------------------------------- From 9be668c057d2907476dfadb6f93be16d5287ab83 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Thu, 18 Apr 2024 11:31:39 -0700 Subject: [PATCH 11/13] Add to assembler/REPL. --- assembler/grammar/assembly.pest | 2 +- assembler/src/lib.rs | 4 ++-- cpu/src/lib.rs | 6 +++--- machine/src/program.rs | 9 +++++++++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/assembler/grammar/assembly.pest b/assembler/grammar/assembly.pest index 530aa40e..82cea9e2 100644 --- a/assembler/grammar/assembly.pest +++ b/assembler/grammar/assembly.pest @@ -3,7 +3,7 @@ comment = { ";" ~ (!"\n" ~ ANY)* ~ "\n" } label = { (!":" ~ !"\n" ~ ANY)+ ~ ":" ~ "\n" } instruction = { mnemonic ~ (operand ~ ", "?)+? ~ "\n"? } mnemonic = { - "lw" | "sw" | "jalv" | "jal" | "beqi" | "beq" | "bnei" | "bne" | "imm32" | "stop" | + "lw" | "sw" | "loadu8" | "loads8" | "storeu8" | "jalv" | "jal" | "beqi" | "beq" | "bnei" | "bne" | "imm32" | "stop" | "advread" | "advwrite" | "addi" | "add" | "subi" | "sub" | "muli" | "mul" | "mulhsi"| "mulhui"| "mulhs"| "mulhu" | "divi" | "div" | "sdiv" | "sdivi" | "ilte" | "ltei" | "lte" | "ilt" | "lti" | "lt" | "shli" | "shl" | "shri" | "shr" | "srai" | "sra" | diff --git a/assembler/src/lib.rs b/assembler/src/lib.rs index 5d0c1e96..b3ed64be 100644 --- a/assembler/src/lib.rs +++ b/assembler/src/lib.rs @@ -104,12 +104,12 @@ pub fn assemble(input: &str) -> Result, String> { // Insert zero operands if necessary match mnemonic { - "lw" => { + "lw" | "loadu8" | "loads8" => { // (a, 0, c, 0, 0) operands.insert(1, 0); operands.extend(vec![0; 2]); } - "sw" => { + "sw" | "storeu8" => { // (0, b, c, 0, 0) operands.insert(0, 0); operands.extend(vec![0; 2]); diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 6af95dcb..ded77728 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -11,7 +11,7 @@ use core::marker::Sync; use core::mem::transmute; use valida_bus::{MachineWithGeneralBus, MachineWithMemBus, MachineWithProgramBus}; use valida_machine::{ - index_of_byte, addr_of_word, instructions, AdviceProvider, Chip, Instruction, InstructionWord, + addr_of_word, index_of_byte, instructions, AdviceProvider, Chip, Instruction, InstructionWord, Interaction, Operands, Word, }; use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation}; @@ -532,9 +532,9 @@ where let read_addr = state .mem_mut() .read(clk, read_addr_loc, true, pc, opcode, 0, ""); - + let read_addr_index = addr_of_word(read_addr.into()); - + // The word from the read address. let cell = state.mem_mut().read( clk, diff --git a/machine/src/program.rs b/machine/src/program.rs index f61bcbad..3032f8cf 100644 --- a/machine/src/program.rs +++ b/machine/src/program.rs @@ -102,9 +102,18 @@ impl InstructionWord { valida_opcodes::LOAD32 => { format!("{}(fp), {}(fp)", self.operands.0[0], self.operands.0[2]) } + valida_opcodes::LOADU8 => { + format!("{}(fp), {}(fp)", self.operands.0[0], self.operands.0[2]) + } + valida_opcodes::LOADS8 => { + format!("{}(fp), {}(fp)", self.operands.0[0], self.operands.0[2]) + } valida_opcodes::STORE32 => { format!("{}(fp), {}(fp)", self.operands.0[1], self.operands.0[2]) } + valida_opcodes::STOREU8 => { + format!("{}(fp), {}(fp)", self.operands.0[1], self.operands.0[2]) + } _ => { format!( "{}(fp), {}, {}", From 62ac58e0e5e319567d89b642db9db21e305f4fcd Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Thu, 18 Apr 2024 13:19:23 -0700 Subject: [PATCH 12/13] Put the least significant byte into the lowest memory addr. --- cpu/src/lib.rs | 2 +- machine/src/core.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index ded77728..cb9c0a59 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -643,7 +643,7 @@ where state .mem_mut() - .write(clk, write_addr_index, cell_to_write, true); + .write(clk, 0, Word::from(0), true); state.cpu_mut().pc += 1; state.cpu_mut().push_op(Operation::StoreU8, opcode, ops); } diff --git a/machine/src/core.rs b/machine/src/core.rs index f09d6f89..4ff8d2fa 100644 --- a/machine/src/core.rs +++ b/machine/src/core.rs @@ -31,7 +31,7 @@ impl Word { pub fn sign_extend_byte(byte: u8) -> Self { let sign = byte as i8 >> 7; let mut result: [u8; MEMORY_CELL_BYTES] = [sign as u8; MEMORY_CELL_BYTES]; - result[3] = byte; + result[0] = byte; Self(result) } } @@ -39,7 +39,7 @@ impl Word { impl Word { pub fn zero_extend_byte(byte: u8) -> Self { let mut result: [u8; MEMORY_CELL_BYTES] = [0; MEMORY_CELL_BYTES]; - result[3] = byte; + result[0] = byte; Self(result) } } From c4f44ac55a8cdf003176ea60baea84a67cc262e4 Mon Sep 17 00:00:00 2001 From: thealmarty <“thealmartyblog@gmail.com”> Date: Thu, 18 Apr 2024 13:20:07 -0700 Subject: [PATCH 13/13] f --- cpu/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index cb9c0a59..ded77728 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -643,7 +643,7 @@ where state .mem_mut() - .write(clk, 0, Word::from(0), true); + .write(clk, write_addr_index, cell_to_write, true); state.cpu_mut().pc += 1; state.cpu_mut().push_op(Operation::StoreU8, opcode, ops); }