Add basic yosys (nopy), klayout scripts and command support to designflow.

* New: In cumulus.designflow: add yosysnp to manage Yosys without
    Python support enabled.
      Add klayout support for running scripts in batch mode.
      Add generic system command support.
* Change: In cumulus.designflow.task.TaskFlow, systematically
    convert pathes (str) into pathlib.Path in targets and depends.
* New: In cumulus.designflow.clean.Clean, add cleaning by glob.
This commit is contained in:
Jean-Paul Chaput 2023-03-01 23:57:55 +01:00
parent 5546c2d89f
commit 50937d69c7
24 changed files with 281 additions and 78 deletions

View File

@ -16,8 +16,11 @@
${CMAKE_CURRENT_SOURCE_DIR}/designflow/graal.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/dreal.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/yosys.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/yosysnp.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/blif2vst.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/pnr.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/klayout.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/command.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/clean.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/alias.py
${CMAKE_CURRENT_SOURCE_DIR}/designflow/technos.py

View File

@ -7,12 +7,16 @@ class BadAliasDepend ( Exception ): pass
class Alias ( FlowTask ):
"""
Create an alias for a rule. Takes only two arguments, the aliased name
of the rule and the original rule itself.
"""
@staticmethod
def mkRule ( rule, depends=[] ):
return Alias( rule, depends )
def __init__ ( self, rule, depends, ):
def __init__ ( self, rule, depends ):
if len(depends) != 1:
raise BadAliasDepend( 'Alias.__init__(): There must be exactly *one* dependency ({})' \
.format( depends ))

View File

@ -21,9 +21,9 @@ class Asimut ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.vhdlFile = Path( self.file_depend(0) )
self.patFile = Path( self.file_depend(1) )
self.simFile = Path( self.targets[0] )
self.vhdlFile = self.file_depend(0)
self.patFile = self.file_depend(1)
self.simFile = self.targets[0]
self.command = [ 'asimut' ]
if flags & Asimut.RootIsBehavioral: self.command.append( '-b' )
if flags & Asimut.UseBdd: self.command.append( '-bdd' )

View File

@ -37,18 +37,20 @@ class Blif2Vst ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.flags = flags
if not self.targets[0].endswith('.vst'):
if not self.targets[0].suffix == '.vst':
raise TargetNotVst( 'Blif2Vst.__init__(): First target *must* "{}" be a vst file.' \
.format( self.targets[0] ))
self.addClean( self.targets )
def __repr__ ( self ):
for d in self.file_dep:
print( d )
return '<blif2vst {} depends=[{}]>' \
.format( self.design, ','.join(self.file_dep) )
.format( self.design, ','.join([f.as_posix() for f in self.file_dep]) )
@property
def design ( self ):
if len(self.targets): return self.targets[0][:-4]
if len(self.targets): return self.targets[0].stem
return None
def doTask ( self ):
@ -60,7 +62,7 @@ class Blif2Vst ( FlowTask ):
print( 'Blif2Vst.doTask() on "{}"'.format( self.design ))
views = CRL.Catalog.State.Logical | self.flags
cell = CRL.Blif.load( self.file_depend() )
cell = CRL.Blif.load( self.file_depend().as_posix() )
if cell.getName() == 'top':
print( ' o Renaming RTLIL anonymous top cell "top" into "{}".'.format(self.design) )
cell.setName( self.design )

View File

@ -27,8 +27,8 @@ class Boog ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.flags = flags
self.inputFile = Path( self.file_depend(0) )
self.outputFile = Path( self.targets[0] )
self.inputFile = self.file_depend(0)
self.outputFile = self.targets[0]
self.command = [ 'boog' ]
if flags & Boog.XschModeCritical: self.command += [ '-x', '0' ]
if flags & Boog.XschModeAll: self.command += [ '-x', '1' ]
@ -38,7 +38,7 @@ class Boog ( FlowTask ):
if flags & Boog.OptimDelaysMostly: self.command += [ '-m', '3' ]
if flags & Boog.OptimDelays: self.command += [ '-m', '4' ]
self.command += [ self.inputFile.stem, self.outputFile.stem ]
self.targets.append( self.outputFile.stem + '.xsc' )
self.targets.append( self.outputFile.with_suffix('.xsc') )
self.addClean( self.targets )
def __repr__ ( self ):

