Skip to content

Instantly share code, notes, and snippets.

@RF5
Created April 23, 2018 20:27
Show Gist options
  • Save RF5/2ea407bf512ab2c94b1a918942cfeb75 to your computer and use it in GitHub Desktop.
Save RF5/2ea407bf512ab2c94b1a918942cfeb75 to your computer and use it in GitHub Desktop.
Python script to generate VHDL, currently for a DE0 FPGA board.
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