Browse Source

de-lint and repr improvements

devel
Stefan Holst 4 years ago
parent
commit
ff4de6d782
  1. 11
      src/kyupy/__init__.py
  2. 4
      src/kyupy/bench.py
  3. 6
      src/kyupy/logic.py
  4. 2
      src/kyupy/logic_sim.py
  5. 12
      src/kyupy/saed.py
  6. 14
      src/kyupy/sdf.py
  7. 12
      src/kyupy/stil.py
  8. 19
      src/kyupy/verilog.py
  9. 25
      src/kyupy/wave_sim.py
  10. 4
      tests/test_bench.py
  11. 7
      tests/test_stil.py
  12. 36
      tests/test_wave_sim.py

11
src/kyupy/__init__.py

@ -77,14 +77,15 @@ class Log: @@ -77,14 +77,15 @@ class Log:
yield i
current_time = time.perf_counter()
if current_time > lastlog_time + log_interval:
work_done = (elem + 1) / elems
done = (elem + 1) / elems
elapsed_time = current_time - start_time
total_time = elapsed_time / work_done
remaining_time = total_time - elapsed_time
self.log(':', f'{work_done*100:.0f}% done {hr_time(elapsed_time)} elapsed {hr_time(remaining_time)} remaining')
total_time = elapsed_time / done
rem_time = total_time - elapsed_time
self.log(':', f'{done*100:.0f}% done {hr_time(elapsed_time)} elapsed {hr_time(rem_time)} remaining')
log_interval = min(600, int(log_interval*1.5))
lastlog_time = current_time
log = Log()
@ -107,7 +108,7 @@ class MockCuda: @@ -107,7 +108,7 @@ class MockCuda:
outer = self
def make_launcher(func):
class Launcher(object):
class Launcher:
def __init__(self, funcc):
self.func = funcc

4
src/kyupy/bench.py