View File

@ -24,8 +24,8 @@ class Boom ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.flags = flags
self.inputFile = Path( self.file_depend(0) )
self.outputFile = Path( self.targets[0] )
self.inputFile = self.file_depend(0)
self.outputFile = self.targets[0]
self.command = [ 'boom' ]
if flags & Boom.Verbose: self.command.append( '-V' )
if flags & Boom.TraceOn: self.command.append( '-T' )

View File

@ -10,12 +10,13 @@ class MissingTarget ( Exception ): pass
class Clean ( FlowTask ):
@staticmethod
def mkRule ( extrasClean=[] ):
return Clean( extrasClean )
def mkRule ( extrasClean=[], extrasGlobs=[] ):
return Clean( extrasClean, extrasGlobs )
def __init__ ( self, extrasClean ):
def __init__ ( self, extrasClean, extrasGlobs ):
super().__init__( 'clean_flow', [], [] )
self.extrasClean = extrasClean
self.extrasClean = FlowTask._normFileList( extrasClean )
self.extrasGlobs = extrasGlobs
def __repr__ ( self ):
return '<clean>'
@ -23,8 +24,7 @@ class Clean ( FlowTask ):
def doTask ( self, doExtrasClean ):
print( ' Removing all target files' )
print( ' =========================' )
for fileName in FlowTask.cleanTargets:
filePath = Path( fileName )
for filePath in FlowTask.cleanTargets:
if filePath.is_file():
print( ' - {:<40} [removed]'.format( filePath.as_posix() ))
filePath.unlink()
@ -33,13 +33,20 @@ class Clean ( FlowTask ):
if doExtrasClean and len(self.extrasClean):
print( ' Removing extra clean files' )
print( ' ==========================' )
for fileName in self.extrasClean:
filePath = Path( fileName )
for filePath in self.extrasClean:
if filePath.is_file():
print( ' - {:<40} [removed]'.format( filePath.as_posix() ))
filePath.unlink()
else:
print( ' - {}'.format( filePath.as_posix() ))
if doExtrasClean and len(self.extrasGlobs):
print( ' Removing extra clean files (by glob)' )
print( ' ====================================' )
for directory, glob in self.extrasGlobs:
for filePath in Path(directory).glob(glob):
if filePath.is_file():
print( ' - {:<40} [removed]'.format( filePath.as_posix() ))
filePath.unlink()
return True
def create_doit_tasks ( self ):

View File

@ -0,0 +1,41 @@
import os
import subprocess
from pathlib import Path
from doit.exceptions import TaskFailed
from .task import FlowTask, ShellEnv
class MissingTarget ( Exception ): pass
class Command ( FlowTask ):
@staticmethod
def mkRule ( rule, targets=[], depends=[], command=None ):
return Command( rule, targets, depends, command )
def __init__ ( self, rule, targets, depends, command ):
super().__init__( rule, targets, depends )
self.command = command
self.addClean( self.targets )
def __repr__ ( self ):
return '<{}>'.format( ' '.join(self.command) )
def doTask ( self ):
from ..helpers.io import ErrorMessage
state = subprocess.run( self.command )
if state.returncode:
e = ErrorMessage( 1, 'Command.doTask(): UNIX command failed ({}).' \
.format( state.returncode ))
return TaskFailed( e )
return self.checkTargets( 'Command.doTask' )
def create_doit_tasks ( self ):
return { 'basename' : self.basename
, 'actions' : [ self.doTask ]
, 'doc' : 'Run {}.'.format( self )
, 'file_dep' : self.file_dep
}

View File

@ -17,8 +17,8 @@ class Copy ( FlowTask ):
def __init__ ( self, rule, targets, depends ):
super().__init__( rule, targets, depends )
self.sourceFile = Path( self.file_depend(0) )
self.targetFile = Path( self.targets[0] )
self.sourceFile = self.file_depend(0)
self.targetFile = self.targets[0]
self.addClean( self.targets )
def __repr__ ( self ):

