Vscode自动生成verilog例化

更新:2020-08-12 14:58:50 修改增加SV语法支持,暂时支持logic、interface,用到别的再改吧。

前言

veirlog模块例化的时候,辣么多的信号端子,手动例化又慢又容易出错,葵花妈妈开课啦,孩子手残老犯错怎么办?

当然是脚本一劳永逸,妈妈再也不担心手残党。

流程

(1)在vscode中安装如下插件。

(2)在电脑中安装python3以上的环境。

下载地址:https://www.python.org/downloads/release/python-373/

安装记得一定要勾选添加路径,记得管理员安装。重启你的电脑。

在cmd窗口输入python即可验证是否安装成功!

(3)安装chardet。为确保插件可用,这个需要安装。

参考链接:https://blog.csdn.net/sinat_28631741/article/details/80483064

方式一   源码按照:    

    第一步:下载压缩文件,例如: 'chardet-3.0.4.tar.gz';

    第二步:解压文件到python安装位置下的‘site-packages’目录下,例如:‘D:python2.7Libsite-packages’;

    第三步:打开终端命令窗口,进入解压的‘chardet’目录下,执行命令:python setup.py install  
(4)修改插件的原始py文件,觉得开发者的py有瑕疵,让帅气的同事重新整了个,把以下代码替换进原始py文件即可。

在打开v文件的vscode下按ctrl+p,输入instance可出现下述界面。

替换此py文件的代码即可。

#! /usr/bin/env python

'''
vTbgenerator.py -- generate verilog module Testbench
generated bench file like this:

        fifo_sc #(
            .DATA_WIDTH ( 8 ),
            .ADDR_WIDTH ( 8 )
        )
         u_fifo_sc (
            .CLK   ( CLK                     ),
            .RST_N ( RST_N                   ),
            .RD_EN ( RD_EN                   ),
            .WR_EN ( WR_EN                   ),
            .DIN   ( DIN   [DATA_WIDTH-1 :0] ),
            .DOUT  ( DOUT  [DATA_WIDTH-1 :0] ),
            .EMPTY ( EMPTY                   ),
            .FULL  ( FULL                    )
        );

Usage:
      python vTbgenerator.py ModuleFileName.v

'''
import random
import re
import sys
from queue import Queue

import chardet


def delComment(Text):
    """ removed comment """
    single_line_comment = re.compile(r"//(.*)$", re.MULTILINE)
    multi_line_comment = re.compile(r"/*(.*?)*/", re.DOTALL)
    Text = multi_line_comment.sub(' ', Text)
    Text = single_line_comment.sub(' ', Text)
    return Text


def delBlock(Text):
    """ removed task and function block """
    Text = re.sub(r'WtaskW[Ww]*?WendtaskW', ' ', Text)
    Text = re.sub(r'WfunctionW[Ww]*?WendfunctionW', ' ', Text)
    return Text


def findName(inText):
    """ find module name and port list"""
    p = re.search(r'([a-zA-Z_][a-zA-Z_0-9]*)s*', inText)
    mo_Name = p.group(0).strip()
    return mo_Name


def paraDeclare(inText, portArr):
    """ find parameter declare """
    pat = r's' + portArr + r's[wW]*?[;,)]'
    ParaList = re.findall(pat, inText)

    return ParaList


def portDeclare(inText, portArr):
    """find port declare, Syntax:
       input [ net_type ] [ signed ] [ range ] list_of_port_identifiers

       return list as : (port, [range])
    """
    port_definition = re.compile(
        r'' + portArr +
        r''' (s+(wire|reg|logic|interface)s+)* (s*signeds+)*  (s*[.*?:.*?]s*)*
        (?P<port_list>.*?)
        (?= input | output | inout | ; | ) )
        ''',
        re.VERBOSE | re.MULTILINE | re.DOTALL
    )

    pList = port_definition.findall(inText)
    t = []
    for ls in pList:
        if len(ls) >= 2:
            t = t + portDic(ls[-2:])
    return t


def portDic(port):
    """delet as : input a =c &d;
        return list as : (port, [range])
    """
    pRe = re.compile(r'(.*?)s*=.*', re.DOTALL)

    pRange = port[0]
    pList = port[1].split(',')
    pList = [i.strip() for i in pList if i.strip() != '']
    pList = [(pRe.sub(r'1', p), pRange.strip()) for p in pList]

    return pList


def formatPort(AllPortList, isPortRange=1):
    PortList = AllPortList

    str = ''
    if PortList != []:
        l1 = max([len(i[0]) for i in PortList])+2
        l3 = max(18, l1)

        strList = []
        str = ', '.join([' ' * 4 + '.' + i[0].ljust(l3)
                          + '(' + (i[0]) + ')' for i in AllPortList])
        strList = strList + [str]

        str = ', '.join(strList)

    return str


