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 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()
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')
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 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')
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()
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)
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')
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_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')
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.')
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()
def reset(): yield from reset_input() dut.i_reset = 1 yield from wait() dut.i_reset = 0 yield from wait()
def reset_input(): dut.i_bus = 0 dut.i_load_data = 0 dut.i_send_data = 0 dut.i_reset = 0 yield from wait()
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')
def reset_input(): dut.i_a = 0 dut.i_b = 0 dut.i_subtract = 0 dut.i_send_result = 0 yield from wait()
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)