View File

@ -25,8 +25,8 @@ class Cougar ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.flags = flags
self.inputFile = Path( self.file_depend(0) )
self.outputFile = Path( self.targets[0] )
self.inputFile = self.file_depend(0)
self.outputFile = self.targets[0]
self.command = [ 'cougar' ]
if flags & Cougar.Transistor: self.command.append( '-t' )
if flags & Cougar.Flatten: self.command.append( '-f' )

View File

@ -23,7 +23,7 @@ class Dreal ( FlowTask ):
def __init__ ( self, rule, depends, flags ):
super().__init__( rule, [], depends )
self.flags = flags
self.layoutFile = Path( self.file_depend(0) )
self.layoutFile = self.file_depend(0)
self.command = [ 'dreal', '-l', self.layoutFile.stem ]
if flags & Dreal.Debug: self.command.append( '-debug' )
if flags & Dreal.Xor: self.command.append( '-xor' )

View File

@ -20,10 +20,10 @@ class Druc ( FlowTask ):
def __init__ ( self, rule, depends, flags ):
super().__init__( rule, [], depends )
self.flags = flags
self.referenceFile = Path( self.file_depend(0) )
self.targets = [ self.referenceFile.stem + '.drc'
, self.referenceFile.stem + '_drc.gds'
, self.referenceFile.stem + '_rng.gds' ]
self.referenceFile = self.file_depend(0)
self.targets = [ self.referenceFile.with_suffix('.drc')
, Path(self.referenceFile.stem + '_drc.gds')
, Path(self.referenceFile.stem + '_rng.gds') ]
self.command = [ 'druc', self.referenceFile.stem ]
if flags & Druc.Verbose: self.command.append( '-v' )
self.addClean( self.targets )

View File

@ -22,14 +22,14 @@ class Flatph ( FlowTask ):
super().__init__( rule, targets, depends )
self.flags = flags
self.instFile = None
self.hierFile = Path( self.file_depend(0) )
self.flatFile = Path( self.targets[0] )
self.hierFile = self.file_depend(0)
self.flatFile = self.targets[0]
self.command = [ 'flatph' ]
if flags & Flatph.Transistor: self.command.append( '-t' )
if flags & Flatph.Catalog: self.command.append( '-r' )
self.command.append( self.hierFile.stem )
if len(self.targets) > 1:
self.instFile = Path( self.targets[1] )
self.instFile = self.targets[1]
self.command.append( self.instFile.stem )
self.command.append( self.flatFile.stem )
self.addClean( self.targets )

View File

@ -17,8 +17,8 @@ class Genpat ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.inputFile = Path( self.file_depend(0) )
self.outputFile = Path( self.targets[0] )
self.inputFile = self.file_depend(0)
self.outputFile = self.targets[0]
self.command = [ 'genpat' ]
self.command += [ self.inputFile.stem ]
self.addClean( self.targets )

View File

@ -23,7 +23,7 @@ class Graal ( FlowTask ):
def __init__ ( self, rule, depends, flags ):
super().__init__( rule, [], depends )
self.flags = flags
self.layoutFile = Path( self.file_depend(0) )
self.layoutFile = self.file_depend(0)
self.command = [ 'graal', '-l', self.layoutFile.stem ]
if flags & Graal.Debug: self.command.append( '-debug' )
if flags & Graal.Xor: self.command.append( '-xor' )

View File

