lc3_zkvm/memory.rs
1//! LC3 Memory Module
2//!
3//! This module implements the memory system for the LC3 (Little Computer 3) Zero-Knowledge Virtual Machine.
4//!
5//! ## Design
6//! - The LC3 uses a 16-bit address space, allowing for 65,536 (2^16) memory locations.
7//! - Each memory location stores a 16-bit word.
8//! - The memory is implemented as a fixed-size array of 65,536 16-bit unsigned integers.
9//! - Memory operations include reading, writing, and clearing.
10//! - The module implements the `Index` and `IndexMut` traits for convenient array-like access.
11//!
12//! ## Usage
13//! Create a new memory instance:
14//! ```
15//! use lc3_zkvm::memory::Memory;
16//! let mut memory = Memory::new();
17//!
18//! // Read from and write to memory:
19//! memory.write(0x3000, 0x1234);
20//! let value = memory.read(0x3000);
21//!
22//! // Use array-like indexing:
23//! memory[0x3000] = 0x5678;
24//! let value = memory[0x3000];
25//! ```
26
27use std::ops::{Index, IndexMut};
28
29pub const MEMORY_SIZE: usize = 65536; // 2^16, as LC3 uses 16-bit addressing
30
31pub struct Memory {
32 data: [u16; MEMORY_SIZE],
33}
34
35impl Memory {
36 pub fn new() -> Self {
37 Memory {
38 data: [0; MEMORY_SIZE],
39 }
40 }
41
42 pub fn read(&self, address: u16) -> u16 {
43 self.data[address as usize]
44 }
45
46 pub fn write(&mut self, address: u16, value: u16) {
47 self.data[address as usize] = value;
48 }
49
50 pub fn clear(&mut self) {
51 self.data = [0; MEMORY_SIZE];
52 }
53}
54
55impl Index<u16> for Memory {
56 type Output = u16;
57
58 fn index(&self, address: u16) -> &Self::Output {
59 &self.data[address as usize]
60 }
61}
62
63impl IndexMut<u16> for Memory {
64 fn index_mut(&mut self, address: u16) -> &mut Self::Output {
65 &mut self.data[address as usize]
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_memory_operations() {
75 let mut mem = Memory::new();
76
77 // Test write and read
78 mem.write(0x3000, 0x1234);
79 assert_eq!(mem.read(0x3000), 0x1234);
80
81 // Test indexing
82 mem[0x3001] = 0x5678;
83 assert_eq!(mem[0x3001], 0x5678);
84
85 // Test clear
86 mem.clear();
87 assert_eq!(mem[0x3000], 0);
88 assert_eq!(mem[0x3001], 0);
89 }
90}