initial letch support, fix capture in logic sim
This commit is contained in:
1 parent
d05841a6a2
commit
864230b883
6 files changed
+163
-16
No files matched your search
@@ -256,14 +256,14 @@ class Circuit:
|
|||||||
yielded first.
|
yielded first.
|
||||||
"""
|
"""
|
||||||
visit_count = [0] * len(self.nodes)
|
visit_count = [0] * len(self.nodes)
|
||||||
queue = deque(n for n in self.nodes if len(n.ins) == 0 or 'DFF' in n.kind)
|
queue = deque(n for n in self.nodes if len(n.ins) == 0 or 'dff' in n.kind.lower())
|
||||||
while len(queue) > 0:
|
while len(queue) > 0:
|
||||||
n = queue.popleft()
|
n = queue.popleft()
|
||||||
for line in n.outs:
|
for line in n.outs:
|
||||||
if line is None: continue
|
if line is None: continue
|
||||||
succ = line.reader
|
succ = line.reader
|
||||||
visit_count[succ] += 1
|
visit_count[succ] += 1
|
||||||
if visit_count[succ] == len(succ.ins) and 'DFF' not in succ.kind:
|
if visit_count[succ] == len(succ.ins) and 'dff' not in succ.kind.lower():
|
||||||
queue.append(succ)
|
queue.append(succ)
|
||||||
yield n
|
yield n
|
||||||
|
|
||||||
@@ -282,13 +282,13 @@ class Circuit:
|
|||||||
yielded first.
|
yielded first.
|
||||||
"""
|
"""
|
||||||
visit_count = [0] * len(self.nodes)
|
visit_count = [0] * len(self.nodes)
|
||||||
queue = deque(n for n in self.nodes if len(n.outs) == 0 or 'DFF' in n.kind)
|
queue = deque(n for n in self.nodes if len(n.outs) == 0 or 'dff' in n.kind.lower())
|
||||||
while len(queue) > 0:
|
while len(queue) > 0:
|
||||||
n = queue.popleft()
|
n = queue.popleft()
|
||||||
for line in n.ins:
|
for line in n.ins:
|
||||||
pred = line.driver
|
pred = line.driver
|
||||||
visit_count[pred] += 1
|
visit_count[pred] += 1
|
||||||
if visit_count[pred] == len(pred.outs) and 'DFF' not in pred.kind:
|
if visit_count[pred] == len(pred.outs) and 'dff' not in pred.kind.lower():
|
||||||
queue.append(pred)
|
queue.append(pred)
|
||||||
yield n
|
yield n
|
||||||
|
|
||||||
@@ -310,21 +310,21 @@ class Circuit:
|
|||||||
|
|
||||||
def fanout_free_regions(self):
|
def fanout_free_regions(self):
|
||||||
for stem in self.reversed_topological_order():
|
for stem in self.reversed_topological_order():
|
||||||
if len(stem.outs) == 1 and 'DFF' not in stem.kind: continue
|
if len(stem.outs) == 1 and 'dff' not in stem.kind.lower(): continue
|
||||||
region = []
|
region = []
|
||||||
if 'DFF' in stem.kind:
|
if 'dff' in stem.kind.lower():
|
||||||
n = stem.ins[0]
|
n = stem.ins[0]
|
||||||
if len(n.driver.outs) == 1 and 'DFF' not in n.driver.kind:
|
if len(n.driver.outs) == 1 and 'dff' not in n.driver.kind.lower():
|
||||||
queue = deque([n.driver])
|
queue = deque([n.driver])
|
||||||
else:
|
else:
|
||||||
queue = deque()
|
queue = deque()
|
||||||
else:
|
else:
|
||||||
queue = deque(n.driver for n in stem.ins
|
queue = deque(n.driver for n in stem.ins
|
||||||
if len(n.driver.outs) == 1 and 'DFF' not in n.driver.kind)
|
if len(n.driver.outs) == 1 and 'dff' not in n.driver.kind.lower())
|
||||||
while len(queue) > 0:
|
while len(queue) > 0:
|
||||||
n = queue.popleft()
|
n = queue.popleft()
|
||||||
preds = [pred.driver for pred in n.ins
|
preds = [pred.driver for pred in n.ins
|
||||||
if len(pred.driver.outs) == 1 and 'DFF' not in pred.driver.kind]
|
if len(pred.driver.outs) == 1 and 'dff' not in pred.driver.kind.lower()]
|
||||||
queue.extend(preds)
|
queue.extend(preds)
|
||||||
region.append(n)
|
region.append(n)
|
||||||
yield stem, region
|
yield stem, region
|
||||||
@@ -291,6 +291,23 @@ def mv_xor(x1, x2, out=None):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def mv_latch(d, t, q_prev, out=None):
|
||||||
|
"""A latch that is transparent if `t` is high. `q_prev` has to be the output value from the previous clock cycle.
|
||||||
|
"""
|
||||||
|
m = mv_getm(d, t, q_prev)
|
||||||
|
d, t, q_prev = mv_cast(d, t, q_prev, m=m)
|
||||||
|
out = out or MVArray(np.broadcast(d.data, t.data, q_prev).shape, m=m)
|
||||||
|
out.data[...] = t.data & d.data & 0b011
|
||||||
|
out.data[...] |= ~t.data & 0b010 & (q_prev.data << 1)
|
||||||
|
out.data[...] |= ~t.data & 0b001 & (out.data >> 1)
|
||||||
|
out.data[...] |= ((out.data << 1) ^ (out.data << 2)) & 0b100
|
||||||
|
unknown = (t.data == UNKNOWN) \
|
||||||
|
| (t.data == UNASSIGNED) \
|
||||||
|
| (((d.data == UNKNOWN) | (d.data == UNASSIGNED)) & (t.data != ZERO))
|
||||||
|
np.putmask(out.data, unknown, UNKNOWN)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
def mv_transition(init, final, out=None):
|
def mv_transition(init, final, out=None):
|
||||||
"""Computes the logic transitions from the initial values of ``init`` to the final values of ``final``.
|
"""Computes the logic transitions from the initial values of ``init`` to the final values of ``final``.
|
||||||
Pulses in the input data are ignored. If any of the inputs are ``UNKNOWN``, the result is ``UNKNOWN``.
|
Pulses in the input data are ignored. If any of the inputs are ``UNKNOWN``, the result is ``UNKNOWN``.
|
||||||
@@ -460,3 +477,27 @@ def bp_xor(out, *ins):
|
|||||||
out[..., 0, :] |= any_unknown
|
out[..., 0, :] |= any_unknown
|
||||||
out[..., 1, :] &= ~any_unknown
|
out[..., 1, :] &= ~any_unknown
|
||||||
out[..., 2, :] &= ~any_unknown
|
out[..., 2, :] &= ~any_unknown
|
||||||
|
|
||||||
|
|
||||||
|
def bp_latch(out, d, t, q_prev):
|
||||||
|
md = out.shape[-2]
|
||||||
|
assert md == d.shape[-2]
|
||||||
|
assert md == t.shape[-2]
|
||||||
|
assert md == q_prev.shape[-2]
|
||||||
|
if md == 1:
|
||||||
|
out[...] = (d & t) | (q_prev & ~t)
|
||||||
|
elif md == 2:
|
||||||
|
any_unknown = t[..., 0, :] ^ t[..., 1, :]
|
||||||
|
any_unknown |= (d[..., 0, :] ^ d[..., 1, :]) & (t[..., 0, :] | t[..., 1, :])
|
||||||
|
out[...] = (d & t) | (q_prev & ~t)
|
||||||
|
out[..., 0, :] |= any_unknown
|
||||||
|
out[..., 1, :] &= ~any_unknown
|
||||||
|
else:
|
||||||
|
any_unknown = (t[..., 0, :] ^ t[..., 1, :]) & ~t[..., 2, :]
|
||||||
|
any_unknown |= ((d[..., 0, :] ^ d[..., 1, :]) & ~d[..., 2, :]) & (t[..., 0, :] | t[..., 1, :] | t[..., 2, :])
|
||||||
|
out[..., 1, :] = (d[..., 1, :] & t[..., 1, :]) | (q_prev[..., 0, :] & ~t[..., 1, :])
|
||||||
|
out[..., 0, :] = (d[..., 0, :] & t[..., 0, :]) | (out[..., 1, :] & ~t[..., 0, :])
|
||||||
|
out[..., 2, :] = out[..., 1, :] ^ out[..., 0, :]
|
||||||
|
out[..., 0, :] |= any_unknown
|
||||||
|
out[..., 1, :] &= ~any_unknown
|
||||||
|
out[..., 2, :] &= ~any_unknown
|
||||||
+36
-5
@@ -30,15 +30,22 @@ class LogicSim:
|
|||||||
self.circuit = circuit
|
self.circuit = circuit
|
||||||
self.sims = sims
|
self.sims = sims
|
||||||
nbytes = (sims - 1) // 8 + 1
|
nbytes = (sims - 1) // 8 + 1
|
||||||
self.interface = list(circuit.interface) + [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
dffs = [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||||
|
latches = [n for n in circuit.nodes if 'latch' in n.kind.lower()]
|
||||||
|
self.interface = list(circuit.interface) + dffs + latches
|
||||||
|
|
||||||
self.width = len(self.interface)
|
self.width = len(self.interface)
|
||||||
"""The number of bits in the circuit state (number of ports + number of state-elements)."""
|
"""The number of bits in the circuit state (number of ports + number of state-elements)."""
|
||||||
|
|
||||||
self.state = np.zeros((len(circuit.lines), mdim, nbytes), dtype='uint8')
|
self.state = np.zeros((len(circuit.lines), mdim, nbytes), dtype='uint8')
|
||||||
self.state_epoch = np.zeros(len(circuit.nodes), dtype='int8') - 1
|
self.state_epoch = np.zeros(len(circuit.nodes), dtype='int8') - 1
|
||||||
self.tmp = np.zeros((5, mdim, nbytes), dtype='uint8')
|
self.tmp = np.zeros((5, mdim, nbytes), dtype='uint8')
|
||||||
self.zero = np.zeros((mdim, nbytes), dtype='uint8')
|
self.zero = np.zeros((mdim, nbytes), dtype='uint8')
|
||||||
self.epoch = 0
|
self.epoch = 0
|
||||||
|
|
||||||
|
self.latch_dict = dict((n.index, i) for i, n in enumerate(latches))
|
||||||
|
self.latch_state = np.zeros((len(latches), mdim, nbytes), dtype='uint8')
|
||||||
|
|
||||||
known_fct = [(f[:-4], getattr(self, f)) for f in dir(self) if f.endswith('_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:
|
||||||
@@ -69,8 +76,11 @@ class LogicSim:
|
|||||||
"""
|
"""
|
||||||
for node, stim in zip(self.interface, stimuli.data if hasattr(stimuli, 'data') else stimuli):
|
for node, stim in zip(self.interface, stimuli.data if hasattr(stimuli, 'data') else stimuli):
|
||||||
if len(node.outs) == 0: continue
|
if len(node.outs) == 0: continue
|
||||||
outputs = [self.state[line] if line else self.tmp[3] for line in node.outs]
|
if node.index in self.latch_dict:
|
||||||
self.node_fct[node]([stim], outputs)
|
self.latch_state[self.latch_dict[node.index]] = stim
|
||||||
|
else:
|
||||||
|
outputs = [self.state[line] if line else self.tmp[3] for line in node.outs]
|
||||||
|
self.node_fct[node]([stim], outputs)
|
||||||
for line in node.outs:
|
for line in node.outs:
|
||||||
if line is not None: self.state_epoch[line.reader] = self.epoch
|
if line is not None: self.state_epoch[line.reader] = self.epoch
|
||||||
for n in self.circuit.nodes:
|
for n in self.circuit.nodes:
|
||||||
@@ -83,13 +93,27 @@ class LogicSim:
|
|||||||
|
|
||||||
def capture(self, responses):
|
def capture(self, responses):
|
||||||
"""Capture the current values at the primary outputs and in the state-elements (flip-flops).
|
"""Capture the current values at the primary outputs and in the state-elements (flip-flops).
|
||||||
|
For primary outputs, the logic value is stored unmodified in the given target array.
|
||||||
|
For flip-flops, the logic value is constructed from the previous state and the new state.
|
||||||
|
|
||||||
:param responses: A bit-parallel storage target for the responses in a compatible shape.
|
:param responses: A bit-parallel storage target for the responses in a compatible shape.
|
||||||
:type responses: :py:class:`~kyupy.logic.BPArray`
|
:type responses: :py:class:`~kyupy.logic.BPArray`
|
||||||
:returns: The given responses object.
|
:returns: The given responses object.
|
||||||
"""
|
"""
|
||||||
for node, resp in zip(self.interface, responses.data if hasattr(responses, 'data') else responses):
|
for node, resp in zip(self.interface, responses.data if hasattr(responses, 'data') else responses):
|
||||||
if len(node.ins) > 0: resp[...] = self.state[node.ins[0]]
|
if len(node.ins) == 0: continue
|
||||||
|
if node.index in self.latch_dict:
|
||||||
|
resp[...] = self.state[node.outs[0]]
|
||||||
|
else:
|
||||||
|
resp[...] = self.state[node.ins[0]]
|
||||||
|
if self.m > 2 and 'dff' in node.kind.lower() and len(node.outs) > 0:
|
||||||
|
if node.outs[0] is None:
|
||||||
|
resp[1, :] = ~self.state[node.outs[1], 0, :] # assume QN is connected, take inverse of that.
|
||||||
|
else:
|
||||||
|
resp[1, :] = self.state[node.outs[0], 0, :]
|
||||||
|
resp[..., 2, :] = resp[..., 0, :] ^ resp[..., 1, :]
|
||||||
|
# We don't handle X or - correctly.
|
||||||
|
|
||||||
return responses
|
return responses
|
||||||
|
|
||||||
def propagate(self, inject_cb=None):
|
def propagate(self, inject_cb=None):
|
||||||
@@ -116,7 +140,8 @@ class LogicSim:
|
|||||||
if self.state_epoch[node] != self.epoch: continue
|
if self.state_epoch[node] != self.epoch: continue
|
||||||
inputs = [self.state[line] if line else self.zero for line in node.ins]
|
inputs = [self.state[line] if line else self.zero for line in node.ins]
|
||||||
outputs = [self.state[line] if line else self.tmp[3] for line in node.outs]
|
outputs = [self.state[line] if line else self.tmp[3] for line in node.outs]
|
||||||
# print('sim', node)
|
if node.index in self.latch_dict:
|
||||||
|
inputs.append(self.latch_state[self.latch_dict[node.index]])
|
||||||
self.node_fct[node](inputs, outputs)
|
self.node_fct[node](inputs, outputs)
|
||||||
for line in node.outs:
|
for line in node.outs:
|
||||||
if inject_cb is not None: inject_cb(line, self.state[line])
|
if inject_cb is not None: inject_cb(line, self.state[line])
|
||||||
@@ -179,6 +204,12 @@ class LogicSim:
|
|||||||
if len(outputs) > 1:
|
if len(outputs) > 1:
|
||||||
logic.bp_not(outputs[1], inputs[0])
|
logic.bp_not(outputs[1], inputs[0])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def latch_fct(inputs, outputs):
|
||||||
|
logic.bp_latch(outputs[0], inputs[0], inputs[1], inputs[2])
|
||||||
|
if len(outputs) > 1:
|
||||||
|
logic.bp_not(outputs[1], inputs[0])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def nand_fct(inputs, outputs):
|
def nand_fct(inputs, outputs):
|
||||||
logic.bp_and(outputs[0], *inputs)
|
logic.bp_and(outputs[0], *inputs)
|
||||||
|
|||||||
@@ -33,12 +33,14 @@ class TechLib:
|
|||||||
if pin[0] == 'A': return int(pin[1])
|
if pin[0] == 'A': return int(pin[1])
|
||||||
if pin[0] == 'B': return int(pin[1]) + int(kind[4])
|
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', 'S0'), 2),
|
||||||
('MX2', ('S0',), 2),
|
('MX2', ('S0',), 2),
|
||||||
('TBUF', ('OE',), 1),
|
('TBUF', ('OE',), 1),
|
||||||
('TINV', ('OE',), 1),
|
('TINV', ('OE',), 1),
|
||||||
('DFF', ('QN',), 1),
|
('LATCH', ('D',), 0),
|
||||||
|
('LATCH', ('QN',), 1),
|
||||||
('DFF', ('D',), 0),
|
('DFF', ('D',), 0),
|
||||||
|
('DFF', ('QN',), 1),
|
||||||
('SDFF', ('D',), 0),
|
('SDFF', ('D',), 0),
|
||||||
('SDFF', ('QN',), 1),
|
('SDFF', ('QN',), 1),
|
||||||
('SDFF', ('CLK',), 3),
|
('SDFF', ('CLK',), 3),
|
||||||
|
|||||||
@@ -145,6 +145,20 @@ def test_mv_operations():
|
|||||||
assert lg.mv_xor(x1_4v, x2_4v)[0] == '0XX1XXXXXXXX1XX0'
|
assert lg.mv_xor(x1_4v, x2_4v)[0] == '0XX1XXXXXXXX1XX0'
|
||||||
assert lg.mv_xor(x1_8v, x2_8v)[0] == '0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'
|
assert lg.mv_xor(x1_8v, x2_8v)[0] == '0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'
|
||||||
|
|
||||||
|
x30_2v = lg.MVArray("0000", m=2)
|
||||||
|
x31_2v = lg.MVArray("1111", m=2)
|
||||||
|
x30_4v = lg.MVArray("0000000000000000", m=4)
|
||||||
|
x31_4v = lg.MVArray("1111111111111111", m=4)
|
||||||
|
x30_8v = lg.MVArray("0000000000000000000000000000000000000000000000000000000000000000", m=8)
|
||||||
|
x31_8v = lg.MVArray("1111111111111111111111111111111111111111111111111111111111111111", m=8)
|
||||||
|
|
||||||
|
assert lg.mv_latch(x1_2v, x2_2v, x30_2v)[0] == '0001'
|
||||||
|
assert lg.mv_latch(x1_2v, x2_2v, x31_2v)[0] == '1011'
|
||||||
|
assert lg.mv_latch(x1_4v, x2_4v, x30_4v)[0] == '0XX00XXX0XXX0XX1'
|
||||||
|
assert lg.mv_latch(x1_4v, x2_4v, x31_4v)[0] == '1XX01XXX1XXX1XX1'
|
||||||
|
assert lg.mv_latch(x1_8v, x2_8v, x30_8v)[0] == '0XX000000XXXXXXX0XXXXXXX0XX10R110XX000000XXR0R0R0XXF001F0XX10R11'
|
||||||
|
assert lg.mv_latch(x1_8v, x2_8v, x31_8v)[0] == '1XX01F001XXXXXXX1XXXXXXX1XX111111XX01F001XXR110R1XXF1F1F1XX11111'
|
||||||
|
|
||||||
|
|
||||||
def test_bparray():
|
def test_bparray():
|
||||||
|
|
||||||
@@ -212,3 +226,27 @@ def test_bparray():
|
|||||||
assert lg.MVArray(out_2v)[0] == '0110'
|
assert lg.MVArray(out_2v)[0] == '0110'
|
||||||
assert lg.MVArray(out_4v)[0] == '0XX1XXXXXXXX1XX0'
|
assert lg.MVArray(out_4v)[0] == '0XX1XXXXXXXX1XX0'
|
||||||
assert lg.MVArray(out_8v)[0] == '0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'
|
assert lg.MVArray(out_8v)[0] == '0XX1PRFNXXXXXXXXXXXXXXXX1XX0NFRPPXXNPRFNRXXFRPNFFXXRFNPRNXXPNFRP'
|
||||||
|
|
||||||
|
x30_2v = lg.BPArray("0000", m=2)
|
||||||
|
x30_4v = lg.BPArray("0000000000000000", m=4)
|
||||||
|
x30_8v = lg.BPArray("0000000000000000000000000000000000000000000000000000000000000000", m=8)
|
||||||
|
|
||||||
|
lg.bp_latch(out_2v.data, x1_2v.data, x2_2v.data, x30_2v.data)
|
||||||
|
lg.bp_latch(out_4v.data, x1_4v.data, x2_4v.data, x30_4v.data)
|
||||||
|
lg.bp_latch(out_8v.data, x1_8v.data, x2_8v.data, x30_8v.data)
|
||||||
|
|
||||||
|
assert lg.MVArray(out_2v)[0] == '0001'
|
||||||
|
assert lg.MVArray(out_4v)[0] == '0XX00XXX0XXX0XX1'
|
||||||
|
assert lg.MVArray(out_8v)[0] == '0XX000000XXXXXXX0XXXXXXX0XX10R110XX000000XXR0R0R0XXF001F0XX10R11'
|
||||||
|
|
||||||
|
x31_2v = lg.BPArray("1111", m=2)
|
||||||
|
x31_4v = lg.BPArray("1111111111111111", m=4)
|
||||||
|
x31_8v = lg.BPArray("1111111111111111111111111111111111111111111111111111111111111111", m=8)
|
||||||
|
|
||||||
|
lg.bp_latch(out_2v.data, x1_2v.data, x2_2v.data, x31_2v.data)
|
||||||
|
lg.bp_latch(out_4v.data, x1_4v.data, x2_4v.data, x31_4v.data)
|
||||||
|
lg.bp_latch(out_8v.data, x1_8v.data, x2_8v.data, x31_8v.data)
|
||||||
|
|
||||||
|
assert lg.MVArray(out_2v)[0] == '1011'
|
||||||
|
assert lg.MVArray(out_4v)[0] == '1XX01XXX1XXX1XX1'
|
||||||
|
assert lg.MVArray(out_8v)[0] == '1XX01F001XXXXXXX1XXXXXXX1XX111111XX01F001XXR110R1XXF1F1F1XX11111'
|
||||||
@@ -73,6 +73,41 @@ def test_8v():
|
|||||||
assert resp[i] == mva[i]
|
assert resp[i] == mva[i]
|
||||||
|
|
||||||
|
|
||||||
|
def test_loop():
|
||||||
|
c = bench.parse('q=dff(d) d=not(q)')
|
||||||
|
s = LogicSim(c, 2, m=8)
|
||||||
|
assert len(s.interface) == 1
|
||||||
|
mva = MVArray([['0'], ['1']], m=8)
|
||||||
|
|
||||||
|
s.assign(BPArray(mva))
|
||||||
|
s.propagate()
|
||||||
|
resp_bp = BPArray((len(s.interface), s.sims))
|
||||||
|
s.capture(resp_bp)
|
||||||
|
resp = MVArray(resp_bp)
|
||||||
|
|
||||||
|
assert resp[0] == 'R'
|
||||||
|
assert resp[1] == 'F'
|
||||||
|
|
||||||
|
resp_bp = s.cycle(resp_bp)
|
||||||
|
resp = MVArray(resp_bp)
|
||||||
|
|
||||||
|
assert resp[0] == 'F'
|
||||||
|
assert resp[1] == 'R'
|
||||||
|
|
||||||
|
|
||||||
|
def test_latch():
|
||||||
|
c = bench.parse('input(d, t) output(q) q=latch(d, t)')
|
||||||
|
s = LogicSim(c, 8, m=8)
|
||||||
|
assert len(s.interface) == 4
|
||||||
|
mva = MVArray(['00-0', '00-1', '01-0', '01-1', '10-0', '10-1', '11-0', '11-1'], m=8)
|
||||||
|
exp = MVArray(['0000', '0011', '0100', '0100', '1000', '1011', '1111', '1111'], m=8)
|
||||||
|
|
||||||
|
resp = MVArray(s.cycle(BPArray(mva)))
|
||||||
|
|
||||||
|
for i in range(len(mva)):
|
||||||
|
assert resp[i] == exp[i]
|
||||||
|
|
||||||
|
|
||||||
def test_b01(mydir):
|
def test_b01(mydir):
|
||||||
c = bench.load(mydir / 'b01.bench')
|
c = bench.load(mydir / 'b01.bench')
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user