From 662b0124b83666e95ee8d01cfef1e473746a40b2 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 31 Aug 2023 16:14:51 +0200 Subject: [PATCH] Add partial support for SVase and sv2v to the DesignFlow. --- cumulus/src/CMakeLists.txt | 2 + cumulus/src/designflow/sv2v.py | 77 +++++++++++++++++++++++++++++ cumulus/src/designflow/svase.py | 86 +++++++++++++++++++++++++++++++++ cumulus/src/designflow/yosys.py | 5 +- 4 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 cumulus/src/designflow/sv2v.py create mode 100644 cumulus/src/designflow/svase.py diff --git a/cumulus/src/CMakeLists.txt b/cumulus/src/CMakeLists.txt index 139fdaeb..4c2ce127 100644 --- a/cumulus/src/CMakeLists.txt +++ b/cumulus/src/CMakeLists.txt @@ -15,6 +15,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/designflow/druc.py ${CMAKE_CURRENT_SOURCE_DIR}/designflow/graal.py ${CMAKE_CURRENT_SOURCE_DIR}/designflow/dreal.py + ${CMAKE_CURRENT_SOURCE_DIR}/designflow/sv2v.py + ${CMAKE_CURRENT_SOURCE_DIR}/designflow/svase.py ${CMAKE_CURRENT_SOURCE_DIR}/designflow/yosys.py ${CMAKE_CURRENT_SOURCE_DIR}/designflow/yosysnp.py ${CMAKE_CURRENT_SOURCE_DIR}/designflow/blif2vst.py diff --git a/cumulus/src/designflow/sv2v.py b/cumulus/src/designflow/sv2v.py new file mode 100644 index 00000000..177f7d21 --- /dev/null +++ b/cumulus/src/designflow/sv2v.py @@ -0,0 +1,77 @@ + +import os.path +import subprocess +from pathlib import Path +from pyosys import libyosys as yosys +from doit.exceptions import TaskFailed +from .task import FlowTask + + +def printCommand ( command ): + commandBin = command[0] + print( commandBin, command[1] ) + for arg in command[2:]: + print( ' '*len(commandBin), arg ) + + +class Sv2v ( FlowTask ): + + FlagLog = 0x00000001 + + @staticmethod + def mkRule ( rule, targets, depends, top=None, incdirs=[], libdirs=[], defines=[], flags=0 ): + return Sv2v( rule, targets, depends, top, incdirs, libdirs, defines, flags ) + + def __init__ ( self, rule, targets, depends, top, incdirs, libdirs, defines, flags ): + self.flags = flags + self.incdirs = incdirs + self.libdirs = libdirs + self.defines = defines + self.log = None + self.success = True + 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 + '.v' ) + #if self.flags & Sv2v.FlagLog: + # self.log = Path( self.top + '.log' ) + # targets.append( self.log ) + super().__init__( rule, targets, depends ) + self.addClean( targets ) + + def __repr__ ( self ): + return ''.format( self.main, self.top ) + + @property + def main ( self ): + return self.file_depend( 0 ) + + def doTask ( self ): + from ..helpers.io import ErrorMessage + for incdir in self.incdirs: + if not Path(incdir).is_dir(): + e = ErrorMessage( 1, [ 'Sv2v.doTask(): Include directory not found "{}"' + , '"{}"'.format( incdir ) ] ) + return TaskFailed( e ) + command = [ 'sv2v' ] + command += [ '--define={}'.format(d) for d in self.defines ] + command += [ '--incdir={}'.format(i) for i in self.incdirs ] + command += [ '--libdir={}'.format(l) for l in self.libdirs ] + command += [ '--top={}'.format( self.top ) ] + command += [ depend.as_posix() for depend in self.depends ] + printCommand( command ) + with open( self.file_target(), 'w' ) as fdOut: + status = subprocess.call( command, stdout=fdOut ) + 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 + } diff --git a/cumulus/src/designflow/svase.py b/cumulus/src/designflow/svase.py new file mode 100644 index 00000000..ec096c7c --- /dev/null +++ b/cumulus/src/designflow/svase.py @@ -0,0 +1,86 @@ + +import os.path +import subprocess +from pathlib import Path +from pyosys import libyosys as yosys +from doit.exceptions import TaskFailed +from .task import FlowTask + + +def printCommand ( command ): + commandBin = command[0] + print( commandBin, command[1] ) + for arg in command[2:]: + print( ' '*len(commandBin), arg ) + + +class Svase ( FlowTask ): + + FlagLog = 0x00000001 + + @staticmethod + def mkRule ( rule, targets, depends, top=None, incdirs=[], libdirs=[], defines=[], svargs=[], flags=0 ): + return Svase( rule, targets, depends, top, incdirs, libdirs, defines, svargs, flags ) + + def __init__ ( self, rule, targets, depends, top, incdirs, libdirs, defines, svargs, flags ): + self.flags = flags + self.svargs = svargs + self.incdirs = incdirs + self.libdirs = libdirs + self.defines = defines + self.log = None + self.success = True + 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 + '.v' ) + #if self.flags & Svase.FlagLog: + # self.log = Path( self.top + '.log' ) + # targets.append( self.log ) + super().__init__( rule, targets, depends ) + self.addClean( targets ) + + def __repr__ ( self ): + return ''.format( self.top, self.file_target(0), self.main ) + + @property + def main ( self ): + return self.file_depend( 0 ) + + def doTask ( self ): + from ..helpers.io import ErrorMessage + for incdir in self.incdirs: + if not Path(incdir).is_dir(): + e = ErrorMessage( 1, [ 'Svase.doTask(): Include directory not found.' + , '"{}"'.format( incdir ) ] ) + return TaskFailed( e ) + with open( 'slang-args.txt', 'w' ) as fdSlangArgs: + for svarg in self.svargs: + fdSlangArgs.write( '{}\n'.format(svarg) ) + for define in self.defines: + fdSlangArgs.write( '-D{}\n'.format(define) ) + for incdir in self.incdirs: + fdSlangArgs.write( '--include-directory {}\n'.format(incdir) ) + for libdir in self.libdirs: + fdSlangArgs.write( '--libdir {}\n'.format(libdir) ) + + command = [ 'svase' ] + command += [ '--slang-argfile=slang-args.txt' ] + command += [ self.top ] + command += [ self.file_target(0) ] + command += [ depend.as_posix() for depend in self.depends ] + printCommand( command ) + 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 + } diff --git a/cumulus/src/designflow/yosys.py b/cumulus/src/designflow/yosys.py index bc7ff40d..69e55a60 100644 --- a/cumulus/src/designflow/yosys.py +++ b/cumulus/src/designflow/yosys.py @@ -65,8 +65,9 @@ class Yosys ( FlowTask ): e = ErrorMessage( 1, 'Yosys._loadDesign(): Can\'t find design file "{}".'.format( design )) self.success = TaskFailed( e ) return - 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() )) + design = Path( design ) + if design.suffix == '.v' : self._run_pass( 'read_verilog -sv {}'.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 )