Last active
February 14, 2018 20:58
-
-
Save Badel2/90439adeb63b9682e3d0f012f63b5abe to your computer and use it in GitHub Desktop.
Implementing an OR gate from NAND gates https://badel2.github.io/comphdl-01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code)] | |
#[derive(Debug, Copy, Clone, PartialEq)] | |
enum Bit { | |
L, // Low, false, 0 | |
H, // High, true, 1 | |
} | |
trait Component { | |
fn update(&mut self, input: &[Bit]) -> Vec<Bit>; | |
} | |
fn nand2(a: Bit, b: Bit) -> Bit { | |
match (a, b) { | |
(Bit::L, Bit::L) => Bit::H, | |
(Bit::L, Bit::H) => Bit::H, | |
(Bit::H, Bit::L) => Bit::H, | |
(Bit::H, Bit::H) => Bit::L, | |
} | |
} | |
fn nandn(x: &[Bit]) -> Bit { | |
match x.len() { | |
0 => panic!("Empty input"), | |
1 => nand2(x[0], x[0]), | |
2 => nand2(x[0], x[1]), | |
n => nand2(x[n-1], nandn(&x[0..n-1])), | |
} | |
} | |
#[derive(Debug, Copy, Clone)] | |
struct Nand { | |
num_inputs: usize, | |
} | |
impl Nand { | |
fn new(num_inputs: usize) -> Nand { | |
Nand { num_inputs } | |
} | |
} | |
impl Component for Nand { | |
fn update(&mut self, input: &[Bit]) -> Vec<Bit> { | |
assert_eq!(self.num_inputs, input.len()); | |
if input.iter().any(|&a| a == Bit::L) { | |
vec![Bit::H] | |
} else { | |
vec![Bit::L] | |
} | |
} | |
} | |
#[derive(Debug, Copy, Clone)] | |
struct Or2 { | |
nand_a: Nand, | |
nand_b: Nand, | |
nand_c: Nand, | |
} | |
impl Or2 { | |
fn new() -> Or2 { | |
Or2 { | |
nand_a: Nand::new(1), | |
nand_b: Nand::new(1), | |
nand_c: Nand::new(2), | |
} | |
} | |
} | |
impl Component for Or2 { | |
fn update(&mut self, input: &[Bit]) -> Vec<Bit> { | |
assert_eq!(input.len(), 2); | |
let a = input[0]; | |
let b = input[1]; | |
let not_a = self.nand_a.update(&[a])[0]; | |
let not_b = self.nand_b.update(&[b])[0]; | |
// not_a nand not_b == not (not_a or not_b) == a or b | |
self.nand_c.update(&[not_a, not_b]) | |
} | |
} | |
fn main(){ | |
let mut or_gate = Or2::new(); | |
// Truth table | |
let mut i = vec![Bit::L, Bit::L]; | |
println!("{:?} = {:?}", i, or_gate.update(&i)); | |
i = vec![Bit::L, Bit::H]; | |
println!("{:?} = {:?}", i, or_gate.update(&i)); | |
i = vec![Bit::H, Bit::L]; | |
println!("{:?} = {:?}", i, or_gate.update(&i)); | |
i = vec![Bit::H, Bit::H]; | |
println!("{:?} = {:?}", i, or_gate.update(&i)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment