Skip to content

Commit 18ccf83

Browse files
committed
Make userCodeMap part of the class to avoid conversion issues
_userCodeMap was a global variable. It has been integrated inside the classes that use it to avoid undesired interactions.
1 parent 09f1cec commit 18ccf83

File tree

3 files changed

+92
-81
lines changed

3 files changed

+92
-81
lines changed

myhdl/_extractHierarchy.py

+51-48
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@
3636
from ._resolverefs import _resolveRefs
3737
from ._util import _flatten, _genfunc, _isTupleOfInts, _isTupleOfFloats
3838

39-
4039
_profileFunc = None
4140

4241

4342
class _error:
4443
pass
4544

45+
4646
_error.NoInstances = "No instances found"
4747
_error.InconsistentHierarchy = "Inconsistent hierarchy - are all" \
48-
" instances returned ?"
48+
" instances returned ?"
4949
_error.InconsistentToplevel = "Inconsistent top level %s for %s - should be 1"
5050

5151

@@ -77,6 +77,7 @@ def __init__(self, level, obj, subs, constdict, sigdict, memdict,
7777

7878
self.name = None
7979

80+
8081
_memInfoMap = {}
8182

8283

@@ -174,11 +175,6 @@ def _isRom(mem):
174175
return id(mem) in _romInfoMap
175176

176177

177-
_userCodeMap = {'verilog': {},
178-
'vhdl': {}
179-
}
180-
181-
182178
class _UserCode(object):
183179
__slots__ = ['code', 'namespace', 'funcname', 'func', 'sourcefile',
184180
'sourceline']
@@ -204,7 +200,14 @@ def __str__(self):
204200
code = "\n%s\n" % code
205201
return code
206202

203+
def _scrub_namespace(self):
204+
for nm, obj in self.namespace.items():
205+
if _isMem(obj):
206+
memi = _getMemInfo(obj)
207+
self.namespace[nm] = memi.name
208+
207209
def _interpolate(self):
210+
self._scrub_namespace()
208211
return string.Template(self.code).substitute(self.namespace)
209212

210213

@@ -264,40 +267,6 @@ def __str__(self):
264267
return s
265268

266269

267-
def _addUserCode(specs, arg, funcname, func, frame):
268-
classMap = {
269-
'__verilog__': _UserVerilogCodeDepr,
270-
'__vhdl__': _UserVhdlCodeDepr,
271-
'verilog_code': _UserVerilogCode,
272-
'vhdl_code': _UserVhdlCode,
273-
'verilog_instance': _UserVerilogInstance,
274-
'vhdl_instance': _UserVhdlInstance,
275-
276-
}
277-
namespace = frame.f_globals.copy()
278-
namespace.update(frame.f_locals)
279-
sourcefile = inspect.getsourcefile(frame)
280-
sourceline = inspect.getsourcelines(frame)[1]
281-
for hdl in _userCodeMap:
282-
oldspec = "__%s__" % hdl
283-
codespec = "%s_code" % hdl
284-
instancespec = "%s_instance" % hdl
285-
spec = None
286-
# XXX add warning logic
287-
if instancespec in specs:
288-
spec = instancespec
289-
elif codespec in specs:
290-
spec = codespec
291-
elif oldspec in specs:
292-
spec = oldspec
293-
if spec:
294-
assert id(arg) not in _userCodeMap[hdl]
295-
code = specs[spec]
296-
_userCodeMap[hdl][id(arg)] = classMap[spec](code, namespace,
297-
funcname, func,
298-
sourcefile, sourceline)
299-
300-
301270
class _CallFuncVisitor(object):
302271

303272
def __init__(self):
@@ -319,8 +288,10 @@ def __init__(self, name, dut, *args, **kwargs):
319288

320289
global _profileFunc
321290
_memInfoMap.clear()
322-
for hdl in _userCodeMap:
323-
_userCodeMap[hdl].clear()
291+
self.userCodeMap = {'verilog': {},
292+
'vhdl': {}
293+
}
294+
324295
self.skipNames = ('always_comb', 'instance',
325296
'always_seq', '_always_seq_decorator',
326297
'always', '_always_decorator',
@@ -395,7 +366,7 @@ def extractor(self, frame, event, arg):
395366
isGenSeq = _isGenSeq(arg)
396367
if isGenSeq:
397368
specs = {}
398-
for hdl in _userCodeMap:
369+
for hdl in self.userCodeMap:
399370
spec = "__%s__" % hdl
400371
if spec in frame.f_locals and frame.f_locals[spec]:
401372
specs[spec] = frame.f_locals[spec]
@@ -408,7 +379,7 @@ def extractor(self, frame, event, arg):
408379
getattr(func, spec):
409380
specs[spec] = getattr(func, spec)
410381
if specs:
411-
_addUserCode(specs, arg, funcname, func, frame)
382+
self._add_user_code(specs, arg, funcname, func, frame)
412383
# building hierarchy only makes sense if there are generators
413384
if isGenSeq and arg:
414385
constdict = {}
@@ -462,7 +433,7 @@ def extractor(self, frame, event, arg):
462433

463434
subs = []
464435
for n, sub in frame.f_locals.items():
465-
for elt in _inferArgs(arg):
436+
for elt in _infer_args(arg):
466437
if elt is sub:
467438
subs.append((n, sub))
468439
inst = _Instance(self.level, arg, subs, constdict,
@@ -474,8 +445,40 @@ def extractor(self, frame, event, arg):
474445
if funcname in self.skipNames:
475446
self.skip -= 1
476447

477-
478-
def _inferArgs(arg):
448+
def _add_user_code(self, specs, arg, funcname, func, frame):
449+
classMap = {
450+
'__verilog__': _UserVerilogCodeDepr,
451+
'__vhdl__': _UserVhdlCodeDepr,
452+
'verilog_code': _UserVerilogCode,
453+
'vhdl_code': _UserVhdlCode,
454+
'verilog_instance': _UserVerilogInstance,
455+
'vhdl_instance': _UserVhdlInstance,
456+
}
457+
namespace = frame.f_globals.copy()
458+
namespace.update(frame.f_locals)
459+
sourcefile = inspect.getsourcefile(frame)
460+
sourceline = inspect.getsourcelines(frame)[1]
461+
for hdl in self.userCodeMap:
462+
oldspec = "__%s__" % hdl
463+
codespec = "%s_code" % hdl
464+
instancespec = "%s_instance" % hdl
465+
spec = None
466+
# XXX add warning logic
467+
if instancespec in specs:
468+
spec = instancespec
469+
elif codespec in specs:
470+
spec = codespec
471+
elif oldspec in specs:
472+
spec = oldspec
473+
if spec:
474+
assert id(arg) not in self.userCodeMap[hdl]
475+
code = specs[spec]
476+
self.userCodeMap[hdl][id(arg)] = classMap[spec](code, namespace,
477+
funcname, func,
478+
sourcefile, sourceline)
479+
480+
481+
def _infer_args(arg):
479482
c = [arg]
480483
if isinstance(arg, (tuple, list)):
481484
c += list(arg)

myhdl/conversion/_toVHDL.py

+20-17
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
from .._bin import bin
5656
from .._errors import ToVHDLError, ToVHDLWarning, ConversionError
5757
from .._extractHierarchy import (_HierExtr, _isMem, _isRom, _getMemInfo,
58-
_UserVhdlCode, _userCodeMap, _MemInfo,
58+
_UserVhdlCode, _MemInfo,
5959
_RomInfo, _Constant, _getRomInfo,
6060
_makeMemInfo, _makeRomInfo)
6161
from .._instance import _Instantiator
@@ -90,12 +90,16 @@ def __init__(self):
9090
self.enum_types = {}
9191
self.rom_types = {}
9292
self.sfixed = False
93+
self.userCodeMap = {'verilog': {},
94+
'vhdl': {}
95+
}
9396

9497
def __call__(self, h, stdLogicPorts):
9598
p_entity_dict = {}
9699
p_offsprings_dict = {}
97100
p_v_entity_dict = {}
98-
entity_list = _flatten(h.hierarchy[:])
101+
entity_list = self._flatten(h.hierarchy[:])
102+
self.userCodeMap = h.userCodeMap
99103
absnames = h.absnames
100104

101105
# Search the associated entities (components)
@@ -158,7 +162,7 @@ def __call__(self, h, stdLogicPorts):
158162
components_list.append(component)
159163
component._clean_signals(1)
160164

161-
p_entity_obj = _flatten(p_entity.obj)
165+
p_entity_obj = self._flatten(p_entity.obj)
162166
# After having determined the signals and other elements, the
163167
# duplicated generators are deleted. It has to be done between
164168
# generating the signals and analyzing the top function to avoid
@@ -402,6 +406,18 @@ def __call__(self, h, stdLogicPorts):
402406

403407
return self
404408

409+
def _flatten(self, *args):
410+
arglist = []
411+
for arg in args:
412+
if id(arg) in self.userCodeMap['vhdl']:
413+
arglist.append(self.userCodeMap['vhdl'][id(arg)])
414+
elif isinstance(arg, (list, tuple, set)):
415+
for item in arg:
416+
arglist.extend(self._flatten(item))
417+
else:
418+
arglist.append(arg)
419+
return arglist
420+
405421
def _flattenNames(self, args_list, args_dict, names_list, existing_signals,
406422
base_name=''):
407423
sigs_dict = {}
@@ -1083,19 +1099,6 @@ def _clean_signals(self, level):
10831099
self.entity._clean_signals(level - 1)
10841100

10851101

1086-
def _flatten(*args):
1087-
arglist = []
1088-
for arg in args:
1089-
if id(arg) in _userCodeMap['vhdl']:
1090-
arglist.append(_userCodeMap['vhdl'][id(arg)])
1091-
elif isinstance(arg, (list, tuple, set)):
1092-
for item in arg:
1093-
arglist.extend(_flatten(item))
1094-
else:
1095-
arglist.append(arg)
1096-
return arglist
1097-
1098-
10991102
def _makeDoc(doc, indent=''):
11001103
if doc is None:
11011104
return ''
@@ -4452,7 +4455,7 @@ def visit_Call(self, node):
44524455
node.vhd = vhd_unsigned(s)
44534456
elif f is bool:
44544457
node.vhd = vhd_boolean()
4455-
elif f in _flatten(int, ord):
4458+
elif f in (int, ord):
44564459
node.vhd = vhd_int()
44574460
node.args[0].vhd = vhd_int()
44584461
elif f is float:

myhdl/conversion/_toVerilog.py

+21-16
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
from .._delay import delay
4848
from .._errors import ToVerilogError, ToVerilogWarning
4949
from .._extractHierarchy import _HierExtr, _isMem, _getMemInfo, _MemInfo, \
50-
_isRom, _getRomInfo, _UserVerilogCode, _userCodeMap
50+
_isRom, _getRomInfo, _UserVerilogCode
5151

5252
from .._instance import _Instantiator
5353
from ._misc import _error, _kind, _context, \
@@ -70,19 +70,6 @@ def _checkArgs(arglist):
7070
raise ToVerilogError(_error.ArgType, arg)
7171

7272

73-
def _flatten(*args):
74-
arglist = []
75-
for arg in args:
76-
if id(arg) in _userCodeMap['verilog']:
77-
arglist.append(_userCodeMap['verilog'][id(arg)])
78-
elif isinstance(arg, (list, tuple, set)):
79-
for item in arg:
80-
arglist.extend(_flatten(item))
81-
else:
82-
arglist.append(arg)
83-
return arglist
84-
85-
8673
def _makeDoc(doc, indent=''):
8774
if doc is None:
8875
return ''
@@ -105,7 +92,8 @@ class _ToVerilogConvertor(object):
10592
"no_myhdl_header",
10693
"no_testbench",
10794
"portmap",
108-
"trace"
95+
"trace",
96+
"userCodeMap"
10997
)
11098

11199
def __init__(self):
@@ -119,6 +107,21 @@ def __init__(self):
119107
self.no_myhdl_header = False
120108
self.no_testbench = False
121109
self.trace = False
110+
self.userCodeMap = {'verilog': {},
111+
'vhdl': {}
112+
}
113+
114+
def _flatten(self, *args):
115+
arglist = []
116+
for arg in args:
117+
if id(arg) in self.userCodeMap['verilog']:
118+
arglist.append(self.userCodeMap['verilog'][id(arg)])
119+
elif isinstance(arg, (list, tuple, set)):
120+
for item in arg:
121+
arglist.extend(self._flatten(item))
122+
else:
123+
arglist.append(arg)
124+
return arglist
122125

123126
def __call__(self, func, *args, **kwargs):
124127
global _converting
@@ -148,14 +151,16 @@ def __call__(self, func, *args, **kwargs):
148151
else:
149152
directory = self.directory
150153

154+
self.userCodeMap = h.userCodeMap
155+
151156
vfilename = name + ".v"
152157
vpath = os.path.join(directory, vfilename)
153158
vfile = open(vpath, 'w+')
154159

155160
# initialize properly #
156161
_genUniqueSuffix.reset()
157162

158-
arglist = _flatten(h.top)
163+
arglist = self._flatten(h.top)
159164
# print h.top
160165
_checkArgs(arglist)
161166
genlist = _analyzeGens(arglist, h.absnames)

0 commit comments

Comments
 (0)