2017-05-18 48 views
0

我是TCL腳本初學者。我正在研究如何將Verilog文件中的數據解析爲xls文件。解析verilog文件中的數據

輸入的Verilog文件包含以下數據:

 
Inferred components 
Operator Signedness Inputs Outputs CellArea Line Col  Filename  
===================================================================================================== 
apn 
u_apn_ttp_logic 
abc 
u_apn_wgt_op_rd_u_apn_sca_u_part_sel1_sl_69_33 
module:shift_right_vlog_unsigned_4662_7709 
very_fast/barrel  >>  x   25x5  25  223.02 69 33 part_select.v 
===================================================================================================== 
apn 
u_apn_ttp_logic 
u_apn_wgt_op_rd_u_apn_scale_u_part_sel1_sub00283545 
module:sub_signed_4513_5538 
very_fast    -  signed  11x24  25  152.80 0 0 a     
===================================================================================================== 

(這是一個長文件...)

最後一節之後,解析將結束:

 
===================================================================================================== 
apn 
u_apn_start_ctrl_final_adder_add_212_41 
module:add_unsigned_carry_882 
very_fast    +  unsigned 32x32x1 32  120.39 212 41 feu_start_ctrl.v 
===================================================================================================== 

我想提取數據如下,考慮第一節

 
Top name=apn 
Instance=u_apn_ttp_logic/abc/u_apn_wgt_op_rd_u_feu_scale_u_part_select1_srl_69_33 
Module = shift_right_vlog_unsigned_4662_7709 
Architecture=very_fast/barrel 
Operator = >> 
Sign=x 
Input Size = 25x5 
Output = 25 
Area = 223.02 
Column = 69 
Row = 33 
File Name = part_select.v 

我在執行此操作時遇到了一些困難。下面

是我相同的方法:輸出topnameinstance

