1use serde::{Deserialize, Serialize};
2
3mod memory;
5
6mod register_file;
8
9#[cfg(test)]
10mod test_runner;
11
12pub use lib_rv32_isa as isa;
14
15pub use lib_rv32_isa::common;
17
18pub use memory::*;
19pub use register_file::*;
20
21#[derive(Clone, Serialize, Deserialize)]
24pub struct Mcu {
25 pub pc: u32,
26 pub mem: Memory,
27 pub rf: RegisterFile,
28}
29
30impl Mcu {
31 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}