]> Witch of Git - minecraft-eda/blob - genlib.py
Add romgen, a tool to generate ROMs for litho
[minecraft-eda] / genlib.py
1 """
2 Generate a cell library for redstone circuits
3 """
4
5 import sys
6
7 CELLS = [
8 (6, {'Y': 'A'}),
9 (6, {'Y': '!A'}),
10 (12, {'Y': 'A & B'}),
11 (12, {'Y': '!(A & B)'}),
12 (12, {'Y': 'A | B'}),
13 (12, {'Y': '!(A | B)'}),
14 (18, {'Y': 'A & B & C'}),
15 (18, {'Y': '!(A & B & C)'}),
16 (18, {'Y': 'A | B | C'}),
17 (18, {'Y': '!(A | B | C)'}),
18 (18, {'Y': '(A & B) | C'}),
19 (18, {'Y': '(A & B) | !C'}),
20 (18, {'Y': '!(A & B) | C'}),
21 (18, {'Y': '!(A & B) | !C'}),
22 (18, {'Y': '(A | B) & C'}),
23 (18, {'Y': '!((A | B) & C)'}),
24 (24, {'Y': 'A & B & C & D'}),
25 (24, {'Y': '!(A & B & C & D)'}),
26 (24, {'Y': 'A | B | C | D'}),
27 (24, {'Y': '!(A | B | C | D)'}),
28 (24, {'Y': '(A | B) & (C | D)'}),
29 (24, {'Y': '!((A | B) & (C | D))'}),
30 (24, {'Y': '(A & B) | (C & D)'}),
31 (24, {'Y': '(A & B) | !(C & D)'}),
32 (24, {'Y': '!(A & B) | !(C & D)'}),
33 (24, {'Y': '!((A & B) | !(C & D))'}),
34 (24, {'Y': '!(!(A & B) | (C & D))'}),
35 (24, {'Y': '!(!(A & B) | !(C & D))'}),
36 (24, {'Y': '(A | B) & C & D'}),
37 (24, {'Y': '!((A | B) & C & D)'}),
38 (24, {'Y': '(A | B) & (C | D)'}),
39 (24, {'Y': '!((A | B) & (C | D))'}),
40 """
41 cell(DFF_P) {
42 area: 8;
43 ff(IQ, IQN) { clocked_on: C; next_state: D; }
44 pin(C) { direction: input; clock: true; }
45 pin(D) { direction: input; }
46 pin(Q) { direction: output; function: "IQ"; }
47 }
48 """,
49 """
50 cell(DFF_N) {
51 area: 8;
52 ff(IQ, IQN) { clocked_on: "!C"; next_state: D; }
53 pin(C) { direction: input; clock: true; }
54 pin(D) { direction: input; }
55 pin(Q) { direction: output; function: "IQ"; }
56 }
57 """,
58 ]
59
60 def find_inputs(eqs):
61 inputs = set()
62 for eq in eqs.values():
63 inputs.update(
64 eq.replace('(', ' ').replace(')', ' ')
65 .replace('&', ' ').replace('|', ' ')
66 .replace('+', ' ').replace('*', ' ')
67 .replace('!', ' ').split()
68 )
69 return inputs
70
71 def make_name(eqs):
72 return ','.join(
73 f"{x}={f.replace(' ', '').replace('|', '+')}"
74 for x, f in eqs.items()
75 )
76
77 def print_lib(lib, defns):
78 print(f"library({lib}) {{")
79 defined = {}
80 for i, defn in enumerate(defns):
81 if isinstance(defn, str):
82 print(' ' + defn.strip().replace('\n', '\n '))
83 else:
84 area, eqs = defn
85 name = make_name(eqs)
86 if name in defined:
87 print(f"Warning: {name} defined at both {defined[name]} and {i}, skipping...", file=sys.stderr)
88 continue
89 defined[name] = i
90 inputs = find_inputs(eqs)
91 print(f""" cell("{name}") {{""")
92 print(f""" area: {area};""")
93 for pin in sorted(inputs):
94 print(f" pin({pin}) {{ direction: input; }}")
95 for x, f in eqs.items():
96 print(f""" pin({x}) {{ direction: output; function: "{f}"; }}""")
97 print(" }")
98 print("}")
99
100 print_lib("redstone", CELLS)