eeric_core/
rv_core.rs

1pub mod arbitrary_float;
2pub mod instruction;
3pub mod memory;
4pub mod registers;
5pub mod snapshot;
6pub mod vector_engine;
7
8use derive_builder::Builder;
9
10use instruction::{executor::Executor, Instruction};
11use memory::Memory;
12use registers::Registers;
13
14use self::vector_engine::VectorEngine;
15
16#[derive(Builder, Clone, PartialEq, Debug)]
17#[builder(build_fn(skip))]
18pub struct RvCore {
19    pub memory: Memory,
20    pub instructions: Vec<Instruction>,
21    #[builder(setter(skip))]
22    pub registers: Registers,
23    pub vec_engine: VectorEngine,
24}
25
26impl RvCore {
27    pub fn step(&mut self) -> Option<Result<(), String>> {
28        self.run().next()
29    }
30
31    pub fn run(&mut self) -> RunningRvCore<'_> {
32        RunningRvCore { core: self }
33    }
34}
35
36impl Default for RvCore {
37    fn default() -> Self {
38        let vec_engine = VectorEngine::default();
39        let memory = Memory::default();
40
41        Self {
42            instructions: Vec::new(),
43            registers: Registers::new(&vec_engine, &memory),
44            memory,
45            vec_engine,
46        }
47    }
48}
49
50impl RvCoreBuilder {
51    pub fn build(&self) -> RvCore {
52        let memory = self.memory.clone().unwrap_or_default();
53        let instructions = self.instructions.clone().unwrap_or_default();
54        let vec_engine = self.vec_engine.unwrap_or_default();
55        let registers = Registers::new(&vec_engine, &memory);
56
57        RvCore {
58            memory,
59            instructions,
60            vec_engine,
61            registers,
62        }
63    }
64}
65
66pub struct RunningRvCore<'core> {
67    core: &'core mut RvCore,
68}
69
70impl Iterator for RunningRvCore<'_> {
71    type Item = Result<(), String>;
72
73    fn next(&mut self) -> Option<Self::Item> {
74        let instruction_pointer = self.core.registers.pc / 4;
75        let instruction = self
76            .core
77            .instructions
78            .get(instruction_pointer as usize)?
79            .clone();
80
81        Some(
82            Executor::new(
83                &mut self.core.registers,
84                &mut self.core.memory,
85                &mut self.core.vec_engine,
86            )
87            .execute(instruction),
88        )
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use crate::rv_core::{
95        registers::aliases::{csr::VLENB, integer::SP},
96        snapshot::Snapshotable,
97        vector_engine::{VectorEngineBuilder, Vlen},
98    };
99
100    use super::*;
101
102    #[test]
103    fn default_has_vector_registers() {
104        let core = RvCore::default();
105        assert_eq!(
106            core.registers.snapshot().v.len(),
107            32 * Vlen::V128.byte_length()
108        );
109    }
110
111    #[test]
112    fn custom_vlen_works() {
113        use Instruction::*;
114
115        let core = RvCoreBuilder::default()
116            .instructions(vec![Vsetvli(instruction::format::Vsetvli {
117                rd: 5,
118                rs1: 12,
119                vtypei: 195,
120            })])
121            .vec_engine(VectorEngineBuilder::default().vlen(Vlen::V256).build())
122            .build();
123        assert_eq!(
124            core.registers.snapshot().v.len(),
125            32 * Vlen::V256.byte_length()
126        );
127    }
128
129    #[test]
130    fn vlenb_csr_works() {
131        let core = RvCoreBuilder::default()
132            .vec_engine(VectorEngineBuilder::default().vlen(Vlen::V256).build())
133            .build();
134        assert_eq!(
135            core.registers.snapshot().c[VLENB].read(),
136            Vlen::V256.byte_length() as u64
137        );
138    }
139
140    #[test]
141    fn sp_points_to_stack() {
142        let memory = Memory::new([5, 2, 1, 3, 4].into_iter());
143
144        let core = RvCoreBuilder::default().memory(memory).build();
145
146        assert_eq!(core.registers.snapshot().x[SP], 4);
147    }
148}