当前位置:   article > 正文

gvim中进行verilog语言信号追踪、显示拓扑插件_gvim查看跟某一个信号连接的源头信号

gvim查看跟某一个信号连接的源头信号

插件使用方法及功能:

vtags 是一款在gvim下实现类似verdi的信号追踪、显示拓扑等功能的插件。vtags插件完全使用python实现,目前实现功能包括信号追踪、宏定义追踪、显示模块拓扑、快速打开文件、保存和打开gvim快照、添加断点等功能。

支持功能和快捷键:

快捷键

功能

gi

进入子模块

gu

回到上层模块

<Space><Left>

追信号源,或宏定义

<Space><Right>

追信号目的

<Space><Down>

回退

<Space><Up>

向前

<Space> + v

显示策略,和展开收回策略条目

<Space> + c

添加记录点

<Space> + b

添加基本模块

<Space> + d

删除记录点或基本模块

<Space> +h

固定当前窗口

<Space>

快速访问

<Space> + s

储存快照

gvim/vim

加载快照

详细信息看《二:开始使用及支持功能和快捷键》

注意:

(1)在code目录下通过vtags生成vtags.db后,第一次打开verilog code时需要编译生成的database,所以第一打开code比较慢,之后打开code就会非常迅速。

 

安装方式:

1. 下载插件代码,解压并复制到自选的安装路径下。下面以安装目录为“~/vtags-1.20/为例”

   代码下载地址: (1)https://pan.baidu.com/s/1kVfRXFx

                         (2)http://www.vim.org/scripts/script.php?script_id=5494

2. 在linux配置文件中添加别名。

  ~/.cshrc  中添加:alias vtags 'python  ~/vtags-1.20/vtags.py'

 或  ~/.bashrc 中添加:alias=vtags 'python  ~/vtags-1.20/vtags.py'

  source ~/.cshrc 或 source ~/.bashre 使设置生效。

3. 在vim配置文件中加入插件。

  ~/.vimrc  中添加: source  ~/vtags-1.20/vtags_vim_api.vim

4. 本步骤可选,可以在vtags-1.20/vim_glb_config.py中设置插件的一些全局设置,

  你也可以使用vtags时生成的局部配置文件vim_local_config.py中进行设置。

5. cd 到code目录使用命令:vtags, 在code目录下生成base文件 vtags.db, 用gvim打开代码就可以使用上面定义快捷键中功能。

注: 要求python版本2.7,详情请看《用户使用指南》。

 

