aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenedict <benedict@0xb8000.de>2018-04-16 10:23:49 +0200
committerBenedict <benedict@0xb8000.de>2018-04-26 11:19:01 +0200
commita34ee32c743b35170777038a4c3ebbabf5686b43 (patch)
tree1df2053d6dd64e64626b542532fa0a42dbbaea18
parent831920937a1541d6c15b357d3e0336c3291d8084 (diff)
eeprom: control logic: define instructions layout and write out script
-rw-r--r--7seg-hex.py30
-rw-r--r--eeprom_pi.py63
-rw-r--r--inst.py90
-rw-r--r--test_prog.py8
-rw-r--r--write_inst_eeprom.py98
-rw-r--r--write_prog_eeprom.py39
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
diff --git a/inst.py b/inst.py
new file mode 100644
index 0000000..4d56770
--- /dev/null
+++ b/inst.py
@@ -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()
+
+