Example #1
0
def bench():
    opcode = Signal(alu_opcode_t.alu_add)
    operand_0 = Signal(data_bus(0))
    operand_1 = Signal(data_bus(0))
    result = Signal(data_bus(0))

    alu = ALU(opcode, operand_0, operand_1, result)

    @instance
    def stimulus():
        for i in range(100):
            for operator, compute_result in (
                (alu_opcode_t.alu_add, lambda a, b: a + b),
                (alu_opcode_t.alu_sub, lambda a, b: a - b),
                ):
                a = random.randrange(-2 ** 30, 2 ** 30)
                b = random.randrange(-2 ** 30, 2 ** 30)
                expect = compute_result(a, b)

                opcode.next = operator
                operand_0.next = data_bus(a)
                operand_1.next = data_bus(b)

                yield delay(10)

                assert result.signed() == expect

    return alu, stimulus
def bench(number_of_registers = 32, ram_from_file = False):

    def ClockDriver(clock, period = 100):
        @always(delay(period / 2))
        def drive_clock():
            clock.next = not clock

        return drive_clock

    clock = Signal(False)
    clock_driver = ClockDriver(clock)

    abus = Signal(data_bus(0))
    dbus = Signal(data_bus(0))
    data_in = Signal(data_bus(0))
    write_enabled = Signal(False)

    ram = Ram(
        clock,
        dbus, data_in,
        abus,
        write_enabled,
        from_file = ram_from_file,
    )

    processor = Processor(clock, dbus, abus)

    return clock_driver, ram, processor
    def logic():
        opcode.next = opcode_t.add
        operand_0.next = data_bus(1)
        operand_1.next = data_bus(1)

        update_select_a.next = 0
        update_value_a.next = 0
        update_select_b.next = 0
        update_value_b.next = 0
        write_enabled.next = False
        select_a.next = 0
        select_b.next = 0
def bench(number_of_registers = 32):
    update_select_a = Signal(intbv(min = 0, max = number_of_registers))
    update_value_a = Signal(data_bus(0))
    update_select_b = Signal(intbv(min = 0, max = number_of_registers))
    update_value_b = Signal(data_bus(0))
    write_enabled = Signal(False)

    select_a = Signal(intbv(min = 0, max = number_of_registers))
    result_a = Signal(data_bus(0))
    select_b = Signal(intbv(min = 0, max = number_of_registers))
    result_b = Signal(data_bus(0))

    clock = Signal(False)

    register_bank = RegisterBank(
        update_select_a, update_value_a,
        update_select_b, update_value_b,
        write_enabled,
        select_a, result_a,
        select_b, result_b,
        clock,
        number_of_registers,
    )

    @instance
    def stimulus():
        for i in range(number_of_registers):
            for v in range(100):
                update_select_a.next = i
                update_value_a.next = v
                update_select_b.next = i
                update_value_b.next = v
                write_enabled.next = True

                clock.next = True
                yield delay(10)
                clock.next = False
                yield delay(10)

                write_enabled.next = False
                select_a.next = i
                select_b.next = i

                clock.next = True
                yield delay(10)
                clock.next = False
                yield delay(10)

                assert result.signed() == v

    return register_bank, stimulus
Example #5
0
    def stimulus():
        for i in range(100):
            for operator, compute_result in (
                (alu_opcode_t.alu_add, lambda a, b: a + b),
                (alu_opcode_t.alu_sub, lambda a, b: a - b),
                ):
                a = random.randrange(-2 ** 30, 2 ** 30)
                b = random.randrange(-2 ** 30, 2 ** 30)
                expect = compute_result(a, b)

                opcode.next = operator
                operand_0.next = data_bus(a)
                operand_1.next = data_bus(b)

                yield delay(10)

                assert result.signed() == expect
Example #6
0
def bench(number_of_ram=128):

    address = Signal(intbv(min = 0, max = number_of_ram))
    data_in = Signal(data_bus(0))
    data_out = Signal(data_bus(0))
    write_enabled = Signal(False)
    clock = Signal(False)

    ram =  Ram(
        clock,
        data_out, data_in,
        address,
        write_enabled,
        number_of_ram,
    )

    @instance
    def stimulus():
        for i in range(number_of_ram):
            for v in range(100):

                write_enabled.next = True
                address.next = i
                data_in.next = v

                clock.next = True
                yield delay(10)
                clock.next = False
                yield delay(10)

                write_enabled.next = False 
                address.next = i

                clock.next = True
                yield delay(10)
                clock.next = False
                yield delay(10)
 
                result = data_out.next 

                assert result.signed() == v

    return ram, stimulus
