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 fn example_fn() -> ::machine_check::Bitvector<8> {
45 ::std::panic!("Example panic 1");
46 ::machine_check::Bitvector::<8>::new(0)
47 }
48 }
49
50 #[allow(unused_variables)]
51 impl ::machine_check::Machine for System {
52 type Input = Input;
53 type State = State;
54
55 fn init(&self, input: &Input) -> State {
56 State {}
57 }
58
59 #[allow(unreachable_code)]
60 fn next(&self, state: &State, input: &Input) -> State {
61 // Do not execute the following block.
62 if false {
63 // The example function can be called as an associated
64 // method, and would always panic (you can try it
65 // by changing the condition).
66 //
67 // Currently, it is necessary to assign the result
68 // to a variable. Since discovering the return type of other
69 // methods is not supported yet, its type must be explicitly
70 // specified.
71 let a: ::machine_check::Bitvector<8> = Self::example_fn();
72 }
73 // Panic if the input field panic_input is equal to 1.
74 if input.panic_input == Bitvector::<8>::new(1) {
75 // The first panic should win, i.e. "Example panic 2"
76 // inherent panic error should be returned when formally
77 // verifying with machine-check.
78 ::std::panic!("Example panic 2");
79 ::std::panic!("Example panic 3");
80 }
81 State {}
82 }
More examples
examples/recovery.rs (line 67)
64 fn init(&self, _input: &Input) -> State {
65 State {
66 max_value: Unsigned::<4>::new(0),
67 unused: Bitvector::<4>::new(0),
68 free_counter: Unsigned::<4>::new(0),
69 }
70 }
71
72 fn next(&self, state: &State, input: &Input) -> State {
73 let input_value = input.value;
74
75 // If the maximum value is smaller than the input value,
76 // update it to the input value.
77 let mut next_max = state.max_value;
78 if next_max < input_value {
79 next_max = input_value;
80 }
81 // If the reset input is asserted and it is actually enabled in the system,
82 // reset the maximum value to zero.
83 if (input.reset & self.enable_reset) == Bitvector::<1>::new(1) {
84 next_max = Unsigned::<4>::new(0);
85 }
86
87 // Increment the free-running counter. It will wrap around eventually.
88 let free_counter = state.free_counter + Unsigned::<4>::new(1);
89 State {
90 max_value: next_max,
91 unused: input.unused,
92 free_counter,
93 }
94 }
95 }
96}
97
98#[derive(Args)]
99struct SystemArgs {
100 #[arg(long = "system-enable-reset")]
101 enable_reset: bool,
102}
103
104fn main() {
105 let (run_args, system_args) = machine_check::parse_args::<SystemArgs>(std::env::args());
106 if system_args.enable_reset {
107 println!("Reset input is enabled");
108 } else {
109 println!("Reset input is disabled");
110 }
111 let enable_reset = Bitvector::<1>::new(system_args.enable_reset as u64);
112 machine_check::execute(machine_module::System { enable_reset }, run_args);
113}
examples/simple_risc.rs (line 69)
65 fn init(&self, input: &Input) -> State {
66 // Only initialize Program Counter to 0 at reset.
67 // Leave working registers and data uninitialized.
68 State {
69 pc: Bitvector::<7>::new(0),
70 reg: Clone::clone(&input.uninit_reg),
71 data: Clone::clone(&input.uninit_data),
72 }
73 }
74 fn next(&self, state: &State, input: &Input) -> State {
75 // Fetch the instruction to execute from program memory.
76 let instruction = self.progmem[state.pc];
77 // Increment the program counter.
78 let mut pc = state.pc + Bitvector::<7>::new(1);
79 // Clone registers and data.
80 let mut reg = Clone::clone(&state.reg);
81 let mut data = Clone::clone(&state.data);
82
83 // Perform instruction-specific behaviour.
84 ::machine_check::bitmask_switch!(instruction {
85 "00dd_00--_aabb" => { // add
86 reg[d] = reg[a] + reg[b];
87 }
88 "00dd_01--_gggg" => { // read input
89 reg[d] = input.gpio_read[g];
90 }
91 "00rr_1kkk_kkkk" => { // jump if bit 0 is set
92 if reg[r] & Bitvector::<8>::new(1)
93 == Bitvector::<8>::new(1) {
94 pc = k;
95 };
96 }
97 "01dd_kkkk_kkkk" => { // load immediate
98 reg[d] = k;
99 }
100 "10dd_nnnn_nnnn" => { // load direct
101 reg[d] = data[n];
102 }
103 "11ss_nnnn_nnnn" => { // store direct
104 data[n] = reg[s];
105 }
106 });
107
108 // Return the state.
109 State { pc, reg, data }
110 }
111 }
112}
113
114use machine_check::{Bitvector, BitvectorArray};
115
116fn main() {
117 let toy_program = [
118 // (0) set r0 to zero
119 Bitvector::new(0b0100_0000_0000),
120 // (1) set r1 to one
121 Bitvector::new(0b0101_0000_0001),
122 // (2) set r2 to zero
123 Bitvector::new(0b0110_0000_0000),
124 // --- main loop ---
125 // (3) store r1 content to data location 0
126 Bitvector::new(0b1100_0000_0000),
127 // (4) store r2 content to data location 1
128 Bitvector::new(0b1100_0000_0001),
129 // (5) read input location 0 to r3
130 Bitvector::new(0b0011_0100_0000),
131 // (6) jump to (3) if r3 bit 0 is set
132 Bitvector::new(0b0011_1000_0011),
133 // (7) increment r2
134 Bitvector::new(0b0010_0000_1001),
135 // (8) store r2 content to data location 1
136 Bitvector::new(0b1110_0000_0001),
137 // (9) jump to (3)
138 Bitvector::new(0b0001_1000_0011),
139 ];
140
141 // load toy program to program memory, filling unused locations with 0
142 let mut progmem = BitvectorArray::new_filled(Bitvector::new(0));
143 for (index, instruction) in toy_program.into_iter().enumerate() {
144 progmem[Bitvector::new(index as u64)] = instruction;
145 }
146 let system = machine_module::System { progmem };
147 machine_check::run(system);
148}
Trait Implementations§
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> Freeze for Bitvector<L>
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<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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.