美文网首页ASIC DV
Python脚本辅助快速verilog例化

Python脚本辅助快速verilog例化

作者: sarai_c7eb | 来源:发表于2019-11-02 15:43 被阅读0次

verilog coding过程中,经常需要调用其他module,业内俗称“例化”(instance)。
根据module的信号列表一行行的敲代码确实不是个事,本文提供一套python脚本,可以一键式完成例化工作,从而提高效率;

  1. Python 代码(python2.7)
    新建名字为inst文件,输入如下code:
#!/usr/bin/python
import sys
import re
 
#global parameter max length
maxlen=0
maxbw =0

#global match mode
comment_pt=r'^\s*\/\/'
cmatch    =re.compile(comment_pt)

module_pt =r'module\s+(\w+)'
mmatch    =re.compile(module_pt)

parameter_pt=r'parameter\s*(\w+)\s*=.*'
pmatch      =re.compile(parameter_pt)

signal_pt =r'(output|input|inout)\s*(wire|reg|\s)\s*(\[.*?:.*?\]|\s)\s*(\w+)\s*[,; \n]'
smatch    =re.compile(signal_pt)

end_pt    = r'^\s*endmodule'
ematch    = re.compile(end_pt)

#caculate the max length
def calc_maxlen(rtlfile):
    global maxlen
    global maxbw
    global pmatch
    global smatch
    test=open(rtlfile)
    while True:
        line=test.readline()
        if not line:
            break
        if pmatch.findall(line):
            p_tmp=pmatch.findall(line)[0]
            if len(p_tmp)>maxlen:
                maxlen=len(p_tmp)
        if smatch.findall(line):
            s_tmp=smatch.findall(line)[0]
            if len(s_tmp[3])>maxlen:
                maxlen=len(s_tmp[3])
            if len(s_tmp[2].replace('/t',''))>maxbw:
                maxbw=len(s_tmp[2].replace('/t',''))

def igen(rtlfile):
    global maxlen
    global maxbw 
    global cmatch
    global mmatch
    global pmatch
    global smatch
    global ematch
    params=[]
    sigs  =[]
    start =0
    end   =0
    md_name=''
    ins_name='U_'+md_name

    file=rtlfile
    test=open(file)
    while True:
        line=test.readline()
        if not line:
            break

        comment_mc=cmatch.match(line)
        module_mc =mmatch.match(line)
        end_mc    =ematch.match(line)

        if comment_mc:
            pass
        elif module_mc:
            md_name=module_mc.group(1)
            start=1
        elif end==1:
            start=0
            break
        if pmatch.findall(line) and start==1:
            p_tmp=pmatch.findall(line)[0]
            params.append(p_tmp)
        if smatch.findall(line) and start==1:
            s_tmp=smatch.findall(line)[0]
            sigs.append(s_tmp)
        if end_mc:
            end=1
    test.close

    ins_name='U_'+md_name.upper()

    #print head
    head_fmt0='/'*2+'-'*58
    head_fmt1='/'*2+'-'*4+' INSTANCE OF '+md_name

    print head_fmt0
    print head_fmt1
    print head_fmt0

    #print output wire
    for sig in sigs:
        #if sig[3][:3]=='clk' or sig[3][:3]=='rst':
        #    new_sig3=sig[3]
        #elif sig[3][-2:]=='_i' or sig[3][-2:]=='_o':
        #    new_sig3=sig[3][:-2]+'_s'
        #else:
        #   new_sig3=sig[3]
        new_sig3=sig[3]

        if sig[0]=='output' or sig[0]=='inout':
            print "wire"+" "*4+\
                  "%-*s "%(maxbw,sig[2].replace('/t',''))+\
                  " "*4+\
                  "%-*s;"%(maxlen,new_sig3)
    
    #print module name
    if len(params)==0:
        print "%-s %-s("%(md_name,ins_name)
    else:
        print "%-s #("%md_name
    
    #print instance of parameter
    if len(params)==0:
        pass
    else:
        for param in params:
            if params[len(params)-1]==param:
                sp_param=")"
            else:
                sp_param=","
            print "    .%-*s (%-*s )%s"%\
            (maxlen,param,maxlen,param,sp_param)
    
    #print instance name
    if len(params)==0:
        pass
    else:
        print ins_name+' ('
    
    #print input and output signals
    for sig in sigs:
        if sigs[len(sigs)-1]==sig:
            sp_sig=' '
        else:
            sp_sig=','
        if sigs[0]=='inout':
            dirtag='io'
        else :
            dirtag=sig[0][0]

        #if sig[3][:3]=='clk' or sig[3][:3]=='rst':
        #    new_sig3=sig[3]
        #elif sig[3][-2:]=='_i' or sig[3][-2:]=='_o':
        #    new_sig3=sig[3][:-2]+'_s'
        #else:
        #    new_sig3=sig[3]
        new_sig3=sig[3]
        print "    .%-*s (%-*s )%s //%s,%-*s"%\
                (maxlen,sig[3],\
                 maxlen,new_sig3,\
                 sp_sig       ,\
                 dirtag,maxbw ,\
                 sig[2].replace('/t',''))
    
    #print end
    print ");"
    print ""
    
#run the program
if len(sys.argv)<2:
    print "ERROR USEAGE"
else:
    for aidx in range(1,len(sys.argv)):
        calc_maxlen(sys.argv[aidx])
    for aidx in range(1,len(sys.argv)):
        igen(sys.argv[aidx])

整体思路是打开verilog module file,一般一个module一个file,这在许多公司都是规范;然后提取parameter/input/output 信号名称,位宽等信息,然后再在当前file打印;

  1. 调用方法
    将inst放入/home/bin下,并确保/home/bin加入到path中。
    在gvim coding过程中,在需要插入instance的位置输入如下命令即可;
:!r inst xxxx.v

3.存在的问题

  • 默认连线名称与信号接口名称一致,如不一致,利用其它工具删除,并重新连接;
  • 很好的支持verilog2001,对verilog1998效果没有2001好;

<end and enjoy yourself>

相关文章

网友评论

    本文标题:Python脚本辅助快速verilog例化

    本文链接:https://www.haomeiwen.com/subject/tvthbctx.html