You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.8 KiB
150 lines
4.8 KiB
import numpy as np |
|
|
|
from kyupy.wave_sim 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(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_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_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)
|
|
|