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}