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.
Files changed (79) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/sc_install.py +26 -4
  3. siliconcompiler/apps/sc_remote.py +1 -3
  4. siliconcompiler/core.py +24 -9
  5. siliconcompiler/flowgraph.py +11 -23
  6. siliconcompiler/{package.py → package/__init__.py} +62 -176
  7. siliconcompiler/package/git.py +81 -0
  8. siliconcompiler/package/https.py +93 -0
  9. siliconcompiler/remote/schema.py +9 -8
  10. siliconcompiler/report/report.py +4 -3
  11. siliconcompiler/scheduler/__init__.py +127 -113
  12. siliconcompiler/scheduler/docker_runner.py +4 -4
  13. siliconcompiler/scheduler/run_node.py +3 -3
  14. siliconcompiler/scheduler/send_messages.py +1 -1
  15. siliconcompiler/schema/schema_cfg.py +367 -357
  16. siliconcompiler/schema/schema_obj.py +39 -29
  17. siliconcompiler/schema/utils.py +19 -0
  18. siliconcompiler/sphinx_ext/schemagen.py +3 -1
  19. siliconcompiler/templates/replay/replay.sh.j2 +92 -0
  20. siliconcompiler/templates/tcl/manifest.tcl.j2 +1 -1
  21. siliconcompiler/tools/_common/__init__.py +8 -2
  22. siliconcompiler/tools/_common/asic.py +1 -1
  23. siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +3 -5
  24. siliconcompiler/tools/genfasm/genfasm.py +1 -1
  25. siliconcompiler/tools/klayout/export.py +5 -0
  26. siliconcompiler/tools/klayout/klayout.py +18 -1
  27. siliconcompiler/tools/klayout/klayout_export.py +4 -1
  28. siliconcompiler/tools/klayout/klayout_operations.py +5 -2
  29. siliconcompiler/tools/klayout/klayout_utils.py +23 -0
  30. siliconcompiler/tools/klayout/operations.py +5 -0
  31. siliconcompiler/tools/magic/magic.py +1 -1
  32. siliconcompiler/tools/openroad/_apr.py +14 -3
  33. siliconcompiler/tools/openroad/antenna_repair.py +2 -1
  34. siliconcompiler/tools/openroad/clock_tree_synthesis.py +2 -1
  35. siliconcompiler/tools/openroad/detailed_placement.py +2 -1
  36. siliconcompiler/tools/openroad/detailed_route.py +8 -0
  37. siliconcompiler/tools/openroad/fillercell_insertion.py +2 -1
  38. siliconcompiler/tools/openroad/global_placement.py +2 -1
  39. siliconcompiler/tools/openroad/pin_placement.py +2 -1
  40. siliconcompiler/tools/openroad/rdlroute.py +4 -0
  41. siliconcompiler/tools/openroad/repair_design.py +2 -1
  42. siliconcompiler/tools/openroad/repair_timing.py +2 -1
  43. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +6 -0
  44. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +1 -0
  45. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +8 -0
  46. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +1 -0
  47. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -0
  48. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +3 -3
  49. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +5 -0
  50. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +1 -0
  51. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +1 -0
  52. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +3 -0
  53. siliconcompiler/tools/openroad/scripts/common/procs.tcl +29 -12
  54. siliconcompiler/tools/openroad/scripts/common/reports.tcl +15 -0
  55. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -0
  56. siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +3 -13
  57. siliconcompiler/tools/vpr/vpr.py +86 -6
  58. siliconcompiler/tools/yosys/__init__.py +7 -0
  59. siliconcompiler/tools/yosys/sc_syn.tcl +33 -24
  60. siliconcompiler/tools/yosys/syn_asic.py +27 -0
  61. siliconcompiler/tools/yosys/syn_asic.tcl +27 -0
  62. siliconcompiler/toolscripts/_tools.json +15 -3
  63. siliconcompiler/toolscripts/rhel8/install-yosys-moosic.sh +17 -0
  64. siliconcompiler/toolscripts/rhel8/install-yosys-slang.sh +22 -0
  65. siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +17 -0
  66. siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +22 -0
  67. siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +17 -0
  68. siliconcompiler/toolscripts/ubuntu20/install-yosys-slang.sh +22 -0
  69. siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +17 -0
  70. siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +22 -0
  71. siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +17 -0
  72. siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +22 -0
  73. siliconcompiler/utils/__init__.py +33 -5
  74. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/METADATA +21 -23
  75. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/RECORD +79 -66
  76. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/WHEEL +1 -1
  77. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/entry_points.txt +4 -0
  78. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.1.dist-info}/LICENSE +0 -0
  79. {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)
