blob: a311301641612b751ed6d00c60b96d4024969c0c [file] [log] [blame]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001# Copyright lowRISC contributors.
2# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3# SPDX-License-Identifier: Apache-2.0
4"""
Rupert Swarbrick200d8b42021-03-08 12:32:11 +00005Generate HTML documentation from Block
lowRISC Contributors802543a2019-08-31 12:12:56 +01006"""
7
Rupert Swarbrick200d8b42021-03-08 12:32:11 +00008from typing import TextIO
9
Eunchan Kim2861a7c2022-07-29 11:52:36 -070010from reggen.ip_block import IpBlock
11from reggen.html_helpers import render_td
12from reggen.signal import Signal
Rupert Swarbrick302f0382021-02-05 13:32:02 +000013
lowRISC Contributors802543a2019-08-31 12:12:56 +010014
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000015def genout(outfile: TextIO, msg: str) -> None:
lowRISC Contributors802543a2019-08-31 12:12:56 +010016 outfile.write(msg)
17
18
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000019def name_width(x: Signal) -> str:
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +000020 if x.bits.width() == 1:
21 return x.name
22
23 return '{}[{}:0]'.format(x.name, x.bits.msb)
lowRISC Contributors802543a2019-08-31 12:12:56 +010024
25
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000026def gen_kv(outfile: TextIO, key: str, value: str) -> None:
Rupert Swarbrick6c831292021-02-25 17:08:53 +000027 genout(outfile,
28 '<p><i>{}:</i> {}</p>\n'.format(key, value))
lowRISC Contributors802543a2019-08-31 12:12:56 +010029
30
Rupert Swarbrick4f282bb2021-03-31 10:32:06 +010031def gen_cfg_html(cfgs: IpBlock, outfile: TextIO) -> None:
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000032 rnames = cfgs.get_rnames()
Rupert Swarbrick302f0382021-02-05 13:32:02 +000033
Rupert Swarbrick6c831292021-02-25 17:08:53 +000034 ot_server = 'https://docs.opentitan.org'
35 comport_url = ot_server + '/doc/rm/comportability_specification'
Eunchan Kim0bd75662020-04-24 10:21:18 -070036 genout(outfile,
Rupert Swarbrick6c831292021-02-25 17:08:53 +000037 '<p>Referring to the <a href="{url}">Comportable guideline for '
38 'peripheral device functionality</a>, the module '
39 '<b><code>{mod_name}</code></b> has the following hardware '
40 'interfaces defined.</p>\n'
41 .format(url=comport_url, mod_name=cfgs.name))
42
lowRISC Contributors802543a2019-08-31 12:12:56 +010043 # clocks
Rupert Swarbrick6c831292021-02-25 17:08:53 +000044 gen_kv(outfile,
45 'Primary Clock',
Rupert Swarbrickd0cbfad2021-06-29 17:04:51 +010046 '<b><code>{}</code></b>'.format(cfgs.clocking.primary.clock))
47 other_clocks = cfgs.clocking.other_clocks()
48 if other_clocks:
49 other_clocks_str = ['<b><code>{}</code></b>'.format(clk)
50 for clk in other_clocks]
51 gen_kv(outfile, 'Other Clocks', ', '.join(other_clocks_str))
lowRISC Contributors802543a2019-08-31 12:12:56 +010052 else:
Rupert Swarbrick6c831292021-02-25 17:08:53 +000053 gen_kv(outfile, 'Other Clocks', '<i>none</i>')
54
lowRISC Contributors802543a2019-08-31 12:12:56 +010055 # bus interfaces
Rupert Swarbrick6c831292021-02-25 17:08:53 +000056 dev_ports = ['<b><code>{}</code></b>'.format(port)
57 for port in cfgs.bus_interfaces.get_port_names(False, True)]
58 assert dev_ports
59 gen_kv(outfile, 'Bus Device Interfaces (TL-UL)', ', '.join(dev_ports))
60
61 host_ports = ['<b><code>{}</code></b>'.format(port)
62 for port in cfgs.bus_interfaces.get_port_names(True, False)]
63 if host_ports:
64 gen_kv(outfile, 'Bus Host Interfaces (TL-UL)', ', '.join(host_ports))
lowRISC Contributors802543a2019-08-31 12:12:56 +010065 else:
Rupert Swarbrick6c831292021-02-25 17:08:53 +000066 gen_kv(outfile, 'Bus Host Interfaces (TL-UL)', '<i>none</i>')
Rupert Swarbrick302f0382021-02-05 13:32:02 +000067
lowRISC Contributors802543a2019-08-31 12:12:56 +010068 # IO
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +000069 ios = ([('input', x) for x in cfgs.xputs[1]] +
70 [('output', x) for x in cfgs.xputs[2]] +
71 [('inout', x) for x in cfgs.xputs[0]])
Rupert Swarbrick302f0382021-02-05 13:32:02 +000072 if ios:
lowRISC Contributors802543a2019-08-31 12:12:56 +010073 genout(outfile, "<p><i>Peripheral Pins for Chip IO:</i></p>\n")
74 genout(
75 outfile, "<table class=\"cfgtable\"><tr>" +
76 "<th>Pin name</th><th>direction</th>" +
77 "<th>Description</th></tr>\n")
Rupert Swarbrick302f0382021-02-05 13:32:02 +000078 for direction, x in ios:
79 genout(outfile,
80 '<tr><td>{}</td><td>{}</td>{}</tr>'
81 .format(name_width(x),
82 direction,
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +000083 render_td(x.desc, rnames, None)))
lowRISC Contributors802543a2019-08-31 12:12:56 +010084 genout(outfile, "</table>\n")
85 else:
86 genout(outfile, "<p><i>Peripheral Pins for Chip IO: none</i></p>\n")
Rupert Swarbricke166d872021-02-05 13:34:35 +000087
Eunchan Kimfdcfb3b2022-08-01 15:39:32 -070088 # Inter-Module Signals
89 if not cfgs.inter_signals:
90 genout(outfile, "<p><em>Inter-Module Signals: none</em></p>\n")
91 else:
Eli Kim233dca22022-10-19 09:43:14 -070092 genout(outfile,
93 "<p><em>Inter-Module Signals:</em>\n" +
94 "<a href=\"/doc/rm/comportability_specification/#inter-signal-handling\">\n" +
95 "Reference</a></p>\n")
Eunchan Kimfdcfb3b2022-08-01 15:39:32 -070096
97 genout(outfile,
98 "<table class=\"cfgtable\">\n" +
99 " <caption>Inter-Module Signals</caption>\n" +
100 " <thead>\n" +
101 " <tr>\n" +
102 " <th>Port Name</th>\n" +
103 " <th>Package::Struct</th>\n" +
104 " <th>Type</th>\n" +
105 " <th>Act</th>\n" +
106 " <th>Width</th>\n" +
Michael Schaffnerea403862022-09-01 14:45:49 -0700107 " <th>Description</th>\n" +
Eunchan Kimfdcfb3b2022-08-01 15:39:32 -0700108 " </tr>\n" +
109 " </thead>\n" +
110 " <tbody>\n")
111
112 for ims in cfgs.inter_signals:
113 name = ims.name
114 pkg_struct = ims.package + "::" + ims.struct if ims.package is not None else ims.struct
115 sig_type = ims.signal_type
116 act = ims.act
117 width = str(ims.width) if ims.width is not None else "1"
Michael Schaffnerea403862022-09-01 14:45:49 -0700118 desc = ims.desc if ims.desc is not None else ""
Eunchan Kimfdcfb3b2022-08-01 15:39:32 -0700119 genout(outfile,
120 " <tr>\n" +
121 " <td>" + name + "</td>\n" +
122 " <td>" + pkg_struct + "</td>\n" +
Eli Kim233dca22022-10-19 09:43:14 -0700123 " <td>" + sig_type + "</td>\n" +
Eunchan Kimfdcfb3b2022-08-01 15:39:32 -0700124 " <td>" + act + "</td>\n" +
125 " <td>" + width + "</td>\n" +
Michael Schaffnerea403862022-09-01 14:45:49 -0700126 " <td>" + desc + "</td>\n" +
Eunchan Kimfdcfb3b2022-08-01 15:39:32 -0700127 " </tr>\n")
128 continue
129
130 genout(outfile,
131 " </tbody>\n" +
132 "</table>\n")
133
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +0000134 if not cfgs.interrupts:
Rupert Swarbricke166d872021-02-05 13:34:35 +0000135 genout(outfile, "<p><i>Interrupts: none</i></p>\n")
136 else:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100137 genout(outfile, "<p><i>Interrupts:</i></p>\n")
138 genout(
139 outfile, "<table class=\"cfgtable\"><tr><th>Interrupt Name</th>" +
Eli Kim233dca22022-10-19 09:43:14 -0700140 "<th>Type</th><th>Description</th></tr>\n")
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +0000141 for x in cfgs.interrupts:
Rupert Swarbrick302f0382021-02-05 13:32:02 +0000142 genout(outfile,
Eli Kim233dca22022-10-19 09:43:14 -0700143 '<tr><td>{}</td><td>{}</td>{}</tr>'
Rupert Swarbrick302f0382021-02-05 13:32:02 +0000144 .format(name_width(x),
Eli Kim233dca22022-10-19 09:43:14 -0700145 x.intr_type.name,
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +0000146 render_td(x.desc, rnames, None)))
lowRISC Contributors802543a2019-08-31 12:12:56 +0100147 genout(outfile, "</table>\n")
Rupert Swarbricke166d872021-02-05 13:34:35 +0000148
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +0000149 if not cfgs.alerts:
Rupert Swarbricke166d872021-02-05 13:34:35 +0000150 genout(outfile, "<p><i>Security Alerts: none</i></p>\n")
lowRISC Contributors802543a2019-08-31 12:12:56 +0100151 else:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100152 genout(outfile, "<p><i>Security Alerts:</i></p>\n")
153 genout(
154 outfile, "<table class=\"cfgtable\"><tr><th>Alert Name</th>" +
155 "<th>Description</th></tr>\n")
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +0000156 for x in cfgs.alerts:
Rupert Swarbrick302f0382021-02-05 13:32:02 +0000157 genout(outfile,
158 '<tr><td>{}</td>{}</tr>'
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +0000159 .format(x.name,
160 render_td(x.desc, rnames, None)))
lowRISC Contributors802543a2019-08-31 12:12:56 +0100161 genout(outfile, "</table>\n")
Michael Schaffnerd6f6f3e2021-12-10 15:26:08 -0800162
163 if not cfgs.countermeasures:
164 genout(outfile, "<p><i>Security Countermeasures: none</i></p>\n")
165 else:
166 genout(outfile, "<p><i>Security Countermeasures:</i></p>\n")
167 genout(
168 outfile, "<table class=\"cfgtable\"><tr><th>Countermeasure ID</th>" +
169 "<th>Description</th></tr>\n")
170 for cm in cfgs.countermeasures:
171 genout(outfile,
172 '<tr><td>{}</td>{}</tr>'
173 .format(cfgs.name.upper() + '.' + str(cm),
174 render_td(cm.desc, rnames, None)))
175 genout(outfile, "</table>\n")