summaryrefslogtreecommitdiffstats
path: root/lab1/lab1ucode.py
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2022-02-04 08:58:45 +0100
committerGustav Sörnäs <gustav@sornas.net>2022-02-04 08:58:45 +0100
commit63a6a21f1f728a131b599fca7bc20e2001b2ad33 (patch)
tree85e7ed116c2a567d1017a30381322e3cabd89303 /lab1/lab1ucode.py
parentf3eae905ca1e378948ee228e93f3c697cb879605 (diff)
downloadtsea83-63a6a21f1f728a131b599fca7bc20e2001b2ad33.tar.gz
move to dir
Diffstat (limited to 'lab1/lab1ucode.py')
-rw-r--r--lab1/lab1ucode.py198
1 files changed, 198 insertions, 0 deletions
diff --git a/lab1/lab1ucode.py b/lab1/lab1ucode.py
new file mode 100644
index 0000000..cc8c94c
--- /dev/null
+++ b/lab1/lab1ucode.py
@@ -0,0 +1,198 @@
+import sys
+
+from string import Template
+
+TWOWAY = {
+ "ir": "001",
+ "pm": "010",
+ "pc": "011",
+ "hr": "101",
+ "grx": "110",
+}
+
+# to bus: source
+TB = TWOWAY | {
+ "ar": "100",
+ # "styrord": "111",
+}
+
+# from bus: destination
+FB = TWOWAY | {
+ "asr": "111"
+}
+
+def compile(lines):
+ addr = 0
+ labels = {}
+ compiled = []
+ todo = []
+ for line in lines:
+ if not line:
+ # empty line, ignore
+ continue
+ if line.startswith(";"):
+ # comment
+ continue
+ if line.endswith(":"):
+ # label
+ labels[line.split(":")[0]] = addr
+ continue
+ if line.startswith("!"):
+ # inline
+ compiled.append(line[1:])
+ addr += 1
+ continue
+
+ for inst in line.split(", "):
+ alu = "0000"
+ tb = "000"
+ fb = "000"
+ s = "0"
+ p = "0"
+ lc = "00"
+ seq = "0000"
+ myadr = "0000000"
+
+ if "->" in inst:
+ # move a value
+ fr, to = inst.split("->")
+ # via bus
+ if fr in TB:
+ tb = TB[fr]
+ if to in FB:
+ fb = FB[to]
+
+ if "gr" in fr and len(fr) == 3:
+ tb = TB["grx"]
+ if "gr" in to and len(to) == 3:
+ fb = FB["grx"]
+
+ if to == "lc":
+ lc = "10"
+
+ # load alu
+ if to == "ar":
+ alu = "0001"
+
+ # alu addition
+ if "+" in fr:
+ if "+'" in fr:
+ # ignore flags
+ other = fr.split("+'")[1]
+ alu = "1000"
+ else:
+ other = fr.split("+")[1]
+ alu = "0100"
+ tb = TB[other]
+
+ # alu subtraction
+ if "-" in fr:
+ other = fr.split("-")[1]
+ tb = TB[other]
+ alu = "0101"
+
+ if "&" in fr:
+ other = fr.split("&")[1]
+ tb = TB[other]
+ alu = "0110"
+
+ if inst == "pc++":
+ p = "1"
+
+ if inst == "k1->upc":
+ seq = "0001"
+ if inst == "k2->upc":
+ seq = "0010"
+ if inst == "0->upc":
+ seq = "0011"
+ if inst == "halt":
+ seq = "1111"
+ if inst == "lc--":
+ lc = "01"
+ if inst == "lsr":
+ alu = "1101"
+
+ if "?" in inst:
+ cond, to = inst.split("? ")
+ if cond == "l=1":
+ seq = "1100"
+ elif cond == "z=1":
+ seq = "1000"
+ elif cond == "n=1":
+ seq = "1001"
+ elif cond == "o=1":
+ seq = "1011"
+ else:
+ assert False
+ myadr = f"<{to}>"
+
+ if inst.startswith("b "):
+ seq = "0110" #TODO 0101?
+ myadr = "<{}>".format(inst.split("b ")[1])
+
+ compiled.append((inst, (alu, tb, fb, s, p, lc, seq, myadr)))
+
+ addr += 1
+
+ linked = []
+ for addr, line in enumerate(compiled):
+ if type(line) is str:
+ linked.append((addr, line))
+ continue
+ inst, (alu, tb, fb, s, p, lc, seq, myadr) = line
+ if myadr != "0000000":
+ for label, label_line in labels.items():
+ myadr = myadr.replace(f"<{label}>", str(bin(label_line)[2:]).zfill(7))
+ first = alu[0]
+ rest = alu[1:] + tb + fb + s + p + lc + seq + myadr
+ hs = "".join([f"{int(first):01x}"] + [f"{int(rest[i:i+4], 2):01x}" for i in range(0, len(rest), 4)])
+ linked.append((addr, hs))
+ if hs == "0000000":
+ todo.append(inst)
+
+ if todo:
+ print("todo", file=sys.stderr)
+ print("\n".join(todo), file=sys.stderr)
+ assert False
+
+ return ["{:02x}: {}".format(addr, line) for addr, line in linked], labels
+
+
+def write(prog, labels):
+ #with open("template.mia", "r") as f:
+ # template = Template(f.read())
+
+ ucode_pad = 0x80 - len(prog)
+ ucode = "\n".join(prog + [f"{len(prog)+n:02x}: 0000000" for n in range(ucode_pad)])
+
+ insts = [
+ "load",
+ "store",
+ "add",
+ "sub",
+ "and",
+ "lsr",
+ "bra",
+ "bne",
+ "halt",
+ "cmp",
+ "bge",
+ "beq",
+ ]
+ inst_pad = 0x10 - len(insts)
+ inst_locations = "\n".join([f"{i:02x}: {labels[inst]:02x}" for i, inst in enumerate(insts)] +
+ [f"{n+len(insts):02x}: 00" for n in range(inst_pad)])
+
+ print("MyM:")
+ print(ucode)
+ print()
+
+ print("K1:")
+ print(inst_locations)
+ #print(template.safe_substitute(pm))
+
+ print("K2:")
+
+
+if __name__ == "__main__":
+ write(*compile([line.strip() for line in sys.stdin]))