Skip to content

Instantly share code, notes, and snippets.

@Badel2
Last active February 14, 2018 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Badel2/90439adeb63b9682e3d0f012f63b5abe to your computer and use it in GitHub Desktop.
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
#![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