From e5fcf9281e1da4b5e04ed6915eb082a78c90d8ec Mon Sep 17 00:00:00 2001 From: Kareem Farid Date: Thu, 9 Dec 2021 12:58:26 +0200 Subject: [PATCH] Miscellaneous Enhancements (#745) + Add RUN_MAGIC_DRC flag to control running DRC with magic + Add RUN_LVS flag to control running LVS ~ replace grepCount.sh with something sane --- configuration/README.md | 2 + configuration/general.tcl | 5 +- scripts/grepCount.sh | 15 --- scripts/tcl_commands/checkers.tcl | 6 +- scripts/tcl_commands/lvs.tcl | 171 +++++++++++++++--------------- scripts/tcl_commands/magic.tcl | 80 +++++++------- scripts/utils/utils.tcl | 5 + 7 files changed, 142 insertions(+), 142 deletions(-) delete mode 100644 scripts/grepCount.sh diff --git a/configuration/README.md b/configuration/README.md index d2de1b2f..91cb1508 100644 --- a/configuration/README.md +++ b/configuration/README.md @@ -263,7 +263,9 @@ These variables worked initially, but they were too sky130 specific to be scalab | `USE_GPIO_PADS` | Decides whether or not to use the gpio pads in routing by merging their LEF file set in `::env(USE_GPIO_ROUTING_LEF)` and blackboxing their verilog modules set in `::env(GPIO_PADS_VERILOG)`. 1=Enabled, 0=Disabled.
(Default: `0`) | | `LEC_ENABLE` | Enables logic verification using yosys, for comparing each netlist at each stage of the flow with the previous netlist and verifying that they are logically equivalent. Warning: this will increase the runtime significantly. 1 = Enabled, 0 = Disabled
(Default: `0`)| | `RUN_ROUTING_DETAILED` | Enables detailed routing. 1 = Enabled, 0 = Disabled
(Default: `1`)| +| `RUN_LVS` | Enables running LVS. 1 = Enabled, 0 = Disabled
(Default: `1`)| | `RUN_MAGIC` | Enables running magic and GDSII streaming. 1 = Enabled, 0 = Disabled
(Default: `1`)| +| `RUN_MAGIC_DRC` | Enables running magic DRC on GDS-II produced by magic. 1 = Enabled, 0 = Disabled
(Default: `1`)| | `RUN_KLAYOUT` | Enables running Klayout and GDSII streaming. 1 = Enabled, 0 = Disabled
(Default: `1`)| | `RUN_KLAYOUT_DRC` | Enables running Klayout DRC on GDS-II produced by magic. 1 = Enabled, 0 = Disabled
(Default: `1`)| | `KLAYOUT_DRC_KLAYOUT_GDS` | Enables running Klayout DRC on GDS-II produced by Klayout. 1 = Enabled, 0 = Disabled
(Default: `0`)| diff --git a/configuration/general.tcl b/configuration/general.tcl index cd1e3080..cde6a543 100755 --- a/configuration/general.tcl +++ b/configuration/general.tcl @@ -22,10 +22,13 @@ if { ! [info exists ::env(STD_CELL_LIBRARY)] } { set ::env(USE_GPIO_PADS) 0 # Flow control defaults +set ::env(RUN_LVS) 1 + set ::env(LEC_ENABLE) 0 set ::env(YOSYS_REWRITE_VERILOG) 0 set ::env(RUN_MAGIC) 1 +set ::env(RUN_MAGIC_DRC) 1 set ::env(MAGIC_PAD) 0 set ::env(MAGIC_ZEROIZE_ORIGIN) 0 set ::env(MAGIC_GENERATE_GDS) 1 @@ -75,4 +78,4 @@ if { [file exists /build/transforms/] } { set ::env(PSN_TRANSFORM_PATH) /build/transforms } else { set ::env(PSN_TRANSFORM_PATH) $::env(HOME)/.local/transforms -} \ No newline at end of file +} diff --git a/scripts/grepCount.sh b/scripts/grepCount.sh deleted file mode 100644 index 6a12b359..00000000 --- a/scripts/grepCount.sh +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2020 Efabless Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -grep $1 $2 | wc -l \ No newline at end of file diff --git a/scripts/tcl_commands/checkers.tcl b/scripts/tcl_commands/checkers.tcl index baf23a96..346c27ce 100755 --- a/scripts/tcl_commands/checkers.tcl +++ b/scripts/tcl_commands/checkers.tcl @@ -15,7 +15,7 @@ proc check_assign_statements {args} { - set checker [ exec sh $::env(SCRIPTS_DIR)/grepCount.sh assign $::env(synthesis_results).v ] + set checker [count_matches assign $::env(synthesis_results).v] if { $checker != 0 } { puts_err "There are assign statements in the netlist" @@ -207,7 +207,7 @@ proc check_macro_placer_num_solns {args} { proc quit_on_tr_drc {args} { if { [info exists ::env(QUIT_ON_TR_DRC)] && $::env(QUIT_ON_TR_DRC) } { - set checker [ exec sh $::env(SCRIPTS_DIR)/grepCount.sh violation $::env(routing_reports)/detailed.drc ] + set checker [count_matches violation $::env(routing_reports)/detailed.drc] if { $checker != 0 } { puts_err "There are violations in the design after detailed routing." @@ -227,7 +227,7 @@ proc quit_on_magic_drc {args} { } parse_key_args "quit_on_magic_drc" args arg_values $options - set checker [ exec sh $::env(SCRIPTS_DIR)/grepCount.sh violation $arg_values(-log) ] + set checker [count_matches violation $arg_values(-log)] if { $checker != 0 } { puts_err "There are violations in the design after Magic DRC." diff --git a/scripts/tcl_commands/lvs.tcl b/scripts/tcl_commands/lvs.tcl index 81436a75..99635fa3 100755 --- a/scripts/tcl_commands/lvs.tcl +++ b/scripts/tcl_commands/lvs.tcl @@ -16,11 +16,11 @@ proc verilog_to_verilogPower {args} { puts_info "Adding Power Nets to Verilog..." set options { - {-input required} - {-output required} - {-lef required} - {-power required} - {-ground required} + {-input required} + {-output required} + {-lef required} + {-power required} + {-ground required} } set flags {} parse_key_args "verilog_to_verilogPower" args arg_values $options flags_map $flags @@ -32,10 +32,10 @@ proc verilog_to_verilogPower {args} { set lef $arg_values(-lef) try_catch $bin \ - -v $power \ - -g $gnd \ - -l $lef \ - $in |& tee $out + -v $power \ + -g $gnd \ + -l $lef \ + $in |& tee $out } # WORKS ON DEF FILES @@ -43,13 +43,13 @@ proc write_powered_verilog {args} { increment_index puts_info "Writing Powered Verilog..." set options { - {-def optional} - {-output_def optional} - {-output_verilog optional} - {-lef optional} - {-power optional} - {-ground optional} - {-powered_netlist optional} + {-def optional} + {-output_def optional} + {-output_verilog optional} + {-lef optional} + {-power optional} + {-ground optional} + {-powered_netlist optional} } set flags {} parse_key_args "write_powered_verilog" args arg_values $options flags_map $flags @@ -68,86 +68,88 @@ proc write_powered_verilog {args} { } try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/write_powered_def.py \ - -d $arg_values(-def) \ - -l $arg_values(-lef) \ - --power-port $arg_values(-power) \ - --ground-port $arg_values(-ground) \ - --powered-netlist $arg_values(-powered_netlist) \ - -o $arg_values(-output_def) \ - |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(routing_logs)/write_powered_verilog.log] - + -d $arg_values(-def) \ + -l $arg_values(-lef) \ + --power-port $arg_values(-power) \ + --ground-port $arg_values(-ground) \ + --powered-netlist $arg_values(-powered_netlist) \ + -o $arg_values(-output_def) \ + |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(routing_logs)/write_powered_verilog.log] + write_verilog $arg_values(-output_verilog) -def $arg_values(-output_def) -log $::env(routing_logs)/write_verilog.log -canonical } # "layout": a spice netlist # "schematic": a verilog netlist proc run_lvs {{layout "$::env(EXT_NETLIST)"} {schematic "$::env(CURRENT_NETLIST)"}} { - # LEF LVS output to lvs.lef.log, design.lvs.lef.log, design.lvs.lef.json, design.lvs.lef.log - # GDS LVS output to lvs.gds.log, design.lvs.gds.log, design.lvs.gds.json, design.lvs.gds.log - # GDS LVS uses STD_CELL_LIBRARY spice and - # if defined, additional LVS_EXTRA_STD_CELL_LIBRARY spice and LVS_EXTRA_GATE_LEVEL_VERILOG files - increment_index - TIMER::timer_start - if { [info exist ::env(MAGIC_EXT_USE_GDS)] && $::env(MAGIC_EXT_USE_GDS) } { - set extract_type gds - puts_info "Running GDS LVS..." - } else { - set extract_type lef - puts_info "Running LEF LVS..." - } - - set layout [subst $layout] - set schematic [subst $schematic] - - set setup_file $::env(NETGEN_SETUP_FILE) - set module_name $::env(DESIGN_NAME) - #writes setup_file_*_lvs to tmp directory. - set lvs_file_path [index_file $::env(finishing_tmpfiles)/setup_file.$extract_type.lvs] - set lvs_file [open $lvs_file_path w] - if { "$extract_type" == "gds" } { - if { [info exist ::env(LVS_EXTRA_STD_CELL_LIBRARY)] } { - set libs_in $::env(LVS_EXTRA_STD_CELL_LIBRARY) - foreach lib_file $libs_in { - puts $lvs_file "puts \"Reading spice netlist file $lib_file\"" - puts $lvs_file "readnet spice $lib_file 1" - } + if { $::env(RUN_LVS) } { + # LEF LVS output to lvs.lef.log, design.lvs.lef.log, design.lvs.lef.json, design.lvs.lef.log + # GDS LVS output to lvs.gds.log, design.lvs.gds.log, design.lvs.gds.json, design.lvs.gds.log + # GDS LVS uses STD_CELL_LIBRARY spice and + # if defined, additional LVS_EXTRA_STD_CELL_LIBRARY spice and LVS_EXTRA_GATE_LEVEL_VERILOG files + increment_index + TIMER::timer_start + if { [info exist ::env(MAGIC_EXT_USE_GDS)] && $::env(MAGIC_EXT_USE_GDS) } { + set extract_type gds + puts_info "Running GDS LVS..." } else { - if { [info exist ::env(STD_CELL_LIBRARY)] } { - set std_cell_source $::env(PDK_ROOT)/$::env(PDK)/libs.ref/$::env(STD_CELL_LIBRARY)/spice/$::env(STD_CELL_LIBRARY).spice + set extract_type lef + puts_info "Running LEF LVS..." + } + + set layout [subst $layout] + set schematic [subst $schematic] + + set setup_file $::env(NETGEN_SETUP_FILE) + set module_name $::env(DESIGN_NAME) + #writes setup_file_*_lvs to tmp directory. + set lvs_file_path [index_file $::env(finishing_tmpfiles)/setup_file.$extract_type.lvs] + set lvs_file [open $lvs_file_path w] + if { "$extract_type" == "gds" } { + if { [info exist ::env(LVS_EXTRA_STD_CELL_LIBRARY)] } { + set libs_in $::env(LVS_EXTRA_STD_CELL_LIBRARY) + foreach lib_file $libs_in { + puts $lvs_file "puts \"Reading spice netlist file $lib_file\"" + puts $lvs_file "readnet spice $lib_file 1" + } } else { - set std_cell_source $::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_sc_hd/spice/sky130_fd_sc_hd.spice + if { [info exist ::env(STD_CELL_LIBRARY)] } { + set std_cell_source $::env(PDK_ROOT)/$::env(PDK)/libs.ref/$::env(STD_CELL_LIBRARY)/spice/$::env(STD_CELL_LIBRARY).spice + } else { + set std_cell_source $::env(PDK_ROOT)/$::env(PDK)/libs.ref/sky130_fd_sc_hd/spice/sky130_fd_sc_hd.spice + } + puts $lvs_file "puts \"Reading spice netlist file $std_cell_source\"" + puts $lvs_file "readnet spice $std_cell_source 1" } - puts $lvs_file "puts \"Reading spice netlist file $std_cell_source\"" - puts $lvs_file "readnet spice $std_cell_source 1" - } - if { [info exist ::env(LVS_EXTRA_GATE_LEVEL_VERILOG)] } { - set libs_in $::env(LVS_EXTRA_GATE_LEVEL_VERILOG) - foreach lib_file $libs_in { - puts $lvs_file "puts \"Reading verilog netlist file $lib_file\"" - puts $lvs_file "readnet verilog $lib_file 1" + if { [info exist ::env(LVS_EXTRA_GATE_LEVEL_VERILOG)] } { + set libs_in $::env(LVS_EXTRA_GATE_LEVEL_VERILOG) + foreach lib_file $libs_in { + puts $lvs_file "puts \"Reading verilog netlist file $lib_file\"" + puts $lvs_file "readnet verilog $lib_file 1" + } } } + + set extraction_prefix [index_file $::env(finishing_logs)/$::env(DESIGN_NAME).$extract_type] + + puts $lvs_file "lvs {$layout $module_name} {$schematic $module_name} $setup_file $extraction_prefix.log -json" + close $lvs_file + + puts_info "$layout against $schematic" + + try_catch netgen -batch source $lvs_file_path \ + |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(finishing_logs)/$extract_type.log] + + set count_lvs_log [index_file $::env(finishing_logs)/$::env(DESIGN_NAME).lvs.$extract_type.log] + + exec python3 $::env(SCRIPTS_DIR)/count_lvs.py \ + -f $extraction_prefix.json \ + |& tee $::env(TERMINAL_OUTPUT) $count_lvs_log + + TIMER::timer_stop + exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "lvs - netgen" + quit_on_lvs_error -log $count_lvs_log } - - set extraction_prefix [index_file $::env(finishing_logs)/$::env(DESIGN_NAME).$extract_type] - - puts $lvs_file "lvs {$layout $module_name} {$schematic $module_name} $setup_file $extraction_prefix.log -json" - close $lvs_file - - puts_info "$layout against $schematic" - - try_catch netgen -batch source $lvs_file_path \ - |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(finishing_logs)/$extract_type.log] - - set count_lvs_log [index_file $::env(finishing_logs)/$::env(DESIGN_NAME).lvs.$extract_type.log] - - exec python3 $::env(SCRIPTS_DIR)/count_lvs.py \ - -f $extraction_prefix.json \ - |& tee $::env(TERMINAL_OUTPUT) $count_lvs_log - - TIMER::timer_stop - exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "lvs - netgen" - quit_on_lvs_error -log $count_lvs_log } proc run_netgen {args} { @@ -155,3 +157,4 @@ proc run_netgen {args} { } package provide openlane 0.9 + diff --git a/scripts/tcl_commands/magic.tcl b/scripts/tcl_commands/magic.tcl index eb56f4a1..df4be6ee 100755 --- a/scripts/tcl_commands/magic.tcl +++ b/scripts/tcl_commands/magic.tcl @@ -88,50 +88,52 @@ proc run_magic {args} { proc run_magic_drc {args} { - increment_index - TIMER::timer_start - puts_info "Running Magic DRC..." + if { $::env(RUN_MAGIC_DRC) } { + increment_index + TIMER::timer_start + puts_info "Running Magic DRC..." - set ::env(PDKPATH) "$::env(PDK_ROOT)/$::env(PDK)" - set ::env(drc_prefix) $::env(finishing_reports)/drc - # Has to be maglef for DRC Checking - set ::env(MAGTYPE) maglef + set ::env(PDKPATH) "$::env(PDK_ROOT)/$::env(PDK)" + set ::env(drc_prefix) $::env(finishing_reports)/drc + # Has to be maglef for DRC Checking + set ::env(MAGTYPE) maglef - try_catch magic \ - -noconsole \ - -dnull \ - -rcfile $::env(MAGIC_MAGICRC) \ - $::env(SCRIPTS_DIR)/magic/drc.tcl \ - $antenna_log set ::env(ANTENNA_CHECKER_LOG) $antenna_log - + TIMER::timer_stop exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "antenna check - magic" diff --git a/scripts/utils/utils.tcl b/scripts/utils/utils.tcl index b16fa283..6b39daa2 100755 --- a/scripts/utils/utils.tcl +++ b/scripts/utils/utils.tcl @@ -335,5 +335,10 @@ proc assert_files_exist {files} { } } +proc count_matches {pattern search_file} { + set count [exec bash -c "grep $pattern $search_file | wc -l"] + return $count +} + package provide openlane_utils 0.9