1pub mod field;
6pub mod regfile;
7pub mod register;
8pub mod state;
9
10pub mod test_helpers;
11
12#[doc(hidden)]
13pub use paste::paste;
14
15pub enum Permission {
17 ReadOnly,
19
20 ReadVolatileOnly,
22
23 ReadWrite,
26
27 ReadVolatileWrite,
30
31 WriteCommits,
33
34 WriteOneCommits,
36
37 WriteOnly,
41
42 WriteIgnore,
44
45 Reserved,
47}
48
49#[cfg(test)]
50pub mod tests {
51 use std::cell::RefCell;
52 use std::rc::Rc;
53
54 use gwr_engine::traits::Resolve;
55
56 use super::register::{Read, Register, Written};
57 use super::state::{RegisterState, UpdatePriority};
58 use crate::registers::test_helpers::TestResolver;
59 use crate::{
60 build_register_file, build_register_state, build_register_states, build_register_view,
61 };
62
63 pub struct TestCallbackHandler {
64 pub written_count: RefCell<usize>,
65 pub read_count: RefCell<usize>,
66 pub last_write: RefCell<Option<(u64, u64, u64)>>,
67 }
68
69 impl TestCallbackHandler {
70 #[must_use]
71 pub fn new() -> Self {
72 Self {
73 written_count: RefCell::new(0),
74 read_count: RefCell::new(0),
75 last_write: RefCell::new(None),
76 }
77 }
78 }
79
80 impl Default for TestCallbackHandler {
81 fn default() -> Self {
82 Self::new()
83 }
84 }
85
86 impl Written for TestCallbackHandler {
87 fn written(&self, old_value: u64, value_written: u64, new_value: u64) {
88 *self.written_count.borrow_mut() += 1;
89 *self.last_write.borrow_mut() = Some((old_value, value_written, new_value));
90 }
91 }
92
93 impl Read for TestCallbackHandler {
94 fn read(&self, _value_read: u64) {
95 *self.read_count.borrow_mut() += 1;
96 }
97 }
98
99 pub const CSR_RESET_VALUE: u64 = 0x0000_cc01;
101 pub const CSR_WRITE_VALUE: u64 = 0x0000_ccff;
103 pub const CSR_SET_VALUE: u64 = 0x00ff_ccff;
105
106 build_register_state!(
108 Csr, 32 ;
110 enabled: 8, 0x1,
112 reserved: 8, 0xcc,
114 excepted: 8, 0,
116 trigger: 1, 0,
118 );
119
120 build_register_states!(
122 TestCsrStates ; Csr, 1,
124 );
125
126 build_register_view!(
128 CsrRw, CsrState, CsrStatePerms, High ;
130 enabled: ReadWrite,
132 reserved: Reserved,
134 excepted: ReadVolatileOnly,
136 trigger: WriteOneCommits,
138 );
139
140 build_register_view!(
142 CsrRo, CsrState, CsrStatePerms, High ;
144 enabled: ReadOnly,
146 reserved: Reserved,
148 excepted: ReadVolatileOnly,
150 trigger: ReadOnly,
152 );
153
154 build_register_file!(
156 TestCsrsRw, TestCsrStates ;
158 Csr : 0x00, CsrRw, Csr,
159 );
160
161 build_register_file!(
163 TestCsrsRo, TestCsrStates ;
165 Csr : 0x10, CsrRo, Csr,
166 );
167
168 #[test]
169 fn basics() {
170 let resolver = TestResolver::new();
171 let csr_state = Rc::new(CsrState::new());
172
173 let csr_ro = CsrRoReg::new(csr_state.clone());
174 let csr_rw = CsrRwReg::new(csr_state);
175
176 assert_eq!(csr_ro.read(), CSR_RESET_VALUE);
177 assert_eq!(csr_rw.read(), CSR_RESET_VALUE);
178
179 csr_ro.write(&resolver, 0xffff_ffff);
180 resolver.resolve();
181 assert_eq!(csr_ro.read(), CSR_RESET_VALUE);
182 assert_eq!(csr_rw.read(), CSR_RESET_VALUE);
183
184 csr_rw.write(&resolver, 0xffff_ffff);
185 resolver.resolve();
186 assert_eq!(csr_ro.read(), CSR_WRITE_VALUE);
187 assert_eq!(csr_rw.read(), CSR_WRITE_VALUE);
188 }
189
190 #[test]
191 fn reset() {
192 let resolver = TestResolver::new();
193 let csr_state = Rc::new(CsrState::new());
194 let csr_rw = CsrRwReg::new(csr_state);
195
196 csr_rw.write(&resolver, 0xffff);
197 assert_eq!(csr_rw.value(), CSR_RESET_VALUE);
198 resolver.resolve();
199 assert_eq!(csr_rw.value(), CSR_WRITE_VALUE);
200
201 csr_rw.reset_sync(&resolver);
203 assert_eq!(csr_rw.value(), CSR_WRITE_VALUE);
204
205 resolver.resolve();
206 assert_eq!(csr_rw.value(), CSR_RESET_VALUE);
207
208 csr_rw.write(&resolver, 0xffff);
210 resolver.resolve();
211 assert_eq!(csr_rw.value(), CSR_WRITE_VALUE);
212
213 csr_rw.reset_async();
214 assert_eq!(csr_rw.value(), CSR_RESET_VALUE);
215 }
216
217 #[test]
218 fn reg_file() {
219 let resolver = TestResolver::new();
220 let csr_states = TestCsrStates::new();
221 let csrs = TestCsrsRwRegs::new(&csr_states, 0);
222 assert_eq!(csrs.csr.value(), CSR_RESET_VALUE);
223
224 csrs.csr.write(&resolver, 0xffff);
225 assert_eq!(csrs.csr.value(), CSR_RESET_VALUE);
226
227 resolver.resolve();
228 assert_eq!(csrs.csr.value(), CSR_WRITE_VALUE);
229
230 csrs.reset_sync(&resolver);
231 assert_eq!(csrs.csr.value(), CSR_WRITE_VALUE);
232
233 resolver.resolve();
234 assert_eq!(csrs.csr.value(), CSR_RESET_VALUE);
235 }
236
237 #[test]
238 fn reg_file_by_index() {
239 const CSR_RW_INDEX: u64 = testcsrsrw_indices::CSR;
240 const CSR_RO_INDEX: u64 = testcsrsro_indices::CSR;
241
242 let resolver = TestResolver::new();
243 let csr_states = TestCsrStates::new();
244 let csrs_rw = TestCsrsRwRegs::new(&csr_states, 0);
245 let csrs_ro = TestCsrsRoRegs::new(&csr_states, 0);
246 assert_eq!(csrs_rw.csr.value(), CSR_RESET_VALUE);
247
248 csrs_rw.write(&resolver, testcsrsrw_indices::CSR, 0xffff);
249 assert_eq!(csrs_rw.csr.value(), CSR_RESET_VALUE);
250
251 resolver.resolve();
252 assert_eq!(csrs_rw.csr.value(), CSR_WRITE_VALUE);
253 assert_eq!(csrs_rw.read(CSR_RW_INDEX), CSR_WRITE_VALUE);
254 assert_eq!(csrs_ro.read(CSR_RO_INDEX), CSR_WRITE_VALUE);
255 }
256
257 #[test]
258 fn reserved_stays_on_set() {
259 let resolver = TestResolver::new();
260 let state = Rc::new(CsrState::new());
261 let reg = CsrRwReg::new(state);
262
263 assert_eq!(reg.value(), CSR_RESET_VALUE);
264
265 reg.set(&resolver, 0xffff_ffff);
266 assert_eq!(reg.value(), CSR_RESET_VALUE);
267
268 resolver.resolve();
269 assert_eq!(reg.value(), CSR_SET_VALUE);
270 }
271
272 #[test]
273 fn alias() {
274 let resolver = TestResolver::new();
275 let state = Rc::new(TestCsrStates::new());
276 let regs_ro = TestCsrsRoRegs::new(&state, 0);
277 let regs_rw = TestCsrsRwRegs::new(&state, 0);
278
279 assert_eq!(regs_ro.csr.value(), CSR_RESET_VALUE);
280 assert_eq!(regs_rw.csr.value(), CSR_RESET_VALUE);
281
282 regs_ro.csr.write(&resolver, 0xffff_ffff);
283 resolver.resolve();
284 assert_eq!(regs_ro.csr.value(), CSR_RESET_VALUE);
285 assert_eq!(regs_rw.csr.value(), CSR_RESET_VALUE);
286
287 regs_rw.csr.write(&resolver, 0xffff_ffff);
288 assert_eq!(regs_ro.csr.value(), CSR_RESET_VALUE);
289 assert_eq!(regs_rw.csr.value(), CSR_RESET_VALUE);
290
291 resolver.resolve();
292 assert_eq!(regs_ro.csr.value(), CSR_WRITE_VALUE);
293 assert_eq!(regs_rw.csr.value(), CSR_WRITE_VALUE);
294
295 regs_ro.reset_sync(&resolver);
296 assert_eq!(regs_ro.csr.value(), CSR_WRITE_VALUE);
297 assert_eq!(regs_rw.csr.value(), CSR_WRITE_VALUE);
298
299 resolver.resolve();
300 assert_eq!(regs_ro.csr.value(), CSR_RESET_VALUE);
301 assert_eq!(regs_rw.csr.value(), CSR_RESET_VALUE);
302 }
303
304 #[test]
305 fn write_callback() {
306 let resolver = TestResolver::new();
307 let state = Rc::new(CsrState::new());
308 let mut reg: CsrRwReg = CsrRwReg::new(state);
309
310 let cb_handler = Rc::new(TestCallbackHandler::new());
311 reg.install_read_cb(cb_handler.clone());
312 reg.install_write_cb(cb_handler.clone());
313
314 reg.write(&resolver, 0xffff_ffff);
315 resolver.resolve();
316
317 assert_eq!(*cb_handler.read_count.borrow(), 0);
318 assert_eq!(*cb_handler.written_count.borrow(), 1);
319 }
320
321 #[test]
322 fn read_callback() {
323 let state = Rc::new(CsrState::new());
324 let mut reg = CsrRwReg::new(state);
325
326 let cb_handler = Rc::new(TestCallbackHandler::new());
327 reg.install_read_cb(cb_handler.clone());
328 reg.install_write_cb(cb_handler.clone());
329
330 let _ = reg.read();
331 assert_eq!(*cb_handler.read_count.borrow(), 1);
332 assert_eq!(*cb_handler.written_count.borrow(), 0);
333 }
334
335 #[test]
336 fn write_one_commit() {
337 let resolver = TestResolver::new();
340 let state = Rc::new(CsrState::new());
341 let mut reg: CsrRwReg = CsrRwReg::new(state);
342
343 let cb_handler = Rc::new(TestCallbackHandler::new());
344 reg.install_read_cb(cb_handler.clone());
345 reg.install_write_cb(cb_handler.clone());
346
347 reg.write(&resolver, 0xffff_ffff);
348 resolver.resolve();
349
350 assert_eq!(*cb_handler.read_count.borrow(), 0);
351 assert_eq!(*cb_handler.written_count.borrow(), 1);
352
353 assert_eq!(reg.read(), CSR_WRITE_VALUE);
354
355 let (old_value, written_value, new_value) = cb_handler.last_write.borrow().unwrap();
356
357 assert_eq!(old_value, CSR_RESET_VALUE);
358 assert_eq!(written_value, 0xffff_ffff);
359 assert_eq!(new_value, CSR_WRITE_VALUE);
360 }
361}