pub struct Bitvector<const L: u32>(/* private fields */);
Expand description

Bitvector without signedness information.

The number of bits is specified in the generic parameter L. Bitvectors support bitwise operations and wrapping-arithmetic operations. Only operations where the behaviour of signed and unsigned numbers match are implemented. For others, conversion into Unsigned or Signed is necessary. Bit-extension is not possible directly, as signed and unsigned bitvectors are extended differently.

Implementations§

source§

impl<const L: u32> Bitvector<L>

source

pub fn new(value: u64) -> Self

Creates a new bitvector with the given value. Panics if the value does not fit into the type.

Examples found in repository?
examples/conditional_panic.rs (line 46)
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
        fn example_fn() -> ::machine_check::Bitvector<8> {
            ::std::panic!("Example panic 1");
            ::machine_check::Bitvector::<8>::new(0)
        }
    }

    #[allow(unused_variables)]
    impl ::machine_check::Machine for System {
        type Input = Input;
        type State = State;

        fn init(&self, input: &Input) -> State {
            State {}
        }

        #[allow(unreachable_code)]
        fn next(&self, state: &State, input: &Input) -> State {
            // Do not execute the following block.
            if false {
                // The example function can be called as an associated
                // method, and would always panic (you can try it
                // by changing the condition).
                //
                // Currently, it is necessary to assign the result
                // to a variable. Since discovering the return type of other
                // methods is not supported yet, its type must be explicitly
                // specified.
                let a: ::machine_check::Bitvector<8> = Self::example_fn();
            }
            // Panic if the input field panic_input is equal to 1.
            if input.panic_input == Bitvector::<8>::new(1) {
                // The first panic should win, i.e. "Example panic 2"
                // inherent panic error should be returned when formally
                // verifying with machine-check.
                ::std::panic!("Example panic 2");
                ::std::panic!("Example panic 3");
            }
            State {}
        }
More examples
Hide additional examples
examples/simple_risc.rs (line 67)
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
        fn init(&self, input: &Input) -> State {
            // Only initialize Program Counter to 0 at reset.
            // Leave working registers and data uninitialized.
            State {
                pc: Bitvector::<7>::new(0),
                reg: Clone::clone(&input.uninit_reg),
                data: Clone::clone(&input.uninit_data),
            }
        }
        fn next(&self, state: &State, input: &Input) -> State {
            // Fetch the instruction to execute from program memory.
            let instruction = self.progmem[state.pc];
            // Increment the program counter.
            let mut pc = state.pc + Bitvector::<7>::new(1);
            // Clone registers and data.
            let mut reg = Clone::clone(&state.reg);
            let mut data = Clone::clone(&state.data);

            // Perform instruction-specific behaviour.
            ::machine_check::bitmask_switch!(instruction {
                "00dd_00--_aabb" => { // add
                    reg[d] = reg[a] + reg[b];
                }
                "00dd_01--_gggg" => { // read input
                    reg[d] = input.gpio_read[g];
                }
                "00rr_1kkk_kkkk" => { // jump if bit 0 is set
                    if reg[r] & Bitvector::<8>::new(1)
                        == Bitvector::<8>::new(1) {
                        pc = k;
                    };
                }
                "01dd_kkkk_kkkk" => { // load immediate
                    reg[d] = k;
                }
                "10dd_nnnn_nnnn" => { // load direct
                    reg[d] = data[n];
                }
                "11ss_nnnn_nnnn" => { // store direct
                    data[n] = reg[s];
                }
            });

            // Return the state.
            State { pc, reg, data }
        }
    }
}

use machine_check::{Bitvector, BitvectorArray};

