Skip to content

Commit

Permalink
sim: clean up shared functions in sim/util
Browse files Browse the repository at this point in the history
  • Loading branch information
vk2seb committed Nov 1, 2023
1 parent a8ed628 commit 50ca691
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 96 deletions.
3 changes: 0 additions & 3 deletions gateware/drivers/ak4619.sv
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,6 @@ always_ff @(posedge clk_256fs) begin
// BICK transition HI -> LO: Clock in W bits
// On HI -> LO both SDIN and SDOUT do not transition.
// (determined by AK4619 transition polarity register BCKP)
if (bit_counter == 0) begin
adc_words[channel] <= 0;
end
if (bit_counter < W) begin
adc_words[channel][W - bit_counter - 1] <= sdout1;
end
Expand Down
35 changes: 13 additions & 22 deletions gateware/sim/ak4619/tb_ak4619.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import sys
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer, FallingEdge, RisingEdge, ClockCycles
from cocotb.handle import Force, Release


async def clock_out_word(dut, word):
for i in range(32):
await RisingEdge(dut.bick)
dut.sdout1.value = (word >> (0x1F-i)) & 1

async def clock_in_word(dut):
word = 0x00000000
await RisingEdge(dut.bick)
for i in range(32):
await FallingEdge(dut.bick)
word |= dut.sdin1.value << (0x1F-i)
return word
# Hack to import some helpers despite existing outside a package.
sys.path.append("..")
from util.i2s import *

@cocotb.test()
async def test_ak4619_00(dut):
Expand All @@ -37,11 +28,11 @@ async def test_ak4619_00(dut):
await RisingEdge(dut.clk_256fs)
dut.rst.value = 0

await FallingEdge(dut.clk_fs)
await clock_out_word(dut, TEST_L0)
await clock_out_word(dut, TEST_R0)
await clock_out_word(dut, TEST_L1)
await clock_out_word(dut, TEST_R1)
await FallingEdge(dut.lrck)
await i2s_clock_out_u32(dut.bick, dut.sdout1, TEST_L0)
await i2s_clock_out_u32(dut.bick, dut.sdout1, TEST_R0)
await i2s_clock_out_u32(dut.bick, dut.sdout1, TEST_L1)
await i2s_clock_out_u32(dut.bick, dut.sdout1, TEST_R1)

# Note: this edge is also where dac_words <= sample_in (sample.sv)

Expand All @@ -66,10 +57,10 @@ async def test_ak4619_00(dut):
await FallingEdge(dut.lrck)
await FallingEdge(dut.lrck)

result_l0 = await clock_in_word(dut)
result_r0 = await clock_in_word(dut)
result_l1 = await clock_in_word(dut)
result_r1 = await clock_in_word(dut)
result_l0 = await i2s_clock_in_u32(dut.bick, dut.sdin1)
result_r0 = await i2s_clock_in_u32(dut.bick, dut.sdin1)
result_l1 = await i2s_clock_in_u32(dut.bick, dut.sdin1)
result_r1 = await i2s_clock_in_u32(dut.bick, dut.sdin1)

print("Data clocked from sample_inX out to sdin1:")
print(hex(result_l0))
Expand Down
21 changes: 8 additions & 13 deletions gateware/sim/cal/tb_cal.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import sys
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer, FallingEdge, RisingEdge, ClockCycles
from cocotb.handle import Force, Release

def bit_not(n, numbits=16):
return (1 << numbits) - 1 - n

def signed_to_twos_comp(n, numbits=16):
return n if n >= 0 else bit_not(-n, numbits) + 1

def twos_comp_to_signed(n, numbits=16):
if (1 << (numbits-1) & n) > 0:
return -int(bit_not(n, numbits) + 1)
else:
return n
# Hack to import some helpers despite existing outside a package.
sys.path.append("..")
from util.i2s import *

@cocotb.test()
async def test_cal_00(dut):

sample_width = 16

