eeric_core/rv_core/registers/
csr.rs

1use crate::{prelude::Snapshotable, rv_core::vector_engine::Vlen};
2
3use super::aliases::csr::VLENB;
4
5#[derive(Clone, PartialEq, Debug)]
6pub enum CsrPrivilege {
7    ReadOnly,
8    ReadWrite,
9}
10
11#[derive(Clone, PartialEq, Debug)]
12pub struct CsrRegister {
13    value: u64,
14    pub privilege: CsrPrivilege,
15}
16
17impl CsrRegister {
18    pub fn read(&self) -> u64 {
19        self.value
20    }
21
22    pub fn write(&mut self, value: u64) -> Result<(), String> {
23        if self.privilege == CsrPrivilege::ReadOnly {
24            return Err("Cannot write to read-only register".to_owned());
25        }
26
27        unsafe {
28            self.set(value);
29        }
30
31        Ok(())
32    }
33
34    pub unsafe fn set(&mut self, value: u64) {
35        self.value = value;
36    }
37}
38
39#[derive(Clone, PartialEq, Debug)]
40pub struct CsrRegisters([CsrRegister; 4096]);
41
42impl Snapshotable for CsrRegisters {
43    type Snapshot = [CsrRegister; 4096];
44
45    fn snapshot(&self) -> Self::Snapshot {
46        self.0.clone()
47    }
48}
49
50impl CsrRegisters {
51    pub fn new(vlen: &Vlen) -> Self {
52        let mut regs = Self::default();
53
54        unsafe { regs[VLENB].set(vlen.byte_length() as u64) }
55
56        regs
57    }
58}
59
60impl Default for CsrRegisters {
61    fn default() -> Self {
62        let mut index = 0;
63        Self([0; 4096].map(|_| {
64            let privilege = if ((index >> 10) & 0b11) == 0b11 {
65                CsrPrivilege::ReadOnly
66            } else {
67                CsrPrivilege::ReadWrite
68            };
69            let register = CsrRegister {
70                value: 0,
71                privilege,
72            };
73
74            index += 1;
75
76            register
77        }))
78    }
79}
80
81impl std::ops::Index<usize> for CsrRegisters {
82    type Output = CsrRegister;
83
84    fn index(&self, index: usize) -> &Self::Output {
85        &self.0[index]
86    }
87}
88
89impl std::ops::IndexMut<usize> for CsrRegisters {
90    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
91        &mut self.0[index]
92    }
93}