115 lines
4.4 KiB
Python
Executable File
115 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import sys
|
|
import os
|
|
import os.path
|
|
import subprocess
|
|
import optparse
|
|
from helpers.io import ErrorMessage
|
|
from helpers.io import catch
|
|
|
|
|
|
class Yosys ( object ):
|
|
|
|
ReadRTLIL = 0x0001
|
|
ReadVerilog = 0x0002
|
|
Flatten = 0x0004
|
|
KeepTcl = 0x0008
|
|
ReadMask = ReadRTLIL | ReadVerilog
|
|
|
|
def __init__ ( self ):
|
|
self.flags = Yosys.ReadRTLIL
|
|
self.libertyFile = None
|
|
return
|
|
|
|
def setFlags ( self, mask, value ):
|
|
if value: self.flags |= mask
|
|
else: self.flags &= ~mask
|
|
return
|
|
|
|
def setFlatten ( self, value ): self.setFlags( Yosys.Flatten, True )
|
|
def setKeepTcl ( self, value ): self.setFlags( Yosys.KeepTcl, True )
|
|
|
|
def setLiberty ( self, libertyFile ):
|
|
if not os.path.isfile(libertyFile):
|
|
raise ErrorMessage( 1, [ 'Yosys.setLiberty(): Can\'t find liberty file.'
|
|
, '"%s"' % libertyFile ] )
|
|
|
|
self.libertyFile = libertyFile
|
|
return
|
|
|
|
def setInputRTLIL ( self ):
|
|
self.setFlags( Yosys.ReadMask , False )
|
|
self.setFlags( Yosys.ReadRTLIL, True )
|
|
return
|
|
|
|
def setInputVerilog ( self ):
|
|
self.setFlags( Yosys.ReadMask , False )
|
|
self.setFlags( Yosys.ReadVerilog, True )
|
|
return
|
|
|
|
def run ( self, designName, top='top' ):
|
|
if self.flags & Yosys.ReadRTLIL:
|
|
if not os.path.isfile(designName+'.il'):
|
|
raise ErrorMessage( 1, 'Yosys.run(): Can\'t find RTLIL design file "%s.il".' % designName )
|
|
tclScript = 'yosys read_ilang %(designName)s.il\n'
|
|
else:
|
|
if not os.path.isfile(designName+".v"):
|
|
raise ErrorMessage( 1, 'Yosys.run(): Can\'t find Verilog design file "%s.v".' % designName )
|
|
tclScript = 'yosys read_verilog %(designName)s.v\n'
|
|
|
|
tclScript += 'yosys hierarchy -check -top %(designTop)s\n' \
|
|
'yosys synth -top %(designTop)s\n'
|
|
|
|
if self.flags & Yosys.Flatten:
|
|
tclScript += 'yosys flatten %(designTop)s\n' \
|
|
'yosys hierarchy -top %(designTop)s\n'
|
|
|
|
tclScript += 'yosys dfflibmap -liberty %(libertyFile)s\n' \
|
|
'yosys memorydff\n' \
|
|
'yosys abc -liberty %(libertyFile)s\n' \
|
|
'yosys clean\n' \
|
|
'yosys write_blif %(designName)s.blif\n'
|
|
|
|
tclFile = designName + '.tcl'
|
|
tclFd = open( tclFile, 'w' )
|
|
tclFd.write( tclScript % { 'designName' : designName
|
|
, 'designTop' : top
|
|
, 'libertyFile': self.libertyFile
|
|
} )
|
|
tclFd.close()
|
|
|
|
status = subprocess.call( [ 'yosys', '-c', tclFile ] )
|
|
|
|
if not (self.flags & Yosys.KeepTcl): os.unlink( tclFile )
|
|
return status
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
parser = optparse.OptionParser()
|
|
parser.add_option ( '-d', '--design' , action='store' , type='string', dest='design' , help='The name of the design file, without extension.' )
|
|
parser.add_option ( '-t', '--top' , action='store' , type='string', dest='top'
|
|
, default='top' , help='The hierarchy top level name model.' )
|
|
parser.add_option ( '-f', '--flatten' , action='store_true', dest='flatten' , help='Flatten the design hierarchy.' )
|
|
parser.add_option ( '-k', '--keep-tcl' , action='store_true', dest='keepTcl' , help='Keep the Yosys TCL command script.' )
|
|
parser.add_option ( '-i', '--input-lang', action='store' , type='string', dest='inputLang', help='Set the input description language (RTLIL or Verilog).' )
|
|
parser.add_option ( '-l', '--liberty' , action='store' , type='string', dest='liberty' , help='Set the path to the liberty file (.lib).' )
|
|
(options, args) = parser.parse_args()
|
|
|
|
try:
|
|
yosys = Yosys()
|
|
if options.inputLang == 'Verilog': yosys.setInputVerilog()
|
|
if options.inputLang == 'RTLIL' : yosys.setInputRTLIL()
|
|
if options.flatten: yosys.setFlatten( True )
|
|
if options.keepTcl: yosys.setKeepTcl( True )
|
|
if options.liberty: yosys.setLiberty( options.liberty )
|
|
|
|
rcode = yosys.run( options.design, top=options.top )
|
|
|
|
except Exception, e:
|
|
catch( e )
|
|
sys.exit(2)
|
|
|
|
sys.exit( rcode )
|