librelane 2.4.0.dev7__py3-none-any.whl → 3.0.0.dev22__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of librelane might be problematic. Click here for more details.
- librelane/__main__.py +12 -15
- librelane/common/__init__.py +1 -1
- librelane/common/drc.py +88 -7
- librelane/common/misc.py +6 -6
- librelane/common/toolbox.py +1 -1
- librelane/config/config.py +5 -1
- librelane/config/flow.py +51 -66
- librelane/config/pdk_compat.py +79 -2
- librelane/config/preprocessor.py +1 -1
- librelane/config/variable.py +2 -2
- librelane/flows/classic.py +1 -0
- librelane/flows/flow.py +3 -6
- librelane/flows/sequential.py +85 -40
- librelane/plugins.py +1 -1
- librelane/scripts/magic/common/read.tcl +2 -2
- librelane/scripts/magic/gds/extras_mag.tcl +2 -2
- librelane/scripts/odbpy/diodes.py +2 -2
- librelane/scripts/openroad/common/dpl.tcl +1 -1
- librelane/scripts/openroad/common/grt.tcl +3 -3
- librelane/scripts/openroad/common/io.tcl +163 -45
- librelane/scripts/openroad/common/resizer.tcl +1 -40
- librelane/scripts/openroad/common/set_global_connections.tcl +2 -2
- librelane/scripts/openroad/common/set_power_nets.tcl +1 -1
- librelane/scripts/openroad/common/set_rc.tcl +159 -40
- librelane/scripts/openroad/cts.tcl +37 -6
- librelane/scripts/openroad/cut_rows.tcl +19 -4
- librelane/scripts/openroad/drt.tcl +59 -8
- librelane/scripts/openroad/dump_rc.tcl +105 -0
- librelane/scripts/openroad/fill.tcl +2 -2
- librelane/scripts/openroad/floorplan.tcl +5 -3
- librelane/scripts/openroad/gpl.tcl +7 -8
- librelane/scripts/openroad/gui.tcl +22 -2
- librelane/scripts/openroad/insert_buffer.tcl +2 -2
- librelane/scripts/openroad/ioplacer.tcl +1 -2
- librelane/scripts/openroad/irdrop.tcl +3 -3
- librelane/scripts/openroad/pdn.tcl +17 -18
- librelane/scripts/openroad/rcx.tcl +1 -1
- librelane/scripts/openroad/repair_design.tcl +14 -7
- librelane/scripts/openroad/repair_design_postgrt.tcl +13 -6
- librelane/scripts/openroad/rsz_timing_postcts.tcl +13 -12
- librelane/scripts/openroad/rsz_timing_postgrt.tcl +13 -12
- librelane/scripts/openroad/sta/check_macro_instances.tcl +1 -1
- librelane/scripts/openroad/tapcell.tcl +13 -6
- librelane/scripts/openroad/ungpl.tcl +23 -0
- librelane/state/__init__.py +1 -1
- librelane/state/design_format.py +194 -142
- librelane/state/state.py +20 -21
- librelane/steps/checker.py +12 -1
- librelane/steps/common_variables.py +4 -4
- librelane/steps/cvc_rv.py +1 -1
- librelane/steps/klayout.py +14 -6
- librelane/steps/magic.py +18 -2
- librelane/steps/misc.py +1 -1
- librelane/steps/odb.py +50 -31
- librelane/steps/openroad.py +455 -128
- librelane/steps/pyosys.py +20 -5
- librelane/steps/step.py +17 -20
- librelane/steps/tclstep.py +9 -7
- librelane/steps/yosys.py +1 -1
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/METADATA +1 -1
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/RECORD +63 -61
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/WHEEL +0 -0
- {librelane-2.4.0.dev7.dist-info → librelane-3.0.0.dev22.dist-info}/entry_points.txt +0 -0
|
@@ -23,30 +23,29 @@ read_pdn_cfg
|
|
|
23
23
|
set arg_list [list]
|
|
24
24
|
if { $::env(FP_PDN_SKIPTRIM) } {
|
|
25
25
|
lappend arg_list -skip_trim
|
|
26
|
-
puts "adding -skip_trim to pdngen"
|
|
27
26
|
}
|
|
28
27
|
# run PDNGEN
|
|
29
|
-
if {[catch {pdngen {*}$arg_list} errmsg]} {
|
|
28
|
+
if {[catch {log_cmd pdngen {*}$arg_list} errmsg]} {
|
|
30
29
|
puts stderr $errmsg
|
|
31
|
-
|
|
32
|
-
}
|
|
30
|
+
exit_unless_gui 1
|
|
31
|
+
} else {
|
|
32
|
+
write_views
|
|
33
|
+
report_design_area_metrics
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
foreach {net} "$::env(VDD_NETS) $::env(GND_NETS)" {
|
|
36
|
+
set report_file $::env(STEP_DIR)/$net-grid-errors.rpt
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
# For some reason, check_power_grid is… totally okay if no nodes are found
|
|
39
|
+
# at all. i.e. PDN generation has completely failed.
|
|
40
|
+
# This is a fallback file.
|
|
41
|
+
set f [open $report_file "w"]
|
|
42
|
+
puts $f ""
|
|
43
|
+
close $f
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
set f [open $report_file "w"]
|
|
44
|
-
puts $f "violation type: no nodes"
|
|
45
|
-
puts $f " srcs: "
|
|
46
|
-
puts $f " - N/A"
|
|
47
|
-
close $f
|
|
45
|
+
if { [catch {check_power_grid -net $net -error_file $report_file} err] } {
|
|
46
|
+
puts stderr "\[WARNING\] Grid check for $net failed: $err"
|
|
47
|
+
}
|
|
48
48
|
|
|
49
|
-
if { [catch {check_power_grid -net $net -error_file $report_file} err] } {
|
|
50
|
-
puts stderr "\[WARNING\] Grid check for $net failed: $err"
|
|
51
49
|
}
|
|
50
|
+
|
|
52
51
|
}
|
|
@@ -26,7 +26,7 @@ if { !$::env(RCX_MERGE_VIA_WIRE_RES) } {
|
|
|
26
26
|
# RCX
|
|
27
27
|
puts "Using RCX ruleset '$::env(RCX_RULESET)'…"
|
|
28
28
|
define_process_corner -ext_model_index 0 CURRENT_CORNER
|
|
29
|
-
extract_parasitics $rcx_flags\
|
|
29
|
+
log_cmd extract_parasitics $rcx_flags\
|
|
30
30
|
-ext_model_file $::env(RCX_RULESET)\
|
|
31
31
|
-lef_res
|
|
32
32
|
write_views
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
source $::env(SCRIPTS_DIR)/openroad/common/resizer.tcl
|
|
16
16
|
|
|
17
|
-
load_rsz_corners
|
|
18
17
|
read_current_odb
|
|
19
18
|
|
|
20
19
|
unset_propagated_clock [all_clocks]
|
|
@@ -42,17 +41,25 @@ if { $::env(DESIGN_REPAIR_BUFFER_OUTPUT_PORTS) } {
|
|
|
42
41
|
buffer_ports -outputs
|
|
43
42
|
}
|
|
44
43
|
|
|
44
|
+
set arg_list [list]
|
|
45
|
+
lappend arg_list -verbose
|
|
46
|
+
lappend arg_list -max_wire_length $::env(DESIGN_REPAIR_MAX_WIRE_LENGTH)
|
|
47
|
+
lappend arg_list -slew_margin $::env(DESIGN_REPAIR_MAX_SLEW_PCT)
|
|
48
|
+
lappend arg_list -cap_margin $::env(DESIGN_REPAIR_MAX_CAP_PCT)
|
|
49
|
+
if { [info exists ::env(DESIGN_REPAIR_MAX_UTILIZATION)] } {
|
|
50
|
+
lappend arg_list -max_utilization $::env(DESIGN_REPAIR_MAX_UTILIZATION)
|
|
51
|
+
}
|
|
52
|
+
if { [info exists ::env(DESIGN_REPAIR_BUFFER_GAIN)] } {
|
|
53
|
+
lappend arg_list -buffer_gain $::env(DESIGN_REPAIR_BUFFER_GAIN)
|
|
54
|
+
}
|
|
45
55
|
# Repair Design
|
|
46
|
-
repair_design
|
|
47
|
-
-max_wire_length $::env(DESIGN_REPAIR_MAX_WIRE_LENGTH) \
|
|
48
|
-
-slew_margin $::env(DESIGN_REPAIR_MAX_SLEW_PCT) \
|
|
49
|
-
-cap_margin $::env(DESIGN_REPAIR_MAX_CAP_PCT)
|
|
56
|
+
log_cmd repair_design {*}$arg_list
|
|
50
57
|
|
|
51
58
|
if { $::env(DESIGN_REPAIR_TIE_FANOUT) } {
|
|
52
59
|
# repair tie lo fanout
|
|
53
|
-
repair_tie_fanout -separation $::env(DESIGN_REPAIR_TIE_SEPARATION) $::env(SYNTH_TIELO_CELL)
|
|
60
|
+
repair_tie_fanout -verbose -separation $::env(DESIGN_REPAIR_TIE_SEPARATION) $::env(SYNTH_TIELO_CELL)
|
|
54
61
|
# repair tie hi fanout
|
|
55
|
-
repair_tie_fanout -separation $::env(DESIGN_REPAIR_TIE_SEPARATION) $::env(SYNTH_TIEHI_CELL)
|
|
62
|
+
repair_tie_fanout -verbose -separation $::env(DESIGN_REPAIR_TIE_SEPARATION) $::env(SYNTH_TIEHI_CELL)
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
report_floating_nets -verbose
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
source $::env(SCRIPTS_DIR)/openroad/common/resizer.tcl
|
|
16
16
|
|
|
17
|
-
load_rsz_corners
|
|
18
17
|
read_current_odb
|
|
19
18
|
|
|
20
19
|
set_propagated_clock [all_clocks]
|
|
@@ -31,11 +30,19 @@ source $::env(SCRIPTS_DIR)/openroad/common/grt.tcl
|
|
|
31
30
|
#}
|
|
32
31
|
estimate_parasitics -global_routing
|
|
33
32
|
|
|
34
|
-
# Repair
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
# Repair Design
|
|
34
|
+
set arg_list [list]
|
|
35
|
+
lappend arg_list -verbose
|
|
36
|
+
lappend arg_list -max_wire_length $::env(GRT_DESIGN_REPAIR_MAX_WIRE_LENGTH)
|
|
37
|
+
lappend arg_list -slew_margin $::env(GRT_DESIGN_REPAIR_MAX_SLEW_PCT)
|
|
38
|
+
lappend arg_list -cap_margin $::env(GRT_DESIGN_REPAIR_MAX_CAP_PCT)
|
|
39
|
+
if { [info exists ::env(GRT_DESIGN_REPAIR_MAX_UTILIZATION)] } {
|
|
40
|
+
lappend arg_list -max_utilization $::env(GRT_DESIGN_REPAIR_MAX_UTILIZATION)
|
|
41
|
+
}
|
|
42
|
+
if { [info exists ::env(GRT_DESIGN_REPAIR_BUFFER_GAIN)] } {
|
|
43
|
+
lappend arg_list -buffer_gain $::env(GRT_DESIGN_REPAIR_BUFFER_GAIN)
|
|
44
|
+
}
|
|
45
|
+
log_cmd repair_design {*}$arg_list
|
|
39
46
|
|
|
40
47
|
# Re-DPL and GRT
|
|
41
48
|
source $::env(SCRIPTS_DIR)/openroad/common/dpl.tcl
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2020-
|
|
1
|
+
# Copyright 2020-2024 Efabless Corporation
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
source $::env(SCRIPTS_DIR)/openroad/common/resizer.tcl
|
|
16
16
|
|
|
17
|
-
load_rsz_corners
|
|
18
17
|
read_current_odb
|
|
19
18
|
|
|
20
19
|
set_propagated_clock [all_clocks]
|
|
@@ -34,9 +33,11 @@ lappend setup_args -verbose
|
|
|
34
33
|
lappend setup_args -setup
|
|
35
34
|
lappend setup_args -setup_margin $::env(PL_RESIZER_SETUP_SLACK_MARGIN)
|
|
36
35
|
lappend setup_args -max_buffer_percent $::env(PL_RESIZER_SETUP_MAX_BUFFER_PCT)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
append_if_not_flag setup_args PL_RESIZER_SETUP_BUFFERING -skip_buffering
|
|
37
|
+
append_if_not_flag setup_args PL_RESIZER_SETUP_BUFFER_REMOVAL -skip_buffer_removal
|
|
38
|
+
append_if_not_flag setup_args PL_RESIZER_SETUP_GATE_CLONING -skip_gate_cloning
|
|
39
|
+
append_if_exists_argument setup_args PL_RESIZER_SETUP_REPAIR_TNS_PCT -repair_tns
|
|
40
|
+
append_if_exists_argument setup_args PL_RESIZER_SETUP_MAX_UTIL_PCT -max_utilization
|
|
40
41
|
|
|
41
42
|
set hold_args [list]
|
|
42
43
|
lappend hold_args -verbose
|
|
@@ -44,16 +45,16 @@ lappend hold_args -hold
|
|
|
44
45
|
lappend hold_args -setup_margin $::env(PL_RESIZER_SETUP_SLACK_MARGIN)
|
|
45
46
|
lappend hold_args -hold_margin $::env(PL_RESIZER_HOLD_SLACK_MARGIN)
|
|
46
47
|
lappend hold_args -max_buffer_percent $::env(PL_RESIZER_HOLD_MAX_BUFFER_PCT)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
append_if_flag hold_args PL_RESIZER_ALLOW_SETUP_VIOS -allow_setup_violations
|
|
49
|
+
append_if_exists_argument hold_args PL_RESIZER_HOLD_REPAIR_TNS_PCT -repair_tns
|
|
50
|
+
append_if_exists_argument hold_args PL_RESIZER_HOLD_MAX_UTIL_PCT -max_utilization
|
|
50
51
|
|
|
51
52
|
if { $::env(PL_RESIZER_FIX_HOLD_FIRST) == 1 } {
|
|
52
|
-
repair_timing {*}$hold_args
|
|
53
|
-
repair_timing {*}$setup_args
|
|
53
|
+
log_cmd repair_timing {*}$hold_args
|
|
54
|
+
log_cmd repair_timing {*}$setup_args
|
|
54
55
|
} else {
|
|
55
|
-
repair_timing {*}$setup_args
|
|
56
|
-
repair_timing {*}$hold_args
|
|
56
|
+
log_cmd repair_timing {*}$setup_args
|
|
57
|
+
log_cmd repair_timing {*}$hold_args
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
# Legalize
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2020-
|
|
1
|
+
# Copyright 2020-2024 Efabless Corporation
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
source $::env(SCRIPTS_DIR)/openroad/common/resizer.tcl
|
|
16
16
|
|
|
17
|
-
load_rsz_corners
|
|
18
17
|
read_current_odb
|
|
19
18
|
|
|
20
19
|
set_propagated_clock [all_clocks]
|
|
@@ -37,9 +36,11 @@ lappend setup_args -verbose
|
|
|
37
36
|
lappend setup_args -setup
|
|
38
37
|
lappend setup_args -setup_margin $::env(GRT_RESIZER_SETUP_SLACK_MARGIN)
|
|
39
38
|
lappend setup_args -max_buffer_percent $::env(GRT_RESIZER_SETUP_MAX_BUFFER_PCT)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
append_if_not_flag setup_args GRT_RESIZER_SETUP_BUFFERING -skip_buffering
|
|
40
|
+
append_if_not_flag setup_args GRT_RESIZER_SETUP_BUFFER_REMOVAL -skip_buffer_removal
|
|
41
|
+
append_if_not_flag setup_args GRT_RESIZER_SETUP_GATE_CLONING -skip_gate_cloning
|
|
42
|
+
append_if_exists_argument setup_args GRT_RESIZER_SETUP_REPAIR_TNS_PCT -repair_tns
|
|
43
|
+
append_if_exists_argument setup_args GRT_RESIZER_SETUP_MAX_UTIL_PCT -max_utilization
|
|
43
44
|
|
|
44
45
|
set hold_args [list]
|
|
45
46
|
lappend hold_args -verbose
|
|
@@ -47,16 +48,16 @@ lappend hold_args -hold
|
|
|
47
48
|
lappend hold_args -setup_margin $::env(GRT_RESIZER_SETUP_SLACK_MARGIN)
|
|
48
49
|
lappend hold_args -hold_margin $::env(GRT_RESIZER_HOLD_SLACK_MARGIN)
|
|
49
50
|
lappend hold_args -max_buffer_percent $::env(GRT_RESIZER_HOLD_MAX_BUFFER_PCT)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
append_if_flag hold_args GRT_RESIZER_ALLOW_SETUP_VIOS -allow_setup_violations
|
|
52
|
+
append_if_exists_argument hold_args GRT_RESIZER_HOLD_REPAIR_TNS_PCT -repair_tns
|
|
53
|
+
append_if_exists_argument hold_args GRT_RESIZER_HOLD_MAX_UTIL_PCT -max_utilization
|
|
53
54
|
|
|
54
55
|
if { $::env(GRT_RESIZER_FIX_HOLD_FIRST) == 1 } {
|
|
55
|
-
repair_timing {*}$hold_args
|
|
56
|
-
repair_timing {*}$setup_args
|
|
56
|
+
log_cmd repair_timing {*}$hold_args
|
|
57
|
+
log_cmd repair_timing {*}$setup_args
|
|
57
58
|
} else {
|
|
58
|
-
repair_timing {*}$setup_args
|
|
59
|
-
repair_timing {*}$hold_args
|
|
59
|
+
log_cmd repair_timing {*}$setup_args
|
|
60
|
+
log_cmd repair_timing {*}$hold_args
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
# Re-DPL and GRT
|
|
@@ -14,12 +14,19 @@
|
|
|
14
14
|
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
15
|
read_current_odb
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-halo_width_x $::env(FP_MACRO_HORIZONTAL_HALO)\
|
|
22
|
-
-halo_width_y $::env(FP_MACRO_VERTICAL_HALO)
|
|
17
|
+
set tapcell_args [list]
|
|
18
|
+
append_if_exists_argument tapcell_args FP_TAPCELL_DIST -distance
|
|
19
|
+
append_if_exists_argument tapcell_args WELLTAP_CELL -tapcell_master
|
|
20
|
+
append_if_exists_argument tapcell_args ENDCAP_CELL -endcap_master
|
|
23
21
|
|
|
22
|
+
if { [llength tapcell_args] } {
|
|
23
|
+
log_cmd tapcell\
|
|
24
|
+
-halo_width_x $::env(FP_MACRO_HORIZONTAL_HALO)\
|
|
25
|
+
-halo_width_y $::env(FP_MACRO_VERTICAL_HALO)\
|
|
26
|
+
{*}$tapcell_args
|
|
27
|
+
|
|
28
|
+
} else {
|
|
29
|
+
puts "\[INFO\] WELLTAP_CELL and ENDCAP_CELL both unspecified. Doing nothing."
|
|
30
|
+
}
|
|
24
31
|
|
|
25
32
|
write_views
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright 2024 Efabless Corporation
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
source $::env(SCRIPTS_DIR)/openroad/common/io.tcl
|
|
15
|
+
read_current_odb
|
|
16
|
+
|
|
17
|
+
set ::insts [$::block getInsts]
|
|
18
|
+
|
|
19
|
+
foreach inst $::insts {
|
|
20
|
+
$inst setPlacementStatus "NONE"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
write_views
|
librelane/state/__init__.py
CHANGED
|
@@ -20,5 +20,5 @@ This module manages the State of a Design before and after the execution of an
|
|
|
20
20
|
LibreLane step. The State is essentially a list of views in various formats in
|
|
21
21
|
addition to the cumulative set of metrics created by previous Steps.
|
|
22
22
|
"""
|
|
23
|
-
from .design_format import DesignFormat
|
|
23
|
+
from .design_format import DesignFormat
|
|
24
24
|
from .state import State, InvalidState, StateElement
|
librelane/state/design_format.py
CHANGED
|
@@ -11,26 +11,38 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
from dataclasses import dataclass, field, replace
|
|
16
|
+
from typing import Dict, List, Optional, ClassVar
|
|
17
|
+
from deprecated.sphinx import deprecated
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DFMetaclass(type):
|
|
21
|
+
def __getattr__(Self, key: str):
|
|
22
|
+
if df := Self.factory.get(key):
|
|
23
|
+
return df
|
|
24
|
+
raise AttributeError(
|
|
25
|
+
"Unknown DesignFormat or Type[DesignFormat] attribute",
|
|
26
|
+
key,
|
|
27
|
+
Self,
|
|
28
|
+
)
|
|
17
29
|
|
|
18
30
|
|
|
19
31
|
@dataclass
|
|
20
|
-
class
|
|
32
|
+
class DesignFormat(metaclass=DFMetaclass):
|
|
21
33
|
"""
|
|
22
34
|
Metadata about the various possible text or binary representations (views)
|
|
23
35
|
of any design.
|
|
24
36
|
|
|
25
|
-
For example, ``DesignFormat.
|
|
26
|
-
views.
|
|
37
|
+
For example, ``DesignFormat.nl`` has the metadata for Netlist views.
|
|
27
38
|
|
|
28
|
-
:param id: A lowercase alphanumeric identifier for the design
|
|
29
|
-
|
|
30
|
-
be addressed in the next major version of LibreLane as it would be a
|
|
31
|
-
breaking change.
|
|
39
|
+
:param id: A lowercase alphanumeric/underscore identifier for the design
|
|
40
|
+
format.
|
|
32
41
|
:param extension: The file extension for designs saved in this format.
|
|
33
|
-
:param
|
|
42
|
+
:param full_name: A human-readable name for this design format.
|
|
43
|
+
:param alts: A list of alternate ids used to access the DesignFormat by
|
|
44
|
+
the subscript operator. Includes its OpenLane <3.0.0 enumeration name
|
|
45
|
+
for limited backwards compatibility.
|
|
34
46
|
:param folder_override: The subdirectory when
|
|
35
47
|
:meth:`librelane.state.State.save_snapshot` is called on a state. If
|
|
36
48
|
unset, the value for ``id`` will be used.
|
|
@@ -40,7 +52,8 @@ class DesignFormatObject:
|
|
|
40
52
|
|
|
41
53
|
id: str
|
|
42
54
|
extension: str
|
|
43
|
-
|
|
55
|
+
full_name: str
|
|
56
|
+
alts: List[str] = field(default_factory=list)
|
|
44
57
|
folder_override: Optional[str] = None
|
|
45
58
|
multiple: bool = False
|
|
46
59
|
|
|
@@ -51,145 +64,184 @@ class DesignFormatObject:
|
|
|
51
64
|
return self.folder_override or self.id
|
|
52
65
|
|
|
53
66
|
@property
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class DesignFormat(Enum):
|
|
59
|
-
"""
|
|
60
|
-
An `enumeration <https://docs.python.org/3/library/enum.html>`_ of a number
|
|
61
|
-
of :class:`librelane.state.DesignFormatObject`\\s representing the various
|
|
62
|
-
possible text or binary representations (views) supported by LibreLane
|
|
63
|
-
states.
|
|
64
|
-
|
|
65
|
-
Members of this enumeration are used as the keys of
|
|
66
|
-
:class:`librelane.state.State` objects.
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
NETLIST: DesignFormatObject = DesignFormatObject(
|
|
70
|
-
"nl",
|
|
71
|
-
"nl.v",
|
|
72
|
-
"Verilog Netlist",
|
|
73
|
-
)
|
|
74
|
-
POWERED_NETLIST: DesignFormatObject = DesignFormatObject(
|
|
75
|
-
"pnl",
|
|
76
|
-
"pnl.v",
|
|
77
|
-
"Powered Verilog Netlist",
|
|
78
|
-
)
|
|
79
|
-
POWERED_NETLIST_SDF_FRIENDLY: DesignFormatObject = DesignFormatObject(
|
|
80
|
-
"pnl-sdf-friendly",
|
|
81
|
-
"pnl-sdf.v",
|
|
82
|
-
"Powered Verilog Netlist For SDF Simulation (Without Fill Cells)",
|
|
83
|
-
folder_override="pnl",
|
|
84
|
-
)
|
|
85
|
-
POWERED_NETLIST_NO_PHYSICAL_CELLS: DesignFormatObject = DesignFormatObject(
|
|
86
|
-
"pnl-npc",
|
|
87
|
-
"pnl-npc.v",
|
|
88
|
-
"Powered Verilog Netlist Without Physical Cells (Fill Cells and Diode Cells)",
|
|
89
|
-
folder_override="pnl",
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
DEF: DesignFormatObject = DesignFormatObject(
|
|
93
|
-
"def",
|
|
94
|
-
"def",
|
|
95
|
-
"Design Exchange Format",
|
|
96
|
-
)
|
|
97
|
-
LEF: DesignFormatObject = DesignFormatObject(
|
|
98
|
-
"lef",
|
|
99
|
-
"lef",
|
|
100
|
-
"Library Exchange Format",
|
|
101
|
-
)
|
|
102
|
-
OPENROAD_LEF: DesignFormatObject = DesignFormatObject(
|
|
103
|
-
"openroad-lef",
|
|
104
|
-
"openroad.lef",
|
|
105
|
-
"Library Exchange Format Generated by OpenROAD",
|
|
106
|
-
folder_override="lef",
|
|
107
|
-
)
|
|
108
|
-
ODB: DesignFormatObject = DesignFormatObject(
|
|
109
|
-
"odb",
|
|
110
|
-
"odb",
|
|
111
|
-
"OpenDB Database",
|
|
67
|
+
@deprecated(
|
|
68
|
+
"The DesignFormat is directly returned now, no need for .value",
|
|
69
|
+
version="3.0.0",
|
|
70
|
+
action="once",
|
|
112
71
|
)
|
|
72
|
+
def value(self) -> DesignFormat:
|
|
73
|
+
return self
|
|
113
74
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"Design Constraints",
|
|
118
|
-
)
|
|
119
|
-
SDF: DesignFormatObject = DesignFormatObject(
|
|
120
|
-
"sdf",
|
|
121
|
-
"sdf",
|
|
122
|
-
"Standard Delay Format",
|
|
123
|
-
multiple=True,
|
|
124
|
-
)
|
|
125
|
-
SPEF: DesignFormatObject = DesignFormatObject(
|
|
126
|
-
"spef",
|
|
127
|
-
"spef",
|
|
128
|
-
"Standard Parasitics Extraction Format",
|
|
129
|
-
multiple=True, # nom, min, max, ...
|
|
130
|
-
)
|
|
131
|
-
LIB: DesignFormatObject = DesignFormatObject(
|
|
132
|
-
"lib",
|
|
133
|
-
"lib",
|
|
134
|
-
"LIB Timing Library Format",
|
|
135
|
-
multiple=True,
|
|
136
|
-
)
|
|
137
|
-
SPICE: DesignFormatObject = DesignFormatObject(
|
|
138
|
-
"spice",
|
|
139
|
-
"spice",
|
|
140
|
-
"Simulation Program with Integrated Circuit Emphasis",
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
MAG: DesignFormatObject = DesignFormatObject(
|
|
144
|
-
"mag",
|
|
145
|
-
"mag",
|
|
146
|
-
"Magic VLSI View",
|
|
147
|
-
)
|
|
75
|
+
@property
|
|
76
|
+
def optional(self) -> bool:
|
|
77
|
+
return self._instance_optional
|
|
148
78
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"
|
|
152
|
-
"
|
|
153
|
-
|
|
154
|
-
MAG_GDS: DesignFormatObject = DesignFormatObject(
|
|
155
|
-
"mag_gds",
|
|
156
|
-
"magic.gds",
|
|
157
|
-
"GDSII Stream (Magic)",
|
|
158
|
-
)
|
|
159
|
-
KLAYOUT_GDS: DesignFormatObject = DesignFormatObject(
|
|
160
|
-
"klayout_gds",
|
|
161
|
-
"klayout.gds",
|
|
162
|
-
"GDSII Stream (KLayout)",
|
|
79
|
+
@property
|
|
80
|
+
@deprecated(
|
|
81
|
+
".name has been removed because it's redundant, use .id",
|
|
82
|
+
version="3.0.0",
|
|
83
|
+
action="once",
|
|
163
84
|
)
|
|
85
|
+
def name(self) -> str:
|
|
86
|
+
return self.id
|
|
164
87
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
"h.json",
|
|
168
|
-
"Design JSON Header File",
|
|
169
|
-
)
|
|
170
|
-
VERILOG_HEADER: DesignFormatObject = DesignFormatObject(
|
|
171
|
-
"vh",
|
|
172
|
-
"vh",
|
|
173
|
-
"Verilog Header",
|
|
174
|
-
)
|
|
88
|
+
def register(self):
|
|
89
|
+
self.__class__.factory.register(self)
|
|
175
90
|
|
|
176
91
|
def __str__(self) -> str:
|
|
177
|
-
return self.
|
|
92
|
+
return self.id
|
|
93
|
+
|
|
94
|
+
def __hash__(self):
|
|
95
|
+
return hash(self.id)
|
|
178
96
|
|
|
179
97
|
@staticmethod
|
|
98
|
+
@deprecated(
|
|
99
|
+
"Use DesignFormat.factory.get",
|
|
100
|
+
version="3.0.0",
|
|
101
|
+
action="once",
|
|
102
|
+
)
|
|
180
103
|
def by_id(id: str) -> Optional["DesignFormat"]:
|
|
181
|
-
return
|
|
104
|
+
return DesignFormat.factory.get(id)
|
|
105
|
+
|
|
106
|
+
class DesignFormatFactory(object):
|
|
107
|
+
"""
|
|
108
|
+
A factory singleton for DesignFormats, allowing them to be registered
|
|
109
|
+
and then retrieved by a string name.
|
|
110
|
+
|
|
111
|
+
See https://en.wikipedia.org/wiki/Factory_(object-oriented_programming) for
|
|
112
|
+
a primer.
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
_registry: ClassVar[Dict[str, DesignFormat]] = {}
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def register(Self, df: DesignFormat) -> DesignFormat:
|
|
119
|
+
"""
|
|
120
|
+
Adds a DesignFormat to the registry using its
|
|
121
|
+
:attr:`DesignFormat.id`, :attr:`DesignFormat.name` and
|
|
122
|
+
:attr:`DesignFormat.alts` attributes.
|
|
123
|
+
"""
|
|
124
|
+
Self._registry[df.id] = df
|
|
125
|
+
for alt in df.alts:
|
|
126
|
+
Self._registry[alt] = df
|
|
127
|
+
return df
|
|
128
|
+
|
|
129
|
+
@classmethod
|
|
130
|
+
def get(Self, name: str) -> Optional[DesignFormat]:
|
|
131
|
+
"""
|
|
132
|
+
Retrieves a DesignFormat type from the registry using a lookup
|
|
133
|
+
string.
|
|
134
|
+
|
|
135
|
+
:param name: The registered name of the Step. Case-insensitive.
|
|
136
|
+
"""
|
|
137
|
+
return Self._registry.get(name)
|
|
138
|
+
|
|
139
|
+
@classmethod
|
|
140
|
+
def list(Self) -> List[str]:
|
|
141
|
+
"""
|
|
142
|
+
:returns: A list of IDs of all registered DesignFormat.
|
|
143
|
+
"""
|
|
144
|
+
return [cls.id for cls in Self._registry.values()]
|
|
145
|
+
|
|
146
|
+
factory: ClassVar = DesignFormatFactory
|
|
182
147
|
|
|
183
148
|
def mkOptional(self) -> "DesignFormat":
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
149
|
+
return replace(self, _instance_optional=True)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# Common Design Formats
|
|
153
|
+
DesignFormat(
|
|
154
|
+
"nl",
|
|
155
|
+
"nl.v",
|
|
156
|
+
"Verilog Netlist",
|
|
157
|
+
alts=["NETLIST"],
|
|
158
|
+
).register()
|
|
159
|
+
|
|
160
|
+
DesignFormat(
|
|
161
|
+
"pnl",
|
|
162
|
+
"pnl.v",
|
|
163
|
+
"Powered Verilog Netlist",
|
|
164
|
+
alts=["POWERED_NETLIST"],
|
|
165
|
+
).register()
|
|
166
|
+
|
|
167
|
+
DesignFormat(
|
|
168
|
+
"sdf_pnl",
|
|
169
|
+
"sdf_pnl.v",
|
|
170
|
+
"Powered Verilog Netlist for SDF Simulation (No Fills)",
|
|
171
|
+
alts=["SDF_FRIENDLY_POWERED_NETLIST"],
|
|
172
|
+
folder_override="pnl",
|
|
173
|
+
).register()
|
|
174
|
+
|
|
175
|
+
DesignFormat(
|
|
176
|
+
"logical_pnl",
|
|
177
|
+
"logical_pnl.v",
|
|
178
|
+
"Logical cell-only Powered Verilog Netlist",
|
|
179
|
+
alts=["LOGICAL_POWERED_NETLIST"],
|
|
180
|
+
folder_override="pnl",
|
|
181
|
+
).register()
|
|
182
|
+
|
|
183
|
+
DesignFormat(
|
|
184
|
+
"def",
|
|
185
|
+
"def",
|
|
186
|
+
"Design Exchange Format",
|
|
187
|
+
alts=["def_", "DEF"],
|
|
188
|
+
).register()
|
|
189
|
+
|
|
190
|
+
DesignFormat(
|
|
191
|
+
"lef",
|
|
192
|
+
"lef",
|
|
193
|
+
"Library Exchange Format",
|
|
194
|
+
alts=["LEF"],
|
|
195
|
+
).register()
|
|
196
|
+
|
|
197
|
+
DesignFormat(
|
|
198
|
+
"sdc",
|
|
199
|
+
"sdc",
|
|
200
|
+
"Design Constraints",
|
|
201
|
+
alts=["SDC"],
|
|
202
|
+
).register()
|
|
203
|
+
|
|
204
|
+
DesignFormat(
|
|
205
|
+
"sdf",
|
|
206
|
+
"sdf",
|
|
207
|
+
"Standard Delay Format",
|
|
208
|
+
alts=["SDF"],
|
|
209
|
+
multiple=True,
|
|
210
|
+
).register()
|
|
211
|
+
|
|
212
|
+
DesignFormat(
|
|
213
|
+
"spef",
|
|
214
|
+
"spef",
|
|
215
|
+
"Standard Parasitics Extraction Format",
|
|
216
|
+
alts=["SPEF"],
|
|
217
|
+
multiple=True, # nom, min, max, ...
|
|
218
|
+
).register()
|
|
219
|
+
|
|
220
|
+
DesignFormat(
|
|
221
|
+
"lib",
|
|
222
|
+
"lib",
|
|
223
|
+
"LIB Timing Library Format",
|
|
224
|
+
alts=["LIB"],
|
|
225
|
+
multiple=True,
|
|
226
|
+
).register()
|
|
227
|
+
|
|
228
|
+
DesignFormat(
|
|
229
|
+
"spice",
|
|
230
|
+
"spice",
|
|
231
|
+
"Simulation Program with Integrated Circuit Emphasis",
|
|
232
|
+
alts=["SPICE"],
|
|
233
|
+
).register()
|
|
234
|
+
|
|
235
|
+
DesignFormat(
|
|
236
|
+
"gds",
|
|
237
|
+
"gds",
|
|
238
|
+
"GDSII Stream",
|
|
239
|
+
alts=["GDS"],
|
|
240
|
+
).register()
|
|
241
|
+
|
|
242
|
+
DesignFormat(
|
|
243
|
+
"vh",
|
|
244
|
+
"vh",
|
|
245
|
+
"Verilog Header",
|
|
246
|
+
alts=["VERILOG_HEADER"],
|
|
247
|
+
).register()
|