lib_rv32_mcu/
register_file.rs1use log::info;
2use serde::{Deserialize, Serialize};
3
4pub use lib_rv32_isa::traits::RegisterFile as RegisterFileTrait;
5use lib_rv32_isa::{common::constants::*, RiscvError};
6
7#[derive(Default, Clone, Serialize, Deserialize)]
9pub struct RegisterFile {
10 registers: Vec<u32>,
11}
12
13impl RegisterFile {
14 pub fn new() -> Self {
15 RegisterFile {
16 registers: vec![0; 31],
17 }
18 }
19}
20
21impl RegisterFileTrait for RegisterFile {
22 fn write(&mut self, num: u8, data: u32) -> Result<(), RiscvError> {
23 if num > 31 {
24 return Err(RiscvError::RegisterOutOfRangeError(num));
25 } else if num >= 1 {
26 self.registers[num as usize - 1] = data;
27 }
28
29 info!(
30 "{} <- 0x{:x} ({})",
31 REG_NAMES[num as usize], data, data as i32
32 );
33
34 Ok(())
35 }
36
37 fn read(&self, num: u8) -> Result<u32, RiscvError> {
38 if num == 0 {
39 Ok(0)
40 } else if num > 31 {
41 Err(RiscvError::RegisterOutOfRangeError(num))
42 } else {
43 Ok(self.registers[num as usize - 1])
44 }
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_zero() {
54 let mut rf = RegisterFile::new();
55 rf.write(0, 17).unwrap();
56 assert_eq!(0, rf.read(0).unwrap());
57 }
58
59 #[test]
60 fn test_read_write() {
61 let mut rf = RegisterFile::new();
62 for i in 0..128 {
63 let d = i << 16;
64 for n in 0..32 {
65 rf.write(n, d).unwrap();
66 assert_eq!(if n == 0 { 0 } else { d }, rf.read(n).unwrap());
67 }
68 }
69 }
70
71 #[test]
72 fn test_out_of_range() {
73 assert_eq!(
74 Err(RiscvError::RegisterOutOfRangeError(32)),
75 RegisterFile::new().read(32)
76 )
77 }
78}