-
Notifications
You must be signed in to change notification settings - Fork 152
/
makesdf.py
136 lines (112 loc) · 3.99 KB
/
makesdf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import json
import argparse
from prjxray.util import OpenSafeFile
def get_elems_count(timings, slice, site, bel_type):
combinational = 0
sequential = 0
for delay in timings[slice][site][bel_type]:
if 'sequential' in timings[slice][site][bel_type][delay]:
sequential += 1
else:
combinational += 1
return combinational, sequential
def produce_sdf(timings, outdir):
for slice in timings:
sdf = \
"""
(DELAYFILE
(SDFVERSION \"3.0\")
(TIMESCALE 1ns)
"""
for site in sorted(timings[slice]):
for bel_type in sorted(timings[slice][site]):
combinational, sequential = get_elems_count(
timings, slice, site, bel_type)
#define CELL
cell= \
"""
(CELL
(CELLTYPE \"{name}\")
(INSTANCE {location})""".format(name=bel_type.upper(), location=site)
sdf += cell
#define delay header (if needed)
if combinational > 0:
delay_hdr = \
"""
(DELAY
(ABSOLUTE"""
sdf += delay_hdr
# add all delays definitions
for delay in sorted(timings[slice][site][bel_type]):
if 'sequential' in timings[slice][site][bel_type][
delay]:
continue
dly = \
"""
(IOPATH {input} {output} ({FAST_MIN}::{FAST_MAX})({SLOW_MIN}::{SLOW_MAX}))""".format(**timings[slice][site][bel_type][delay])
if 'extra_ports' in timings[slice][site][bel_type][
delay] is not None:
dly += \
""" #extra ports {}""".format(timings[slice][site][bel_type][delay]['extra_ports'])
sdf += dly
# close DELAY definition
enddelay = \
"""
)
)"""
sdf += enddelay
# define TIMINGCHECK header (if needed)
if sequential > 0:
timingcheck_hdr = \
"""
(TIMINGCHECK"""
sdf += timingcheck_hdr
for delay in sorted(timings[slice][site][bel_type]):
if 'sequential' not in timings[slice][site][bel_type][
delay]:
continue
timingcheck = \
"""
({prop} {input} (posedge {clock}) ({SLOW_MIN}::{SLOW_MAX}))""".format(
prop=timings[slice][site][bel_type][delay]['sequential'].upper(),
**timings[slice][site][bel_type][delay])
if 'extra_ports' in timings[slice][site][bel_type][
delay] is not None:
timingcheck += \
""" #extra ports {}""".format(timings[slice][site][bel_type][delay]['extra_ports'])
sdf += timingcheck
# close TIMINGCHECK definition
endtimingcheck = \
"""
)"""
sdf += endtimingcheck
endcell = \
"""
)"""
sdf += endcell
# end of SDF
sdf += \
"""
)"""
with OpenSafeFile(outdir + '/' + slice + '.sdf', "w") as fp:
fp.write(sdf)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--json', type=str, help="Input JSON file")
parser.add_argument('--sdf', type=str, help="SDF files output directory")
args = parser.parse_args()
with OpenSafeFile(args.json, 'r') as fp:
timings = json.load(fp)
produce_sdf(timings, args.sdf)
if __name__ == '__main__':
main()