fn main() {
    let toy_program = [
        // (0) set r0 to zero
        Bitvector::new(0b0100_0000_0000),
        // (1) set r1 to one
        Bitvector::new(0b0101_0000_0001),
        // (2) set r2 to zero
        Bitvector::new(0b0110_0000_0000),
        // --- main loop ---
        // (3) store r1 content to data location 0
        Bitvector::new(0b1100_0000_0000),
        // (4) store r2 content to data location 1
        Bitvector::new(0b1100_0000_0001),
        // (5) read input location 0 to r3
        Bitvector::new(0b0011_0100_0000),
        // (6) jump to (3) if r3 bit 0 is set
        Bitvector::new(0b0011_1000_0011),
        // (7) increment r2
        Bitvector::new(0b0010_0000_1001),
        // (8) store r2 content to data location 1
        Bitvector::new(0b1110_0000_0001),
        // (9) jump to (3)
        Bitvector::new(0b0001_1000_0011),
    ];

    // load toy program to program memory, filling unused locations with 0
    let mut progmem = BitvectorArray::new_filled(Bitvector::new(0));
    for (index, instruction) in toy_program.into_iter().enumerate() {
        progmem[Bitvector::new(index as u64)] = instruction;
    }
    let system = machine_module::System { progmem };
    machine_check::run(system);
}

Trait Implementations§

source§

impl<const L: u32> Add for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the + operator.
source§

fn add(self, rhs: Bitvector<L>) -> Self::Output

Performs the + operation. Read more
source§

impl<const L: u32> BitAnd for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the & operator.
source§

fn bitand(self, rhs: Bitvector<L>) -> Self::Output

Performs the & operation. Read more
source§

impl<const L: u32> BitOr for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the | operator.
source§

fn bitor(self, rhs: Bitvector<L>) -> Self::Output

Performs the | operation. Read more
source§

impl<const L: u32> BitXor for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the ^ operator.
source§

fn bitxor(self, rhs: Bitvector<L>) -> Self::Output

Performs the ^ operation. Read more
source§

impl<const L: u32> Clone for Bitvector<L>

source§

fn clone(&self) -> Bitvector<L>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<const L: u32> Debug for Bitvector<L>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<const L: u32> From<Bitvector<L>> for Signed<L>

source§

fn from(value: Bitvector<L>) -> Self

Converts to this type from the input type.
source§

impl<const L: u32> From<Bitvector<L>> for Unsigned<L>

source§

fn from(value: Bitvector<L>) -> Self

Converts to this type from the input type.
source§

impl<const L: u32> From<Signed<L>> for Bitvector<L>

source§

fn from(value: Signed<L>) -> Self

Converts to this type from the input type.
source§

impl<const L: u32> From<Unsigned<L>> for Bitvector<L>

source§

fn from(value: Unsigned<L>) -> Self

Converts to this type from the input type.
source§

impl<const L: u32> Hash for Bitvector<L>

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<const I: u32, const L: u32> Index<Bitvector<I>> for BitvectorArray<I, L>

§

type Output = Bitvector<L>

The returned type after indexing.
source§

fn index(&self, index: Bitvector<I>) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
source§

impl<const I: u32, const L: u32> IndexMut<Bitvector<I>> for BitvectorArray<I, L>

source§

fn index_mut(&mut self, index: Bitvector<I>) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
source§

impl<const L: u32> Mul for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: Bitvector<L>) -> Self::Output

Performs the * operation. Read more
source§

impl<const L: u32> Not for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the ! operator.
source§

fn not(self) -> Self::Output

Performs the unary ! operation. Read more
source§

impl<const L: u32> PartialEq for Bitvector<L>

source§

fn eq(&self, other: &Bitvector<L>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<const L: u32> Shl for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the << operator.
source§

fn shl(self, rhs: Bitvector<L>) -> Self::Output

Performs the << operation. Read more
source§

impl<const L: u32> Sub for Bitvector<L>

§

type Output = Bitvector<L>

The resulting type after applying the - operator.
source§

fn sub(self, rhs: Bitvector<L>) -> Self::Output

Performs the - operation. Read more
source§

impl<const L: u32> Copy for Bitvector<L>

source§

impl<const L: u32> Eq for Bitvector<L>

source§

impl<const L: u32> StructuralPartialEq for Bitvector<L>

Auto Trait Implementations§

§

impl<const L: u32> RefUnwindSafe for Bitvector<L>

§

impl<const L: u32> Send for Bitvector<L>

§

impl<const L: u32> Sync for Bitvector<L>

§

impl<const L: u32> Unpin for Bitvector<L>

§

impl<const L: u32> UnwindSafe for Bitvector<L>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.