Пример #1
0
def jump(clock, write, address, data_in):
    """
    allows manipulation of the PC

    address  read  write
    0        PC    PC
    1        PC    dest
    2        PC    if 0: dest -> PC
    3        PC    if !0: dest -> PC
    """

    assert len(address) >= 2
    address = address[:2]

    control_lines = address_decode(address)

    # a destination register for conditional jumps
    write_dest = And(clock, write, control_lines[1])
    dest = register(data_in, write_dest)

    # are we jumping and if so where
    jump_if_zero = And(control_lines[2], Not(Or(*data_in)))
    jump_if_not_zero = And(control_lines[3], Or(*data_in))
    conditional_jump = Or(jump_if_zero, jump_if_not_zero)
    unconditional_jump = control_lines[0]
    write_pc = And(write, Or(conditional_jump, unconditional_jump))
    pc_out = word_switch([conditional_jump, unconditional_jump], dest, data_in)

    return dest, pc_out, write_pc
Пример #2
0
def cpu_core(clock, data_in, pc_in, write_pc, debug=False):
    """
    the core CPU state machine
    executes a 4 state loop continuously
    s0: fetch address from pc
    s1: fetch value from address and increment pc
    s2: fetch address from pc
    s3: store value to address and increment pc
    """

    network = clock.network
    word_size = len(data_in)

    # step through the 4 states in order
    state = PlaceholderWord(network, 2)
    incr, c = ripple_incr(state)
    state.replace(register(incr, clock))
    s0, s1, s2, s3 = address_decode(state)

    # pc increments in s1 and s3, incoming pc writes from the jump module are taken in s3
    pc = PlaceholderWord(network, word_size)
    incr, c = ripple_incr(pc)
    jumping = And(write_pc, s3)
    new_pc = word_mux([jumping], incr, pc_in)
    clock_pc = And(clock, Or(s1, s3))
    pc.replace(register(new_pc, clock_pc))

    # clock in address in s0 and s2
    addr = register(data_in, And(clock, Or(s0, s2)))

    # set address lines to pc in s0 and s2 and to the previously fetched address in s1 and s3
    addr_out = word_switch([Or(s0, s2), Or(s1, s3)], pc, addr)

    # read in data in s1
    data = register(data_in, And(clock, s1))

    # write out data in s3
    write_out = s3
    data_out = data

    if debug:
        clock.watch('clock')
        s0.watch('s0')
        s1.watch('s1')
        s2.watch('s2')
        s3.watch('s3')
        jumping.watch('jumping')
        clock_pc.watch('clock pc')
        write_out.watch('write out')

    return addr_out, data_out, write_out
Пример #3
0
def full_subtractor(a, b, c):
    """
    chain two half subtractors to subtract bit B and previous borrow from A, again returning a difference and a borrow
    """
    s1, c1 = half_subtractor(a, b)
    s2, c2 = half_subtractor(s1, c)
    return s2, Or(c1, c2)
Пример #4
0
def shuffle_right(word, amount):
    """ shuffle a word right (x2) adding 0's to the left """
    network = word[0].network
    res = [Tie(network, False) for i in range(amount)] + word
    if amount:
        carry = Or(*res[len(word):])
    else:
        carry = Tie(network, False)
    return res[:len(word)], carry
Пример #5
0
def ripple_sum(*words):
    """ sum multiple words """
    carries = []
    # iterate building layers of a binary tree structure
    while len(words) > 1:
        new_words = []
        # add every adjacent pair, so 1+2, 3+4 etc
        for a, b in zip(words[::2], words[1::2]):
            res, carry = ripple_adder(a, b)
            carries.append(carry)
            new_words.append(res)
        # if there is one left at the end just keep it in the next level up
        if len(words) % 2:
            new_words.append(words[-1])
        words = new_words
    return words[0], Or(*carries)
Пример #6
0
def bit_switch(control_lines_, *data_):
    """ select the bit(s) from the data that match the enabled control line(s) (generally only 1) """
    assert len(control_lines_) >= len(data_)
    return Or(*[Nor(c_, d_) for c_, d_ in zip(control_lines_, data_)])
Пример #7
0
def half_subtractor(a, b):
    """ subtract bit B from bit A, return a difference and a borrow """
    borrow = And(Not(a), b)
    result = Or(And(a, Not(b)), And(Not(a), b))
    return result, borrow
Пример #8
0
def full_adder(a, b, c):
    """ chain two half adders to add two bits and a previous carry, again returning a sum and a carry """
    s1, c1 = half_adder(a, b)
    s2, c2 = half_adder(s1, c)
    return s2, Or(c1, c2)