Skip to content

Commit

Permalink
ECO Flow Tweaks (The-OpenROAD-Project#1008)
Browse files Browse the repository at this point in the history
+ Enable insert_buffer to be used outside of the ECO flow
+ Added ability to use interactive.tcl in issue regression flow
~ Made the ECO flow far less chatty
~ Other non-functional ECO flow tweaks
~ Merged apply_fix.tcl and eco.tcl into eco.tcl
~ Added `cat` command to utils.tcl
  • Loading branch information
donn authored Mar 28, 2022
1 parent 08e650b commit f2f5d83
Show file tree
Hide file tree
Showing 19 changed files with 432 additions and 428 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ clean_all: clean_runs clean_results

clean_runs:
@rm -rf ./designs/*/runs && rm -rf ./_build/it_tc_logs && echo "Runs cleaned successfully." || echo "Failed to delete runs."
@rm -rf ./tests/*/runs && echo "Test runs cleaned successfully." || echo "Failed to delete test runs."

clean_results:
@{ find regression_results -mindepth 1 -maxdepth 1 -type d | grep -v benchmark | xargs rm -rf ; } && echo "Results cleaned successfully." || echo "Failed to delete results."
1 change: 1 addition & 0 deletions flow.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set ::env(OPENLANE_ROOT) [file dirname [file normalize [info script]]]
set ::env(SCRIPTS_DIR) "$::env(OPENLANE_ROOT)/scripts"

if { [file exists $::env(OPENLANE_ROOT)/install/env.tcl ] } {
source $::env(OPENLANE_ROOT)/install/env.tcl
Expand Down
7 changes: 6 additions & 1 deletion run_issue_regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ def run_test_case(test_case):
try:
logfile = open(logpath, "w")
print(f"Running test case: {test_case_name} (logging to {logpath})")
interactive = []
interactive_file = os.path.join(test_case, "interactive.tcl")
if os.path.exists(interactive_file):
interactive = ["-it", "-file", interactive_file]
result = subprocess.run(
[
"./flow.tcl",
Expand All @@ -101,7 +105,8 @@ def run_test_case(test_case):
"issue_regression_run",
"-run_hooks",
"-overwrite",
],
]
+ interactive,
stdout=logfile,
stderr=subprocess.STDOUT,
check=True,
Expand Down
42 changes: 6 additions & 36 deletions scripts/gen_insert_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,46 +128,16 @@
insert_times = math.floor(
abs(min(vio_dict[pin_unq])) / 0.06
) # insert buffer conservatively
if insert_times == 0:
if insert_times < 1:
insert_times = 1

for i in range(0, insert_times):
vio_count += 1
print("insert multiple buffers: ", insert_times + 1)
insert_buffer_line = (
"insert_buffer "
+ pin_unq
+ " "
+ "sky130_fd_sc_hd__dlygate4sd3_1"
+ " net_HOLD_NET_"
+ str(eco_iter)
+ "_"
+ str(vio_count)
+ " U_HOLD_FIX_BUF_"
+ str(eco_iter)
+ "_"
+ str(vio_count)
)
insert_buffer_line = f"insert_buffer {pin_unq} sky130_fd_sc_hd__dlygate4sd3_1 net_HOLD_NET_{eco_iter}_{vio_count} U_HOLD_FIX_BUF_{eco_iter}_{vio_count}"
printArr.append(insert_buffer_line)
print(insert_buffer_line)
else:
print("insert multiple buffers: ", insert_times)
for i in range(0, insert_times):
vio_count += 1
print("insert multiple buffers: ", insert_times + 1)
insert_buffer_line = (
"insert_buffer "
+ pin_unq
+ " "
+ "sky130_fd_sc_hd__dlygate4sd3_1"
+ " net_HOLD_NET_"
+ str(eco_iter)
+ "_"
+ str(vio_count)
+ " U_HOLD_FIX_BUF_"
+ str(eco_iter)
+ "_"
+ str(vio_count)
)
printArr.append(insert_buffer_line)
print(insert_buffer_line)

if vio_count == 0:
insert_buffer_line = "No violations found"
printArr.append(insert_buffer_line)
Expand Down
79 changes: 0 additions & 79 deletions scripts/openroad/apply_fix.tcl

This file was deleted.

190 changes: 57 additions & 133 deletions scripts/openroad/eco.tcl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 The University of Michigan
# Copyright 2022 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,151 +13,36 @@
# See the License for the specific language governing permissions and
# limitations under the License.

source $::env(SCRIPTS_DIR)/openroad/insert_buffer.tcl

proc move_to_dir {filenames dirname} {
foreach filename $filenames {
file rename $filename [file join $dirname [file tail $filename]]
}
}

proc pause {{message "Press enter to continue ==> "}} {
puts -nonewline $message
flush stdout
gets stdin
}

proc insert_buffer {pin_name pin_type master_name net_name inst_name} {
puts "Successfully set db"
set db [ord::get_db]
set new_master [$db findMaster $master_name]
puts "Set DB: "
puts $db
puts "NEW MASTER: "
puts $new_master
set block [ord::get_db_block]
puts "GOT BLOCK FROM DB: "
puts $block

# Create buffer instance
puts "Successfully create new instance"
set inst [odb::dbInst_create $block $new_master $inst_name]
puts "create new master"

# Figure out the inputs & outputs of the master
foreach mterm [$new_master getMTerms] {
if {[$mterm getSigType] == "POWER"} {
continue
}
if {[$mterm getSigType] == "GROUND"} {
continue
}
if {[$mterm getIoType] == "INPUT"} {
set input $mterm
}
if {[$mterm getIoType] == "OUTPUT"} {
set output $mterm
}
}

# New net to connect to
set new_net [odb::dbNet_create $block $net_name]

if {$pin_type=="ITerm"} {
puts "Start Inserting buffer for reg-* cases"

# Finding the block with pin name
set iterm [$block findITerm $pin_name]
set old_net [$iterm getNet]

# Original disconnect command
odb::dbITerm_disconnect $iterm

# Original connect command
odb::dbITerm_connect $iterm $new_net

# Set I/O of iterm (Buffer)
set in_iterm [$inst getITerm $input]
set out_iterm [$inst getITerm $output]

# define the instance to which the buffer inserted will connected to
set master_inst [$iterm getInst]
# get the geometry of the instance, geometry means its shape, the coordinate of its vertex...
set box [$master_inst getBBox]

# get the position of the lower left point of this instance
set x_min [$box xMin]
set y_min [$box yMin]


# $inst is the buffer we want to insert, now insert it in the position of the instance it is connected to,
# using setLocation, and detail_place will help us separate them
[$inst setLocation $x_min $y_min]
[$inst setPlacementStatus PLACED]

# done inserting the buffer
puts "done insert buffer"

odb::dbITerm_connect $in_iterm $new_net
puts "connect to in_iterm"

odb::dbITerm_connect $out_iterm $old_net
puts "connect to out_iterm "

puts "Done Inserting buffer for reg-* cases"
} else {
puts "Start Inserting buffer for pin-* cases"
# Finding the block with pin name
set bterm [$block findBTerm $pin_name]
set old_net [$bterm getNet]
puts [odb::dbNet_get1stITerm $old_net]
set net_out_iterm [odb::dbNet_get1stITerm $old_net]
set old_net_inst [$net_out_iterm getInst]
set net_mterm [$net_out_iterm getMTerm]
puts [$net_mterm getSigType]
set old_net_input $net_mterm
odb::dbITerm_disconnect $net_out_iterm

set box [$bterm getBBox]

# get the position of the lower left point of this instance
set x_min [$box xMin]
set y_min [$box yMin]

# $inst is the buffer we want to insert, now insert it in the position of the instance it is connected to,
# using setLocation, and detail_place will help us separate them
[$inst setLocation $x_min $y_min]
[$inst setPlacementStatus PLACED]

# Find output/input of buffer iterm
set in_iterm [$inst getITerm $input]
puts "get in iterm"
set out_iterm [$inst getITerm $output]
puts "get out iterm"

odb::dbITerm_connect $out_iterm $new_net
odb::dbITerm_connect $net_out_iterm $new_net
odb::dbITerm_connect $in_iterm $old_net

puts "Done Inserting buffer for pin-* cases"
}
}


proc size_cell {inst_name new_master_name} {
set db [ord::get_db]
set new_master [$db findMaster $new_master_name]
set db [ord::get_db]
set new_master [$db findMaster $new_master_name]

set block [ord::get_db_block]
set inst [$block findInst $inst_name]
$inst swapMaster $new_master
set block [ord::get_db_block]
set inst [$block findInst $inst_name]
$inst swapMaster $new_master
}

proc run_eco {args} {
# Source fixes
puts "Sourcing fixes !!!"

set cur_iter [expr $::env(ECO_ITER) == 0 ? \
0 : \
[expr {$::env(ECO_ITER) -1}] \
]
set cur_iter [expr $::env(ECO_ITER) == 0 ? 0 : expr {$::env(ECO_ITER) -1}]]
# Uncomment to source the generated fix
# Currently args in the fix tcl has some bugs:
# 1st argument of insert_buffer (pin_name) not found
source "$::env(eco_results)/fix/eco_fix_$cur_iter.tcl"

# Run detailed placement
detailed_placement

Expand All @@ -166,11 +52,49 @@ proc run_eco {args} {

foreach net $nets {
set wire [$net getWire]
if {$wire != "NULL"} {
[odb::dbWire_destroy $wire]
}
if {$wire != "NULL"} {
[odb::dbWire_destroy $wire]
}
}

}

if {[catch {read_lef $::env(MERGED_LEF_UNPADDED)} errmsg]} {
puts stderr $errmsg
exit 1
}

foreach lib $::env(LIB_CTS) {
read_liberty $lib
}

set cur_iter [expr $::env(ECO_ITER) == 0 ? \
0 : \
[expr {$::env(ECO_ITER) -1}] \
]

if {[expr {$cur_iter == 0}]} {
if {[catch {read_def $::env(CURRENT_DEF)} errmsg]} {
puts stderr $errmsg
exit 1
}
puts "Reading '$::env(CURRENT_NETLIST)'..."
read_verilog $::env(CURRENT_NETLIST)
} else {
if {[catch {read_def \
$::env(eco_results)/def/eco_$cur_iter.def} errmsg]} {
puts stderr $errmsg
exit 1
}
set nl $::env(eco_results)/net/eco_$cur_iter.v
puts "Reading '$nl'..."
read_verilog $nl
}

read_sdc -echo $::env(CURRENT_SDC)
set_propagated_clock [all_clocks]

run_eco

write_verilog $::env(eco_results)/net/eco_$::env(ECO_ITER).v
write_def $::env(eco_results)/def/eco_$::env(ECO_ITER).def
Loading

0 comments on commit f2f5d83

Please sign in to comment.