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

4
src/kyupy/bench.py

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

6
src/kyupy/logic.py

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

2
src/kyupy/logic_sim.py

@ -37,7 +37,7 @@ class LogicSim:
self.zero = np.zeros((mdim, nbytes), dtype='uint8') self.zero = np.zeros((mdim, nbytes), dtype='uint8')
self.epoch = 0 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 = [] self.node_fct = []
for n in circuit.nodes: for n in circuit.nodes:
t = n.kind.lower().replace('__fork__', 'fork') t = n.kind.lower().replace('__fork__', 'fork')

12
src/kyupy/saed.py

@ -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 == 'CLK': return 1
if cell_type.startswith('DFF') and pin == 'RSTB': return 2 if cell_type.startswith('DFF') and pin == 'RSTB': return 2
if cell_type.startswith('DFF') and pin == 'SETB': return 3 if cell_type.startswith('DFF') and pin == 'SETB': return 3
if pin in ['A2', 'IN2', 'SE', 'B', 'CO']: return 1 if pin in ('A2', 'IN2', 'SE', 'B', 'CO'): return 1
if pin in ['A3', 'IN3', 'SI', 'CI']: return 2 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 in ('A4', 'IN4', 'CLK'): return 3 # CLK for scan cells SDFF
if pin == 'A5' or pin == 'IN5' or pin == 'RSTB': return 4 if pin in ('A5', 'IN5', 'RSTB'): return 4
if pin == 'A6' or pin == 'IN6' or pin == 'SETB': return 5 if pin in ('A6', 'IN6', 'SETB'): return 5
return 0 return 0
def pin_is_output(kind, pin): def pin_is_output(kind, pin):
if 'MUX' in kind and pin == 'S': if 'MUX' in kind and pin == 'S':
return False 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): def add_and_connect(circuit, name, kind, in1=None, in2=None, out=None):

14
src/kyupy/sdf.py

@ -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. 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): def select_del(_delvals, idx):
if type(dataset) is tuple: if isinstance(dataset, tuple):
s = 0 return sum(_delvals[idx][d] for d in dataset) / len(dataset)
for d in dataset: return _delvals[idx][dataset]
s += _delvals[idx][d]
return s / len(dataset)
else:
return _delvals[idx][dataset]
def find_cell(name): def find_cell(name):
if name not in circuit.cells: if name not in circuit.cells:
@ -184,7 +180,7 @@ class SdfTransformer(Transformer):
return DelayFile(name, cells) return DelayFile(name, cells)
grammar = r""" GRAMMAR = r"""
start: "(DELAYFILE" ( "(SDFVERSION" _NOB ")" start: "(DELAYFILE" ( "(SDFVERSION" _NOB ")"
| "(DESIGN" "\"" NAME "\"" ")" | "(DESIGN" "\"" NAME "\"" ")"
| "(DATE" _NOB ")" | "(DATE" _NOB ")"
@ -218,7 +214,7 @@ grammar = r"""
def parse(text): def parse(text):
"""Parses the given ``text`` and returns a :class:`DelayFile` object.""" """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): def load(file):

12
src/kyupy/stil.py

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

19
src/kyupy/verilog.py

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

25
src/kyupy/wave_sim.py

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

4
tests/test_bench.py

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

7
tests/test_stil.py

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

36
tests/test_wave_sim.py

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

Loading…
Cancel
Save