opentitanlib/util/
bitfield.rs

1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5/// Represents a single field of bits within a u32 word.
6pub struct BitField {
7    /// Number of bits into the word that the field starts.
8    pub offset: u32,
9    /// Length in bits of the field.
10    pub size: u32,
11}
12
13impl BitField {
14    /// Create a new BitField with the given offset and length.
15    pub const fn new(offset: u32, size: u32) -> BitField {
16        BitField { offset, size }
17    }
18
19    /// Extract a value of this field from a word.
20    pub const fn extract(&self, word: u32) -> u32 {
21        (word & self.mask()) >> self.offset
22    }
23
24    /// Emplace a value into this field within a word.
25    pub const fn emplace(&self, value: u32) -> u32 {
26        (value << self.offset) & self.mask()
27    }
28
29    /// Returns the bit-mask of this bitfield.
30    pub const fn mask(&self) -> u32 {
31        let mask = (1 << self.size) - 1;
32        mask << self.offset
33    }
34}
35
36#[cfg(test)]
37mod test {
38    use super::*;
39
40    #[test]
41    fn basic() {
42        let bitfield = BitField { offset: 2, size: 3 };
43
44        assert_eq!(bitfield.mask(), 0b0011100);
45        assert_eq!(bitfield.extract(0b1110111), 0b101);
46        assert_eq!(bitfield.emplace(0b101), 0b0010100);
47    }
48}