Browse Source

more robust matching and assign processing

devel
Stefan Holst 5 months ago
parent
commit
d2357859f6
  1. 2
      src/kyupy/circuit.py
  2. 4
      src/kyupy/sdf.py
  3. 9
      src/kyupy/verilog.py

2
src/kyupy/circuit.py

@ -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]:

4
src/kyupy/sdf.py

@ -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]

9
src/kyupy/verilog.py

@ -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,6 +144,8 @@ 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))
while len(assignments) > 0:
more_assignments = []
for target, source in assignments: # pass 1.5: process signal assignments for target, source in assignments: # pass 1.5: process signal assignments
target_sigs = [] target_sigs = []
if not isinstance(target, list): target = [target] if not isinstance(target, list): target = [target]
@ -167,9 +172,13 @@ class VerilogTransformer(Transformer):
cnode = Node(c, f'__const{s[3]}_{const_count}__', f'__const{s[3]}__') cnode = Node(c, f'__const{s[3]}_{const_count}__', f'__const{s[3]}__')
const_count += 1 const_count += 1
Line(c, cnode, Node(c, t)) 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"):

Loading…
Cancel
Save