def Processor(clock, dbus, abus):
    number_of_registers = 32

    alu_opcode = Signal(alu_opcode_t.alu_add)
    operand_0 = Signal(data_bus(0))
    operand_1 = Signal(data_bus(0))
    result = Signal(data_bus(0))

    alu = ALU(alu_opcode, operand_0, operand_1, result)

    update_select_a = Signal(intbv(min = 0, max = number_of_registers))
    update_value_a = Signal(data_bus(0))
    update_select_b = Signal(intbv(min = 0, max = number_of_registers))
    update_value_b = Signal(data_bus(0))
    write_enabled = Signal(False)

    select_a = Signal(intbv(min = 0, max = number_of_registers))
    value_a = Signal(data_bus(0))
    select_b = Signal(intbv(min = 0, max = number_of_registers))
    value_b = Signal(data_bus(0))

    register_bank = RegisterBank(
        update_select_a, update_value_a,
        update_select_b, update_value_b,
        write_enabled,
        select_a, value_a,
        select_b, value_b,
        clock,
    )

    opcode = Signal(data_bus(0))

    control_unit = ControlUnit(
        clock,
        opcode,
        alu_opcode, operand_0, operand_1, result,
        update_select_a, update_value_a,
        update_select_b, update_value_b,
        write_enabled,
        select_a, value_a,
        select_b, value_b,
        dbus, abus,
    )

    return alu, register_bank, control_unit
def RegisterBank(
    update_select_a, update_value_a,
    update_select_b, update_value_b,
    write_enabled,
    select_a, value_a,
    select_b, value_b,
    clock,
    number_of_registers = 32):

    '''
    Comment
    '''

    registers = [Signal(data_bus(0)) for i in range(number_of_registers)]

    @always_comb
    def read_logic():
        '''
        Handles reads to the register bank.
        '''
        if select_a == ZERO_REGISTER:
            value_a.next = 0
        else:
            value_a.next = registers[select_a]

        if select_b == ZERO_REGISTER:
            value_b.next = 0
        else:
            value_b.next = registers[select_b]

    @always(clock.posedge)
    def logic():
        '''
        Updates the values stored in the register bank.
        '''
        if write_enabled:
            if update_select_a != ZERO_REGISTER:
                registers[update_select_a].next = update_value_a
            if update_select_b != ZERO_REGISTER:
                registers[update_select_b].next = update_value_b


    return logic, read_logic
def Processor(clock):
    number_of_registers = 32

    opcode = Signal(opcode_t.add)
    operand_0 = Signal(data_bus(0))
    operand_1 = Signal(data_bus(0))
    result = Signal(data_bus(0))

    alu = ALU(opcode, operand_0, operand_1, result)

    update_select_a = Signal(intbv(min = 0, max = number_of_registers))
    update_value_a = Signal(data_bus(0))
    update_select_b = Signal(intbv(min = 0, max = number_of_registers))
    update_value_b = Signal(data_bus(0))
    write_enabled = Signal(False)

    select_a = Signal(intbv(min = 0, max = number_of_registers))
    value_a = Signal(data_bus(0))
    select_b = Signal(intbv(min = 0, max = number_of_registers))
    value_b = Signal(data_bus(0))

    register_bank = RegisterBank(
        update_select_a, update_value_a,
        update_select_b, update_value_b,
        write_enabled,
        select_a, value_a,
        select_b, value_b,
        clock,
    )

    @always(clock.posedge)
    def logic():
        opcode.next = opcode_t.add
        operand_0.next = data_bus(1)
        operand_1.next = data_bus(1)

        update_select_a.next = 0
        update_value_a.next = 0
        update_select_b.next = 0
        update_value_b.next = 0
        write_enabled.next = False
        select_a.next = 0
        select_b.next = 0

    return alu, register_bank, logic
