利用python自动生成verilog模块例化模板

  一、前言
 
  初入职场,一直忙着熟悉工作,就没什么时间更新博客。今天受“利奇马”的影响,只好宅在家中,写写技术文章。芯片设计规模日益庞大,编写脚本成了芯片开发人员必要的软技能。模块端口动不动就几十上百个,手动编写代码伤不起。实现verilog模块例化模板的自动生成也算是我自砸饭碗的第一步了O(∩_∩)O!
 
  二、代码设计
 
  要自动生成模块例化模板总共分三步:1打开设计文件,读取内容2正则匹配3打开指定上层文件,写入例化模板。涉及到的知识点主要有文件读写和正则匹配。该脚本分别用两个表达式匹配模块名称和端口列表,之后把两者按照verilog模块例化的代码规则写入到指定文件。具体细节上代码之后再说:
 
  1#!/usr/bin/python
 
  2
 
  3importre
 
  4importos
 
  5
 
  6#regexcompile
 
  7regex_module=re.compile('(module)(s+)(w+)')
 
  8
 
  9regex_ports=re.compile('''
 
  10(input|output)#0
 
  11(s+)#1
 
  12(wire|regs+)?#2
 
  13([w+-1:0]s+)?#3
 
  14(w+)#4
 
  15''',re.VERBOSE)
 
  16
 
  17directory=os.getcwd()
 
  18#openthedesignfile
 
  19file_design=input('Pleaseenterthefilename:')
 
  20withopen(directory+'/'+file_design,'r')asfile_obj:
 
  21comment=file_obj.read()
 
  22
 
  23#regexmatchmodulename
 
  24module_obj=regex_module.search(comment)
 
  25print(module_obj.group())
 
  26#regexmatchportsname
 
  27groups_ports=regex_ports.findall(comment)
 
  28print('nnumberofports:',len(groups_ports))
 
  29
 
  30#writetheinstantiationtempletetoanassignedfile
 
  31file_tb=input('Pleaseenterthetopfilename:')
 
  32withopen(directory+'/'+file_tb,'a')asfile_obj2:
 
  33ifmodule_objisnotNone:
 
  34file_obj2.write(module_obj.group(3)+'uutn(n')
 
  35
 
  36num=len(groups_ports)
 
  37foriinrange(num):
 
  38ifi==num-1:
 
  39file_obj2.write('.'+groups_ports[i][4]+'()n')
 
  40else:
 
  41file_obj2.write('.'+groups_ports[i][4]+'(),n')
 
  42file_obj2.write(');n')
 
  python_inst.py
 
  python的文件读写非常简洁,使用withopen打开可以确保在合适的时候自动关闭文件,防止数据受损丢失。为了保证代码通用性,使用os.getcwd获取当前脚本所在路径,这样改动路径时不需要再次修改代码即可照常运行。至于正则匹配在之前的博文:python中正则表达式与模式匹配-没落骑士-博客https://www.cnblogs.com/moluoqishi/p/10825221.html中已经描述的比较详尽了,这里不再赘述。有一点需要注意,search和findall返回的数据结构不同,依次是匹配对象和匹配内容列表。
 
  三、运行结果
 
  最后我们来看下运行结果。命令行:
 
  设计源文件及写入文件:
 
  脚本正确生成设计模块的例化模板,后续再进一步优化。