set fd "[open "path_data.v" r]" 
set flag 0 
    while {[gets $fd line] !=-1} { 
     if {[regexp "\===*" $line]} { 
     while {[gets $fd line] >= 0} { 
      append data "$line " 
      if {[regexp "\====*" $line]} { 
       break 
      } } 
set topname [lindex $data 0] 
regexp {(^[a-z]*) (.*) (.*module)} $data match topname instance sub3 
puts "top name :$topname " 
puts "instance: $instance" 

} 

close $fd 

我能夠只,而不是其他值 還請大家幫我提取這些值。

回答

0

有了這種任務,它真的幫助,如果你把任務的部分成只做一個簡單的比特程序。例如,假設我們將單個部分的處理分爲自己的過程。由於它只執行一個部分(大概比整個文件短很多),因此它可以在字符串(或字符串列表)上工作,而不必按行處理,這會使事情更容易理解。

例如,它會處理眼前這個輸入文本:

 
apn 
u_apn_ttp_logic 
abc 
u_apn_wgt_op_rd_u_apn_sca_u_part_sel1_sl_69_33 
module:shift_right_vlog_unsigned_4662_7709 
very_fast/barrel  >>  x   25x5  25  223.02 69 33 part_select.v 

我們可以處理,像這樣:

proc processSection {sectionText} { 
    set top "" 
    set instance "" 
    set module "" 
    set other {} 
    foreach line [split $sectionText "\n"] { 
     if {$top eq ""} { 
      set top [string trim $line] 
      continue 
     } 
     if {$module eq ""} { 
      # This regular expression matches lines starting with 「module:」 and 
      # extracts the rest of the line 
      if {[regexp {^module:(.*)} $line -> tail]} { 
       set module [string trim $tail] 
      } else { 
       append instance [string trim $line] "/" 
      } 
      continue 
     } 
     # This regular expression matches a sequence of non-space characters, and 
     # the -all -inline options make regexp return a list of all such matches. 
     lappend other {*}[regexp -all -inline {\S+} $line] 
    } 
    # Remember to remove trailing 「/」 character of the instance 
    set instance [string trimright $instance /] 

    # Note that this splits apart the list in $other 
    outputSectionInfo $top $instance $module {*}$other 
} 

我們還需要一些東西來產生輸出。我已經將它分解到自己的過程中,因爲將解析與輸出分開通常是很好的。

proc outputSectionInfo {top instance module arch op sgn in out area col row file} { 
    # Output the variables 
    foreach {label varname} { 
     "Top name" top 
     "Instance" instance 
     "Module" module 
     "Architecture" arch 
     "Operator" op 
     "Sign"  sgn 
     "Input Size" in 
     "Output" out 
     "Area"  area 
     "Column" col 
     "Row"  row 
     "File Name" file 
    } { 
     # Normally, best to avoid using variables whose names are in variables, but 
     # for printing out like this, this is actually really convenient. 
     puts "$label = [set $varname]" 
    } 
} 

現在,我們已經有了一個區段處理器和輸出發生器(你可以驗證自己,這些做明智的事情,因爲他們比你試圖要一次做的相當簡單一點),我們只需要將文件中的部分放入它,跳過標題。代碼是這樣的,而只是這樣做。

set fd [open "path_data.v"] 
set flag 0 
while {[gets $fd line] >= 0} { 
    if {[regexp {^=====+$} $line]} { 
     if {$flag} { 
      processSection [string trimright $accumulator "\n"] 
     } 
     set flag 1 
     set accumulator "" 
    } else { 
     append accumulator $line "\n" 
    } 
} 
close $fd 

你眼前的問題是,你的代碼是太早關閉通道,但是這反過來造成你的困惑了壓痕,那就是又引起你試圖做太多一個地方。爲了使代碼更易於理解,將事情分解爲這類問題的解決方案,因爲它可以更容易地告訴代碼是絕對正確的(或者肯定是錯誤的)。

+0

我不確定這是否適用於真實數據,但至少可以更容易地看到出現問題並驗證碎片。 –

+0

嗨多納爾, 感謝您的支持, 我試着用你的代碼,但有錯誤來了,我也試圖與設置第一,如果循環內的標誌, 還請大家幫我理解下面的命令, 「outputSectionInfo $ top $ instance $ module {*} $ other「 – Krishh

0

我在上面的腳本上工作,這裏是我的代碼。如果在「========」行後有空行,此代碼將不起作用

但我想探索您的代碼,因爲它的組織良好。

set fd "[open "path_data.v" r]" 

set fd1 "[open ./data_path_rpt.xls w+]" 
puts $fd1 "Top Name\tInstance\tModule\tArchitecture\tOperator\tSign\tInput Size\tOutput size\tArea\tLine number\tColumn number\tFile Name" 
set data {} 
while {[gets $fd line] !=-1} { 
if {[regexp "\===*" $line]} { 
     set data {}; set flag 0 
     while {[gets $fd line] >= 0} { append data "$line " 
       if {[regexp {[a-z]\.v} $line]} { set flag 1;break} } 
puts "$data\n\n" 
    if {$flag} { 
     set topname [lindex $data 0] 
     regexp {(^[a-z]*) (.*) (.*module\:)(.*)} $data match topname instance sub3 sub4 
     set inst_name {} ; 
     foreach txt $instance { 
     append inst_name "$txt\/" 
     } 
     set instance [string trim $inst_name "\/"] 
     set module [lindex $sub4 0] 
     set architecture [lindex $sub4 1] 
     set operator [lindex $sub4 2] 
     set sign [lindex $sub4 3] 
     set input_size [lindex $sub4 4] 
     set output_size [lindex $sub4 5] 
     set area [lindex $sub4 6] 
     set linenum [lindex $sub4 7] 
     set col_num [lindex $sub4 8] 
     set file_name [lindex $sub4 9] 
     puts $fd1 "$topname\t$instance\t$module\t$architecture\t$operator\t$sign\t$input_size\t$output_size\t$area\t$linenum\t$col_num\t$file_name" 
     set data {} ; set flag 0 
}} 
} 
close $fd1 
close $fd