TCL is very important from automation point of view in VLSI Industry but students are lacking bigtime. Even if they learn, they face problem to understand the uses of TCL in VLSI Industry. In these series of articles, I am listing down few of the small projects or say programs or say exercise which can help anyone to understand the use-model of TCL in Industry. As a fresher, if you try at least once, it will boost your confidence. If you are able to automate below few task, more then 50% of work (based on TCL) can be done easily.
This is second part. If you have missed first part, please visit it (TCL Practice Task 1). Because to understand this Task, you should have Task 1 program handy. :)
If you have completed previous task (task 1), I am sure now you are good in file handling.
Task 2:- Mapping Two Files
Step 1: Create 2 Input files ("file_input1.txt" and "file_input2.txt")
Content of "file_input1.txt" is same as in the previous Task. So, you can copy file from last program. Snapshot of both the files are present below.
Input File: “file_input1.txt”
Input File: “file_input2.txt”
Step 2: Reuse TCL Program of Task 1 and convert into procedure or procedures.
Step 3: Write a TCL program, where you will read both input files "file_input1.txt" & "file_input2.txt" and as per the CELL name present in second file (e.g. AND1_2X ...), you have to extract below data and display it in the below format.
Total Delay = Delay of Cell + Delay of Previous stage
So, in our case,
Delay of AND1_2X = 1.50ns + 0ns = 1.50ns
Delay of AND2_3X = 2.37ns + 1.50ns = 3.87ns
Delay of AND2_4X = 1.82ns + 3.87ns = 5.69ns
Delay of NAND2_3X = 2.48ns + 5.69ns = 8.17ns
Note:
Step 4: Print the above formated data onto the terminal & in output file "file_output2.txt"
Learning after this Program:
Industrial Use of this Task:
Most of the time, we work on automation of data in Industry.This data present in the form of report file (.rpt file) or output file or may be logfile. After reading data, we have to do a lot of operation (mathematically) and has to represent the data as per our requirement.
For example,
I am sure this article will help you. In the Next article, we will discuss about a task where you have to take inputs from user in runtime (means during the execution of Program).
This is second part. If you have missed first part, please visit it (TCL Practice Task 1). Because to understand this Task, you should have Task 1 program handy. :)
If you have completed previous task (task 1), I am sure now you are good in file handling.
Task 2:- Mapping Two Files
Step 1: Create 2 Input files ("file_input1.txt" and "file_input2.txt")
Content of "file_input1.txt" is same as in the previous Task. So, you can copy file from last program. Snapshot of both the files are present below.
Input File: “file_input1.txt”
Name Delay Trans Load
---------------------------------------------
AND1_2X 1.50ns 0.1 1.25ff
AND1_3X 1.75ns 0.2 1.98ff
AND2_3X 2.37ns 0.3 2.27ff
AND2_4X 1.82ns 0.5 2.54ff
NAND1_2X 2.14ns 0.2 1.69ff
NAND2_3X 2.48ns 0.3 2.11ff
---------------------------------------------
AND1_2X 1.50ns 0.1 1.25ff
AND1_3X 1.75ns 0.2 1.98ff
AND2_3X 2.37ns 0.3 2.27ff
AND2_4X 1.82ns 0.5 2.54ff
NAND1_2X 2.14ns 0.2 1.69ff
NAND2_3X 2.48ns 0.3 2.11ff
Input File: “file_input2.txt”
CELL_1: AND1_2X
CELL_2: AND2_3X
CELL_3: AND2_4X
CELL_4: NAND2_3X
CELL_2: AND2_3X
CELL_3: AND2_4X
CELL_4: NAND2_3X
Step 2: Reuse TCL Program of Task 1 and convert into procedure or procedures.
Step 3: Write a TCL program, where you will read both input files "file_input1.txt" & "file_input2.txt" and as per the CELL name present in second file (e.g. AND1_2X ...), you have to extract below data and display it in the below format.
Name Trans Load Delay Total_Delay
----------------------------------------------------------------------------
AND1_2X 0.1 1.25ff 1.50ns 1.50ns
AND2_3X 0.3 2.27ff 2.37ns 3.87ns
AND2_4X 0.5 2.54ff 1.82ns 5.69ns
NAND2_3X 0.3 2.11ff 2.48ns 8.17ns
----------------------------------------------------------------------------
AND1_2X 0.1 1.25ff 1.50ns 1.50ns
AND2_3X 0.3 2.27ff 2.37ns 3.87ns
AND2_4X 0.5 2.54ff 1.82ns 5.69ns
NAND2_3X 0.3 2.11ff 2.48ns 8.17ns
Total Delay = Delay of Cell + Delay of Previous stage
So, in our case,
Delay of AND1_2X = 1.50ns + 0ns = 1.50ns
Delay of AND2_3X = 2.37ns + 1.50ns = 3.87ns
Delay of AND2_4X = 1.82ns + 3.87ns = 5.69ns
Delay of NAND2_3X = 2.48ns + 5.69ns = 8.17ns
Note:
- All the above calculations, you have to do with in TCL Program.
- You have to reuse TCL program of Task 1.
- Reading of File "file_input1.txt" should be with the help of previous program only.
- Rearranging the data should be using previous program.
- Writing data should be as per previous program.
Step 4: Print the above formated data onto the terminal & in output file "file_output2.txt"
Learning after this Program:
- How to Open & Close 2 Input files simultaneously
- How to Read or Write from/in a file
- How to save data in List and do different operation on that
- How to do Matching or say comparison of Data
- How to select only a specific data
- How to do mathematical calculations
- Different commands use-model
- list, lindex, lappend
- Foreach loop, While loop, If-else loop
- gets and puts
- split
- expr
- incr
- How to manage single space, multiple space
- Regular expression concepts
- Procedure concepts (proc in tcl)
- How to write a Procedure
- How to pass a value to Procedure
- How to call a Procedure
- How to get return from a Procedure (return command)
Industrial Use of this Task:
Most of the time, we work on automation of data in Industry.This data present in the form of report file (.rpt file) or output file or may be logfile. After reading data, we have to do a lot of operation (mathematically) and has to represent the data as per our requirement.
For example,
- Timing Report have a lot of information about several Timing paths. You may have to create a automation to find out only slack of specific paths mentioned in other file.
- SPEF file has C (cap) information of Nets. You want to compare 2 SPEF files of same design generated after making certain changes in design. This type of automation create a final report of Delta Cap for all Nets present in either SPEF file. Analysis of this final report (created after automation) may help you to fix design issues.
I am sure this article will help you. In the Next article, we will discuss about a task where you have to take inputs from user in runtime (means during the execution of Program).
-By Rajat Bansal
(Btech-EC:- 2019 Passout)
(ABES Engineering College)
-Supervised By Puneet Mittal
(Founder & Director)
(VLSI Expert Private Limited)
(Btech-EC:- 2019 Passout)
(ABES Engineering College)
-Supervised By Puneet Mittal
(Founder & Director)
(VLSI Expert Private Limited)
Mail me at 14294.abhishek@gmail.com for the script. Was not able to post it here!
ReplyDeletePART1
ReplyDeleteproc read_file {file_name} {
set fp_infile [open "$file_name" r]
set file_data [read $fp_infile]
close $fp_infile
return $file_data
}
proc read_cell {cell_index file2_data_split} {
while {$cell_index != 4} {
#
#read the ith cell from file_input2
#
set cell [lindex $file2_data_split $cell_index]
#puts $cell
regexp {([A-Z0-9_:]+) ([A-Z0-9_]+)} $cell match_var sub_cell sub_gate
return $sub_gate
} ;# while
} ;# proc
proc get_data_from_fileinput1 {array_to_list x} {
#find_in_fileinput1 $cell_index $array_to_list
#while {$cell_index != 4} {
#
#find the cell name in file_input1
#
#set file_input1_data [array get row]
#puts $array_to_list
set match_cell [lsearch -all -inline -regexp $array_to_list "^$x"]
set split_match_cell [split $match_cell " "]
#puts $split_match_cell
regexp {[NAND]+} $split_match_cell found
if {$found == "NAND"} {
set col1 [lindex $split_match_cell 5]
set col2 [lindex $split_match_cell 11]
set col3 [lindex $split_match_cell 15]
set mylist [list $col1 $col2 $col3]
#puts $mylist
} else {
set col1 [lindex $split_match_cell 6]
set col2 [lindex $split_match_cell 12]
set col3 [lindex $split_match_cell 16]
set mylist [list $col1 $col2 $col3]
#puts $mylist
}
#set arrange [lsort -ascii $mylist]
#puts $arrange
#set trans_value [lindex $arrange 0]
#set load_value [lindex $arrange 1]
#set delay_value [lindex $arrange 2]
set delay_value [lsearch -all -inline -regexp $mylist "ns*"]
set trans_value 0
regexp {[0-9.]*} $mylist trans_value
set load_value [lsearch -all -inline -regexp $mylist "ff*"]
#puts [format "%-12s" "%-9s" "%-9s" "%-9s" $x $trans_value $load_value $delay_value]
set arranged_cell_values [list $x $trans_value $load_value $delay_value]
#puts $arranged_cell_values
return $arranged_cell_values
#} ;#findinfileinput1 while
} ;#proc
PART2
ReplyDeleteproc total_delay_calc {got_data_from_fileinput1 old_delay} {
#upvar $old_delay ref_old_delay
#global old_delay
set convert_to_list [split $got_data_from_fileinput1 " "]
#puts $convert_to_list
#puts "hello $old_delay"
set match_and [lsearch $convert_to_list "D"]
#puts $match_and
set current_delayns [lindex $convert_to_list 3]
set current_delay 0
regexp {[0-9.]+} $current_delayns current_delay
#puts $current_delay
set total_delay [expr ($current_delay + $old_delay)]
set old_delay $total_delay
set delays [list $total_delay $old_delay]
#puts $delays
return $delays
}
#
#displays the info in modified way
#
proc add_total_delay_to_row {array_to_list tot_delay_1 got_data_from_fileinput1
} {
#puts $array_to_list
#puts $got_data_from_fileinput1
#puts $tot_delay_1
set new_row [split $got_data_from_fileinput1 " "]
#puts $new_row
#set dummy [lindex $new_row 13]
#puts $dummy
#puts $new_row
regexp {[NAND]+} $new_row found
if {$found == "NAND"} {
#puts "hello $new_row"
set row_list_dummy [lindex $new_row 0]
regexp {[A-Z0-9_]+} $row_list_dummy row_list(0)
set row_list(1) [lindex $new_row 1]
set row_list(2) [lindex $new_row 2]
set row_list(3) [lindex $new_row 3]
set ns ns
set tot_delay_1 "$tot_delay_1 $ns"
set tot_delay_1_ns [join $tot_delay_1 ""]
} else {
set row_list_dummy [lindex $new_row 0]
regexp {[A-Z0-9_]+} $row_list_dummy row_list(0)
set row_list(1) [lindex $new_row 1]
set row_list(2) [lindex $new_row 2]
set row_list(3) [lindex $new_row 3]
set ns ns
set tot_delay_1 "$tot_delay_1 $ns"
set tot_delay_1_ns [join $tot_delay_1 ""]
}
set formatted_row [format "%-12s %-9s %-9s %-9s %-9s" $row_list(0) $row_list(1) $row_list(2) $row_list(3) $tot_delay_1_ns]
return $formatted_row
}
proc write_in_out {fp_outfile row_cell} {
puts $fp_outfile
puts $fp_outfile $row_cell
}
if {[catch {open "file_input1.txt"} file_input1_id] && [catch {open "file_input2.txt"} file_input2_id]} {
puts "error1: $file_input1_id"
puts "error2: $file_input2_id"
} else {
#read from file_input1.txt and sort/modify
source "/nfs/iind/disks/pds.tfm.disk_0001/Abhishek/file_handling_1.tcl"
set cell_index 0
#read from file_input2.txt
set file_name "file_input2.txt"
set file2_data [read_file $file_name]
puts $file2_data
set file2_data_split [split $file2_data "\n"]
#
#puts $name
puts [format "%-12s %-9s %-9s %-9s %-5s" $name $Trans $Load $Delay {Total Delay}]
#puts $ohye
puts "---------------------------------------------------------"
#
#in file_out2.txt
#
set fp_outfile [open "file_out2.txt" w+]
set m [format "%-12s %-9s %-9s %-9s %-5s" $name $Trans $Load $Delay {Total Delay}]
puts $fp_outfile $m
puts $fp_outfile "---------------------------------------------------------"
#
#puts $file2_data_split
#
PART3
ReplyDeleteproc total_delay_calc {got_data_from_fileinput1 old_delay} {
#upvar $old_delay ref_old_delay
#global old_delay
set convert_to_list [split $got_data_from_fileinput1 " "]
#puts $convert_to_list
#puts "hello $old_delay"
set match_and [lsearch $convert_to_list "D"]
#puts $match_and
set current_delayns [lindex $convert_to_list 3]
set current_delay 0
regexp {[0-9.]+} $current_delayns current_delay
#puts $current_delay
set total_delay [expr ($current_delay + $old_delay)]
set old_delay $total_delay
set delays [list $total_delay $old_delay]
#puts $delays
return $delays
}
#
#displays the info in modified way
#
proc add_total_delay_to_row {array_to_list tot_delay_1 got_data_from_fileinput1
} {
#puts $array_to_list
#puts $got_data_from_fileinput1
#puts $tot_delay_1
set new_row [split $got_data_from_fileinput1 " "]
#puts $new_row
#set dummy [lindex $new_row 13]
#puts $dummy
#puts $new_row
regexp {[NAND]+} $new_row found
if {$found == "NAND"} {
#puts "hello $new_row"
set row_list_dummy [lindex $new_row 0]
regexp {[A-Z0-9_]+} $row_list_dummy row_list(0)
set row_list(1) [lindex $new_row 1]
set row_list(2) [lindex $new_row 2]
set row_list(3) [lindex $new_row 3]
set ns ns
set tot_delay_1 "$tot_delay_1 $ns"
set tot_delay_1_ns [join $tot_delay_1 ""]
} else {
set row_list_dummy [lindex $new_row 0]
regexp {[A-Z0-9_]+} $row_list_dummy row_list(0)
set row_list(1) [lindex $new_row 1]
set row_list(2) [lindex $new_row 2]
set row_list(3) [lindex $new_row 3]
set ns ns
set tot_delay_1 "$tot_delay_1 $ns"
set tot_delay_1_ns [join $tot_delay_1 ""]
}
set formatted_row [format "%-12s %-9s %-9s %-9s %-9s" $row_list(0) $row_list(1) $row_list(2) $row_list(3) $tot_delay_1_ns]
return $formatted_row
}
proc write_in_out {fp_outfile row_cell} {
puts $fp_outfile
puts $fp_outfile $row_cell
}
if {[catch {open "file_input1.txt"} file_input1_id] && [catch {open "file_input2.txt"} file_input2_id]} {
puts "error1: $file_input1_id"
puts "error2: $file_input2_id"
} else {
#read from file_input1.txt and sort/modify
source "/nfs/iind/disks/pds.tfm.disk_0001/Abhishek/file_handling_1.tcl"
set cell_index 0
#read from file_input2.txt
set file_name "file_input2.txt"
set file2_data [read_file $file_name]
puts $file2_data
set file2_data_split [split $file2_data "\n"]
#
#puts $name
puts [format "%-12s %-9s %-9s %-9s %-5s" $name $Trans $Load $Delay {Total Delay}]
#puts $ohye
puts "---------------------------------------------------------"
#
#in file_out2.txt
#
set fp_outfile [open "file_out2.txt" w+]
set m [format "%-12s %-9s %-9s %-9s %-5s" $name $Trans $Load $Delay {Total Delay}]
puts $fp_outfile $m
puts $fp_outfile "---------------------------------------------------------"
#
#puts $file2_data_split
#
PART3 (Please ignore the older one)
ReplyDelete#Cell 1
set x [read_cell $cell_index $file2_data_split] ;#cell_index=0
set array_to_list [array get row]
#puts $array_to_list
#puts $x
set got_data_from_fileinput1 [get_data_from_fileinput1 $array_to_list $x]
set old_delay 0
#puts "1 $got_data_from_fileinput1"
#puts "2 $old_delay"
set delay_list1 [total_delay_calc $got_data_from_fileinput1 $old_delay]
set old_delay [lindex $delay_list1 1]
set tot_delay_1 [lindex $delay_list1 0]
set row_cell_1 [add_total_delay_to_row $array_to_list $tot_delay_1 $got_data_from_fileinput1]
puts $row_cell_1
write_in_out $fp_outfile $row_cell_1
#
#Cell 2
set cell_index [expr $cell_index+1]
set x [read_cell $cell_index $file2_data_split]
set array_to_list [array get row]
set got_data_from_fileinput1 [get_data_from_fileinput1 $array_to_list $x]
set delay_list2 [total_delay_calc $got_data_from_fileinput1 $old_delay]
set old_delay [lindex $delay_list2 1]
set tot_delay_2 [lindex $delay_list2 0]
set row_cell_2 [add_total_delay_to_row $array_to_list $tot_delay_2 $got_data_from_fileinput1]
puts $row_cell_2
write_in_out $fp_outfile $row_cell_2
#
#Cell 3
set cell_index [expr $cell_index+1]
set x [read_cell $cell_index $file2_data_split]
#puts "hey $x"
set array_to_list [array get row]
set got_data_from_fileinput1 [get_data_from_fileinput1 $array_to_list $x]
#puts $got_data_from_fileinput1
set delay_list3 [total_delay_calc $got_data_from_fileinput1 $old_delay]
set old_delay [lindex $delay_list3 1]
set tot_delay_3 [lindex $delay_list3 0]
set row_cell_3 [add_total_delay_to_row $array_to_list $tot_delay_3 $got_data_from_fileinput1]
puts $row_cell_3
write_in_out $fp_outfile $row_cell_3
#
# Cell 4
set cell_index [expr $cell_index+1]
set x [read_cell $cell_index $file2_data_split]
set array_to_list [array get row]
set got_data_from_fileinput1 [get_data_from_fileinput1 $array_to_list $x]
#puts $got_data_from_fileinput1
set delay_list4 [total_delay_calc $got_data_from_fileinput1 $old_delay]
set old_delay [lindex $delay_list4 1]
set tot_delay_4 [lindex $delay_list4 0]
#puts "$array_to_list $tot_delay_4 $got_data_from_fileinput1"
set row_cell_4 [add_total_delay_to_row $array_to_list $tot_delay_4 $got_data_from_fileinput1]
puts $row_cell_4
write_in_out $fp_outfile $row_cell_4
close $fp_outfile
};#if
Please share the solution
ReplyDelete#!/usr/bin/tclsh
ReplyDeleteset input_file1 [open "file_input1.txt" r]
set input_file2 [open "file_input2.txt" r]
set output_file [open "C:/ActiveTcl/bin/training/output_file1.txt" w]
set obj_cell_name ""
set sum_delay 0
while {[gets $input_file1 line]>=0} {
lappend obj_cell_name [lindex $line 1]
}
close $input_file2
set line_num 1
while {[gets $input_file2 line]>=0} {
if {$line_num == 1} {
puts $output_file "$line\tdelay"
set line_num [expr $line_num+1]
} else {
if {[string match "*[lindex $line 0]*" $obj_cell_name]==1} {
#regexp {([0-9].*)ns} [lindex $line 1]] delay_unit delay
set delay [string trimright [lindex $line 1] "ns"]
set sum_delay [expr $sum_delay+$delay]
puts $output_file "$line\t[expr $sum_delay]ns"
set line_num [expr $line_num+1]
continue
}
}
}
close $input_file1
close $output_file