1#!/usr/local/bin/tclsh8.6 2# 3# Usage: 4# blif2sim.tcl <blif_filename> <dir> [<sim_filename>] 5# 6# If cel_filename is not specified, then name will be the root name 7# of the .blif file with the .sim extension. 8# 9# "dir" is the directory where .sim views of the standard cells are 10# located. If .sim views are not available but .mag files are, the 11# .sim files will be generated automatically. 12# 13#------------------------------------------------------------ 14# Written by Tim Edwards February 12, 2007 15# MultiGiG, Inc. 16#------------------------------------------------------------ 17 18set bliffile [lindex $argv 0] 19set cellname [file rootname $bliffile] 20if {"$cellname" == "$bliffile"} { 21 set bliffile ${cellname}.blif 22} 23 24set prefix "" 25if {$argc > 2} { 26 if {[lindex $argv [expr {$argc - 2}]] == "-prefix"} { 27 set prefix [lindex $argv [expr {$argc - 1}]]/ 28 incr argc -2 29 } 30} 31 32if {$argc > 1} { 33 set magdir [lindex $argv 1] 34} else { 35 set magdir /home/tim/projects/multigig/digital_flow/layout/digital2 36} 37 38if {$argc == 3} { 39 set simfile [lindex $argv 2] 40} else { 41 set simfile ${cellname}.sim 42} 43 44set scriptdir [file dirname $argv0] 45 46#------------------------------------------------------------- 47# Open files for read and write 48 49if [catch {open $bliffile r} fnet] { 50 puts stderr "Error: can't open file $bliffile for reading!" 51 exit 0 52} 53 54#---------------------------------------------------------------- 55# First, parse the contents of the .blif file and get a list 56# of all macro names used. 57#---------------------------------------------------------------- 58 59puts stdout "1st pass of blif file ${bliffile}. . ." 60flush stdout 61 62set macrolist {} 63while {[gets $fnet line] >= 0} { 64 if [regexp {^INSTANCE[ \t]+"([^"]+)"} $line lmatch macro] { 65 lappend macrolist $macro 66 } 67} 68set macrolist [lsort -unique $macrolist] 69close $fnet 70 71set needsims {} 72foreach macro $macrolist { 73 if {[glob -nocomplain ${magdir}/${macro}.sim] == {}} { 74 lappend needsims ${macro} 75 } elseif {[file size ${magdir}/${macro}.ext] == 0} { 76 lappend needsims ${macro} 77 } 78} 79 80if {$needsims != {}} { 81 puts stdout "Generating .sim views. . ." 82 flush stdout 83 84 foreach macro $needsims { 85 puts stdout "Generating ${macro}.sim" 86 flush stdout 87 catch {exec ${scriptdir}/makesim.sh ${magdir}/$macro} 88 } 89} 90 91if [catch {open $simfile w} fsim] { 92 puts stderr "Error: can't open file $simfile for writing!" 93 exit 0 94} 95 96puts $fsim "| SIM file $simfile generated by blif2sim" 97 98#---------------------------------------------------------------- 99# Procedure to dump the contents of a subcircuit .sim file to the 100# top-level .sim file, replacing pin names with net names. 101#---------------------------------------------------------------- 102 103proc dump_sim {fsim mode magdir prefix} { 104 105 # Pick up variable definition from top-level 106 upvar $mode mname 107 108 # Make VDD, VSS, and GND show up as globals 109 set mname(VDD) VDD 110 set mname(VDD!) VDD 111 set mname(VSS) VSS 112 set mname(VSS!) VSS 113 set mname(GND) GND 114 set mname(GND!) GND 115 116 set fsub [open ${magdir}/${mode}.sim r] 117 while {[gets $fsub line] >= 0} { 118 set mtype [string index $line 0] 119 120 # Parse .sim file lines. Ignore lumped "R", which is not used by IRSIM. 121 122 switch -exact $mtype { 123 n - 124 p { regexp {^[pn] ([^ ]+) ([^ ]+) ([^ ]+) (.*)} $line valid \ 125 gate drain source rest 126 puts -nonewline $fsim "$mtype " 127 if {[catch {puts -nonewline $fsim "${prefix}$mname(${gate}) "}]} { 128 puts -nonewline $fsim "${prefix}${mode}$mname(count)/$gate " 129 } 130 if {[catch {puts -nonewline $fsim "${prefix}$mname(${drain}) "}]} { 131 puts -nonewline $fsim "${prefix}${mode}$mname(count)/$drain " 132 } 133 if {[catch {puts -nonewline $fsim "${prefix}$mname(${source}) "}]} { 134 puts -nonewline $fsim "${prefix}${mode}$mname(count)/$source " 135 } 136 puts $fsim $rest 137 } 138 r { regexp {^r ([^ ]+) ([^ ]+) (.*)} $line valid r1 r2 rest 139 puts -nonewline $fsim "r " 140 if {[catch {puts -nonewline $fsim "${prefix}$mname(${r1}) "}]} { 141 puts -nonewline $fsim "${prefix}${mode}$mname(count)/$r1 " 142 } 143 if {[catch {puts -nonewline $fsim "${prefix}$mname(${r2}) "}]} { 144 puts -nonewline $fsim "${prefix}${mode}$mname(count)/$r2 " 145 } 146 puts $fsim $rest 147 } 148 C { regexp {^C ([^ ]+) ([^ ]+) (.*)} $line valid top bottom rest 149 puts -nonewline $fsim "C " 150 if {[catch {puts -nonewline $fsim "${prefix}$mname(${top}) "}]} { 151 puts -nonewline $fsim "${prefix}${mode}$mname(count)/$top " 152 } 153 if {[catch {puts -nonewline $fsim "${prefix}$mname(${bottom}) "}]} { 154 puts -nonewline $fsim "${prefix}${mode}$mname(count)/$bottom " 155 } 156 puts $fsim $rest 157 } 158 | { puts $fsim $line } 159 } 160 } 161 close $fsub 162} 163 164#---------------------------------------------------------------- 165# Parse the contents of the .blif file again and dump each cell 166# instance to the .sim file output. 167 168puts stdout "2nd pass of blif file. . ." 169flush stdout 170 171set fnet [open $bliffile r] 172set mode none 173while {[gets $fnet line] >= 0} { 174 if [regexp {^INSTANCE[ \t]+"([^"]+)"[ \t]*:[ \t]*"([^"]+)"} $line \ 175 lmatch macroname macrotype] { 176 # New instance. First dump the current instance to the sim file 177 if {$mode != "pins" && $mode != "none"} { dump_sim $fsim $mode $magdir $prefix} 178 179 # (There is now a valid mag/ext/sim file for TIELO and TIEHI) 180 # if [string equal $macroname TIELO] {gets $fnet line; continue} 181 # if [string equal $macroname TIEHI] {gets $fnet line; continue} 182 set mode $macroname 183 if {[catch {incr ${mode}(count)}]} {set ${mode}(count) 0} 184 } elseif [regexp {^ENDMODEL} $line lmatch] { 185 # Dump last "mode" output 186 if {$mode != "pins"} { dump_sim $fsim $mode $magdir $prefix} 187 } elseif [regexp {^INPUT} $line lmatch] { 188 set mode "pins" 189 } elseif [regexp {^OUTPUT} $line lmatch] { 190 set mode "pins" 191 } elseif [regexp {^MODEL[ \t]+"([^"]+)"} $line lmatch cellverify] { 192 if {"$cellname" != "$cellverify"} { 193 puts -nonewline stderr "WARNING: MODEL name ${cellverify} does not" 194 puts stderr " match filename ${cellname}!" 195 } 196 } elseif {"$mode" == "pins"} { 197 if [regexp {"([^"]+)"[ \t]*:[ \t]*"([^"]+)"} $line lmatch pinname netname] { 198 # Don't do anything with these. 199 } 200 } else { 201 # In the middle of parsing an instance; mode = instance name (in lowercase). 202 if [regexp {"([^"]+)"[ \t]*:[ \t]*"([^"]+)"} $line lmatch pinname netname] { 203 set ${mode}(${pinname}) $netname 204 } 205 } 206} 207# Dump the final instance to the sim file, if there was one. 208if {$mode != "pins" && $mode != "none"} { dump_sim $fsim $mode $magdir $prefix} 209close $fnet 210 211puts stdout "Done!" 212