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):
|
def _locs(self, prefix, nodes):
|
||||||
d_top = dict()
|
d_top = dict()
|
||||||
for i, n in enumerate(nodes):
|
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]
|
path = [m[1]] + [int(v) for v in re.split(r'[_\[\]]+', m[2]) if len(v) > 0]
|
||||||
d = d_top
|
d = d_top
|
||||||
for j in path[:-1]:
|
for j in path[:-1]:
|
||||||
|
|||||||
+2
-2
@@ -107,8 +107,8 @@ class DelayFile:
|
|||||||
for n1, n2, *delvals in self._interconnects:
|
for n1, n2, *delvals in self._interconnects:
|
||||||
delvals = [d if len(d) > 0 else [0, 0, 0] for d in delvals]
|
delvals = [d if len(d) > 0 else [0, 0, 0] for d in delvals]
|
||||||
if max(max(delvals)) == 0: continue
|
if max(max(delvals)) == 0: continue
|
||||||
cn1, pn1 = n1.split('/') if '/' in n1 else (n1, None)
|
cn1, pn1 = (n1, None) if (slash := n1.rfind('/')) < 0 else (n1[:slash], n1[slash+1:])
|
||||||
cn2, pn2 = n2.split('/') if '/' in n2 else (n2, None)
|
cn2, pn2 = (n2, None) if (slash := n2.rfind('/')) < 0 else (n2[:slash], n2[slash+1:])
|
||||||
cn1 = cn1.replace('\\','')
|
cn1 = cn1.replace('\\','')
|
||||||
cn2 = cn2.replace('\\','')
|
cn2 = cn2.replace('\\','')
|
||||||
c1, c2 = circuit.cells[cn1], circuit.cells[cn2]
|
c1, c2 = circuit.cells[cn1], circuit.cells[cn2]
|
||||||
|
|||||||
+35
-26
@@ -123,6 +123,9 @@ class VerilogTransformer(Transformer):
|
|||||||
assignments = []
|
assignments = []
|
||||||
for stmt in args[2:]: # pass 1: instantiate cells and driven signals
|
for stmt in args[2:]: # pass 1: instantiate cells and driven signals
|
||||||
if isinstance(stmt, Instantiation):
|
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)
|
n = Node(c, stmt.name, kind=stmt.type)
|
||||||
for p, s in stmt.pins.items():
|
for p, s in stmt.pins.items():
|
||||||
if self.tlib.pin_is_output(n.kind, p):
|
if self.tlib.pin_is_output(n.kind, p):
|
||||||
@@ -141,35 +144,41 @@ class VerilogTransformer(Transformer):
|
|||||||
c.io_nodes[positions[name]] = n
|
c.io_nodes[positions[name]] = n
|
||||||
if sd.kind == 'input':
|
if sd.kind == 'input':
|
||||||
Line(c, n, Node(c, name))
|
Line(c, n, Node(c, name))
|
||||||
for target, source in assignments: # pass 1.5: process signal assignments
|
while len(assignments) > 0:
|
||||||
target_sigs = []
|
more_assignments = []
|
||||||
if not isinstance(target, list): target = [target]
|
for target, source in assignments: # pass 1.5: process signal assignments
|
||||||
for s in target:
|
target_sigs = []
|
||||||
if s in sig_decls:
|
if not isinstance(target, list): target = [target]
|
||||||
target_sigs += sig_decls[s].names
|
for s in target:
|
||||||
else:
|
if s in sig_decls:
|
||||||
target_sigs.append(s)
|
target_sigs += sig_decls[s].names
|
||||||
source_sigs = []
|
else:
|
||||||
if not isinstance(source, list): source = [source]
|
target_sigs.append(s)
|
||||||
for s in source:
|
source_sigs = []
|
||||||
if s in sig_decls:
|
if not isinstance(source, list): source = [source]
|
||||||
source_sigs += sig_decls[s].names
|
for s in source:
|
||||||
else:
|
if s in sig_decls:
|
||||||
source_sigs.append(s)
|
source_sigs += sig_decls[s].names
|
||||||
for t, s in zip(target_sigs, source_sigs):
|
else:
|
||||||
if t in c.forks:
|
source_sigs.append(s)
|
||||||
assert s not in c.forks, 'assignment between two driven signals'
|
for t, s in zip(target_sigs, source_sigs):
|
||||||
Line(c, c.forks[t], Node(c, s))
|
if t in c.forks:
|
||||||
elif s in c.forks:
|
assert s not in c.forks, 'assignment between two driven signals'
|
||||||
assert t not in c.forks, 'assignment between two driven signals'
|
Line(c, c.forks[t], Node(c, s))
|
||||||
Line(c, c.forks[s], Node(c, t))
|
elif s in c.forks:
|
||||||
elif s.startswith("1'b"):
|
assert t not in c.forks, 'assignment between two driven signals'
|
||||||
cnode = Node(c, f'__const{s[3]}_{const_count}__', f'__const{s[3]}__')
|
Line(c, c.forks[s], Node(c, t))
|
||||||
const_count += 1
|
elif s.startswith("1'b"):
|
||||||
Line(c, cnode, Node(c, t))
|
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
|
for stmt in args[2:]: # pass 2: connect signals to readers
|
||||||
if isinstance(stmt, Instantiation):
|
if isinstance(stmt, Instantiation):
|
||||||
for p, s in stmt.pins.items():
|
for p, s in stmt.pins.items():
|
||||||
|
if stmt.name not in c.cells: continue
|
||||||
n = c.cells[stmt.name]
|
n = c.cells[stmt.name]
|
||||||
if self.tlib.pin_is_output(n.kind, p): continue
|
if self.tlib.pin_is_output(n.kind, p): continue
|
||||||
if s.startswith("1'b"):
|
if s.startswith("1'b"):
|
||||||
|
|||||||
Reference in new issue
Block a user