diff options
| author | Benedict <benedict@0xb8000.de> | 2018-04-16 10:23:49 +0200 |
|---|---|---|
| committer | Benedict <benedict@0xb8000.de> | 2018-04-26 11:19:01 +0200 |
| commit | a34ee32c743b35170777038a4c3ebbabf5686b43 (patch) | |
| tree | 1df2053d6dd64e64626b542532fa0a42dbbaea18 | |
| parent | 831920937a1541d6c15b357d3e0336c3291d8084 (diff) | |
eeprom: control logic: define instructions layout and write out script
| -rw-r--r-- | 7seg-hex.py | 30 | ||||
| -rw-r--r-- | eeprom_pi.py | 63 | ||||
| -rw-r--r-- | inst.py | 90 | ||||
| -rw-r--r-- | test_prog.py | 8 | ||||
| -rw-r--r-- | write_inst_eeprom.py | 98 | ||||
| -rw-r--r-- | write_prog_eeprom.py | 39 |
6 files changed, 282 insertions, 46 deletions
diff --git a/7seg-hex.py b/7seg-hex.py index e1bc35b..3bb946a 100644 --- a/7seg-hex.py +++ b/7seg-hex.py @@ -11,22 +11,24 @@ import eeprom_pi as ep ep.init_board() ## Mapping of the I/O 0-7 two the 7-segement display: -## I/O 0: A -## I/O 1: B -## I/O 2: C +## I/O 0: G +## I/O 1: F +## I/O 2: E ## I/O 3: D -## I/O 4: E -## I/O 5: F -## I/O 6: G -SEG_A = 0x1 -SEG_B = 0x2 -SEG_C = 0x4 +## I/O 4: A +## I/O 5: B +## I/O 6: C +SEG_G = 0x1 +SEG_F = 0x2 +SEG_E = 0x4 SEG_D = 0x8 -SEG_E = 0x10 -SEG_F = 0x20 -SEG_G = 0x40 +SEG_A = 0x10 +SEG_B = 0x20 +SEG_C = 0x40 -ep.write_data_at(0x0, SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F) +# do not show anything on 0 +ep.write_data_at(0x0, 0x0) +#ep.write_data_at(0x0, SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F) ep.write_data_at(0x1, SEG_B | SEG_C) ep.write_data_at(0x2, SEG_A | SEG_B | SEG_G | SEG_E | SEG_D) ep.write_data_at(0x3, SEG_A | SEG_B | SEG_G | SEG_C | SEG_D) @@ -43,4 +45,6 @@ ep.write_data_at(0xd, SEG_B | SEG_C | SEG_D | SEG_E | SEG_G) ep.write_data_at(0xe, SEG_A | SEG_D | SEG_G | SEG_F | SEG_E) ep.write_data_at(0xf, SEG_A | SEG_E | SEG_F | SEG_G) +raw_input("please unplug the power from the EEPROM and press any key to continue") + ep. cleanup() diff --git a/eeprom_pi.py b/eeprom_pi.py index e51f4b8..e45678b 100644 --- a/eeprom_pi.py +++ b/eeprom_pi.py @@ -32,15 +32,12 @@ def init_board(write = True): GPIO.setup(19, GPIO.OUT) GPIO.setup(10, GPIO.OUT) GPIO.setup(8, GPIO.OUT) - - # used to trigger a write GPIO.setup(5, GPIO.OUT) # used to read GPIO.setup(3, GPIO.OUT) # set the pins to high, pins are active low - GPIO.output(5, True) GPIO.output(3, True) @@ -49,22 +46,22 @@ def read_data(): GPIO.output(3, False) time.sleep(0.3) data = (GPIO.input(11)) - print(GPIO.input(11)) + #print(GPIO.input(11)) data |= (GPIO.input(12) << 0x1) - print(GPIO.input(12)) + #print(GPIO.input(12)) data |= (GPIO.input(13) << 0x2) - print(GPIO.input(13)) + #print(GPIO.input(13)) data |= (GPIO.input(15) << 0x3) - print(GPIO.input(15)) + #print(GPIO.input(15)) data |= (GPIO.input(16) << 0x4) - print(GPIO.input(16)) + #print(GPIO.input(16)) data |= (GPIO.input(18) << 0x5) - print(GPIO.input(18)) + #print(GPIO.input(18)) data |= (GPIO.input(22) << 0x6) - print(GPIO.input(22)) + #print(GPIO.input(22)) data |= (GPIO.input(7) << 0x7) - print(GPIO.input(7)) - print("read data: %s" % data) + #print(GPIO.input(7)) + #print("read data: %s" % data) time.sleep(0.3) GPIO.output(3, True) return data @@ -72,40 +69,39 @@ def read_data(): # data should be one byte def set_data(data): GPIO.output(11, (data & 0x1) > 0) - print((data & 0x1) > 0) + #print((data & 0x1) > 0) GPIO.output(12, (data & 0x2) > 0) - print((data & 0x2) > 0) + #print((data & 0x2) > 0) GPIO.output(13, (data & 0x4) > 0) - print((data & 0x4) > 0) + #print((data & 0x4) > 0) GPIO.output(15, (data & 0x8) > 0) - print((data & 0x8) > 0) + #print((data & 0x8) > 0) GPIO.output(16, (data & 0x10) > 0) - print((data & 0x10) > 0) + #print((data & 0x10) > 0) GPIO.output(18, (data & 0x20) > 0) - print((data & 0x20) > 0) + #print((data & 0x20) > 0) GPIO.output(22, (data & 0x40) > 0) - print((data & 0x40) > 0) + #print((data & 0x40) > 0) GPIO.output(7, (data & 0x80) > 0) - print((data & 0x80) > 0) + #print((data & 0x80) > 0) # address should be one byte def set_address(address): GPIO.output(26, (address & 0x1) > 0) - print((address & 0x1) > 0) + #print((address & 0x1) > 0) GPIO.output(24, (address & 0x2) > 0) - print((address & 0x2) > 0) + #print((address & 0x2) > 0) GPIO.output(23, (address & 0x4) > 0) - print((address & 0x4) > 0) + #print((address & 0x4) > 0) GPIO.output(21, (address & 0x8) > 0) - print((address & 0x8) > 0) + #print((address & 0x8) > 0) GPIO.output(19, (address & 0x10) > 0) - print((address & 0x10) > 0) + #print((address & 0x10) > 0) GPIO.output(10, (address & 0x20) > 0) - print((address & 0x20) > 0) + #print((address & 0x20) > 0) GPIO.output(8, (address & 0x40) > 0) - print((address & 0x40) > 0) - # for DEBUG use only 7 address bits to have one left for read trigger - #GPIO.output(5, (address & 0x80) > 0) + #print((address & 0x40) > 0) + GPIO.output(5, (address & 0x80) > 0) #print((address & 0x80) > 0) def write_data_at(address, data): @@ -115,10 +111,10 @@ def write_data_at(address, data): set_data(data) # wait so everythings is stable time.sleep(0.3) - # trigger write on pin 5 - GPIO.output(5, False) + # trigger write on pin 3 + GPIO.output(3, False) time.sleep(0.3) - GPIO.output(5, True) + GPIO.output(3, True) def read_data_at(address): @@ -128,4 +124,5 @@ def read_data_at(address): time.sleep(0.3) # trigger output enable data = read_data() - print("read data %s" % data) + print("read data %s, hex: %s" % (data, hex(data))) + return data @@ -0,0 +1,90 @@ +## Hard wired locations of the control signals +SIG_REG_A_OUT = 0x1 +SIG_ALU_OUT = 0x2 +SIG_REG_B_OUT = 0x4 +SIG_PC_OUT = 0x8 +SIG_PC_TICK = 0x10 +SIG_PC_LOAD = 0x20 +SIG_ALU_SUB = 0x40 +SIG_MEM_ENABLE = 0x80 +SIG_MEM_DIR_OUT = 0x100 +SIG_INST_OUT = 0x200 +SIG_INST_IN = 0x400 +SIG_MEM_ADDRESS_IN = 0x800 +SIG_REG_A_IN = 0x1000 +SIG_REG_B_IN = 0x2000 +SIG_HEX_OUT = 0x4000 + +## Define control word for common micro instructions +MICRO_INST_MEM_TO_REG_A = SIG_REG_A_IN | SIG_MEM_DIR_OUT | SIG_MEM_ENABLE +MICRO_INST_MEM_TO_REG_B = SIG_REG_B_IN | SIG_MEM_DIR_OUT | SIG_MEM_ENABLE +MICRO_INST_PC_TO_REG_MEM_ADDRESS = SIG_MEM_ADDRESS_IN | SIG_PC_OUT +MICRO_INST_MEM_TO_INST = SIG_INST_IN | SIG_MEM_DIR_OUT | SIG_MEM_ENABLE + +## max number of micro instructions a macro instruction can have +MAX_MICRO_OPS = 6 + +## the last four bits of this OP is loaded into the REG A +INST_LDA = 0x10 +INST_MICRO_OP_LDA = [SIG_INST_OUT | SIG_REG_A_IN] + +## the last four bits of this OP is loaded into the REG B +INST_LDB = 0x20 +INST_MICRO_OP_LDB = [SIG_INST_OUT | SIG_REG_B_IN] + +## this instruction show the content of REG A on the 7hex display +INST_REG_A_OUT = 0x30 +INST_MICRO_OP_REG_A_OUT = [SIG_REG_A_OUT | SIG_HEX_OUT] + +## this instruction show the content of REG B on the 7hex display +INST_REG_B_OUT = 0x40 +INST_MICRO_OP_REG_B_OUT = [SIG_REG_B_OUT | SIG_HEX_OUT] + +## this instruction adds the content of REG_A and REG_B and saves the result in +## REG_A +INST_ADD_A = 0x50 +INST_MICRO_OP_ADD_A = [SIG_ALU_OUT | SIG_REG_A_IN] + +## this instruction adds the content of REG_A and REG_B and saves the result in +## REG_B +INST_ADD_B = 0x60 +INST_MICRO_OP_ADD_B = [SIG_ALU_OUT | SIG_REG_B_IN] + +## this instrcutions substracts the content of REG_A and REG_B and saves the +## result in REG_A +INST_SUB_A = 0x70 +INST_MICRO_OP_SUB_A = [SIG_ALU_SUB | SIG_ALU_OUT | SIG_REG_A_IN] + +## this instrcutions substracts the content of REG_A and REG_B and saves the +## result in REG_A +INST_SUB_B = 0x80 +INST_MICRO_OP_SUB_B = [SIG_ALU_SUB | SIG_ALU_OUT | SIG_REG_B_IN] + +## this loads a new PC value +## the last for bits of this instruction are loaded into the REG PC +INST_PC_LOAD = 0x90 +INST_MICRO_OP_PC_LOAD = [SIG_INST_OUT | SIG_PC_LOAD] + +## halt instruction +## no new fetch cycle of the next instruction halts the PC +INST_HLT = 0xe0 +INST_MICRO_OP_HLT = [0x0000] + +INST_RESET = [] + +## fetch the instrcution itself from memory, and increment PC +INST_MICRO_OP_FETCH_INSTRUCTION = [MICRO_INST_PC_TO_REG_MEM_ADDRESS, + MICRO_INST_MEM_TO_INST | SIG_PC_TICK] + +## list of all implemented instructions +## Mapping between instruction and control signals +INST = [[INST_LDA, INST_MICRO_OP_LDA], + [INST_LDB, INST_MICRO_OP_LDB], + [INST_REG_A_OUT, INST_MICRO_OP_REG_A_OUT], + [INST_REG_B_OUT, INST_MICRO_OP_REG_B_OUT], + [INST_ADD_A, INST_MICRO_OP_ADD_A], + [INST_ADD_B, INST_MICRO_OP_ADD_B], + [INST_SUB_A, INST_MICRO_OP_SUB_A], + [INST_SUB_B, INST_MICRO_OP_SUB_B], + [INST_PC_LOAD, INST_MICRO_OP_PC_LOAD] + ] diff --git a/test_prog.py b/test_prog.py new file mode 100644 index 0000000..e6fdd11 --- /dev/null +++ b/test_prog.py @@ -0,0 +1,8 @@ +## import the instruction definitions +import inst + +## little test programm, which loads two values from memory, adds them and +## output it on the 7seg display + +## 0x1 and 0x2 are the values loaded into the registers +prog = [inst.INST_LDA | 0x1, inst.INST_LDB | 0x2, inst.INST_ADD, inst.INST_HLT] diff --git a/write_inst_eeprom.py b/write_inst_eeprom.py new file mode 100644 index 0000000..224572a --- /dev/null +++ b/write_inst_eeprom.py @@ -0,0 +1,98 @@ +## This file writes the in inst.py defined instruction to the AT28C EEPROM +## conntected to a raspberry pi via GPIO pins + +import inst +import eeprom_pi as ep + +## for cmd line args access +import sys + +## given an address and an instruction this writes corredsponding bytes to the +## EEPROM +def write_micro_inst_out(address, instruction): + ctl_word_half = 0x00 + if eeprom_n == 1: + ctl_word_half = instruction & 0xff + elif eeprom_n == 2: + ctl_word_half = (instruction >> 8) & 0xff + + print("%s: %s (%s)" % (hex(address), hex(ctl_word_half), + hex(instruction))) + ep.write_data_at(address, ctl_word_half) + + + +## look for cmd line parameter to known which EEPROM we write to currently +if(len(sys.argv) != 2): + print("usage: %s <number eeprom>" % sys.argv[0]) + print("please specify the eeprom you want to write to.") + exit() + +eeprom_n = int(sys.argv[1]) + +if not (eeprom_n == 1 or eeprom_n == 2): + print("error: only two eeproms supported right now") + exit() + +print("writing eeprom %s" % eeprom_n) + +## setup board +ep.init_board() + + +## for every instruction +nr_inst = 1 +for instruction_data in inst.INST: + print("writing instruction %s" % nr_inst) + base_address = instruction_data[0] + mops = instruction_data[1] + n = 0 + + # write fetch instruction micro ops for every instruction + for fi_mop in inst.INST_MICRO_OP_FETCH_INSTRUCTION: + write_micro_inst_out(base_address+n, fi_mop) + n += 1 + + print("------------") + + for mop in mops: + write_micro_inst_out(base_address+n, mop) + n += 1 + + ## insert 0x00 for not used micro instuctions, so all control signals 0 + ## and the pc is not doing some unwanted stuff + while n < inst.MAX_MICRO_OPS: + write_micro_inst_out(base_address+n, 0x0000) + n += 1 + + + nr_inst += 1 + + +## write a fetch instruction at address 0x0, so that after a reset we are +## fetching the first instruction +print("\n") +print("writing inst fetch instruction at address 0x0, so we begin executing" + "after reset:") +n = 0 +base_address = 0x0 +for fi_mop in inst.INST_MICRO_OP_FETCH_INSTRUCTION: + write_micro_inst_out(base_address+n, fi_mop) + n += 1 + +## write NULLs +while n < inst.MAX_MICRO_OPS: + write_micro_inst_out(base_address+n, 0x0000) + n += 1 + +## write HLT instruction aka, everything 0x00, no new instruction fetch cycle +n = 0 +base_address = inst.INST_HLT +while n < inst.MAX_MICRO_OPS: + write_micro_inst_out(base_address+n, 0x0000) + n += 1 + + +trash = raw_input("please unplug the power to the EEPORM now and press any key to continue...") + +ep.cleanup() diff --git a/write_prog_eeprom.py b/write_prog_eeprom.py new file mode 100644 index 0000000..a7440cf --- /dev/null +++ b/write_prog_eeprom.py @@ -0,0 +1,39 @@ +## This file write different programms to the EEPROM AT28C + +## programm start at 0x00 + +import test_prog +import fibonacci_prog + + +import eeprom_pi as ep +import sys + +prog = None + +if len(sys.argv) == 2: + if sys.argv[1] == "test": + prog = test_prog.prog + + +if prog == None: + print("error: please specify a valid programm.") + print("valid programms are: test") + exit() + +## start at addres 0x0 +address = 0x0 +inst_nr = 0 + +ep.init_board() + +for instruction in prog: + print("%s: %s" % (hex(address+inst_nr), hex(instruction))) + ep.write_data_at(address+inst_nr, instruction) + inst_nr += 1 + +trash = raw_input("please unplug the power from the EEPORM and press any key to continue") + +ep.cleanup() + + |
