Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
217 lines (194 sloc) 8.96 KB
not(a) = nand(a, a)
and(a, b) = not(nand(a, b))
or(a, b) = nand(not(a), not(b))
xor(a, b) = or(and(a, not(b)), and(not(a), b))
add1(a, b) = and(a, b), xor(a, b)
or3(a, b, c) = or(a, or(b, c))
xor3(a, b, c) = xor(a, xor(b, c))
add(a, b, c) = or3(and(a, b), and(b, c), and(a, c)), xor3(a, b, c)
def add2bits(a1, a0, b1, b0, c) -> twos_high, twos_low, unit_low:
unit_high, unit_low = add(a0, b0, c)
twos_high, twos_low = add(a1, b1, unit_high)
select(sel, d1, d0) = or(and(sel, d1), and(not(sel), d0))
def latch(store_mode, value) -> out:
out = select(store_mode, value, out)
flip_flop(store_mode, value, clock) =
latch(clock, latch(and(store_mode, not(clock)), value))
def register16(store_mode, bits, clock) -> out:
bit15, bit14, bit13, bit12, bit11, bit10, bit9, bit8, bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0 = unpack(bits)
out = pack(out15, out14, out13, out12, out11, out10, out9, out8, out7, out6, out5, out4, out3, out2, out1, out0)
out0 = flip_flop(store_mode, bit0, clock)
out1 = flip_flop(store_mode, bit1, clock)
out2 = flip_flop(store_mode, bit2, clock)
out3 = flip_flop(store_mode, bit3, clock)
out4 = flip_flop(store_mode, bit4, clock)
out5 = flip_flop(store_mode, bit5, clock)
out6 = flip_flop(store_mode, bit6, clock)
out7 = flip_flop(store_mode, bit7, clock)
out8 = flip_flop(store_mode, bit8, clock)
out9 = flip_flop(store_mode, bit9, clock)
out10 = flip_flop(store_mode, bit10, clock)
out11 = flip_flop(store_mode, bit11, clock)
out12 = flip_flop(store_mode, bit12, clock)
out13 = flip_flop(store_mode, bit13, clock)
out14 = flip_flop(store_mode, bit14, clock)
out15 = flip_flop(store_mode, bit15, clock)
def not16(bits) -> out:
bit15, bit14, bit13, bit12, bit11, bit10, bit9, bit8, bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0 = unpack(bits)
out = pack(out15, out14, out13, out12, out11, out10, out9, out8, out7, out6, out5, out4, out3, out2, out1, out0)
out0 = not(bit0)
out1 = not(bit1)
out2 = not(bit2)
out3 = not(bit3)
out4 = not(bit4)
out5 = not(bit5)
out6 = not(bit6)
out7 = not(bit7)
out8 = not(bit8)
out9 = not(bit9)
out10 = not(bit10)
out11 = not(bit11)
out12 = not(bit12)
out13 = not(bit13)
out14 = not(bit14)
out15 = not(bit15)
def and16(as, bs) -> out:
a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0 = unpack(as)
b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0 = unpack(bs)
out = pack(out15, out14, out13, out12, out11, out10, out9, out8, out7, out6, out5, out4, out3, out2, out1, out0)
out0 = and(a0, b0)
out1 = and(a1, b1)
out2 = and(a2, b2)
out3 = and(a3, b3)
out4 = and(a4, b4)
out5 = and(a5, b5)
out6 = and(a6, b6)
out7 = and(a7, b7)
out8 = and(a8, b8)
out9 = and(a9, b9)
out10 = and(a10, b10)
out11 = and(a11, b11)
out12 = and(a12, b12)
out13 = and(a13, b13)
out14 = and(a14, b14)
out15 = and(a15, b15)
def or16(bits) -> out15:
bit15, bit14, bit13, bit12, bit11, bit10, bit9, bit8, bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0 = unpack(bits)
out1 = or(bit1, bit0)
out2 = or(out1, bit2)
out3 = or(out2, bit3)
out4 = or(out3, bit4)
out5 = or(out4, bit5)
out6 = or(out5, bit6)
out7 = or(out6, bit7)
out8 = or(out7, bit8)
out9 = or(out8, bit9)
out10 = or(out9, bit10)
out11 = or(out10, bit11)
out12 = or(out11, bit12)
out13 = or(out12, bit13)
out14 = or(out13, bit14)
out15 = or(out14, bit15)
out16 = or(out15, bit16)
def add16(as, bs) -> out:
a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0 = unpack(as)
b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0 = unpack(bs)
out = pack(out15, out14, out13, out12, out11, out10, out9, out8, out7, out6, out5, out4, out3, out2, out1, out0)
carry1, out0 = add1(a0, b0)
carry2, out1 = add(carry1, a1, b1)
carry3, out2 = add(carry2, a2, b2)
carry4, out3 = add(carry3, a3, b3)
carry5, out4 = add(carry4, a4, b4)
carry6, out5 = add(carry5, a5, b5)
carry7, out6 = add(carry6, a6, b6)
carry8, out7 = add(carry7, a7, b7)
carry9, out8 = add(carry8, a8, b8)
carry10, out9 = add(carry9, a9, b9)
carry11, out10 = add(carry10, a10, b10)
carry12, out11 = add(carry11, a11, b11)
carry13, out12 = add(carry12, a12, b12)
carry14, out13 = add(carry13, a13, b13)
carry15, out14 = add(carry14, a14, b14)
carry16, out15 = add(carry15, a15, b15)
def select16(sel, ones, zeros) -> out:
one15, one14, one13, one12, one11, one10, one9, one8, one7, one6, one5, one4, one3, one2, one1, one0 = unpack(ones)
zero15, zero14, zero13, zero12, zero11, zero10, zero9, zero8, zero7, zero6, zero5, zero4, zero3, zero2, zero1, zero0 = unpack(zeros)
out = pack(out15, out14, out13, out12, out11, out10, out9, out8, out7, out6, out5, out4, out3, out2, out1, out0)
out0 = select(sel, one0, zero0)
out1 = select(sel, one1, zero1)
out2 = select(sel, one2, zero2)
out3 = select(sel, one3, zero3)
out4 = select(sel, one4, zero4)
out5 = select(sel, one5, zero5)
out6 = select(sel, one6, zero6)
out7 = select(sel, one7, zero7)
out8 = select(sel, one8, zero8)
out9 = select(sel, one9, zero9)
out10 = select(sel, one10, zero10)
out11 = select(sel, one11, zero11)
out12 = select(sel, one12, zero12)
out13 = select(sel, one13, zero13)
out14 = select(sel, one14, zero14)
out15 = select(sel, one15, zero15)
def is_negative(bits) -> bit15:
bit15, bit14, bit13, bit12, bit11, bit10, bit9, bit8, bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0 = unpack(bits)
def increment(x16) -> out:
minus1 = add16(x16, not16(x16))
out = add16(x16, not16(add16(minus1, minus1)))
def counter(store_mode, bits, clock) -> out:
stored_new_value = register16(not(clock), new_value, clock)
new_value = select16(store_mode, bits, increment(old_value))
old_value = register16(clock, stored_new_value, not(clock))
out = select16(clock, stored_new_value, old_value)
switch(sel, value) = and(sel, value), and(not(sel), value)
def RAM(address, store_mode, bits, clock) -> out:
reg1mode, reg0mode = switch(address, store_mode)
reg1 = register16(reg1mode, bits, clock)
reg0 = register16(reg0mode, bits, clock)
out = select16(address, reg1, reg0)
def sign_modifier(zero, neg, value) -> out:
zeroed = select16(zero, zero_16(zero), value)
out = select16(neg, not16(zeroed), zeroed)
is_zero16(bits) = not(or16(bits))
def ALU(opers, raw_x, raw_y) -> out:
zero_x, neg_x, zero_y, neg_y, oper, neg = unpack(opers)
x = sign_modifier(zero_x, neg_x, raw_x)
y = sign_modifier(zero_y, neg_y, raw_y)
result = select16(oper, add16(x, y), and16(x, y))
out = select16(neg, not16(result), result)
def compare_to_zero(comparator, x) -> out:
lt, eq, gt = unpack3(comparator)
x_zero = is_zero16(x)
x_neg = is_negative(x)
x_pos = and(not(x_zero), not(x_neg))
out = or3(and(lt, x_neg), and(eq, x_zero), and(gt, x_pos))
def storage(write_destination, value, clock) -> address_reg, data_reg, ram:
write_address, write_data, write_ram = unpack(write_destination)
address_reg = register16(write_address, value, clock)
data_reg = register16(write_data, value, clock)
address_reg15, address_reg14, address_reg13, address_reg12, address_reg11, address_reg10, address_reg9, address_reg8, address_reg7, address_reg6, address_reg5, address_reg4, address_reg3, address_reg2, address_reg1, address_reg0 = unpack(address_reg)
ram = RAM(write_ram, address_reg0, value, clock)
def instruction_decoder(instr) -> out:
aux15, aux14, aux13, aux12, aux11, aux10, aux9, aux8, aux7, aux6, aux5, aux4, aux3, aux2, aux1, aux0 = unpack(aux)
instr15, instr14, instr13, instr12, instr11, instr10, instr9, instr8, instr7, instr6, instr5, instr4, instr3, instr2, instr1, instr0 = unpack(instr)
is_comp = id(instr15)
aux = select16(is_comp, instr, zero_16(is_comp))
data = select16(is_comp, zero_16(is_comp), instr)
out = pack6(is_comp, aux12, pack6(aux11, aux10, aux9, aux8, aux7, aux6),
pack3(aux5, or(not(is_comp), aux4), aux3),
pack3(aux2, aux1, aux0),
data)
def control_unit(instr, clock) -> need_to_jump, address_reg:
is_comp, alu_operand, ALU_opers, write_destination, comparator, value = unpack6(instruction_decoder(instr))
need_to_jump = compare_to_zero(comparator, alu_output)
y = select16(alu_operand, address_reg, ram_at_addr)
alu_output = ALU(ALU_opers, data_reg, y)
ram_input = select16(is_comp, alu_output, value)
address_reg, data_reg, ram_at_addr = storage(write_destination, ram_input, clock)
rom(address) = RAM(address, zero_1(address), zero_16(address), zero_1(address))
program_engine(need_to_jump, address_reg, clock) =
manual_rom(counter(need_to_jump, address_reg, clock))
# Don't need any output actually
def CPU(clock) -> instr:
instr = program_engine(need_to_jump, address_reg, clock)
need_to_jump, address_reg = control_unit(instr, clock)