@ -0,0 +1,50 @@
import os
import subprocess
from pathlib import Path
from doit.exceptions import TaskFailed
from .task import FlowTask, ShellEnv
class MissingTarget ( Exception ): pass
class Klayout ( FlowTask ):
Verbose = 0x0001
@staticmethod
def mkRule ( rule, targets=[], depends=[], script=None, variables={}, flags=0 ):
return Klayout( rule, targets, depends, script, variables, flags )
def __init__ ( self, rule, targets, depends, script, variables, flags ):
depends.insert( 0, script )
super().__init__( rule, targets, depends )
self.flags = flags
self.variable = variables
self.command = [ 'klayout' ]
for name, value in variables.items():
self.command += [ '-rd', '{}={}'.format(name,value) ]
self.command += [ '-b', '-r', self.file_depend(0).as_posix() ]
#self.addClean( self.targets )
def __repr__ ( self ):
return '<{}>'.format( ' '.join(self.command) )
def doTask ( self ):
from ..helpers.io import ErrorMessage
state = subprocess.run( self.command )
if state.returncode:
e = ErrorMessage( 1, 'Klayout.doTask(): UNIX command failed ({}).' \
.format( state.returncode ))
return TaskFailed( e )
return self.checkTargets( 'Klayout.doTask' )
def create_doit_tasks ( self ):
return { 'basename' : self.basename
, 'actions' : [ self.doTask ]
, 'doc' : 'Run {}.'.format( self )
, 'file_dep' : self.file_dep
}

View File

@ -27,8 +27,8 @@ class Loon ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.flags = flags
self.inputFile = Path( self.file_depend(0) )
self.outputFile = Path( self.targets[0] )
self.inputFile = self.file_depend(0)
self.outputFile = self.targets[0]
self.command = [ 'loon' ]
#print( 'flags=0x{:08x}'.format( flags ))
if flags & Loon.XschModeCritical: self.command += [ '-x', '0' ]
@ -39,7 +39,7 @@ class Loon ( FlowTask ):
if flags & Loon.OptimDelaysMostly: self.command += [ '-m', '3' ]
if flags & Loon.OptimDelays: self.command += [ '-m', '4' ]
self.command += [ self.inputFile.stem, self.outputFile.stem ]
self.targets.append( self.outputFile.stem + '.xsc' )
self.targets.append( self.outputFile.with_suffix('.xsc') )
self.addClean( self.targets )
def __repr__ ( self ):

View File