@@ -45,7 +45,8 @@ def setup(chip):
45
45
  # Images
46
46
  'placement_density',
47
47
  'routing_congestion',
48
- 'power_density'
48
+ 'power_density',
49
+ 'module_view'
49
50
  ])
50
51
 
51
52
 
@@ -48,7 +48,8 @@ def setup(chip):
48
48
  # Images
49
49
  'placement_density',
50
50
  'routing_congestion',
51
- 'power_density'
51
+ 'power_density',
52
+ 'module_view'
52
53
  ])
53
54
 
54
55
  set_tool_task_var(chip, param_key='enable_multibit_clustering',
@@ -42,7 +42,8 @@ def setup(chip):
42
42
  # Images
43
43
  'placement_density',
44
44
  'routing_congestion',
45
- 'power_density'
45
+ 'power_density',
46
+ 'module_view'
46
47
  ])
47
48
 
48
49
 
@@ -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):
@@ -46,7 +46,8 @@ def setup(chip):
46
46
  'placement_density',
47
47
  'routing_congestion',
48
48
  'power_density',
49
- 'optimization_placement'
49
+ 'optimization_placement',
50
+ 'module_view'
50
51
  ])
51
52
 
52
53
 
@@ -50,7 +50,8 @@ def setup(chip):
50
50
  'power_density',
51
51
  'optimization_placement',
52
52
  'clock_placement',
53
- 'clock_trees'
53
+ 'clock_trees',
54
+ 'module_view'
54
55
  ])
55
56
 
56
57
 
@@ -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 { [llength $layer] != 0 } {
125
- return [sc_get_layer_name [lindex $layer 0]]
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 { [llength $side] != 0 } {
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 \
@@ -99,6 +99,7 @@ foreach net [sc_psm_check_nets] {
99
99
  lappend check_args -dont_require_terminals
100
100
  }
101
101
 
102
+ sc_report_args -command check_power_grid -args $check_args
102
103
  check_power_grid \
103
104
  -floorplanning \
104
105
  -error_file "reports/power_grid_${net}.rpt" \
@@ -41,6 +41,7 @@ if { $rsz_slew_margin != "false" } {
41
41
  lappend repair_design_args "-slew_margin" $rsz_slew_margin
42
42
  }
43
43
 
44
+ sc_report_args -command repair_design -args $repair_design_args
44
45
  repair_design \
45
46
  -verbose \
46
47
  {*}$repair_design_args
@@ -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
- place_pins -hor_layers $sc_hpinmetal \
159
- -ver_layers $sc_vpinmetal \
160
- {*}[sc_cfg_tool_task_get {var} ppl_arguments] \
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
- # Suppress messages if requested
38
+ ##############################
39
+ # Setup debugging
40
40
  ###############################
41
41
 
42
- foreach msg [sc_cfg_tool_task_get warningoff] {
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
@@ -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', '>=8.1.0', clobber=clobber)
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
- if (sdc_file is not None):
171
- sdc_arg = f"--sdc_file {sdc_file}"
172
- options.append(sdc_arg)
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
- if os.path.exists('packing_pin_util.rpt'):
299
- shutil.move('packing_pin_util.rpt', 'reports')
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
- # If UHDM, ilang, or Verilog inputs exist, read them in (this allows mixed
43
- # inputs in designs). UHDM requires a version of Yosys built with this support.
44
-
45
- if { [file exists "inputs/$sc_design.uhdm"] } {
46
- set input_uhdm "inputs/$sc_design.uhdm"
47
- yosys read_uhdm $input_uhdm
48
- }
49
- if { [file exists "inputs/$sc_design.ilang"] } {
50
- set input_ilang "inputs/$sc_design.ilang"
51
- yosys read_ilang $input_ilang
52
- }
53
-
54
- if { [file exists "inputs/$sc_design.v"] } {
55
- set input_verilog "inputs/$sc_design.v"
56
- # Use -noblackbox to correctly interpret empty modules as empty,
57
- # actual black boxes are read in later
58
- # https://github.com/YosysHQ/yosys/issues/1468
59
- yosys read_verilog -noblackbox -sv $input_verilog
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
  ########################################################