switch to new wave_sim, silence occupancy warnings
This commit is contained in:
1 parent
3497bfdc75
commit
8da4a62bce
7 files changed
+1526
-1514
No files matched your search
+129
-111
@@ -1,118 +1,148 @@
|
||||
import numpy as np
|
||||
|
||||
from kyupy.wave_sim import WaveSim, WaveSimCuda, wave_eval, TMIN, TMAX
|
||||
from kyupy.wave_sim import WaveSim, WaveSimCuda, wave_eval_cpu, TMIN, TMAX
|
||||
from kyupy.logic_sim import LogicSim
|
||||
from kyupy import verilog, sdf, logic
|
||||
from kyupy import verilog, sdf, logic, bench
|
||||
from kyupy.logic import MVArray, BPArray
|
||||
from kyupy.sim import SimPrim
|
||||
|
||||
|
||||
def test_wave_eval():
|
||||
def test_nand_delays():
|
||||
op = (SimPrim.NAND4, 4, 0, 1, 2, 3)
|
||||
#op = (0b0111, 4, 0, 1)
|
||||
c = np.full((5*16, 1), TMAX) # 5 waveforms of capacity 16
|
||||
vat = np.zeros((5, 3), dtype='int')
|
||||
for i in range(5): vat[i] = i*16, 16, 0 # 1:1 mapping
|
||||
|
||||
# SDF specifies IOPATH delays with respect to output polarity
|
||||
# SDF pulse rejection value is determined by IOPATH causing last transition and polarity of last transition
|
||||
line_times = np.zeros((3, 2, 2))
|
||||
line_times = np.zeros((5, 2, 2))
|
||||
line_times[0, 0, 0] = 0.1 # A -> Z rise delay
|
||||
line_times[0, 0, 1] = 0.2 # A -> Z fall delay
|
||||
line_times[0, 1, 0] = 0.1 # A -> Z negative pulse limit (terminate in rising Z)
|
||||
line_times[0, 1, 1] = 0.2 # A -> Z positive pulse limit
|
||||
line_times[1, 0, 0] = 0.3 # as above for B -> Z
|
||||
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]
|
||||
b = state[16:32, 0]
|
||||
z = state[32:, 0]
|
||||
sat = np.zeros((3, 3), dtype='int')
|
||||
sat[0] = 0, 16, 0
|
||||
sat[1] = 16, 16, 0
|
||||
sat[2] = 32, 16, 0
|
||||
|
||||
line_times[1, :, 0] = 0.3 # as above for B -> Z
|
||||
line_times[1, :, 1] = 0.4
|
||||
line_times[2, :, 0] = 0.5 # as above for C -> Z
|
||||
line_times[2, :, 1] = 0.6
|
||||
line_times[3, :, 0] = 0.7 # as above for D -> Z
|
||||
line_times[3, :, 1] = 0.8
|
||||
|
||||
sdata = np.asarray([1, -1, 0, 0], dtype='float32')
|
||||
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMIN
|
||||
def wave_assert(inputs, output):
|
||||
for i, a in zip(inputs, c.reshape(-1,16)): a[:len(i)] = i
|
||||
wave_eval_cpu(op, c, vat, 0, line_times, sdata)
|
||||
for i, v in enumerate(output): np.testing.assert_allclose(c.reshape(-1,16)[4,i], v)
|
||||
|
||||
a[0] = TMIN
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMIN
|
||||
wave_assert([[TMAX,TMAX],[TMAX,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # NAND(0,0,1,1) => 1
|
||||
wave_assert([[TMIN,TMAX],[TMAX,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # NAND(1,0,1,1) => 1
|
||||
wave_assert([[TMIN,TMAX],[TMIN,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMAX]) # NAND(1,1,1,1) => 0
|
||||
|
||||
b[0] = TMIN
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMAX
|
||||
|
||||
a[0] = 1 # A _/^^^
|
||||
b[0] = 2 # B __/^^
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
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, sdata)
|
||||
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 ^^^^^^^^
|
||||
b[0] = TMIN
|
||||
b[1] = 2 # B ^^\__/^^
|
||||
b[2] = 2.35
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
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 ^^^^^^^^
|
||||
b[0] = 2 # B __/^^\__
|
||||
b[1] = 2.45
|
||||
b[2] = TMAX
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
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 ^^^^^^^^
|
||||
b[0] = 2 # B __/^^\__
|
||||
b[1] = 2.35
|
||||
b[2] = TMAX
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMIN # ^^^^^^
|
||||
assert z[1] == TMAX
|
||||
|
||||
# pos pulse of 0.25 at B -> 0.35 after delays (filtered)
|
||||
a[0] = TMIN # A ^^^^^^^^
|
||||
b[0] = TMIN
|
||||
b[1] = 2 # B ^^\__/^^
|
||||
b[2] = 2.25
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMAX # ______
|
||||
# Keep inputs C=1 and D=1.
|
||||
wave_assert([[1,TMAX],[2,TMAX]], [TMIN,2.4,TMAX]) # _/⎺⎺⎺ NAND __/⎺⎺ => ⎺⎺⎺\___ (B->Z fall delay)
|
||||
wave_assert([[TMIN,TMAX],[TMIN,2,TMAX]], [2.3,TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺⎺\__ => ___/⎺⎺⎺ (B->Z rise delay)
|
||||
wave_assert([[TMIN,TMAX],[TMIN,2,2.35,TMAX]], [2.3,2.75,TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺\_/⎺ => __/⎺⎺\_ (pos pulse, .35@B -> .45@Z)
|
||||
wave_assert([[TMIN,TMAX],[TMIN,2,2.25,TMAX]], [TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺\_/⎺ => _______ (pos pulse, .25@B -> .35@Z, filtered)
|
||||
wave_assert([[TMIN,TMAX],[2,2.45,TMAX]], [TMIN,2.4,2.75,TMAX]) # ⎺⎺⎺⎺⎺ NAND _/⎺\_ => ⎺⎺\_/⎺⎺ (neg pulse, .45@B -> .35@Z)
|
||||
wave_assert([[TMIN,TMAX],[2,2.35,TMAX]], [TMIN,TMAX]) # ⎺⎺⎺⎺⎺ NAND _/⎺\_ => ⎺⎺⎺⎺⎺⎺⎺ (neg pulse, .35@B -> .25@Z, filtered)
|
||||
|
||||
|
||||
def compare_to_logic_sim(wsim):
|
||||
tests = MVArray((len(wsim.interface), wsim.sims))
|
||||
def test_tiny_circuit():
|
||||
c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)')
|
||||
lt = np.zeros((len(c.lines), 2, 2))
|
||||
lt[:,0,:] = 1.0 # unit delay for all lines
|
||||
wsim = WaveSim(c, lt)
|
||||
assert len(wsim.s) == 5
|
||||
|
||||
# values for x
|
||||
wsim.s[0,0,:3] = 0, 0.1, 0
|
||||
wsim.s[0,1,:3] = 0, 0.2, 1
|
||||
wsim.s[0,2,:3] = 1, 0.3, 0
|
||||
wsim.s[0,3,:3] = 1, 0.4, 1
|
||||
|
||||
# values for y
|
||||
wsim.s[1,0,:3] = 1, 0.5, 0
|
||||
wsim.s[1,1,:3] = 1, 0.6, 0
|
||||
wsim.s[1,2,:3] = 1, 0.7, 0
|
||||
wsim.s[1,3,:3] = 0, 0.8, 1
|
||||
|
||||
wsim.s_to_c()
|
||||
|
||||
x_c_loc = wsim.vat[wsim.ppi_offset+0, 0] # check x waveforms
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 0], [TMAX, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 1], [0.2, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 2], [TMIN, 0.3, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 3], [TMIN, TMAX, TMAX])
|
||||
|
||||
y_c_loc = wsim.vat[wsim.ppi_offset+1, 0] # check y waveforms
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 0], [TMIN, 0.5, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 1], [TMIN, 0.6, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 2], [TMIN, 0.7, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 3], [0.8, TMAX, TMAX])
|
||||
|
||||
wsim.c_prop()
|
||||
|
||||
a_c_loc = wsim.vat[wsim.ppo_offset+2, 0] # check a waveforms
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 0], [TMAX, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 1], [1.2, 1.6, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 2], [TMIN, 1.3, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 3], [1.8, TMAX, TMAX])
|
||||
|
||||
o_c_loc = wsim.vat[wsim.ppo_offset+3, 0] # check o waveforms
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 0], [TMIN, 1.5, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 1], [TMIN, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 2], [TMIN, 1.7, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 3], [TMIN, TMAX, TMAX])
|
||||
|
||||
n_c_loc = wsim.vat[wsim.ppo_offset+4, 0] # check n waveforms
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 0], [TMIN, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 1], [TMIN, 1.2, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 2], [1.3, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 3], [TMAX, TMAX, TMAX])
|
||||
|
||||
wsim.c_to_s()
|
||||
|
||||
# check a captures
|
||||
np.testing.assert_allclose(wsim.s[2, 0, 3:7], [0, TMAX, TMIN, 0])
|
||||
np.testing.assert_allclose(wsim.s[2, 1, 3:7], [0, 1.2, 1.6, 0])
|
||||
np.testing.assert_allclose(wsim.s[2, 2, 3:7], [1, 1.3, 1.3, 0])
|
||||
np.testing.assert_allclose(wsim.s[2, 3, 3:7], [0, 1.8, 1.8, 1])
|
||||
|
||||
# check o captures
|
||||
np.testing.assert_allclose(wsim.s[3, 0, 3:7], [1, 1.5, 1.5, 0])
|
||||
np.testing.assert_allclose(wsim.s[3, 1, 3:7], [1, TMAX, TMIN, 1])
|
||||
np.testing.assert_allclose(wsim.s[3, 2, 3:7], [1, 1.7, 1.7, 0])
|
||||
np.testing.assert_allclose(wsim.s[3, 3, 3:7], [1, TMAX, TMIN, 1])
|
||||
|
||||
# check o captures
|
||||
np.testing.assert_allclose(wsim.s[4, 0, 3:7], [1, TMAX, TMIN, 1])
|
||||
np.testing.assert_allclose(wsim.s[4, 1, 3:7], [1, 1.2, 1.2, 0])
|
||||
np.testing.assert_allclose(wsim.s[4, 2, 3:7], [0, 1.3, 1.3, 1])
|
||||
np.testing.assert_allclose(wsim.s[4, 3, 3:7], [0, TMAX, TMIN, 0])
|
||||
|
||||
|
||||
def compare_to_logic_sim(wsim: WaveSim):
|
||||
tests = MVArray((len(wsim.s_nodes), wsim.sims))
|
||||
choices = np.asarray([logic.ZERO, logic.ONE, logic.RISE, logic.FALL], dtype=np.uint8)
|
||||
rng = np.random.default_rng(10)
|
||||
tests.data[...] = rng.choice(choices, tests.data.shape)
|
||||
tests_bp = BPArray(tests)
|
||||
wsim.assign(tests_bp)
|
||||
wsim.propagate()
|
||||
cdata = wsim.capture()
|
||||
|
||||
wsim.s[:, :, 0] = (tests.data & 2) >> 1
|
||||
wsim.s[:, :, 3] = (tests.data & 2) >> 1
|
||||
wsim.s[:, :, 1] = 0.0
|
||||
wsim.s[:, :, 2] = tests.data & 1
|
||||
wsim.s[:, :, 6] = tests.data & 1
|
||||
|
||||
wsim.s_to_c()
|
||||
wsim.c_prop()
|
||||
wsim.c_to_s()
|
||||
|
||||
resp = MVArray(tests)
|
||||
resp.data[...] = np.array(wsim.s[:, :, 6], dtype=np.uint8) | (np.array(wsim.s[:, :, 3], dtype=np.uint8)<<1)
|
||||
resp.data |= ((resp.data ^ (resp.data >> 1)) & 1) << 2 # transitions
|
||||
|
||||
for iidx, inode in enumerate(wsim.interface):
|
||||
if len(inode.ins) > 0:
|
||||
for vidx in range(wsim.sims):
|
||||
resp.data[iidx, vidx] = logic.ZERO if cdata[iidx, vidx, 0] < 0.5 else logic.ONE
|
||||
# resp.set_value(vidx, iidx, 0 if cdata[iidx, vidx, 0] < 0.5 else 1)
|
||||
|
||||
tests_bp = BPArray(tests)
|
||||
lsim = LogicSim(wsim.circuit, len(tests_bp))
|
||||
lsim.assign(tests_bp)
|
||||
lsim.propagate()
|
||||
@@ -121,30 +151,18 @@ def compare_to_logic_sim(wsim):
|
||||
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')
|
||||
exp_str = exp[i].replace('P', '0').replace('N', '1')
|
||||
res_str = resp[i].replace('P', '0').replace('N', '1')
|
||||
assert res_str == exp_str
|
||||
|
||||
|
||||
def test_b14(mydir):
|
||||
c = verilog.load(mydir / 'b14.v.gz', branchforks=True)
|
||||
df = sdf.load(mydir / 'b14.sdf.gz')
|
||||
lt = df.annotation(c)
|
||||
wsim = WaveSim(c, lt, 8)
|
||||
compare_to_logic_sim(wsim)
|
||||
def test_b14(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSim(b14_circuit, b14_timing, 8))
|
||||
|
||||
|
||||
def test_b14_strip_forks(mydir):
|
||||
c = verilog.load(mydir / 'b14.v.gz', branchforks=True)
|
||||
df = sdf.load(mydir / 'b14.sdf.gz')
|
||||
lt = df.annotation(c)
|
||||
wsim = WaveSim(c, lt, 8, strip_forks=True)
|
||||
compare_to_logic_sim(wsim)
|
||||
def test_b14_strip_forks(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSim(b14_circuit, b14_timing, 8, strip_forks=True))
|
||||
|
||||
|
||||
def test_b14_cuda(mydir):
|
||||
c = verilog.load(mydir / 'b14.v.gz', branchforks=True)
|
||||
df = sdf.load(mydir / 'b14.sdf.gz')
|
||||
lt = df.annotation(c)
|
||||
wsim = WaveSimCuda(c, lt, 8)
|
||||
compare_to_logic_sim(wsim)
|
||||
def test_b14_cuda(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSimCuda(b14_circuit, b14_timing, 8, strip_forks=True))
|
||||
@@ -1,166 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
from kyupy.wave_sim4 import WaveSim, WaveSimCuda, wave_eval_cpu, TMIN, TMAX
|
||||
from kyupy.logic_sim import LogicSim
|
||||
from kyupy import verilog, sdf, logic, bench
|
||||
from kyupy.logic import MVArray, BPArray
|
||||
from kyupy.sim import SimPrim
|
||||
|
||||
|
||||
def test_nand_delays():
|
||||
op = (SimPrim.NAND4, 4, 0, 1, 2, 3)
|
||||
#op = (0b0111, 4, 0, 1)
|
||||
c = np.full((5*16, 1), TMAX) # 5 waveforms of capacity 16
|
||||
vat = np.zeros((5, 3), dtype='int')
|
||||
for i in range(5): vat[i] = i*16, 16, 0 # 1:1 mapping
|
||||
|
||||
# SDF specifies IOPATH delays with respect to output polarity
|
||||
# SDF pulse rejection value is determined by IOPATH causing last transition and polarity of last transition
|
||||
line_times = np.zeros((5, 2, 2))
|
||||
line_times[0, 0, 0] = 0.1 # A -> Z rise delay
|
||||
line_times[0, 0, 1] = 0.2 # A -> Z fall delay
|
||||
line_times[0, 1, 0] = 0.1 # A -> Z negative pulse limit (terminate in rising Z)
|
||||
line_times[0, 1, 1] = 0.2 # A -> Z positive pulse limit
|
||||
line_times[1, :, 0] = 0.3 # as above for B -> Z
|
||||
line_times[1, :, 1] = 0.4
|
||||
line_times[2, :, 0] = 0.5 # as above for C -> Z
|
||||
line_times[2, :, 1] = 0.6
|
||||
line_times[3, :, 0] = 0.7 # as above for D -> Z
|
||||
line_times[3, :, 1] = 0.8
|
||||
|
||||
sdata = np.asarray([1, -1, 0, 0], dtype='float32')
|
||||
|
||||
def wave_assert(inputs, output):
|
||||
for i, a in zip(inputs, c.reshape(-1,16)): a[:len(i)] = i
|
||||
wave_eval_cpu(op, c, vat, 0, line_times, sdata)
|
||||
for i, v in enumerate(output): np.testing.assert_allclose(c.reshape(-1,16)[4,i], v)
|
||||
|
||||
wave_assert([[TMAX,TMAX],[TMAX,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # NAND(0,0,1,1) => 1
|
||||
wave_assert([[TMIN,TMAX],[TMAX,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # NAND(1,0,1,1) => 1
|
||||
wave_assert([[TMIN,TMAX],[TMIN,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMAX]) # NAND(1,1,1,1) => 0
|
||||
|
||||
# Keep inputs C=1 and D=1.
|
||||
wave_assert([[1,TMAX],[2,TMAX]], [TMIN,2.4,TMAX]) # _/⎺⎺⎺ NAND __/⎺⎺ => ⎺⎺⎺\___ (B->Z fall delay)
|
||||
wave_assert([[TMIN,TMAX],[TMIN,2,TMAX]], [2.3,TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺⎺\__ => ___/⎺⎺⎺ (B->Z rise delay)
|
||||
wave_assert([[TMIN,TMAX],[TMIN,2,2.35,TMAX]], [2.3,2.75,TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺\_/⎺ => __/⎺⎺\_ (pos pulse, .35@B -> .45@Z)
|
||||
wave_assert([[TMIN,TMAX],[TMIN,2,2.25,TMAX]], [TMAX]) # ⎺⎺⎺⎺⎺ NAND ⎺\_/⎺ => _______ (pos pulse, .25@B -> .35@Z, filtered)
|
||||
wave_assert([[TMIN,TMAX],[2,2.45,TMAX]], [TMIN,2.4,2.75,TMAX]) # ⎺⎺⎺⎺⎺ NAND _/⎺\_ => ⎺⎺\_/⎺⎺ (neg pulse, .45@B -> .35@Z)
|
||||
wave_assert([[TMIN,TMAX],[2,2.35,TMAX]], [TMIN,TMAX]) # ⎺⎺⎺⎺⎺ NAND _/⎺\_ => ⎺⎺⎺⎺⎺⎺⎺ (neg pulse, .35@B -> .25@Z, filtered)
|
||||
|
||||
|
||||
def test_tiny_circuit():
|
||||
c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)')
|
||||
lt = np.zeros((len(c.lines), 2, 2))
|
||||
lt[:,0,:] = 1.0 # unit delay for all lines
|
||||
wsim = WaveSim(c, lt)
|
||||
assert len(wsim.s) == 5
|
||||
|
||||
# values for x
|
||||
wsim.s[0,0,:3] = 0, 0.1, 0
|
||||
wsim.s[0,1,:3] = 0, 0.2, 1
|
||||
wsim.s[0,2,:3] = 1, 0.3, 0
|
||||
wsim.s[0,3,:3] = 1, 0.4, 1
|
||||
|
||||
# values for y
|
||||
wsim.s[1,0,:3] = 1, 0.5, 0
|
||||
wsim.s[1,1,:3] = 1, 0.6, 0
|
||||
wsim.s[1,2,:3] = 1, 0.7, 0
|
||||
wsim.s[1,3,:3] = 0, 0.8, 1
|
||||
|
||||
wsim.s_to_c()
|
||||
|
||||
x_c_loc = wsim.vat[wsim.ppi_offset+0, 0] # check x waveforms
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 0], [TMAX, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 1], [0.2, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 2], [TMIN, 0.3, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[x_c_loc:x_c_loc+3, 3], [TMIN, TMAX, TMAX])
|
||||
|
||||
y_c_loc = wsim.vat[wsim.ppi_offset+1, 0] # check y waveforms
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 0], [TMIN, 0.5, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 1], [TMIN, 0.6, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 2], [TMIN, 0.7, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[y_c_loc:y_c_loc+3, 3], [0.8, TMAX, TMAX])
|
||||
|
||||
wsim.c_prop()
|
||||
|
||||
a_c_loc = wsim.vat[wsim.ppo_offset+2, 0] # check a waveforms
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 0], [TMAX, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 1], [1.2, 1.6, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 2], [TMIN, 1.3, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[a_c_loc:a_c_loc+3, 3], [1.8, TMAX, TMAX])
|
||||
|
||||
o_c_loc = wsim.vat[wsim.ppo_offset+3, 0] # check o waveforms
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 0], [TMIN, 1.5, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 1], [TMIN, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 2], [TMIN, 1.7, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[o_c_loc:o_c_loc+3, 3], [TMIN, TMAX, TMAX])
|
||||
|
||||
n_c_loc = wsim.vat[wsim.ppo_offset+4, 0] # check n waveforms
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 0], [TMIN, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 1], [TMIN, 1.2, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 2], [1.3, TMAX, TMAX])
|
||||
np.testing.assert_allclose(wsim.c[n_c_loc:n_c_loc+3, 3], [TMAX, TMAX, TMAX])
|
||||
|
||||
wsim.c_to_s()
|
||||
|
||||
# check a captures
|
||||
np.testing.assert_allclose(wsim.s[2, 0, 3:7], [0, TMAX, TMIN, 0])
|
||||
np.testing.assert_allclose(wsim.s[2, 1, 3:7], [0, 1.2, 1.6, 0])
|
||||
np.testing.assert_allclose(wsim.s[2, 2, 3:7], [1, 1.3, 1.3, 0])
|
||||
np.testing.assert_allclose(wsim.s[2, 3, 3:7], [0, 1.8, 1.8, 1])
|
||||
|
||||
# check o captures
|
||||
np.testing.assert_allclose(wsim.s[3, 0, 3:7], [1, 1.5, 1.5, 0])
|
||||
np.testing.assert_allclose(wsim.s[3, 1, 3:7], [1, TMAX, TMIN, 1])
|
||||
np.testing.assert_allclose(wsim.s[3, 2, 3:7], [1, 1.7, 1.7, 0])
|
||||
np.testing.assert_allclose(wsim.s[3, 3, 3:7], [1, TMAX, TMIN, 1])
|
||||
|
||||
# check o captures
|
||||
np.testing.assert_allclose(wsim.s[4, 0, 3:7], [1, TMAX, TMIN, 1])
|
||||
np.testing.assert_allclose(wsim.s[4, 1, 3:7], [1, 1.2, 1.2, 0])
|
||||
np.testing.assert_allclose(wsim.s[4, 2, 3:7], [0, 1.3, 1.3, 1])
|
||||
np.testing.assert_allclose(wsim.s[4, 3, 3:7], [0, TMAX, TMIN, 0])
|
||||
|
||||
|
||||
def compare_to_logic_sim(wsim: WaveSim):
|
||||
tests = MVArray((len(wsim.s_nodes), wsim.sims))
|
||||
choices = np.asarray([logic.ZERO, logic.ONE, logic.RISE, logic.FALL], dtype=np.uint8)
|
||||
rng = np.random.default_rng(10)
|
||||
tests.data[...] = rng.choice(choices, tests.data.shape)
|
||||
|
||||
wsim.s[..., 0] = (tests.data & 2) >> 1
|
||||
wsim.s[..., 3] = (tests.data & 2) >> 1
|
||||
wsim.s[..., 1] = 0.0
|
||||
wsim.s[..., 2] = tests.data & 1
|
||||
wsim.s[..., 6] = tests.data & 1
|
||||
|
||||
wsim.s_to_c()
|
||||
wsim.c_prop()
|
||||
wsim.c_to_s()
|
||||
|
||||
resp = MVArray(tests)
|
||||
resp.data[...] = wsim.s[..., 6].astype(np.uint8) | (wsim.s[..., 3].astype(np.uint8)<<1)
|
||||
resp.data |= ((resp.data ^ (resp.data >> 1)) & 1) << 2 # transitions
|
||||
|
||||
tests_bp = BPArray(tests)
|
||||
lsim = LogicSim(wsim.circuit, len(tests_bp))
|
||||
lsim.assign(tests_bp)
|
||||
lsim.propagate()
|
||||
exp_bp = BPArray(tests_bp)
|
||||
lsim.capture(exp_bp)
|
||||
exp = MVArray(exp_bp)
|
||||
|
||||
for i in range(8):
|
||||
exp_str = exp[i].replace('P', '0').replace('N', '1')
|
||||
res_str = resp[i].replace('P', '0').replace('N', '1')
|
||||
assert res_str == exp_str
|
||||
|
||||
|
||||
def test_b14(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSim(b14_circuit, b14_timing, 8))
|
||||
|
||||
def test_b14_strip_forks(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSim(b14_circuit, b14_timing, 8, strip_forks=True))
|
||||
|
||||
def test_b14_cuda(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSimCuda(b14_circuit, b14_timing, 8, strip_forks=True))
|
||||
@@ -0,0 +1,138 @@
|
||||
import numpy as np
|
||||
|
||||
from kyupy.wave_sim_old import WaveSim, WaveSimCuda, wave_eval, TMIN, TMAX
|
||||
from kyupy.logic_sim import LogicSim
|
||||
from kyupy import verilog, sdf, logic
|
||||
from kyupy.logic import MVArray, BPArray
|
||||
|
||||
|
||||
def test_wave_eval():
|
||||
# SDF specifies IOPATH delays with respect to output polarity
|
||||
# SDF pulse rejection value is determined by IOPATH causing last transition and polarity of last transition
|
||||
line_times = np.zeros((3, 2, 2))
|
||||
line_times[0, 0, 0] = 0.1 # A -> Z rise delay
|
||||
line_times[0, 0, 1] = 0.2 # A -> Z fall delay
|
||||
line_times[0, 1, 0] = 0.1 # A -> Z negative pulse limit (terminate in rising Z)
|
||||
line_times[0, 1, 1] = 0.2 # A -> Z positive pulse limit
|
||||
line_times[1, 0, 0] = 0.3 # as above for B -> Z
|
||||
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]
|
||||
b = state[16:32, 0]
|
||||
z = state[32:, 0]
|
||||
sat = np.zeros((3, 3), dtype='int')
|
||||
sat[0] = 0, 16, 0
|
||||
sat[1] = 16, 16, 0
|
||||
sat[2] = 32, 16, 0
|
||||
|
||||
sdata = np.asarray([1, -1, 0, 0], dtype='float32')
|
||||
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMIN
|
||||
|
||||
a[0] = TMIN
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMIN
|
||||
|
||||
b[0] = TMIN
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMAX
|
||||
|
||||
a[0] = 1 # A _/^^^
|
||||
b[0] = 2 # B __/^^
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
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, sdata)
|
||||
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 ^^^^^^^^
|
||||
b[0] = TMIN
|
||||
b[1] = 2 # B ^^\__/^^
|
||||
b[2] = 2.35
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
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 ^^^^^^^^
|
||||
b[0] = 2 # B __/^^\__
|
||||
b[1] = 2.45
|
||||
b[2] = TMAX
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
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 ^^^^^^^^
|
||||
b[0] = 2 # B __/^^\__
|
||||
b[1] = 2.35
|
||||
b[2] = TMAX
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMIN # ^^^^^^
|
||||
assert z[1] == TMAX
|
||||
|
||||
# pos pulse of 0.25 at B -> 0.35 after delays (filtered)
|
||||
a[0] = TMIN # A ^^^^^^^^
|
||||
b[0] = TMIN
|
||||
b[1] = 2 # B ^^\__/^^
|
||||
b[2] = 2.25
|
||||
wave_eval((0b0111, 2, 0, 1), state, sat, 0, line_times, sdata)
|
||||
assert z[0] == TMAX # ______
|
||||
|
||||
|
||||
def compare_to_logic_sim(wsim):
|
||||
tests = MVArray((len(wsim.interface), wsim.sims))
|
||||
choices = np.asarray([logic.ZERO, logic.ONE, logic.RISE, logic.FALL], dtype=np.uint8)
|
||||
rng = np.random.default_rng(10)
|
||||
tests.data[...] = rng.choice(choices, tests.data.shape)
|
||||
tests_bp = BPArray(tests)
|
||||
wsim.assign(tests_bp)
|
||||
wsim.propagate()
|
||||
cdata = wsim.capture()
|
||||
|
||||
resp = MVArray(tests)
|
||||
|
||||
for iidx, inode in enumerate(wsim.interface):
|
||||
if len(inode.ins) > 0:
|
||||
for vidx in range(wsim.sims):
|
||||
resp.data[iidx, vidx] = logic.ZERO if cdata[iidx, vidx, 0] < 0.5 else logic.ONE
|
||||
# resp.set_value(vidx, iidx, 0 if cdata[iidx, vidx, 0] < 0.5 else 1)
|
||||
|
||||
lsim = LogicSim(wsim.circuit, len(tests_bp))
|
||||
lsim.assign(tests_bp)
|
||||
lsim.propagate()
|
||||
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')
|
||||
assert res_str == exp_str
|
||||
|
||||
|
||||
def test_b14(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSim(b14_circuit, b14_timing, 8))
|
||||
|
||||
|
||||
def test_b14_strip_forks(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSim(b14_circuit, b14_timing, 8, strip_forks=True))
|
||||
|
||||
|
||||
def test_b14_cuda(b14_circuit, b14_timing):
|
||||
compare_to_logic_sim(WaveSimCuda(b14_circuit, b14_timing, 8, strip_forks=True))
|
||||
Reference in new issue
Block a user