From 82a53e0171026c6b05cc0d58af0a3fc3c3368b94 Mon Sep 17 00:00:00 2001 From: Stefan Holst Date: Sun, 31 Jan 2021 13:41:36 +0900 Subject: [PATCH] improve techlib for gsclib, better constant handling in verilog parser --- src/kyupy/techlib.py | 18 ++++++++++++------ src/kyupy/verilog.py | 21 +++++++++++++++------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/kyupy/techlib.py b/src/kyupy/techlib.py index 5a5a01b..9340cc8 100644 --- a/src/kyupy/techlib.py +++ b/src/kyupy/techlib.py @@ -29,20 +29,26 @@ class TechLib: @staticmethod def pin_index(kind, pin): """Returns a pin list position for a given node kind and pin name.""" + if kind[:3] in ('OAI', 'AOI'): + if pin[0] == 'A': return int(pin[1]) + if pin[0] == 'B': return int(pin[1]) + int(kind[4]) for prefix, pins, index in [('HADD', ('B0', 'SO'), 1), ('MUX21', ('S',), 2), + ('MX2', ('S0',), 2), ('DFF', ('QN',), 1), + ('DFF', ('D',), 0), + ('SDFF', ('D',), 0), ('SDFF', ('QN',), 1), ('SDFF', ('CLK',), 3), ('SDFF', ('RSTB',), 4), ('SDFF', ('SETB',), 5)]: if kind.startswith(prefix) and pin in pins: return index - for index, pins in enumerate([('A1', 'IN1', 'D', 'S', 'INP', 'A', 'Q', 'QN', 'Y', 'Z', 'ZN'), - ('A2', 'IN2', 'CLK', 'CO', 'SE', 'B'), - ('A3', 'IN3', 'RSTB', 'CI', 'SI'), - ('A4', 'IN4', 'SETB'), - ('A5', 'IN5'), - ('A6', 'IN6')]): + for index, pins in enumerate([('A1', 'IN1', 'A', 'S', 'INP', 'Q', 'QN', 'Y', 'Z', 'ZN'), + ('A2', 'IN2', 'B', 'CK', 'CLK', 'CO', 'SE'), + ('A3', 'IN3', 'C', 'RN', 'RSTB', 'CI', 'SI'), + ('A4', 'IN4', 'D', 'SN', 'SETB'), + ('A5', 'IN5', 'E'), + ('A6', 'IN6', 'F')]): if pin in pins: return index raise ValueError(f'Unknown pin index for {kind}.{pin}') diff --git a/src/kyupy/verilog.py b/src/kyupy/verilog.py index c6b5ab0..9d3568f 100644 --- a/src/kyupy/verilog.py +++ b/src/kyupy/verilog.py @@ -57,7 +57,8 @@ class VerilogTransformer(Transformer): @staticmethod def instantiation(args): return Instantiation(args[0], args[1], - dict((pin.children[0], pin.children[1]) for pin in args[2:])) + dict((pin.children[0], + pin.children[1]) for pin in args[2:] if len(pin.children) > 1)) def input(self, args): for sd in [SignalDeclaration('input', signal) for signal in args]: @@ -73,12 +74,14 @@ class VerilogTransformer(Transformer): def wire(self, args): for sd in [SignalDeclaration('wire', signal) for signal in args]: - self._signal_declarations[sd.basename] = sd + if sd.basename not in self._signal_declarations: + self._signal_declarations[sd.basename] = sd def module(self, args): c = Circuit(args[0]) positions = {} pos = 0 + const_count = 0 for intf_sig in args[1].children: for name in self._signal_declarations[intf_sig].names: positions[name] = pos @@ -107,15 +110,21 @@ class VerilogTransformer(Transformer): elif s2 in c.forks: assert s1 not in c.forks, 'assignment between two driven signals' Line(c, c.forks[s2], Node(c, s1)) + elif s2.startswith("1'b"): + cnode = Node(c, f'__const{s2[3]}_{const_count}__', f'__const{s2[3]}__') + const_count += 1 + Line(c, cnode, Node(c, s1)) for stmt in args[2:]: # pass 2: connect signals to readers if isinstance(stmt, Instantiation): for p, s in stmt.pins.items(): n = c.cells[stmt.name] if self.tlib.pin_is_output(n.kind, p): continue if s.startswith("1'b"): - const = f'__const{s[3]}__' - if const not in c.cells: - Line(c, Node(c, const, const), Node(c, s)) + cname = f'__const{s[3]}_{const_count}__' + cnode = Node(c, cname, f'__const{s[3]}__') + const_count += 1 + s = cname + Line(c, cnode, Node(c, s)) fork = c.forks[s] if self.branchforks: branchfork = Node(c, fork.name + "~" + n.name + "/" + p) @@ -144,7 +153,7 @@ GRAMMAR = """ wire: "wire" signal ( "," signal )* ";" assign: "assign" name "=" name ";" instantiation: name name "(" [ pin ( "," pin )* ] ")" ";" - pin: "." name "(" name ")" + pin: "." name "(" name? ")" signal: ( name | "[" /[0-9]+/ ":" /[0-9]+/ "]" name ) name: ( /[a-z_][a-z0-9_\\[\\]]*/i | /\\\\[^\\t \\r\\n]+[\\t \\r\\n](\\[[0-9]+\\])?/i | /1'b0/i | /1'b1/i )