def bit(in_: bool, load: bool): nonlocal state not_load = nand(load, load) nand_1 = nand(in_, load) nand_2 = nand(not_load, state) state = nand(nand_1, nand_2) return state
def half_adder(a: bool, b: bool) -> (bool, bool): """Returns a + b in the form of a tuple of two bools representing the two bits.""" nand_a_b = nand(a, b) nand_c = nand(nand_a_b, a) nand_d = nand(nand_a_b, b) high = nand(nand_a_b, nand_a_b) low = nand(nand_c, nand_d) return high, low
def latch(store: bool, d: bool) -> bool: """If store is True, the latch output will be set to d, otherwise the previous output will be returned""" nonlocal state not_st = nand(store, store) nand_1 = nand(store, d) nand_2 = nand(not_st, state) state = nand(nand_1, nand_2) return state
def demux(selector: bool, in_: bool) -> (bool, bool): """Demultiplexer: Returns pairs of bools (a, b) based on selector. If selector is True, a will equal the input. If selector is False, b will equal the input. The non-selected output will always be false.""" not_selector = nand(selector, selector) nand_not_s_in = nand(not_selector, in_) nand_s_in = nand(selector, in_) a = nand(nand_s_in, nand_s_in) b = nand(nand_not_s_in, nand_not_s_in) return a, b
def full_adder(a: bool, b: bool, c: bool) -> (bool, bool): """Returns a + b + c in the form of a tuple of two bools representing the two bits. Carried value is ignored. """ nand_a_b = nand(a, b) nand_c = nand(nand_a_b, a) nand_d = nand(nand_a_b, b) low_a_b = nand(nand_c, nand_d) nand_low_a_b_c = nand(low_a_b, c) nand_e = nand(low_a_b, nand_low_a_b_c) nand_f = nand(nand_low_a_b_c, c) high = nand(nand_a_b, nand_low_a_b_c) low = nand(nand_e, nand_f) return high, low
def dff(load: bool, in_: bool, clock: bool) -> bool: """A Data Flip-Flop component which stores and outputs a bit. The output only changes to the stored value when the clock changes from False to True. The stored value only changes when store is True. When clock is True, the store and d value do not change anything. """ nonlocal state_1, state_2 not_cl = nand(clock, clock) nand_1 = nand(load, not_cl) not_nand_1 = nand(nand_1, nand_1) nand_2 = nand(not_nand_1, in_) nand_3 = nand(nand_1, state_1) state_1 = nand(nand_2, nand_3) nand_5 = nand(clock, state_1) nand_6 = nand(not_cl, state_2) state_2 = nand(nand_5, nand_6) return state_2
def equal_to_zero(in_: Bool16) -> bool: """Returns True if in_ is equal to 0.""" # Reduce to 8 or_01 = or_(in_[0], in_[1]) or_23 = or_(in_[2], in_[3]) or_45 = or_(in_[4], in_[5]) or_67 = or_(in_[6], in_[7]) or_89 = or_(in_[8], in_[9]) or_1011 = or_(in_[10], in_[11]) or_1213 = or_(in_[12], in_[13]) or_1415 = or_(in_[14], in_[15]) # Reduce to 4 or_0123 = or_(or_01, or_23) or_4567 = or_(or_45, or_67) or_891011 = or_(or_89, or_1011) or_12131415 = or_(or_1213, or_1415) # Reduce to 2 or_01234567 = or_(or_0123, or_4567) or_89101112131415 = or_(or_891011, or_12131415) # Reduce to 1 or_result = or_(or_01234567, or_89101112131415) # Return inverse return nand(or_result, or_result)
def test_nand(self): for a, b in self.test_pairs: self.assertEqual(nand(a, b), not (a and b))
def mux(selector: bool, a: bool, b: bool) -> bool: """Multiplexer: returns a if selector is True, otherwise returns b.""" not_selector = nand(selector, selector) nand_s_a = nand(selector, a) nand_not_s_b = nand(not_selector, b) return nand(nand_s_a, nand_not_s_b)
def not_(a: bool) -> bool: """Return not a.""" return nand(a, a)
def xor_(a: bool, b: bool) -> bool: """Return a xor b.""" nand_a_b = nand(a, b) nand_c = nand(nand_a_b, a) nand_d = nand(nand_a_b, b) return nand(nand_c, nand_d)
def or_(a: bool, b: bool) -> bool: """Return a or b.""" not_a = nand(a, a) not_b = nand(b, b) return nand(not_a, not_b)
def and_(a: bool, b: bool) -> bool: """Return a and b.""" nand_a_b = nand(a, b) return nand(nand_a_b, nand_a_b)