eeric_core/rv_core/registers/
csr.rs1use 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}