Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
nand2cpu/program.txt
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
216 lines (194 sloc)
8.96 KB
This file contains 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
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) |