1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use crate::processor::isa_mods::PossibleXlen;
use thiserror::Error;

pub trait RegisterFile<TData> {
    fn read(&mut self, idx: u8) -> Result<TData, RegisterFileError>;
    fn write(&mut self, idx: u8, val: TData) -> Result<(), RegisterFileError>;
}

#[derive(Debug,Error,Copy,Clone,PartialEq,Eq)]
pub enum RegisterFileError {
    #[error("Tried to access nonexistant register {0}")]
    InvalidIndex(u8),
}

pub struct RvRegisterFile<T: PossibleXlen> {
    regs: [T; 31],
}
impl<T> RvRegisterFile<T> where T: PossibleXlen {
    pub fn dump(&self) {
        const REGISTER_NAMES: [&str; 32] = [
            "zero", "ra", "sp", "gp",
            "tp", "t0", "t1", "t2",
            "fp", "s1", "a0", "a1",
            "a2", "a3", "a4", "a5",
            "a6", "a7", "s2", "s3",
            "s4", "s5", "s6", "s7",
            "s8", "s9", "s10", "s11",
            "t3", "t4", "t5", "t6"
        ];

        for i in 0..32 {
            println!("x{} = {} = 0x{:08x}", i, REGISTER_NAMES[i], match i {
                0 => T::zero(),
                _ => self.regs[i - 1]
            });
        }
    }
    pub fn reset(&mut self) {
        self.regs = [T::zero(); 31];
    }
}
impl<T> RegisterFile<T> for RvRegisterFile<T> where T: PossibleXlen {    
    fn read(&mut self, idx: u8) -> Result<T, RegisterFileError> {
        let val = match idx {
            0    => Ok(T::zero()),
            1..=31 => Ok(self.regs[(idx - 1) as usize]),
            _ => Err(RegisterFileError::InvalidIndex(idx))
        }?;

        Ok(val)
    }
    fn write(&mut self, idx: u8, val: T) -> Result<(), RegisterFileError> {
        match idx {
            0    => Ok(()),
            1..=31 => {
                self.regs[(idx - 1) as usize] = val;
                Ok(())
            },
            _ => Err(RegisterFileError::InvalidIndex(idx))
        }?;

        Ok(())
    }
}
impl<T> Default for RvRegisterFile<T> where T: PossibleXlen {
    fn default() -> Self {
        RvRegisterFile {
            regs: [T::zero(); 31],
        }
    }
}