Skip to content

Commit d8c93c1

Browse files
committed
Merge branch 'master' into update_microwatt
Signed-off-by: Eder Monteiro <[email protected]>
2 parents afa6a60 + 745c3d9 commit d8c93c1

File tree

4 files changed

+128
-66
lines changed

4 files changed

+128
-66
lines changed

flow/scripts/open.tcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ proc read_timing {input_file} {
5151
log_cmd estimate_parasitics -placement
5252
}
5353

54-
fast_route
55-
5654
puts "Populating timing paths..."
5755
# Warm up OpenSTA, so clicking on timing related buttons reacts faster
5856
set _tmp [find_timing_paths]
@@ -63,6 +61,8 @@ if {[env_var_equals GUI_TIMING 1]} {
6361
read_timing $input_file
6462
}
6563

64+
fast_route
65+
6666
if {[env_var_equals GUI_SHOW 1]} {
6767
# Show the GUI when it is ready; it is unresponsive(with modal requesters
6868
# saying it is unresponsive) until everything is loaded

flow/scripts/util.tcl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@ proc fast_route {} {
1515
}
1616
}
1717

18-
# -hold_margin is only set when hold_margin is set, default 1
1918
proc repair_timing_helper { {hold_margin 1} } {
2019
set additional_args "-verbose"
2120
append_env_var additional_args SETUP_SLACK_MARGIN -setup_margin 1
22-
if {$hold_margin} {
21+
if {$hold_margin || $::env(HOLD_SLACK_MARGIN) < 0} {
2322
append_env_var additional_args HOLD_SLACK_MARGIN -hold_margin 1
2423
}
2524
append_env_var additional_args TNS_END_PERCENT -repair_tns 1

flow/scripts/variables.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,22 @@ HOLD_SLACK_MARGIN:
347347
Specifies a time margin for the slack when fixing hold violations.
348348
This option allows you to overfix or underfix(negative value, terminate
349349
retiming before 0 or positive slack).
350+
351+
Use min of HOLD_SLACK_MARGIN and 0(default hold slack margin) in floorplan.
352+
353+
This avoids overrepair in floorplan for hold by default, but allows skipping
354+
hold repair using a negative HOLD_SLACK_MARGIN.
355+
356+
Exiting timing repair early is useful in exploration where
357+
358+
the .sdc has a fixed clock period at designs target clock period and where
359+
HOLD/SETUP_SLACK_MARGIN is used to avoid overrepair(extremelly long running times)
360+
when exploring different parameter settings.
350361
stages:
351362
- cts
352363
- floorplan
353364
- grt
365+
default: 0
354366
SETUP_SLACK_MARGIN:
355367
description: >
356368
Specifies a time margin for the slack when fixing setup violations.
@@ -360,6 +372,7 @@ SETUP_SLACK_MARGIN:
360372
- cts
361373
- floorplan
362374
- grt
375+
default: 0
363376
SKIP_GATE_CLONING:
364377
description: >
365378
Do not use gate cloning transform to fix timing violations (default: use gate cloning).

flow/util/convertDrc.py

Lines changed: 112 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,118 @@
11
# This is a KLayout script to load a RVE DRC rpt file
22
# and write out a json the DRC viewer can read.
33

4+
import os
45
import pya
5-
66
import json
77

8+
9+
def convert_drc(rdb):
10+
source = os.path.abspath(in_drc)
11+
12+
ordb = {"source": source, "description": "KLayout DRC conversion", "category": {}}
13+
14+
for category in rdb.each_category():
15+
if category.num_items() == 0:
16+
# ignore categories with no data
17+
continue
18+
19+
ordb_category = {
20+
"description": category.description,
21+
"source": source,
22+
"violations": [],
23+
}
24+
ordb["category"][category.name()] = ordb_category
25+
26+
for item in rdb.each_item_per_category(category.rdb_id()):
27+
violation = {
28+
"visited": item.is_visited(),
29+
"visible": True,
30+
"waived": "waived" in item.tags_str,
31+
}
32+
33+
ordb_category["violations"].append(violation)
34+
35+
shapes = []
36+
violation["shape"] = shapes
37+
38+
text = []
39+
40+
for value in item.each_value():
41+
if value.is_box():
42+
shapes.append(
43+
{
44+
"type": "box",
45+
"points": [
46+
{"x": value.box().left, "y": value.box().bottom},
47+
{"x": value.box().right, "y": value.box().top},
48+
],
49+
}
50+
)
51+
elif value.is_edge():
52+
shapes.append(
53+
{
54+
"type": "line",
55+
"points": [
56+
{"x": value.edge().p1.x, "y": value.edge().p1.y},
57+
{"x": value.edge().p2.x, "y": value.edge().p2.y},
58+
],
59+
}
60+
)
61+
elif value.is_edge_pair():
62+
edge1 = value.edge_pair().first
63+
edge2 = value.edge_pair().second
64+
65+
shapes.append(
66+
{
67+
"type": "line",
68+
"points": [
69+
{"x": edge1.p1.x, "y": edge1.p1.y},
70+
{"x": edge1.p2.x, "y": edge1.p2.y},
71+
],
72+
}
73+
)
74+
shapes.append(
75+
{
76+
"type": "line",
77+
"points": [
78+
{"x": edge2.p1.x, "y": edge2.p1.y},
79+
{"x": edge2.p2.x, "y": edge2.p2.y},
80+
],
81+
}
82+
)
83+
elif value.is_polygon():
84+
points = []
85+
for edge in value.polygon().each_edge():
86+
points.append({"x": edge.p1.x, "y": edge.p1.y})
87+
points.append({"x": edge.p2.x, "y": edge.p2.y})
88+
shapes.append({"type": "polygon", "points": points})
89+
elif value.is_path():
90+
points = []
91+
for edge in value.path().polygon().each_edge():
92+
points.append({"x": edge.p1.x, "y": edge.p1.y})
93+
points.append({"x": edge.p2.x, "y": edge.p2.y})
94+
shapes.append({"type": "polygon", "points": points})
95+
elif value.is_text():
96+
text.append(value.text())
97+
elif value.is_string():
98+
text.append(value.string())
99+
else:
100+
print("[WARN] Unknown violation shape:", value)
101+
102+
comment = ""
103+
if hasattr(item, "comment"):
104+
comment = item.comment
105+
if text:
106+
if comment:
107+
comment += ": "
108+
comment += ", ".join(text)
109+
110+
if comment:
111+
violation["comment"] = comment
112+
113+
return ordb
114+
115+
8116
app = pya.Application.instance()
9117
win = app.main_window()
10118

@@ -16,68 +124,10 @@
16124
rdb = layout_view.rdb(rdb_id)
17125
rdb.load(in_drc)
18126

19-
violations = []
20-
21-
for category in rdb.each_category():
22-
if category.num_items() == 0:
23-
# ignore categories with no data
24-
continue
25-
26-
violations_shapes = []
27-
for item in rdb.each_item_per_category(category.rdb_id()):
28-
for value in item.each_value():
29-
if value.is_box():
30-
violations_shapes.append(
31-
{
32-
"type": "box",
33-
"shape": [
34-
{"x": value.box().left, "y": value.box().bottom},
35-
{"x": value.box().right, "y": value.box().top},
36-
],
37-
}
38-
)
39-
elif value.is_edge():
40-
violations_shapes.append(
41-
{
42-
"type": "edge",
43-
"shape": [
44-
{"x": value.edge().p1.x, "y": value.edge().p1.y},
45-
{"x": value.edge().p2.x, "y": value.edge().p2.y},
46-
],
47-
}
48-
)
49-
elif value.is_edge_pair():
50-
edge1 = value.edge_pair().first
51-
edge2 = value.edge_pair().second
52-
violations_shapes.append(
53-
{
54-
"type": "edge_pair",
55-
"shape": [
56-
{"x": edge1.p1.x, "y": edge1.p1.y},
57-
{"x": edge1.p2.x, "y": edge1.p2.y},
58-
{"x": edge2.p1.x, "y": edge2.p1.y},
59-
{"x": edge2.p2.x, "y": edge2.p2.y},
60-
],
61-
}
62-
)
63-
elif value.is_polygon():
64-
points = []
65-
for edge in value.polygon().each_edge():
66-
points.append({"x": edge.p1.x, "y": edge.p1.y})
67-
points.append({"x": edge.p2.x, "y": edge.p2.y})
68-
violations_shapes.append({"type": "polygon", "shape": points})
69-
else:
70-
print("Unknown violation shape:", value)
71-
72-
violations.append(
73-
{
74-
"name": category.name(),
75-
"description": category.description,
76-
"violations": violations_shapes,
77-
}
78-
)
127+
ordb = {}
128+
ordb["DRC"] = convert_drc(rdb)
79129

80130
with open(out_file, "w") as outfile:
81-
json.dump({"DRC": violations}, outfile)
131+
json.dump(ordb, outfile)
82132

83133
app.exit(0)

0 commit comments

Comments
 (0)