def RegisterBank(
    update_select_a, update_value_a,
    update_select_b, update_value_b,
    write_enabled,
    select_a, value_a,
    select_b, value_b,
    clock,
    number_of_registers = 32):

    '''
    Comment
    '''

    registers = [Signal(data_bus(0)) for i in range(number_of_registers)]
    
    @always_comb
    def read_logic():
        value_a.next = registers[select_a]
        value_b.next = registers[select_b]
    

    @always_comb
    def read_logic():
        value_a.next = registers[select_a]
        value_b.next = registers[select_b]

    @always(clock.posedge)
    def logic():
        '''
        Updates the values stored in the register bank. Also handles reads.
        '''
        if write_enabled:
            registers[update_select_a] = update_value_a
            registers[update_select_b] = update_value_b

    return logic, read_logic
Example #11
0
                assert result.signed() == v

    return ram, stimulus

def test_bench():
    sim = Simulation(traceSignals(bench))
    sim.run()



if __name__ == '__main__':
    from myhdl import toVHDL

    number_of_ram=128

    addressess = Signal(intbv(min = 0, max = number_of_ram))
    data_in = Signal(data_bus(0))
    data_out = Signal(data_bus(0))
    write_enabled = Signal(False)
    clock = Signal(False)

    toVHDL(
        Ram,
        data_in, data_out,
        addressess,
        write_enabled,
        clock,
        number_of_ram,
    )

        write_enabled,
        from_file = ram_from_file,
    )

    processor = Processor(clock, dbus, abus)

    return clock_driver, ram, processor

def test_bench(ram_from_file):
    sim = Simulation(traceSignals(bench, ram_from_file = ram_from_file))
    sim.run()

if __name__ == '__main__':
    import sys

    if sys.argv[1] == 'convert':
        from myhdl import toVHDL

        clock = Signal(False)
        abus = Signal(data_bus(0))
        dbus = Signal(data_bus(0))

        toVHDL(
            Processor,
            clock,
            dbus,
            abus,
        )
    else:
        test_bench(open(sys.argv[1]))
                assert result.signed() == v

    return register_bank, stimulus

def test_bench():
    sim = Simulation(traceSignals(bench))
    sim.run()

if __name__ == '__main__':
    from myhdl import toVHDL

    number_of_registers = 32

    update_select_a = Signal(intbv(min = 0, max = number_of_registers))
    update_value_a = Signal(data_bus(0))
    update_select_b = Signal(intbv(min = 0, max = number_of_registers))
    update_value_b = Signal(data_bus(0))
    write_enabled = Signal(False)

    select_a = Signal(intbv(min = 0, max = number_of_registers))
    result_a = Signal(data_bus(0))
    select_b = Signal(intbv(min = 0, max = number_of_registers))
    result_b = Signal(data_bus(0))

    clock = Signal(False)

    toVHDL(
        RegisterBank,
        update_select_a, update_value_a,
        update_select_b, update_value_b,
Example #14
0
                (alu_opcode_t.alu_add, lambda a, b: a + b),
                (alu_opcode_t.alu_sub, lambda a, b: a - b),
                ):
                a = random.randrange(-2 ** 30, 2 ** 30)
                b = random.randrange(-2 ** 30, 2 ** 30)
                expect = compute_result(a, b)

                opcode.next = operator
                operand_0.next = data_bus(a)
                operand_1.next = data_bus(b)

                yield delay(10)

                assert result.signed() == expect

    return alu, stimulus

def test_bench():
    sim = Simulation(traceSignals(bench))
    sim.run()

if __name__ == '__main__':
    from myhdl import toVHDL

    opcode = Signal(alu_opcode_t.alu_add)
    operand_0 = Signal(data_bus(0))
    operand_1 = Signal(data_bus(0))
    result = Signal(data_bus(0))

    toVHDL(ALU, opcode, operand_0, operand_1, result)
