GuiShell.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. #!python3
  2. import sys
  3. import threading
  4. import time
  5. import os
  6. if sys.platform == 'linux':
  7. import readline
  8. import rlcompleter
  9. import traceback
  10. from PySide2.QtCore import QObject, QThread, Signal
  11. import gui
  12. from GuiType import *
  13. class _GuiMain():
  14. Title = "NeoConstraint"
  15. WindowCount = 0
  16. History = []
  17. SideBar = None
  18. Messages = None
  19. TextFont = "Cantarell"
  20. TextFontSize = 11
  21. SysFont = "Cantarell"
  22. SysFontSize = 12
  23. About = "NeoConstraint(R) 2023.03-Alpha\nChipara, Inc. Ltd" # Help-About
  24. Prompt = "nc_shell-t>" # Console-Shell
  25. def __init__(self):
  26. super().__init__()
  27. self.SideBar = _GuiSideBar(
  28. "Hierarchy", _GuiTree(["", "DFFs", "SubModules"], []))
  29. self.Messages = _GuiMessages([])
  30. self._stage = "no design in memory"
  31. def Start(self): # GUI Loop Entry, Please modify content
  32. return gui.signale('start')
  33. def Stop(self): # GUI Loop Exit, Please modify content
  34. # self.sig.emit('Stop')
  35. # return gui.StopGui()
  36. return gui.signale('stop')
  37. def Log_Print(self): # test: _GUI.Log_Print()
  38. gui.signale("Busy")
  39. print(1)
  40. time.sleep(1)
  41. print(2)
  42. time.sleep(1)
  43. gui.signale("Ready")
  44. return ""
  45. # test: _GUI.Shell_IsCmdFinished("print(1,")
  46. def Shell_IsCmdFinished(self, cmd):
  47. return cmd.count('(') == cmd.count(')') and cmd.count('"') % 2 == 0 and cmd.count("'") % 2 == 0
  48. def Shell_Execute(self, cmd):
  49. self.History.append(cmd)
  50. exec(cmd)
  51. print('demo> ', end='')
  52. def ViewGetDefault(self):
  53. # Read from disk, blah blah
  54. self.TextFont = "Cantarell"
  55. self.TextFontSize = 11
  56. self.SysFont = "Cantarell"
  57. self.SysFontSize = 12
  58. def ViewSet(self, text_font_size, text_font, sys_font_size, sys_font):
  59. self.TextFont = text_font
  60. self.TextFontSize = text_font_size
  61. self.SysFont = sys_font
  62. self.SysFontSize = sys_font_size
  63. def ViewSetDefault(self, text_font_size, text_font, sys_font_size, sys_font):
  64. self.ViewSet(text_font_size, text_font, sys_font_size, sys_font)
  65. # write to disk, blahblah
  66. return
  67. def Analyze(self, type_paths):
  68. assert isinstance(type_paths, list)
  69. gui.signale("Busy")
  70. gui.signale("message")
  71. for tp in type_paths:
  72. assert tp[0] in ("Filelist", "Netlist", "V2001",
  73. "V2005", "SV2005", "SV2009", "SV2012", "SearchPath")
  74. assert isinstance(tp[1], str)
  75. print("Analyze:", tp[0], tp[1])
  76. time.sleep(0.1)
  77. print("Analyze Done")
  78. gui.signale("Ready")
  79. return
  80. def Elaborate(self, top, bbox):
  81. assert isinstance(top, str)
  82. assert isinstance(bbox, bool)
  83. gui.signale("Busy")
  84. gui.signale("message")
  85. if top == "":
  86. print("Elaborate: Auto Top, ", end='')
  87. else:
  88. print("Elaborate: Top is "+top+", ", end='')
  89. if bbox:
  90. print("Allow BlackBox")
  91. else:
  92. print("Do Not Allow BlackBox")
  93. time.sleep(0.5)
  94. self._stage = "elaborating"
  95. gui.signale("Stage")
  96. time.sleep(0.5)
  97. self._stage = "elaborated"
  98. gui.signale("Stage")
  99. self.Title = "NeoConstraint - "+top
  100. # self.SideBar = _GuiSideBar("Hierarchy", _GuiTree(["", "DFFs", "SubModules"], [_GuiTreeRow([_GuiTreeRow([], "SubDesign1", [
  101. # "12", "0"]), _GuiTreeRow([_GuiTreeRow([], "Sub3", ["5", "0"])], "SubDesign2", ["34", "1"])], "DemoDesign", ["123", "2"]),]))
  102. self.SideBar = _GuiSideBar("Hierarchy", _GuiTree(["", "DFFs", "SubModules"], [_GuiTreeRow([
  103. _GuiTreeRow([_GuiTreeRow([], "SubRow1", ["1","2"]),], "SubTreeRow1",["1","2"]),
  104. _GuiTreeRow([ ], "SubRow2", ["1","2"]),
  105. ], "DemoDesign", ["123", "2"]),]))
  106. print("Elaborate Done")
  107. gui.signale("Ready")
  108. return gui.signale(self.SideBar)
  109. def ReloadDesign(self):
  110. gui.signale("Busy")
  111. gui.signale("message")
  112. time.sleep(1)
  113. print("Reload Design Done")
  114. gui.signale("Ready")
  115. return
  116. def ReadTimingConstraint(self, filename):
  117. assert isinstance(filename, str)
  118. print("Reading Timing Constraint: "+filename)
  119. gui.signale("Busy")
  120. gui.signale("message")
  121. time.sleep(1)
  122. print("Read Timing Constraint Done")
  123. gui.signale("Ready")
  124. return
  125. def ReportExceptions(self, mcp, fp, mdp, limit):
  126. assert isinstance(mcp, bool)
  127. assert isinstance(fp, bool)
  128. assert isinstance(mdp, bool)
  129. assert isinstance(limit, int)
  130. gui.signale("Busy")
  131. print("Reporting Exception: ", end='')
  132. if mcp:
  133. print("MultiCycle Path, ", end='')
  134. if fp:
  135. print("False Path, ", end='')
  136. if mdp:
  137. print("Max Delay Path, ", end='')
  138. if limit > 0:
  139. print("Path Limit", limit)
  140. else:
  141. print("No Path Limit")
  142. time.sleep(1)
  143. print("Report Exception Done")
  144. self.WindowCount += 1
  145. title = "Report "+str(self.WindowCount)
  146. fixed_row = ["Startpoint", "Endpoint", "Virtual Slack"]
  147. form_mcp = _GuiForm(fixed_row, [["a1", "a2", "0.1"]])
  148. form_fp = _GuiForm(
  149. fixed_row, [["b1", "b2", "0.2"], ["c1", "c2", "0.3"]])
  150. form_mdp = _GuiForm(fixed_row, [["d1", "d2", "0.4"], [
  151. "e1", "e2", "0.5"], ["f1", "f2", "0.6"]])
  152. forms = _GuiFormMulti(
  153. [["MCP", form_mcp], ["FP", form_fp], ["MDP", form_mdp]])
  154. print("Names:", forms.Names)
  155. gui.signale("Ready")
  156. return gui.signale(_GuiWinFormMulti(title, forms, "Timing"))
  157. def ReportClocks(self, start, end, exclude, autogen, include_async):
  158. assert isinstance(start, str)
  159. assert isinstance(end, str)
  160. assert isinstance(exclude, str)
  161. assert isinstance(autogen, bool)
  162. assert isinstance(include_async, bool)
  163. gui.signale("Busy")
  164. print("Reporting Clocks: Startpoints",
  165. start, "Endpoints", end, end='')
  166. if exclude:
  167. print("Exclude", exclude, end='')
  168. if autogen:
  169. print(", Auto Include Generated Clocks", end='')
  170. if include_async:
  171. print(", Include Async Clocks", end='')
  172. print()
  173. time.sleep(1)
  174. print("Report Clocks Done")
  175. gui.signale("Ready")
  176. self.WindowCount += 1
  177. title = "Report "+str(self.WindowCount)
  178. fixed_row = ["Startpoint Clock", "Startpoint",
  179. "Endpoint Clock", "Endpoint", "Type"]
  180. rows = [["CLKA", "DFFA/Q", "CLKB", "DFFB/D", "Sync"],
  181. ["CLKB", "DFFB/Q", "CLKA", "DFFA/D", "Async"]]
  182. form = _GuiForm(fixed_row, rows)
  183. return gui.signale(_GuiWinForm(title, form, "Clock"))
  184. def ReportVirtualTiming(self, from_type, from_, thru_type, thru, to_type, to, flat, limit):
  185. assert from_type in ("", "Clocks", "Pins", "Registers")
  186. assert thru_type in ("", "Pins")
  187. assert to_type in ("", "Clocks", "Pins", "Registers")
  188. assert isinstance(from_, str)
  189. assert isinstance(thru, str)
  190. assert isinstance(to, str)
  191. assert isinstance(flat, bool)
  192. assert isinstance(limit, int)
  193. gui.signale("Busy")
  194. print("Reporting Virtual Timing: From", from_type, from_,
  195. "Through", thru_type, thru, "To", to_type, to, end='')
  196. if flat:
  197. print(", Enabled Flat Search, ", end='')
  198. else:
  199. print(", Disabled Flat Search, ", end='')
  200. if limit > 0:
  201. print("Path Limit", limit)
  202. else:
  203. print("No Path Limit")
  204. time.sleep(1)
  205. print("Report Virtual Timing Done")
  206. gui.signale("Ready")
  207. self.WindowCount += 1
  208. title = "Report "+str(self.WindowCount)
  209. text = "Virtual Timing:\nFrom "+from_type+" "+from_ + \
  210. "\nThrough "+thru_type+" "+thru+"\nTo "+to_type+" "+to
  211. return gui.signale(_GuiWinText(title, text))
  212. def lineEdit_input(self, dat):
  213. # sys.stdout.stdout_bak.write(dat)
  214. print('input:', dat)
  215. # input(self.lineEdit.text()+'\n')
  216. # sys.stdout.stdout_bak.flush()
  217. def run(self):
  218. shell_loop()
  219. def Exit(self): # File - Exit
  220. os._exit(0)
  221. def GetHistory(self): # Console - History
  222. return ["first cmd", "last cmd"]
  223. def GetErrors(self): # Console - Message
  224. return _GuiMessages([["Err-123","This is an error",[_GuiMessage("This is an error!", 100, "/x/x.v"),_GuiMessage("This is an error!!", 200, "/xx/xx.v")]]])
  225. def GetCriticalWarnings(self): # Console - Message
  226. return _GuiMessages([])
  227. def GetWarnings(self): # Console - Message
  228. return _GuiMessages([["Warn-234","This is a warning",[_GuiMessage("This is a warning!", 100, "/x/x.v"),_GuiMessage("This is a warning!!", 200, "/xx/xx.v")]]])
  229. def GetInfos(self): # Console - Message
  230. return _GuiMessages([["Info-345","This is an info",[_GuiMessage("This is an info!", 100, "/x/x.v"),]],["Info-456","This is another info",[_GuiMessage("This is another info!", 200, "/xx/xx.v"),]]])
  231. # _GUI.Analyze([["SearchPath", "../.."],["SV2009", "file.sv"]])
  232. # _GUI.Elaborate("DemoDesign", True)
  233. # _GUI.ReportExceptions(True, True, False, 10)
  234. # _GUI.ReportClocks("CLK*", "CLK*", "", True, False)
  235. # _GUI.ReportVirtualTiming("Clocks", "CLK", "Pins", "DFF/Q", "Registers", "DFF2", False, 2)
  236. _GUI = _GuiMain()
  237. ###################
  238. # Shell Loop
  239. ###################
  240. def shell_loop():
  241. if sys.platform == 'linux':
  242. # -------------------------- Shell Completer -------------------------
  243. default_completer = readline.get_completer()
  244. def completer(text, state):
  245. return default_completer(text, state)
  246. if 'libedit' in readline.__doc__:
  247. readline.parse_and_bind("bind -e")
  248. readline.parse_and_bind("bind '\t' rl_complete")
  249. else:
  250. readline.parse_and_bind('tab: complete')
  251. readline.set_completer(completer)
  252. readline.set_completer_delims('')
  253. # ---------------------------- Shell Loop ---------------------------
  254. print('\n'+' '*20+'GuiDemo\n'+' '*21 +
  255. 'V 1.1\n'+' '*14+'Copyright (c) 2022 \n')
  256. pre_exit = False
  257. stdin = ''
  258. try:
  259. while 1:
  260. try:
  261. print('demo> ', end='')
  262. stdin = input()
  263. pre_exit = False
  264. except KeyboardInterrupt:
  265. if pre_exit:
  266. os._exit(0)
  267. else:
  268. print('\n one more ctrl-c to exit')
  269. pre_exit = True
  270. except EOFError:
  271. os._exit()
  272. if stdin != '' and not pre_exit:
  273. try:
  274. # -------------- multi line --------------
  275. stdin_next = ''
  276. while stdin.endswith(':') or stdin.endswith('\\') or stdin_next.startswith(' ') or stdin_next.startswith('\t'):
  277. stdin_next = input('... ')
  278. stdin += '\n'+stdin_next
  279. # --------------- def call ---------------
  280. if stdin.endswith('('):
  281. stdout = eval(miao+')')
  282. else:
  283. try:
  284. if stdin.endswith(')'):
  285. stdout = eval(stdin)
  286. else:
  287. stdout = eval(stdin+'()')
  288. except (SyntaxError, TypeError):
  289. if stdin.endswith(')'):
  290. exec(stdin)
  291. stdout = ''
  292. else:
  293. try:
  294. stdout = eval(stdin)
  295. except (SyntaxError, TypeError):
  296. exec(stdin)
  297. stdout = ''
  298. # --------------- printer ----------------
  299. if stdout != '':
  300. if isinstance(stdout, set) and len(stdout) < 1000:
  301. print(sorted(list(stdout)))
  302. else:
  303. print('', stdout)
  304. except KeyboardInterrupt:
  305. print('\n\n ctrl-c interrupt:', miao, '\n')
  306. except NameError as e:
  307. if os.system(stdin):
  308. print(' NameError:{}'.format(e))
  309. except Exception:
  310. traceback.print_exc()
  311. finally:
  312. gui.exit()
  313. print('\n\n thank you for gui development !\n')
  314. if __name__ == '__main__':
  315. # _GUI.Start()
  316. # _GUI.Stop()
  317. # _GUI.Log_Print()
  318. t = gui.run_in_thread(_GUI)
  319. _GUI.run()