diff --git a/src/kyupy/__init__.py b/src/kyupy/__init__.py index 7e8c78d..5b461bf 100644 --- a/src/kyupy/__init__.py +++ b/src/kyupy/__init__.py @@ -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: outer = self def make_launcher(func): - class Launcher(object): + class Launcher: def __init__(self, funcc): self.func = funcc diff --git a/src/kyupy/bench.py b/src/kyupy/bench.py index 7ec1e1e..f63deac 100644 --- a/src/kyupy/bench.py +++ b/src/kyupy/bench.py @@ -14,15 +14,15 @@ from . import readtext class BenchTransformer(Transformer): - + def __init__(self, name): super().__init__() self.c = Circuit(name) - + def start(self, _): return self.c - + def parameters(self, args): return [self.c.get_or_add_fork(name) for name in args] - + def interface(self, args): self.c.interface.extend(args[0]) def assignment(self, args): @@ -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): :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): diff --git a/src/kyupy/circuit.py b/src/kyupy/circuit.py index 84cc96c..31828b1 100644 --- a/src/kyupy/circuit.py +++ b/src/kyupy/circuit.py @@ -53,7 +53,7 @@ class Node: """ self.kind = kind """A string describing the type of the node. - + Common types are the names from a standard cell library or general gate names like 'AND' or 'NOR'. If :py:attr:`kind` is set to '__fork__', it receives special treatment. A `fork` describes a named signal or a fan-out point in the circuit and not a physical `cell` like a gate. @@ -130,7 +130,7 @@ class Line: """ self.driver_pin = driver[1] """The output pin position of the driver node this line is connected to. - + This is the position in the outs-list of the driving node this line referenced from: :code:`self.driver.outs[self.driver_pin] == self`. """ @@ -187,17 +187,17 @@ class Circuit: """ self.nodes = IndexList() """A list of all :class:`Node` objects contained in the circuit. - + The position of a node in this list equals its index :code:`self.nodes[42].index == 42`. """ self.lines = IndexList() """A list of all :class:`Line` objects contained in the circuit. - + The position of a line in this list equals its index :code:`self.lines[42].index == 42`. """ self.interface = GrowingList() """A list of nodes that are designated as primary input- or output-ports. - + Port-nodes are contained in :py:attr:`nodes` as well as :py:attr:`interface`. The position of a node in the interface list corresponds to positions of logic values in test vectors. The port direction is not stored explicitly. @@ -213,7 +213,7 @@ class Circuit: def get_or_add_fork(self, name): return self.forks[name] if name in self.forks else Node(self, name) - + def copy(self): """Returns a deep copy of the circuit. """ @@ -231,7 +231,7 @@ class Circuit: n = c.cells[node.name] c.interface.append(n) return c - + def dump(self): """Returns a string representation of the circuit and all its nodes. """ diff --git a/src/kyupy/logic.py b/src/kyupy/logic.py index d30fd55..559c50c 100644 --- a/src/kyupy/logic.py +++ b/src/kyupy/logic.py @@ -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: self.width = self.data.shape[-2] def __repr__(self): - return f'' + return f'' def __str__(self): return str([self[idx] for idx in range(self.length)]) @@ -396,7 +396,7 @@ class BPArray: self.width = a.width def __repr__(self): - return f'' + return f'' def __len__(self): return self.length diff --git a/src/kyupy/logic_sim.py b/src/kyupy/logic_sim.py index fee054f..484456c 100644 --- a/src/kyupy/logic_sim.py +++ b/src/kyupy/logic_sim.py @@ -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') diff --git a/src/kyupy/saed.py b/src/kyupy/saed.py index 21771fd..d75be0b 100644 --- a/src/kyupy/saed.py +++ b/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 == '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): @@ -103,7 +103,7 @@ def split_complex_gates(circuit): n_or1 = add_and_connect(circuit, name+'~or1', 'OR2', None, ins[4], outs[0]) Line(circuit, n_and0, n_or0) Line(circuit, n_and1, n_or0) - Line(circuit, n_or0, n_or1) + Line(circuit, n_or0, n_or1) elif n.kind.startswith('AOI221X'): n.remove() n_and0 = add_and_connect(circuit, name+'~and0', 'AND2', ins[0], ins[1], None) @@ -112,7 +112,7 @@ def split_complex_gates(circuit): n_nor = add_and_connect(circuit, name+'~nor', 'NOR2', None, ins[4], outs[0]) Line(circuit, n_and0, n_or) Line(circuit, n_and1, n_or) - Line(circuit, n_or, n_nor) + Line(circuit, n_or, n_nor) elif n.kind.startswith('OA221X'): n.remove() n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) @@ -121,7 +121,7 @@ def split_complex_gates(circuit): n_and1 = add_and_connect(circuit, name+'~and1', 'AND2', None, ins[4], outs[0]) Line(circuit, n_or0, n_and0) Line(circuit, n_or1, n_and0) - Line(circuit, n_and0, n_and1) + Line(circuit, n_and0, n_and1) elif n.kind.startswith('OAI221X'): n.remove() n_or0 = add_and_connect(circuit, name+'~or0', 'OR2', ins[0], ins[1], None) diff --git a/src/kyupy/sdf.py b/src/kyupy/sdf.py index beb58c0..9c4ecfd 100644 --- a/src/kyupy/sdf.py +++ b/src/kyupy/sdf.py @@ -58,14 +58,10 @@ 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: name = name.replace('\\', '') @@ -74,7 +70,7 @@ class DelayFile: if name not in circuit.cells: return None return circuit.cells[name] - + timing = np.zeros((len(circuit.lines), 2, 2)) for cn, iopaths in self.cells.items(): for ipn, opn, *delvals in iopaths: @@ -91,7 +87,7 @@ class DelayFile: ipn2 = ipn.replace('(posedge A1)', 'A1').replace('(negedge A1)', 'A1')\ .replace('(posedge A2)', 'A2').replace('(negedge A2)', 'A2') - + def add_delays(_line): if _line is not None: timing[_line.index, :, 0] += select_del(delvals, 0) @@ -111,10 +107,10 @@ class DelayFile: add_delays(cell.ins[ipin]) if take_avg: timing[cell.ins[ipin].index] /= 2 - + if not interconnect or self.interconnects is None: return timing - + for n1, n2, *delvals in self.interconnects: delvals = [d if len(d) > 0 else [0, 0, 0] for d in delvals] if max(max(delvals)) == 0: @@ -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""" 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): diff --git a/src/kyupy/stil.py b/src/kyupy/stil.py index 5c022ca..5faf56b 100644 --- a/src/kyupy/stil.py +++ b/src/kyupy/stil.py @@ -54,26 +54,26 @@ class StilFile: launch = dict((k, v.replace('\n', '')) for k, v in call.parameters.items()) else: capture = dict((k, v.replace('\n', '')) for k, v in call.parameters.items()) - + 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 = [] inversion = False for n in chain[1:-1]: - if n == '!': + if n == '!': inversion = not inversion else: scan_in_inversion.append(inversion) scan_in_inversion = list(reversed(scan_in_inversion)) - inversion = False + inversion = False for n in reversed(chain[1:-1]): if n == '!': inversion = not inversion @@ -85,13 +85,13 @@ class StilFile: scan_inversions[chain[0]] = scan_in_inversion scan_inversions[chain[-1]] = scan_out_inversion return interface, pi_map, po_map, scan_maps, scan_inversions - + def tests(self, circuit): """Assembles and returns a scan test pattern set for given circuit. 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(): @@ -133,10 +133,10 @@ class StilFile: launch.data[po_map, i] = logic.UNASSIGNED return logic.mv_transition(init, launch) - + 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): @@ -150,27 +150,27 @@ class StilFile: resp.data[scan_maps[so_port], i] = pattern.data[:, 0] # resp.set_values(i, p.unload[so_port], scan_maps[so_port], scan_inversions[so_port]) return resp - - + + class StilTransformer(Transformer): def __init__(self): super().__init__() self._signal_groups = None self._calls = None self._scan_chains = None - + @staticmethod def quoted(args): return args[0][1:-1] @staticmethod def call(args): return Call(args[0], dict(args[1:])) - + @staticmethod def call_parameter(args): return args[0], args[1].value @staticmethod def signal_group(args): return args[0], args[1:] - + @staticmethod def scan_chain(args): scan_in = None @@ -187,7 +187,7 @@ class StilTransformer(Transformer): return args[0], ([scan_in] + scan_cells + [scan_out]) def signal_groups(self, args): self._signal_groups = dict(args) - + def pattern(self, args): self._calls = [c for c in args if isinstance(c, Call)] def scan_structures(self, args): self._scan_chains = dict(args) @@ -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""" 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): diff --git a/src/kyupy/verilog.py b/src/kyupy/verilog.py index 61e76ee..c0f3636 100644 --- a/src/kyupy/verilog.py +++ b/src/kyupy/verilog.py @@ -16,7 +16,7 @@ Instantiation = namedtuple('Instantiation', ['type', 'name', 'pins']) class SignalDeclaration: - + def __init__(self, kind, tokens): self.left = None self.right = None @@ -27,16 +27,15 @@ class SignalDeclaration: self.basename = tokens.children[2] self.left = int(tokens.children[0].value) self.right = int(tokens.children[1].value) - + @property def names(self): if self.left is None: 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,24 +56,24 @@ 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]: self._signal_declarations[sd.basename] = sd - + def inout(self, args): for sd in [SignalDeclaration('input', signal) for signal in args]: # just treat as input self._signal_declarations[sd.basename] = sd - + def output(self, args): for sd in [SignalDeclaration('output', signal) for signal in args]: self._signal_declarations[sd.basename] = sd - + def wire(self, args): for sd in [SignalDeclaration('wire', signal) for signal in args]: self._signal_declarations[sd.basename] = sd - + def module(self, args): c = Circuit(args[0]) positions = {} @@ -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): 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): 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): (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): diff --git a/src/kyupy/wave_sim.py b/src/kyupy/wave_sim.py index 1549307..d9e95cf 100644 --- a/src/kyupy/wave_sim.py +++ b/src/kyupy/wave_sim.py @@ -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: 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: # 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: def __repr__(self): total_mem = self.state.nbytes + self.sat.nbytes + self.ops.nbytes + self.cdata.nbytes return f'' + 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: 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: 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: 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): 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 @@ -541,7 +539,7 @@ def wave_eval(op, state, sat, st_idx, line_times, sd=0.0, seed=0): state[z_mem + z_cur, st_idx] = TMAX_OVL else: state[z_mem + z_cur, st_idx] = a if a > b else b # propagate overflow flags by storing biggest TMAX from input - + return overflows @@ -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'' + 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): 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): 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 diff --git a/tests/test_bench.py b/tests/test_bench.py index 25b9b1b..44ddf7c 100644 --- a/tests/test_bench.py +++ b/tests/test_bench.py @@ -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(): diff --git a/tests/test_logic_sim.py b/tests/test_logic_sim.py index 990eec7..76edb95 100644 --- a/tests/test_logic_sim.py +++ b/tests/test_logic_sim.py @@ -49,7 +49,7 @@ def test_4v(): assert mva[14] == 'X-XXX' assert mva[15] == 'XXXXX' - + def test_8v(): c = bench.parse('input(x, y) output(a, o, n, xo) a=and(x,y) o=or(x,y) n=not(x) xo=xor(x,y)') s = LogicSim(c, 64, m=8) @@ -71,7 +71,7 @@ def test_8v(): for i in range(64): assert resp[i] == mva[i] - + def test_b01(mydir): c = bench.load(mydir / 'b01.bench') diff --git a/tests/test_stil.py b/tests/test_stil.py index 1f0d89b..63f19e4 100644 --- a/tests/test_stil.py +++ b/tests/test_stil.py @@ -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 diff --git a/tests/test_wave_sim.py b/tests/test_wave_sim.py index bea26d3..6240ace 100644 --- a/tests/test_wave_sim.py +++ b/tests/test_wave_sim.py @@ -19,7 +19,7 @@ def test_wave_eval(): line_times[1, 0, 1] = 0.4 line_times[1, 1, 0] = 0.3 line_times[1, 1, 1] = 0.4 - + state = np.zeros((3*16, 1)) + TMAX # 3 waveforms of capacity 16 state[::16, 0] = 16 # first entry is capacity a = state[0:16, 0] @@ -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(): 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(): 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(): 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(): 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): @@ -118,7 +118,7 @@ def compare_to_logic_sim(wsim): exp_bp = BPArray(tests_bp) lsim.capture(exp_bp) exp = MVArray(exp_bp) - + for i in range(8): exp_str = exp[i].replace('R', '1').replace('F', '0').replace('P', '0').replace('N', '1') res_str = resp[i].replace('R', '1').replace('F', '0').replace('P', '0').replace('N', '1')