Example #15
0
def ControlUnit(
    clock,
    instruction,
    alu_opcode, operand_0, operand_1, result,
    update_select_a, update_value_a,
    update_select_b, update_value_b,
    write_enabled,
    select_a, value_a,
    select_b, value_b,
    dbus, abus,
    ):

    '''
    Pipeline stages:

    0 - decode instruction
    1 - load operands
    2 - compute
    3 - store result
    '''

    # todo: find a more appropriate name for this variable
    depth = 4

    p_opcode = [Signal(opcode_t.op_nop) for i in range(depth)]
    p_conditional = [Signal(conditional_t.al) for i in range(depth)]
    p_alu_opcode = [Signal(alu_opcode_t.alu_sub) for i in range(depth)]
    p_is_alu_opcode = [Signal(False) for i in range(depth)]
    p_modify_status = [Signal(False) for i in range(depth)]
    p_argument_0 = [Signal(intbv()[5:]) for i in range(depth)]
    p_argument_1 = [Signal(intbv()[19:]) for i in range(depth)]
    p_argument_2 = [Signal(intbv()[5:]) for i in range(depth)]
    p_argument_3 = [Signal(intbv()[9:]) for i in range(depth)]
    p_result = [Signal(data_bus(0)) for i in range(depth)]
    p_is_valid = [Signal(True) for i in range(depth)]

    d_instruction = Signal(data_bus(0))
    d_opcode = Signal(opcode_t.op_nop)
    d_conditional = Signal(conditional_t.al)
    d_modify_status = Signal(False)
    d_is_alu_opcode = Signal(False)
    d_alu_opcode = Signal(alu_opcode_t.alu_add)
    d_argument_0 = Signal(intbv()[5:])
    d_argument_1 = Signal(intbv()[19:])
    d_argument_2 = Signal(intbv()[5:])
    d_argument_3 = Signal(intbv()[9:])

    instruction_register = Signal(intbv()[32:])

    instruction_decoder = InstructionDecoder(
        d_instruction,
        d_opcode,
        d_conditional,
        d_modify_status,
        d_is_alu_opcode, d_alu_opcode,
        d_argument_0, d_argument_1, d_argument_2, d_argument_3)

    @always(clock.posedge)
    def logic():
        '''
        push pipeline register values
        '''
        for i in range(depth - 1):
            p_opcode[i + 1].next = p_opcode[i]
            p_alu_opcode[i + 1].next = p_alu_opcode[i]
            p_is_alu_opcode[i + 1].next = p_is_alu_opcode[i]
            p_modify_status[i + 1].next = p_modify_status[i]
            p_argument_0[i + 1].next = p_argument_0[i]
            p_argument_1[i + 1].next = p_argument_1[i]
            p_argument_2[i + 1].next = p_argument_2[i]
            p_argument_3[i + 1].next = p_argument_3[i]
            p_result[i + 1].next = p_result[i]
            p_is_valid[i + 1].next = p_is_valid[i]

        '''
        increment instruction register
        '''
        instruction_register.next = instruction_register + 1

        '''
        0th stage - fetch instruction
        '''
        abus.next = instruction_register

        '''
        1st stage - decode instruction
        '''
        d_instruction.next = dbus

        '''
        2nd stage - load operands
        '''
        # note the index is 1 b/c of signal semantics!

        '''
          - remember decoding result
        '''
        p_opcode[1].next = d_opcode
        p_alu_opcode[1].next = d_alu_opcode
        p_is_alu_opcode[1].next = d_is_alu_opcode
        p_modify_status[1].next = d_modify_status
        p_argument_0[1].next = d_argument_0
        p_argument_1[1].next = d_argument_1
        p_argument_2[1].next = d_argument_2
        p_argument_3[1].next = d_argument_3

        '''
          - load operands
        '''
        select_a.next = d_argument_0
        select_b.next = d_argument_1

        '''
        3rd stage - execute
        '''
        alu_opcode.next = p_alu_opcode[2]
        operand_0.next = value_a
        operand_1.next = value_b
        p_result[3].next = result

        '''
          - handle branches
        '''
        if p_opcode[2] == opcode_t.op_br:
            for i in range(1, 3):
                p_is_valid[i].next = False
            # todo: this is a quick and dirty absolute jump
            instruction_register.next = p_argument_0[2]

        '''
        4th stage - store result
        '''
        write_enabled.next = False

        if not p_is_valid[3]:
            return

        if p_is_alu_opcode[3]:
            update_select_a.next = p_argument_2[3]
            update_value_a.next = p_result[3]
            write_enabled.next = True
        elif p_opcode[3] == opcode_t.op_li:
            update_select_a.next = p_argument_0[3]
            update_value_a.next = p_argument_1[3]
            write_enabled.next = True

    return instruction_decoder, logic