blob: 8ada8eb0173cce454a5dfcdfe6bd266ba71c802d [file] [log] [blame]
#!/usr/bin/env python3
"""
Project Trellis Master HTML Generation Script
Usage:
html_all.py <output_folder>
"""
import os, sys, time
from os import path
from string import Template
import argparse
import database
import html_tilegrid
import html_bits
import fuzzloops
import pytrellis
import cell_html
import timing_dbs
import interconnect_html
trellis_docs_index = """
<html>
<head>
<title>Project Trellis HTML Documentation</title>
</head>
<body>
<h1>Project Trellis HTML Documentation</h1>
<p>Project Trellis is a project to document the ECP5 bitstream and internal architecture.</p>
<p>This repository contains HTML documentation automatically generated from the
<a href="https://github.com/SymbiFlow/prjtrellis">Project Trellis</a> database. The equivalent
machine-readable data is located in <a href="https://github.com/SymbiFlow/prjtrellis-db">prjtrellis-db.<a/>
Data generated includes tilemap data and bitstream data for many tile types. Click on any tile to see its bitstream
documentation.
</p>
<p>More human-readable documentation on the ECP5 architecture and the Project Trellis methodology can be found
on the <a href="http://prjtrellis.readthedocs.io/en/latest/">Read the Docs</a> site.</p>
<p>This HTML documentation was generated at ${datetime} from prjtrellis-db commit
<a href="https://github.com/SymbiFlow/prjtrellis-db/tree/${commit}">${commit}</a>.</p>
<hr/>
$docs_toc
<hr/>
<p>Licensed under a very permissive <a href="COPYING">CC0 1.0 Universal</a> license.</p>
</body>
</html>
"""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('fld', type=str,
help="output folder")
def generate_device_docs(family, device, folder):
html_tilegrid.main(["html_tilegrid", family, device, path.join(folder, "index.html")])
def generate_tile_docs(family, device, tile, folder):
html_bits.main(["html_bits", family, device, tile, path.join(folder, "{}.html".format(tile))])
def get_device_tiles(family, devices):
all_tiles = set()
fd_tiles = {}
for dev, devdata in sorted(devices.items()):
if devdata["fuzz"]:
fd_tiles[family, dev] = []
c = pytrellis.Chip(dev)
for tile in c.get_all_tiles():
tt = tile.info.type
if tt not in all_tiles:
all_tiles.add(tt)
fd_tiles[family, dev].append(tt)
return fd_tiles
def main(argv):
args = parser.parse_args(argv[1:])
if not path.exists(args.fld):
os.mkdir(args.fld)
commit_hash = database.get_db_commit()
build_dt = time.strftime('%Y-%m-%d %H:%M:%S')
docs_toc = ""
pytrellis.load_database(database.get_db_root())
for fam, fam_data in sorted(database.get_devices()["families"].items()):
if fam == "MachXO2":
continue
fdir = path.join(args.fld, fam)
if not path.exists(fdir):
os.mkdir(fdir)
thdir = path.join(fdir, "tilehtml")
if not path.exists(thdir):
os.mkdir(thdir)
docs_toc += "<h3>{} Family</h3>".format(fam)
docs_toc += "<h4>Bitstream Documentation</h4>"
docs_toc += "<ul>"
tiles = get_device_tiles(fam, fam_data["devices"])
for dev, devdata in sorted(fam_data["devices"].items()):
if devdata["fuzz"]:
ddir = path.join(fdir, dev)
if not path.exists(ddir):
os.mkdir(ddir)
print("********* Generating documentation for device {}".format(dev))
generate_device_docs(fam, dev, ddir)
if (fam, dev) in tiles:
for tile in tiles[fam, dev]:
print("*** Generating documentation for tile {}".format(tile))
generate_tile_docs(fam, dev, tile, thdir)
docs_toc += '<li><a href="{}">{} Documentation</a></li>'.format(
'{}/{}/index.html'.format(fam, dev),
dev
)
docs_toc += "</ul>"
docs_toc += "<h4>Cell Timing Documentation</h4>"
docs_toc += "<ul>"
for spgrade in ["6", "7", "8", "8_5G"]:
tdir = path.join(fdir, "timing")
if not path.exists(tdir):
os.mkdir(tdir)
docs_toc += '<li><a href="{}">Speed Grade -{}</a></li>'.format(
'{}/timing/cell_timing_{}.html'.format(fam, spgrade),
spgrade
)
cell_html.make_cell_timing_html(timing_dbs.cells_db_path(fam, spgrade), fam, spgrade,
path.join(tdir, 'cell_timing_{}.html'.format(spgrade)))
docs_toc += "</ul>"
docs_toc += "<h4>Interconnect Timing Documentation</h4>"
docs_toc += "<ul>"
for spgrade in ["6", "7", "8", "8_5G"]:
tdir = path.join(fdir, "timing")
if not path.exists(tdir):
os.mkdir(tdir)
docs_toc += '<li><a href="{}">Speed Grade -{}</a></li>'.format(
'{}/timing/interconn_timing_{}.html'.format(fam, spgrade),
spgrade
)
interconnect_html.make_interconn_timing_html(timing_dbs.interconnect_db_path(fam, spgrade), fam, spgrade,
path.join(tdir, 'interconn_timing_{}.html'.format(spgrade)))
docs_toc += "</ul>"
index_html = Template(trellis_docs_index).substitute(
datetime=build_dt,
commit=commit_hash,
docs_toc=docs_toc
)
with open(path.join(args.fld, "index.html"), 'w') as f:
f.write(index_html)
if __name__ == "__main__":
main(sys.argv)