@ -32,7 +32,7 @@ class BenchTransformer(Transformer): @@ -32,7 +32,7 @@ class BenchTransformer(Transformer):
[Line(self.c, d, cell) for d in drivers]
grammar = r"""
GRAMMAR = r"""
start: (statement)*
statement: input | output | assignment
input: ("INPUT" | "input") parameters -> interface
@ -51,7 +51,7 @@ def parse(text, name=None): @@ -51,7 +51,7 @@ def parse(text, name=None):
:param name: The name of the circuit. Circuit names are not included in bench descriptions.
:return: A :class:`Circuit` object.
"""
return Lark(grammar, parser="lalr", transformer=BenchTransformer(name)).parse(text)
return Lark(GRAMMAR, parser="lalr", transformer=BenchTransformer(name)).parse(text)
def load(file, name=None):

6
src/kyupy/logic.py

@ -25,7 +25,7 @@ from collections.abc import Iterable @@ -25,7 +25,7 @@ from collections.abc import Iterable
import numpy as np
from . import numba
from . import numba, hr_bytes
ZERO = 0b000
@ -247,7 +247,7 @@ class MVArray: @@ -247,7 +247,7 @@ class MVArray:
self.width = self.data.shape[-2]
def __repr__(self):
return f'<MVArray length={self.length} width={self.width} m={self.m} nbytes={self.data.nbytes}>'
return f'<MVArray length={self.length} width={self.width} m={self.m} mem={hr_bytes(self.data.nbytes)}>'
def __str__(self):
return str([self[idx] for idx in range(self.length)])
@ -396,7 +396,7 @@ class BPArray: @@ -396,7 +396,7 @@ class BPArray:
self.width = a.width
def __repr__(self):
return f'<BPArray length={self.length} width={self.width} m={self.m} bytes={self.data.nbytes}>'
return f'<BPArray length={self.length} width={self.width} m={self.m} mem={hr_bytes(self.data.nbytes)}>'
def __len__(self):
return self.length

2
src/kyupy/logic_sim.py

@ -37,7 +37,7 @@ class LogicSim: @@ -37,7 +37,7 @@ class LogicSim:
self.zero = np.zeros((mdim, nbytes), dtype='uint8')
self.epoch = 0
known_fct = [(f[:-4], getattr(self, f)) for f in dir(self) if f.endswith(f'_fct')]
known_fct = [(f[:-4], getattr(self, f)) for f in dir(self) if f.endswith('_fct')]
self.node_fct = []
for n in circuit.nodes:
t = n.kind.lower().replace('__fork__', 'fork')

12
src/kyupy/saed.py

@ -10,18 +10,18 @@ def pin_index(cell_type, pin): @@ -10,18 +10,18 @@ def pin_index(cell_type, pin):
if cell_type.startswith('DFF') and pin == 'CLK': return 1
if cell_type.startswith('DFF') and pin == 'RSTB': return 2
if cell_type.startswith('DFF') and pin == 'SETB': return 3
if pin in ['A2', 'IN2', 'SE', 'B', 'CO']: return 1
if pin in ['A3', 'IN3', 'SI', 'CI']: return 2
if pin == 'A4' or pin == 'IN4' or pin == 'CLK': return 3 # CLK for scan cells SDFF
if pin == 'A5' or pin == 'IN5' or pin == 'RSTB': return 4
if pin == 'A6' or pin == 'IN6' or pin == 'SETB': return 5
if pin in ('A2', 'IN2', 'SE', 'B', 'CO'): return 1
if pin in ('A3', 'IN3', 'SI', 'CI'): return 2
if pin in ('A4', 'IN4', 'CLK'): return 3 # CLK for scan cells SDFF
if pin in ('A5', 'IN5', 'RSTB'): return 4
if pin in ('A6', 'IN6', 'SETB'): return 5
return 0
def pin_is_output(kind, pin):
if 'MUX' in kind and pin == 'S':
return False
return pin in ['Q', 'QN', 'Z', 'ZN', 'Y', 'CO', 'S', 'SO', 'C1']
return pin in ('Q', 'QN', 'Z', 'ZN', 'Y', 'CO', 'S', 'SO', 'C1')
def add_and_connect(circuit, name, kind, in1=None, in2=None, out=None):

14
src/kyupy/sdf.py

@ -58,13 +58,9 @@ class DelayFile: @@ -58,13 +58,9 @@ class DelayFile:
E.g., timing[42,1,0] is the rejection limit of a negative pulse at the output of the reader of line 42.
"""
def select_del(_delvals, idx):
if type(dataset) is tuple:
s = 0
for d in dataset:
s += _delvals[idx][d]
return s / len(dataset)
else:
return _delvals[idx][dataset]
if isinstance(dataset, tuple):
return sum(_delvals[idx][d] for d in dataset) / len(dataset)
return _delvals[idx][dataset]
def find_cell(name):
if name not in circuit.cells:
@ -184,7 +180,7 @@ class SdfTransformer(Transformer): @@ -184,7 +180,7 @@ class SdfTransformer(Transformer):
return DelayFile(name, cells)
grammar = r"""
GRAMMAR = r"""
start: "(DELAYFILE" ( "(SDFVERSION" _NOB ")"
| "(DESIGN" "\"" NAME "\"" ")"
| "(DATE" _NOB ")"
@ -218,7 +214,7 @@ grammar = r""" @@ -218,7 +214,7 @@ grammar = r"""
def parse(text):
"""Parses the given ``text`` and returns a :class:`DelayFile` object."""
return Lark(grammar, parser="lalr", transformer=SdfTransformer()).parse(text)
return Lark(GRAMMAR, parser="lalr", transformer=SdfTransformer()).parse(text)
def load(file):

12
src/kyupy/stil.py

@ -57,12 +57,12 @@ class StilFile: @@ -57,12 +57,12 @@ class StilFile:
def _maps(self, c):
interface = list(c.interface) + [n for n in c.nodes if 'DFF' in n.kind]
intf_pos = dict([(n.name, i) for i, n in enumerate(interface)])
intf_pos = dict((n.name, i) for i, n in enumerate(interface))
pi_map = [intf_pos[n] for n in self.signal_groups['_pi']]
po_map = [intf_pos[n] for n in self.signal_groups['_po']]
scan_maps = {}
scan_inversions = {}
for chain_name, chain in self.scan_chains.items():
for chain in self.scan_chains.values():
scan_map = []
scan_in_inversion = []
scan_out_inversion = []
@ -91,7 +91,7 @@ class StilFile: @@ -91,7 +91,7 @@ class StilFile:
This function assumes a static (stuck-at fault) test.
"""
interface, pi_map, po_map, scan_maps, scan_inversions = self._maps(circuit)
interface, pi_map, _, scan_maps, scan_inversions = self._maps(circuit)
tests = logic.MVArray((len(interface), len(self.patterns)))
for i, p in enumerate(self.patterns):
for si_port in self.si_ports.keys():
@ -136,7 +136,7 @@ class StilFile: @@ -136,7 +136,7 @@ class StilFile:
def responses(self, circuit):
"""Assembles and returns a scan test response pattern set for given circuit."""
interface, pi_map, po_map, scan_maps, scan_inversions = self._maps(circuit)
interface, _, po_map, scan_maps, scan_inversions = self._maps(circuit)
resp = logic.MVArray((len(interface), len(self.patterns)))
# resp = PackedVectors(len(self.patterns), len(interface), 2)
for i, p in enumerate(self.patterns):
@ -196,7 +196,7 @@ class StilTransformer(Transformer): @@ -196,7 +196,7 @@ class StilTransformer(Transformer):
return StilFile(float(args[0]), self._signal_groups, self._scan_chains, self._calls)
grammar = r"""
GRAMMAR = r"""
start: "STIL" FLOAT _ignore _block*
_block: signal_groups | scan_structures | pattern
| "Header" _ignore
@ -240,7 +240,7 @@ grammar = r""" @@ -240,7 +240,7 @@ grammar = r"""
def parse(text):
"""Parses the given ``text`` and returns a :class:`StilFile` object."""
return Lark(grammar, parser="lalr", transformer=StilTransformer()).parse(text)
return Lark(GRAMMAR, parser="lalr", transformer=StilTransformer()).parse(text)
def load(file):

19
src/kyupy/verilog.py

@ -34,8 +34,7 @@ class SignalDeclaration: @@ -34,8 +34,7 @@ class SignalDeclaration:
return [self.basename]
if self.left <= self.right:
return [f'{self.basename}[{i}]' for i in range(self.left, self.right + 1)]
else:
return [f'{self.basename}[{i}]' for i in range(self.left, self.right - 1, -1)]
return [f'{self.basename}[{i}]' for i in range(self.left, self.right - 1, -1)]
def __repr__(self):
return f"{self.kind}:{self.basename}[{self.left}:{self.right}]"
@ -57,7 +56,7 @@ class VerilogTransformer(Transformer): @@ -57,7 +56,7 @@ 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:]))
def input(self, args):
for sd in [SignalDeclaration('input', signal) for signal in args]:
@ -85,7 +84,7 @@ class VerilogTransformer(Transformer): @@ -85,7 +84,7 @@ class VerilogTransformer(Transformer):
pos += 1
assignments = []
for stmt in args[2:]: # pass 1: instantiate cells and driven signals
if type(stmt) is Instantiation:
if isinstance(stmt, Instantiation):
n = Node(c, stmt.name, kind=stmt.type)
for p, s in stmt.pins.items():
if pin_is_output(n.kind, p):
@ -108,7 +107,7 @@ class VerilogTransformer(Transformer): @@ -108,7 +107,7 @@ class VerilogTransformer(Transformer):
assert s1 not in c.forks, 'assignment between two driven signals'
Line(c, c.forks[s2], Node(c, s1))
for stmt in args[2:]: # pass 2: connect signals to readers
if type(stmt) is Instantiation:
if isinstance(stmt, Instantiation):
for p, s in stmt.pins.items():
n = c.cells[stmt.name]
if pin_is_output(n.kind, p): continue
@ -129,14 +128,10 @@ class VerilogTransformer(Transformer): @@ -129,14 +128,10 @@ class VerilogTransformer(Transformer):
return c
@staticmethod
def start(args):
if len(args) == 1:
return args[0]
else:
return args
def start(args): return args[0] if len(args) == 1 else args
grammar = """
GRAMMAR = """
start: (module)*
module: "module" name parameters ";" (_statement)* "endmodule"
parameters: "(" [ name ( "," name )* ] ")"
@ -167,7 +162,7 @@ def parse(text, *, branchforks=False): @@ -167,7 +162,7 @@ def parse(text, *, branchforks=False):
(see :py:func:`kyupy.sdf.DelayFile.annotation`).
:return: A :class:`~kyupy.circuit.Circuit` object.
"""
return Lark(grammar, parser="lalr", transformer=VerilogTransformer(branchforks)).parse(text)
return Lark(GRAMMAR, parser="lalr", transformer=VerilogTransformer(branchforks)).parse(text)
def load(file, *args, **kwargs):

25
src/kyupy/wave_sim.py

@ -37,7 +37,7 @@ class Heap: @@ -37,7 +37,7 @@ class Heap:
if self.chunks[loc] == size:
del self.released[idx]
return loc
elif self.chunks[loc] > size: # split chunk
if self.chunks[loc] > size: # split chunk
chunksize = self.chunks[loc]
self.chunks[loc] = size
self.chunks[loc + size] = chunksize - size
@ -103,7 +103,7 @@ class WaveSim: @@ -103,7 +103,7 @@ class WaveSim:
self.cdata = np.zeros((len(self.interface), sims, 7), dtype='float32')
if type(wavecaps) is int:
if isinstance(wavecaps, int):
wavecaps = [wavecaps] * len(circuit.lines)
intf_wavecap = 4 # sufficient for storing only 1 transition.
@ -117,7 +117,7 @@ class WaveSim: @@ -117,7 +117,7 @@ class WaveSim:
# translate circuit structure into self.ops
ops = []
interface_dict = dict([(n, i) for i, n in enumerate(self.interface)])
interface_dict = dict((n, i) for i, n in enumerate(self.interface))
for n in circuit.topological_order():
if n in interface_dict:
inp_idx = self.ppi_offset + interface_dict[n]
@ -255,8 +255,7 @@ class WaveSim: @@ -255,8 +255,7 @@ class WaveSim:
def __repr__(self):
total_mem = self.state.nbytes + self.sat.nbytes + self.ops.nbytes + self.cdata.nbytes
return f'<WaveSim {self.circuit.name} sims={self.sims} ops={len(self.ops)} ' + \
f'levels={len(self.level_starts)} state_mem={hr_bytes(self.state.nbytes)} ' + \
f'total_mem={hr_bytes(total_mem)}>'
f'levels={len(self.level_starts)} mem={hr_bytes(total_mem)}>'
def get_line_delay(self, line, polarity):
return self.timing[line, 0, polarity]
@ -266,7 +265,7 @@ class WaveSim: @@ -266,7 +265,7 @@ class WaveSim:
def assign(self, vectors, time=0.0, offset=0):
nvectors = min(len(vectors) - offset, self.sims)
for i, node in enumerate(self.interface):
for i in range(len(self.interface)):
ppi_loc = self.sat[self.ppi_offset + i, 0]
if ppi_loc < 0: continue
for p in range(nvectors):
@ -321,7 +320,7 @@ class WaveSim: @@ -321,7 +320,7 @@ class WaveSim:
return self.cdata
def reassign(self, time=0.0):
for i, node in enumerate(self.interface):
for i in range(len(self.interface)):
ppi_loc = self.sat[self.ppi_offset + i, 0]
ppo_loc = self.sat[self.ppo_offset + i, 0]
if ppi_loc < 0 or ppo_loc < 0: continue
@ -386,8 +385,7 @@ class WaveSim: @@ -386,8 +385,7 @@ class WaveSim:
accs[idx] += 1
if s_sqrt2 == 0:
return values
else:
return accs
return accs
def vals(self, line, vector, times, sd=0):
return self._vals(line, vector, times, sd)
@ -464,7 +462,7 @@ def rand_gauss(seed, sd): @@ -464,7 +462,7 @@ def rand_gauss(seed, sd):
return 1.0
while True:
x = -6.0
for i in range(12):
for _ in range(12):
seed = int(0xDEECE66D) * seed + 0xB
x += float((seed >> 8) & 0xffffff) / float(1 << 24)
x *= sd
@ -565,8 +563,7 @@ class WaveSimCuda(WaveSim): @@ -565,8 +563,7 @@ class WaveSimCuda(WaveSim):
total_mem = self.state.nbytes + self.sat.nbytes + self.ops.nbytes + self.timing.nbytes + \
self.tdata.nbytes + self.cdata.nbytes
return f'<WaveSimCuda {self.circuit.name} sims={self.sims} ops={len(self.ops)} ' + \
f'levels={len(self.level_starts)} state_mem={hr_bytes(self.state.nbytes)} ' + \
f'total_mem={hr_bytes(total_mem)}>'
f'levels={len(self.level_starts)} mem={hr_bytes(total_mem)}>'
def get_line_delay(self, line, polarity):
return self.d_timing[line, 0, polarity]
@ -661,7 +658,7 @@ def reassign_kernel(state, sat, ppi_offset, ppo_offset, cdata, ppi_time): @@ -661,7 +658,7 @@ def reassign_kernel(state, sat, ppi_offset, ppo_offset, cdata, ppi_time):
if vector >= state.shape[-1]: return
if ppo_offset + y >= len(sat): return
ppo, ppo_cap, _ = sat[ppo_offset + y]
ppo, _, _ = sat[ppo_offset + y]
ppi, ppi_cap, _ = sat[ppi_offset + y]
if ppo < 0: return
if ppi < 0: return
@ -771,7 +768,7 @@ def rand_gauss_dev(seed, sd): @@ -771,7 +768,7 @@ def rand_gauss_dev(seed, sd):
return 1.0
while True:
x = -6.0
for i in range(12):
for _ in range(12):
seed = int(0xDEECE66D) * seed + 0xB
x += float((seed >> 8) & 0xffffff) / float(1 << 24)
x *= sd

4
tests/test_bench.py

@ -4,9 +4,9 @@ from kyupy import bench @@ -4,9 +4,9 @@ from kyupy import bench
def test_b01(mydir):
with open(mydir / 'b01.bench', 'r') as f:
c = bench.parse(f.read())
assert 92 == len(c.nodes)
assert len(c.nodes) == 92
c = bench.load(mydir / 'b01.bench')
assert 92 == len(c.nodes)
assert len(c.nodes) == 92
def test_simple():

7
tests/test_stil.py

@ -3,7 +3,6 @@ from kyupy import stil @@ -3,7 +3,6 @@ from kyupy import stil
def test_b14(mydir):
s = stil.load(mydir / 'b14.stuck.stil.gz')
assert 10 == len(s.signal_groups)
assert 1 == len(s.scan_chains)
assert 2163 == len(s.calls)
assert len(s.signal_groups) == 10
assert len(s.scan_chains) == 1
assert len(s.calls) == 2163

36
tests/test_wave_sim.py

@ -31,29 +31,29 @@ def test_wave_eval(): @@ -31,29 +31,29 @@ def test_wave_eval():
sat[2] = 32, 16, 0
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert TMIN == z[0]
assert z[0] == TMIN
a[0] = TMIN
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert TMIN == z[0]
assert z[0] == TMIN
b[0] = TMIN
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert TMAX == z[0]
assert z[0] == TMAX
a[0] = 1 # A _/^^^
b[0] = 2 # B __/^^
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert TMIN == z[0] # ^^^\___ B -> Z fall delay
assert 2.4 == z[1]
assert TMAX == z[2]
assert z[0] == TMIN # ^^^\___ B -> Z fall delay
assert z[1] == 2.4
assert z[2] == TMAX
a[0] = TMIN # A ^^^^^^
b[0] = TMIN # B ^^^\__
b[1] = 2
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert 2.3 == z[0] # ___/^^^ B -> Z rise delay
assert TMAX == z[1]
assert z[0] == 2.3 # ___/^^^ B -> Z rise delay
assert z[1] == TMAX
# pos pulse of 0.35 at B -> 0.45 after delays
a[0] = TMIN # A ^^^^^^^^
@ -61,9 +61,9 @@ def test_wave_eval(): @@ -61,9 +61,9 @@ def test_wave_eval():
b[1] = 2 # B ^^\__/^^
b[2] = 2.35
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert 2.3 == z[0] # __/^^\__
assert 2.75 == z[1]
assert TMAX == z[2]
assert z[0] == 2.3 # __/^^\__
assert z[1] == 2.75
assert z[2] == TMAX
# neg pulse of 0.45 at B -> 0.35 after delays
a[0] = TMIN # A ^^^^^^^^
@ -71,10 +71,10 @@ def test_wave_eval(): @@ -71,10 +71,10 @@ def test_wave_eval():
b[1] = 2.45
b[2] = TMAX
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert TMIN == z[0] # ^^\__/^^
assert 2.4 == z[1]
assert 2.75 == z[2]
assert TMAX == z[3]
assert z[0] == TMIN # ^^\__/^^
assert z[1] == 2.4
assert z[2] == 2.75
assert z[3] == TMAX
# neg pulse of 0.35 at B -> 0.25 after delays (filtered)
a[0] = TMIN # A ^^^^^^^^
@ -82,8 +82,8 @@ def test_wave_eval(): @@ -82,8 +82,8 @@ def test_wave_eval():
b[1] = 2.35
b[2] = TMAX
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert TMIN == z[0] # ^^^^^^
assert TMAX == z[1]
assert z[0] == TMIN # ^^^^^^
assert z[1] == TMAX
# pos pulse of 0.25 at B -> 0.35 after delays (filtered)
a[0] = TMIN # A ^^^^^^^^
@ -91,7 +91,7 @@ def test_wave_eval(): @@ -91,7 +91,7 @@ def test_wave_eval():
b[1] = 2 # B ^^\__/^^
b[2] = 2.25
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times)
assert TMAX == z[0] # ______
assert z[0] == TMAX # ______
def compare_to_logic_sim(wsim):

Loading…
Cancel
Save