|
|
|
#!/usr/bin/python3
|
|
|
|
|
|
|
|
# Create makefile dependencies for VHDL files, looking for "use work" and
|
|
|
|
# "entity work" declarations
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import re
|
|
|
|
import os
|
|
|
|
from collections import defaultdict
|
|
|
|
|
|
|
|
if len(sys.argv) == 1 and sys.argv[1] == '--help':
|
|
|
|
print("Usage: dependencies.py [--synth]")
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
synth = False
|
|
|
|
args = sys.argv[1:]
|
|
|
|
if sys.argv[1] == '--synth':
|
|
|
|
synth = True
|
|
|
|
args = sys.argv[2:]
|
|
|
|
|
|
|
|
# Look at what a file provides
|
|
|
|
entity = re.compile('entity (.*) is')
|
|
|
|
package = re.compile('package (.*) is')
|
|
|
|
|
|
|
|
# Look at what a file depends on
|
|
|
|
work = re.compile('use work\.([^.]+)\.')
|
|
|
|
entity_work = re.compile('entity work\.([^;]+)')
|
|
|
|
|
|
|
|
# Synthesis targets
|
|
|
|
synth_provides = {
|
|
|
|
"dmi_dtm" : "dmi_dtm_dummy.vhdl",
|
|
|
|
"clock_generator" : "fpga/clk_gen_bypass.vhd",
|
|
|
|
"main_bram" : "fpga/main_bram.vhdl",
|
|
|
|
"pp_soc_uart" : "fpga/pp_soc_uart.vhd"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Simulation targets
|
|
|
|
sim_provides = {
|
|
|
|
"dmi_dtm" : "dmi_dtm_xilinx.vhdl",
|
|
|
|
"clock_generator" : "fpga/clk_gen_bypass.vhd",
|
|
|
|
"main_bram" : "sim_bram.vhdl",
|
|
|
|
"pp_soc_uart" : "sim_pp_uart.vhdl"
|
|
|
|
}
|
|
|
|
|
|
|
|
if synth:
|
|
|
|
provides = synth_provides
|
|
|
|
else:
|
|
|
|
provides = sim_provides
|
|
|
|
|
|
|
|
dependencies = defaultdict(set)
|
|
|
|
|
|
|
|
for filename in args:
|
|
|
|
with open(filename, 'r') as f:
|
|
|
|
for line in f:
|
|
|
|
l = line.rstrip(os.linesep)
|
|
|
|
m = entity.search(l)
|
|
|
|
if m:
|
|
|
|
p = m.group(1)
|
|
|
|
if p not in provides:
|
|
|
|
provides[p] = filename
|
|
|
|
|
|
|
|
m = package.search(l)
|
|
|
|
if m:
|
|
|
|
p = m.group(1)
|
|
|
|
if p not in provides:
|
|
|
|
provides[p] = filename
|
|
|
|
|
|
|
|
m = work.search(l)
|
|
|
|
if m:
|
|
|
|
dependency = m.group(1)
|
|
|
|
dependencies[filename].add(dependency)
|
|
|
|
|
|
|
|
m = entity_work.search(l)
|
|
|
|
if m:
|
|
|
|
dependency = m.group(1)
|
|
|
|
dependencies[filename].add(dependency)
|
|
|
|
|
|
|
|
|
|
|
|
emitted = set()
|
|
|
|
def chase_dependencies(filename):
|
|
|
|
if filename not in dependencies:
|
|
|
|
if filename not in emitted:
|
|
|
|
print("%s " % (filename), end="")
|
|
|
|
emitted.add(filename)
|
|
|
|
else:
|
|
|
|
for dep in dependencies[filename]:
|
|
|
|
f = provides[dep]
|
|
|
|
chase_dependencies(f)
|
|
|
|
if f not in emitted:
|
|
|
|
print("%s " % (f), end="")
|
|
|
|
emitted.add(f)
|
|
|
|
|
|
|
|
|
|
|
|
if synth:
|
|
|
|
chase_dependencies("fpga/toplevel.vhdl")
|
|
|
|
print("fpga/toplevel.vhdl")
|
|
|
|
else:
|
|
|
|
for filename in dependencies:
|
|
|
|
(basename, suffix) = filename.split('.')
|
|
|
|
print("%s.o:" % (basename), end="")
|
|
|
|
for dependency in dependencies[filename]:
|
|
|
|
p = provides[dependency]
|
|
|
|
(basename2, suffix2) = p.split('.')
|
|
|
|
print(" %s.o" % (basename2), end="")
|
|
|
|
print("")
|