@@ -160,6 +160,13 @@ class VerilogDiagram(Directive):
160160 'caption' : directives .unchanged ,
161161 }
162162
163+ global_variable_options = {
164+ "verilog_diagram_output_format" : ["svg" , "png" ],
165+ "verilog_diagram_skin" : ["default" ], # or path
166+ "verilog_diagram_yosys_script" : ["default" ], # or path
167+ "verilog_diagram_yosys" : ["yowasp" , "system" ] # or path
168+ }
169+
163170 def run (self ):
164171 # type: () -> List[nodes.Node]
165172
@@ -229,19 +236,38 @@ def run(self):
229236 return [node ]
230237
231238
232- def run_yosys (src , cmd ):
233- ycmd = "yosys -p '{cmd}' {src}" .format (src = src , cmd = cmd )
234- print ("Running yosys:" , ycmd )
235- subprocess .check_output (ycmd , shell = True )
239+ def run_yosys (src , cmd , yosys = 'yowasp' ):
240+ if yosys == 'yowasp' :
241+ import yowasp_yosys
242+ ycmd = ["-q" , "-p" , "{}" .format (cmd ), src ]
243+ print ("Running YoWASP yosys: {}" .format (ycmd ))
244+ yowasp_yosys .run_yosys (ycmd )
245+ elif yosys == 'system' :
246+ ycmd = "yosys -p '{cmd}' {src}" .format (src = src , cmd = cmd )
247+ print ("Running yosys: {}" .format (ycmd ))
248+ subprocess .check_output (ycmd , shell = True )
249+ else :
250+ ycmd = "{yosys} -p '{cmd}' {src}" .format (yosys = yosys , src = src , cmd = cmd )
251+ print ("Running yosys: {}" .format (ycmd ))
252+ subprocess .check_output (ycmd , shell = True )
253+
254+
255+ def diagram_yosys (ipath , opath , module = 'top' , flatten = False ,
256+ yosys_script = 'default' , yosys = 'yowasp' ):
236257
258+ # Assertions
237259
238- def diagram_yosys (ipath , opath , module = 'top' , flatten = False , yosys_script = 'default' ):
239260 assert path .exists (ipath ), 'Input file missing: {}' .format (ipath )
240261 assert not path .exists (opath ), 'Output file exists: {}' .format (opath )
262+ yosys_options = VerilogDiagram .global_variable_options ["verilog_diagram_yosys" ]
263+ assert yosys in yosys_options or os .path .exists (yosys ), "Invalid verilog_diagram_yosys value!"
241264 if yosys_script != 'default' :
242265 assert path .exists (yosys_script ), 'Yosys script file missing: {}' .format (yosys_script )
243266 oprefix , oext = path .splitext (opath )
244267 assert oext .startswith ('.' ), oext
268+
269+ # Diagram generation
270+
245271 oext = oext [1 :]
246272
247273 if flatten :
@@ -254,12 +280,21 @@ def diagram_yosys(ipath, opath, module='top', flatten=False, yosys_script='defau
254280 else :
255281 yosys_script_cmd = "script {}" .format (yosys_script )
256282
257- run_yosys (
258- src = ipath ,
259- cmd = """\
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 (),
262- )
283+ yosys_cmd = "prep -top {top} {flatten}; cd {top}; {script}; show -format {fmt} -prefix {oprefix}" .format (
284+ top = module ,
285+ flatten = flatten ,
286+ fmt = oext ,
287+ oprefix = oprefix ,
288+ script = yosys_script_cmd
289+ ).strip ()
290+ run_yosys (ipath , yosys_cmd , yosys )
291+
292+ if yosys == 'yowasp' :
293+ # somehow yowasp_yosys fails to execute `dot` to convert the dot file to svg,
294+ # which works on native yosys, perhaps a limitation with wasm
295+ svgdata = subprocess .check_output (["dot" , "-Tsvg" , "{}.dot" .format (oprefix )])
296+ with open ("{}.svg" .format (oprefix ), "wb" ) as img :
297+ img .write (svgdata )
263298
264299 assert path .exists (opath ), 'Output file {} was not created!' .format (oopath )
265300 print ('Output file created: {}' .format (opath ))
@@ -268,7 +303,7 @@ def run_netlistsvg(ipath, opath, skin='default'):
268303 assert path .exists (ipath ), 'Input file missing: {}' .format (ipath )
269304 assert not path .exists (opath ), 'Output file exists: {}' .format (opath )
270305 if skin != 'default' :
271- assert path .exists (skin ), 'Skin file missing: {}' .format (skin )
306+ assert path .exists (skin ), 'Skin file missing: {}' .format (skin )
272307
273308 netlistsvg_cmd = "netlistsvg {ipath} -o {opath}" .format (ipath = ipath , opath = opath )
274309 if skin != 'default' :
@@ -281,15 +316,23 @@ def run_netlistsvg(ipath, opath, skin='default'):
281316 print ('netlistsvg - Output file created: {}' .format (opath ))
282317
283318
284- def diagram_netlistsvg (ipath , opath , module = 'top' , flatten = False , yosys_script = 'default' , skin = 'default' ):
319+ def diagram_netlistsvg (ipath , opath , module = 'top' , flatten = False ,
320+ yosys_script = 'default' , skin = 'default' , yosys = 'yowasp' ):
321+ # Assertions
322+
285323 assert path .exists (ipath ), 'Input file missing: {}' .format (ipath )
286324 assert not path .exists (opath ), 'Output file exists: {}' .format (opath )
325+ yosys_options = VerilogDiagram .global_variable_options ["verilog_diagram_yosys" ]
326+ assert yosys in yosys_options or os .path .exists (yosys ), "Invalid verilog_diagram_yosys value!"
287327 if yosys_script != 'default' :
288328 assert path .exists (yosys_script ), 'Yosys script file missing: {}' .format (yosys_script )
289329 if skin != 'default' :
290330 assert path .exists (skin ), 'Skin file missing: {}' .format (skin )
291331 oprefix , oext = path .splitext (opath )
292332 assert oext .startswith ('.' ), oext
333+
334+ # Diagram generation
335+
293336 oext = oext [1 :]
294337
295338 if flatten :
@@ -306,11 +349,14 @@ def diagram_netlistsvg(ipath, opath, module='top', flatten=False, yosys_script='
306349 if path .exists (ojson ):
307350 os .remove (ojson )
308351
309- run_yosys (
310- src = ipath ,
311- cmd = """\
312- prep -top {top} {flatten}; cd {top}; {script}; write_json {ojson}
313- """ .format (top = module , flatten = flatten , ojson = ojson , script = yosys_script_cmd ).strip ())
352+ yosys_cmd = """prep -top {top} {flatten}; cd {top}; {script}; write_json {compat} {ojson}""" .format (
353+ top = module ,
354+ flatten = flatten ,
355+ ojson = ojson ,
356+ script = yosys_script_cmd ,
357+ compat = "-compat-int" if yosys == 'yowasp' else ""
358+ ).strip ()
359+ run_yosys (ipath , yosys_cmd , yosys )
314360 assert path .exists (ojson ), 'Output file {} was not created!' .format (ojson )
315361
316362 run_netlistsvg (ojson , opath , skin )
@@ -336,14 +382,31 @@ def render_diagram(self, code, options, format, skin, yosys_script):
336382 yosys_script = options ['yosys_script' ] if options ['yosys_script' ] is not None else yosys_script
337383 skin = options ['skin' ] if options ['skin' ] is not None else skin
338384
385+ yosys = self .builder .config .verilog_diagram_yosys
386+ yosys_options = VerilogDiagram .global_variable_options ["verilog_diagram_yosys" ]
387+ if yosys not in yosys_options and not os .path .exists (yosys ):
388+ raise VerilogDiagramError ("Yosys not found!" )
389+ else :
390+ yosys = yosys if yosys in yosys_options else os .path .realpath (yosys )
391+
339392 diagram_type = options ['type' ]
340393 if diagram_type .startswith ('yosys' ):
341394 assert diagram_type .startswith ('yosys-' ), diagram_type
342395 diagram_yosys (
343- verilog_path , outfn , module = options ['module' ], flatten = options ['flatten' ], yosys_script = yosys_script )
396+ verilog_path ,
397+ outfn ,
398+ module = options ['module' ],
399+ flatten = options ['flatten' ],
400+ yosys_script = yosys_script ,
401+ yosys = yosys )
344402 elif diagram_type == 'netlistsvg' :
345403 diagram_netlistsvg (
346- verilog_path , outfn , module = options ['module' ], flatten = options ['flatten' ], skin = skin )
404+ verilog_path ,
405+ outfn ,
406+ module = options ['module' ],
407+ flatten = options ['flatten' ],
408+ skin = skin ,
409+ yosys = yosys )
347410 else :
348411 raise Exception ('Invalid diagram type "%s"' % diagram_type )
349412 #raise self.severe(\n' %
@@ -486,5 +549,5 @@ def setup(app):
486549 app .add_config_value ('verilog_diagram_output_format' , 'svg' , 'html' )
487550 app .add_config_value ('verilog_diagram_skin' , 'default' , 'html' )
488551 app .add_config_value ('verilog_diagram_yosys_script' , 'default' , 'html' )
552+ app .add_config_value ('verilog_diagram_yosys' , 'yowasp' , 'html' )
489553 return {'version' : '1.0' , 'parallel_read_safe' : True }
490-
0 commit comments