clk_256fs = Clock(dut.clk_256fs, 83, units='ns')
clk_fs = Clock(dut.clk_fs, 83*256, units='ns')
cocotb.start_soon(clk_256fs.start())
Expand Down Expand Up @@ -63,15 +58,15 @@ async def test_cal_00(dut):
# values everywhere else in the input array.
for i, o in all_ins_outs:
i.value = Force(0)
cal_inx.value = Force(signed_to_twos_comp(value))
cal_inx.value = Force(bits_from_signed(value, sample_width))
if expect > 32000: expect = 32000
if expect < -32000: expect = -32000
print(f"ch={channel}\t{int(value):6d}\t", end="")
await FallingEdge(dut.clk_fs)
await RisingEdge(dut.clk_fs)
await RisingEdge(dut.clk_fs)
await RisingEdge(dut.clk_fs)
output = twos_comp_to_signed(cal_outx.value)
output = signed_from_bits(cal_outx.value, sample_width)
print(f"=>\t{int(output):6d}\t(expect={expect})")
cal_inx.value = Release()
assert output == expect
Expand Down
53 changes: 21 additions & 32 deletions gateware/sim/integration/tb_integration.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,53 @@
import sys
import math
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer, FallingEdge, RisingEdge, ClockCycles
from cocotb.handle import Force, Release


async def clock_out_word(dut, word):
await FallingEdge(dut.bick)
for i in range(32):
await RisingEdge(dut.bick)
dut.sdout1.value = (word >> (0x1F-i)) & 1

async def clock_in_word(dut):
word = 0x00000000
await RisingEdge(dut.bick)
for i in range(32):
await FallingEdge(dut.bick)
word |= dut.sdin1.value << (0x1F-i)
return word

def bit_not(n, numbits=16):
return (1 << numbits) - 1 - n

def signed_to_twos_comp(n, numbits=16):
return n if n >= 0 else bit_not(-n, numbits) + 1
# Hack to import some helpers despite existing outside a package.
sys.path.append("..")
from util.i2s import *

@cocotb.test()
async def test_integration_00(dut):

sample_width=16

clk_256fs = Clock(dut.CLK, 83, units='ns')
cocotb.start_soon(clk_256fs.start())

dut.eurorack_pmod1.ak4619_instance.sdout1.value = 0
# Simulate all jacks connected so the cal core doesn't zero them
dut.eurorack_pmod1.jack.value = Force(0xFF)

# The reset timer is downstream of the PLL lock.
# So if we toggle the PLL lock, we are triggering
# a reset from the highest-level part of the system.
dut.sysmgr_instance.pll_lock.value = 0
await RisingEdge(dut.clk_256fs)
await RisingEdge(dut.clk_256fs)
dut.sysmgr_instance.pll_lock.value = 1

dut = dut.eurorack_pmod1.ak4619_instance
ak4619 = dut.eurorack_pmod1.ak4619_instance

N = 20

await FallingEdge(dut.lrck)

for i in range(N):

v = signed_to_twos_comp(int(16000*math.sin((2*math.pi*i)/N)))
v = bits_from_signed(int(16000*math.sin((2*math.pi*i)/N)), sample_width)

await FallingEdge(ak4619.lrck)

await clock_out_word(dut, v << 16)
await clock_out_word(dut, v << 16)
await clock_out_word(dut, v << 16)
await clock_out_word(dut, v << 16)
await i2s_clock_out_u32(ak4619.bick, ak4619.sdout1, v << 16)
await i2s_clock_out_u32(ak4619.bick, ak4619.sdout1, v << 16)
await i2s_clock_out_u32(ak4619.bick, ak4619.sdout1, v << 16)
await i2s_clock_out_u32(ak4619.bick, ak4619.sdout1, v << 16)

# Note: this edge is also where dac_words <= sample_in (sample.sv)

print("Data clocked from sdout1 present at sample_outX:")
print(hex(dut.sample_out0.value))
print(hex(dut.sample_out1.value))
print(hex(dut.sample_out2.value))
print(hex(dut.sample_out3.value))
print(hex(ak4619.sample_out0.value))
print(hex(ak4619.sample_out1.value))
print(hex(ak4619.sample_out2.value))
print(hex(ak4619.sample_out3.value))
21 changes: 8 additions & 13 deletions gateware/sim/transpose/tb_transpose.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
import pickle
import cocotb
import random
Expand All @@ -6,21 +7,15 @@
from cocotb.triggers import Timer, FallingEdge, RisingEdge, ClockCycles
from cocotb.handle import Force, Release

