siliconcompiler 0.30.0__py3-none-any.whl → 0.31.1__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.
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/sc_install.py +26 -4
- siliconcompiler/apps/sc_remote.py +1 -3
- siliconcompiler/core.py +24 -9
- siliconcompiler/flowgraph.py +11 -23
- siliconcompiler/{package.py → package/__init__.py} +62 -176
- siliconcompiler/package/git.py +81 -0
- siliconcompiler/package/https.py +93 -0
- siliconcompiler/remote/schema.py +9 -8
- siliconcompiler/report/report.py +4 -3
- siliconcompiler/scheduler/__init__.py +127 -113
- siliconcompiler/scheduler/docker_runner.py +4 -4
- siliconcompiler/scheduler/run_node.py +3 -3
- siliconcompiler/scheduler/send_messages.py +1 -1
- siliconcompiler/schema/schema_cfg.py +367 -357
- siliconcompiler/schema/schema_obj.py +39 -29
- siliconcompiler/schema/utils.py +19 -0
- siliconcompiler/sphinx_ext/schemagen.py +3 -1
- siliconcompiler/templates/replay/replay.sh.j2 +92 -0
- siliconcompiler/templates/tcl/manifest.tcl.j2 +1 -1
- siliconcompiler/tools/_common/__init__.py +8 -2
- siliconcompiler/tools/_common/asic.py +1 -1
- siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +3 -5
- siliconcompiler/tools/genfasm/genfasm.py +1 -1
- siliconcompiler/tools/klayout/export.py +5 -0
- siliconcompiler/tools/klayout/klayout.py +18 -1
- siliconcompiler/tools/klayout/klayout_export.py +4 -1
- siliconcompiler/tools/klayout/klayout_operations.py +5 -2
- siliconcompiler/tools/klayout/klayout_utils.py +23 -0
- siliconcompiler/tools/klayout/operations.py +5 -0
- siliconcompiler/tools/magic/magic.py +1 -1
- siliconcompiler/tools/openroad/_apr.py +14 -3
- siliconcompiler/tools/openroad/antenna_repair.py +2 -1
- siliconcompiler/tools/openroad/clock_tree_synthesis.py +2 -1
- siliconcompiler/tools/openroad/detailed_placement.py +2 -1
- siliconcompiler/tools/openroad/detailed_route.py +8 -0
- siliconcompiler/tools/openroad/fillercell_insertion.py +2 -1
- siliconcompiler/tools/openroad/global_placement.py +2 -1
- siliconcompiler/tools/openroad/pin_placement.py +2 -1
- siliconcompiler/tools/openroad/rdlroute.py +4 -0
- siliconcompiler/tools/openroad/repair_design.py +2 -1
- siliconcompiler/tools/openroad/repair_timing.py +2 -1
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +6 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +1 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +8 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +1 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +3 -3
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +5 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +1 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +1 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +3 -0
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +29 -12
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +15 -0
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -0
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -13
- siliconcompiler/tools/vpr/vpr.py +86 -6
- siliconcompiler/tools/yosys/__init__.py +7 -0
- siliconcompiler/tools/yosys/sc_syn.tcl +33 -24
- siliconcompiler/tools/yosys/syn_asic.py +27 -0
- siliconcompiler/tools/yosys/syn_asic.tcl +27 -0
- siliconcompiler/toolscripts/_tools.json +15 -3
- siliconcompiler/toolscripts/rhel8/install-yosys-moosic.sh +17 -0
- siliconcompiler/toolscripts/rhel8/install-yosys-slang.sh +22 -0
- siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +17 -0
- siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +22 -0
- siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +17 -0
- siliconcompiler/toolscripts/ubuntu20/install-yosys-slang.sh +22 -0
- siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +17 -0
- siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +22 -0
- siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +17 -0
- siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +22 -0
- siliconcompiler/utils/__init__.py +33 -5
- {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/METADATA +21 -23
- {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/RECORD +79 -66
- {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/entry_points.txt +4 -0
- {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/top_level.txt +0 -0
|
@@ -52,6 +52,14 @@ def setup(chip):
|
|
|
52
52
|
'clock_trees'
|
|
53
53
|
])
|
|
54
54
|
|
|
55
|
+
chip.set('tool', tool, 'task', task, 'var', 'drt_end_iteration',
|
|
56
|
+
'end iteration for detail routing',
|
|
57
|
+
field='help')
|
|
58
|
+
if chip.get('tool', tool, 'task', task, 'var', 'drt_end_iteration', step=step, index=index):
|
|
59
|
+
chip.add('tool', tool, 'task', task, 'require',
|
|
60
|
+
','.join(['tool', tool, 'task', task, 'var', 'drt_end_iteration']),
|
|
61
|
+
step=step, index=index)
|
|
62
|
+
|
|
55
63
|
|
|
56
64
|
def pre_process(chip):
|
|
57
65
|
define_ord_files(chip)
|
|
@@ -75,6 +75,10 @@ def setup(chip):
|
|
|
75
75
|
'if enabled by the PDK, to the design',
|
|
76
76
|
skip='lib')
|
|
77
77
|
|
|
78
|
+
chip.set('tool', tool, 'task', task, 'var', 'debug_level',
|
|
79
|
+
'list of "tool key level" to enable debugging of OpenROAD',
|
|
80
|
+
field='help')
|
|
81
|
+
|
|
78
82
|
if f'{design}.v' in input_provides(chip, step, index):
|
|
79
83
|
chip.add('tool', tool, 'task', task, 'input', design + '.v', step=step, index=index)
|
|
80
84
|
elif f'{design}.vg' in input_provides(chip, step, index):
|
|
@@ -65,6 +65,12 @@ sc_set_dont_use
|
|
|
65
65
|
|
|
66
66
|
sc_setup_global_routing
|
|
67
67
|
|
|
68
|
+
# Store incoming markers to avoid rewriting them
|
|
69
|
+
set sc_starting_markers []
|
|
70
|
+
foreach markerdb [[ord::get_db_block] getMarkerCategories] {
|
|
71
|
+
lappend sc_starting_markers [$markerdb getName]
|
|
72
|
+
}
|
|
73
|
+
|
|
68
74
|
###############################
|
|
69
75
|
# Source Step Script
|
|
70
76
|
###############################
|
|
@@ -36,6 +36,7 @@ if { [llength [all_clocks]] > 0 } {
|
|
|
36
36
|
|
|
37
37
|
set cts_distance_between_buffers \
|
|
38
38
|
[lindex [sc_cfg_tool_task_get var cts_distance_between_buffers] 0]
|
|
39
|
+
sc_report_args -command clock_tree_synthesis -args $sc_cts_arguments
|
|
39
40
|
clock_tree_synthesis \
|
|
40
41
|
-sink_clustering_enable \
|
|
41
42
|
-sink_clustering_size [lindex [sc_cfg_tool_task_get var cts_cluster_size] 0] \
|
|
@@ -40,12 +40,20 @@ set drt_repair_pdn_vias \
|
|
|
40
40
|
if { $drt_repair_pdn_vias != "" } {
|
|
41
41
|
lappend drt_arguments "-repair_pdn_vias" $drt_repair_pdn_vias
|
|
42
42
|
}
|
|
43
|
+
set drt_end_iteration [lindex [sc_cfg_tool_task_get {var} drt_end_iteration] 0]
|
|
44
|
+
if { $drt_end_iteration != "" } {
|
|
45
|
+
lappend drt_arguments "-droute_end_iter" $drt_end_iteration
|
|
46
|
+
}
|
|
47
|
+
lappend drt_arguments \
|
|
48
|
+
-drc_report_iter_step \
|
|
49
|
+
[lindex [sc_cfg_tool_task_get {var} drt_report_interval] 0]
|
|
43
50
|
|
|
44
51
|
set sc_minmetal [sc_cfg_get pdk $sc_pdk minlayer $sc_stackup]
|
|
45
52
|
set sc_minmetal [sc_get_layer_name $sc_minmetal]
|
|
46
53
|
set sc_maxmetal [sc_cfg_get pdk $sc_pdk maxlayer $sc_stackup]
|
|
47
54
|
set sc_maxmetal [sc_get_layer_name $sc_maxmetal]
|
|
48
55
|
|
|
56
|
+
sc_report_args -command detailed_route -args $drt_arguments
|
|
49
57
|
detailed_route \
|
|
50
58
|
-save_guide_updates \
|
|
51
59
|
-output_drc "reports/${sc_design}_drc.rpt" \
|
|
@@ -41,6 +41,7 @@ if { [lindex [sc_cfg_tool_task_get var enable_scan_chains] 0] == "true" } {
|
|
|
41
41
|
[lindex [sc_cfg_tool_task_get var scan_enable_port_pattern] 0]
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
sc_report_args -command set_dft_config -args $dft_args
|
|
44
45
|
set_dft_config -clock_mixing clock_mix {*}$dft_args
|
|
45
46
|
tee -file reports/scan_chain_config.rpt {report_dft_config}
|
|
46
47
|
scan_replace
|
|
@@ -29,6 +29,7 @@ if { [lindex [sc_cfg_tool_task_get {var} grt_use_pin_access] 0] == "true" } {
|
|
|
29
29
|
[lindex [sc_cfg_tool_task_get {var} drt_process_node] 0]
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
sc_report_args -command pin_access -args $pin_access_args
|
|
32
33
|
pin_access \
|
|
33
34
|
-bottom_routing_layer $sc_minmetal \
|
|
34
35
|
-top_routing_layer $sc_maxmetal \
|
|
@@ -47,6 +48,7 @@ if { [lindex [sc_cfg_tool_task_get {var} grt_allow_overflow] 0] == "true" } {
|
|
|
47
48
|
lappend sc_grt_arguments "-allow_overflow"
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
sc_report_args -command global_route -args $sc_grt_arguments
|
|
50
52
|
if {
|
|
51
53
|
[catch {
|
|
52
54
|
global_route -guide_file "reports/route.guide" \
|
|
@@ -121,11 +121,11 @@ if { [sc_cfg_exists constraint pin] } {
|
|
|
121
121
|
global sc_vpinmetal
|
|
122
122
|
|
|
123
123
|
set layer [sc_cfg_get constraint pin $pin layer]
|
|
124
|
-
if {
|
|
125
|
-
return [sc_get_layer_name
|
|
124
|
+
if { $layer != {} } {
|
|
125
|
+
return [sc_get_layer_name $layer]
|
|
126
126
|
}
|
|
127
127
|
set side [sc_cfg_get constraint pin $pin side]
|
|
128
|
-
if {
|
|
128
|
+
if { $side != {} } {
|
|
129
129
|
switch -regexp $side {
|
|
130
130
|
"1|3" {
|
|
131
131
|
return [lindex $sc_hpinmetal 0]
|
|
@@ -85,6 +85,10 @@ if { [sc_design_has_unplaced_macros] } {
|
|
|
85
85
|
if { $rtlmp_guidance_weight != "" } {
|
|
86
86
|
lappend rtlmp_args -guidance_weight $rtlmp_guidance_weight
|
|
87
87
|
}
|
|
88
|
+
set rtlmp_boundary_weight [lindex [sc_cfg_tool_task_get var rtlmp_boundary_weight] 0]
|
|
89
|
+
if { $rtlmp_boundary_weight != "" } {
|
|
90
|
+
lappend rtlmp_args -boundary_weight $rtlmp_boundary_weight
|
|
91
|
+
}
|
|
88
92
|
set rtlmp_fence_weight [lindex [sc_cfg_tool_task_get var rtlmp_fence_weight] 0]
|
|
89
93
|
if { $rtlmp_fence_weight != "" } {
|
|
90
94
|
lappend rtlmp_args -fence_weight $rtlmp_fence_weight
|
|
@@ -98,6 +102,7 @@ if { [sc_design_has_unplaced_macros] } {
|
|
|
98
102
|
lappend rtlmp_args -blockage_weight $rtlmp_blockage_weight
|
|
99
103
|
}
|
|
100
104
|
|
|
105
|
+
sc_report_args -command rtl_macro_placer -args $rtlmp_args
|
|
101
106
|
rtl_macro_placer \
|
|
102
107
|
-report_directory reports/rtlmp \
|
|
103
108
|
-halo_width $halo_x \
|
|
@@ -40,6 +40,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_setup_repair] 0] != "true" } {
|
|
|
40
40
|
|
|
41
41
|
estimate_parasitics -placement
|
|
42
42
|
|
|
43
|
+
sc_report_args -command repair_timing -args $repair_timing_args
|
|
43
44
|
repair_timing \
|
|
44
45
|
-setup \
|
|
45
46
|
-verbose \
|
|
@@ -64,6 +65,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_hold_repair] 0] != "true" } {
|
|
|
64
65
|
# Enable hold cells
|
|
65
66
|
sc_set_dont_use -hold -scanchain -multibit -report dont_use.repair_timing.hold
|
|
66
67
|
|
|
68
|
+
sc_report_args -command repair_timing -args $repair_timing_args
|
|
67
69
|
repair_timing \
|
|
68
70
|
-hold \
|
|
69
71
|
-verbose \
|
|
@@ -88,6 +90,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_recover_power] 0] != "true" } {
|
|
|
88
90
|
# Enable cells
|
|
89
91
|
sc_set_dont_use -hold -scanchain -multibit -report dont_use.repair_timing.power
|
|
90
92
|
|
|
93
|
+
sc_report_args -command repair_timing -args $repair_timing_args
|
|
91
94
|
repair_timing \
|
|
92
95
|
-recover_power $rsz_recover_power \
|
|
93
96
|
-verbose \
|
|
@@ -86,6 +86,7 @@ proc sc_global_placement { args } {
|
|
|
86
86
|
|
|
87
87
|
set density [sc_global_placement_density]
|
|
88
88
|
|
|
89
|
+
sc_report_args -command global_placement -args $gpl_args
|
|
89
90
|
global_placement {*}$gpl_args \
|
|
90
91
|
-density $density \
|
|
91
92
|
-pad_left $gpl_padding \
|
|
@@ -110,6 +111,7 @@ proc sc_detailed_placement { } {
|
|
|
110
111
|
lappend dpl_args "-disallow_one_site_gaps"
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
sc_report_args -command detailed_placement -args $dpl_args
|
|
113
115
|
detailed_placement \
|
|
114
116
|
-max_displacement $dpl_max_displacement \
|
|
115
117
|
{*}$dpl_args
|
|
@@ -126,15 +128,6 @@ proc sc_pin_placement { args } {
|
|
|
126
128
|
flags {-random}
|
|
127
129
|
sta::check_argc_eq0 "sc_pin_placement" $args
|
|
128
130
|
|
|
129
|
-
global sc_pdk
|
|
130
|
-
global sc_stackup
|
|
131
|
-
global sc_tool
|
|
132
|
-
|
|
133
|
-
set sc_hpinmetal [sc_cfg_get pdk $sc_pdk {var} $sc_tool pin_layer_horizontal $sc_stackup]
|
|
134
|
-
set sc_hpinmetal [sc_get_layer_name $sc_hpinmetal]
|
|
135
|
-
set sc_vpinmetal [sc_cfg_get pdk $sc_pdk {var} $sc_tool pin_layer_vertical $sc_stackup]
|
|
136
|
-
set sc_vpinmetal [sc_get_layer_name $sc_vpinmetal]
|
|
137
|
-
|
|
138
131
|
if { [sc_cfg_tool_task_exists var pin_thickness_h] } {
|
|
139
132
|
set h_mult [lindex [sc_cfg_tool_task_get var pin_thickness_h] 0]
|
|
140
133
|
set_pin_thick_multiplier -hor_multiplier $h_mult
|
|
@@ -155,9 +148,19 @@ proc sc_pin_placement { args } {
|
|
|
155
148
|
lappend ppl_args "-random"
|
|
156
149
|
}
|
|
157
150
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
151
|
+
lappend ppl_args {*}[sc_cfg_tool_task_get {var} ppl_arguments]
|
|
152
|
+
|
|
153
|
+
global sc_pdk
|
|
154
|
+
global sc_stackup
|
|
155
|
+
global sc_tool
|
|
156
|
+
|
|
157
|
+
set sc_hpinmetal [sc_cfg_get pdk $sc_pdk {var} $sc_tool pin_layer_horizontal $sc_stackup]
|
|
158
|
+
set sc_vpinmetal [sc_cfg_get pdk $sc_pdk {var} $sc_tool pin_layer_vertical $sc_stackup]
|
|
159
|
+
|
|
160
|
+
sc_report_args -command place_pins -args $ppl_args
|
|
161
|
+
place_pins \
|
|
162
|
+
-hor_layers [sc_get_layer_name $sc_hpinmetal] \
|
|
163
|
+
-ver_layers [sc_get_layer_name $sc_vpinmetal] \
|
|
161
164
|
{*}$ppl_args
|
|
162
165
|
}
|
|
163
166
|
|
|
@@ -783,3 +786,17 @@ proc sc_setup_detailed_route { } {
|
|
|
783
786
|
detailed_route_set_unidirectional_layer $layer
|
|
784
787
|
}
|
|
785
788
|
}
|
|
789
|
+
|
|
790
|
+
proc sc_report_args { args } {
|
|
791
|
+
sta::parse_key_args "sc_report_args" args \
|
|
792
|
+
keys {-command -args} \
|
|
793
|
+
flags {}
|
|
794
|
+
|
|
795
|
+
sta::check_argc_eq0 "sc_report_args" $args
|
|
796
|
+
|
|
797
|
+
if { [llength $keys(-args)] == 0 } {
|
|
798
|
+
return
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
puts "$keys(-command) siliconcompiler arguments: $keys(-args)"
|
|
802
|
+
}
|
|
@@ -100,6 +100,17 @@ if { [sc_cfg_tool_task_check_in_list fmax var reports] } {
|
|
|
100
100
|
puts "$clk_name fmax = [format %.2f [expr { $fmax / 1e6 }]] MHz"
|
|
101
101
|
set fmax_metric [expr { max($fmax_metric, $fmax) }]
|
|
102
102
|
}
|
|
103
|
+
if { $fmax_metric == 0 } {
|
|
104
|
+
# attempt to compute based on combinatorial path
|
|
105
|
+
set max_path [find_timing_paths -unconstrained -path_delay max]
|
|
106
|
+
set max_path_delay [$max_path data_arrival_time]
|
|
107
|
+
set min_path [find_timing_paths -unconstrained -path_delay min]
|
|
108
|
+
set min_path_delay [$min_path data_arrival_time]
|
|
109
|
+
set path_delay [expr { $max_path_delay - min(0, $min_path_delay) }]
|
|
110
|
+
if { $path_delay > 0 } {
|
|
111
|
+
set fmax_metric [expr { 1.0 / $path_delay }]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
103
114
|
if { $fmax_metric > 0 } {
|
|
104
115
|
utl::metric_float "timing__fmax" $fmax_metric
|
|
105
116
|
}
|
|
@@ -169,6 +180,10 @@ foreach markerdb [[ord::get_db_block] getMarkerCategories] {
|
|
|
169
180
|
continue
|
|
170
181
|
}
|
|
171
182
|
|
|
183
|
+
if { [lsearch -exact $sc_starting_markers [$markerdb getName]] != -1 } {
|
|
184
|
+
continue
|
|
185
|
+
}
|
|
186
|
+
|
|
172
187
|
$markerdb writeTR "reports/markers/${sc_design}.[$markerdb getName].rpt"
|
|
173
188
|
$markerdb writeJSON "reports/markers/${sc_design}.[$markerdb getName].json"
|
|
174
189
|
}
|
|
@@ -210,6 +210,24 @@ proc sc_image_placement_density { } {
|
|
|
210
210
|
"placement density"
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
proc sc_image_module_view { } {
|
|
214
|
+
if { ![sc_has_placed_instances] } {
|
|
215
|
+
return
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if { [llength [[ord::get_db_block] getModInsts]] < 1 } {
|
|
219
|
+
return
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
global sc_design
|
|
223
|
+
sc_image_setup_default
|
|
224
|
+
|
|
225
|
+
gui::set_display_controls "Misc/Module view" visible true
|
|
226
|
+
gui::set_display_controls "Nets/*" visible false
|
|
227
|
+
|
|
228
|
+
sc_save_image "module view" reports/images/${sc_design}.modules.png
|
|
229
|
+
}
|
|
230
|
+
|
|
213
231
|
proc sc_image_clocks { } {
|
|
214
232
|
if { ![sc_has_placed_instances] } {
|
|
215
233
|
return
|
|
@@ -333,12 +351,18 @@ proc sc_image_markers { } {
|
|
|
333
351
|
global sc_design
|
|
334
352
|
sc_image_setup_default
|
|
335
353
|
|
|
354
|
+
global sc_starting_markers
|
|
355
|
+
|
|
336
356
|
file mkdir reports/images/markers
|
|
337
357
|
foreach markerdb [[ord::get_db_block] getMarkerCategories] {
|
|
338
358
|
if { [$markerdb getMarkerCount] == 0 } {
|
|
339
359
|
continue
|
|
340
360
|
}
|
|
341
361
|
|
|
362
|
+
if { [lsearch -exact $sc_starting_markers [$markerdb getName]] != -1 } {
|
|
363
|
+
continue
|
|
364
|
+
}
|
|
365
|
+
|
|
342
366
|
gui::select_marker_category $markerdb
|
|
343
367
|
|
|
344
368
|
sc_save_image \
|
|
@@ -359,6 +383,10 @@ sc_image_everything
|
|
|
359
383
|
sc_image_placement
|
|
360
384
|
sc_image_routing
|
|
361
385
|
|
|
386
|
+
if { [sc_cfg_tool_task_check_in_list module_view var reports] } {
|
|
387
|
+
sc_image_module_view
|
|
388
|
+
}
|
|
389
|
+
|
|
362
390
|
# Markers
|
|
363
391
|
sc_image_markers
|
|
364
392
|
|
|
@@ -35,21 +35,11 @@ set sc_threads [sc_cfg_tool_task_get threads]
|
|
|
35
35
|
# MACROS
|
|
36
36
|
set sc_macrolibs [sc_get_asic_libraries macro]
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
#
|
|
38
|
+
##############################
|
|
39
|
+
# Setup debugging
|
|
40
40
|
###############################
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
set or_msg [split $msg "-"]
|
|
44
|
-
if { [llength $or_msg] != 2 } {
|
|
45
|
-
utl::warn FLW 1 "$msg is not a valid message id"
|
|
46
|
-
} else {
|
|
47
|
-
set or_tool [lindex $or_msg 0]
|
|
48
|
-
set or_msg_id [expr { int([lindex $or_msg 1]) }]
|
|
49
|
-
utl::info FLW 1 "Suppressing $msg messages"
|
|
50
|
-
suppress_message $or_tool $or_msg_id
|
|
51
|
-
}
|
|
52
|
-
}
|
|
42
|
+
source -echo "$sc_refdir/common/debugging.tcl"
|
|
53
43
|
|
|
54
44
|
###############################
|
|
55
45
|
# Source helper functions
|
siliconcompiler/tools/vpr/vpr.py
CHANGED
|
@@ -16,6 +16,7 @@ Sources: https://github.com/verilog-to-routing/vtr-verilog-to-routing
|
|
|
16
16
|
Installation: https://github.com/verilog-to-routing/vtr-verilog-to-routing
|
|
17
17
|
'''
|
|
18
18
|
|
|
19
|
+
import glob
|
|
19
20
|
import os
|
|
20
21
|
import shutil
|
|
21
22
|
import json
|
|
@@ -42,7 +43,7 @@ def setup_tool(chip, clobber=True):
|
|
|
42
43
|
|
|
43
44
|
chip.set('tool', 'vpr', 'exe', 'vpr', clobber=clobber)
|
|
44
45
|
chip.set('tool', 'vpr', 'vswitch', '--version')
|
|
45
|
-
chip.set('tool', 'vpr', 'version', '>=
|
|
46
|
+
chip.set('tool', 'vpr', 'version', '>=9.0.0', clobber=clobber)
|
|
46
47
|
|
|
47
48
|
step = chip.get('arg', 'step')
|
|
48
49
|
index = chip.get('arg', 'index')
|
|
@@ -80,6 +81,16 @@ def add_tool_requirements(chip):
|
|
|
80
81
|
chip.add('tool', tool, 'task', task, 'require', f'fpga,{part_name},var,vpr_device_code',
|
|
81
82
|
step=step, index=index)
|
|
82
83
|
|
|
84
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_paths',
|
|
85
|
+
'number of timing paths to report', field='help')
|
|
86
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_paths', '20',
|
|
87
|
+
step=step, index=index, clobber=False)
|
|
88
|
+
|
|
89
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_report_type',
|
|
90
|
+
'type of timing report', field='help')
|
|
91
|
+
chip.set('tool', tool, 'task', task, 'var', 'timing_report_type', 'aggregated',
|
|
92
|
+
step=step, index=index, clobber=False)
|
|
93
|
+
|
|
83
94
|
|
|
84
95
|
def runtime_options(chip):
|
|
85
96
|
|
|
@@ -163,13 +174,22 @@ def runtime_options(chip):
|
|
|
163
174
|
'vpr_clock model must be set to ideal, route, or dedicated_clock_network',
|
|
164
175
|
chip=chip)
|
|
165
176
|
|
|
177
|
+
sdc_file = None
|
|
166
178
|
if chip.valid('input', 'constraint', 'sdc'):
|
|
167
179
|
sdc_file = find_single_file(chip, 'input', 'constraint', 'sdc',
|
|
168
180
|
step=step, index=index,
|
|
169
181
|
file_not_found_msg="SDC file not found")
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
182
|
+
|
|
183
|
+
if sdc_file:
|
|
184
|
+
sdc_arg = f"--sdc_file {sdc_file}"
|
|
185
|
+
options.append(sdc_arg)
|
|
186
|
+
|
|
187
|
+
report_type = chip.get('tool', tool, 'task', task, 'var', 'timing_report_type',
|
|
188
|
+
step=step, index=index)[0]
|
|
189
|
+
options.append(f'--timing_report_detail {report_type}')
|
|
190
|
+
report_paths = chip.get('tool', tool, 'task', task, 'var', 'timing_paths',
|
|
191
|
+
step=step, index=index)[0]
|
|
192
|
+
options.append(f'--timing_report_npaths {report_paths}')
|
|
173
193
|
else:
|
|
174
194
|
options.append("--timing_analysis off")
|
|
175
195
|
|
|
@@ -295,8 +315,8 @@ def vpr_post_process(chip):
|
|
|
295
315
|
step = chip.get('arg', 'step')
|
|
296
316
|
index = chip.get('arg', 'index')
|
|
297
317
|
|
|
298
|
-
|
|
299
|
-
shutil.move(
|
|
318
|
+
for report in glob.glob("*.rpt"):
|
|
319
|
+
shutil.move(report, 'reports')
|
|
300
320
|
|
|
301
321
|
part_name = chip.get('fpga', 'partname')
|
|
302
322
|
dff_cells = []
|
|
@@ -379,6 +399,66 @@ def vpr_post_process(chip):
|
|
|
379
399
|
|
|
380
400
|
record_metric(chip, step, index, "pins", io, __block_file)
|
|
381
401
|
|
|
402
|
+
for setup_report in ("reports/report_timing.setup.rpt",
|
|
403
|
+
"reports/pre_pack.report_timing.setup.rpt"):
|
|
404
|
+
if not os.path.exists(setup_report):
|
|
405
|
+
continue
|
|
406
|
+
|
|
407
|
+
slack = _parse_timing_report(setup_report)
|
|
408
|
+
if slack is not None:
|
|
409
|
+
wns = min([slack, 0])
|
|
410
|
+
record_metric(chip, step, index, "setupslack", slack, setup_report, source_unit="ns")
|
|
411
|
+
record_metric(chip, step, index, "setupwns", wns, setup_report, source_unit="ns")
|
|
412
|
+
break
|
|
413
|
+
|
|
414
|
+
for hold_report in ("reports/report_timing.hold.rpt", ):
|
|
415
|
+
if not os.path.exists(hold_report):
|
|
416
|
+
continue
|
|
417
|
+
|
|
418
|
+
slack = _parse_timing_report(hold_report)
|
|
419
|
+
if slack is not None:
|
|
420
|
+
wns = min([slack, 0])
|
|
421
|
+
record_metric(chip, step, index, "holdslack", slack, hold_report, source_unit="ns")
|
|
422
|
+
record_metric(chip, step, index, "holdwns", wns, hold_report, source_unit="ns")
|
|
423
|
+
break
|
|
424
|
+
|
|
425
|
+
unconstrained = None
|
|
426
|
+
unconstrained_reports = []
|
|
427
|
+
for unconstrained_report in ("reports/report_unconstrained_timing.hold.rpt",
|
|
428
|
+
"reports/report_unconstrained_timing.setup.rpt"):
|
|
429
|
+
if not os.path.exists(unconstrained_report):
|
|
430
|
+
continue
|
|
431
|
+
|
|
432
|
+
paths = _parse_unconstrained_report(unconstrained_report)
|
|
433
|
+
if unconstrained is None:
|
|
434
|
+
unconstrained = paths
|
|
435
|
+
|
|
436
|
+
unconstrained = max([paths, unconstrained])
|
|
437
|
+
unconstrained_reports.append(unconstrained_report)
|
|
438
|
+
|
|
439
|
+
if unconstrained is not None:
|
|
440
|
+
record_metric(chip, step, index, "unconstrained", unconstrained, unconstrained_reports)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def _parse_timing_report(report):
|
|
444
|
+
slack = re.compile(r"slack \(.*\)\s+(-?\d+\.?\d*)")
|
|
445
|
+
with sc_open(report) as f:
|
|
446
|
+
for line in f:
|
|
447
|
+
match_slack = slack.findall(line)
|
|
448
|
+
if match_slack:
|
|
449
|
+
return float(match_slack[0])
|
|
450
|
+
return None
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def _parse_unconstrained_report(report):
|
|
454
|
+
path = re.compile(r"\d+ .*")
|
|
455
|
+
count = 0
|
|
456
|
+
with sc_open(report) as f:
|
|
457
|
+
for line in f:
|
|
458
|
+
if path.match(line):
|
|
459
|
+
count += 1
|
|
460
|
+
return count
|
|
461
|
+
|
|
382
462
|
|
|
383
463
|
##################################################
|
|
384
464
|
if __name__ == "__main__":
|
|
@@ -98,6 +98,13 @@ def syn_setup(chip):
|
|
|
98
98
|
chip.set('tool', tool, 'task', task, 'output', design + '.vg', step=step, index=index)
|
|
99
99
|
chip.add('tool', tool, 'task', task, 'output', design + '.netlist.json', step=step, index=index)
|
|
100
100
|
|
|
101
|
+
chip.set('tool', tool, 'task', task, 'var', 'use_slang', False,
|
|
102
|
+
step=step, index=index,
|
|
103
|
+
clobber=False)
|
|
104
|
+
chip.set('tool', tool, 'task', task, 'var', 'use_slang',
|
|
105
|
+
'true/false, if true will attempt to use the slang frontend',
|
|
106
|
+
field='help')
|
|
107
|
+
|
|
101
108
|
|
|
102
109
|
##################################################
|
|
103
110
|
def syn_post_process(chip):
|
|
@@ -39,32 +39,41 @@ source "$sc_refdir/procs.tcl"
|
|
|
39
39
|
# TODO: the original OpenFPGA synth script used read_verilog with -nolatches. Is
|
|
40
40
|
# that a flag we might want here?
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
42
|
+
set input_verilog "inputs/$sc_design.v"
|
|
43
|
+
if { [file exists $input_verilog] } {
|
|
44
|
+
if { [lindex [sc_cfg_tool_task_get var use_slang] 0] == "true" && [sc_load_plugin slang] } {
|
|
45
|
+
# This needs some reordering of loaded to ensure blackboxes are handled
|
|
46
|
+
# before this
|
|
47
|
+
set slang_params []
|
|
48
|
+
if { [sc_cfg_exists option param] } {
|
|
49
|
+
dict for {key value} [sc_cfg_get option param] {
|
|
50
|
+
if { ![string is integer $value] } {
|
|
51
|
+
set value [concat \"$value\"]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
lappend slang_params -G "${key}=${value}"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
yosys read_slang \
|
|
58
|
+
-D SYNTHESIS \
|
|
59
|
+
--keep-hierarchy \
|
|
60
|
+
--top $sc_design \
|
|
61
|
+
{*}$slang_params \
|
|
62
|
+
$input_verilog
|
|
63
|
+
} else {
|
|
64
|
+
# Use -noblackbox to correctly interpret empty modules as empty,
|
|
65
|
+
# actual black boxes are read in later
|
|
66
|
+
# https://github.com/YosysHQ/yosys/issues/1468
|
|
67
|
+
yosys read_verilog -noblackbox -sv $input_verilog
|
|
68
|
+
|
|
69
|
+
########################################################
|
|
70
|
+
# Override top level parameters
|
|
71
|
+
########################################################
|
|
72
|
+
|
|
73
|
+
sc_apply_params
|
|
74
|
+
}
|
|
60
75
|
}
|
|
61
76
|
|
|
62
|
-
########################################################
|
|
63
|
-
# Override top level parameters
|
|
64
|
-
########################################################
|
|
65
|
-
|
|
66
|
-
sc_apply_params
|
|
67
|
-
|
|
68
77
|
########################################################
|
|
69
78
|
# Synthesis based on mode
|
|
70
79
|
########################################################
|