PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/SyntheSys/SysGen/__main__.py

https://gitlab.com/Yabolo/SyntheSys
Python | 363 lines | 337 code | 7 blank | 19 comment | 12 complexity | bf74e3debf2cec4f5a54029c5c87a2d1 MD5 | raw file
  1. #!/usr/bin/python3
  2. #-----------------------------
  3. VERSION="1.0"
  4. DATETIME="2014-06-25 at 18:21:47"
  5. MODULE="SysGen"
  6. NAME="SysGen"
  7. DESCRIPTION="A FPGA system generator"
  8. #-----------------------------
  9. import os, sys, logging, argparse, subprocess
  10. try:
  11. import configparser
  12. except ImportError:
  13. import configparser as configparser
  14. from openpyxl import Workbook
  15. import datetime, tempfile
  16. #======================LOGGING CONFIGURATION===========================
  17. sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), "..")))
  18. from Utilities import ConsoleInterface
  19. ConsoleInterface.ConfigLogging(Version="1.0", ModuleName="SysGen")
  20. #======================================================================
  21. from Utilities import ColoredLogging, Timer, Misc, DataMining
  22. from SysGen.HW.HwModel import HwModel
  23. #import SysGen
  24. from SysGen import XmlLibManager, Module
  25. import SysGen
  26. import pkgutil
  27. #=======================================================================
  28. def ShowGUI(Options):
  29. """
  30. Initialize and launch GUI.
  31. """
  32. if Options.lib is None: Library=SysGen.BBLIBRARYPATH
  33. else: Library=Options.lib
  34. logging.error("No GUI available yet.")
  35. #=======================================================================
  36. def ListModules(Options):
  37. """
  38. Display a list of modules found in the library.
  39. """
  40. Library=XmlLibManager.XmlLibManager(SysGen.BBLIBRARYPATH)
  41. for Mod in Library.ListModules():
  42. print(Mod.Name)
  43. return
  44. #=======================================================================
  45. def EvalModuleCmd(Options):
  46. """
  47. Implement specified module on target architecture and fetch FPGA resource usage.
  48. """
  49. # Fetch module in library
  50. Library=XmlLibManager.XmlLibManager(SysGen.BBLIBRARYPATH)
  51. OriMod=Library.Module(Options.module, [Library,])
  52. Mod=OriMod.Copy()
  53. if Mod is None:
  54. logging.error("No such module '{0}' in library.".format(Options.module))
  55. return None
  56. Archi = Options.architecture
  57. ParamVal = {}
  58. for PAssignment in Options.parameter:
  59. if PAssignment=='': continue
  60. try: PName, Value=PAssignment.split('=', 2)
  61. except:
  62. logging.error("Cannot recognize expression '{0}'. Expected format: <Name>=<Value>.".format(PAssignment))
  63. return None
  64. # for PNameValue in PNameValues:
  65. # PName, Value=PNameValue.split(':')
  66. ParamVal[PName]=Value
  67. RemoteHost = Options.host
  68. TargetHwModel=HwModel(Archi)
  69. HWRsc=TargetHwModel.ModuleResources(
  70. Mod = Mod,
  71. Library=Library,
  72. ParamVal = ParamVal,
  73. RemoteHost=RemoteHost
  74. )
  75. if HWRsc is None:
  76. logging.error("Failed to evaluate resources.")
  77. return None
  78. else:
  79. logging.info("Used resources : {0}".format(HWRsc))
  80. # Update XML
  81. OriMod.UpdateResources(FpgaId=TargetHwModel.GetFPGA(FullId=False), HWRsc=HWRsc)
  82. OriMod.DumpToLibrary()
  83. return HWRsc
  84. #=======================================================================
  85. #def EvalModule(Mod, Archi, ParamVal={}, Library=None, RemoteHost=None):
  86. # """
  87. # Implement specified module on target architecture and fetch FPGA resource usage.
  88. # """
  89. # # Fetch architecture in library
  90. # TargetHW=HwModel(Archi)
  91. # if not TargetHW.IsSupported():
  92. # logging.error("Architecture {0} not supported. {0}'s configuration must be provided in library.".format(Archi))
  93. # return None
  94. #
  95. # logging.info("Start evaluation of FPGA resources usage for module '{0}' on architecture '{1}' with parameters '{2}'".format(Mod, TargetHW, ParamVal))
  96. #
  97. # for PName, Value in ParamVal.items():
  98. # if PName in Mod.Params:
  99. # logging.info("\t> Set '{0}' to {1}.".format(PName, Value))
  100. # Mod.EditParam(PName, Value)
  101. # else:
  102. # logging.error("No such parameter '{0}' in module '{1}'.".format(PName, Mod.Name))
  103. # Mod.Reload()
  104. # if Library:
  105. # Mod.IdentifyServices(Library.Services)
  106. #
  107. # OutputPath=tempfile.mkdtemp(suffix='', prefix='RscEval_{0}_{1}_'.format(Mod.Name, Timer.TimeStamp()), dir=None)
  108. # SrcPath=os.path.join(OutputPath, "src")
  109. ## SynPath=os.path.join(OutputPath, "synthesis")
  110. # os.makedirs(SrcPath)
  111. ## os.makedirs(SynPath)
  112. ## WrappedMod=Module.GenerateEmptyWrapper(Mod=Mod, CopyMod=False)
  113. # WrappedMod=Mod.Copy()
  114. # WrappedMod.GenSrc(
  115. # Synthesizable = True,
  116. # OutputDir = SrcPath,
  117. # TestBench = False,
  118. # IsTop = True,
  119. # ModInstance = None,
  120. # NewPkg = WrappedMod.IsAbstract(),
  121. ## TBValues = TBValues,
  122. ## TBClkCycles = TBClkCycles,
  123. ## CommunicationService=CommunicationService
  124. # Recursive=True,
  125. # )
  126. #
  127. # HWRsc=TargetHW.ModuleResources(Mod=WrappedMod, Library=Library, OutputPath=OutputPath, RemoteHost=RemoteHost)
  128. # if HWRsc is None:
  129. # logging.error("Failed to evaluate resources.")
  130. # Misc.CleanTempFiles(OutputPath)
  131. # return None
  132. # else:
  133. # logging.info("Used resources : {0}".format(HWRsc))
  134. # # Update XML
  135. # Mod.UpdateResources(FpgaId=TargetHW.GetFPGA(FullId=False), HWRsc=HWRsc)
  136. # Mod.DumpToLibrary()
  137. # Misc.CleanTempFiles(OutputPath)
  138. # return HWRsc
  139. #=======================================================================
  140. def ModelNoCResourcesCmd(Options):
  141. """
  142. Implement specified module on target architecture and fetch FPGA resource usage.
  143. """
  144. Archi = Options.architecture
  145. OutputPath = Options.output
  146. RemoteHost = Options.host
  147. return ModelNoCResources(Archi=Archi, OutputPath=OutputPath, RemoteHost=RemoteHost)
  148. #=======================================================================
  149. def ModelNoCResources(Archi, OutputPath=None, RemoteHost=None):
  150. """
  151. Estimate resource for specified Module for each combination of specified parameters.
  152. And perform data mining to generate a model.
  153. """
  154. if OutputPath is None:
  155. OutputPath=tempfile.mkdtemp(prefix='NoCRscModels_{0}_{1}'.format(Archi, Timer.TimeStamp()), dir='./')
  156. else:
  157. OutputPath=os.path.abspath(OutputPath)
  158. if not os.path.isdir(OutputPath): os.makedirs(OutputPath)
  159. RscIniPath=os.path.join(OutputPath, "CollectedResources_{0}.ini".format(Timer.TimeStamp()))
  160. Config=configparser.RawConfigParser()
  161. TargetHwModel=HwModel(Archi)
  162. ModelValues={'LUT':[], 'REGISTER':[], 'RAM':[]}
  163. for FifoDepth in [96,]:#2, 4, 16, 32,]:#
  164. for FlitWidth in [64,]:#8, 16, 32, 64,]: #
  165. for DimX, DimY in [(5,5), (9,9), (12,12)]:
  166. # Fetch module in library (reload library for each iteration)
  167. Library=XmlLibManager.XmlLibManager(SysGen.BBLIBRARYPATH)
  168. Mod=Library.Module("AdOCNet", [Library,])
  169. if Mod is None:
  170. logging.error("No such module '{0}' in library.".format("AdOCNet"))
  171. return None
  172. Rsc=TargetHwModel.ModuleResources(
  173. Mod = Mod,
  174. Library=Library,
  175. ParamVal = {'FlitWidth':FlitWidth, 'InputFifoDepth_Table': [FifoDepth for i in range(DimX*DimY)], 'DimX':DimX, 'DimY':DimY, 'NbInputs_Table': [5 for i in range(DimX*DimY)], 'NbOutputs_Table': [5 for i in range(DimX*DimY)],},
  176. RemoteHost=RemoteHost
  177. )
  178. if Rsc is None:
  179. logging.error("[ModelNoCResources] Failed to evaluate resources for module '{0}'.".format(Mod))
  180. RscDict={}
  181. return None
  182. else:
  183. RscDict=Rsc.GetResourcesDict()
  184. # RscDict={'LUT':(5*DimX,-1,-1), 'REGISTER':(3*DimX,-1,-1), 'RAM':(1*DimX,-1,-1)}
  185. ConfigName="{0}_{1}*{2}_Flit{3}_Buffer{4}".format('AdOCNet', DimX, DimY, FlitWidth, FifoDepth)
  186. Config.add_section(ConfigName)
  187. Config.set(ConfigName, 'DimX', DimX)
  188. Config.set(ConfigName, 'DimY', DimY)
  189. Config.set(ConfigName, 'DimX*DimY', DimX*DimY)
  190. Config.set(ConfigName, 'FlitWidth', FlitWidth)
  191. Config.set(ConfigName, 'FifoDepth', FifoDepth)
  192. for Item in ('LUT', 'REGISTER', 'RAM'):
  193. if Item in RscDict:
  194. Config.set(ConfigName, Item, RscDict[Item][0])
  195. ModelValues[Item].append( (DimX*DimY, RscDict[Item][0]) )
  196. else:
  197. logging.warning("[ModelNoCResources] No such key '{0}' in resource dictionary {1}.".format(Item, RscDict))
  198. with open(RscIniPath, 'w+') as ConfFile:
  199. Config.write(ConfFile)
  200. logging.info("INI Resource file generated: '{0}'".format(RscIniPath))
  201. XlsPath=RscIniToXls(RscIniPath, HwArchiName=Archi, OutputPath=OutputPath, ParamOrder=('DimX', 'DimY', 'DimX*DimY', 'FlitWidth', 'FifoDepth', 'lut', 'register', 'ram'))
  202. logging.debug("Model values: '{0}'".format(ModelValues))
  203. LinearExpressions=DataMining.LinearRegression(ModelValues, Variable='DimX*DimY')
  204. for RscType, LinearExpression in LinearExpressions.items():
  205. logging.info(" * Model for '{0}': {1}".format(RscType, LinearExpression))
  206. logging.info("XLS Resource file generated: '{0}'".format(XlsPath))
  207. Answer=''
  208. while not Answer in ('Y', 'N'):
  209. Answer=input("Would you like to open the generated XLS file? Y/N\n").upper()
  210. if Answer=='Y':
  211. if sys.platform.startswith('linux'):
  212. subprocess.call(["xdg-open", XlsPath])
  213. else:
  214. os.startfile(XlsPath)
  215. return XlsPath
  216. #=======================================================================
  217. def RscIniToXls(RscIniPath, HwArchiName, OutputPath, ParamOrder):
  218. """
  219. Generate XLS from ini resource file.
  220. """
  221. if OutputPath is None:
  222. OutputPath=tempfile.mkdtemp(prefix='RscIniToXls_{0}_'.format(Timer.TimeStamp()))
  223. else:
  224. OutputPath=os.path.abspath(OutputPath)
  225. if not os.path.isdir(OutputPath): os.makedirs(OutputPath)
  226. wb = Workbook()
  227. # grab the active worksheet
  228. ws = wb.active
  229. Config=configparser.RawConfigParser()
  230. Config.read(RscIniPath)
  231. ws['A1'] = "Resources collection date:" # Data can be assigned directly to cells
  232. ws['A2'] = datetime.datetime.now() # Python types will automatically be converted
  233. ws.append(["",]) # Rows can be appended
  234. ws.append(["Target:",])
  235. ws.append([HwArchiName,])
  236. ws.append(["",])
  237. ws.append(["",]+list(ParamOrder))
  238. for Row, Section in enumerate(Config.sections()):
  239. ws.append([Section,]+[Config.getint(Section, Item) if Config.has_option(Section, Item) else '' for Item in ParamOrder])
  240. XlsPath=os.path.join(OutputPath, "CollectedResources_{0}.xlsx".format(Timer.TimeStamp()))
  241. # Save the file
  242. wb.save(XlsPath)
  243. return XlsPath
  244. #=======================================================================
  245. def ParseOptions():
  246. """
  247. Parse argument options and do corresponding actions.
  248. """
  249. # Display the banner on terminal
  250. Parser = argparse.ArgumentParser(description='Manage architecture and HDL libraries.', epilog="If no arguments are specified, the GUI will popup.")
  251. #------------------General command arguments-------------------------------------
  252. # ARGUMENT: Launch the GUI
  253. Parser.add_argument('-g', '--gui', action='store_true', help='If the GUI should be open (ignoring specified options).', default=False)
  254. # ARGUMENT: Display version
  255. Parser.add_argument('--version', action='version', version="%(prog)s: version='{0}'".format(VERSION), help="Displays YANGO version.")
  256. #================================================================
  257. SubParsers = Parser.add_subparsers(help='Library manager sub-commands.', dest='Sub-command')
  258. SubParsers.required = True
  259. EvalParser = SubParsers.add_parser('eval', help='Evaluate the resources used by a library module.')
  260. # Create the parser for the 'gui' command
  261. GUIParser = SubParsers.add_parser('gui', help='Launch the GUI.')
  262. # Create the parser for the 'ListModules' command
  263. ListModParser = SubParsers.add_parser('ListModules', help='Display a list of modules found in the library.')
  264. NoCModelParser= SubParsers.add_parser('NoCModel', help='Estimate NoC resource and generate NoC model. Two files are created a *.ini and *.xls.')
  265. #================================================================
  266. #------------------'GUI' command arguments---------------------------------------
  267. # None
  268. #------------------'ListModules' command arguments---------------------------------------
  269. # None
  270. #------------------'eval' command arguments---------------------------------------
  271. EvalParser.add_argument('-m', '--module', metavar='ModuleName', type=str, help='The name of a module saved in library.', required=True)
  272. EvalParser.add_argument('-a', '--architecture', metavar='ArchiName', type=str, help='The name of an Architecture saved in library.', required=True)
  273. EvalParser.add_argument('-p', '--parameter', metavar='ParamValue', action='append', help='A coma sparated liste of Parameter Name and value pairs (Param:Value).', default=[])
  274. # ARGUMENT: Display version
  275. EvalParser.add_argument('--host', action='store', help='Execute commands remotely.', default=None)
  276. #------------------'NoCModel' command arguments---------------------------------------
  277. NoCModelParser.add_argument('-a', '--architecture', metavar='ArchiName', type=str, help='The name of an Architecture saved in library.', required=True)
  278. NoCModelParser.add_argument('-o', '--output', action='store', help='Output folder path.', type=DirectoryPath, default=None)
  279. NoCModelParser.add_argument('--host', action='store', help='Execute commands remotely.', default=None)
  280. GUIParser.set_defaults( func=ShowGUI)
  281. ListModParser.set_defaults( func=ListModules)
  282. EvalParser.set_defaults( func=EvalModuleCmd)
  283. NoCModelParser.set_defaults(func=ModelNoCResourcesCmd)
  284. Opt = Parser.parse_args()
  285. Opt.func(Opt)
  286. return Opt
  287. #====================================================================
  288. def DirectoryPath(Path):
  289. """
  290. raise error if path is no a directory
  291. """
  292. if os.path.isdir(Path):
  293. return os.path.abspath(Path)
  294. else:
  295. try: os.makedirs(Path)
  296. except: raise TypeError
  297. #====================================================================
  298. def FilePath(Path):
  299. """
  300. raise error if path is no a directory
  301. """
  302. if os.path.isfile(Path):
  303. return os.path.abspath(Path)
  304. else:
  305. raise TypeError
  306. #====================================================================
  307. # ==================== START OF THE SysGen APPLICATION =====================
  308. if (__name__ == "__main__"):
  309. ColoredLogging.SetActive(True)
  310. # It's a standalone module
  311. Options = ParseOptions()
  312. logging.shutdown()
  313. sys.exit(0)