Skip to content

Commit b0a5556

Browse files
committed
Merge branch 'feature_fast_axi_memory_model' into develop
2 parents 2f2679a + 8538740 commit b0a5556

File tree

1 file changed

+68
-75
lines changed

1 file changed

+68
-75
lines changed

veriloggen/types/axi.py

Lines changed: 68 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,13 +2291,22 @@ def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=32,
22912291
self._make_fsm(write_delay, read_delay, sleep)
22922292

22932293
@staticmethod
2294-
def _make_img(filename, size, width):
2294+
def _make_img(filename, size, width, blksize=4096):
2295+
import numpy as np
2296+
2297+
wordsize = width // 8
2298+
zero = np.zeros([size // wordsize, wordsize], dtype=np.int64)
2299+
base = np.arange(size // wordsize, dtype=np.int64).reshape([-1, 1])
2300+
shamt = np.arange(wordsize, dtype=np.int64) * [8]
2301+
mask = np.full([1], 2 ** 8 - 1, dtype=np.int64)
2302+
data = (((zero + base) >> shamt) & mask).reshape([-1])
2303+
fmt = '%02x\n'
2304+
22952305
with open(filename, 'w') as f:
2296-
for i in range(size * 8 // width):
2297-
s = (''.join(['%0', '%d' %
2298-
int(math.ceil(width / 4)), 'x'])) % i
2299-
for w in range(int(math.ceil(width / 4)), 0, -2):
2300-
f.write('%s\n' % s[w - 2:w])
2306+
for i in range(0, len(data), blksize):
2307+
blk = data[i:i + blksize]
2308+
s = ''.join([fmt % d for d in blk])
2309+
f.write(s)
23012310

23022311
def _make_fsm(self, write_delay=10, read_delay=10, sleep=4):
23032312
write_mode = 100
@@ -2551,7 +2560,7 @@ def make_memory_image(filename, length, pattern='inc', dtype=None,
25512560

25522561

25532562
def to_memory_image(filename, array, length=None,
2554-
datawidth=32, wordwidth=8, endian='little'):
2563+
datawidth=32, wordwidth=8, endian='little', blksize=4096):
25552564

25562565
import numpy as np
25572566

@@ -2576,46 +2585,43 @@ def to_memory_image(filename, array, length=None,
25762585

25772586
if datawidth >= wordwidth:
25782587
num = int(math.ceil(datawidth / wordwidth))
2579-
mask = (2 ** wordwidth) - 1
25802588

2581-
with open(filename, 'w') as f:
2582-
for data in array:
2583-
values = []
2584-
for i in range(num):
2585-
values.append(data & mask)
2586-
data >>= wordwidth
2589+
zero = np.zeros(list(array.shape) + [num], dtype=np.int64)
2590+
base = array.reshape([-1, 1])
2591+
shamt = np.arange(num, dtype=np.int64) * [wordwidth]
2592+
if endian == 'big':
2593+
shamt.reverse()
25872594

2588-
if endian == 'big':
2589-
values.reverse()
2595+
mask = np.full([1], 2 ** wordwidth - 1, dtype=np.int64)
2596+
data = (((zero + base) >> shamt) & mask).reshape([-1])
25902597

2591-
for v in values:
2592-
f.write(fmt % v)
2598+
with open(filename, 'w') as f:
2599+
for i in range(0, len(data), blksize):
2600+
blk = data[i:i + blksize]
2601+
s = ''.join([fmt % d for d in blk])
2602+
f.write(s)
25932603

2594-
num_lines = len(array) * num
2595-
return num_lines
2604+
return len(data)
25962605

25972606
else:
25982607
num = int(math.ceil(wordwidth / datawidth))
2599-
mask = (2 ** datawidth) - 1
26002608

2601-
with open(filename, 'w') as f:
2602-
values = []
2603-
for data in array:
2604-
values.append(data & mask)
2605-
2606-
if len(values) == num:
2607-
if endian == 'big':
2608-
values.reverse()
2609+
base = array.reshape([-1, num])
2610+
shamt = np.arange(num, dtype=np.int64) * [datawidth]
2611+
if endian == 'big':
2612+
shamt.reverse()
26092613

2610-
cat = 0
2611-
for i, v in enumerate(values):
2612-
cat = cat | (v << (i * datawidth))
2614+
mask = np.full([1], 2 ** datawidth - 1, dtype=np.int64)
2615+
data = (base.reshape([-1, num]) & mask) << shamt
2616+
data = np.bitwise_or.reduce(data, -1).reshape([-1])
26132617

2614-
f.write(fmt % cat)
2615-
values = []
2618+
with open(filename, 'w') as f:
2619+
for i in range(0, len(data), blksize):
2620+
blk = data[i:i + blksize]
2621+
s = ''.join([fmt % d for d in blk])
2622+
f.write(s)
26162623

2617-
num_lines = len(array) // num
2618-
return num_lines
2624+
return len(data)
26192625

26202626

26212627
def aligned_shape(shape, datawidth, mem_datawidth):
@@ -2666,37 +2672,26 @@ def _set_memory_wide(mem, src, mem_datawidth, src_datawidth, mem_offset,
26662672
if num_align_words is not None:
26672673
src = align(src, num_align_words)
26682674

2669-
src_aligned_shape = aligned_shape(src.shape, src_datawidth, mem_datawidth)
26702675
num_pack = int(math.ceil(mem_datawidth / src_datawidth))
2671-
2672-
src_mask = np.uint64(2 ** src_datawidth - 1)
2673-
mem_mask = np.uint64(2 ** mem_datawidth - 1)
2676+
src_mask = np.full([1], 2 ** src_datawidth - 1, dtype=np.int64)
2677+
mem_mask = np.full([1], 2 ** mem_datawidth - 1, dtype=np.int64)
26742678
offset = mem_offset // int(math.ceil(mem_datawidth / 8))
2675-
pack = 0
2676-
index = 0
2677-
align_count = 0
26782679

2679-
for data in src.reshape([-1]):
2680-
v = np.uint64(data) & src_mask
2681-
shift = np.uint64(src_datawidth * pack)
2682-
v = v << shift
2683-
if pack > 0:
2684-
old = np.uint64(mem[offset]) & mem_mask
2685-
v = v | old
2686-
mem[offset] = v
2680+
if src.shape[-1] % num_pack != 0:
2681+
pads = []
2682+
for s in src.shape[:-1]:
2683+
pads.append((0, 0))
2684+
pads.append((0, num_pack - src.shape[-1]))
26872685

2688-
index += 1
2689-
if pack == num_pack - 1:
2690-
pack = 0
2691-
offset += 1
2692-
if index == src.shape[-1]:
2693-
index = 0
2694-
else:
2695-
pack += 1
2696-
if index == src.shape[-1]:
2697-
index = 0
2698-
pack = 0
2699-
offset += 1
2686+
src = np.pad(src, pads, 'constant')
2687+
2688+
masked_data = src.astype(np.int64) & src_mask
2689+
pack = np.arange(src.shape[-1], dtype=np.int64) % [num_pack]
2690+
shift = [src_datawidth] * pack
2691+
v = (masked_data << shift) & mem_mask
2692+
v = np.reshape(v, [-1, num_pack])
2693+
v = np.bitwise_or.reduce(v, -1)
2694+
mem[offset:offset + v.shape[-1]] = v
27002695

27012696

27022697
def _set_memory_narrow(mem, src, mem_datawidth, src_datawidth, mem_offset,
@@ -2710,21 +2705,19 @@ def _set_memory_narrow(mem, src, mem_datawidth, src_datawidth, mem_offset,
27102705
if num_align_words is not None:
27112706
src = align(src, num_align_words)
27122707

2713-
src_aligned_shape = aligned_shape(src.shape, src_datawidth, mem_datawidth)
27142708
num_pack = int(math.ceil(src_datawidth / mem_datawidth))
2715-
2716-
src_mask = np.uint64(2 ** src_datawidth - 1)
2717-
mem_mask = np.uint64(2 ** mem_datawidth - 1)
2709+
src_mask = np.full([1], 2 ** src_datawidth - 1, dtype=np.int64)
2710+
mem_mask = np.full([1], 2 ** mem_datawidth - 1, dtype=np.int64)
27182711
offset = mem_offset // int(math.ceil(mem_datawidth / 8))
27192712

2720-
for data in src.reshape([-1]):
2721-
for pack in range(num_pack):
2722-
v = np.uint64(data)
2723-
shift = np.uint64(mem_datawidth * pack)
2724-
v = v >> shift
2725-
v = v & mem_mask
2726-
mem[offset] = v
2727-
offset += 1
2713+
pack = np.arange(num_pack, dtype=np.int64)
2714+
shift = [mem_datawidth] * pack
2715+
dup_src_based = np.zeros(list(src.shape) + [num_pack], dtype=np.int64)
2716+
dup_src = dup_src_based + np.reshape(src, list(src.shape) + [1])
2717+
v = dup_src >> shift
2718+
v = np.reshape(v, [-1])
2719+
v = v & mem_mask
2720+
mem[offset:offset + v.shape[-1]] = v
27282721

27292722

27302723
def align(src, num_align_words):

0 commit comments

Comments
 (0)