Skip to main content

ab_riscv_primitives/
hart.rs

1//! Hart configuration of an implementation
2
3#[cfg(test)]
4mod tests;
5
6use crate::instructions::v::{Elen, Vlen};
7use crate::registers::general_purpose::Register;
8use core::fmt;
9use core::marker::PhantomData;
10
11/// Vector lengths of an implementation with vector extensions
12#[derive(Debug, Clone, Copy)]
13#[derive_const(PartialEq, Eq)]
14pub struct VectorLengths {
15    /// Maximum vector element width `ELEN` in bits
16    pub mut(self) elen: Elen,
17    /// Vector register width `VLEN` in bits
18    pub mut(self) vlen: Vlen,
19}
20
21impl VectorLengths {
22    /// Create new vector lengths, returns `None` if `ELEN > VLEN`
23    #[inline(always)]
24    pub const fn new(elen: Elen, vlen: Vlen) -> Option<Self> {
25        if u32::from(elen) > u32::from(vlen) {
26            return None;
27        }
28        Some(Self { elen, vlen })
29    }
30}
31
32/// Hart configuration of an implementation that instruction enums are generic over.
33///
34/// It is implemented by marker types, describing properties of the implementation that
35/// instructions depend on, like the register type.
36pub const trait HartConfig: fmt::Debug + Copy + Eq + Send + Sync + 'static {
37    /// General purpose register type
38    type Reg: [const] Register;
39}
40
41/// Hart configuration of an implementation with vector extensions.
42///
43/// Vector instructions require it instead of [`HartConfig`].
44pub const trait VectorHartConfig: [const] HartConfig {
45    /// Vector lengths
46    const VECTOR_LENGTHS: VectorLengths;
47}
48
49/// Basic hart configuration with a given register type and no other properties
50#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub struct BasicHart<Reg>(PhantomData<Reg>);
52
53const impl<Reg> HartConfig for BasicHart<Reg>
54where
55    Reg: [const] Register,
56{
57    type Reg = Reg;
58}
59
60/// Basic hart configuration with a given register type and vector lengths
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub struct BasicVectorHart<Reg, const ELEN: Elen, const VLEN: Vlen>(PhantomData<Reg>);
63
64const impl<Reg, const ELEN: Elen, const VLEN: Vlen> HartConfig for BasicVectorHart<Reg, ELEN, VLEN>
65where
66    Reg: [const] Register,
67{
68    type Reg = Reg;
69}
70
71const impl<Reg, const ELEN: Elen, const VLEN: Vlen> VectorHartConfig
72    for BasicVectorHart<Reg, ELEN, VLEN>
73where
74    Reg: [const] Register,
75{
76    const VECTOR_LENGTHS: VectorLengths =
77        VectorLengths::new(ELEN, VLEN).expect("`ELEN` must be <= `VLEN`");
78}