Exemplo n.º 1
0
 def assert_read(address, value, error_msg='wrong data read'):
     dut.i_address = address
     dut.i_read_enable = 1
     yield from wait()
     assert_io_data(value, error_msg)
     dut.i_read_enable = 0
     yield from wait()
Exemplo n.º 2
0
def memory_address_register(dut):

    def assert_o_address(value, error_msg):
        """Check the output address"""
        assertions.assertEqual(dut.o_address.value.binstr, value, error_msg)

    # Test initialization
    yield from wait() 
    assert_o_address('0000', 'Address should initialize to 0000')
    dut.i_reset = 0

    # Set the input address to store
    dut.i_address = 0b0100
    yield from wait()
    assert_o_address('0000', 'Address should not change until enabled')

    # Enable the input
    dut.i_enable_in = 1
    yield from wait()
    assert_o_address('0100', 'Address should change to 0100')

    # Reset the address
    dut.i_reset = 1
    yield from wait()
    assert_o_address('0000', 'Address should reset to 0000')
    dut.i_reset = 0
    yield from wait()
Exemplo n.º 3
0
def program_counter(dut):
    def assert_o_count(value, error_msg):
        """Check the value of the output count"""
        assertions.assertEqual(dut.o_count.value.binstr, value, error_msg)

    # Test initialization
    yield from wait()
    assert_o_count('xxxx', 'o_count should start disconnected')

    # Pulse the clock, nothing should change:
    yield from clock(dut)
    assert_o_count('xxxx', 'o_count should still be disconnected')

    # Enable the output:
    dut.i_enable_out = 1
    yield from wait()
    assert_o_count('0000', 'o_count should be enabled and initialized')

    # Increment:
    dut.i_increment = 1
    yield from wait()
    assert_o_count('0000', 'o_count should not increment until clock pulse')
    yield from clock(dut)
    assert_o_count('0001', 'o_count should increment')
    yield from clock(dut)
    assert_o_count('0010', 'o_count should increment')
    yield from clock(dut)
    assert_o_count('0011', 'o_count should increment')

    # Cycle without increment:
    dut.i_increment = 0
    yield from clock(dut)
    assert_o_count('0011', 'o_count should not increment')

    # Disable and Re-enable output:
    dut.i_enable_out = 0
    yield from wait()
    assert_o_count('zzzz', 'o_count should disconnect')
    dut.i_enable_out = 1
    yield from wait()
    assert_o_count('0011', 'o_count should re-enable')

    # Reset:
    yield from reset(dut)
    assert_o_count('0000', 'o_count should reset')

    # Test roll-over:
    dut.i_increment = 1
    # Increment over 8 cycles:
    yield from clock(dut, 8)
    assert_o_count('1000', 'o_count should be 8')
    # Increment over 9 cycles, rolling over the count:
    yield from clock(dut, 9)
    assert_o_count('0001', 'o_count should roll-over back to 1')
Exemplo n.º 4
0
 def program_data(address, data):
     dut.i_program_mode = 1
     dut.i_address = address
     dut.i_program_data = data
     yield from cycle(dut, 1, ['i_write_enable'])
     dut.i_program_mode = 0
     yield from wait()
Exemplo n.º 5
0
def mux_2x4(dut):

    def assert_o_address(value, error_msg):
        """Check the value of the output address"""
        assertions.assertEqual(dut.o_address.value.binstr, value, error_msg)
        
    dut.i_address_1 = 0b0101
    dut.i_address_2 = 0b1010

    dut.i_input_select = 0
    yield from wait()
    assert_o_address('0101', 'Output address should be first input')

    dut.i_input_select = 1
    yield from wait()
    assert_o_address('1010', 'Output address should be second input')
Exemplo n.º 6
0
 def reset_input():
     dut.i_debug = True
     dut.i_bus.value.binstr = 'zzzzzzzz'
     dut.i_load_instruction = 0
     dut.i_send_address = 0
     dut.i_reset = 0
     yield from wait()
Exemplo n.º 7
0
 def reset():
     dut.i_opcode = 0b0000
     dut.i_flag_carry = 0
     dut.i_flag_zero = 0
     dut.i_reset = 1
     yield from wait()
     dut.i_reset = 0
     assert_step(0)
