lib_rv32_mcu/
lib.rs

1use serde::{Deserialize, Serialize};
2
3/// Contains reference `Memory` struct.
4mod memory;
5
6/// Contains referende `RegisterFile` struct.
7mod register_file;
8
9#[cfg(test)]
10mod test_runner;
11
12/// Re-export ISA simulator.
13pub use lib_rv32_isa as isa;
14
15/// Re-export common library.
16pub use lib_rv32_isa::common;
17
18pub use memory::*;
19pub use register_file::*;
20
21/// Reference implementation of an MCU. Contains a PC,
22/// register file, and memory.
23#[derive(Clone, Serialize, Deserialize)]
24pub struct Mcu {
25    pub pc: u32,
26    pub mem: Memory,
27    pub rf: RegisterFile,
28}
29
30impl Mcu {
31    /// Construct an MCU with the provided memory size.
32    pub fn new(size: usize) -> Self {
33        Mcu {
34            pc: 0,
35            mem: Memory::new(size),
36            rf: RegisterFile::new(),
37        }
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    use lib_rv32_isa::{common::instructions, exec_one};
45
46    const MEM_SIZE: u32 = 0x10000;
47
48    #[test]
49    fn test_addi_x5_x5_1() {
50        let mut mcu = Mcu::new(MEM_SIZE as usize);
51        let bytes = instructions::ADDI_X5_X5_1.to_le_bytes();
52        mcu.mem.program_le_bytes(&bytes).unwrap();
53        exec_one(&mut mcu.pc, &mut mcu.mem, &mut mcu.rf).unwrap();
54
55        for i in 0..32 {
56            assert_eq!(
57                match i {
58                    5 => 1,
59                    _ => 0,
60                },
61                mcu.rf.read(i).unwrap()
62            );
63        }
64
65        for i in 1..(MEM_SIZE / 4) {
66            assert_eq!(0, mcu.mem.read_word(i * 4).unwrap());
67        }
68
69        assert_eq!(4, mcu.pc);
70    }
71
72    #[test]
73    fn test_addi_x5_x6_neg_1() {
74        let mut mcu = Mcu::new(MEM_SIZE as usize);
75        let bytes = instructions::ADDI_X5_X6_NEG_1.to_le_bytes();
76        mcu.mem.program_le_bytes(&bytes).unwrap();
77        exec_one(&mut mcu.pc, &mut mcu.mem, &mut mcu.rf).unwrap();
78
79        for i in 0..32 {
80            assert_eq!(
81                match i {
82                    5 => -1,
83                    _ => 0,
84                },
85                mcu.rf.read(i).unwrap() as i32
86            );
87        }
88
89        for i in 1..(MEM_SIZE / 4) {
90            assert_eq!(0, mcu.mem.read_word(i * 4).unwrap());
91        }
92
93        assert_eq!(4, mcu.pc);
94    }
95}