improve techlib for gsclib, better constant handling in verilog parser
This commit is contained in:
1 parent
a2df0e5682
commit
82a53e0171
2 files changed
+26
-11
No files matched your search
+12
-6
@@ -29,20 +29,26 @@ class TechLib:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def pin_index(kind, pin):
|
def pin_index(kind, pin):
|
||||||
"""Returns a pin list position for a given node kind and pin name."""
|
"""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),
|
for prefix, pins, index in [('HADD', ('B0', 'SO'), 1),
|
||||||
('MUX21', ('S',), 2),
|
('MUX21', ('S',), 2),
|
||||||
|
('MX2', ('S0',), 2),
|
||||||
('DFF', ('QN',), 1),
|
('DFF', ('QN',), 1),
|
||||||
|
('DFF', ('D',), 0),
|
||||||
|
('SDFF', ('D',), 0),
|
||||||
('SDFF', ('QN',), 1),
|
('SDFF', ('QN',), 1),
|
||||||
('SDFF', ('CLK',), 3),
|
('SDFF', ('CLK',), 3),
|
||||||
('SDFF', ('RSTB',), 4),
|
('SDFF', ('RSTB',), 4),
|
||||||
('SDFF', ('SETB',), 5)]:
|
('SDFF', ('SETB',), 5)]:
|
||||||
if kind.startswith(prefix) and pin in pins: return index
|
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'),
|
for index, pins in enumerate([('A1', 'IN1', 'A', 'S', 'INP', 'Q', 'QN', 'Y', 'Z', 'ZN'),
|
||||||
('A2', 'IN2', 'CLK', 'CO', 'SE', 'B'),
|
('A2', 'IN2', 'B', 'CK', 'CLK', 'CO', 'SE'),
|
||||||
('A3', 'IN3', 'RSTB', 'CI', 'SI'),
|
('A3', 'IN3', 'C', 'RN', 'RSTB', 'CI', 'SI'),
|
||||||
('A4', 'IN4', 'SETB'),
|
('A4', 'IN4', 'D', 'SN', 'SETB'),
|
||||||
('A5', 'IN5'),
|
('A5', 'IN5', 'E'),
|
||||||
('A6', 'IN6')]):
|
('A6', 'IN6', 'F')]):
|
||||||
if pin in pins: return index
|
if pin in pins: return index
|
||||||
raise ValueError(f'Unknown pin index for {kind}.{pin}')
|
raise ValueError(f'Unknown pin index for {kind}.{pin}')
|
||||||
|
|
||||||
|
|||||||
+14
-5
@@ -57,7 +57,8 @@ class VerilogTransformer(Transformer):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def instantiation(args):
|
def instantiation(args):
|
||||||
return Instantiation(args[0], args[1],
|
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):
|
def input(self, args):
|
||||||
for sd in [SignalDeclaration('input', signal) for signal in args]:
|
for sd in [SignalDeclaration('input', signal) for signal in args]:
|
||||||
@@ -73,12 +74,14 @@ class VerilogTransformer(Transformer):
|
|||||||
|
|
||||||
def wire(self, args):
|
def wire(self, args):
|
||||||
for sd in [SignalDeclaration('wire', signal) for signal in args]:
|
for sd in [SignalDeclaration('wire', signal) for signal in args]:
|
||||||
|
if sd.basename not in self._signal_declarations:
|
||||||
self._signal_declarations[sd.basename] = sd
|
self._signal_declarations[sd.basename] = sd
|
||||||
|
|
||||||
def module(self, args):
|
def module(self, args):
|
||||||
c = Circuit(args[0])
|
c = Circuit(args[0])
|
||||||
positions = {}
|
positions = {}
|
||||||
pos = 0
|
pos = 0
|
||||||
|
const_count = 0
|
||||||
for intf_sig in args[1].children:
|
for intf_sig in args[1].children:
|
||||||
for name in self._signal_declarations[intf_sig].names:
|
for name in self._signal_declarations[intf_sig].names:
|
||||||
positions[name] = pos
|
positions[name] = pos
|
||||||
@@ -107,15 +110,21 @@ class VerilogTransformer(Transformer):
|
|||||||
elif s2 in c.forks:
|
elif s2 in c.forks:
|
||||||
assert s1 not in c.forks, 'assignment between two driven signals'
|
assert s1 not in c.forks, 'assignment between two driven signals'
|
||||||
Line(c, c.forks[s2], Node(c, s1))
|
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
|
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():
|
||||||
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"):
|
||||||
const = f'__const{s[3]}__'
|
cname = f'__const{s[3]}_{const_count}__'
|
||||||
if const not in c.cells:
|
cnode = Node(c, cname, f'__const{s[3]}__')
|
||||||
Line(c, Node(c, const, const), Node(c, s))
|
const_count += 1
|
||||||
|
s = cname
|
||||||
|
Line(c, cnode, Node(c, s))
|
||||||
fork = c.forks[s]
|
fork = c.forks[s]
|
||||||
if self.branchforks:
|
if self.branchforks:
|
||||||
branchfork = Node(c, fork.name + "~" + n.name + "/" + p)
|
branchfork = Node(c, fork.name + "~" + n.name + "/" + p)
|
||||||
@@ -144,7 +153,7 @@ GRAMMAR = """
|
|||||||
wire: "wire" signal ( "," signal )* ";"
|
wire: "wire" signal ( "," signal )* ";"
|
||||||
assign: "assign" name "=" name ";"
|
assign: "assign" name "=" name ";"
|
||||||
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";"
|
instantiation: name name "(" [ pin ( "," pin )* ] ")" ";"
|
||||||
pin: "." name "(" name ")"
|
pin: "." name "(" name? ")"
|
||||||
signal: ( name | "[" /[0-9]+/ ":" /[0-9]+/ "]" 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 )
|
name: ( /[a-z_][a-z0-9_\\[\\]]*/i | /\\\\[^\\t \\r\\n]+[\\t \\r\\n](\\[[0-9]+\\])?/i | /1'b0/i | /1'b1/i )
|
||||||
|
|||||||
Reference in new issue
Block a user