Skip to content

Commit dc60c26

Browse files
committed
Add skin and yosys_script options
The :skin: option allows providing a skin file to netlistsvg. The :yosys_script: option gives the possibility to use additional Yosys commands during the diagram generation. Signed-off-by: Robert Winkler <rwinkler@antmicro.com>
1 parent 8c16b8f commit dc60c26

File tree

2 files changed

+69
-16
lines changed

2 files changed

+69
-16
lines changed

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,11 @@ Check out the `examples <https://sphinxcontrib-verilog-diagrams.readthedocs.io/e
101101

102102
.. code-block:: rst
103103
104-
105104
.. verilog-diagram:: file.v
106105
:type: XXXXX
107106
:module: XXXX
107+
:skin: XXXX
108+
:yosys_script: XXXX
108109
:flatten:
109110
110111
Options

sphinxcontrib_verilog_diagrams/__init__.py

Lines changed: 67 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ class VerilogDiagram(Directive):
152152
'type': str,
153153
'module': str,
154154
'flatten': bool,
155+
'skin': str,
156+
'yosys_script': str,
155157

156158
'alt': directives.unchanged,
157159
'align': align_spec,
@@ -199,6 +201,26 @@ def run(self):
199201
if 'align' in self.options:
200202
node['align'] = self.options['align']
201203

204+
yosys_script = self.options.get('yosys_script', None)
205+
if yosys_script not in [None, 'default']:
206+
_, yosys_script_filename = env.relfn2path(yosys_script)
207+
if not path.exists(yosys_script_filename):
208+
raise VerilogDiagramError("Yosys script {} does not exist!".format(yosys_script_filename))
209+
else:
210+
node['options']['yosys_script'] = yosys_script_filename
211+
else:
212+
node['options']['yosys_script'] = yosys_script
213+
214+
skin = self.options.get('skin', None)
215+
if skin not in [None, 'default']:
216+
_, skin_filename = env.relfn2path(skin)
217+
if not os.path.exists(skin_filename):
218+
raise VerilogDiagramError("Skin file {} does not exist!".format(skin_filename))
219+
else:
220+
node['options']['skin'] = skin_filename
221+
else:
222+
node['options']['skin'] = skin
223+
202224
caption = self.options.get('caption')
203225
if caption:
204226
node = figure_wrapper(self, node, caption)
@@ -213,9 +235,11 @@ def run_yosys(src, cmd):
213235
subprocess.check_output(ycmd, shell=True)
214236

215237

216-
def diagram_yosys(ipath, opath, module='top', flatten=False):
238+
def diagram_yosys(ipath, opath, module='top', flatten=False, yosys_script='default'):
217239
assert path.exists(ipath), 'Input file missing: {}'.format(ipath)
218240
assert not path.exists(opath), 'Output file exists: {}'.format(opath)
241+
if yosys_script != 'default':
242+
assert path.exists(yosys_script), 'Yosys script file missing: {}'.format(yosys_script)
219243
oprefix, oext = path.splitext(opath)
220244
assert oext.startswith('.'), oext
221245
oext = oext[1:]
@@ -225,33 +249,43 @@ def diagram_yosys(ipath, opath, module='top', flatten=False):
225249
else:
226250
flatten = ''
227251

252+
if yosys_script == 'default':
253+
yosys_script_cmd = ""
254+
else:
255+
yosys_script_cmd = "script {}".format(yosys_script)
256+
228257
run_yosys(
229258
src=ipath,
230259
cmd = """\
231-
prep -top {top} {flatten}; cd {top}; show -format {fmt} -prefix {oprefix}
232-
""".format(top=module, flatten=flatten, fmt=oext, oprefix=oprefix).strip(),
260+
prep -top {top} {flatten}; cd {top}; {script}; show -format {fmt} -prefix {oprefix}
261+
""".format(top=module, flatten=flatten, fmt=oext, oprefix=oprefix, script=yosys_script_cmd).strip(),
233262
)
234263

235264
assert path.exists(opath), 'Output file {} was not created!'.format(oopath)
236265
print('Output file created: {}'.format(opath))
237266

238-
239-
def run_netlistsvg(ipath, opath, skin=None):
267+
def run_netlistsvg(ipath, opath, skin='default'):
240268
assert path.exists(ipath), 'Input file missing: {}'.format(ipath)
241269
assert not path.exists(opath), 'Output file exists: {}'.format(opath)
270+
if skin != 'default':
271+
assert path.exists(skin), 'Skin file missing: {}'.format(skin)
242272

243273
netlistsvg_cmd = "netlistsvg {ipath} -o {opath}".format(ipath=ipath, opath=opath)
244-
if skin:
274+
if skin != 'default':
245275
netlistsvg_cmd += " --skin {skin}".format(skin=skin)
246276
subprocess.check_output(netlistsvg_cmd, shell=True)
247277

248278
assert path.exists(opath), 'Output file {} was not created!'.format(opath)
249279
print('netlistsvg - Output file created: {}'.format(opath))
250280

251281

252-
def diagram_netlistsvg(ipath, opath, module='top', flatten=False):
282+
def diagram_netlistsvg(ipath, opath, module='top', flatten=False, yosys_script='default', skin='default'):
253283
assert path.exists(ipath), 'Input file missing: {}'.format(ipath)
254284
assert not path.exists(opath), 'Output file exists: {}'.format(opath)
285+
if yosys_script != 'default':
286+
assert path.exists(yosys_script), 'Yosys script file missing: {}'.format(yosys_script)
287+
if skin != 'default':
288+
assert path.exists(skin), 'Skin file missing: {}'.format(skin)
255289
oprefix, oext = path.splitext(opath)
256290
assert oext.startswith('.'), oext
257291
oext = oext[1:]
@@ -261,22 +295,27 @@ def diagram_netlistsvg(ipath, opath, module='top', flatten=False):
261295
else:
262296
flatten = ''
263297

298+
if yosys_script == 'default':
299+
yosys_script_cmd = ""
300+
else:
301+
yosys_script_cmd = "script {}".format(yosys_script)
302+
264303
ojson = oprefix + '.json'
265304
if path.exists(ojson):
266305
os.remove(ojson)
267306

268307
run_yosys(
269308
src=ipath,
270309
cmd = """\
271-
prep -top {top} {flatten}; cd {top}; write_json {ojson}
272-
""".format(top=module, flatten=flatten, ojson=ojson).strip())
310+
prep -top {top} {flatten}; cd {top}; {script}; write_json {ojson}
311+
""".format(top=module, flatten=flatten, ojson=ojson, script=yosys_script_cmd).strip())
273312
assert path.exists(ojson), 'Output file {} was not created!'.format(ojson)
274313

275-
run_netlistsvg(ojson, opath)
314+
run_netlistsvg(ojson, opath, skin)
276315
print('netlistsvg - Output file created: {}'.format(ojson))
277316

278317

279-
def render_diagram(self, code, options, format):
318+
def render_diagram(self, code, options, format, skin, yosys_script):
280319
# type: (nodes.NodeVisitor, unicode, Dict, unicode, unicode) -> Tuple[unicode, unicode]
281320
"""Render verilog_diagram code into a PNG or SVG output file."""
282321

@@ -292,14 +331,17 @@ def render_diagram(self, code, options, format):
292331

293332
ensuredir(path.dirname(outfn))
294333

334+
yosys_script = options['yosys_script'] if options['yosys_script'] is not None else yosys_script
335+
skin = options['skin'] if options['skin'] is not None else skin
336+
295337
diagram_type = options['type']
296338
if diagram_type.startswith('yosys'):
297339
assert diagram_type.startswith('yosys-'), diagram_type
298340
diagram_yosys(
299-
verilog_path, outfn, module=options['module'], flatten=options['flatten'])
341+
verilog_path, outfn, module=options['module'], flatten=options['flatten'], yosys_script=yosys_script)
300342
elif diagram_type == 'netlistsvg':
301343
diagram_netlistsvg(
302-
verilog_path, outfn, module=options['module'], flatten=options['flatten'])
344+
verilog_path, outfn, module=options['module'], flatten=options['flatten'], skin=skin)
303345
else:
304346
raise Exception('Invalid diagram type "%s"' % diagram_type)
305347
#raise self.severe(\n' %
@@ -311,13 +353,21 @@ def render_diagram(self, code, options, format):
311353
def render_diagram_html(
312354
self, node, code, options, imgcls=None, alt=None):
313355
# type: (nodes.NodeVisitor, verilog_diagram, unicode, Dict, unicode, unicode, unicode) -> Tuple[unicode, unicode] # NOQA
314-
format = self.builder.config.verilog_diagram_output_format
315356

357+
yosys_script = self.builder.config.verilog_diagram_yosys_script
358+
if yosys_script != 'default' and not path.exists(yosys_script):
359+
raise VerilogDiagramError("Yosys script file {} does not exist! Change verilog_diagram_yosys_script variable".format(yosys_script))
360+
361+
skin = self.builder.config.verilog_diagram_skin
362+
if skin != 'default' and not path.exists(skin):
363+
raise VerilogDiagramError("Skin file {} does not exist! Change verilog_diagram_skin variable".format(skin))
364+
365+
format = self.builder.config.verilog_diagram_output_format
316366
try:
317367
if format not in ('png', 'svg'):
318368
raise VerilogDiagramError("verilog_diagram_output_format must be one of 'png', "
319369
"'svg', but is %r" % format)
320-
fname, outfn = render_diagram(self, code, options, format)
370+
fname, outfn = render_diagram(self, code, options, format, skin, yosys_script)
321371
except VerilogDiagramError as exc:
322372
logger.warning('verilog_diagram code %r: ' % code + str(exc))
323373
raise nodes.SkipNode
@@ -432,5 +482,7 @@ def setup(app):
432482
app.add_directive('verilog-diagram', VerilogDiagram)
433483
app.add_directive('no-license', NoLicenseInclude)
434484
app.add_config_value('verilog_diagram_output_format', 'svg', 'html')
485+
app.add_config_value('verilog_diagram_skin', 'default', 'html')
486+
app.add_config_value('verilog_diagram_yosys_script', 'default', 'html')
435487
return {'version': '1.0', 'parallel_read_safe': True}
436488

0 commit comments

Comments
 (0)