Exemplo n.º 8
0
def register(dut):
    def assert_o_bus(value, error_msg='wrong data'):
        """Check the bus out value"""
        assertions.assertEqual(dut.o_bus.value.binstr, value, error_msg)

    def assert_o_unbuffered(value, error_msg='wrong data'):
        """Check the unbuffered output"""
        assertions.assertEqual(dut.o_unbuffered.value.binstr, value, error_msg)

    def reset_input():
        dut.i_bus = 0
        dut.i_load_data = 0
        dut.i_send_data = 0
        dut.i_reset = 0
        yield from wait()

    #### Test initialization
    yield from reset_input()
    assert_o_bus('zzzzzzzz')

    #### Test loading data
    # Simulate an data on the bus:
    dut.i_bus = 0b01000010
    # Tell the register to load it:
    dut.i_load_data = 1
    yield from wait()
    assert_o_unbuffered('01000010',
                        'Data should go to unbuffered out immediately')
    yield from reset_input()
    assert_o_bus('zzzzzzzz', 'Data should be latched in, but not output yet.')

    #### Test sending data
    dut.i_send_data = 1
    yield from wait()
    assert_o_bus('01000010', 'Data should be output now')
    assert_o_unbuffered('01000010', 'Data should go to unbuffered still')

    #### Test reset
    yield from reset_input()
    dut.i_reset = 1
    yield from wait()
    assert_o_bus('zzzzzzzz', 'bus output disconnected')
    assert_o_unbuffered('zzzzzzzz', 'unbuffered data is now undefined')
Exemplo n.º 9
0
    def reset_input():
        dut.i_debug = 1
        dut.i_program_mode = 0
        dut.i_program_data.value.binstr = 'zzzzzzzz'
        dut.i_address.value.binstr = 'zzzz'
        dut.i_write_enable = 0
        dut.i_read_enable = 0
        dut.io_data.value.binstr = 'zzzzzzzz'

        yield from wait()
Exemplo n.º 10
0
    def assert_load_instruction(instruction):
        opcode, operand = (instruction[:4], instruction[4:])
        yield from reset_input()
        dut.i_bus = int(instruction, 2)
        yield from wait()

        yield from cycle(dut, 1, ['i_load_instruction'])
        assert_o_opcode(opcode,'opcode should be loaded immediately')
        assert_o_address('zzzz','address bus should be silent until i_send_address=1')
        
        dut.i_send_address = 1
        yield from wait()
        assert_o_opcode(opcode,'opcode should still be available')
        assert_o_address(operand,'address should write to the bus')

        yield from reset_input()
        assert_o_opcode(opcode,'opcode should remember even when reset')
        assert_o_address('zzzz','address bus is silent on reset')
        dut.i_send_address = 1
        yield from wait()
        assert_o_opcode(opcode,'opcode should still be available')
        assert_o_address(operand,'address should write to the bus again')
Exemplo n.º 11
0
def pc_and_mar(dut):
    def assert_o_address(value, error_msg):
        """Check the value of the output address"""
        assertions.assertEqual(dut.o_address.value.binstr, value, error_msg)

    yield from wait()
    dut.i_enable = 1

    yield from cycle(dut, 4, ('i_clock', 'i_increment'))
    # MAR is one cycle behind PC, so after 4 cycles, MAR should contain 3
    assert_o_address('0011', 'When PC has counted to 4, MAR should contain 3.')

    yield from reset(dut)
    assert_o_address('0000', 'MAR should reset to 0000.')
Exemplo n.º 12
0
 def reset_input():
     dut.i_program_mode = 0
     dut.i_program_address = 0b0000
     dut.i_program_data = 0b00000000
     dut.i_program_write = 0
     # Each component has a seperate debug line to selectively enable:
     dut.i_debug_pc = True
     dut.i_debug_mar = True
     dut.i_debug_ir = True
     dut.i_debug_ram = True
     dut.i_debug_bus = True
     dut.i_debug_control = True
     dut.i_debug_out = True
     dut.i_debug_register_A = True
     dut.i_debug_register_B = True
     yield from wait()
Exemplo n.º 13
0
 def reset():
     yield from reset_input()
     dut.i_reset = 1
     yield from wait()
     dut.i_reset = 0
     yield from wait()
Exemplo n.º 14
0
 def reset_input():
     dut.i_bus = 0
     dut.i_load_data = 0
     dut.i_send_data = 0
     dut.i_reset = 0
     yield from wait()
