blob: 65c12070f5810d925654c35e6fc9616e9400307e [file] [log] [blame]
ranan-uspe6a8abc2022-05-23 07:01:33 +09001# Copyright 2021 The University of Michigan
2# Copyright 2022 Efabless Corporation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16proc insert_buffer {pin_name pin_type master_name net_name inst_name} {
17 set db [ord::get_db]
18 set block [ord::get_db_block]
19
20 # Create buffer instance
21 set master [$db findMaster $master_name]
22 if { $master == "NULL" } {
23 puts "Buffer cell '$master' not found."
24 exit -1
25 }
26
27 set inst [odb::dbInst_create $block $master $inst_name]
28
29 # Figure out the inputs & outputs of the master
30 foreach mterm [$master getMTerms] {
31 if {[$mterm getSigType] == "POWER"} {
32 continue
33 }
34 if {[$mterm getSigType] == "GROUND"} {
35 continue
36 }
37 if {[$mterm getIoType] == "INPUT"} {
38 set input $mterm
39 }
40 if {[$mterm getIoType] == "OUTPUT"} {
41 set output $mterm
42 }
43 }
44
45 # New net to connect to
46 set new_net [odb::dbNet_create $block $net_name]
47
48 if {$pin_type=="ITerm"} {
49 # Finding the block with pin name
50 set iterm [$block findITerm $pin_name]
51 if { $iterm == "NULL" } {
52 puts "Instance terminal '$pin_name' not found."
53 exit -1
54 }
55 set old_net [$iterm getNet]
56
57 # Original disconnect command
58 odb::dbITerm_disconnect $iterm
59
60 # Original connect command
61 odb::dbITerm_connect $iterm $new_net
62
63 # Set I/O of iterm (Buffer)
64 set in_iterm [$inst getITerm $input]
65 set out_iterm [$inst getITerm $output]
66
67 if { ![info exists ::env(INSERT_BUFFER_NO_PLACE)] } {
68 # define the instance to which the buffer inserted will connected to
69 set master_inst [$iterm getInst]
70 # get the geometry of the instance, geometry means its shape, the coordinate of its vertex...
71 set box [$master_inst getBBox]
72
73 # get the position of the lower left point of this instance
74 set x_min [$box xMin]
75 set y_min [$box yMin]
76
77 # $inst is the buffer we want to insert, now insert it in the position of the instance it is connected to,
78 # using setLocation, and detail_place will help us separate them
79 [$inst setLocation $x_min $y_min]
80 [$inst setPlacementStatus PLACED]
81 }
82
83 odb::dbITerm_connect $in_iterm $new_net
84 odb::dbITerm_connect $out_iterm $old_net
85
86 } else {
87 # Finding the block with pin name
88 set bterm [$block findBTerm $pin_name]
89 set old_net [$bterm getNet]
90 set net_out_iterm [odb::dbNet_get1stITerm $old_net]
91 set old_net_inst [$net_out_iterm getInst]
92 set net_mterm [$net_out_iterm getMTerm]
93 set old_net_input $net_mterm
94 odb::dbITerm_disconnect $net_out_iterm
95
96 if { ![info exists ::env(INSERT_BUFFER_NO_PLACE)] } {
97 set box [$bterm getBBox]
98
99 # get the position of the lower left point of this instance
100 set x_min [$box xMin]
101 set y_min [$box yMin]
102
103 # $inst is the buffer we want to insert, now insert it in the position of the instance it is connected to,
104 # using setLocation, and detail_place will help us separate them
105 [$inst setLocation $x_min $y_min]
106 [$inst setPlacementStatus PLACED]
107 }
108
109 # Find output/input of buffer iterm
110 set in_iterm [$inst getITerm $input]
111 set out_iterm [$inst getITerm $output]
112
113 odb::dbITerm_connect $out_iterm $new_net
114 odb::dbITerm_connect $net_out_iterm $new_net
115 odb::dbITerm_connect $in_iterm $old_net
116 }
117}
118
119if { [info exists ::env(INSERT_BUFFER_COMMAND) ]} {
120 if {[catch {read_lef $::env(MERGED_LEF)} errmsg]} {
121 puts stderr $errmsg
122 exit 1
123 }
124
125 if {[catch {read_def $::env(CURRENT_DEF)} errmsg]} {
126 puts stderr $errmsg
127 exit 1
128 }
129
130 set arg_list [split $::env(INSERT_BUFFER_COMMAND) " "]
131 insert_buffer {*}$arg_list
132
133 write_def $::env(SAVE_DEF)
134}