more robust matching and assign processing
This commit is contained in:
1 parent
53629c5c28
commit
d2357859f6
3 files changed
+38
-29
No files matched your search
@@ -312,7 +312,7 @@ class Circuit:
|
||||
def _locs(self, prefix, nodes):
|
||||
d_top = dict()
|
||||
for i, n in enumerate(nodes):
|
||||
if m := re.match(fr'({prefix}.*?)((?:[\d_\[\]])*$)', n.name):
|
||||
if m := re.match(fr'({re.escape(prefix)}.*?)((?:[\d_\[\]])*$)', n.name):
|
||||
path = [m[1]] + [int(v) for v in re.split(r'[_\[\]]+', m[2]) if len(v) > 0]
|
||||
d = d_top
|
||||
for j in path[:-1]:
|
||||
|
||||
+2
-2
@@ -107,8 +107,8 @@ class DelayFile:
|
||||
for n1, n2, *delvals in self._interconnects:
|
||||
delvals = [d if len(d) > 0 else [0, 0, 0] for d in delvals]
|
||||
if max(max(delvals)) == 0: continue
|
||||
cn1, pn1 = n1.split('/') if '/' in n1 else (n1, None)
|
||||
cn2, pn2 = n2.split('/') if '/' in n2 else (n2, None)
|
||||
cn1, pn1 = (n1, None) if (slash := n1.rfind('/')) < 0 else (n1[:slash], n1[slash+1:])
|
||||
cn2, pn2 = (n2, None) if (slash := n2.rfind('/')) < 0 else (n2[:slash], n2[slash+1:])
|
||||
cn1 = cn1.replace('\\','')
|
||||
cn2 = cn2.replace('\\','')
|
||||
c1, c2 = circuit.cells[cn1], circuit.cells[cn2]
|
||||
|
||||
+35
-26
@@ -123,6 +123,9 @@ class VerilogTransformer(Transformer):
|
||||
assignments = []
|
||||
for stmt in args[2:]: # pass 1: instantiate cells and driven signals
|
||||
if isinstance(stmt, Instantiation):
|
||||
if stmt.type not in self.tlib.cells:
|
||||
log.warn(f'Ignoring cell of unknown kind "{stmt.type}"')
|
||||
continue
|
||||
n = Node(c, stmt.name, kind=stmt.type)
|
||||
for p, s in stmt.pins.items():
|
||||
if self.tlib.pin_is_output(n.kind, p):
|
||||
@@ -141,35 +144,41 @@ class VerilogTransformer(Transformer):
|
||||
c.io_nodes[positions[name]] = n
|
||||
if sd.kind == 'input':
|
||||
Line(c, n, Node(c, name))
|
||||
for target, source in assignments: # pass 1.5: process signal assignments
|
||||
target_sigs = []
|
||||
if not isinstance(target, list): target = [target]
|
||||
for s in target:
|
||||
if s in sig_decls:
|
||||
target_sigs += sig_decls[s].names
|
||||
else:
|
||||
target_sigs.append(s)
|
||||
source_sigs = []
|
||||
if not isinstance(source, list): source = [source]
|
||||
for s in source:
|
||||
if s in sig_decls:
|
||||
source_sigs += sig_decls[s].names
|
||||
else:
|
||||
source_sigs.append(s)
|
||||
for t, s in zip(target_sigs, source_sigs):
|
||||
if t in c.forks:
|
||||
assert s not in c.forks, 'assignment between two driven signals'
|
||||
Line(c, c.forks[t], Node(c, s))
|
||||
elif s in c.forks:
|
||||
assert t not in c.forks, 'assignment between two driven signals'
|
||||
Line(c, c.forks[s], Node(c, t))
|
||||
elif s.startswith("1'b"):
|
||||
cnode = Node(c, f'__const{s[3]}_{const_count}__', f'__const{s[3]}__')
|
||||
const_count += 1
|
||||
Line(c, cnode, Node(c, t))
|
||||
while len(assignments) > 0:
|
||||
more_assignments = []
|
||||
for target, source in assignments: # pass 1.5: process signal assignments
|
||||
target_sigs = []
|
||||
if not isinstance(target, list): target = [target]
|
||||
for s in target:
|
||||
if s in sig_decls:
|
||||
target_sigs += sig_decls[s].names
|
||||
else:
|
||||
target_sigs.append(s)
|
||||
source_sigs = []
|
||||
if not isinstance(source, list): source = [source]
|
||||
for s in source:
|
||||
if s in sig_decls:
|
||||
source_sigs += sig_decls[s].names
|
||||
else:
|
||||
source_sigs.append(s)
|
||||
for t, s in zip(target_sigs, source_sigs):
|
||||
if t in c.forks:
|
||||
assert s not in c.forks, 'assignment between two driven signals'
|
||||
Line(c, c.forks[t], Node(c, s))
|
||||
elif s in c.forks:
|
||||
assert t not in c.forks, 'assignment between two driven signals'
|
||||
Line(c, c.forks[s], Node(c, t))
|
||||
elif s.startswith("1'b"):
|
||||
cnode = Node(c, f'__const{s[3]}_{const_count}__', f'__const{s[3]}__')
|
||||
const_count += 1
|
||||
Line(c, cnode, Node(c, t))
|
||||
else:
|
||||
more_assignments.append((target, source))
|
||||
assignments = more_assignments
|
||||
for stmt in args[2:]: # pass 2: connect signals to readers
|
||||
if isinstance(stmt, Instantiation):
|
||||
for p, s in stmt.pins.items():
|
||||
if stmt.name not in c.cells: continue
|
||||
n = c.cells[stmt.name]
|
||||
if self.tlib.pin_is_output(n.kind, p): continue
|
||||
if s.startswith("1'b"):
|
||||
|
||||
Reference in new issue
Block a user