def formatDeclare(PortList, portArr, initial=""):
    str = ''

    if PortList != []:
        str = ' '.join([portArr.ljust(4) + '  '+(i[1]+min(len(i[1]), 1)*'  '
                                                  + i[0]) + ';' for i in PortList])
    return str


def formatPara(ParaList):
    paraDec = ''
    paraDef = ''
    if ParaList != []:
        s = ' '.join(ParaList)
        pat = r'([a-zA-Z_][a-zA-Z_0-9]*)s*=s*([wW]*?)s*[;,)]'
        p = re.findall(pat, s)

        l1 = max([len(i[0]) for i in p])
        l2 = max([len(i[1]) for i in p])
        paraDec = ' '.join(['parameter %s = %s;'
                             % (i[0].ljust(l1 + 1), i[1].ljust(l2))
                             for i in p])
        paraDef = '#( ' + ', '.join(['    .' + i[0].ljust(l1 + 1)
                                       + '( ' + i[1].ljust(l2)+' )' for i in p]) + ') '
    return paraDec, paraDef


def portT(inText, ioPadAttr):
    x = {}
    count_list = []
    order_list = []
    for i in ioPadAttr:
        p = port_index_list(inText, i)
        for j in p:
            count_list.append(j)
            x[j] = i
    count_list = quick_sort(count_list, 0, len(count_list)-1)
    for c in count_list:
        order_list.append(x.get(c))
    return order_list


def quick_sort(myList, start, end):
    if start < end:
        i, j = start, end
        base = myList[i]
        while i < j:
            while (i < j) and (myList[j] >= base):
                j = j - 1

            myList[i] = myList[j]

            while (i < j) and (myList[i] <= base):
                i = i + 1
            myList[j] = myList[i]
        myList[i] = base

        quick_sort(myList, start, i - 1)
        quick_sort(myList, j + 1, end)
    return myList


def formatPort_order(padAttr, orderList):

    for p in padAttr:
        q = Queue()
        for i in padAttr.get(p):
            q.put(i)
        padAttr[p] = q
    AllPortList = []
    for o in orderList:
        AllPortList.append(padAttr.get(o).get())
    return AllPortList


def port_index_list(intext, text):
    l = []
    t = intext
    index = t.find(text)
    while index > -1:
        t = t.replace(text, random_str(len(text)), 1)
        l.append(index)
        index = t.find(text)
    return l


def random_str(size):
    s = ''
    for i in range(size):
        s += str(random.randint(0, 9))
    return s


def getPortMap(AllPortList, ioPadAttr):
    if len(AllPortList) != len(ioPadAttr):
        return

    p_map = {}
    for i in range(len(AllPortList)):
        p_map[ioPadAttr[i]] = AllPortList[i]
    return p_map


def writeTestBench(input_file):
    """ write testbench to file """
    with open(input_file, 'rb') as f:
        f_info = chardet.detect(f.read())
        f_encoding = f_info['encoding']
    with open(input_file, encoding=f_encoding) as inFile:
        inText = inFile.read()

    # removed comment,task,function
    inText = delComment(inText)
    inText = delBlock(inText)

    # moduel ... endmodule  #
    moPos_begin = re.search(r'(|^)module', inText).end()
    moPos_end = re.search(r'endmodule', inText).start()
    inText = inText[moPos_begin:moPos_end]

    name = findName(inText)
    paraList = paraDeclare(inText, 'parameter')
    paraDec, paraDef = formatPara(paraList)

    ioPadAttr = ['input', 'output', 'inout','interface']
    orlder = portT(inText, ioPadAttr)
    input = portDeclare(inText, ioPadAttr[0])
    output = portDeclare(inText, ioPadAttr[1])
    inout = portDeclare(inText, ioPadAttr[2])
    interface = portDeclare(inText, ioPadAttr[3])

    portList = formatPort(formatPort_order(
        getPortMap([input, output, inout,interface], ioPadAttr), orlder))

    input = formatDeclare(input, 'reg')
    output = formatDeclare(output, 'wire')
    inout = formatDeclare(inout, 'wire')
    interface = formatDeclare(interface, 'wire')
    # write Instance

    # module_parameter_port_list
    if(paraDec != ''):
        print("// %s Parameters %s " % (name, paraDec))

    # list_of_port_declarations
    #print("// %s Inputs %s " % (name, input))
    #print("// %s Outputs %s " % (name, output))
    #if(inout != ''):
    #    print("// %s Bidirs %s " % (name, inout))
    print(" ")
    # UUT
    print("%s %s inst_%s ( %s );" % (name, paraDef, name, portList))


if __name__ == '__main__':
     writeTestBench(sys.argv[1])

(5)享受一下吧。

比如我们有如下代码:

crtl+p,输入instance,按回车即可。

 复制粘贴大法好。

以上。

原文地址:https://www.cnblogs.com/kingstacker/p/9944259.html