Struct machine_check::Bitvector
source · 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>
impl<const L: u32> Bitvector<L>
sourcepub fn new(value: u64) -> Self
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
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> PartialEq for Bitvector<L>
impl<const L: u32> PartialEq for Bitvector<L>
impl<const L: u32> Copy for Bitvector<L>
impl<const L: u32> Eq for Bitvector<L>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to
key
and return true
if they are equal.