systemc-clang
2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
plugins
hdl
parselib
transforms
sensevar_movement.py
Go to the documentation of this file.
1
from
lark
import
Tree
2
from
parselib.transforms
import
TopDown
3
from
parselib.transforms.node
import
TypeDefType
4
from
..utils
import
dprint, is_tree_type, get_ids_in_tree_types, get_ids_in_tree, alternate_ids, set_ids_in_tree_dfs
5
from
pprint
import
pprint
6
from
copy
import
deepcopy
7
8
9
class
SensevarMovement
(
TopDown
):
10
"""This pass moves sensevar declaration within a for loop to the top of the module,
11
and generate a generate block for each sensevar"""
12
def __init__(self):
13
super().__init__()
14
self.is_in_initblock = False
15
self.is_for_stmt = False
16
self.only_sensevar = False
17
self.current_for_stmt = None
18
self.current_module = None
19
self.initblock_vardecls = []
20
21
def __decl_referred_in_sensvar(self, sensvar, vardecl):
22
var_ids = get_ids_in_tree_types(vardecl, ['vardeclrn'])
23
sensvar_ids = get_ids_in_tree_types(sensvar, ['hvarref'])
24
if set(var_ids).intersection(set(sensvar_ids)):
25
return True
26
return False
27
28
def __create_sensevar_generate_block(self, tree):
29
assert is_tree_type(tree, "hmodule"), "tree should be a hmodule when creating generate blocks for sensitivity variables"
30
if self.sensevar_dict == {}: return
31
genblk = Tree("hgenerateblock", [ ])
32
external_decl = set()
33
for_list = []
34
for sensvar, (process, for_stmt) in self.sensevar_dict.items():
35
# create a generate block for each sensevar
36
for vardecl in self.initblock_vardecls:
37
if self.__decl_referred_in_sensvar(sensvar, vardecl):
38
external_decl.add(vardecl)
39
40
process_node = self.processes.get(process, None)
41
assert process_node is not None, f"sensvar {sensvar} defined for unknown process {process}"
42
for_stmt_duplicate = deepcopy(for_stmt)
43
proc = deepcopy(process_node)
44
setattr(proc, 'force_sensevar', sensvar)
45
for_stmt_duplicate.children[3].children = [proc]
46
for_list.append(for_stmt_duplicate)
47
48
genblk.children = [Tree("hgenvardecl", list(external_decl))] + for_list
49
tree.children.append(genblk)
50
51
def hmodule(self, tree):
52
self.current_module = tree.children[0].value
53
self.initblock_vardecls = []
54
self.sensevar_dict = {}
55
self.processes = dict()
56
57
self.__push_up(tree)
58
59
self.__create_sensevar_generate_block(tree)
60
61
self.current_module = None
62
self.sensevar_dict = {}
63
self.initblock_vardecls = []
64
return tree
65
66
def hprocess(self, tree):
67
# we don't need to push up the process for now.
68
self.processes[tree.children[0].value] = tree
69
return tree
70
71
def hmodinitblock(self, tree):
72
self.is_in_initblock = True
73
self.__push_up(tree)
74
tree.children = list(filter(lambda x: x is not None, tree.children)) # we might remove for loops
75
self.is_in_initblock = False
76
return tree
77
78
def vardecl(self, tree):
79
if self.is_in_initblock:
80
self.__push_up(tree)
81
self.initblock_vardecls.append(tree)
82
return tree
83
else:
84
self.__push_up(tree)
85
return tree
86
87
def forstmt(self, tree):
88
self.is_for_stmt = True
89
self.only_sensevar = False
90
self.current_for_stmt = tree
91
92
for_loop_sensevar = self.is_in_initblock and self.is_for_stmt
93
94
self.__push_up(tree)
95
# init, cond, step, body = tree.children
96
97
98
self.is_for_stmt = False
99
self.current_for_stmt = None
100
if self.only_sensevar:
101
self.only_sensevar = False
102
return None # In this case we simply remove the for loop statement
103
else:
104
self.only_sensevar = False
105
return tree
106
107
108
def stmt(self, tree):
109
if self.is_for_stmt and self.is_in_initblock:
110
is_sensvar = map(lambda x: is_tree_type(x, "hnamedsensvar") , tree.children)
111
if all(is_sensvar):
112
self.only_sensevar = True
113
self.__push_up(tree)
114
# In this case, all the sensevar declaration should be moved to the top of the module
115
return Tree("hnoop", [])
116
elif any(is_sensvar):
117
raise ValueError("sensevar declaration should be the only statement in for loop init block, if it contains a sensevar declaration")
118
else:
119
self.__push_up(tree)
120
return tree
121
else:
122
self.__push_up(tree)
123
return tree
124
125
def hnamedsensvar(self, tree):
126
for_loop_sensevar = self.is_in_initblock and self.is_for_stmt
127
assert for_loop_sensevar, "named sensevar is only allowed in for loop init block"
128
129
process = tree.children[0].value
130
sensevar = tree.children[1]
131
self.sensevar_dict[sensevar] = (process, self.current_for_stmt)
132
133
# remove the sensevar declaration from the original for loop
134
return None
135
parselib.transforms.sensevar_movement.SensevarMovement
Definition
sensevar_movement.py:9
parselib.transforms.top_down.TopDown
Definition
top_down.py:24
parselib.transforms.node
Definition
node.py:1
parselib.transforms
Definition
__init__.py:1
Generated by
1.12.0