Exemplo n.º 15
0
def alu_test(dut):

    def assert_o_bus(value, error_msg='wrong data'):
        """Check the bus out value"""
        assertions.assertEqual(dut.o_bus.value.binstr, value, error_msg)

    def assert_overflow(overflow=True, error_msg='expected overflow flag did not register'):
        """Ensure that the overflow flag was set (or not)"""
        assertions.assertEqual(dut.o_flag_overflow.value.binstr, '1' if overflow else '0', error_msg)

    def assert_zero(zero=True, error_msg='expected zero flag did not register'):
        """Ensure that the zero flag was set (or not)"""
        assertions.assertEqual(dut.o_flag_zero.value.binstr, '1' if zero else '0', error_msg)

    def reset_input():
        dut.i_a = 0
        dut.i_b = 0
        dut.i_subtract = 0
        dut.i_send_result = 0
        yield from wait()

    ### Test init
    yield from reset_input()
    assert_o_bus('zzzzzzzz', 'Output should default disabled')    

    ### Test add
    dut.i_a = 22
    dut.i_b = 42
    dut.i_send_result = 1
    yield from wait()
    assert_o_bus('01000000', '22 + 42 = 64')
    assert_overflow(False)
    assert_zero(False)

    ### Test subtract
    yield from reset_input()
    dut.i_a = 34
    dut.i_b = 30
    dut.i_subtract = 1
    dut.i_send_result = 1
    yield from wait()
    assert_o_bus('00000100', '34 - 30 = 4')
    assert_overflow(False)
    assert_zero(False)

    ### Test negative numbers
    yield from reset_input()
    dut.i_a = 29
    dut.i_b = 56
    dut.i_subtract = 1
    dut.i_send_result = 1
    yield from wait()    
    assert_o_bus('11100101', '29 - 56 = -27')
    assert_overflow(False)
    assert_zero(False)

    ### Test numbers larger than we handle:
    yield from reset_input()
    dut.i_a = 127
    dut.i_b = 127
    dut.i_send_result = 1
    yield from wait()
    assert_o_bus('11111110', '127 + 127 =  -2 with overflow')
    assert_overflow()
    assert_zero(False)
    
    ### Test zero flag:
    yield from reset_input()
    dut.i_a = -2
    dut.i_b = 2
    dut.i_send_result = 1
    yield from wait()
    assert_o_bus('00000000','-2 + 2 = 0')
    assert_zero()
    
    ### Test disconnection from bus
    dut.i_send_result = 0
    yield from wait()
    assert_o_bus('zzzzzzzz', 'Should disconnect from bus')
Exemplo n.º 16
0
 def reset_input():
     dut.i_a = 0
     dut.i_b = 0
     dut.i_subtract = 0
     dut.i_send_result = 0
     yield from wait()
Exemplo n.º 17
0
def ram_16x8(dut):
    def assert_io_data(value, error_msg):
        """Check the value of the data lines"""
        if (isinstance(value, numbers.Number)):
            assertions.assertEqual(dut.io_data.value, value, error_msg)
        else:
            assertions.assertEqual(dut.io_data.value.binstr, value, error_msg)

    def reset_input():
        dut.i_debug = 1
        dut.i_program_mode = 0
        dut.i_program_data.value.binstr = 'zzzzzzzz'
        dut.i_address.value.binstr = 'zzzz'
        dut.i_write_enable = 0
        dut.i_read_enable = 0
        dut.io_data.value.binstr = 'zzzzzzzz'

        yield from wait()

    def assert_read(address, value, error_msg='wrong data read'):
        dut.i_address = address
        dut.i_read_enable = 1
        yield from wait()
        assert_io_data(value, error_msg)
        dut.i_read_enable = 0
        yield from wait()

    def write_data(address, data):
        dut.i_address = address
        dut.io_data = data
        yield from cycle(dut, 1, ['i_write_enable'])

    def program_data(address, data):
        dut.i_program_mode = 1
        dut.i_address = address
        dut.i_program_data = data
        yield from cycle(dut, 1, ['i_write_enable'])
        dut.i_program_mode = 0
        yield from wait()

    def assert_write(address, data, error_msg='Could not verify written data'):
        yield from write_data(address, data)
        yield from assert_read(address, data, error_msg)

    # Initialize
    yield from reset_input()
    yield from wait()
    assert_io_data('zzzzzzzz', 'No output should be made on initialization')

    # Verify all RAM is cleared
    yield from reset_input()
    for addr in range(16):
        assert_read(addr, '00000000', 'RAM address is cleared')

    # Manually enter new RAM data
    yield from reset_input()
    data = [random.randint(0, 255) for x in range(16)]
    for addr in range(16):
        yield from program_data(addr, data[addr])
    assert_io_data('zzzzzzzz',
                   'No output should be available unless read is enabled')

    # Read from RAM
    yield from reset_input()
    for addr in range(16):
        assert_read(addr, data[addr])

    # Write data from the io_data bus
    yield from reset_input()
    yield from assert_write(0b0010, 0b11001100)