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
This commit is contained in:
Kareem Farid
2021-12-09 12:58:26 +02:00
committed by GitHub
parent 6ad621eac0
commit e5fcf9281e
7 changed files with 142 additions and 142 deletions

View File

@@ -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. <br> (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 <br> (Default: `0`)|
| `RUN_ROUTING_DETAILED` | Enables detailed routing. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
| `RUN_LVS` | Enables running LVS. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
| `RUN_MAGIC` | Enables running magic and GDSII streaming. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
| `RUN_MAGIC_DRC` | Enables running magic DRC on GDS-II produced by magic. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
| `RUN_KLAYOUT` | Enables running Klayout and GDSII streaming. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
| `RUN_KLAYOUT_DRC` | Enables running Klayout DRC on GDS-II produced by magic. 1 = Enabled, 0 = Disabled <br> (Default: `1`)|
| `KLAYOUT_DRC_KLAYOUT_GDS` | Enables running Klayout DRC on GDS-II produced by Klayout. 1 = Enabled, 0 = Disabled <br> (Default: `0`)|

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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."

View File

@@ -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

View File

@@ -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 \
</dev/null \
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(finishing_logs)/drc.log]
try_catch magic \
-noconsole \
-dnull \
-rcfile $::env(MAGIC_MAGICRC) \
$::env(SCRIPTS_DIR)/magic/drc.tcl \
</dev/null \
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(finishing_logs)/drc.log]
puts_info "Converting Magic DRC Violations to Magic Readable Format..."
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_tcl.py \
-i $::env(drc_prefix).rpt \
-o $::env(drc_prefix).tcl
puts_info "Converting Magic DRC Violations to Magic Readable Format..."
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_tcl.py \
-i $::env(drc_prefix).rpt \
-o $::env(drc_prefix).tcl
puts_info "Converting Magic DRC Violations to Klayout XML Database..."
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_tr_drc.py \
-i $::env(drc_prefix).rpt \
-o $::env(drc_prefix).tr
puts_info "Converting Magic DRC Violations to Klayout XML Database..."
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_tr_drc.py \
-i $::env(drc_prefix).rpt \
-o $::env(drc_prefix).tr
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/tr2klayout.py \
-i $::env(drc_prefix).tr \
-o $::env(drc_prefix).klayout.xml \
--design-name $::env(DESIGN_NAME)
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/tr2klayout.py \
-i $::env(drc_prefix).tr \
-o $::env(drc_prefix).klayout.xml \
--design-name $::env(DESIGN_NAME)
if { $::env(MAGIC_CONVERT_DRC_TO_RDB) == 1 } {
puts_info "Converting DRC Violations to RDB Format..."
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_rdb.py \
--magic_drc_in $::env(drc_prefix).rpt \
--rdb_out $::env(drc_prefix).rdb
puts_info "Converted DRC Violations to RDB Format"
}
file copy -force $::env(MAGIC_MAGICRC) $::env(finishing_results)/.magicrc
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "drc - magic"
quit_on_magic_drc -log $::env(drc_prefix).tr
if { $::env(MAGIC_CONVERT_DRC_TO_RDB) == 1 } {
puts_info "Converting DRC Violations to RDB Format..."
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_rdb.py \
--magic_drc_in $::env(drc_prefix).rpt \
--rdb_out $::env(drc_prefix).rdb
puts_info "Converted DRC Violations to RDB Format"
}
file copy -force $::env(MAGIC_MAGICRC) $::env(finishing_results)/.magicrc
TIMER::timer_stop
exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "drc - magic"
quit_on_magic_drc -log $::env(drc_prefix).tr
}
}
proc run_magic_spice_export {args} {
@@ -304,7 +306,7 @@ antennacheck
try_catch awk "/Cell:/ {print \$2}" $antenna_log > $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"

View File

@@ -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