code 源码:

  1. """
  2. https://my.oschina.net/u/2520885
  3. """
  4. #===============================================================================
  5. # Copyright (C) 2016 by Jun Cao
  6. # Permission is hereby granted, free of charge, to any person obtaining a copy
  7. # of this software and associated documentation files (the "Software"), to deal
  8. # in the Software without restriction, including without limitation the rights
  9. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. # copies of the Software, and to permit persons to whom the Software is
  11. # furnished to do so, subject to the following conditions:
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. # THE SOFTWARE.
  21. #===============================================================================
  22. # left sidebar window width
  23. frame_window_width = 20
  24. # right bottom report window height
  25. report_window_height = 8
  26. # max work window vtags auto opened, not include use self opened window and holded window
  27. max_open_work_window_number = 1
  28. # when use <Space><left>/<Space><right> the max number of history trace valid
  29. max_roll_trace_depth = 1000
  30. # when <Space>c add check point, the max number of check point valid
  31. max_his_check_point_num = 10
  32. # when gen the vtags database, in all verilog modules when some module called more then threshold times,
  33. # set this module to be base module, then show topo will not list it's inst one by one
  34. base_module_threshold = 200
  35. # supported verilog postfix, we only add postfix in below to data base
  36. support_verilog_postfix = ['v']
  37. # open debug module or not, open debug module will print a lot debug log at vtags.db
  38. debug_mode = False
  39. # when trace source, match bigger than TraceSourceOptimizingThreshold, open opt func, mainly for signal like clk,rst ...
  40. trace_source_optimizing_threshold = 20
  41. # frame fold level space, use to set pre space num, if current level is 3 ,
  42. # and fold level space is ' ', then current line pre space is ' '*3 = ' '
  43. frame_fold_level_space = ' '
  44. # weather show report or not
  45. show_report = True
  46. # weather show sidebar or not
  47. show_sidebar = True
  48. """
  49. https://my.oschina.net/u/2520885
  50. """
  51. #===============================================================================
  52. # Copyright (C) 2016 by Jun Cao
  53. # Permission is hereby granted, free of charge, to any person obtaining a copy
  54. # of this software and associated documentation files (the "Software"), to deal
  55. # in the Software without restriction, including without limitation the rights
  56. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  57. # copies of the Software, and to permit persons to whom the Software is
  58. # furnished to do so, subject to the following conditions:
  59. # The above copyright notice and this permission notice shall be included in
  60. # all copies or substantial portions of the Software.
  61. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  62. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  63. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  64. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  65. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  66. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  67. # THE SOFTWARE.
  68. #===============================================================================
  69. __version__ = "1.20"
  70. __project_url__ = "https://my.oschina.net/u/2520885"
  71. import os
  72. import sys
  73. import re
  74. import pickle
  75. #print help
  76. help = ''
  77. try:
  78. help = sys.argv[1]
  79. except:
  80. pass
  81. if help in ['-h','-help']:
  82. print("(1) generate vtags at code dir, use command \"vtags\" ;" )
  83. print("(2) config vtags vim at vtags gen dir \"/vtags.db/vim_local_config.py\"," )
  84. print(" config items and detail look vim_local_config.py notes;" )
  85. print("(3) support action in vim window:" )
  86. print(" 1) gi : if cursor on module call, go in submodule;" )
  87. print(" 2) gu : if cur module called before, go upper module;" )
  88. print(" 3) <Space><Left> : trace cursor word signal source;" )
  89. print(" 4) <Space><Right> : trace cursor word signal dest;" )
  90. print(" 5) <Space><Down> : roll back;" )
  91. print(" 6) <Space><Up> : go forward;" )
  92. print(" 7) <Space>v : show current module topo " )
  93. print(" or fold/unfold sidebar items;" )
  94. print(" 8) <Space>c : add current cursor as checkpoint, can go back directly;" )
  95. print(" 9) <Space>b : add current cursor module as basemodule, not show in topo;" )
  96. print(" 10) <Space> : in sidebar or report win, just go cursor line link;" )
  97. print(" 11) <Space>h : hold cursor win, will not auto close it;" )
  98. print(" 12) <Space>d : in sidebar, delete valid items(base_module, checkpoint...);" )
  99. print(" 13) <Space>s : save current vim snapshort," )
  100. print(" use \"gvim/vim\" without input file to reload snapshort;" )
  101. exit()
  102. def cur_file_dir():
  103. path = sys.path[0]
  104. if os.path.isdir(path):
  105. return path
  106. elif os.path.isfile(path):
  107. return os.path.dirname(path)
  108. vtags_install_path = cur_file_dir()
  109. sys.path.insert(0,vtags_install_path)
  110. sed_vtags_install_path = re.sub('/','\/',vtags_install_path)
  111. os.system('sed -ig \'s/vtags_install_path =.*/vtags_install_path = "%s"/g\' %s/vtags_vim_api.vim' %(sed_vtags_install_path, vtags_install_path) )
  112. os.system('sed -ig \'s/let is_vtags_installed =.*/let is_vtags_installed = 1/g\' %s/vtags_vim_api.vim' %(vtags_install_path) )
  113. vtags_folder_path = os.getcwd() + '/vtags.db'
  114. os.system('mkdir -p %s'%(vtags_folder_path))
  115. if os.path.isfile(vtags_folder_path + '/vtag_gen_log.txt'):
  116. os.system('rm -rf '+vtags_folder_path+'/vtag_gen_log.txt')
  117. import Lib.GLB as GLB
  118. G = GLB.G
  119. GLB.vtags_run_log_path[0] = vtags_folder_path + '/vtags_run.log'
  120. import Lib.Code as Code
  121. import Lib.View as View
  122. from Lib.Base import *
  123. # filelist:
  124. # use "//" as note sign
  125. # support dir_path and file path mix
  126. def get_all_verilog_files_from_filelist(filelist_path):
  127. verilog_file_paths = []
  128. # get ~ path
  129. home_path = os.popen('echo ~').readlines()[0].rstrip('\n').rstrip('/')
  130. for l in open(filelist_path,'r').readlines():
  131. l = l.strip('\n')
  132. l = re.sub('//.*','',l)
  133. l = re.sub('^~', home_path, l)
  134. if re.match('\s*$',l):
  135. continue
  136. path = l
  137. if os.path.isdir(path):
  138. c_files_path = os.popen('find ' + dir_path + ' -type f 2>/dev/null').readlines()
  139. c_files_path = [ d_l.rstrip('\n') for d_l in c_files_path ]
  140. for c_f in c_files_path:
  141. if get_file_path_postfix(c_f) not in G['SupportVerilogPostfix']:
  142. continue
  143. verilog_file_paths.append(c_f)
  144. if os.path.isfile(path):
  145. if get_file_path_postfix(path) not in G['SupportVerilogPostfix']:
  146. continue
  147. verilog_file_paths.append(path)
  148. return verilog_file_paths
  149. # get all verilog files inf and merge
  150. # modules_inf = { module_name: module_inf }
  151. # defines_inf = { macro_name : [ define_inf ] }
  152. # files_inf = { file_name : file_inf }
  153. # module_inf = { 'module_name' : module_name
  154. # ,'file_path' : f
  155. # ,'line_range_in_file' : (module_start_line_num, module_end_line_num)
  156. # ,'sub_modules' : sub_modules }
  157. # define_inf = { "name" : xxx
  158. # ,"path" : f
  159. # ,"pos" : (line_num, colum_num) # name first char pos
  160. # ,'code_line' : `define xxx .... }
  161. # file_inf = { 'glb_defines' : [ define_inf ]
  162. # ,'module_infs' : [ module_inf ]
  163. # ,'module_calls' : [ call_sub_inf ]
  164. # ,'file_edit_inf' : { 'create_time': ..., 'last_modify_time': ...}
  165. # call_sub_inf = { 'inst_name' : inst_name
  166. # ,'module_name' : modu_name
  167. # ,'match_range' : match_range }
  168. def get_verilog_files_code_inf(paths):
  169. # step 1/2 get all module/define inf
  170. all_file_module_inf = {}
  171. all_file_define_inf = {}
  172. all_module_name = set()
  173. print('step 1/2:')
  174. for i,f in enumerate(paths):
  175. show_progress_bar( i, len(paths))
  176. PrintDebug(f)
  177. # gen cur module and define inf
  178. cur_file_module_inf = get_single_verilog_file_module_inf(f)
  179. cur_file_define_inf = get_single_verilog_file_define_inf(f)
  180. # add to result
  181. all_file_module_inf[f] = cur_file_module_inf
  182. all_file_define_inf[f] = cur_file_define_inf
  183. all_module_name = all_module_name | set([ mi['module_name'] for mi in cur_file_module_inf])
  184. print('')
  185. # step 2/2 get all file sub call inf
  186. all_file_subcall_inf = {}
  187. patten = get_submodule_match_patten(all_module_name)
  188. print('step 2/2:')
  189. for i,f in enumerate(paths):
  190. PrintDebug(f)
  191. show_progress_bar( i, len(paths))
  192. all_file_subcall_inf[f] = get_single_verilog_file_subcall_inf(f, patten, all_module_name)
  193. print('')
  194. # merge to all_file_inf
  195. all_file_inf = {}
  196. for i,f in enumerate(paths):
  197. add_single_verilog_file_submodule_inf_to_module_inf( all_file_module_inf[f], all_file_subcall_inf[f] )
  198. all_file_inf[f] = {
  199. 'glb_defines' : all_file_define_inf[f]
  200. ,'module_infs' : all_file_module_inf[f]
  201. ,'module_calls' : all_file_subcall_inf[f]
  202. ,'file_edit_inf' : { 'create_time': os.path.getctime(f), 'last_modify_time': os.path.getmtime(f)}
  203. }
  204. modules_inf , global_defines_inf = gen_modules_and_defines_inf(all_file_inf)
  205. return {
  206. 'files_inf' : all_file_inf
  207. ,'modules_inf' : modules_inf
  208. ,'defines_inf' : global_defines_inf
  209. }
  210. #------------------------function for get module inf--------------------
  211. filelist_path = ''
  212. verilog_file_paths = []
  213. if filelist_path:
  214. verilog_file_paths = get_all_verilog_files_from_filelist(filelist_path)
  215. else:
  216. c_dir_path = os.getcwd()
  217. c_dir_files_path = os.popen('find ' + c_dir_path + ' -type f 2>/dev/null').readlines()
  218. c_dir_files_path = [ d_l.rstrip('\n') for d_l in c_dir_files_path ]
  219. for c_f in c_dir_files_path:
  220. if get_file_path_postfix(c_f) not in G['SupportVerilogPostfix']:
  221. continue
  222. verilog_file_paths.append(c_f)
  223. # get all code inf
  224. verilog_code_inf = get_verilog_files_code_inf(verilog_file_paths)
  225. modules_inf = verilog_code_inf['modules_inf']
  226. files_inf = verilog_code_inf['files_inf' ]
  227. defines_inf = verilog_code_inf['defines_inf']
  228. # set base module
  229. base_modules = set()
  230. base_threshold = G['BaseModuleInf']['BaseModuleThreshold']
  231. module_inst_num = {}
  232. for m in modules_inf:
  233. for sm in modules_inf[m]['sub_modules']:
  234. module_name = sm['module_name']
  235. module_inst_num.setdefault(module_name,0)
  236. module_inst_num[module_name] += 1
  237. for m in module_inst_num:
  238. if module_inst_num[m] >= base_threshold:
  239. base_modules.add(m)
  240. # change vim HDLTags path
  241. fp = open(vtags_folder_path + '/files_inf.py','w')
  242. fp.write('FileInf = %s \n'%(files_inf.__str__()))
  243. fp.write('HDLTagsActive = True \n')
  244. fp.close()
  245. if not os.path.isfile(vtags_folder_path + '/vim_local_config.py'):
  246. os.system('cp %s/vim_glb_config.py %s/vim_local_config.py'%(vtags_install_path, vtags_folder_path))
  247. if not os.path.isfile(vtags_folder_path+'/base_modules.pkl'):
  248. output = open(vtags_folder_path+'/base_modules.pkl','wb')
  249. pickle.dump(base_modules, output)
  250. output.close()
  251. """
  252. " https://my.oschina.net/u/2520885
  253. """
  254. "===============================================================================
  255. " Copyright (C) 2016 by Jun Cao
  256. " Permission is hereby granted, free of charge, to any person obtaining a copy
  257. " of this software and associated documentation files (the "Software"), to deal
  258. " in the Software without restriction, including without limitation the rights
  259. " to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  260. " copies of the Software, and to permit persons to whom the Software is
  261. " furnished to do so, subject to the following conditions:
  262. " The above copyright notice and this permission notice shall be included in
  263. " all copies or substantial portions of the Software.
  264. " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  265. " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  266. " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  267. " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  268. " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  269. " OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  270. " THE SOFTWARE.
  271. "===============================================================================
  272. function! VimPythonExtend()
  273. python << EOF
  274. import os
  275. import sys
  276. vtags_install_path = "/mnt/hgfs/VMShare/my_tools/vtags-1.20"
  277. if os.path.isdir(vtags_install_path):
  278. sys.path.insert(0,vtags_install_path)
  279. from Lib.API import *
  280. EOF
  281. endfunction
  282. let is_vtags_installed = 1
  283. if is_vtags_installed == 1
  284. "vi_HDLTags_begin-----------------------------------
  285. call VimPythonExtend()
  286. map gi :py try_go_into_submodule() <CR>
  287. map gu :py try_go_upper_module() <CR>
  288. map <Space><Left> :py try_trace_signal_sources() <CR>
  289. map <Space><Right> :py try_trace_signal_destinations() <CR>
  290. map <Space><Down> :py try_roll_back() <CR>
  291. map <Space><Up> :py try_go_forward() <CR>
  292. map <Space>v :py try_show_frame() <CR>
  293. map <Space>c :py try_add_check_point() <CR>
  294. map <Space>b :py try_add_base_module() <CR>
  295. map <Space> :py try_space_operation() <CR>
  296. map <Space>h :py try_hold_current_win() <CR>
  297. map <Space>d :py try_del_operation() <CR>
  298. map <Space>s :py try_save_env_snapshort() <CR>
  299. "vi_HDLTags_end-------------------------------------
  300. endif
  301. """
  302. https://my.oschina.net/u/2520885
  303. """
  304. #===============================================================================
  305. # Copyright (C) 2016 by Jun Cao
  306. # Permission is hereby granted, free of charge, to any person obtaining a copy
  307. # of this software and associated documentation files (the "Software"), to deal
  308. # in the Software without restriction, including without limitation the rights
  309. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  310. # copies of the Software, and to permit persons to whom the Software is
  311. # furnished to do so, subject to the following conditions:
  312. # The above copyright notice and this permission notice shall be included in
  313. # all copies or substantial portions of the Software.
  314. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  315. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  316. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  317. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  318. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  319. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  320. # THE SOFTWARE.
  321. #===============================================================================
  322. import os
  323. import sys
  324. # import vim, when gen vtags it will no vim,so use try
  325. try:
  326. import vim
  327. except:
  328. pass
  329. # import normal lib
  330. import re
  331. import Lib.Code as Code
  332. import Lib.View as View
  333. PrintReport = View.PrintReport
  334. import Lib.GLB as GLB
  335. G = GLB.G
  336. from Lib.Base import *
  337. # init gen module_inf, and glb define
  338. if G['HDLTagsActive']:
  339. G['ModuleInf'], G['CodeDefineInf'] = gen_modules_and_defines_inf(G['FileInf'])
  340. # open snapshort wins
  341. if G['HDLTagsActive'] and G['EnvSnapshortWinsInf']:
  342. OldOpenWinTrace = [p for p in G['WorkWin_Inf']['OpenWinTrace']]
  343. G['WorkWin_Inf']['OpenWinTrace'].insert(0,vim.current.buffer.name)
  344. for w_inf in G['EnvSnapshortWinsInf']:
  345. c_path = w_inf['path']
  346. c_cursor = w_inf['cursor']
  347. if os.path.isfile(c_path):
  348. View.Open(c_path)
  349. if c_path not in OldOpenWinTrace:
  350. if G['WorkWin_Inf']['OpenWinTrace'] and G['WorkWin_Inf']['OpenWinTrace'][-1] == c_path:
  351. del G['WorkWin_Inf']['OpenWinTrace'][-1]
  352. else:
  353. PrintDebug('Warning: reload file not exit ! file: %s'%(c_path))
  354. for w_inf in G['EnvSnapshortWinsInf']:
  355. c_size = w_inf['size']
  356. c_path = w_inf['path']
  357. if os.path.isfile(c_path):
  358. View.Open(c_path)
  359. vim.current.window.width = c_size[0]
  360. vim.current.window.height = c_size[1]
  361. # because base module may be changed so refresh topo and show base
  362. if G['Frame_Inf']['Frame_Path'] in [ w.buffer.name for w in vim.windows]:
  363. View.refresh_topo()
  364. View.show_base_module()
  365. PrintReport('reload snapshort finish !')
  366. elif G['HDLTagsActive']:
  367. # treat the first win as work win , if cur win is hdl code, and add first trace point
  368. first_cursor_inf = View.get_cur_cursor_inf()
  369. if first_cursor_inf['hdl_type'] == 'verilog':
  370. G['WorkWin_Inf']['OpenWinTrace'].append(first_cursor_inf['file_path'])
  371. View.add_trace_point()
  372. PrintDebug('Point: initial new env finish !')
  373. # shortcut key: gi
  374. def go_into_submodule():
  375. cursor_inf = View.get_cur_cursor_inf()
  376. cur_module_inf = cursor_inf['cur_module_inf']
  377. if not cur_module_inf:
  378. PrintReport('Warning: cur cursor not in a valid module, no submodule call !')
  379. return
  380. call_module_name = cur_module_inf['module_name']
  381. sub_call_inf = Code.get_module_call_sub_module_io_inf(cursor_inf['line'], cursor_inf['pos'], cursor_inf['file_path'])
  382. if not sub_call_inf:
  383. PrintReport('Warning: cur cursor not on recgnized subcall !')
  384. return
  385. sub_module_name = sub_call_inf['sub_module_name']
  386. sub_module_inf = get_module_inf(sub_module_name)
  387. if not sub_module_inf:
  388. PrintReport('Warning: sub module %s no module inf in database !'%(sub_module_name))
  389. return
  390. sub_signal_name = sub_call_inf['sub_io_name']
  391. sub_match_pos = []
  392. if sub_signal_name:
  393. sub_match_pos = sub_call_inf['sub_match_pos']
  394. else:
  395. sub_signal_name = sub_module_name
  396. sub_match_pos = sub_module_inf['module_pos']
  397. call_sub_inf = sub_call_inf['call_sub_inf'] # GLB call sub inf(atom)
  398. sub_module_path = sub_module_inf['file_path']
  399. set_module_last_call_inf(sub_module_name, call_module_name, call_sub_inf['inst_name'])
  400. View.add_trace_point()
  401. View.go_win( sub_module_path, sub_match_pos, sub_signal_name)
  402. def try_go_into_submodule():
  403. if not G['HDLTagsActive']: return
  404. if G['Debug']:
  405. go_into_submodule()
  406. else:
  407. try: go_into_submodule()
  408. except: pass
  409. # shortcut key: gu
  410. def go_upper_module():
  411. cursor_inf = View.get_cur_cursor_inf()
  412. cur_module_inf = cursor_inf['cur_module_inf']
  413. if not cur_module_inf:
  414. PrintReport('Warning: cur line not in a valid verilog module, or current module not in database !')
  415. return
  416. cur_last_call_inf = get_module_last_call_inf(cur_module_inf['module_name'])
  417. if not cur_last_call_inf:
  418. PrintReport('Warning: cur module %s not called by upper module before !'%(cur_module_inf['module_name']))
  419. return
  420. upper_module_name = cur_last_call_inf['upper_module_name']
  421. upper_call_sub_inf = cur_last_call_inf['upper_call_inf']
  422. upper_match_pos = upper_call_sub_inf['match_pos']
  423. upper_inst_name = upper_call_sub_inf['inst_name']
  424. View.add_trace_point()
  425. View.go_win( upper_module_name, upper_match_pos, upper_inst_name)
  426. def try_go_upper_module():
  427. if not G['HDLTagsActive']: return
  428. if G['Debug']:
  429. go_upper_module()
  430. else:
  431. try: go_upper_module()
  432. except: pass
  433. # shortcut key: <Space><Left>
  434. def trace_signal_sources():
  435. if G['IgnoreNextSpaceOp']:
  436. G['IgnoreNextSpaceOp'] = False
  437. PrintDebug('Care: not do this trace source op ,bucause <space> is come from unknow reason !')
  438. return
  439. cursor_inf = View.get_cur_cursor_inf()
  440. trace_signal_name = cursor_inf['word']
  441. if not trace_signal_name:
  442. PrintReport("Warning: Current cursor not on signal name, can not trace source !")
  443. return
  444. # case0: if cur cursor on a macro, go macro define
  445. if Code.trace_glb_define_signal('source', cursor_inf): return
  446. # case1: if cur cursor on io signal, need cross to upper module
  447. if Code.trace_io_signal('source', cursor_inf): return
  448. # case2: if cur cursor on module call io line go to submodule io
  449. if Code.trace_module_call_io_signal('source', cursor_inf): return
  450. # case3: trace signal same as pre trace signal, just show next result
  451. if (G['TraceInf']['LastTraceSource']['Path'] == cursor_inf['file_path']) and (G['TraceInf']['LastTraceSource']['SignalName'] == trace_signal_name) :
  452. View.show_next_trace_result('source')
  453. return
  454. # case4: trace a new normal(not io, sub call io) signal
  455. if Code.trace_normal_signal('source', cursor_inf): return
  456. def try_trace_signal_sources():
  457. if not G['HDLTagsActive']: return
  458. if G['Debug']:
  459. trace_signal_sources()
  460. else:
  461. try: trace_signal_sources()
  462. except: pass
  463. # shortcut key: <Space><Right>
  464. def trace_signal_destinations():
  465. if G['IgnoreNextSpaceOp']:
  466. G['IgnoreNextSpaceOp'] = False
  467. PrintDebug('Care: not do this trace source op ,bucause <space> is come from unknow reason !')
  468. return
  469. cursor_inf = View.get_cur_cursor_inf()
  470. trace_signal_name = cursor_inf['word']
  471. if not trace_signal_name:
  472. PrintReport("Warning: Current cursor not on signal name, can not trace dest!")
  473. return
  474. # case0: if cur cursor on io signal, need cross to upper module
  475. if Code.trace_io_signal('dest', cursor_inf): return
  476. # case1: if cur cursor on module call io line go to submodule io
  477. if Code.trace_module_call_io_signal('dest', cursor_inf): return
  478. # case2: trace signal same as pre trace signal, just show next result
  479. if (G['TraceInf']['LastTraceDest']['Path'] == cursor_inf['file_path']) and (G['TraceInf']['LastTraceDest']['SignalName'] == trace_signal_name) :
  480. View.show_next_trace_result('dest')
  481. return
  482. # case3: if cur cursor on a macro, go macro define
  483. if Code.trace_glb_define_signal('dest', cursor_inf): return
  484. # case4: trace a new normal(not io, sub call io) signal
  485. Code.trace_normal_signal('dest', cursor_inf)
  486. def try_trace_signal_destinations():
  487. if not G['HDLTagsActive']: return
  488. if G['Debug']:
  489. trace_signal_destinations()
  490. else:
  491. try: trace_signal_destinations()
  492. except: pass
  493. # shortcut key: <Space><Down>
  494. def roll_back():
  495. if G['IgnoreNextSpaceOp']:
  496. G['IgnoreNextSpaceOp'] = False
  497. PrintDebug('Care: not do this trace source op ,bucause <space> is come from unknow reason !')
  498. return
  499. cur_nonius = G['OpTraceInf']['Nonius'] - 1
  500. TracePoints = G['OpTraceInf']['TracePoints']
  501. # if reach to the oldest trace point just return
  502. if cur_nonius < 0:
  503. PrintReport("Warning: roll backed to the oldest trace point now !")
  504. return
  505. # go to the trace point
  506. cur_point = TracePoints[cur_nonius]
  507. G['OpTraceInf']['Nonius'] = cur_nonius
  508. View.go_win( cur_point['path'], cur_point['pos'], cur_point['key'])
  509. return
  510. def try_roll_back():
  511. if not G['HDLTagsActive']: return
  512. if G['Debug']:
  513. roll_back()
  514. else:
  515. try: roll_back()
  516. except: pass
  517. # shortcut key: <Space><Up>
  518. def go_forward():
  519. if G['IgnoreNextSpaceOp']:
  520. G['IgnoreNextSpaceOp'] = False
  521. PrintDebug('Care: not do this trace source op ,bucause <space> is come from unknow reason !')
  522. return
  523. cur_nonius = G['OpTraceInf']['Nonius'] + 1
  524. TracePoints = G['OpTraceInf']['TracePoints']
  525. if cur_nonius >= len(TracePoints):
  526. PrintReport("Warning: go forward to the newest trace point now !")
  527. return
  528. cur_point = TracePoints[cur_nonius]
  529. G['OpTraceInf']['Nonius'] = cur_nonius
  530. View.go_win( cur_point['path'], cur_point['pos'], cur_point['key'])
  531. return
  532. def try_go_forward():
  533. if not G['HDLTagsActive']: return
  534. if G['Debug']:
  535. go_forward()
  536. else:
  537. try: go_forward()
  538. except: pass
  539. # shortcut key: <space>
  540. def space_operation():
  541. if G['IgnoreNextSpaceOp']:
  542. G['IgnoreNextSpaceOp'] = False
  543. PrintDebug('Care: not do this trace source op ,bucause <space> is come from unknow reason !')
  544. return
  545. cursor_inf = View.get_cur_cursor_inf()
  546. # if cur in Frame or Report, show file link files
  547. if cursor_inf['file_path'] in [ G['Frame_Inf']['Frame_Path'], G['Report_Inf']['Report_Path'] ]:
  548. cur_frame_link = G['VimBufferLineFileLink'][cursor_inf['file_path']][cursor_inf['line_num']]
  549. View.add_trace_point()
  550. if cur_frame_link and cur_frame_link['path']:
  551. View.go_win( cur_frame_link['path'], cur_frame_link['pos'], cur_frame_link['key'])
  552. View.add_trace_point()
  553. else:
  554. PrintReport('Warning: No file link in current line ! ')
  555. else:
  556. PrintReport('Warning: No space operation in current file ! ')
  557. def try_space_operation():
  558. if not G['HDLTagsActive']: return
  559. if G['Debug']:
  560. space_operation()
  561. else:
  562. try: space_operation()
  563. except: pass
  564. # shortcut key: <s-t>
  565. def show_frame():
  566. G["IgnoreNextSpaceOp"] = G['FixExtraSpace']
  567. if cur_in_frame():
  568. cursor_line = vim.current.window.cursor[0] - 1
  569. View.frame_line_fold_operation(cursor_line)
  570. else:
  571. View.show_topo()
  572. View.show_check_point(False)
  573. View.show_base_module(False)
  574. return
  575. def try_show_frame():
  576. if not G['HDLTagsActive']: return
  577. if G['Debug']:
  578. show_frame()
  579. else:
  580. try: show_frame()
  581. except: pass
  582. return
  583. # shortcut key: <Space>h
  584. def hold_current_win():
  585. cur_path = vim.current.buffer.name
  586. # just del current win frome work win, then will not auto close current win
  587. for i,path in enumerate(G['WorkWin_Inf']['OpenWinTrace']):
  588. if cur_path == path:
  589. del G['WorkWin_Inf']['OpenWinTrace'][i]
  590. break
  591. def try_hold_current_win():
  592. if not G['HDLTagsActive']: return
  593. if G['Debug']:
  594. hold_current_win()
  595. else:
  596. try: hold_current_win()
  597. except: pass
  598. # shortcut key: <Space>c
  599. def add_check_point():
  600. G["IgnoreNextSpaceOp"] = G['FixExtraSpace']
  601. cursor_inf = View.get_cur_cursor_inf()
  602. level = G['CheckPointInf']['TopFoldLevel'] + 1
  603. key = G['Frame_Inf']['FoldLevelSpace']*level + cursor_inf['word']
  604. link = {
  605. 'type' : 'check_point'
  606. ,'key' : cursor_inf['word']
  607. ,'pos' : cursor_inf['pos']
  608. ,'path' : cursor_inf['file_path']
  609. ,'fold_inf' : { 'fold_status': 'fix', 'level': level }
  610. }
  611. G['CheckPointInf']['CheckPoints'].insert(0, {'key': key, 'link': link })
  612. if len(G['CheckPointInf']['CheckPoints']) > G['CheckPointInf']['MaxNum']:
  613. del G['CheckPointInf']['CheckPoints'][-1]
  614. View.show_check_point()
  615. def try_add_check_point():
  616. if not G['HDLTagsActive']: return
  617. if G['Debug']:
  618. add_check_point()
  619. else:
  620. try: add_check_point()
  621. except: pass
  622. # shortcut key: <Space>b
  623. def add_base_module():
  624. G["IgnoreNextSpaceOp"] = G['FixExtraSpace']
  625. cursor_inf = View.get_cur_cursor_inf()
  626. cursor_module = cursor_inf['word']
  627. if not cursor_module:
  628. PrintReport('Warning: cursor not on a valid word ! ')
  629. return
  630. if not get_module_inf(cursor_module):
  631. PrintReport('Warning: cursor words: %s not a recgnized module name ! will no file link ! '%(cursor_module))
  632. if cursor_module in G['BaseModuleInf']['BaseModules']:
  633. PrintReport('Care: module %s is already base module ! '%(cursor_module))
  634. return
  635. G['BaseModuleInf']['BaseModules'].add(cursor_module)
  636. update_base_module_pickle()
  637. View.show_base_module()
  638. View.refresh_topo()
  639. def try_add_base_module():
  640. if not G['HDLTagsActive']: return
  641. if G['Debug']:
  642. add_base_module()
  643. else:
  644. try: add_base_module()
  645. except: pass
  646. #------------------------------
  647. # shortcut key: <Space>d
  648. def del_operation():
  649. if not cur_in_frame():
  650. PrintReport('Warning: Cur file no del function ! ')
  651. return
  652. cur_path = vim.current.buffer.name
  653. cur_line_num = vim.current.window.cursor[0] - 1
  654. cur_file_link = G['VimBufferLineFileLink'][cur_path][cur_line_num]
  655. if not cur_file_link:
  656. PrintReport('Warning: Cur line no del function ! ')
  657. return
  658. # delete a check point, if link has path means a valid link
  659. if (cur_file_link['type'] == 'check_point') and (cur_file_link['fold_inf']['level'] > G['CheckPointInf']['TopFoldLevel']):
  660. G["IgnoreNextSpaceOp"] = G['FixExtraSpace']
  661. check_point_begin_line_num = get_frame_range_inf()['check_point_range'][0]
  662. del_index = cur_line_num - check_point_begin_line_num - 1
  663. del G['CheckPointInf']['CheckPoints'][ del_index ]
  664. View.show_check_point()
  665. return
  666. # del a base module
  667. if (cur_file_link['type'] == 'base_module') and (cur_file_link['fold_inf']['level'] > G['BaseModuleInf']['TopFoldLevel']):
  668. G["IgnoreNextSpaceOp"] = G['FixExtraSpace']
  669. G['BaseModuleInf']['BaseModules'].remove(cur_file_link['key'])
  670. update_base_module_pickle()
  671. View.show_base_module()
  672. View.refresh_topo()
  673. return
  674. PrintReport('Warning: Cur line no del function ! ')
  675. def try_del_operation():
  676. if not G['HDLTagsActive']: return
  677. if G['Debug']:
  678. del_operation()
  679. else:
  680. try: del_operation()
  681. except: pass
  682. #----------------------------------------
  683. # shortcut key: <Space>s
  684. def try_save_env_snapshort():
  685. if not G['HDLTagsActive']: return
  686. if G['Debug']:
  687. if G['SaveEnvSnapshort_F']():
  688. PrintReport('save env snapshort success !')
  689. else:
  690. try:
  691. if G['SaveEnvSnapshort_F']():
  692. PrintReport('save env snapshort success !')
  693. except: pass
  694. """
  695. https://my.oschina.net/u/2520885
  696. """
  697. #===============================================================================
  698. # Copyright (C) 2016 by Jun Cao
  699. # Permission is hereby granted, free of charge, to any person obtaining a copy
  700. # of this software and associated documentation files (the "Software"), to deal
  701. # in the Software without restriction, including without limitation the rights
  702. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  703. # copies of the Software, and to permit persons to whom the Software is
  704. # furnished to do so, subject to the following conditions:
  705. # The above copyright notice and this permission notice shall be included in
  706. # all copies or substantial portions of the Software.
  707. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  708. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  709. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  710. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  711. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  712. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  713. # THE SOFTWARE.
  714. #===============================================================================
  715. import sys
  716. try:
  717. import vim
  718. except:
  719. pass
  720. import os
  721. import re
  722. import pickle
  723. import GLB
  724. G = GLB.G
  725. # function to print debug
  726. PrintDebug = G['PrintDebug_F']
  727. def get_valid_code( str ):
  728. str = re.sub('(^\s*)|(\s*$)', '' ,str)
  729. str = re.sub('//.*', '' ,str)
  730. str = re.sub('^`.*', '' ,str) # bug ^\s*`.*
  731. return str
  732. def get_valid_code_leave_head_space( str ):
  733. str = re.sub('\s*$', '' ,str)
  734. str = re.sub('//.*', '' ,str)
  735. str = re.sub('^`.*', '' ,str)
  736. return str
  737. def cur_in_frame():
  738. return vim.current.buffer.name == G['Frame_Inf']['Frame_Path']
  739. def cur_in_report():
  740. return vim.current.buffer.name == G['Report_Inf']['Report_Path']
  741. def get_path_for_name(path_or_name):
  742. if path_or_name == 'Frame':
  743. return G["Frame_Inf"]["Frame_Path"]
  744. if path_or_name == 'Report':
  745. return G["Report_Inf"]["Report_Path"]
  746. may_module_inf = get_module_inf(path_or_name)
  747. if may_module_inf:
  748. return may_module_inf['file_path']
  749. return path_or_name
  750. def get_file_name_from_path(path):
  751. return re.sub('.*/','',path)
  752. def get_full_word(line, y):
  753. pre_part = ( re.match('^(?P<pre>\w*)',(line[:y])[::-1]).group('pre') )[::-1]
  754. post_part = re.match('^(?P<post>\w*)', line[y:]).group('post')
  755. return pre_part + post_part
  756. def get_file_path_postfix(file_path):
  757. if type(file_path) != str:
  758. return
  759. split_by_dot = file_path.split('.')
  760. if len(split_by_dot) < 2 : # which means file_path has no postfix
  761. return ''
  762. # post_fix = split_by_dot[-1].lower() # postfix don't care case
  763. post_fix = split_by_dot[-1] # postfix care case
  764. return post_fix
  765. def get_file_hdl_type(file_path):
  766. postfix = get_file_path_postfix(file_path)
  767. if postfix in G['SupportVHDLPostfix']:
  768. return 'vhdl'
  769. elif postfix in G['SupportVerilogPostfix']:
  770. return 'verilog'
  771. else:
  772. return ''
  773. #------------------------------------------------------------
  774. def get_vhdl_full_line(codes, start_pos, direction):
  775. pass
  776. def get_verilog_pre_full_line(codes, start_pos):
  777. pre_full_line = ''
  778. start_x, start_y = start_pos
  779. start_line = codes[start_x][:start_y+1]
  780. start_line = start_line.strip('\n')
  781. start_line = re.sub('//.*','',start_line)
  782. colon_y = start_line.rfind(';')
  783. if colon_y != -1:
  784. pre_full_line = start_line[colon_y+1:]
  785. else:
  786. pre_full_line = start_line
  787. for i in range(start_x-1,-1,-1):
  788. t_line = codes[i].strip('\n')
  789. t_line = re.sub('//.*', '', t_line)
  790. t_colon_y = t_line.rfind(';')
  791. if t_colon_y != -1:
  792. pre_full_line = t_line[t_colon_y+1:] + ' ' + pre_full_line
  793. break
  794. else:
  795. pre_full_line = t_line + ' ' +pre_full_line
  796. return pre_full_line
  797. def get_verilog_post_full_line(codes, start_pos):
  798. post_full_line = ''
  799. start_x, start_y = start_pos
  800. start_line = codes[start_x][start_y:]
  801. start_line = start_line.strip('\n')
  802. start_line = re.sub('//.*','',start_line)
  803. colon_y = start_line.find(';')
  804. if colon_y != -1:
  805. pre_full_line = start_line[:colon_y+1]
  806. else:
  807. pre_full_line = start_line
  808. for i in range(start_x+1,len(codes)):
  809. t_line = codes[i].strip('\n')
  810. t_line = re.sub('//.*', '', t_line)
  811. t_colon_y = t_line.find(';')
  812. if t_colon_y != -1:
  813. pre_full_line = pre_full_line + ' ' + t_line[: t_colon_y+1]
  814. break
  815. else:
  816. pre_full_line = pre_full_line + ' ' + t_line
  817. return pre_full_line
  818. def get_verilog_full_line(codes, start_pos, direction):
  819. if direction == -1: # 0 <- x
  820. return get_verilog_pre_full_line(codes, start_pos)
  821. elif direction == 1: # x -> n
  822. return get_verilog_post_full_line(codes, start_pos)
  823. elif direction == 0: # 0 <- x -> n
  824. return get_verilog_pre_full_line(codes, start_pos) + get_verilog_post_full_line(codes, start_pos)[1:] # [1:] because start char at both part
  825. else:
  826. return ''
  827. def get_full_line( codes, hdl_type, start_pos, direction = 0):
  828. if hdl_type == 'vhdl':
  829. return get_vhdl_full_line(codes, start_pos, direction)
  830. elif hdl_type == 'verilog':
  831. return get_verilog_full_line(codes, start_pos, direction)
  832. else:
  833. return ''
  834. # --------------------------------------------------------
  835. # ok
  836. def recgnize_io_signal_line(line, line_num):
  837. # pre check if is not io
  838. if line.find('input') == -1 and line.find('output') == -1:
  839. return False
  840. line = line.strip('\n')
  841. line = re.sub('//.*','',line) # del notes
  842. # raw re match
  843. re_match = re.match('\s*(input|output)\W',line)
  844. if not re_match:
  845. re_match = re.match('(?P<prefix>.*\(\s*)(?P<real_io>(input|output)\W.*)',line)
  846. if re_match:
  847. prefix = re_match.group('prefix')
  848. real_io_line = re_match.group('real_io')
  849. line = ' '*(len(prefix)) + real_io_line
  850. else:
  851. return False
  852. # match used egrep io line decode function
  853. egrep_io_line = str(line_num)+':'+line
  854. io_inf = decode_egreped_verilog_io_line(egrep_io_line)['io_infs']
  855. return io_inf
  856. # "name" : name
  857. # , "io_type" : io_type
  858. # , "left" : left_index
  859. # , "right" : right_index
  860. # , "size" : size
  861. # , 'line_num' : line_num
  862. # , 'name_pos' : (line_num, colm_num)
  863. # , 'code_line' : code_line
  864. # , 'signal_type' : signal_type }
  865. #-----------------------------------------------------------
  866. # ok
  867. def search_verilog_code_use_grep(key, path, row_range = ()):
  868. search_result = []
  869. if not path:
  870. path = vim.current.buffer.name
  871. match_lines = os.popen('egrep -n -h \'(^|\W)%s(\W|$)\' %s'%(key, path)).readlines()
  872. for l in match_lines:
  873. l = l.strip('\n')
  874. split0 = l.split(':')
  875. line_num = int(split0[0]) - 1
  876. code_line = ':'.join(split0[1:])
  877. if row_range and ( line_num not in range(row_range[0], row_range[1]+1 ) ):
  878. continue
  879. # del note see if has key
  880. s0 = re.search('(?P<pre>^|\W)%s(\W|$)'%(key), re.sub('//.*','',code_line) )
  881. if s0:
  882. colum_num = s0.span()[0] + len(s0.group('pre'))
  883. match_pos = (line_num, colum_num)
  884. line = code_line
  885. search_result.append( (match_pos, line) )
  886. return search_result
  887. #----------------------------------------------------------
  888. def get_fram_topo_sub_inf(topo_module, cur_level):
  889. sub_level = cur_level + 1
  890. topo_prefix = G['Frame_Inf']['FoldLevelSpace'] * sub_level
  891. topo_datas = []
  892. topo_links = []
  893. sub_func_modules, sub_base_modules = get_sub_func_base_module(topo_module)
  894. # first deal sub func module, show "inst(module)"
  895. sub_func_modules_inst_names = list(sub_func_modules)
  896. sub_func_modules_inst_names.sort()
  897. for c_sub_inst_name in sub_func_modules_inst_names:
  898. c_call_sub_inf = sub_func_modules[c_sub_inst_name]
  899. c_sub_module_name = c_call_sub_inf['module_name']
  900. # gen show data
  901. c_str = '%s%s(%s)'%(topo_prefix, c_sub_inst_name, c_sub_module_name)
  902. topo_datas.append(c_str)
  903. # gen link
  904. c_topo_link = {
  905. 'type' : 'topo'
  906. ,'topo_inst_name' : ''
  907. ,'key' : ''
  908. ,'pos' : ''
  909. ,'path' : ''
  910. ,'fold_inf' : {'fold_status':'off', 'level': sub_level}
  911. }
  912. c_sub_module_inf = get_module_inf(c_sub_module_name)
  913. if c_sub_module_inf:
  914. c_topo_link['topo_inst_name'] = c_sub_inst_name
  915. c_topo_link['key' ] = c_sub_module_name
  916. c_topo_link['pos' ] = c_sub_module_inf['module_pos']
  917. c_topo_link['path' ] = c_sub_module_inf['file_path']
  918. # show cur module, then all submodule, last call set to cur module
  919. set_module_last_call_inf(c_sub_module_name, topo_module, c_call_sub_inf['inst_name'])
  920. topo_links.append(c_topo_link)
  921. sub_base_modules_names = list(sub_base_modules)
  922. sub_base_modules_names.sort()
  923. if len(sub_base_modules_names) > 0:
  924. # deal base , show "module(n)"
  925. # add one to sep func and base
  926. topo_datas.append(topo_prefix+'------')
  927. c_topo_link = {
  928. 'type' : 'topo'
  929. ,'topo_inst_name' : ''
  930. ,'key' : ''
  931. ,'pos' : ()
  932. ,'path' : ''
  933. ,'fold_inf' : {'fold_status':'on', 'level': sub_level}
  934. }
  935. topo_links.append(c_topo_link)
  936. for c_sub_module_name in sub_base_modules_names:
  937. # deal data
  938. c_sub_inst_n = len(sub_base_modules[c_sub_module_name])
  939. c_str = '%s%s(%d)'%(topo_prefix,c_sub_module_name,c_sub_inst_n)
  940. topo_datas.append(c_str)
  941. # deal link
  942. c_topo_link = {
  943. 'type' : 'topo'
  944. ,'topo_inst_name' : ''
  945. ,'key' : ''
  946. ,'pos' : ''
  947. ,'path' : ''
  948. ,'fold_inf' : {'fold_status':'off', 'level': sub_level}
  949. }
  950. c_sub_module_inf = get_module_inf(c_sub_module_name)
  951. if c_sub_module_inf:
  952. c_topo_link['key' ] = c_sub_module_name
  953. c_topo_link['pos' ] = c_sub_module_inf['module_pos']
  954. c_topo_link['path'] = c_sub_module_inf['file_path']
  955. topo_links.append(c_topo_link)
  956. return topo_datas, topo_links
  957. def get_fram_check_point_inf():
  958. datas = []
  959. links = []
  960. for cp in G['CheckPointInf']['CheckPoints']:
  961. datas.append(cp['key'])
  962. links.append(cp['link'])
  963. return datas, links
  964. def get_fram_base_module_inf():
  965. datas = []
  966. links = []
  967. base_module_level = G['BaseModuleInf']['TopFoldLevel'] + 1
  968. base_module_space = G['Frame_Inf']['FoldLevelSpace'] * base_module_level
  969. base_modules = list(G['BaseModuleInf']['BaseModules'])
  970. base_modules.sort()
  971. for bm in base_modules:
  972. key = base_module_space + bm
  973. link = {
  974. 'type' : 'base_module'
  975. ,'key' : bm
  976. ,'pos' : ''
  977. ,'path' : ''
  978. ,'fold_inf' : { 'fold_status': 'fix', 'level': base_module_level }
  979. }
  980. bm_module_inf = get_module_inf(bm)
  981. if bm_module_inf:
  982. link['pos'] = bm_module_inf['module_pos']
  983. link['path'] = bm_module_inf['file_path']
  984. datas.append(key)
  985. links.append(link)
  986. return datas, links
  987. ###########################################################
  988. #----------------------------------------------------------
  989. def decode_egreped_verilog_io_line(o_io_line):
  990. # exp:
  991. # 365:output alu_frf_part_p0_w;
  992. # 366:output [127:0] alu_frf_data_p0_w;
  993. # 357:output [THR_WIDTH-1:0] alu_dst_cond_tid_w
  994. # 368:output reg alu_frf_part_p0_w;
  995. # 369:output wire [127:0] alu_frf_data_p0_w;
  996. # 370:output reg [THR_WIDTH-1:0] alu_dst_cond_tid_w
  997. # 388:input [width-1 : 0] A,B;
  998. # split by ":" | 388:input [width-1 : 0] A,B;
  999. # split0 | 0 ^ 1 ^ 2
  1000. split0 = o_io_line.split(':')
  1001. line_num = int(split0[0]) - 1 # -1 because egrep form 1, our line from 0
  1002. code_line = ':'.join(split0[1:])
  1003. # valid code line is code_line del note, and change all \s+ to ' '
  1004. valid_code_line = re.sub('(//.*)|(^\s+)|(\s+$)','',code_line)
  1005. valid_code_line = re.sub('\s+',' ',valid_code_line)
  1006. valid_code_line = re.sub('\W*$', '',valid_code_line)# del end ";" or ","
  1007. # io type is the first word in valid_code_line
  1008. match_io_type = re.match('(?P<io_type>\w+)\s*(?P<other>.*)',valid_code_line)
  1009. assert(match_io_type)
  1010. io_type = match_io_type.group('io_type')
  1011. other = match_io_type.group('other').strip(' ')
  1012. # other: [width-1 : 0] A,B | wire [127:0] alu_frf_data_p0_w | alu_frf_part_p0_w
  1013. # get name, name is the last word or words sep by ',' ; reverse it and reverse back
  1014. # exp: A | A,B | A,B,C
  1015. match_name = re.match('\s*(?P<r_names_str>\w+(\s*,\s*\w+)*)\s*(?P<r_other>.*)',other[::-1])
  1016. assert(match_name),'%s | %s'%(other,code_line)
  1017. other = (match_name.group('r_other')[::-1]).strip(' ')
  1018. names_str = match_name.group('r_names_str')[::-1]
  1019. names = re.sub('\s+','',names_str).split(',')
  1020. names_pos = []
  1021. if len(names) == 1:
  1022. colum = re.search('\W%s(\W|$)'%(names[0]),code_line).span()[0] + 1
  1023. names_pos = [ ( line_num, colum ) ]
  1024. else:
  1025. for n in names:
  1026. colum = re.search('\W%s(\W|$)'%(n),code_line).span()[0] + 1
  1027. names_pos.append( (line_num, colum) )
  1028. # signal_type is the first word of other, maybe empty
  1029. # case0 : empty
  1030. # case1 : reg
  1031. # case2 : reg [THR_WIDTH-1:0]
  1032. # case3 : [127:0]
  1033. signal_type = 'wire'
  1034. if other:
  1035. match_signal_type = re.match('\s*(?P<signal_type>\w*)\s*(?P<other>.*)',other)
  1036. assert(match_signal_type)
  1037. m_signal_type = match_signal_type.group('signal_type')
  1038. if m_signal_type:
  1039. signal_type = m_signal_type
  1040. other = match_signal_type.group('other').strip(' ')
  1041. # other is empty or [a : b]
  1042. left_index = ''
  1043. right_index = ''
  1044. size = 1
  1045. if other:
  1046. assert(other[0] == '[' and other[-1] == ']'),'%s'%(other)
  1047. indexs = other[1:-1].split(':')
  1048. if len(indexs) == 2:
  1049. left_index = indexs[0].strip(' ')
  1050. right_index = indexs[1].strip(' ')
  1051. try:
  1052. left_index = int(left_index)
  1053. right_index = int(left_index)
  1054. size = right_index - left_index + 1
  1055. except:
  1056. size = other
  1057. # may a line has mulity names
  1058. io_infs = {}
  1059. for i, name in enumerate(names):
  1060. io_infs[name] = {
  1061. "name" : name
  1062. , "io_type" : io_type
  1063. , "left" : left_index
  1064. , "right" : right_index
  1065. , "size" : size
  1066. , 'line_num' : line_num
  1067. , 'name_pos' : names_pos[i]
  1068. , 'code_line' : code_line
  1069. , 'signal_type' : signal_type
  1070. }
  1071. return {'io_infs':io_infs, 'name_list':names}
  1072. #------------------------------------------------
  1073. # for code in verilog modules, from pos to find next pair ")"
  1074. # case 0:
  1075. # if pos is "(" | ( A...B )
  1076. # pos | ^
  1077. # rest | parm_line= A...B, end_pos = B 's pos
  1078. # case 1:
  1079. # if pos not "("| ( A...B )
  1080. # pos | ^
  1081. # rest | parm_line= A...B, end_pos = B 's pos
  1082. def get_str_to_next_right_bracket(module_lines, pos):
  1083. assert(0),'not used not realized '
  1084. def get_str_to_pre_left_bracket(module_lines, pos):
  1085. assert(0),'not used not realized '
  1086. #-------------------------------------------
  1087. # for situation:
  1088. # case0 : module_name inst_name (.a(A), .b(B), .c(C)) |
  1089. # | ^ | input pos
  1090. # | ^0 ^1 | module_range[0]
  1091. # case1 : module_name #( .a(A), .b(B), .c(C) ) inst_name ( ... )
  1092. # | ^ | input pos
  1093. # | ^ | module_range[0]
  1094. # case2 : module_name #( A, B, C ) inst_name ( .x(X), .y(Y) )
  1095. # | ^ | input pos
  1096. # | ^ | module_range[0]
  1097. # case3 : module_name ... inst_name[a:b] ...
  1098. # case4 : module_name ... inst_name[a:b] (A,B,C)
  1099. def get_verilog_sub_module_inf_from_dot_line( pos, module_lines, module_start_line_num):
  1100. dot_line = get_valid_code(module_lines[pos[0]])
  1101. assert(dot_line[pos[1]] == '.')
  1102. module_name = ''
  1103. inst_name = ''
  1104. match_range = []
  1105. match_pos = ()
  1106. # first deal pre dot line
  1107. pre_line_end = False
  1108. dot_pre_line = dot_line[:pos[1]+1] # module_name inst_name (.
  1109. pre_next_line_num = pos[0] - 1
  1110. search_case0 = ''
  1111. search_case12 = ''
  1112. while not pre_line_end:
  1113. semicolon_y = dot_pre_line.find(';')
  1114. if semicolon_y != -1:
  1115. pre_line_end = True
  1116. dot_pre_line = dot_pre_line[semicolon_y + 1:]
  1117. search_case0 = re.search('(^|\W)(?P<m_name>\w+)\s+(?P<i_name>\w+(\s*\[[^\[\]]*\])?)\s*\(\s*\.$',dot_pre_line)
  1118. if search_case0:
  1119. module_name = search_case0.group('m_name')
  1120. inst_name = search_case0.group('i_name')
  1121. break
  1122. search_case12 = re.search('(^|\W)(?P<m_name>\w+)\s*#\s*\(', dot_pre_line)
  1123. if search_case12:
  1124. module_name = search_case12.group('m_name')
  1125. match_case2_inst_name = re.match('\.\s*\(\s*(?P<r_i_name>(\s*\][^\[\]]*\[\s*)?\w+)',dot_pre_line[::-1]) # inst_name ( .
  1126. if match_case2_inst_name:
  1127. inst_name = match_case2_inst_name.group('r_i_name')[::-1]
  1128. break
  1129. if pre_next_line_num >= 0:
  1130. dot_pre_line = get_valid_code(module_lines[pre_next_line_num]) + ' ' + dot_pre_line
  1131. pre_next_line_num -= 1
  1132. else:
  1133. pre_line_end = True
  1134. # if not match anyone then unrecgize
  1135. if not (search_case0 or search_case12):
  1136. PrintDebug('Error: 0 cur dot match cannot recgnize ! line: %s , pos: %s'%(dot_line, pos.__str__()))
  1137. return False
  1138. # if no inst name need decode dot back line
  1139. if not inst_name: # case1: module_name #( .a(A), .b(B), .c(C) ) inst_name ( ... )
  1140. back_line_end = False
  1141. dot_back_line = dot_line[pos[1]:] # .a(A), .b(B), .c(C))
  1142. back_next_line_num = pos[0] + 1
  1143. search_case1_inst_name = ''
  1144. while not back_line_end:
  1145. semicolon_y = dot_back_line.find(';')
  1146. if semicolon_y != -1:
  1147. back_line_end = True
  1148. dot_back_line = dot_back_line[:semicolon_y]
  1149. # inst_name ( .x
  1150. search_case1_inst_name = re.search('\)\s*(?P<i_name>\w+(\s*\[[^\[\]]*\])?)\s*\(',dot_back_line)
  1151. if search_case1_inst_name:
  1152. inst_name = search_case1_inst_name.group('i_name')
  1153. break
  1154. if back_next_line_num < len(module_lines):
  1155. dot_back_line = dot_back_line + ' ' +get_valid_code(module_lines[back_next_line_num])
  1156. back_next_line_num += 1
  1157. else:
  1158. back_line_end = True
  1159. if not inst_name:
  1160. PrintDebug('Error: 1 cur dot match cannot recgnize inst name ! line: %s , pos: %s'%(dot_line, pos.__str__()))
  1161. return False
  1162. match_range = [ pre_next_line_num + 1 + module_start_line_num, -1 ]
  1163. module_y = module_lines[pre_next_line_num + 1].find(module_name)
  1164. assert(module_y != -1)
  1165. match_pos = ( pre_next_line_num + 1 + module_start_line_num, module_y )
  1166. return {
  1167. 'inst_name' : inst_name
  1168. ,'module_name' : module_name
  1169. ,'match_range' : match_range
  1170. ,'match_pos' : match_pos
  1171. }
  1172. # case 0: dff # (...) my_dff(a, b, c); in only one line
  1173. def get_verilog_sub_module_inf_from_pound_line( pos, module_lines, module_start_line_num):
  1174. pound_line = get_valid_code(module_lines[pos[0]])
  1175. match_sub = re.match('\s*(?P<module_name>\w+)\s+#\s*\(.*\)\s*(?P<inst_name>\w+)\s*\(.*\)\s*;\s*', pound_line)
  1176. if match_sub:
  1177. return {
  1178. 'inst_name' : match_sub.group('inst_name')
  1179. ,'module_name' : match_sub.group('module_name')
  1180. ,'match_range' : [ pos[0] + module_start_line_num, pos[0] + module_start_line_num ]
  1181. ,'match_pos' : ( pos[0] + module_start_line_num, module_lines[pos[0]].find(match_sub.group('module_name')) )
  1182. }
  1183. return False
  1184. # for current valid module lines
  1185. # find each pair : (".xxx(...)" ";")
  1186. # get the each pair result :{ 'inst_name' : inst_name
  1187. # ,'module_name' : modu_name
  1188. # ,'match_range' : match_range
  1189. # ,'match_pos' : match_pos}
  1190. # finial result is : [ pair_result0, pair_result1, ... ]
  1191. def get_verilog_sub_module_inf(module_lines, module_start_line_num, gen_vtags_log_path = ''):
  1192. sub_module_inf = []
  1193. has_call_sub_not_end = False
  1194. find_next = True
  1195. for i ,l in enumerate(module_lines):
  1196. if find_next:
  1197. assert(not has_call_sub_not_end),'already start new search, should not has unfinish subcall'
  1198. cur_sub_module_inf = {}
  1199. cur_match_right_part = ''
  1200. if l.find('.') != -1:
  1201. l = get_valid_code(l)
  1202. s0 = re.search('(^|\W)\.\w+\s*\(', l)
  1203. if not s0:
  1204. continue
  1205. # no matter recgnize or not , must wait next ";", continue search
  1206. find_next = False
  1207. # get dot pos
  1208. dot_colm = ''
  1209. if l[0] is '.':
  1210. dot_colm = 0
  1211. else:
  1212. dot_colm = s0.span()[0] + 1
  1213. assert(dot_colm != '')
  1214. cur_match_right_part = l[s0.span()[1]:]
  1215. # get cur sub module inf
  1216. cur_sub_module_inf = get_verilog_sub_module_inf_from_dot_line( (i, dot_colm), module_lines, module_start_line_num)
  1217. elif l.find('#') != -1:
  1218. l = get_valid_code(l)
  1219. s1 = re.search('#\s*\(', l)
  1220. if not s1:
  1221. continue
  1222. # no matter recgnize or not , must wait next ";", continue search
  1223. find_next = False
  1224. # get dot pos
  1225. pound_colm = ''
  1226. dot_colm = s1.span()[0]
  1227. cur_match_right_part = l[s1.span()[1]:]
  1228. # get cur sub module inf
  1229. cur_sub_module_inf = get_verilog_sub_module_inf_from_pound_line( (i, pound_colm), module_lines, module_start_line_num)
  1230. else:
  1231. continue
  1232. # find result in two way
  1233. if cur_sub_module_inf:
  1234. assert(not has_call_sub_not_end)
  1235. sub_module_inf.append(cur_sub_module_inf)
  1236. has_call_sub_not_end = True
  1237. else:
  1238. PrintDebug( 'Error : not recgnize %d: %s '%(i+module_start_line_num, l ), gen_vtags_log_path )
  1239. # no matter find or not , current back line has valid ";", continue find new match
  1240. if cur_match_right_part.find(';') != -1:
  1241. find_next = True
  1242. # if end at current line, set the call range [1]
  1243. if has_call_sub_not_end and cur_match_right_part.find(';') != -1:
  1244. sub_module_inf[-1]['match_range'][1] = i + module_start_line_num # start line and end line the same
  1245. has_call_sub_not_end = False
  1246. continue
  1247. if (not find_next) and l.find(';') != -1:
  1248. if get_valid_code(l).find(';') != -1:
  1249. # if current not find next, and match a valid ";", need continue search
  1250. find_next = True
  1251. # if has unended sub call, and find a valid ";", set last call sub range[1]
  1252. if has_call_sub_not_end:
  1253. sub_module_inf[-1]['match_range'][1] = i + module_start_line_num # end line is the first ; line
  1254. has_call_sub_not_end = False
  1255. # if has_call_sub_not_end and (not find_next) and l.find(';') != -1:
  1256. if has_call_sub_not_end and l.find(';') != -1:
  1257. if get_valid_code(l).find(';') != -1:
  1258. sub_module_inf[-1]['match_range'][1] = i + module_start_line_num # end line is the first ; line
  1259. has_call_sub_not_end = False
  1260. if has_call_sub_not_end:
  1261. PrintDebug('Error : call sub not end at end module , try module end as callsub end ! : %s'%(sub_module_inf[-1].__str__()), gen_vtags_log_path)
  1262. sub_module_inf[-1]['match_range'][1] = len(module_lines) - 1 + module_start_line_num # end line is the first ; line
  1263. return sub_module_inf
  1264. #-------------------------------------------
  1265. # modules_inf = { module_name: module_inf }
  1266. # defines_inf = { macro_name : [ define_inf ] }
  1267. # files_inf = { file_name : file_inf }
  1268. # module_inf = { 'module_name' : module_name
  1269. # ,'file_path' : f
  1270. # ,'line_range_in_file' : (module_start_line_num, module_end_line_num)
  1271. # ,'module_pos' : module_pos
  1272. # ,'sub_modules' : sub_modules }
  1273. # define_inf = { "name" : xxx
  1274. # ,"path" : f
  1275. # ,"pos" : (line_num, colum_num) # name first char pos
  1276. # ,'code_line' : `define xxx .... }
  1277. # file_inf = { 'glb_defines' : [ define_inf ]
  1278. # ,'module_infs' : [ module_inf ]
  1279. # ,'module_calls' : [ call_sub_inf ]
  1280. # ,'file_edit_inf' : { 'create_time': ..., 'last_modify_time': ...}
  1281. # call_sub_inf = { 'inst_name' : inst_name
  1282. # ,'module_name' : module_name
  1283. # ,'match_range' : match_range
  1284. # ,'match_pos' : match_pos }
  1285. def gen_modules_and_defines_inf(files_inf):
  1286. modules_inf = {}
  1287. global_defines_inf = {}
  1288. for c_file_path in files_inf:
  1289. c_file_inf = files_inf[c_file_path]
  1290. # merge defines
  1291. c_file_glb_defines = c_file_inf['glb_defines']
  1292. for d in c_file_glb_defines:
  1293. d_name = d['name']
  1294. global_defines_inf.setdefault(d_name,[])
  1295. global_defines_inf[d_name].append(d)
  1296. # merge modules_inf
  1297. c_file_module_infs = c_file_inf['module_infs']
  1298. for m in c_file_module_infs:
  1299. mn = m['module_name']
  1300. if mn in modules_inf:
  1301. PrintDebug('Error: module %s has multip defines ! in %s '%(mn, [ modules_inf[mn]['file_path'], m['file_path'] ].__str__() ))
  1302. else:
  1303. modules_inf.setdefault(mn, None)
  1304. modules_inf[mn] = m
  1305. return modules_inf, global_defines_inf
  1306. def updata_file_pickle_inf(path):
  1307. PrintDebug('Care: updata database, file: %s'%(path))
  1308. if get_file_path_postfix(path) not in G['SupportVerilogPostfix']:
  1309. PrintDebug('Warning: updata_file_pickle_inf: file not verilog file ! file: %s'%(path))
  1310. return False
  1311. if not os.path.isfile(path):
  1312. PrintDebug('Error: updata_file_pickle_inf: file not exit ! file: %s'%(path))
  1313. return
  1314. new_file_modules_inf = get_single_verilog_file_code_inf(path)
  1315. glb_defines = new_file_modules_inf['glb_defines'] #[ define_inf ]
  1316. module_infs = new_file_modules_inf['module_infs'] #[ module_inf ]
  1317. # updata files_inf
  1318. if path not in G['FileInf']:
  1319. # if add new inf just add
  1320. G['FileInf'][path] = new_file_modules_inf
  1321. # add glb_defines
  1322. for gd in glb_defines:
  1323. gd_name = gd['name']
  1324. G['CodeDefineInf'].setdefault(gd_name,[])
  1325. G['CodeDefineInf'][gd_name].append( gd )
  1326. # add module infs
  1327. for m_inf in module_infs:
  1328. m_name = m_inf['module_name']
  1329. if m_name in G['ModuleInf']:
  1330. PrintDebug('Error: module %s define twice ! used last at %s, %s'%(m_name, G['ModuleInf'][m_name]['file_path'], path))
  1331. G['ModuleInf'][m_name] = m_inf
  1332. else:
  1333. # need refresh old and add new, so just gen new inf
  1334. G['FileInf'][path] = new_file_modules_inf
  1335. G['ModuleInf'], G['CodeDefineInf'] = gen_modules_and_defines_inf(G['FileInf'])
  1336. # update pickles
  1337. if not os.path.isdir(G['VTagsPath']):
  1338. os.system('mkdir -p '+G['VTagsPath'])
  1339. fp = open(G['VTagsPath'] + '/files_inf.py','w')
  1340. fp.write('FileInf = %s \n'%(G['FileInf'].__str__()))
  1341. fp.write('HDLTagsActive = True \n')
  1342. fp.close()
  1343. def get_module_inf(module_name):
  1344. if module_name not in G['ModuleInf']:
  1345. PrintDebug('Warning:get_module_inf: "%s" not konwn module !'%(module_name) )
  1346. return False
  1347. module_inf = G['ModuleInf'][module_name]
  1348. module_path = module_inf['file_path']
  1349. cur_inf_time = G['FileInf'][module_path]['file_edit_inf']['last_modify_time']
  1350. last_modify_time = os.path.getmtime(module_path)
  1351. # cur module file not modify, then inf valid and return
  1352. if cur_inf_time == last_modify_time:
  1353. return module_inf
  1354. # if cur module file modify , update Module_inf and return new
  1355. updata_file_pickle_inf(module_path)
  1356. return get_module_inf(module_name)
  1357. #----------------------------------------------------
  1358. def get_line_inf_from_cur_file_inf(line_num, file_inf):
  1359. line_module_inf = {}
  1360. line_call_sub_inf = {}
  1361. module_infs = file_inf['module_infs' ] #[ module_inf ]
  1362. module_calls = file_inf['module_calls'] #[ call_sub_inf ]
  1363. # first get current line module inf
  1364. for m_inf in module_infs:
  1365. c_module_range = m_inf['line_range_in_file']
  1366. if c_module_range[1] < line_num:
  1367. continue
  1368. if line_num < c_module_range[0]:
  1369. break
  1370. line_module_inf = m_inf
  1371. # second get current line call sub inf
  1372. for c_inf in module_calls:
  1373. c_call_range = c_inf['match_range']
  1374. if c_call_range[1] < line_num:
  1375. continue
  1376. if line_num < c_call_range[0]:
  1377. break
  1378. line_call_sub_inf = c_inf
  1379. return {
  1380. 'line_module_inf' : line_module_inf
  1381. ,'line_call_sub_inf' : line_call_sub_inf
  1382. }
  1383. def get_file_line_inf(line_num, path = ''):
  1384. if not path:
  1385. path = vim.current.buffer.name
  1386. if get_file_path_postfix(path) not in G['SupportVerilogPostfix']:
  1387. PrintDebug('Warning: get_file_line_inf: file not verilog file ! file: %s'%(path))
  1388. return False
  1389. if path not in G['FileInf']:
  1390. updata_file_pickle_inf(path)
  1391. if path not in G['FileInf']:
  1392. PrintDebug('Warning: get_file_line_inf: %s has no file database !'%(path) )
  1393. return False
  1394. cur_inf_time = G['FileInf'][path]['file_edit_inf']['last_modify_time']
  1395. last_modify_time = os.path.getmtime(path)
  1396. # cur module file not modify, then inf valid and return
  1397. if cur_inf_time == last_modify_time:
  1398. return get_line_inf_from_cur_file_inf( line_num, G['FileInf'][path] )
  1399. # if cur module file modify , update Module_inf and return new
  1400. updata_file_pickle_inf(path)
  1401. return get_file_line_inf(line_num, path)
  1402. #----------------------------------------------
  1403. # { module_name:'', 'call_inf':atom}
  1404. def get_module_last_call_inf(module_name):
  1405. if module_name not in G['ModuleLastCallInf']:
  1406. return False
  1407. upper_module_name = G['ModuleLastCallInf'][module_name]['upper_module_name']
  1408. upper_inst_name = G['ModuleLastCallInf'][module_name]['upper_inst_name']
  1409. if upper_module_name not in G['ModuleInf']:
  1410. return False
  1411. if upper_inst_name not in G['ModuleInf'][upper_module_name]['sub_calls']:
  1412. return False
  1413. upper_call_inf = G['ModuleInf'][upper_module_name]['sub_calls'][upper_inst_name]
  1414. return {'upper_module_name': upper_module_name, 'upper_call_inf': upper_call_inf}
  1415. def set_module_last_call_inf(sub_module_name, upper_module_name, upper_inst_name):
  1416. G['ModuleLastCallInf'][sub_module_name] = { 'upper_module_name': upper_module_name, 'upper_inst_name': upper_inst_name }
  1417. #----------------------------------------------
  1418. # for a module's submodule, sep function module and base module
  1419. def get_sub_func_base_module(module_name):
  1420. func_modules = {} # inst:module
  1421. base_modules = {} # module : [inst0,inst1...]
  1422. sub_modules = []
  1423. if module_name in G['ModuleInf']:
  1424. sub_modules = G['ModuleInf'][module_name]['sub_modules']
  1425. for sm in sub_modules:
  1426. inst_name = sm['inst_name']
  1427. module_name = sm['module_name']
  1428. if module_name in G['BaseModuleInf']['BaseModules']:
  1429. base_modules.setdefault(module_name,[])
  1430. base_modules[module_name].append(inst_name)
  1431. else:
  1432. if inst_name in func_modules: # has to same inst name, may be use `ifdefine sep
  1433. new_inst_name = inst_name+'_'+str(sm['match_range'][0])
  1434. func_modules[new_inst_name] = sm
  1435. continue
  1436. func_modules[inst_name] = sm
  1437. return func_modules, base_modules
  1438. #----------------------------------------------
  1439. # update function base information, no need added each times
  1440. def update_base_module_pickle():
  1441. pkl_output = open(G['VTagsPath'] + '/base_modules.pkl','wb')
  1442. pickle.dump(G['BaseModuleInf']['BaseModules'], pkl_output)
  1443. pkl_output.close()
  1444. #----------------------------------------------
  1445. # topo/checkpoint/basemodule line range ,in frame file
  1446. def get_frame_range_inf():
  1447. fram_file_link = G["VimBufferLineFileLink"][G['Frame_Inf']['Frame_Path']]
  1448. # get topo range , default 0,0
  1449. has_topo = False
  1450. has_check_point = False
  1451. has_base_module = False
  1452. topo_range = [0, 0]
  1453. check_point_range = [0, 0]
  1454. base_module_range = [0, 0]
  1455. for i,link in enumerate(fram_file_link):
  1456. if link and (link['type'] == 'topo'):
  1457. if not has_topo:
  1458. topo_range[0] = i
  1459. has_topo = True
  1460. topo_range[1] = i
  1461. if link and (link['type'] == 'check_point'):
  1462. if not has_check_point:
  1463. check_point_range[0] = i
  1464. has_check_point = True
  1465. check_point_range[1] = i
  1466. if link and (link['type'] == 'base_module'):
  1467. if not has_base_module:
  1468. base_module_range[0] = i
  1469. has_base_module = True
  1470. base_module_range[1] = i
  1471. # if no topo ,next topo start at [0,0]
  1472. if not has_topo:
  1473. topo_range = [0, 0]
  1474. # check point initial start at topo end + 2
  1475. if not has_check_point:
  1476. check_point_range[0] = topo_range[1] + 2
  1477. check_point_range[1] = topo_range[1] + 2
  1478. # base module initial at check point end + 2
  1479. if not has_base_module:
  1480. base_module_range[0] = check_point_range[1] + 2
  1481. base_module_range[1] = check_point_range[1] + 2
  1482. return { 'topo_range' : tuple(topo_range)
  1483. ,'check_point_range' : tuple(check_point_range)
  1484. ,'base_module_range' : tuple(base_module_range)
  1485. ,'has_topo' : has_topo
  1486. ,'has_check_point' : has_check_point
  1487. ,'has_base_module' : has_base_module }
  1488. #----------------------------------------------------
  1489. def get_submodule_match_patten(all_module_name):
  1490. patten_char_set_list = []
  1491. len_2_modules = {}
  1492. for m_n in all_module_name:
  1493. l = len(m_n)
  1494. len_2_modules.setdefault(l,[])
  1495. len_2_modules[l].append(m_n)
  1496. l_pattens = []
  1497. for l in len_2_modules:
  1498. l_m = len_2_modules[l]
  1499. l_patten = '(['+ (']['.join(map(''.join, map(set,zip(*l_m))))) + '])'
  1500. l_pattens.append(l_patten)
  1501. patten = '(' + '|'.join(l_pattens) + ')'
  1502. return patten
  1503. #----------------------------------------------------
  1504. def get_single_verilog_file_module_inf(f):
  1505. all_module_start_end_lines = os.popen('egrep -n -h \'^\s*(module|endmodule)\>\' %s'%(f)).readlines()
  1506. cur_file_module_inf = []
  1507. has_module_not_end = False
  1508. i = 0
  1509. while i < len(all_module_start_end_lines):
  1510. cur_start_end_line = all_module_start_end_lines[i]
  1511. cur_start_end_line_num = int(cur_start_end_line.split(':')[0]) - 1
  1512. cur_start_end_line_code = ':'.join( cur_start_end_line.split(':')[1:] )
  1513. match_module_start = re.match('\s*module\s+(?P<name>(|`)\w+)', cur_start_end_line_code) # some module use macro as name so (|`)
  1514. if match_module_start:
  1515. module_name = match_module_start.group('name')
  1516. module_start_line_num = cur_start_end_line_num
  1517. module_pos = ( module_start_line_num, cur_start_end_line_code.find(module_name) )
  1518. # if pre module not end, set new module start pre line as pre module end line
  1519. if has_module_not_end:
  1520. PrintDebug('Error: module:"%s" in file:"%s", no "endmodule" !'%(cur_file_module_inf[-1]['module_name'],f) )
  1521. cur_file_module_inf[-1]['line_range_in_file'][1] = module_start_line_num - 1
  1522. cur_file_module_inf.append(
  1523. { 'module_name' : module_name
  1524. ,'file_path' : f
  1525. ,'line_range_in_file' : [module_start_line_num, -1]
  1526. ,'sub_modules' : None # []
  1527. ,'module_pos' : module_pos
  1528. }
  1529. )
  1530. has_module_not_end = True
  1531. i += 1
  1532. continue
  1533. match_module_end = re.match('\s*endmodule(\W|$)', cur_start_end_line_code)
  1534. if match_module_end:
  1535. if not has_module_not_end:
  1536. PrintDebug( 'Error: line: %s "endmodule" has no correlation module define ! file: %s '%(match_module_end,f) )
  1537. continue
  1538. module_end_line_num = cur_start_end_line_num
  1539. cur_file_module_inf[-1]['line_range_in_file'][1] = module_end_line_num
  1540. has_module_not_end = False
  1541. i += 1
  1542. continue
  1543. i += 1
  1544. if has_module_not_end:
  1545. PrintDebug( 'Error: module:"%s" in file:"%s", no "endmodule" !'%(cur_file_module_inf[-1]['module_name'],f) )
  1546. return cur_file_module_inf
  1547. # for current file line match all patten: `define xxx ....
  1548. # patten_result = {
  1549. # "name" : xxx
  1550. # ,"path" : f
  1551. # ,"pos" : (line_num, colum_num) # name first char pos
  1552. # ,'code_line' : `define xxx ....
  1553. # }
  1554. # finial return [ patten_result0, patten_result1 ]
  1555. def get_single_verilog_file_define_inf(f):
  1556. global_define_inf = []
  1557. global_define_lines = os.popen('egrep -n -h \'^\s*`define\W\' %s'%(f)).readlines()
  1558. for l in global_define_lines:
  1559. split0 = l.split(':')
  1560. line_num = int(split0[0]) - 1
  1561. code_line = ':'.join(split0[1:])
  1562. match_name = re.match('\s*`define\s*(?P<name>\w+)',code_line)
  1563. name = ''
  1564. colum_num = -1
  1565. if match_name:
  1566. name = match_name.group('name')
  1567. colum_num = code_line.find(name)
  1568. if colum_num != -1:
  1569. global_define_inf.append(
  1570. { "name" : name
  1571. ,"path" : f
  1572. ,"pos" : (line_num, colum_num)
  1573. ,'code_line' : code_line }
  1574. )
  1575. return global_define_inf
  1576. def get_single_line_sub_call_inf(egrep_line, all_module_names):
  1577. sp = egrep_line.split(':')
  1578. l_num = int(sp[0]) - 1
  1579. l_code = re.sub('//.*', '', ':'.join(sp[1:]))
  1580. if l_code.find(';') == -1:
  1581. return False
  1582. # match_name = re.match('\s*(?P<m_n>(|`)\w+)\s*(?P<other>.*;)\s*$',l_code)
  1583. match_name = re.match('\s*(?P<m_n>(|`)\w+)\s*(?P<other>.*;)',l_code)
  1584. assert(match_name),'%s,%s'%(egrep_line, l_code)
  1585. module_name = match_name.group('m_n')
  1586. if module_name not in all_module_names:
  1587. return False
  1588. other = match_name.group('other')
  1589. inst_name_patten = '\w+((\s*\[[^\[\]]*\])|)'
  1590. search_i_n = re.search('(^(?P<i_n0>%s))|(#.*\)\s*(?P<i_n1>%s)\s*\()'%(inst_name_patten,inst_name_patten),other)
  1591. if not search_i_n:
  1592. PrintDebug( 'Warning: match module name %s, but no inst name !' )
  1593. return False
  1594. inst_name = search_i_n.group('i_n0')
  1595. if not inst_name:
  1596. inst_name = search_i_n.group('i_n1')
  1597. assert(inst_name)
  1598. return {
  1599. 'module_name': module_name
  1600. ,'inst_name' : inst_name
  1601. ,'match_range': [l_num, l_num]
  1602. ,'match_pos' : [l_num, l_code.find(module_name)]
  1603. }
  1604. def get_mult_line_sub_call_inf(egrep_line, f_lines, all_module_names):
  1605. sp = egrep_line.split(':')
  1606. l_num = int(sp[0]) - 1
  1607. code_line = re.sub('//.*', '', ':'.join(sp[1:]))
  1608. # get module name
  1609. module_name = ''
  1610. module_pos = (-1,-1)
  1611. match_name = re.match('^\s*(?P<m_n>(|`)\w+)\s*(?P<other>.*)',code_line)
  1612. assert(match_name)
  1613. module_name = match_name.group('m_n')
  1614. if module_name not in all_module_names:
  1615. return False
  1616. module_pos = (l_num, code_line.find(module_name))
  1617. # get inst name
  1618. inst_name = ''
  1619. inst_name_patten = '\w+((\s*\[[^\[\]]*\])|)'
  1620. other = match_name.group('other')
  1621. i = l_num + 1
  1622. max_i = len(f_lines)
  1623. line_end = False
  1624. while not other and i < max_i and not line_end:
  1625. next_code_line_with_semi = re.sub('((^\s+)|(^\s*`.*)|(//.*))','',f_lines[i].strip('\n'))
  1626. next_code_line_no_semi = re.sub(';.*','',next_code_line_with_semi)
  1627. other = next_code_line_no_semi
  1628. if len(next_code_line_no_semi) != len(next_code_line_with_semi):
  1629. line_end = True
  1630. i += 1
  1631. match_inst_name_no_parm = re.match('^(?P<i_n>%s)'%(inst_name_patten),other)
  1632. if match_inst_name_no_parm:
  1633. inst_name = match_inst_name_no_parm.group('i_n')
  1634. elif other[0] != '#':
  1635. PrintDebug('Warning: un recgnize 0 module match ! %s ||| %s'%(egrep_line, other))
  1636. return False
  1637. # del has parm inst_name
  1638. search_inst_name_has_parm = re.search('#\s*\(.*\)\s*(?P<i_n>%s)\s*\('%(inst_name_patten),other)
  1639. if search_inst_name_has_parm:
  1640. inst_name = search_inst_name_has_parm.group('i_n')
  1641. while i < max_i and not line_end:
  1642. next_code_line_with_semi = re.sub('((^\s+)|(^\s*`.*)|(//.*))','',f_lines[i].strip('\n'))
  1643. next_code_line_no_semi = re.sub(';.*','',next_code_line_with_semi)
  1644. other = other +' '+next_code_line_no_semi
  1645. if len(next_code_line_no_semi) != len(next_code_line_with_semi):
  1646. line_end = True
  1647. i += 1
  1648. search_inst_name_has_parm = re.search('#\s*\(.*\)\s*(?P<i_n>%s)\s*\('%(inst_name_patten),other)
  1649. if search_inst_name_has_parm:
  1650. inst_name = search_inst_name_has_parm.group('i_n')
  1651. break
  1652. if not inst_name:
  1653. PrintDebug('Warning: un recgnize 1 module match ! %s ||| %d ||| %s '%(egrep_line, i, str(line_end) ) )
  1654. return False
  1655. # get cur call end line
  1656. end_line_num = max_i
  1657. while i < max_i and not line_end:
  1658. next_code_line = re.sub('(^`.*)|(//.*)','',f_lines[i])
  1659. if next_code_line.find(';') != -1:
  1660. line_end = True
  1661. break
  1662. i += 1
  1663. if not line_end:
  1664. PrintDebug('Warning: cur sub call no end ";" ! %s'%(egrep_line))
  1665. else:
  1666. end_line_num = i
  1667. # return result
  1668. return {
  1669. 'module_name': module_name
  1670. ,'inst_name' : inst_name
  1671. ,'match_range': [l_num, end_line_num]
  1672. ,'match_pos' : module_pos
  1673. }
  1674. def get_single_verilog_file_subcall_inf(f, patten, all_module_names):
  1675. egrep_match_lines = os.popen('egrep -n -h \'^\s*(%s)\>\' %s'%(patten,f)).readlines()
  1676. # start get sub call inf
  1677. if not egrep_match_lines:
  1678. return []
  1679. file_sub_call_infs = []
  1680. c0_cnt = 0
  1681. c1_cnt = 0
  1682. f_lines = open(f,'r').readlines()
  1683. for egrep_l in egrep_match_lines:
  1684. # case0: signal line call
  1685. c0_rst = get_single_line_sub_call_inf(egrep_l, all_module_names)
  1686. if c0_rst:
  1687. c0_cnt += 1
  1688. file_sub_call_infs.append(c0_rst)
  1689. continue
  1690. # case1: mult line call
  1691. c1_rst = get_mult_line_sub_call_inf(egrep_l, f_lines, all_module_names)
  1692. if c1_rst:
  1693. c1_cnt += 1
  1694. file_sub_call_infs.append(c1_rst)
  1695. continue
  1696. PrintDebug('subcall: one_line/mult_line = %d/%d'%( c0_cnt,c1_cnt) )
  1697. return file_sub_call_infs
  1698. def add_single_verilog_file_submodule_inf_to_module_inf( file_module_inf, file_subcall_inf ):
  1699. s_inf_i = 0
  1700. for m_inf in file_module_inf:
  1701. m_inf['sub_modules'] = []
  1702. m_inf['sub_calls'] = {}
  1703. m_range = m_inf['line_range_in_file']
  1704. while s_inf_i < len(file_subcall_inf):
  1705. s_range = file_subcall_inf[s_inf_i]['match_range']
  1706. # cur subcall in cur module
  1707. if m_range[0] <= s_range[0] and s_range[1] <= m_range[1]:
  1708. m_inf['sub_modules'].append(file_subcall_inf[s_inf_i])
  1709. m_inf['sub_calls'][file_subcall_inf[s_inf_i]['inst_name']] = file_subcall_inf[s_inf_i]
  1710. s_inf_i += 1
  1711. continue
  1712. elif s_range[0] < m_range[0]:
  1713. PrintDebug('Error: subcall %s not in valid module !'%(file_subcall_inf[s_inf_i].__str__()))
  1714. s_inf_i += 1
  1715. elif s_range[1] > m_range[1]:
  1716. if s_range[0] < m_range[0]:
  1717. PrintDebug('Error: subcall %s cross two module !'%(file_subcall_inf[s_inf_i].__str__()))
  1718. break
  1719. else:
  1720. assert(0)
  1721. return
  1722. def get_single_verilog_file_code_inf(f):
  1723. # gen cur module and define inf
  1724. new_file_module_inf = get_single_verilog_file_module_inf(f)
  1725. new_file_define_inf = get_single_verilog_file_define_inf(f)
  1726. # gen new all_module_names, del old current file add new
  1727. new_module_names = set([ mi['module_name'] for mi in new_file_module_inf ])
  1728. old_file_module_inf = G['FileInf'][f]['module_infs']
  1729. old_module_names = set([ mi['module_name'] for mi in old_file_module_inf ])
  1730. all_module_name = ( set(G['ModuleInf']) - old_module_names ) | new_module_names
  1731. # get file sub call inf
  1732. patten = get_submodule_match_patten(all_module_name)
  1733. new_file_subcall_inf = get_single_verilog_file_subcall_inf(f, patten, all_module_name)
  1734. # merge to file_inf
  1735. add_single_verilog_file_submodule_inf_to_module_inf( new_file_module_inf, new_file_subcall_inf )
  1736. new_file_inf = {
  1737. 'glb_defines' : new_file_define_inf
  1738. ,'module_infs' : new_file_module_inf
  1739. ,'module_calls' : new_file_subcall_inf
  1740. ,'file_edit_inf' : { 'create_time': os.path.getctime(f), 'last_modify_time': os.path.getmtime(f)}
  1741. }
  1742. return new_file_inf
  1743. def show_progress_bar( i, i_max, show_char = '#', show_width = 20):
  1744. i += 1 # count from 1
  1745. i_max_len = len(str(i_max))
  1746. i_len = len(str(i))
  1747. i_str = ' '*(i_max_len-i_len)+str(i)
  1748. i_max_str = str(i_max)
  1749. prefix = '%s/%s: '%(i_str,i_max_str)
  1750. pass_str = show_char*((i*show_width)/i_max)
  1751. empty_str = ' '*(show_width - len(pass_str))
  1752. progress_bar = '[%s%s]'%(pass_str,empty_str)
  1753. tool_len = len(prefix) + show_width
  1754. sys.stdout.write(' '*tool_len + '\r')
  1755. sys.stdout.flush()
  1756. sys.stdout.write(prefix + progress_bar)
  1757. """
  1758. https://my.oschina.net/u/2520885
  1759. """
  1760. #===============================================================================
  1761. # Copyright (C) 2016 by Jun Cao
  1762. # Permission is hereby granted, free of charge, to any person obtaining a copy
  1763. # of this software and associated documentation files (the "Software"), to deal
  1764. # in the Software without restriction, including without limitation the rights
  1765. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  1766. # copies of the Software, and to permit persons to whom the Software is
  1767. # furnished to do so, subject to the following conditions:
  1768. # The above copyright notice and this permission notice shall be included in
  1769. # all copies or substantial portions of the Software.
  1770. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  1771. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1772. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  1773. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  1774. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  1775. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  1776. # THE SOFTWARE.
  1777. #===============================================================================
  1778. import sys
  1779. import re
  1780. import os
  1781. try:
  1782. import vim
  1783. except:
  1784. pass
  1785. import GLB
  1786. G = GLB.G
  1787. from Base import*
  1788. import View
  1789. PrintReport = View.PrintReport
  1790. ########################################################
  1791. def get_sub_io_signal_name_from_sub_call_line(call_line, y):
  1792. word = get_full_word(call_line, y)
  1793. # if | .xxx(xxxx)
  1794. # y | ^
  1795. # | ^ ^ // call_sub_assign_signal_str
  1796. # cur_word is sub_io_signal_name
  1797. if re.match('\w+\.', call_line[:y+1][::-1]):
  1798. call_sub_assign_signal_str = re.sub('(^\w*)|(\.\w+\(.*)', '', call_line[y:])
  1799. call_sub_signals = set( re.findall('\w+',call_sub_assign_signal_str) )
  1800. sub_call_io = word
  1801. return { 'call_sub_signals': call_sub_signals
  1802. ,'sub_call_io' : word
  1803. ,'sub_call_io_num' : None }
  1804. # if | .xxx(xxxx)
  1805. # y | ^
  1806. # | ^ ^ // call_sub_assign_signal_str
  1807. s0 = re.search('\(\s*(?P<sub_call_io>\w+)\.',call_line[:y+1][::-1])
  1808. if s0:
  1809. sub_call_io = s0.group('sub_call_io')[::-1]
  1810. call_sub_assign_and_right = call_line[y-s0.span()[0]:]
  1811. assert(call_sub_assign_and_right[0] == '(')
  1812. call_sub_assign_signal_str = re.sub('\.\w+\s*\(.*', '', call_line[y:])
  1813. call_sub_signals = set( re.findall('\w+',call_sub_assign_signal_str) )
  1814. return { 'call_sub_signals': call_sub_signals
  1815. ,'sub_call_io' : sub_call_io
  1816. ,'sub_call_io_num' : None }
  1817. # if module_name #(parm) inst_name( a, b, c)
  1818. # if module_name inst_name( a, b, c)
  1819. # y
  1820. # call_sub_signals set(b)
  1821. # sub_call_io_num 1
  1822. # sub_call_io ''
  1823. if word:
  1824. s1 = re.search('\)\s*\w+\s*\(',call_line[:y+1])
  1825. if not s1:
  1826. s1 = re.match('\s*\w+\s*\w+\s*\(',call_line[:y+1])
  1827. full_match_s1 = True
  1828. if s1:
  1829. pre_sub_call_signal_str = call_line[s1.span()[1]:y+1]
  1830. pre_sub_call_signals = pre_sub_call_signal_str.split(',')
  1831. assert(pre_sub_call_signals)
  1832. for sc in pre_sub_call_signals:
  1833. if not re.match('\s*(\w+)|(\w+\s*\[[^\[\]]+\])\s*$',sc):
  1834. full_match_s1 = False
  1835. if full_match_s1:
  1836. return { 'call_sub_signals': set([word])
  1837. ,'sub_call_io' : ''
  1838. ,'sub_call_io_num' : len(pre_sub_call_signals) - 1 }
  1839. return None
  1840. # if has io_name return cur io inf
  1841. # else return all io inf of current module
  1842. #io_inf =
  1843. # "name" : name
  1844. # , "io_type" : io_type
  1845. # , "left" : left_index
  1846. # , "right" : right_index
  1847. # , "size" : size
  1848. # , 'line_num' : line_num
  1849. # , 'name_pos' : (line_num, colm_num)
  1850. # , 'code_line' : code_line
  1851. # , 'signal_type' : signal_type }
  1852. def get_io_inf(module_name, io_name = ''):
  1853. module_inf = get_module_inf(module_name)
  1854. if not module_inf:
  1855. return False
  1856. module_path = module_inf['file_path']
  1857. module_range = module_inf['line_range_in_file']
  1858. if io_name: # get cur io inf
  1859. io_inf = {}
  1860. io_lines = os.popen('sed -n \'%d,%dp\' %s | egrep -n -h \'^\s*(input|output)\>.*\<%s\>\''%(module_range[0]+1, module_range[1]+1, module_path, io_name)).readlines()
  1861. if len(io_lines) == 0:
  1862. PrintDebug('Error: module: %s \'s io: %s define not found !'%(module_name,io_name))
  1863. return False
  1864. if len(io_lines) > 1:
  1865. l_i = 0
  1866. while l_i < len(io_lines):
  1867. if not re.search('\W%s(\W|)'%(io_name), re.sub('//.*','',io_lines[l_i])):
  1868. del io_lines[l_i]
  1869. continue
  1870. l_i += 1
  1871. continue
  1872. if len(io_lines) > 1:
  1873. PrintDebug('Error: module: %s \'s io: %s define multiple times !'%(module_name,io_name))
  1874. line = io_lines[0]
  1875. assert(line.find(io_name) != -1)
  1876. io_inf = decode_egreped_verilog_io_line(line)['io_infs']
  1877. if io_name in io_inf:
  1878. # because use "sed ... | grep ..." so the line number is not the real number need add sed started line num
  1879. io_inf[io_name]['line_num'] = io_inf[io_name]['line_num'] + module_range[0]
  1880. io_inf[io_name]['name_pos'] = ( io_inf[io_name]['line_num'], io_inf[io_name]['name_pos'][1] )
  1881. return io_inf[io_name]
  1882. else:
  1883. PrintDebug('Warning: get_io_inf, io_name is parm name ,not a io !')
  1884. return False
  1885. else: # get module all io inf
  1886. all_io_inf = []
  1887. cur_module_code_range = module_inf['line_range_in_file']
  1888. all_io_lines = os.popen('sed -n \'%d,%dp\' %s | egrep -n -h \'^\s*(input|output)\>\''%(cur_module_code_range[0]+1, cur_module_code_range[1]+1, module_path)).readlines()
  1889. for line in all_io_lines:
  1890. line = line.rstrip('\n')
  1891. egrep_io_infs = decode_egreped_verilog_io_line(line)
  1892. io_inf = egrep_io_infs['io_infs']
  1893. name_list = egrep_io_infs['name_list']
  1894. if not io_inf:
  1895. PrintDebug('Error: module: %s, line: %s, can not decode by decode_egreped_verilog_io_line() ! file: %s'(module_name, line, module_path))
  1896. continue
  1897. for io_name in name_list:
  1898. assert(io_name in io_inf)
  1899. c_io_inf = io_inf[io_name]
  1900. c_io_inf['line_num'] = c_io_inf['line_num'] + cur_module_code_range[0]
  1901. c_io_inf['name_pos'] = (c_io_inf['line_num'], c_io_inf['name_pos'][1])
  1902. all_io_inf.append( c_io_inf )
  1903. return all_io_inf
  1904. def get_module_call_sub_module_io_inf(call_line, io_pos, call_file_path):
  1905. call_line_num = io_pos[0]
  1906. # if database has no this file return
  1907. if call_file_path not in G['FileInf']:
  1908. PrintDebug("Warning: get_module_call_sub_module_io_inf : cur file has not in hdltags database, file: %s !"%(call_file_path))
  1909. return False
  1910. file_line_inf = get_file_line_inf(call_line_num, call_file_path)
  1911. line_call_sub_inf = {}
  1912. line_module_inf = {}
  1913. if file_line_inf:
  1914. line_call_sub_inf = file_line_inf['line_call_sub_inf']
  1915. line_module_inf = file_line_inf['line_module_inf']
  1916. # if cursor line not no sub call , return
  1917. if not line_call_sub_inf:
  1918. PrintDebug("Warning: get_module_call_sub_module_io_inf: cur line %d not on sub call ! "%(call_line_num))
  1919. return False
  1920. sub_call_signal_inf = get_sub_io_signal_name_from_sub_call_line(call_line, io_pos[1]) # may be parm
  1921. # call module name
  1922. assert(line_module_inf),'is in sub call, must be valid mudule'
  1923. call_module_name = line_module_inf['module_name']
  1924. # valid cursor on sub call
  1925. sub_module_name = line_call_sub_inf['module_name']
  1926. sub_module_path = ''
  1927. sub_module_inf = get_module_inf(sub_module_name)
  1928. if sub_module_inf:
  1929. sub_module_path = sub_module_inf['file_path']
  1930. # sub_match_pos means cursor call io signal in sub module io pos
  1931. sub_io_inf = {}
  1932. call_sub_signals = set()
  1933. if sub_call_signal_inf:
  1934. call_sub_signals = sub_call_signal_inf['call_sub_signals']
  1935. sub_call_io = sub_call_signal_inf['sub_call_io']
  1936. sub_call_io_num = sub_call_signal_inf['sub_call_io_num']
  1937. if sub_call_io:
  1938. sub_io_inf = get_io_inf(sub_module_name, sub_call_io)
  1939. elif sub_call_io_num != None:
  1940. all_io_inf = get_io_inf(sub_module_name)
  1941. assert(sub_call_io_num < len(all_io_inf))
  1942. sub_io_inf = all_io_inf[sub_call_io_num]
  1943. sub_match_pos = ()
  1944. sub_io_type = ''
  1945. sub_io_line = ''
  1946. sub_io_name = ''
  1947. if sub_io_inf:
  1948. sub_io_name = sub_io_inf['name']
  1949. sub_match_pos = sub_io_inf['name_pos']
  1950. sub_io_type = sub_io_inf['io_type']
  1951. sub_io_line = sub_io_inf['code_line']
  1952. return {
  1953. 'sub_io_name' : sub_io_name
  1954. ,'sub_module_name' : sub_module_name
  1955. ,'sub_module_path' : sub_module_path
  1956. ,'sub_match_pos' : sub_match_pos
  1957. ,'sub_io_type' : sub_io_type
  1958. ,'sub_io_line' : sub_io_line
  1959. ,'sub_io_inf' : sub_io_inf
  1960. ,'call_sub_signals' : call_sub_signals
  1961. ,'call_sub_inf' : line_call_sub_inf
  1962. ,'call_module_name' : call_module_name }
  1963. #########################function for trace##############################
  1964. # ok
  1965. def get_upper_module_call_io_inf(cur_module_name , cur_io_name):
  1966. cur_module_last_call_inf = get_module_last_call_inf(cur_module_name)
  1967. if not cur_module_last_call_inf:
  1968. PrintDebug("Warning: get_upper_module_call_io_inf: module %s, not called before, no upper module !"%(cur_module_name))
  1969. return False
  1970. upper_module_name = cur_module_last_call_inf['upper_module_name']
  1971. upper_call_inf = cur_module_last_call_inf['upper_call_inf']
  1972. upper_module_inf = get_module_inf(upper_module_name)
  1973. assert(upper_module_inf),'upper module %s call %s before, upper should has inf in database !'%(upper_module_name, cur_module_name)
  1974. upper_module_path = upper_module_inf['file_path']
  1975. # get upper call, match this signal pos
  1976. upper_call_lines = open(upper_module_path,'r').readlines()
  1977. upper_call_pos = upper_call_inf['match_pos'] # initial to call inst line
  1978. upper_matched = False
  1979. for i in range( upper_call_inf['match_range'][0] , upper_call_inf['match_range'][1] + 1 ):
  1980. f0 = upper_call_lines[i].find(cur_io_name)
  1981. if f0 == -1:
  1982. continue
  1983. s0 = re.search('(?P<pre>^|\W)%s(\W|$)'%(cur_io_name) , re.sub('//.*','',upper_call_lines[i]))
  1984. if s0:
  1985. colum_num = s0.span()[0] + len(s0.group('pre'))
  1986. upper_call_pos = (i, colum_num)
  1987. upper_matched = True
  1988. break
  1989. assert(upper_matched),'upper called so should be match, cur_io_name:%s, %s '%(upper_call_inf['match_range'].__str__(), cur_io_name)
  1990. upper_call_line = upper_call_lines[upper_call_pos[0]]
  1991. return {
  1992. 'module_name' : upper_module_name
  1993. ,'call_pos' : upper_call_pos
  1994. ,'call_line' : upper_call_line
  1995. ,'module_path' : upper_module_path
  1996. }
  1997. def get_cur_appear_is_source_or_dest(key, code_lines, appear_pos):
  1998. a_x, a_y = appear_pos
  1999. appear_code_line = re.sub('(//.*)|(^\s*`.*)', '', code_lines[a_x] )
  2000. # case 0 cur pos in note return not source and dest
  2001. if len(appear_code_line) - 1 < a_y:
  2002. return 'None'
  2003. # case 1 is io
  2004. if (appear_code_line.find('input') != -1) or (appear_code_line.find('output') != -1):
  2005. match_io_type = re.match('\s*(?P<io_type>(input|output))\W',appear_code_line) # may input a,b,c
  2006. match_io_name = re.match('\s*[;,]?\s*(?P<r_names>\w+(\s*,\s*\w+)*)',appear_code_line[::-1]) # may input a,b,c
  2007. if match_io_type and match_io_name:
  2008. io_type = match_io_type.group('io_type')
  2009. io_names = match_io_name.group('r_names')[::-1]
  2010. io_names = set(re.split('\s*,\s*',io_names))
  2011. if (io_type == 'input') and (key in io_names):
  2012. return 'Source'
  2013. if (io_type == 'output') and (key in io_names):
  2014. return 'Dest'
  2015. elif match_io_type:
  2016. PrintDebug('Error: recgnize_signal_assign_line: unrecgnize io line: '+appear_code_line)
  2017. return 'None'
  2018. # case 2 cur pos in case/casez/for/if (...key...) then it's dest
  2019. match_case2 = False
  2020. c2 = re.search( '(^|\W)(case|casez|for|if|while)\s*\(' , appear_code_line)
  2021. if c2:
  2022. appear_code_right_line = appear_code_line[c2.span()[1]:]
  2023. unmatch_bracket_count = 1
  2024. end_match_patten = '^'
  2025. end_y = len(appear_code_right_line) - 1
  2026. all_brackets = re.findall('\(|\)', appear_code_right_line)
  2027. for b in all_brackets:
  2028. if b == '(':
  2029. unmatch_bracket_count += 1
  2030. else:
  2031. unmatch_bracket_count -= 1
  2032. end_match_patten = end_match_patten + '[^()]*\\'+b
  2033. if unmatch_bracket_count == 0:
  2034. end_y = re.search(end_match_patten, appear_code_right_line).span()[1] - 1
  2035. break
  2036. end_y = c2.span()[1] + end_y
  2037. if end_y >= a_y:
  2038. return 'Dest'
  2039. else:
  2040. # if key not in (...), then use ) right str as real appear_code_line
  2041. match_case2 = True
  2042. appear_code_line = appear_code_line[end_y + 1:]
  2043. # case 3 cur line has = at left or right
  2044. assign_patten = '([^=>!]=[^=<>])'
  2045. # ... =|<= ... key : is dest
  2046. if re.search(assign_patten, appear_code_line[:a_y + 1]):
  2047. return 'Dest'
  2048. # key ... =|<= ... : is source
  2049. if re.search(assign_patten, appear_code_line[a_y:]):
  2050. return 'Source'
  2051. # case 4 if not match case2(if match no pre line) post full line sep by ";" has =|<=, it's dest
  2052. if not match_case2:
  2053. pre_full_line = get_verilog_pre_full_line(code_lines, appear_pos)
  2054. if re.search(assign_patten, pre_full_line):
  2055. return 'Dest'
  2056. # case 5 post full line sep by ";" has =|<=, it's source
  2057. post_full_line = get_verilog_post_full_line(code_lines, appear_pos)
  2058. if re.search(assign_patten, post_full_line[:a_y + 1]):
  2059. return 'Source'
  2060. # case 6 unrecgnize treat as maybe dest/source
  2061. return 'Maybe'
  2062. # ok
  2063. def clear_last_trace_inf( trace_type ):
  2064. if trace_type in ['source','both']:
  2065. G['TraceInf']['LastTraceSource']['Maybe'] = []
  2066. G['TraceInf']['LastTraceSource']['Sure'] = []
  2067. G['TraceInf']['LastTraceSource']['ShowIndex'] = 0
  2068. G['TraceInf']['LastTraceSource']['SignalName'] = ''
  2069. G['TraceInf']['LastTraceSource']['Path'] = ''
  2070. if trace_type in ['dest','both']:
  2071. G['TraceInf']['LastTraceDest']['Maybe'] = []
  2072. G['TraceInf']['LastTraceDest']['Sure'] = []
  2073. G['TraceInf']['LastTraceDest']['ShowIndex'] = 0
  2074. G['TraceInf']['LastTraceDest']['SignalName'] = ''
  2075. G['TraceInf']['LastTraceDest']['Path'] = ''
  2076. # #-------------------trace_io_signal---------------------------
  2077. # del get_cur_module_inf
  2078. def real_trace_io_signal(trace_type, cursor_inf, io_signal_inf):
  2079. assert(trace_type in ['dest', 'source']),'only trace dest/source'
  2080. # verilog
  2081. if (trace_type is 'dest') and (io_signal_inf['io_type'] != 'output'):
  2082. PrintDebug('Warning: real_trace_io_signal: not output signal, not dest')
  2083. return False # not output signal, not dest
  2084. if (trace_type is 'source') and (io_signal_inf['io_type'] != 'input'):
  2085. PrintDebug('Warning: real_trace_io_signal: not input signal, not source')
  2086. return False # not input signal, not source
  2087. # trace a input signal
  2088. clear_last_trace_inf( trace_type ) # clear pre trace dest/source result
  2089. cur_module_inf = cursor_inf['cur_module_inf']
  2090. if not cur_module_inf:
  2091. PrintDebug('Warning: cur file not in database, will not go upper ! file: %s'(cursor_inf['file_path']))
  2092. return True
  2093. cur_module_name = cur_module_inf['module_name']
  2094. upper_module_call_inf = get_upper_module_call_io_inf(cur_module_name , io_signal_inf['name'])
  2095. if not upper_module_call_inf:
  2096. PrintReport('Warning: no upper module call this module before !')
  2097. return True # this dest/source but not found upper module
  2098. # has upper module go to upper module call location
  2099. upper_module_name = upper_module_call_inf['module_name']
  2100. upper_call_pos = upper_module_call_inf['call_pos']
  2101. upper_call_line = upper_module_call_inf['call_line']
  2102. upper_module_path = upper_module_call_inf['module_path']
  2103. show_str = '%s %d : %s'%(upper_module_name, upper_call_pos[0]+1, upper_call_line)
  2104. file_link = {'key':io_signal_inf['name'], 'pos': upper_call_pos, 'path': upper_module_path}
  2105. trace_result = {'show': show_str, 'file_link': file_link}
  2106. if trace_type is 'dest':
  2107. G['TraceInf']['LastTraceDest']['Sure'].append(trace_result)
  2108. G['TraceInf']['LastTraceDest']['SignalName'] = cursor_inf['word']
  2109. G['TraceInf']['LastTraceDest']['Path'] = cursor_inf['file_path']
  2110. else :
  2111. G['TraceInf']['LastTraceSource']['Sure'].append(trace_result)
  2112. G['TraceInf']['LastTraceSource']['SignalName'] = cursor_inf['word']
  2113. G['TraceInf']['LastTraceSource']['Path'] = cursor_inf['file_path']
  2114. # show dest/source to report win, and go first trace
  2115. PrintReport(spec_case = trace_type)
  2116. View.show_next_trace_result(trace_type)
  2117. return True
  2118. # ok
  2119. def trace_io_signal(trace_type, cursor_inf):
  2120. trace_signal_name = cursor_inf['word']
  2121. io_signal_infs = recgnize_io_signal_line(cursor_inf['line'], cursor_inf['line_num'])
  2122. if not io_signal_infs:
  2123. PrintDebug('Warning: trace_io_signal: not io signal')
  2124. return False # not io signal
  2125. # if trace_signal_name != io_signal_inf['name']:
  2126. if trace_signal_name not in io_signal_infs:
  2127. PrintDebug('Warning: trace_io_signal: is io signal but not traced signal')
  2128. return False # is io signal but not traced signal
  2129. if trace_type in ['source','dest']:
  2130. return real_trace_io_signal(trace_type, cursor_inf, io_signal_infs[trace_signal_name])
  2131. assert(0),'unkonw tarce type %s' %(trace_type)
  2132. #-------------------------------------------------------------
  2133. # ok
  2134. def real_trace_module_call_io_signal(trace_type, sub_call_inf, cursor_inf):
  2135. assert(trace_type in ['source', 'dest'])
  2136. if trace_type == 'source' and sub_call_inf['sub_io_type'] != 'output':
  2137. return False # submodule not source, just pass
  2138. elif trace_type == 'dest' and sub_call_inf['sub_io_type'] != 'input':
  2139. return False # submodule not source, just pass
  2140. # has sub module and in submodule signal is out, then it's source
  2141. sub_module_name = sub_call_inf['sub_module_name']
  2142. sub_module_path = sub_call_inf['sub_module_path']
  2143. sub_module_match_pos = sub_call_inf['sub_match_pos']
  2144. sub_module_match_line = sub_call_inf['sub_io_line']
  2145. sub_module_signal_name = sub_call_inf['sub_io_name']
  2146. show_str = '%s %d : %s'%(sub_module_name, sub_module_match_pos[0]+1, sub_module_match_line)
  2147. file_link = {'key':sub_module_signal_name, 'pos': sub_module_match_pos, 'path': sub_module_path}
  2148. trace_result = {'show': show_str, 'file_link': file_link}
  2149. if trace_type == 'source':
  2150. G['TraceInf']['LastTraceSource']['Sure'].append(trace_result)
  2151. G['TraceInf']['LastTraceSource']['SignalName'] = cursor_inf['word']
  2152. G['TraceInf']['LastTraceSource']['Path'] = cursor_inf['file_path']
  2153. else: # dest
  2154. G['TraceInf']['LastTraceDest']['Sure'].append(trace_result)
  2155. G['TraceInf']['LastTraceDest']['SignalName'] = cursor_inf['word']
  2156. G['TraceInf']['LastTraceDest']['Path'] = cursor_inf['file_path']
  2157. # go to sub module code now, so cur module is the sub module last call
  2158. cur_module_name = sub_call_inf['call_module_name']
  2159. call_sub_inf = sub_call_inf['call_sub_inf']
  2160. set_module_last_call_inf(sub_module_name, cur_module_name, call_sub_inf['inst_name'])
  2161. # show source to report win, and go first trace
  2162. PrintReport(spec_case = trace_type)
  2163. View.show_next_trace_result(trace_type)
  2164. return True
  2165. # ok
  2166. # del is_module_call_range
  2167. def trace_module_call_io_signal(trace_type, cursor_inf):
  2168. sub_call_inf = get_module_call_sub_module_io_inf(cursor_inf['line'], cursor_inf['pos'], cursor_inf['file_path'])
  2169. if not sub_call_inf:
  2170. PrintDebug('Warning: trace_module_call_io_signal: not in module call io')
  2171. return False # not in module call io
  2172. if sub_call_inf['sub_module_name'] == cursor_inf['word']:
  2173. PrintReport('Warning: trace key is a submodule call, module name , no source !')
  2174. return True
  2175. if not sub_call_inf['sub_io_name']:
  2176. PrintDebug('Warning: trace_module_call_io_signal: is module call ,but unrecgnize io name !')
  2177. return False
  2178. clear_last_trace_inf( trace_type )
  2179. return real_trace_module_call_io_signal(trace_type, sub_call_inf, cursor_inf)
  2180. # #---------------------------------------------------------------------
  2181. def real_trace_normal_signal(trace_type, signal_appear_pos_line, cursor_inf):
  2182. assert(trace_type in ['source', 'dest'])
  2183. clear_last_trace_inf(trace_type)
  2184. if trace_type == 'source':
  2185. G['TraceInf']['LastTraceSource']['SignalName'] = cursor_inf['word']
  2186. G['TraceInf']['LastTraceSource']['Path'] = cursor_inf['file_path']
  2187. else:
  2188. G['TraceInf']['LastTraceDest']['SignalName'] = cursor_inf['word']
  2189. G['TraceInf']['LastTraceDest']['Path'] = cursor_inf['file_path']
  2190. trace_signal_name = cursor_inf['word']
  2191. cur_module_inf = cursor_inf['cur_module_inf'] # already qualify
  2192. cur_module_name = cur_module_inf['module_name']
  2193. cur_module_path = cur_module_inf['file_path']
  2194. # add optimizing for signal such like clk, used by many times, but only io, or sub call is source
  2195. input_is_only_source = False
  2196. if trace_type == 'source' and len(signal_appear_pos_line) > G['TraceInf']['TraceSourceOptimizingThreshold']:
  2197. for appear_pos, appear_line in signal_appear_pos_line:
  2198. signal_appear_line = cursor_inf['codes'][appear_pos[0]]
  2199. if signal_appear_line.find('input') == -1:
  2200. continue
  2201. dest_or_source = get_cur_appear_is_source_or_dest(trace_signal_name, [signal_appear_line], (0,appear_pos[1]) )
  2202. if dest_or_source != source:
  2203. continue
  2204. input_is_only_source = True
  2205. show_str = '%s %d : %s'%(cur_module_name, appear_pos[0]+1, appear_line)
  2206. file_link = {'key':trace_signal_name, 'pos': appear_pos, 'path': cur_module_path}
  2207. trace_result = {'show': show_str, 'file_link': file_link}
  2208. G['TraceInf']['LastTraceSource']['Sure'].append(trace_result)
  2209. break
  2210. # if found a input as source, should be the only source, clear appear pos to jump, normal search
  2211. if input_is_only_source:
  2212. signal_appear_pos_line = []
  2213. # appear_pos (line number, column), deal each match to find source
  2214. for appear_pos, appear_line in signal_appear_pos_line:
  2215. appear_dest_or_source = False
  2216. appear_is_dest = False
  2217. appear_is_source = False
  2218. # module call assign range
  2219. sub_call_inf = get_module_call_sub_module_io_inf(appear_line, appear_pos, cur_module_path)
  2220. if sub_call_inf:
  2221. if trace_signal_name in sub_call_inf['call_sub_signals']:
  2222. # cur is subcall but not io name not match trace name go next
  2223. if not sub_call_inf['sub_io_type']:
  2224. appear_dest_or_source = True
  2225. elif sub_call_inf['sub_io_type'] == 'output':
  2226. appear_is_source = True
  2227. elif sub_call_inf['sub_io_type'] == 'input':
  2228. appear_is_dest = True
  2229. else:
  2230. PrintDebug('Warning: subcall match on sub io name, not on assign name ! %s,%s'%(appear_pos.__str__(), appear_line))
  2231. continue
  2232. else:
  2233. # not module call then check if a assign signal
  2234. dest_or_source = get_cur_appear_is_source_or_dest(trace_signal_name, cursor_inf['codes'], appear_pos)
  2235. if dest_or_source == 'Dest':
  2236. appear_is_dest = True
  2237. elif dest_or_source == 'Source':
  2238. appear_is_source = True
  2239. elif dest_or_source == 'Maybe':
  2240. appear_dest_or_source = True
  2241. else:
  2242. PrintDebug('Warning: match not source or dest ! %s : %s'%(appear_pos.__str__(), appear_line))
  2243. # finial add to source/dest
  2244. show_str = '%s %d : %s'%(cur_module_name, appear_pos[0]+1, appear_line)
  2245. file_link = {'key':trace_signal_name, 'pos': appear_pos, 'path': cur_module_path}
  2246. trace_result = {'show': show_str, 'file_link': file_link}
  2247. if trace_type == 'source':
  2248. if appear_dest_or_source:
  2249. G['TraceInf']['LastTraceSource']['Maybe'].append(trace_result)
  2250. elif appear_is_source:
  2251. G['TraceInf']['LastTraceSource']['Sure'].append(trace_result)
  2252. else: # trace dest
  2253. if appear_dest_or_source:
  2254. G['TraceInf']['LastTraceDest']['Maybe'].append(trace_result)
  2255. elif appear_is_dest:
  2256. G['TraceInf']['LastTraceDest']['Sure'].append(trace_result)
  2257. continue
  2258. # finish get all dest/source
  2259. if trace_type == 'source':
  2260. finded_source_num = len(G['TraceInf']['LastTraceSource']['Sure'])
  2261. finded_maybe_source_num = len(G['TraceInf']['LastTraceSource']['Maybe'])
  2262. # not find signal source
  2263. if not (finded_source_num + finded_maybe_source_num):
  2264. PrintReport("Warning: Not find signal source !")
  2265. return True
  2266. else: # dest
  2267. finded_dest_num = len(G['TraceInf']['LastTraceDest']['Sure'])
  2268. finded_maybe_dest_num = len(G['TraceInf']['LastTraceDest']['Maybe'])
  2269. # not find signal dest
  2270. if not (finded_dest_num + finded_maybe_dest_num):
  2271. PrintReport("Warning: Not find signal dest !")
  2272. return True
  2273. # show source to report win, and go first trace
  2274. PrintReport(spec_case = trace_type)
  2275. View.show_next_trace_result(trace_type)
  2276. return True
  2277. def trace_normal_signal(trace_type, cursor_inf):
  2278. cur_module_inf = cursor_inf['cur_module_inf']
  2279. if not cur_module_inf:
  2280. PrintDebug('Warning: cur file has no module inf, may be no database or cur line not in module, file: %s '%(cursor_inf['file_path']))
  2281. return False
  2282. # just use grep get all signal appear in current file to speed up signal search
  2283. signal_appear_pos_line = search_verilog_code_use_grep( cursor_inf['word'], cursor_inf['file_path'], cur_module_inf['line_range_in_file'] )
  2284. return real_trace_normal_signal(trace_type, signal_appear_pos_line, cursor_inf)
  2285. #----------------------------------------------------
  2286. def trace_glb_define_signal(trace_type, cursor_inf):
  2287. assert(trace_type in ['dest', 'source'])
  2288. cur_line = cursor_inf['line']
  2289. cur_word = cursor_inf['word']
  2290. if cur_line.find('`') == -1:
  2291. return False
  2292. s0 = re.search('(?P<prefix>^|\W)%s(\W|$)'%(cur_word),cur_line)
  2293. if not s0:
  2294. return False
  2295. if s0.group('prefix') != '`':
  2296. return False
  2297. if cur_word not in G['CodeDefineInf']:
  2298. PrintReport('Warning: cur macro: \"%s\", not has find in database !'%(cur_word))
  2299. return True
  2300. cur_define_infs = G['CodeDefineInf'][cur_word]
  2301. clear_last_trace_inf(trace_type)
  2302. for inf in cur_define_infs: # {name path pos code_line}
  2303. file_name = re.sub('.*/','',inf['path'])
  2304. show_str = '%s %d : %s'%(file_name, inf['pos'][0]+1, inf['code_line'])
  2305. file_link = {'key':cur_word, 'pos': inf['pos'], 'path': inf['path']}
  2306. trace_result = {'show': show_str, 'file_link': file_link}
  2307. if trace_type == 'source':
  2308. G['TraceInf']['LastTraceSource']['SignalName'] = cursor_inf['word']
  2309. G['TraceInf']['LastTraceSource']['Path'] = cursor_inf['file_path']
  2310. G['TraceInf']['LastTraceSource']['Sure'].append(trace_result)
  2311. else: # dest
  2312. PrintReport('Warning: cur not support trace macro dest !')
  2313. return True
  2314. # show source to report win, and go first trace
  2315. PrintReport(spec_case = trace_type)
  2316. View.show_next_trace_result(trace_type)
  2317. return True
  2318. """
  2319. https://my.oschina.net/u/2520885
  2320. """
  2321. #===============================================================================
  2322. # Copyright (C) 2016 by Jun Cao
  2323. # Permission is hereby granted, free of charge, to any person obtaining a copy
  2324. # of this software and associated documentation files (the "Software"), to deal
  2325. # in the Software without restriction, including without limitation the rights
  2326. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  2327. # copies of the Software, and to permit persons to whom the Software is
  2328. # furnished to do so, subject to the following conditions:
  2329. # The above copyright notice and this permission notice shall be included in
  2330. # all copies or substantial portions of the Software.
  2331. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2332. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2333. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2334. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2335. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  2336. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  2337. # THE SOFTWARE.
  2338. #===============================================================================
  2339. import sys
  2340. sys.path.append('../')
  2341. import vim_glb_config as glb_config
  2342. import os
  2343. import re
  2344. import pickle
  2345. vim_start_open_file = ''
  2346. try:
  2347. import vim
  2348. vim_start_open_file = vim.current.buffer.name
  2349. except:
  2350. vim_start_open_file = '|vim_not_open|'
  2351. pass
  2352. # cur call path
  2353. cur_path = os.getcwd()
  2354. # find most resent vtags path
  2355. hdl_tags_path = ''
  2356. while cur_path and cur_path[0] == '/':
  2357. if os.path.isdir(cur_path + '/vtags.db'):
  2358. hdl_tags_path = cur_path + '/vtags.db'
  2359. break
  2360. cur_path = re.sub('/[^/]*$','',cur_path)
  2361. # get local config
  2362. config = glb_config
  2363. try:
  2364. if hdl_tags_path:
  2365. sys.path.append(hdl_tags_path)
  2366. import vim_local_config as local_config
  2367. config = local_config
  2368. except:
  2369. pass
  2370. # get next empty frame, report,log report index, first try del Frame, Report
  2371. def del_old_logs():
  2372. ls_a_f = [ f.strip('\n') for f in os.popen('ls -a ' + hdl_tags_path).readlines() ]
  2373. used_log_index = set()
  2374. for f in ls_a_f:
  2375. match_swp = re.match('\.(Frame\.HF|Report\.HF|run\.log)(?P<idx>\d+)\.swp',f)
  2376. if match_swp:
  2377. used_log_index.add(int(match_swp.group('idx')))
  2378. ls_f = [ f.strip('\n') for f in os.popen('ls ' + hdl_tags_path).readlines() ]
  2379. for f in ls_f:
  2380. match_idx = re.match('(Frame\.HF|Report\.HF|run\.log)(?P<idx>\d+)', f)
  2381. if not match_idx:
  2382. continue
  2383. cur_index = int(match_idx.group('idx'))
  2384. if cur_index in used_log_index:
  2385. continue
  2386. os.system('rm %s/%s'%(hdl_tags_path,f) )
  2387. return
  2388. empty_log_index = 0
  2389. if hdl_tags_path:
  2390. del_old_logs()
  2391. while os.path.isfile(hdl_tags_path + '/run.log' + str(empty_log_index)) or \
  2392. os.path.isfile(hdl_tags_path + '/Frame.HF' + str(empty_log_index)) or \
  2393. os.path.isfile(hdl_tags_path + '/Report.HF' + str(empty_log_index)):
  2394. empty_log_index += 1
  2395. # if in generate vtags situation, print log to vtags.db/vtags_run.log
  2396. vtags_run_log_path = ['']
  2397. # run log path
  2398. run_log_path = hdl_tags_path + '/run.log'+str(empty_log_index)
  2399. def PrintDebug( str, out_path = ''):
  2400. if vtags_run_log_path[0]:
  2401. output = open( vtags_run_log_path[0], 'a')
  2402. output.write(str+'\n')
  2403. output.close()
  2404. return
  2405. if not config.debug_mode:
  2406. return
  2407. if out_path:
  2408. output = open( out_path, 'a')
  2409. output.write(str+'\n')
  2410. output.close()
  2411. return
  2412. if hdl_tags_path:
  2413. output = open( run_log_path ,'a')
  2414. output.write(str+'\n')
  2415. output.close()
  2416. def get_file_path_postfix(file_path):
  2417. split_by_dot = file_path.split('.')
  2418. if len(split_by_dot) < 2: # which means file_path has no postfix
  2419. return ''
  2420. post_fix = split_by_dot[-1] # postfix care case
  2421. return post_fix
  2422. HDLTagsActive = True
  2423. # if cur open a valid file, and file not verilog file not act vtags
  2424. if vim_start_open_file \
  2425. and (get_file_path_postfix(vim_start_open_file) not in config.support_verilog_postfix):
  2426. HDLTagsActive = False
  2427. # get file inf
  2428. FileInf = {}
  2429. try:
  2430. if hdl_tags_path and HDLTagsActive:
  2431. import files_inf
  2432. HDLTagsActive = files_inf.HDLTagsActive
  2433. FileInf = files_inf.FileInf
  2434. else:
  2435. HDLTagsActive = False
  2436. except:
  2437. HDLTagsActive = False
  2438. BaseModules = set()
  2439. if HDLTagsActive:
  2440. # get base module inf
  2441. try:
  2442. pkl_input = open(hdl_tags_path + '/base_modules.pkl','rb')
  2443. BaseModules = pickle.load(pkl_input)
  2444. pkl_input.close()
  2445. except:
  2446. pass
  2447. # function -------------------------------------------------
  2448. def save_env_snapshort():
  2449. snapshort = {}
  2450. # 0: save cur dir path, used to quality opne snapshort
  2451. snapshort['snapshort_dir_path'] = os.getcwd()
  2452. # 1: save Frame
  2453. snapshort['frame_file_lines'] = []
  2454. if os.path.isfile(G['Frame_Inf']['Frame_Path']):
  2455. snapshort['frame_file_lines'] = open(G['Frame_Inf']['Frame_Path'],'r').readlines()
  2456. # 2: save Report
  2457. snapshort['report_file_lines'] = []
  2458. if os.path.isfile(G['Report_Inf']['Report_Path']):
  2459. snapshort['report_file_lines'] = open(G['Report_Inf']['Report_Path'],'r').readlines()
  2460. # 3: save G
  2461. snapshort['G'] = {}
  2462. snapshort['G']['OpTraceInf'] = {}
  2463. snapshort['G']['OpTraceInf']['TracePoints'] = G['OpTraceInf']['TracePoints']
  2464. snapshort['G']['OpTraceInf']['Nonius' ] = G['OpTraceInf']['Nonius' ]
  2465. snapshort['G']['WorkWin_Inf'] = {}
  2466. snapshort['G']['WorkWin_Inf']['OpenWinTrace'] = G['WorkWin_Inf']['OpenWinTrace']
  2467. snapshort['G']['VimBufferLineFileLink' ] = G["VimBufferLineFileLink" ]
  2468. snapshort['G']["TraceInf" ] = G['TraceInf']
  2469. snapshort['G']['CheckPointInf'] = {}
  2470. snapshort['G']['CheckPointInf']['CheckPoints'] = G['CheckPointInf']['CheckPoints']
  2471. snapshort['G']['TopoInf'] = {}
  2472. snapshort['G']['TopoInf']['CurModule'] = G['TopoInf']['CurModule']
  2473. snapshort['G']['ModuleLastCallInf'] = G['ModuleLastCallInf']
  2474. snapshort['G']['Frame_Inf'] = {}
  2475. snapshort['G']['Frame_Inf']['Frame_Path'] = G['Frame_Inf']['Frame_Path']
  2476. snapshort['G']['Report_Inf'] = {}
  2477. snapshort['G']['Report_Inf']['Report_Path'] = G['Report_Inf']['Report_Path']
  2478. # 4: save act windows inf
  2479. act_win_inf = []
  2480. for w in vim.windows:
  2481. c_file_path = w.buffer.name
  2482. if c_file_path == vim.current.buffer.name:
  2483. continue
  2484. c_cursor = w.cursor
  2485. c_size = (w.width, w.height)
  2486. act_win_inf.append({'path': c_file_path, 'cursor': c_cursor, 'size': c_size })
  2487. # last is current window
  2488. cur_file_path = vim.current.buffer.name
  2489. cur_cursor = vim.current.window.cursor
  2490. cur_size = (vim.current.window.width, vim.current.window.height)
  2491. act_win_inf.append({'path': cur_file_path, 'cursor': cur_cursor, 'size': cur_size })
  2492. snapshort['act_win_inf'] = act_win_inf
  2493. pkl_output = open(hdl_tags_path + '/env_snapshort.pkl','wb')
  2494. pickle.dump(snapshort, pkl_output)
  2495. pkl_output.close()
  2496. return True
  2497. def reload_env_snapshort(snapshort):
  2498. # 1: reload G
  2499. snapshort_G = snapshort['G']
  2500. G['OpTraceInf']['TracePoints'] = snapshort_G['OpTraceInf']['TracePoints']
  2501. G['OpTraceInf']['Nonius' ] = snapshort_G['OpTraceInf']['Nonius' ]
  2502. G['WorkWin_Inf']['OpenWinTrace'] = snapshort_G['WorkWin_Inf']['OpenWinTrace']
  2503. G['VimBufferLineFileLink' ] = snapshort_G["VimBufferLineFileLink" ]
  2504. G["TraceInf" ] = snapshort_G['TraceInf']
  2505. G['CheckPointInf']['CheckPoints'] = snapshort_G['CheckPointInf']['CheckPoints']
  2506. G['TopoInf']['CurModule'] = snapshort_G['TopoInf']['CurModule']
  2507. G['ModuleLastCallInf'] = snapshort_G['ModuleLastCallInf']
  2508. G['Frame_Inf']['Frame_Path'] = snapshort_G['Frame_Inf']['Frame_Path']
  2509. G['Report_Inf']['Report_Path'] = snapshort_G['Report_Inf']['Report_Path']
  2510. # 2: reload Frame
  2511. os.system('touch ' + G['Frame_Inf']['Frame_Path'])
  2512. assert(os.path.isfile(G['Frame_Inf']['Frame_Path']))
  2513. frame_fp = open(G['Frame_Inf']['Frame_Path'],'w')
  2514. for l in snapshort['frame_file_lines']:
  2515. frame_fp.write(l)
  2516. frame_fp.close()
  2517. # 3: reload Report
  2518. os.system('touch ' + G['Report_Inf']['Report_Path'])
  2519. assert(os.path.isfile(G['Report_Inf']['Report_Path']))
  2520. report_fp = open(G['Report_Inf']['Report_Path'],'w')
  2521. for l in snapshort['report_file_lines']:
  2522. report_fp.write(l)
  2523. report_fp.close()
  2524. # 4: reload act windows inf need re open at API.py
  2525. G['EnvSnapshortWinsInf'] = snapshort['act_win_inf']
  2526. return
  2527. # structure -----------------------------------------------------
  2528. # frame file_link = {
  2529. # 'type' : '', topo | check_point | base_module
  2530. # 'key' : '', topo module name | add check point word | base module name
  2531. # 'pos' : '', module def pos | add pos | module pos
  2532. # 'path' : '', module def file path | add file path | module def file path
  2533. # 'fold_inf' : {}, 'fold_status': on/off/fix
  2534. # , 'level' : n
  2535. #
  2536. # }
  2537. Frame_Inf = {
  2538. "Frame_Win_x" : config.frame_window_width # frame window width
  2539. ,"Frame_Path" : ''
  2540. ,"FoldLevelSpace" : config.frame_fold_level_space
  2541. }
  2542. Frame_Inf['Frame_Path'] = hdl_tags_path + '/' + "Frame.HF" + str(empty_log_index)
  2543. # report file_link = {
  2544. # 'key' : '' , signal_name
  2545. # 'pos' : '' , match_pos
  2546. # 'path' : '' , match_path
  2547. # }
  2548. Report_Inf = {
  2549. "Report_Win_y" : config.report_window_height # report window height
  2550. ,"Report_Path" : hdl_tags_path + '/' + "Report.HF"
  2551. }
  2552. Report_Inf['Report_Path'] = hdl_tags_path + '/' + "Report.HF" + str(empty_log_index)
  2553. WorkWin_Inf ={
  2554. "MaxNum" : config.max_open_work_window_number
  2555. ,"OpenWinTrace" : []
  2556. }
  2557. # all vim buffer line file link { path:[...]}
  2558. VimBufferLineFileLink = {}
  2559. TraceInf = {
  2560. 'LastTraceSource' : {'Maybe':[], 'Sure':[], 'ShowIndex': 0, 'SignalName':'', 'Path':'' } # Maybe[{'show':'', 'file_link':{ 'key':'','pos':(l,c),'path':'' } }]
  2561. ,'LastTraceDest' : {'Maybe':[], 'Sure':[], 'ShowIndex': 0, 'SignalName':'', 'Path':'' }
  2562. ,'TraceSourceOptimizingThreshold' : config.trace_source_optimizing_threshold
  2563. }
  2564. # operation trace
  2565. OpTraceInf = {
  2566. 'TracePoints' : [] # {'path':'', "pos":(line, colum), 'key':''}
  2567. ,'TraceDepth' : config.max_roll_trace_depth
  2568. ,'Nonius' : -1 # roll nonius
  2569. }
  2570. TopoInf = {
  2571. 'CurModule' : ''
  2572. ,'TopFoldLevel' : 0
  2573. }
  2574. CheckPointInf = {
  2575. "MaxNum" : config.max_his_check_point_num
  2576. ,"CheckPoints" : [] #{}--- key: '', link: {}
  2577. ,"TopFoldLevel" : 0
  2578. }
  2579. BaseModuleInf = {
  2580. "BaseModuleThreshold" : config.base_module_threshold # when module inst BaseModuleThreshold times, then default set it to base module
  2581. ,"BaseModules" : BaseModules # module name set()
  2582. ,"TopFoldLevel" : 0
  2583. }
  2584. G = {
  2585. 'HDLTagsActive' : HDLTagsActive
  2586. ,'SupportVHDLPostfix' : set([])
  2587. ,'SupportVerilogPostfix' : set(config.support_verilog_postfix)
  2588. ,'ModuleInf' : {}
  2589. ,'ModuleLastCallInf' : {} # {module_name:{ upper_module_name:'', 'upper_inst_name':inst_name} }
  2590. ,'FileInf' : FileInf
  2591. ,'CodeDefineInf' : {} # {name: [ {name path pos code_line} ]}
  2592. ,'OpTraceInf' : OpTraceInf
  2593. ,"Debug" : config.debug_mode # debug mode
  2594. ,"ShowReport" : config.show_report
  2595. ,"ShowFrame" : config.show_sidebar
  2596. ,"PrintDebug_F" : PrintDebug # function to print debug
  2597. ,"Frame_Inf" : Frame_Inf # Frame window inf
  2598. ,"Report_Inf" : Report_Inf # report window inf
  2599. ,"WorkWin_Inf" : WorkWin_Inf # win config
  2600. ,"VimBufferLineFileLink" : VimBufferLineFileLink
  2601. ,"TraceInf" : TraceInf
  2602. ,"CheckPointInf" : CheckPointInf
  2603. ,"BaseModuleInf" : BaseModuleInf
  2604. ,'TopoInf' : TopoInf
  2605. ,"FixExtraSpace" : True # some situation come extra space, need do nonthing
  2606. ,"IgnoreNextSpaceOp" : False # just flod has a else space, not do space op
  2607. ,"EnvSnapshortWinsInf" : []
  2608. ,"SaveEnvSnapshort_F" : save_env_snapshort
  2609. ,"VTagsPath" : hdl_tags_path
  2610. }
  2611. # has save history sence then just repaly it
  2612. start_with_empty_file = False
  2613. if not vim_start_open_file :
  2614. start_with_empty_file = True
  2615. EnvSnapshort = {}
  2616. if HDLTagsActive and start_with_empty_file and os.path.isfile(hdl_tags_path + '/env_snapshort.pkl'):
  2617. pkl_input = open(hdl_tags_path + '/env_snapshort.pkl','rb')
  2618. c_snapshort = pickle.load(pkl_input)
  2619. if c_snapshort['snapshort_dir_path'] == os.getcwd():
  2620. os.system('echo \'do you want reload vim snapshort ? (y/n): \'')
  2621. yes_or_no = raw_input()
  2622. if yes_or_no.lower() in ['y','yes']:
  2623. EnvSnapshort = c_snapshort
  2624. pkl_input.close()
  2625. if EnvSnapshort:
  2626. reload_env_snapshort(EnvSnapshort)
  2627. """
  2628. https://my.oschina.net/u/2520885
  2629. """
  2630. #===============================================================================
  2631. # Copyright (C) 2016 by Jun Cao
  2632. # Permission is hereby granted, free of charge, to any person obtaining a copy
  2633. # of this software and associated documentation files (the "Software"), to deal
  2634. # in the Software without restriction, including without limitation the rights
  2635. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  2636. # copies of the Software, and to permit persons to whom the Software is
  2637. # furnished to do so, subject to the following conditions:
  2638. # The above copyright notice and this permission notice shall be included in
  2639. # all copies or substantial portions of the Software.
  2640. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2641. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2642. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2643. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2644. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  2645. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  2646. # THE SOFTWARE.
  2647. #===============================================================================
  2648. import sys
  2649. import re
  2650. try:
  2651. import vim
  2652. except:
  2653. pass
  2654. import os
  2655. import re
  2656. from Base import *
  2657. from Win import *
  2658. import GLB
  2659. G = GLB.G
  2660. #--------------------------------------
  2661. SnapshotStack = []
  2662. def snapshort_push():
  2663. cur_cursor = vim.current.window.cursor
  2664. cur_pos = (cur_cursor[0]-1, cur_cursor[1]) # minus 1 because cursor start from 1, and lines start from 0
  2665. cur_line_num = cur_pos[0]
  2666. cur_line = vim.current.buffer[cur_line_num]
  2667. cur_word = get_full_word(cur_line, cur_pos[1])
  2668. cur_file_path = vim.current.buffer.name
  2669. cur_snapshort = {"path": cur_file_path, "pos":cur_pos, "key":cur_word}
  2670. SnapshotStack.append(cur_snapshort)
  2671. def snapshort_pop():
  2672. pop_snapshort = SnapshotStack[-1]
  2673. del SnapshotStack[-1]
  2674. go_win( pop_snapshort['path'], pop_snapshort['pos'], pop_snapshort['key'])
  2675. #--------------------------------------
  2676. def Show(path): # just show frame win , and not go to that window
  2677. path = get_path_for_name(path)
  2678. Act_Win = Cur_Act_Win()
  2679. if path not in Act_Win:
  2680. snapshort_push()
  2681. Open(path)
  2682. snapshort_pop()
  2683. return
  2684. #--------------------------------------
  2685. def add_trace_point():
  2686. cur_cursor = vim.current.window.cursor
  2687. cur_file_path = vim.current.buffer.name
  2688. if cur_file_path in [ G['Frame_Inf']['Frame_Path'], G['Report_Inf']['Report_Path'] ]:
  2689. PrintDebug('Warning: Frame and Report not add trace point !')
  2690. return
  2691. cur_pos = (cur_cursor[0]-1, cur_cursor[1]) # minus 1 because cursor start from 1, and lines start from 0
  2692. cur_line_num = cur_pos[0]
  2693. cur_line = vim.current.buffer[cur_line_num]
  2694. cur_word = get_full_word(cur_line, cur_pos[1])
  2695. cur_trace_point = {"path": cur_file_path, "pos":cur_pos, "key":cur_word}
  2696. cur_nonius = G['OpTraceInf']['Nonius']
  2697. TracePoints = G['OpTraceInf']['TracePoints']
  2698. # when roll back, and add from middle of queue, just clear old trace point after cur insert index
  2699. # | 0 | 1 | 2 | 3 | 4 |
  2700. # ^ if len 5, nonius <= 3 then del 4
  2701. if cur_nonius <= (len(TracePoints) - 2):
  2702. del TracePoints[cur_nonius + 1 : ]
  2703. # add a new point to TracePoints
  2704. # if cur add is equ to pre not add
  2705. if not TracePoints:
  2706. TracePoints.append(cur_trace_point)
  2707. else:
  2708. pre_point = TracePoints[-1]
  2709. if cur_trace_point != pre_point:
  2710. TracePoints.append(cur_trace_point)
  2711. # if length bigger than TraceDepth del
  2712. TraceDepth = G['OpTraceInf']['TraceDepth']
  2713. while (len(TracePoints) > TraceDepth):
  2714. del TracePoints[0]
  2715. # if add new point ,nonius assign to len(TracePoints)
  2716. # | 0 | 1 | 2 | 3 | 4 |
  2717. # ^ because roll back will first sub 1
  2718. G['OpTraceInf']['Nonius'] = len(TracePoints)
  2719. def get_cur_cursor_inf():
  2720. cur_cursor = vim.current.window.cursor
  2721. cur_line_num = cur_cursor[0] - 1 # minus 1 because cursor start from 1, and lines start from 0
  2722. cur_colm_num = cur_cursor[1]
  2723. cur_line = vim.current.buffer[cur_line_num]
  2724. cur_word = get_full_word(cur_line, cur_cursor[1])
  2725. cur_codes = vim.current.buffer
  2726. cur_file_path = vim.current.buffer.name
  2727. cur_hdl_type = get_file_hdl_type(cur_file_path)
  2728. cur_call_sub_inf = {}
  2729. cur_module_inf = {}
  2730. cur_line_inf = get_file_line_inf(cur_line_num, cur_file_path)
  2731. if cur_line_inf:
  2732. cur_call_sub_inf = cur_line_inf['line_call_sub_inf']
  2733. cur_module_inf = cur_line_inf['line_module_inf']
  2734. cur_module_name = ''
  2735. if cur_module_inf:
  2736. cur_module_name = cur_module_inf['module_name']
  2737. else:
  2738. PrintDebug('Warning: get_cur_cursor_inf: current cursor %s not in module, file: %s ! '%(cur_cursor.__str__(), cur_file_path ))
  2739. return { 'cursor' : cur_cursor
  2740. ,'pos' : (cur_line_num, cur_colm_num)
  2741. ,'line_num' : cur_line_num
  2742. ,'colm_num' : cur_colm_num
  2743. ,'line' : cur_line
  2744. ,'word' : cur_word
  2745. ,'file_path' : cur_file_path
  2746. ,'hdl_type' : cur_hdl_type
  2747. ,'cur_call_sub_inf' : cur_call_sub_inf
  2748. ,'cur_module_inf' : cur_module_inf
  2749. ,'codes' : cur_codes }
  2750. # ok
  2751. # report file_link = {
  2752. # 'key' : '' , signal_name
  2753. # 'pos' : '' , match_pos
  2754. # 'path' : '' , match_path
  2755. # }
  2756. #----for python edition 2.7 +
  2757. # def PrintReport(*show, file_link = {}, spec_case = '', mode = 'a'):
  2758. # # normal show a string
  2759. # show_str = ' '.join([ i.__str__() for i in show ])
  2760. #----for python edition 2.6
  2761. def PrintReport(show = '', file_link = {}, spec_case = '', mode = 'a'):
  2762. if not G['ShowReport']:
  2763. return
  2764. has_self_snap_short = False
  2765. if not cur_in_report():
  2766. snapshort_push()
  2767. Open('Report')
  2768. has_self_snap_short = True
  2769. show_str = show
  2770. if show_str:
  2771. edit_vim_buffer('Report', [show_str], file_links = [file_link], mode = mode)
  2772. # show trace source result
  2773. if spec_case == 'source':
  2774. edit_vim_buffer('Report', "---------------------------source--------------------------------")
  2775. t_data = []
  2776. t_file_link = []
  2777. for Sure in G['TraceInf']['LastTraceSource']['Sure']:
  2778. t_data.append( Sure['show'] )
  2779. t_file_link.append( Sure['file_link'] )
  2780. edit_vim_buffer('Report', t_data, t_file_link)
  2781. edit_vim_buffer('Report', "------------------------maybe source-----------------------------")
  2782. t_data = []
  2783. t_file_link = []
  2784. for Maybe in G['TraceInf']['LastTraceSource']['Maybe']:
  2785. t_data.append( Maybe['show'] )
  2786. t_file_link.append( Maybe['file_link'] )
  2787. edit_vim_buffer('Report', t_data, t_file_link)
  2788. edit_vim_buffer('Report', "----------------------------END----------------------------------")
  2789. edit_vim_buffer('Report', "")
  2790. # show trace dest result
  2791. if spec_case == 'dest':
  2792. edit_vim_buffer('Report', "---------------------------dest--------------------------------")
  2793. t_data = []
  2794. t_file_link = []
  2795. for Sure in G['TraceInf']['LastTraceDest']['Sure']:
  2796. t_data.append( Sure['show'] )
  2797. t_file_link.append( Sure['file_link'] )
  2798. edit_vim_buffer('Report', t_data, t_file_link)
  2799. edit_vim_buffer('Report', "------------------------maybe dest-----------------------------")
  2800. t_data = []
  2801. t_file_link = []
  2802. for Maybe in G['TraceInf']['LastTraceDest']['Maybe']:
  2803. t_data.append( Maybe['show'] )
  2804. t_file_link.append( Maybe['file_link'] )
  2805. edit_vim_buffer('Report', t_data, t_file_link)
  2806. edit_vim_buffer('Report', "----------------------------END----------------------------------")
  2807. edit_vim_buffer('Report', "")
  2808. # go report to the last line, and return
  2809. assert(cur_in_report())
  2810. # if mode == 'a':
  2811. vim.current.window.cursor = (len(vim.current.buffer) - 1 , 0)
  2812. vim.command('w!')
  2813. if has_self_snap_short:
  2814. snapshort_pop()
  2815. # ok
  2816. def show_next_trace_result( trace_type ):
  2817. if trace_type == 'source':
  2818. cur_show_index = G['TraceInf']['LastTraceSource']["ShowIndex"]
  2819. sure_source_len = len(G['TraceInf']['LastTraceSource']['Sure'])
  2820. maybe_source_len = len(G['TraceInf']['LastTraceSource']['Maybe'])
  2821. if (sure_source_len + maybe_source_len) == 0:
  2822. PrintReport('not find source !')
  2823. return
  2824. cur_file_link = {}
  2825. if cur_show_index < sure_source_len:
  2826. cur_file_link = G['TraceInf']['LastTraceSource']['Sure'][cur_show_index]['file_link']
  2827. else:
  2828. cur_file_link = G['TraceInf']['LastTraceSource']['Maybe'][cur_show_index - sure_source_len]['file_link']
  2829. G['TraceInf']['LastTraceSource']["ShowIndex"] = (cur_show_index + 1) % (sure_source_len + maybe_source_len)
  2830. add_trace_point()
  2831. go_win( cur_file_link['path'], cur_file_link['pos'], cur_file_link['key'] )
  2832. elif trace_type == 'dest':
  2833. cur_show_index = G['TraceInf']['LastTraceDest']["ShowIndex"]
  2834. sure_dest_len = len(G['TraceInf']['LastTraceDest']['Sure'])
  2835. maybe_dest_len = len(G['TraceInf']['LastTraceDest']['Maybe'])
  2836. if (sure_dest_len + maybe_dest_len) == 0:
  2837. PrintReport('not find dest !')
  2838. return
  2839. cur_file_link = {}
  2840. if cur_show_index < sure_dest_len:
  2841. cur_file_link = G['TraceInf']['LastTraceDest']['Sure'][cur_show_index]['file_link']
  2842. else:
  2843. cur_file_link = G['TraceInf']['LastTraceDest']['Maybe'][cur_show_index - sure_dest_len]['file_link']
  2844. G['TraceInf']['LastTraceDest']["ShowIndex"] = (cur_show_index + 1) % (sure_dest_len + maybe_dest_len)
  2845. add_trace_point()
  2846. go_win( cur_file_link['path'], cur_file_link['pos'], cur_file_link['key'])
  2847. else:
  2848. assert(0)
  2849. #--------------------------------------------------------------------------
  2850. def gen_top_topo_data_link(topo_module):
  2851. topo_datas = []
  2852. topo_links = []
  2853. topo_module_inf = get_module_inf(topo_module)
  2854. if not topo_module_inf:
  2855. PrintDebug('Error: get topo module name %s, should has module inf !'%(topo_module))
  2856. return topo_datas, topo_links
  2857. TopTopoLevel = G['TopoInf']['TopFoldLevel']
  2858. TopTopoPrefix = G['Frame_Inf']['FoldLevelSpace'] * TopTopoLevel
  2859. # add first topo line
  2860. topo_datas.append(TopTopoPrefix + 'ModuleTopo:')
  2861. topo_link = {
  2862. 'type' : 'topo'
  2863. ,'topo_inst_name' : ''
  2864. ,'key' : ''
  2865. ,'pos' : ''
  2866. ,'path' : ''
  2867. ,'fold_inf' : {'fold_status':'on', 'level': TopTopoLevel - 1 }
  2868. }
  2869. topo_links.append(topo_link)
  2870. # add cur module name
  2871. topo_datas.append(TopTopoPrefix + topo_module + ':')
  2872. topo_link = {
  2873. 'type' : 'topo'
  2874. ,'topo_inst_name' : ''
  2875. ,'key' : topo_module
  2876. ,'pos' : topo_module_inf['module_pos']
  2877. ,'path' : topo_module_inf['file_path']
  2878. ,'fold_inf' : {'fold_status':'on', 'level': TopTopoLevel}
  2879. }
  2880. topo_links.append(topo_link)
  2881. # gen current module sub function module, and base module topo inf
  2882. sub_module_data, sub_module_link = get_fram_topo_sub_inf(topo_module, 0)
  2883. topo_datas = topo_datas + sub_module_data
  2884. topo_links = topo_links + sub_module_link
  2885. return topo_datas, topo_links
  2886. def edit_frame(data = [], file_links = [], mode = 'a', n = 0, del_range = ()):
  2887. has_self_snap_short = False
  2888. if not cur_in_frame():
  2889. snapshort_push()
  2890. Open('Frame')
  2891. has_self_snap_short = True
  2892. edit_vim_buffer( path_or_name = 'Frame', data = data, file_links = file_links, mode = mode, n = n, del_range = del_range)
  2893. # go frame w! and go back
  2894. assert(cur_in_frame())
  2895. vim.command('w!')
  2896. if has_self_snap_short:
  2897. snapshort_pop()
  2898. #---------------------------------------
  2899. def show_base_module(fold = True):
  2900. frame_data = []
  2901. frame_link = []
  2902. # if frame not show ,show it
  2903. Show("Frame")
  2904. # add initial line
  2905. level = G['BaseModuleInf']['TopFoldLevel']
  2906. key = G['Frame_Inf']['FoldLevelSpace']*level + 'BaseModules:'
  2907. link = {
  2908. 'type' : 'base_module'
  2909. ,'key' : ''
  2910. ,'pos' : ''
  2911. ,'path' : ''
  2912. ,'fold_inf' : { 'fold_status': 'on', 'level': level }
  2913. }
  2914. frame_data.append(key)
  2915. frame_link.append(link)
  2916. # add check points
  2917. range_inf = get_frame_range_inf()
  2918. has_base_module = range_inf['has_base_module']
  2919. base_module_range = range_inf['base_module_range']
  2920. cp_data = []
  2921. cp_link = []
  2922. if fold:
  2923. cp_data, cp_link = get_fram_base_module_inf()
  2924. else:
  2925. frame_link[-1]['fold_inf']['fold_status'] = 'off'
  2926. frame_data = frame_data + cp_data
  2927. frame_link = frame_link + cp_link
  2928. # del old cp, add new cp
  2929. if has_base_module: # del
  2930. edit_frame(mode = 'del', del_range = base_module_range)
  2931. edit_frame(data = frame_data, file_links = frame_link, mode = 'i', n = base_module_range[0])
  2932. return True
  2933. #-------------------------------------
  2934. def show_check_point(fold = True):
  2935. frame_data = []
  2936. frame_link = []
  2937. # if frame not show ,show it
  2938. Show("Frame")
  2939. # add initial line
  2940. level = G['CheckPointInf']['TopFoldLevel']
  2941. key = G['Frame_Inf']['FoldLevelSpace']*level + 'CheckPoints:'
  2942. link = {
  2943. 'type' : 'check_point'
  2944. ,'key' : ''
  2945. ,'pos' : ''
  2946. ,'path' : ''
  2947. ,'fold_inf' : { 'fold_status': 'on', 'level': level }
  2948. }
  2949. frame_data.append(key)
  2950. frame_link.append(link)
  2951. # add check points
  2952. range_inf = get_frame_range_inf()
  2953. has_check_point = range_inf['has_check_point']
  2954. check_point_range = range_inf['check_point_range']
  2955. cp_data = []
  2956. cp_link = []
  2957. if fold:
  2958. cp_data, cp_link = get_fram_check_point_inf()
  2959. else:
  2960. frame_link[-1]['fold_inf']['fold_status'] = 'off'
  2961. frame_data = frame_data + cp_data
  2962. frame_link = frame_link + cp_link
  2963. # del old cp, add new cp
  2964. if has_check_point: # del
  2965. edit_frame(mode = 'del', del_range = check_point_range)
  2966. edit_frame(data = frame_data, file_links = frame_link, mode = 'i', n = check_point_range[0])
  2967. return True
  2968. #---------------------------------------
  2969. def show_topo(topo_module_name = ''):
  2970. if not topo_module_name:
  2971. cursor_inf = get_cur_cursor_inf()
  2972. if cursor_inf['hdl_type'] != 'verilog':
  2973. # if not in support file type(verilog,vhdl) just return
  2974. PrintReport("Warning: Current only support verilog !")
  2975. return False
  2976. # get current module inf
  2977. cur_module_inf = cursor_inf['cur_module_inf']
  2978. # current not at module lines, just return
  2979. if not cur_module_inf:
  2980. PrintReport("Warning: Current cursor not in valid module !")
  2981. return False
  2982. topo_module_name = cur_module_inf['module_name']
  2983. else:
  2984. if topo_module_name not in G['ModuleInf']:
  2985. PrintReport("Warning: show topo module %s not have database !"%(topo_module_name))
  2986. return False
  2987. # if frame not show ,show it
  2988. Show("Frame")
  2989. # current module must has module inf
  2990. G['TopoInf']['CurModule'] = topo_module_name # note cur topo name for refresh
  2991. range_inf = get_frame_range_inf()
  2992. has_topo = range_inf['has_topo']
  2993. topo_range = range_inf['topo_range']
  2994. topo_data, topo_link = gen_top_topo_data_link(topo_module_name)
  2995. # del old topo, add new topo
  2996. if has_topo: # del
  2997. edit_frame(mode = 'del', del_range = topo_range)
  2998. edit_frame(data = topo_data, file_links = topo_link, mode = 'i', n = topo_range[0])
  2999. return True
  3000. def iteration_fold_no_module(inst_module_pairs, base_modules):
  3001. c_frame_range_inf = get_frame_range_inf()
  3002. if not c_frame_range_inf['has_topo']:
  3003. return
  3004. frame_path = G['Frame_Inf']['Frame_Path']
  3005. c_topo_range = c_frame_range_inf['topo_range']
  3006. c_topo_links = G['VimBufferLineFileLink'][frame_path][c_topo_range[0] : c_topo_range[1]]
  3007. for i,lk in enumerate(c_topo_links):
  3008. if not( lk and (lk['fold_inf']['fold_status'] == 'off') and lk['key'] ):
  3009. continue
  3010. if lk['topo_inst_name']:
  3011. c_inst_module_pair = (lk['topo_inst_name'], lk['key'])
  3012. if c_inst_module_pair in inst_module_pairs:
  3013. fold_frame_line(lk, i+c_topo_range[0], lk['fold_inf']['level'], 'topo')
  3014. iteration_fold_no_module(inst_module_pairs, base_modules)
  3015. return
  3016. else:
  3017. if lk['key'] in base_modules:
  3018. fold_frame_line(lk, i+c_topo_range[0], lk['fold_inf']['level'], 'topo')
  3019. iteration_fold_no_module(inst_module_pairs, base_modules)
  3020. return
  3021. return
  3022. def refresh_topo():
  3023. # get all folded module or inst pair
  3024. old_frame_range_inf = get_frame_range_inf()
  3025. if not old_frame_range_inf['has_topo']:
  3026. return
  3027. frame_path = G['Frame_Inf']['Frame_Path']
  3028. old_topo_range = old_frame_range_inf['topo_range']
  3029. old_topo_links = G['VimBufferLineFileLink'][frame_path][old_topo_range[0] + 2 : old_topo_range[1] + 1]
  3030. old_fold_inst_module_pairs = set()
  3031. old_fold_base_modules = set()
  3032. for lk in old_topo_links:
  3033. if not( lk and (lk['fold_inf']['fold_status'] == 'on') and lk['key'] ):
  3034. continue
  3035. if lk['topo_inst_name']:
  3036. old_fold_inst_module_pairs.add( (lk['topo_inst_name'], lk['key']) )
  3037. else:
  3038. if lk['key'] in G['BaseModuleInf']['BaseModules']:
  3039. old_fold_base_modules.add(lk['key'])
  3040. # start new topo
  3041. new_topo_module_name = G['TopoInf']['CurModule']
  3042. show_topo(new_topo_module_name)
  3043. # iteration opened old folded topo
  3044. iteration_fold_no_module(old_fold_inst_module_pairs, old_fold_base_modules)
  3045. #---------------------------------------
  3046. def unfold_frame_line(frame_links, frame_line, cur_frame_level, cur_frame_type):
  3047. assert(frame_links[frame_line]['fold_inf']['fold_status'] == 'on')
  3048. G['VimBufferLineFileLink'][ G['Frame_Inf']['Frame_Path'] ][frame_line]['fold_inf']['fold_status'] = 'off'
  3049. unfold_end_line_num = frame_line
  3050. for i in range(frame_line+1, len(frame_links)):
  3051. # if cur not have file link, then cur is unflod end
  3052. if not frame_links[i]:
  3053. unfold_end_line_num = i - 1
  3054. break
  3055. # if has file link ,but not topo inf then unflod end
  3056. if frame_links[i]['type'] != cur_frame_type:
  3057. unfold_end_line_num = i - 1
  3058. break
  3059. # if is topo , but level <= cur level then unflod end
  3060. if frame_links[i]['fold_inf']['level'] <= cur_frame_level:
  3061. unfold_end_line_num = i - 1
  3062. break
  3063. # if cur module has no sub module then just return
  3064. if unfold_end_line_num == frame_line:
  3065. return True
  3066. # else edit the frame buffer and file link, del the unflod lines
  3067. if unfold_end_line_num > frame_line:
  3068. edit_frame(mode = 'del', del_range = (frame_line + 1, unfold_end_line_num))
  3069. return True
  3070. # else some trouble
  3071. assert(0),'shold not happen !'
  3072. def fold_frame_line(cur_line_link, frame_line, cur_frame_level, cur_frame_type):
  3073. assert(cur_line_link['fold_inf']['fold_status'] == 'off')
  3074. G['VimBufferLineFileLink'][ G['Frame_Inf']['Frame_Path'] ][frame_line]['fold_inf']['fold_status'] = 'on'
  3075. if cur_frame_type == 'topo':
  3076. # if cur is ModuleTopo: line, show refresh topo
  3077. if cur_frame_level == G['TopoInf']['TopFoldLevel'] - 1:
  3078. topo_module_name = G['TopoInf']['CurModule']
  3079. show_topo(topo_module_name)
  3080. return
  3081. # cur_line_link['key'] is the cur topo line module name
  3082. cur_module_name = cur_line_link['key']
  3083. if not cur_module_name:
  3084. PrintReport('Warning: cur topo line has no module name !')
  3085. return
  3086. if cur_module_name not in G['ModuleInf']:
  3087. PrintReport('Warning: cur module: \"%s\" has no database !'%(cur_module_name))
  3088. return
  3089. # get cur module sub module inf
  3090. sub_topo_data, sub_topo_link = get_fram_topo_sub_inf(cur_module_name, cur_frame_level)
  3091. # add cur module topo inf to frame
  3092. edit_frame(data = sub_topo_data, file_links = sub_topo_link, mode = 'i', n = frame_line + 1)
  3093. elif cur_frame_type == 'check_point':
  3094. show_check_point()
  3095. elif cur_frame_type == 'base_module':
  3096. show_base_module()
  3097. else:
  3098. PrintReport('Warning: no operation in this line !')
  3099. return
  3100. def frame_line_fold_operation(frame_line):
  3101. frame_path = G['Frame_Inf']['Frame_Path']
  3102. frame_links = G['VimBufferLineFileLink'][frame_path]
  3103. cur_line_link = frame_links[frame_line]
  3104. if not cur_line_link :
  3105. PrintReport('Warning: cur frame line no fold operation !')
  3106. return
  3107. cur_frame_type = cur_line_link['type']
  3108. cur_frame_level = cur_line_link['fold_inf']['level']
  3109. cur_fold_state = cur_line_link['fold_inf']['fold_status']
  3110. if cur_fold_state == 'off':
  3111. fold_frame_line(cur_line_link, frame_line, cur_frame_level, cur_frame_type)
  3112. elif cur_fold_state == 'on':
  3113. unfold_frame_line(frame_links, frame_line, cur_frame_level, cur_frame_type)
  3114. else:
  3115. PrintReport('Warning: cur frame line no fold operation !')
  3116. return
  3117. """
  3118. https://my.oschina.net/u/2520885
  3119. """
  3120. #===============================================================================
  3121. # Copyright (C) 2016 by Jun Cao
  3122. # Permission is hereby granted, free of charge, to any person obtaining a copy
  3123. # of this software and associated documentation files (the "Software"), to deal
  3124. # in the Software without restriction, including without limitation the rights
  3125. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  3126. # copies of the Software, and to permit persons to whom the Software is
  3127. # furnished to do so, subject to the following conditions:
  3128. # The above copyright notice and this permission notice shall be included in
  3129. # all copies or substantial portions of the Software.
  3130. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  3131. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3132. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  3133. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  3134. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  3135. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  3136. # THE SOFTWARE.
  3137. #===============================================================================
  3138. try:
  3139. import vim
  3140. except:
  3141. pass
  3142. import sys
  3143. import re
  3144. import os
  3145. import GLB
  3146. G = GLB.G
  3147. from Base import *
  3148. def Reset_Win_Size():
  3149. cur_act_wins = Cur_Act_Win()
  3150. if G['Report_Inf']['Report_Path'] in cur_act_wins:
  3151. Jump_To_Win(G['Report_Inf']['Report_Path'])
  3152. vim.command('wincmd J')
  3153. vim.current.window.height = G['Report_Inf']['Report_Win_y']
  3154. if G['Frame_Inf']['Frame_Path'] in cur_act_wins:
  3155. Jump_To_Win(G['Frame_Inf']['Frame_Path'])
  3156. vim.command('wincmd H')
  3157. vim.current.window.width = G['Frame_Inf']['Frame_Win_x']
  3158. return
  3159. def Refresh_OpenWinTrace():
  3160. cur_act_win_path = Cur_Act_Win()
  3161. cur_act_work_win_path = cur_act_win_path - set([ G["Report_Inf"]["Report_Path"], G["Frame_Inf"]["Frame_Path"] ])
  3162. i = 0
  3163. while i < len(G['WorkWin_Inf']['OpenWinTrace']) :
  3164. c_path = G['WorkWin_Inf']['OpenWinTrace'][i]
  3165. if c_path not in cur_act_work_win_path:
  3166. del G['WorkWin_Inf']['OpenWinTrace'][i]
  3167. else:
  3168. i += 1
  3169. return
  3170. def Cur_Act_Win():
  3171. Act_Win = set()
  3172. for w in vim.windows:
  3173. Act_Win.add(w.buffer.name)
  3174. return Act_Win
  3175. def Open(name):
  3176. path = get_path_for_name(name)
  3177. Act_Win = Cur_Act_Win()
  3178. if path in Act_Win: # win has open and just jump to than window
  3179. Jump_To_Win(path)
  3180. elif path == G['Frame_Inf']["Frame_Path"]:
  3181. Open_Frame_Win()
  3182. elif path == G['Report_Inf']["Report_Path"]:
  3183. Open_Report_Win()
  3184. else:
  3185. Open_Work_Win(path)
  3186. Reset_Win_Size()
  3187. Jump_To_Win(path)
  3188. assert(vim.current.buffer.name == path)
  3189. def Jump_To_Win(path):
  3190. cur_act_wins = Cur_Act_Win()
  3191. assert(path in cur_act_wins)
  3192. start_path = vim.current.buffer.name
  3193. if start_path == path:
  3194. return
  3195. vim.command('wincmd w')
  3196. cur_path = vim.current.buffer.name
  3197. while cur_path != start_path:
  3198. if cur_path == path:
  3199. break
  3200. vim.command("wincmd w")
  3201. cur_path = vim.current.buffer.name
  3202. assert(vim.current.buffer.name == path),'vim.current.buffer.name: %s, path: %s'%(vim.current.buffer.name, path)
  3203. def Open_Frame_Win():
  3204. G['VimBufferLineFileLink'].setdefault(G["Frame_Inf"]["Frame_Path"],[{}])
  3205. vim.command("vertical topleft sp " + G["Frame_Inf"]["Frame_Path"])
  3206. def Open_Report_Win():
  3207. G['VimBufferLineFileLink'].setdefault(G["Report_Inf"]["Report_Path"],[{}])
  3208. vim.command("bot sp " + G["Report_Inf"]["Report_Path"])
  3209. if G["Frame_Inf"]["Frame_Path"] in Cur_Act_Win():
  3210. Jump_To_Win(G["Frame_Inf"]["Frame_Path"])
  3211. vim.command('wincmd H')
  3212. Jump_To_Win(G["Report_Inf"]["Report_Path"])
  3213. def Open_Work_Win(path):
  3214. # path must valid
  3215. assert(os.path.isfile(path))
  3216. # refresh open work win trace
  3217. Refresh_OpenWinTrace()
  3218. # leave at most G['WorkWin_Inf']['MaxNum'] work win
  3219. win_num_need_to_close = len(G['WorkWin_Inf']['OpenWinTrace']) - G['WorkWin_Inf']['MaxNum']
  3220. for i in range(win_num_need_to_close):
  3221. win_path_need_close = G['WorkWin_Inf']['OpenWinTrace'][i]
  3222. Jump_To_Win(win_path_need_close)
  3223. vim.command('q')
  3224. del G['WorkWin_Inf']['OpenWinTrace'][i]
  3225. # if has work win
  3226. cur_work_win_num = len(G['WorkWin_Inf']['OpenWinTrace'])
  3227. if cur_work_win_num > 0:
  3228. # case 0: has work win, and num less than max
  3229. # just go last work win, and vsp a new win
  3230. if cur_work_win_num < G['WorkWin_Inf']['MaxNum']:
  3231. Jump_To_Win(G['WorkWin_Inf']['OpenWinTrace'][-1])
  3232. vim.command('vsp '+path)
  3233. else: # case 1: opened all work win, just replace the oldest open work win
  3234. Jump_To_Win(G['WorkWin_Inf']['OpenWinTrace'][0])
  3235. vim.command('e '+path)
  3236. del G['WorkWin_Inf']['OpenWinTrace'][0] # replace [0], just del old
  3237. else: # cur no work win
  3238. cur_act_win_paths = Cur_Act_Win()
  3239. cur_act_hold_wins = cur_act_win_paths - set([G["Report_Inf"]["Report_Path"], G["Frame_Inf"]["Frame_Path"]])
  3240. # if has hold win, go hold win, vsp
  3241. if cur_act_hold_wins:
  3242. Jump_To_Win(list(cur_act_hold_wins)[0])
  3243. vim.command('vsp '+path)
  3244. elif G["Report_Inf"]["Report_Path"] in cur_act_win_paths:
  3245. # if no hold win, has report , go report sp new
  3246. Jump_To_Win(G["Report_Inf"]["Report_Path"])
  3247. vim.command('sp '+path)
  3248. else:
  3249. vim.command('vsp '+path)
  3250. # finial add path to trace
  3251. assert(vim.current.buffer.name == path)
  3252. G['WorkWin_Inf']['OpenWinTrace'].append(path)
  3253. def get_file_vim_buffer(path):
  3254. for i,b in enumerate(vim.buffers):
  3255. if b.name == path:
  3256. return b
  3257. # path buffer not open
  3258. vim.command("bad "+path)
  3259. assert(vim.buffers[ len(vim.buffers) - 1].name == path)
  3260. return vim.buffers[ len(vim.buffers) - 1]
  3261. # edit the vim buffer, with put data at some position
  3262. # mode : a --after : append data after current buffer data
  3263. # b --before : append data before current buffer data
  3264. # w --write : clear old buffer data, and write data
  3265. # i --insert : inster list to n
  3266. # del -- delete : delete del_range lines
  3267. # del_range : (start,end) del range, include end
  3268. def edit_vim_buffer(path_or_name = '', data = [], file_links = [], mode = 'a', n = 0, del_range = ()):
  3269. # weather to edit link buffer
  3270. need_edit_buffer_file_link = False
  3271. if data == [] and mode != 'del':
  3272. PrintDebug('Warning: edit_vim_buffer: edit file with empty data= [], file:%s !'%(path_or_name))
  3273. return
  3274. if type(data) is str:
  3275. data = [data]
  3276. path = get_path_for_name(path_or_name)
  3277. # some time edit other buffer, may change cur window cursor or add empty line to cur buffer file,
  3278. # so must edit current buffer
  3279. assert(vim.current.buffer.name == path),'%s,%s'%(vim.current.buffer.name, path)
  3280. if path in [G['Report_Inf']['Report_Path'], G['Frame_Inf']['Frame_Path']]:
  3281. need_edit_buffer_file_link = True
  3282. if file_links:
  3283. assert(len(data) == len(file_links))
  3284. else:
  3285. file_links = [ {} for i in range(len(data))]
  3286. # PrintDebug('edit_vim_buffer path_or_name:'+path_or_name)
  3287. # PrintDebug('edit_vim_buffer data:'+data.__str__())
  3288. # PrintDebug('edit_vim_buffer file_links:'+file_links.__str__())
  3289. # PrintDebug('edit_vim_buffer mode:'+mode.__str__())
  3290. # PrintDebug('edit_vim_buffer n:'+n.__str__())
  3291. # PrintDebug('edit_vim_buffer del_range:'+del_range.__str__())
  3292. t_buffer = get_file_vim_buffer(path)
  3293. assert(t_buffer)
  3294. if mode is 'w':
  3295. del t_buffer[:]
  3296. t_buffer.append(data)
  3297. del t_buffer[:1]
  3298. if need_edit_buffer_file_link:
  3299. G["VimBufferLineFileLink"][path] = file_links
  3300. elif mode is 'a':
  3301. t_buffer.append(data)
  3302. if need_edit_buffer_file_link:
  3303. G["VimBufferLineFileLink"].setdefault(path,[])
  3304. G["VimBufferLineFileLink"][path] = G["VimBufferLineFileLink"][path] + file_links
  3305. elif mode is 'b':
  3306. t_buffer.append(data, 0)
  3307. if need_edit_buffer_file_link:
  3308. G["VimBufferLineFileLink"].setdefault(path,[])
  3309. G["VimBufferLineFileLink"][path] = file_links + G["VimBufferLineFileLink"][path]
  3310. elif mode is 'i':
  3311. while len(t_buffer) <= n+1:
  3312. t_buffer.append('')
  3313. if need_edit_buffer_file_link:
  3314. G["VimBufferLineFileLink"][path].append({})
  3315. t_buffer.append(data, n)
  3316. if need_edit_buffer_file_link:
  3317. G["VimBufferLineFileLink"].setdefault(path,[])
  3318. G["VimBufferLineFileLink"][path] = G["VimBufferLineFileLink"][path][:n] + file_links + G["VimBufferLineFileLink"][path][n:]
  3319. elif mode is 'del':
  3320. assert(del_range != () )
  3321. if type(del_range) is int:
  3322. del t_buffer[del_range]
  3323. del G["VimBufferLineFileLink"][path][del_range]
  3324. elif type(del_range) in [ tuple, list ]:
  3325. del t_buffer[del_range[0]:del_range[1]+1]
  3326. del G["VimBufferLineFileLink"][path][del_range[0]:del_range[1]+1]
  3327. else:
  3328. assert(0)
  3329. def go_win( path_or_name = '', pos = (), search_word = ''):
  3330. if not path_or_name:
  3331. return
  3332. # path_or_name = vim.current.buffer.name
  3333. Open(path_or_name)
  3334. if re.search('\w+',search_word):
  3335. vim.current.window.cursor = (1,0) # search from top in case match to left vim warning
  3336. vim.command('/\c\<'+search_word+'\>')
  3337. if pos:
  3338. cursor = (pos[0]+1, pos[1])
  3339. vim.current.window.cursor = cursor
  3340. ############################################################################

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/516724
推荐阅读
相关标签
  

闽ICP备14008679号