-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUtilityLibertyToMeta.py
More file actions
101 lines (82 loc) · 4.53 KB
/
UtilityLibertyToMeta.py
File metadata and controls
101 lines (82 loc) · 4.53 KB
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
import argparse
import json
import itertools
import pathlib
from enum import StrEnum
from typing import List, Iterable
from logging import info, debug
from Liberty.CellImporter import ImportLibertyCells
from Logging.Logging import ParseOptions, ParseEnumList
from Logic.Logic import NormalizeEquation
class DebugOptions(StrEnum):
pass
def _ExtractPinsFromEquation(equation: str, states: List[str]) -> Iterable[str]:
equation = NormalizeEquation(equation)
for name in equation.split(' '):
name = name.strip()
if name != '' and name not in states and name not in ['0', '1']:
yield name
if __name__ == '__main__':
parser = argparse.ArgumentParser(
prog='UtilityLibertyToMeta',
description='Exports meta data in JSON format about the liberty library',
add_help=True
)
parser.add_argument('--library', dest='library', type=str, required=True, help='Configuration file for the cell library')
parser.add_argument('--library-path', dest='library_path', type=str, required=True, help='Root directory of the cell library')
parser.add_argument('--output', dest='output_path', type=str, required=True, help='Output path for generated meta JSON')
parser.add_argument('-d', '--debug', dest='debug', type=str, nargs='*', default=[], help='Enable debug options (use -h debug for supported options)')
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False, help='Enable verbose logging')
options = ParseOptions(parser, [
('debug', DebugOptions),
])
info('------------------------ PARSING OPTIONS -----------------------')
debugOptions = ParseEnumList('debug', DebugOptions, options.debug)
for debugOption in debugOptions:
debug(f'Enabling debug option {debugOption.value}')
outputPath = pathlib.Path(options.output_path).parent
outputPath.mkdir(parents=True, exist_ok=True)
info('------------------------ LOADING CELL INFO -----------------------')
with open(options.library, 'rt', encoding='utf-8') as file:
library = json.load(file)
libraryPath = pathlib.Path(options.library_path)
libertyPath = libraryPath / library['paths']['liberty']
libertyData = ImportLibertyCells(libertyPath)
info('------------------------ EXPORTING META DATA -----------------------')
meta = {}
for cell_name, cell in libertyData.items():
inputs = cell.inputs
outputs = cell.outputs
clocks = cell.clocks
clocks += cell.attributes['ff_clock'] if 'ff_clock' in cell.attributes else []
clocks += cell.attributes['latch_enable'] if 'latch_enable' in cell.attributes else []
sets = cell.attributes['ff_set'] if 'ff_set' in cell.attributes else []
sets += cell.attributes['latch_set'] if 'latch_set' in cell.attributes else []
resets = cell.attributes['ff_reset'] if 'ff_reset' in cell.attributes else []
resets += cell.attributes['latch_reset'] if 'latch_reset' in cell.attributes else []
states = cell.attributes['ff_state_internal'] if 'ff_state_internal' in cell.attributes else []
states += cell.attributes['ff_state_positive'] if 'ff_state_positive' in cell.attributes else []
states += cell.attributes['ff_state_negative'] if 'ff_state_negative' in cell.attributes else []
states += cell.attributes['latch_state_positive'] if 'latch_state_positive' in cell.attributes else []
states += cell.attributes['latch_state_negative'] if 'latch_state_negative' in cell.attributes else []
clocks = list(set(itertools.chain(*[_ExtractPinsFromEquation(equation, states) for equation in clocks])))
resets = list(set(itertools.chain(*[_ExtractPinsFromEquation(equation, states) for equation in resets])))
sets = list(set(itertools.chain(*[_ExtractPinsFromEquation(equation, states) for equation in sets])))
inputs = list(set(inputs) - set(clocks) - set(sets) - set(resets))
combinational = cell.attributes['combinational'] if 'combinational' in cell.attributes else False
sequential = cell.attributes['sequential'] if 'sequential' in cell.attributes else False
latch = cell.attributes['latch'] if 'latch' in cell.attributes else False
flipflop = cell.attributes['flipflop'] if 'flipflop' in cell.attributes else False
meta[cell_name] = {
'inputs': inputs,
'outputs': outputs,
**({'clocks': clocks} if len(clocks) > 0 else {}),
**({'sets': sets} if len(sets) > 0 else {}),
**({'resets': resets} if len(resets) > 0 else {}),
**({'combinational': True} if combinational else {}),
**({'sequential': True} if sequential else {}),
**({'latch': True} if latch else {}),
**({'flipflop': True} if flipflop else {}),
}
with open(options.output_path, 'wt', encoding='utf-8') as stream:
json.dump(meta, stream, indent=4)