def bit_not(n, numbits=16):
return (1 << numbits) - 1 - n

def signed_to_twos_comp(n, numbits=16):
return n if n >= 0 else bit_not(-n, numbits) + 1

def twos_comp_to_signed(n, numbits=16):
if (1 << (numbits-1) & n) > 0:
return -int(bit_not(n, numbits) + 1)
else:
return int(n)
# Hack to import some helpers despite existing outside a package.
sys.path.append("..")
from util.i2s import *

@cocotb.test()
async def test_transpose_00(dut):

sample_width = 16

clock = Clock(dut.sample_clk, 5, units='us')
cocotb.start_soon(clock.start())

Expand All @@ -47,8 +42,8 @@ async def test_transpose_00(dut):

data_in = int(1000*math.sin(i / 100))

dut.sample_in.value = signed_to_twos_comp(data_in)
data_out = twos_comp_to_signed(dut.sample_out.value)
dut.sample_in.value = bits_from_signed(data_in, sample_width)
data_out = signed_from_bits(dut.sample_out.value, sample_width)

print(f"i={i} in:", data_in)
print(f"i={i} out:", data_out)
Expand Down
35 changes: 35 additions & 0 deletions gateware/sim/util/i2s.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import math
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer, FallingEdge, RisingEdge, ClockCycles
from cocotb.handle import Force, Release

async def i2s_clock_out_u32(bick, sdout, word):
"""Clock out a 32-bit word over I2S."""
for i in range(32):
await RisingEdge(bick)
sdout.value = (word >> (0x1F-i)) & 1

async def i2s_clock_in_u32(bick, sdin):
"""Clock in a 32-bit word over I2S."""
word = 0x00000000
await RisingEdge(bick)
for i in range(32):
await FallingEdge(bick)
word |= sdin.value << (0x1F-i)
return word

def bits_not(n, width):
"""Bitwise NOT from positive integer of `width` bits."""
return (1 << width) - 1 - n

def bits_from_signed(n, width):
"""Bits (2s complement) of `width` from signed integer."""
return n if n >= 0 else bits_not(-n, width) + 1

def signed_from_bits(n, width):
"""Signed integer from (2s complement) bits of `width`."""
if (1 << (width-1) & n) > 0:
return -int(bits_not(n, width) + 1)
else:
return n
21 changes: 8 additions & 13 deletions gateware/sim/vca/tb_vca.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import sys
import cocotb
import random
from cocotb.clock import Clock
from cocotb.triggers import Timer, FallingEdge, RisingEdge, ClockCycles
from cocotb.handle import Force, Release

def bit_not(n, numbits=16):
return (1 << numbits) - 1 - n

def signed_to_twos_comp(n, numbits=16):
return n if n >= 0 else bit_not(-n, numbits) + 1

def twos_comp_to_signed(n, numbits=16):
if (1 << (numbits-1) & n) > 0:
return -int(bit_not(n, numbits) + 1)
else:
return int(n)
# Hack to import some helpers despite existing outside a package.
sys.path.append("..")
from util.i2s import *

@cocotb.test()
async def test_vca_00(dut):

sample_width=16

clock = Clock(dut.sample_clk, 5, units='us')
cocotb.start_soon(clock.start())
clock = Clock(dut.clk, 83, units='ns')
Expand All @@ -35,11 +30,11 @@ async def test_vca_00(dut):
for inx in ins:
random_sample = random.randint(-30000, 30000)
data_in.append(random_sample)
inx.value = signed_to_twos_comp(random_sample)
inx.value = bits_from_signed(random_sample, sample_width)

await RisingEdge(dut.sample_clk)

data_out = [twos_comp_to_signed(out.value) for out in outs]
data_out = [signed_from_bits(out.value, sample_width) for out in outs]

print(f"i={i} stimulus:", data_in)
print(f"i={i} response:", data_out)
Expand Down

0 comments on commit 50ca691

Please sign in to comment.