@ -25,8 +25,8 @@ class Lvx ( FlowTask ):
super().__init__( rule, [], depends )
self.flags = flags
self.referenceFile = Path( self.file_depend(0) )
self.checkedFile = Path( self.file_depend(1) )
self.referenceFile = self.file_depend(0)
self.checkedFile = self.file_depend(1)
self.command = [ 'lvx'
, self.referenceFile.suffix[1:]
, self.checkedFile.suffix[1:]
@ -39,7 +39,7 @@ class Lvx ( FlowTask ):
if self.flags & Lvx.SaveReorder:
env = CRL.AllianceFramework.get().getEnvironment()
self.targets = [ self.checkedFile.stem + '.' + env.getOUT_LO() ]
self.targets = [ self.checkedFile.with_suffix('.' + env.getOUT_LO()) ]
self.addClean( self.targets )
def __repr__ ( self ):

View File

@ -45,7 +45,7 @@ class PnR ( FlowTask ):
def __repr__ ( self ):
return '<pnr {} depends=[{}]>' \
.format( self.design, ','.join(self.file_dep) )
.format( self.design, ','.join([f.as_posix() for f in self.file_dep]) )
@property
def design ( self ):

View File

@ -24,8 +24,8 @@ class S2R ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.flags = flags
self.inputFile = Path( self.file_depend(0) )
self.outputFile = Path( self.targets[0] )
self.inputFile = self.file_depend(0)
self.outputFile = self.targets[0]
self.command = [ 's2r' ]
if flags & S2R.NoDenotch: self.command.append( '-t' )
if flags & S2R.DeleteNames: self.command.append( '-c' )

View File

@ -3,8 +3,9 @@ import os
from pathlib import Path
from doit.exceptions import TaskFailed
class BadDependency ( Exception ): pass
class DuplicatedRule ( Exception ): pass
class BadDependency ( Exception ): pass
class DuplicatedRule ( Exception ): pass
class UnsupportedFileType ( Exception ): pass
class ShellEnv ( object ):
@ -90,11 +91,13 @@ class FlowTask ( object ):
``create_doit_tasks()`` method. It alows task to be chained directly
between them instead of only through dependency/target files.
1. Targets management: targets are always file name, stored as strings.
1. Targets management: targets can be passed as plain files (string)
or pathlib.Path, but are all internally converted into Path.
2. Dependencies management: they can be plain files, pathlib.Path objects
or other tasks. In the later case, the dependencies are the *targets*
of said task, which sould be files, as stated on 1.
of said task, which sould be pathlib.Path, as stated on 1.
plain files are converted into pathlib.Path.
3. Perform an early check for homonymous tasks.
@ -105,6 +108,19 @@ class FlowTask ( object ):
rules = {}
cleanTargets = []
@staticmethod
def _normFile ( depend ):
if isinstance(depend,FlowTask) or isinstance(depend,Path): return depend
if isinstance(depend,str): return Path(depend)
raise UnsupportedFileType( 'FlowTask._normFile(): Unsupported type for "{}"'.format(depend) )
@staticmethod
def _normFileList ( depends ):
if not depends: return [];
if isinstance(depends,list):
return [ FlowTask._normFile(d) for d in depends ]
return [ FlowTask._normFile(depends) ]
def __init__ ( self, basename, targets, depends ):
"""
Promote ``targets`` and ``depends`` arguments to list if needed.
@ -113,12 +129,8 @@ class FlowTask ( object ):
if FlowTask.hasRule(basename):
raise DuplicatedRule( 'FlowTask.__init__(): Duplicated rule "{}"'.format(basename) )
self.basename = basename
if depends is None: self.depends = []
elif not isinstance(depends,list): self.depends = [ depends ]
else: self.depends = depends
if targets is None: self.targets = []
elif not isinstance(targets,list): self.targets = [ targets ]
else: self.targets = targets
self.depends = FlowTask._normFileList( depends )
self.targets = FlowTask._normFileList( targets )
FlowTask.rules[ self.basename ] = self
@staticmethod
@ -130,19 +142,13 @@ class FlowTask ( object ):
def file_dep ( self ):
"""
Build the list of dependencies to be passed on to doit (file_dep task dict).
Convert back pathlib.Path object to string. If the dependency is another
FlowTask, pass on it's own targets.
If the dependency is another FlowTask, pass on it's own targets.
All files are pathlib.Path.
"""
files = []
for depend in self.depends:
if isinstance(depend,str):
files += [ depend ]
elif isinstance(depend,Path):
files += [ depend.as_posix() ]
elif isinstance(depend,FlowTask):
files += depend.targets
else:
raise BadDependency( 'FlowTask.file_dep(): Unsupported kind of dependency {}.'.format(depend) )
if isinstance(depend,FlowTask): files += depend.targets
else: files += [ depend ]
return files
def file_target ( self, tindex=0 ):
@ -174,8 +180,7 @@ class FlowTask ( object ):
"""
from ..helpers.io import ErrorMessage
for target in self.targets:
path = Path( target )
if not path.is_file():
if not target.is_file():
e = ErrorMessage( 1, '{}(): The rule "{}" did *not* generate target "{}".' \
.format( methodName, self.basename, target ))
return TaskFailed( e )
@ -186,6 +191,6 @@ class FlowTask ( object ):
Add the targets list to the global list. This is a helper method
that has to be explicitely called in derived classes.
"""
FlowTask.cleanTargets += targets
FlowTask.cleanTargets += FlowTask._normFileList( targets )

View File

@ -23,11 +23,11 @@ class Vasy ( FlowTask ):
def __init__ ( self, rule, targets, depends, flags ):
super().__init__( rule, targets, depends )
self.flags = flags
self.vhdlFile = Path( self.file_depend(0) )
self.vhdlFile = self.file_depend(0)
if len(self.targets) > 1:
self.outputFile = Path( self.targets[1].stem+'.vbe' )
self.outputFile = self.targets[1].with_suffix('.vbe')
else:
self.outputFile = Path( self.targets[0] )
self.outputFile = self.targets[0]
self.command = [ 'vasy' ]
if flags & Vasy.Verbose: self.command.append( '-V' )
if flags & Vasy.UseStdLogic: self.command.append( '-S' )

View File

@ -38,11 +38,8 @@ class Yosys ( FlowTask ):
if top is not None:
self.top = top
else:
if self.main.find('.') == -1:
self.top = self.main
else:
self.top = '.'.join( self.main.split('.')[0:-1] )
self.targets = [ self.top + '.blif' ]
self.top = self.main.stem
self.targets = [ Path( self.top + '.blif') ]
self.addClean( self.targets )
def __repr__ ( self ):
@ -68,8 +65,8 @@ class Yosys ( FlowTask ):
e = ErrorMessage( 1, 'Yosys._loadDesign(): Can\'t find design file "{}".'.format( design ))
self.success = TaskFailed( e )
return
if design.endswith('.v' ): self._run_pass( 'read_verilog {}'.format( design ))
elif design.endswith('.il'): self._run_pass( 'read_ilang {}'.format( design ))
if design.suffix == '.v' : self._run_pass( 'read_verilog {}'.format( design.as_posix() ))
elif design.suffix == '.il': self._run_pass( 'read_ilang {}'.format( design.as_posix() ))
else:
e = ErrorMessage( 1, 'Yosys._loadDesign(): Unsupported input format for "{}".'.format( design ))
self.success = TaskFailed( e )

View File

@ -0,0 +1,94 @@
import os.path
import subprocess
from pathlib import Path
from pyosys import libyosys as yosys
from doit.exceptions import TaskFailed
from .task import FlowTask
class BadLiberty ( Exception ): pass
class YosysNp ( FlowTask ):
FlagLog = 0x00000001
FlagQuiet = 0x00000002
FlagUseYoWasp = 0x00000004
_liberty = None
@staticmethod
def setLiberty ( liberty ):
if isinstance(liberty,Path): pass
elif isinstance(liberty,str): liberty = Path( liberty )
else:
raise BadLiberty( '[ERROR] YosysNp.setLiberty(): Should be <str> or <Path> ({})' \
.format( liberty ))
if not liberty.is_file():
raise BadLiberty( '[ERROR] YosysNp.setLiberty(): File not found "{}"' \
.format( liberty ))
YosysNp._liberty = liberty
@staticmethod
def mkRule ( rule, targets, depends, script, top=None, flags=0 ):
return YosysNp( rule, targets, depends, script, top, flags )
def __init__ ( self, rule, targets, depends, script, top, flags ):
self.log = None
self.success = True
self.script = script
self.flags = flags
targets = FlowTask._normFileList( targets )
depends = FlowTask._normFileList( depends )
if top is not None:
self.top = top
else:
self.top = depends[0].stem
if targets == []:
targets.append( self.top + '.blif' )
if self.flags & YosysNp.FlagLog:
self.log = Path( self.top + '.log' )
targets.append( self.log )
targets.append( self.top + '.ys' )
super().__init__( rule, targets, depends )
self.addClean( targets )
def __repr__ ( self ):
return '<yosysnp {} top={}>'.format( self.main, self.top )
@property
def liberty ( self ):
return YosysNp._liberty
@property
def main ( self ):
return self.file_depend( 0 )
def doTask ( self ):
from ..helpers.io import ErrorMessage
if self.liberty is None:
e = ErrorMessage( 1, [ 'YosysNp.doTask(): "liberty" has not been set' ] )
return TaskFailed( e )
if not self.liberty.is_file():
e = ErrorMessage( 1, [ 'YosysNp.doTask(): File not found "{}"'
, '"{}"'.format( self.liberty.as_posix() ) ] )
return TaskFailed( e )
ysFile = Path(self.main).stem + '.ys'
with open( ysFile, 'w' ) as ysFd:
ysFd.write( self.script.format( liberty =str(self.liberty)
, cellname=self.main.stem
, top =self.top ))
command = [ 'yowasp-yosys' ] if self.flags & YosysNp.FlagUseYoWasp else [ 'yosys' ]
if self.flags & YosysNp.FlagQuiet: command += [ '-q' ]
if self.flags & YosysNp.FlagLog: command += [ '-l', self.log.as_posix() ]
command += [ '-s', ysFile ]
status = subprocess.call( command )
return status == 0
def create_doit_tasks ( self ):
return { 'basename' : self.basename
, 'actions' : [ self.doTask ]
, 'doc' : 'Run {}.'.format( self )
, 'file_dep' : self.file_dep
, 'targets' : self.targets
}