diff --git a/src/kyupy/logic_sim.py b/src/kyupy/logic_sim.py index 8f35d2c..26c361f 100644 --- a/src/kyupy/logic_sim.py +++ b/src/kyupy/logic_sim.py @@ -371,7 +371,7 @@ class LogicSim6V(sim.SimOps): self.c[self.pippi_c_locs] = logic.mv_to_bp(self.s[0, self.pippi_s_locs]) def c_prop(self): - c_prop_cpu(self.ops, self.c, self.c_locs) + c_prop_cpu(self.ops, self.c, self.c_locs, self.tmp_idx, self.tmp2_idx) def c_to_s(self): """Captures the results of the combinational portion into ``s[1]``. @@ -380,7 +380,9 @@ class LogicSim6V(sim.SimOps): @numba.njit -def c_prop_cpu(ops, c, c_locs): +def c_prop_cpu(ops, c, c_locs, tmp_idx, tmp2_idx): + t0 = c[c_locs[tmp_idx]] + t1 = c[c_locs[tmp2_idx]] inv_op = np.array([255, 255, 0], dtype=np.uint8)[np.newaxis, :, np.newaxis] for op, o0l, i0l, i1l, i2l, i3l in ops[:,:6]: o0, i0, i1, i2, i3 = [c[c_locs[x]] for x in (o0l, i0l, i1l, i2l, i3l)] @@ -426,6 +428,24 @@ def c_prop_cpu(ops, c, c_locs): o0[0] = i0[0] ^ i1[0] o0[1] = i0[1] ^ i1[1] o0[2] = i0[2] | i1[2] + elif op == sim.MUX21: + # t1 = ~i2 + t1[...] = i2 ^ inv_op + # t0 = i0 & t1 + t0[0] = i0[0] & t1[0] + t0[1] = i0[1] & t1[1] + t0[2] = (i0[2]&(t1[0]|t1[1]|t1[2])| + t1[2]&(i0[0]|i0[1]|i0[2])) + # t1 = i1 & i2 + t1[0] = i1[0] & i2[0] + t1[1] = i1[1] & i2[1] + t1[2] = (i1[2]&(i2[0]|i2[1]|i2[2])| + i2[2]&(i1[0]|i1[1]|i1[2])) + # o0 = t0 | t1 + o0[0] = t0[0] | t1[0] + o0[1] = t0[1] | t1[1] + o0[2] = (t0[2]&(~t1[0]|~t1[1]|t1[2])| + t1[2]&(~t0[0]|~t0[1]|t0[2])) else: print(f'unknown op {op}') if (op == sim.INV1 or diff --git a/tests/conftest.py b/tests/conftest.py index a78f6ce..7bf9779 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,8 +20,37 @@ def b15_2ig_circuit_resolved(b15_2ig_circuit): cr.resolve_tlib_cells(SAED32) return cr +@pytest.fixture(scope='session') +def b15_4ig_circuit(mydir): + from kyupy import verilog + from kyupy.techlib import SAED32 + return verilog.load(mydir / 'b15_4ig.v.gz', branchforks=True, tlib=SAED32) + +@pytest.fixture(scope='session') +def b15_4ig_circuit_resolved(b15_4ig_circuit): + from kyupy.techlib import SAED32 + cr = b15_4ig_circuit.copy() + cr.resolve_tlib_cells(SAED32) + return cr + @pytest.fixture(scope='session') def b15_2ig_delays(mydir, b15_2ig_circuit): from kyupy import sdf from kyupy.techlib import SAED32 return sdf.load(mydir / 'b15_2ig.sdf.gz').iopaths(b15_2ig_circuit, tlib=SAED32)[1:2] + +@pytest.fixture(scope='session') +def b15_2ig_sa_nf_test_resp(mydir, b15_2ig_circuit_resolved): + from kyupy import stil + s = stil.load(mydir / 'b15_2ig.sa_nf.stil.gz') + tests = s.tests(b15_2ig_circuit_resolved)[:,1:] + resp = s.responses(b15_2ig_circuit_resolved)[:,1:] + return (tests, resp) + +@pytest.fixture(scope='session') +def b15_4ig_sa_rf_test_resp(mydir, b15_4ig_circuit_resolved): + from kyupy import stil + s = stil.load(mydir / 'b15_4ig.sa_rf.stil.gz') + tests = s.tests(b15_4ig_circuit_resolved)[:,1:] + resp = s.responses(b15_4ig_circuit_resolved)[:,1:] + return (tests, resp) diff --git a/tests/test_logic_sim.py b/tests/test_logic_sim.py index 27b8990..85a11ff 100644 --- a/tests/test_logic_sim.py +++ b/tests/test_logic_sim.py @@ -199,14 +199,8 @@ def test_b01(mydir): bp_to_mv(s.s[1]) -def sim_and_compare(v_file, stil_file, m=8): - from kyupy import verilog, stil - from kyupy.techlib import SAED32 - c = verilog.load(v_file, branchforks=True, tlib=SAED32) - c.resolve_tlib_cells(SAED32) - s = stil.load(stil_file) - tests = s.tests(c)[:,1:] - resp = s.responses(c)[:,1:] +def sim_and_compare(c, test_resp, m=8): + tests, resp = test_resp lsim = LogicSim(c, m=m, sims=tests.shape[1]) lsim.s[0] = logic.mv_to_bp(tests) lsim.s_to_c() @@ -221,26 +215,46 @@ def sim_and_compare(v_file, stil_file, m=8): print(f'mismatch pattern:{pat} ppio:{idx} exp:{logic.mv_str(resp[idx,pat])} act:{logic.mv_str(resp_sim[idx,pat])}') assert len(idxs) == 0 +def sim_and_compare_6v(c, test_resp): + tests, resp = test_resp + lsim = LogicSim6V(c, sims=tests.shape[1]) + lsim.s[0] = tests + lsim.s_to_c() + lsim.c_prop() + lsim.c_to_s() + resp_sim = lsim.s[1] + idxs, pats = np.nonzero(((resp == logic.ONE) & (resp_sim != logic.ONE)) | ((resp == logic.ZERO) & (resp_sim != logic.ZERO))) + for i, (idx, pat) in enumerate(zip(idxs, pats)): + if i >= 10: + print(f'...') + break + print(f'mismatch pattern:{pat} ppio:{idx} exp:{logic.mv_str(resp[idx,pat])} act:{logic.mv_str(resp_sim[idx,pat])}') + assert len(idxs) == 0 + + +def test_b15_2ig_sa_2v(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp): + sim_and_compare(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp, m=2) + -def test_b15_2ig_sa_2v(mydir): - sim_and_compare(mydir / 'b15_2ig.v.gz', mydir / 'b15_2ig.sa_nf.stil.gz', m=2) +def test_b15_2ig_sa_4v(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp): + sim_and_compare(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp, m=4) -def test_b15_2ig_sa_4v(mydir): - sim_and_compare(mydir / 'b15_2ig.v.gz', mydir / 'b15_2ig.sa_nf.stil.gz', m=4) +def test_b15_2ig_sa_6v(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp): + sim_and_compare_6v(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp) -def test_b15_2ig_sa_8v(mydir): - sim_and_compare(mydir / 'b15_2ig.v.gz', mydir / 'b15_2ig.sa_nf.stil.gz', m=8) +def test_b15_2ig_sa_8v(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp): + sim_and_compare(b15_2ig_circuit_resolved, b15_2ig_sa_nf_test_resp, m=8) -def test_b15_4ig_sa_2v(mydir): - sim_and_compare(mydir / 'b15_4ig.v.gz', mydir / 'b15_4ig.sa_rf.stil.gz', m=2) +def test_b15_4ig_sa_2v(b15_4ig_circuit_resolved, b15_4ig_sa_rf_test_resp): + sim_and_compare(b15_4ig_circuit_resolved, b15_4ig_sa_rf_test_resp, m=2) -def test_b15_4ig_sa_4v(mydir): - sim_and_compare(mydir / 'b15_4ig.v.gz', mydir / 'b15_4ig.sa_rf.stil.gz', m=4) +def test_b15_4ig_sa_4v(b15_4ig_circuit_resolved, b15_4ig_sa_rf_test_resp): + sim_and_compare(b15_4ig_circuit_resolved, b15_4ig_sa_rf_test_resp, m=4) -def test_b15_4ig_sa_8v(mydir): - sim_and_compare(mydir / 'b15_4ig.v.gz', mydir / 'b15_4ig.sa_rf.stil.gz', m=8) +def test_b15_4ig_sa_8v(b15_4ig_circuit_resolved, b15_4ig_sa_rf_test_resp): + sim_and_compare(b15_4ig_circuit_resolved, b15_4ig_sa_rf_test_resp, m=8)