verilog模块自动例化perl脚本
生活随笔
收集整理的這篇文章主要介紹了
verilog模块自动例化perl脚本
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
利用perl寫了個自動生成verilog例化腳本,原理就是利用正則表達式瘋狂匹配就可以🌝,O(∩_∩)O。
- 對兩種端口定義都能自帶生成例化模板。
- 切記一定要在代碼沒有語法錯誤的情況下使用!切記一定要在代碼沒有語法錯誤的情況下使用!切記一定要在代碼沒有語法錯誤的情況下使用!
其他可以使用,需要perl安裝環境,去官網安裝,perl官網。
測試模塊
module TestModuleOne#(parameter PARA1 = 123,parameter PARA2 = 123) (input aport1,input aport2,input aport3,aport4,aport5,aport6,input [PARA1-1:0] aport7,output [PARA2-1:0] aport8,aport9,aport10 );endmodulemodule TestModuleTwo (input bport1,input bport2,input bport3,bport4,bport5,bport6,input [99-1:0] bport7,output [99-1:0] bport8,bport9,bport10 );endmodule測試結果
可以在源碼1-5行修改空格的個數,參考上圖,自己根據需要修改空格數。
使用方法
- 假設inst.pl,里面是例化腳本源碼, test.v是需要例化的verilog代碼
- 在命令行輸入以下命令
就可以看到例化模塊的文件,叫moduleinstance.v,若想直接打印到控制臺,將7行用#注釋掉即可。
例化腳本源碼
$table = 4; $paradefinterval = 4; $parainstinterval = 4; $wireinterval = 4; $portinterval = 10; open STDIN,'<:encoding(GB2312)'; open STDOUT,'>:encoding(GB2312)',"moduleinstance.v"; $flagmc = 0; while($_ = <>) {chomp $_;$line = $_;while($line){if(($line =~/^([^\/]*)\/\/(.*)/)&&$find_other) #首先匹配//{$str.=${1}; last;}elsif(($line =~/^([^\/]*)\/\*(.*)/)&&$find_other) #首次匹配/*{$str.=${1};$rest = ${2}; if($rest=~/(.*)\*\/(.*)/) #本行匹配到*/ {$line = ${2};$find_other = 1;}else #需要在其他行匹配到*/ {$find_other = 0;last;}}elsif(!$find_other){#print "$line two\n";if($line=~/(.*)\*\/(.*)/) #本行匹配到*/ {$line = ${2};$find_other = 1;}else #其他行匹配到*/ last;} else{$str.=$line;last;} } #arg $moduleconut; # 發現module個數 print "module moduleinstance();\n"; while( $str =~ /^.*?(module.*?endmodule)/s) {my @paraname; #參數名字my @paravalue; #參數valuemy @portname; #端口名字my @portdef; #端口定義my $modulename; #模塊名字my @port; #一系列端口名字列表$moduleconut++;$nextstr = $'; #下一個模塊字符串$str = ${1}; #當前模塊字符串$str=~ /\s+ #空白(?<modulename>\w+?) #模塊名(?:\s*?) #可能的空白(?<isparam>\(|\#) # # or ((?<rest>.+?\);)/x; $modulename = $+{modulename};$perhapsuse = $';if($+{isparam} eq "\#") #匹配具有paramter參數列表{$+{rest} =~ /(^\s*?) # (\() #( (?<rest>.*?) #中間字符(\)) #)/x; @para = split /,/,$+{rest} ;foreach $t (@para){if($t =~ /^(\s*?)(\w+)(\s+)(?<paraname>\w+?)(\s*?)=/x){push @paraname,$+{paraname};$' =~ /\s*?(?<paravalue>\w+)\s*?/;push @paravalue,$+{paravalue};} }$rest = $';}else{$rest = "\(".$+{rest};}$rest =~/\s*\((.+)\)\s*/; $port = ${1}."output"; #提取端口名unless($rest=~/input|output|inout/) #另一種端口定義方式{ #從端口中恢復$rest = undef; while($perhapsuse =~/^.*?(input|output|inout)(.*?);/s){$perhapsuse = $';$rest .= "${1} ${2}";} $port = $rest."output"; #補充一個使得兩個兩個分割} $port =~ s/wire|reg//g; #去掉wire reg定義while($port=~ /^.*?(?:input|output|inout)(.*?)(input|output|inout)/s) #分割port{push @port,${1};$port = ${2}.$';}foreach $t (@port){$t =~ s/\s+//g; #去除空白$flag = ($t=~/\s*?(\[\s*?.+?\s*?\])/)?1:0; #匹配[]if($flag){push @portdef, ${1}; $t = $'; }else{push @portdef, undef; #一位寬的為undef}@_ = split /,/,$t ; #分割,push (@portname,@_);for($i = 0;$i<$#_;$i++){push @portdef, $flag?${1}:undef; }}#打印模塊paramter定義信息 $parabeforespace = "%$table"."s";$paranamemaxlen = &maxlength(@paraname);for($i=0;$i<=$#paraname;$i++){ $s1 = "%$paradefinterval"."s";$s2 = $paranamemaxlen-length(@paraname[$i])+1;$s2 = "%$s2"."s";printf ("$parabeforespace"."parameter$s1%s$s2=$s1%s;\n"," "," ",@paraname[$i]," "," ",@paravalue[$i]);}#打印模塊wire定義信息 $portdefmaxlen = &maxlength(@portdef);$wirespacelen = 2*$wireinterval + $portdefmaxlen;$wirespacelen = "%$wirespacelen"."s"; $lr = "%$wireinterval"."s"; $beforespace = "%$table"."s";for($i=0;$i<=$#portname;$i++){ unless($portdef[$i]){ printf ("$beforespace"."wire$wirespacelen%s;\n"," "," ",$portname[$i]);}else{$fill = $portdefmaxlen - length($portdef[$i]);$fill = "%$fill"."s"; printf ("$beforespace"."wire$lr%s$fill$lr%s;\n"," "," ",$portdef[$i],""," ",$portname[$i]);}}printf $modulename." ";#打印模塊paramter例化信息 if(@paraname){print "#(\n";for($i=0;$i<=$#paraname;$i++){ $paraendspace = $paranamemaxlen-length($paraname[$i])+ 1;$parainterspace = $paranamemaxlen-length($paraname[$i])+$parainstinterval;$portendspace = "%$paraendspace"."s";$parainterspace = "%$parainterspace"."s";printf ("$beforespace.%s$parainterspace( %s$portendspace)%s\n"," ",$paraname[$i]," ",$paraname[$i]," ",($i==$#paraname)?"":",");}print ")";}#打印模塊wire例化信息 print $modulename,"_inst(\n";$portnamemaxlen = &maxlength(@portname);for($i=0;$i<=$#portname;$i++){ $portinterspace = $portnamemaxlen-length($portname[$i])+$portinterval;$portinterspace = "%$portinterspace"."s";$portendspace = $portnamemaxlen-length($portname[$i])+1;$portendspace = "%$portendspace"."s";printf ("$beforespace.%s$portinterspace( %s$portendspace)%s\n"," ",$portname[$i]," ",$portname[$i]," ",$i==$#portname?"":",");}print ");\n";$str = $nextstr; } print "endmodule\n"; sub maxlength{$maxlen = 0;foreach my $t (@_){if(length($t)>$maxlen){$maxlen = length($t);}}$maxlen; }總結
以上是生活随笔為你收集整理的verilog模块自动例化perl脚本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [html] DOM节点的种类有哪些?
- 下一篇: 前端学习(3020):vue+eleme