Created
April 23, 2018 20:27
-
-
Save RF5/2ea407bf512ab2c94b1a918942cfeb75 to your computer and use it in GitHub Desktop.
Python script to generate VHDL, currently for a DE0 FPGA board.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DE0_Generator(object): | |
def __init__(self, base_hz=50e6): | |
# base clock of 50MHz for DE0 board | |
self.vhdl = "" | |
self.processes = [] | |
self.signals = {} | |
self.with_statements = [] | |
self.base_hz = base_hz | |
self.display_cases = None | |
self.setup_hex_displays() | |
def add_clock(self, hz, name=None): | |
newproc = [] | |
if name is not None: | |
newproc.append(str(name) + " : " + "PROCESS (CLOCK_50)\n") | |
else: | |
newproc.append("PROCESS (CLOCK_50)\n") | |
new_cnt = int((self.base_hz / (2.0*hz)) - 1) | |
newproc.append("\tVARIABLE cnt : INTEGER RANGE 0 TO " + str(new_cnt) + ";\n") | |
newproc.append("\tBEGIN\n") | |
newproc.append("\t\tIF rising_edge(CLOCK_50) THEN\n") | |
newproc.append("\t\t\tcnt := cnt + 1;\n") | |
newproc.append("\t\t\tIF cnt = " + str(new_cnt) + " THEN\n") | |
newproc.append("\t\t\t\tcnt := 0;\n") | |
newproc.append("\t\t\t\tclock_" + str(hz) + "hz <= NOT clock_" + str(hz) + ";\n") | |
newproc.append("\t\t\tEND IF;\n") | |
newproc.append("\t\tEND IF;\n") | |
newproc.append("END PROCESS;\n") | |
self.signals['clock_'+str(hz) + "hz"] = "SIGNAL clock_" + str(hz) + "hz : STD_LOGIC;\n" | |
self.processes.append(newproc) | |
def add_signal(self, dtype, name, span=None): | |
tmp = "SIGNAL " + str(name) + " : " | |
if dtype == str: | |
self.signals[name] = tmp + str(dtype) + ";\n" | |
elif dtype == int: | |
tmp = tmp + "INTEGER"; | |
if span is not None: | |
tmp = tmp + " RANGE " + str(span[0]) + " TO " + str(span[1]) | |
self.signals[name] = tmp + ";\n" | |
elif dtype == bool: | |
self.signals[name] = tmp + "STD_LOGIC;\n" | |
def add_to_display(self, sig, conds=None, disp=[1, 2, 3, 4]): | |
assert sig in self.signals, "Signal chosen must be present in the signals set up!" | |
if 1 in disp: | |
self.display_cases[0].append(sig + " REM 10 WHEN " + str(conds) + " ELSE\n") | |
if 2 in disp: | |
self.display_cases[1].append("(" + sig + " REM 100) / 10 WHEN" + str(conds) + " ELSE\n") | |
if 3 in disp: | |
self.display_cases[2].append("(" + sig + " REM 1000) / 100 WHEN " + str(conds) + " ELSE\n") | |
if 4 in disp: | |
self.display_cases[3].append(sig + " / 1000 WHEN " + conds + " ELSE\n") | |
def save_to_file(self, filename, print_to_console=False): | |
with open(filename, 'w') as f: | |
f.write("ARCHITECTURE structure OF DE0 IS\n") | |
for key in self.signals: | |
f.write("\t") | |
f.write(self.signals[key]) | |
f.write("BEGIN\n\n") | |
for proc in self.processes: | |
for line in proc: | |
f.write("\t") | |
f.write(line) | |
f.write("\n") | |
for wstm in self.with_statements: | |
for line in wstm: | |
f.write("\t") | |
f.write(line) | |
f.write("\n") | |
if self.display_cases is not None: | |
for i, disp in enumerate(self.display_cases): | |
f.write("\tdisplay" + str(i) + " <= ") | |
for i, line in enumerate(disp): | |
if i != 0: | |
f.write('\t\t\t\t') | |
if i != len(disp) - 1: | |
f.write(line) | |
else: | |
f.write(line[:-6] + ";") | |
f.write('\n') | |
f.write("END structure;") | |
def setup_hex_displays(self): | |
self.signals['display1'] = "SIGNAL display1 : INTEGER RANGE 0 TO 9;\n" | |
self.signals['display2'] = "SIGNAL display2 : INTEGER RANGE 0 TO 9;\n" | |
self.signals['display3'] = "SIGNAL display3 : INTEGER RANGE 0 TO 9;\n" | |
self.signals['display4'] = "SIGNAL display4 : INTEGER RANGE 0 TO 9;\n" | |
self.display_cases = [[], [], [], []] | |
for i in range(1, 5): | |
tmp = [] | |
tmp.append("WITH display" + str(i) + " SELECT\n") | |
tmp.append("\tHEX" + str(i-1) + "_D <= \"0000001\" WHEN 0,\n") | |
tmp.append("\t\t\"1001111\" WHEN 1,\n") # 1 | |
tmp.append("\t\t\"0010010\" WHEN 1,\n") # 2 | |
tmp.append("\t\t\"0000110\" WHEN 1,\n") # 3 | |
tmp.append("\t\t\"1001100\" WHEN 1,\n") # 4 | |
tmp.append("\t\t\"0100100\" WHEN 1,\n") # 5 | |
tmp.append("\t\t\"0100000\" WHEN 1,\n") # 6 | |
tmp.append("\t\t\"0001111\" WHEN 1,\n") # 7 | |
tmp.append("\t\t\"0000000\" WHEN 1,\n") # 8 | |
tmp.append("\t\t\"0000100\" WHEN 1,\n") # 9 | |
tmp.append("\t\t\"1111111\" WHEN OTHERS;\n") | |
self.with_statements.append(tmp) | |
def to_hex(number): | |
assert type(number) == int, "number must be an integer" | |
if number == 0: | |
return "0000001" | |
elif number == 1: | |
return "1001111" | |
elif number == 2: | |
return "0010010" | |
elif number == 3: | |
return "0000110" | |
elif number == 4: | |
return "1001100" | |
elif number == 5: | |
return "0100100" | |
elif number == 6: | |
return "0100000" | |
elif number == 7: | |
return "0001111" | |
elif number == 8: | |
return "0000000" | |
elif number == 9: | |
return "0000100" | |
else: | |
print("Number to display on hex was invalid! ", number) | |
return "1111111" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment