Skip to content

Commit dd28091

Browse files
committed
Memory image creation methods in AxiMemoryModel adre updated to speed up.
1 parent 2f2679a commit dd28091

File tree

1 file changed

+61
-76
lines changed

1 file changed

+61
-76
lines changed

veriloggen/types/axi.py

Lines changed: 61 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,13 +2291,20 @@ 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+
s = ''.join([fmt % d for d in data])
2305+
22952306
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])
2307+
f.write(s)
23012308

23022309
def _make_fsm(self, write_delay=10, read_delay=10, sleep=4):
23032310
write_mode = 100
@@ -2576,46 +2583,37 @@ def to_memory_image(filename, array, length=None,
25762583

25772584
if datawidth >= wordwidth:
25782585
num = int(math.ceil(datawidth / wordwidth))
2579-
mask = (2 ** wordwidth) - 1
2580-
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
25872586

2588-
if endian == 'big':
2589-
values.reverse()
2587+
zero = np.zeros(list(array.shape) + [num], dtype=np.int64)
2588+
base = array.reshape([-1, 1])
2589+
shamt = np.arange(num, dtype=np.int64) * [wordwidth]
2590+
if endian == 'big':
2591+
shamt.reverse()
25902592

2591-
for v in values:
2592-
f.write(fmt % v)
2593+
mask = np.full([1], 2 ** wordwidth - 1, dtype=np.int64)
2594+
data = (((zero + base) >> shamt) & mask).reshape([-1])
2595+
s = ''.join([fmt % d for d in data])
2596+
with open(filename, 'w') as f:
2597+
f.write(s)
25932598

2594-
num_lines = len(array) * num
2595-
return num_lines
2599+
return len(data)
25962600

25972601
else:
25982602
num = int(math.ceil(wordwidth / datawidth))
2599-
mask = (2 ** datawidth) - 1
26002603

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()
2604+
base = array.reshape([-1, num])
2605+
shamt = np.arange(num, dtype=np.int64) * [datawidth]
2606+
if endian == 'big':
2607+
shamt.reverse()
26092608

2610-
cat = 0
2611-
for i, v in enumerate(values):
2612-
cat = cat | (v << (i * datawidth))
2613-
2614-
f.write(fmt % cat)
2615-
values = []
2609+
mask = np.full([1], 2 ** datawidth - 1, dtype=np.int64)
2610+
data = (base.reshape([-1, num]) & mask) << shamt
2611+
data = np.bitwise_or.reduce(data, -1).reshape([-1])
2612+
s = ''.join(fmt % d for d in data)
2613+
with open(filename, 'w') as f:
2614+
f.write(s)
26162615

2617-
num_lines = len(array) // num
2618-
return num_lines
2616+
return len(data)
26192617

26202618

26212619
def aligned_shape(shape, datawidth, mem_datawidth):
@@ -2666,37 +2664,26 @@ def _set_memory_wide(mem, src, mem_datawidth, src_datawidth, mem_offset,
26662664
if num_align_words is not None:
26672665
src = align(src, num_align_words)
26682666

2669-
src_aligned_shape = aligned_shape(src.shape, src_datawidth, mem_datawidth)
26702667
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)
2668+
src_mask = np.full([1], 2 ** src_datawidth - 1, dtype=np.int64)
2669+
mem_mask = np.full([1], 2 ** mem_datawidth - 1, dtype=np.int64)
26742670
offset = mem_offset // int(math.ceil(mem_datawidth / 8))
2675-
pack = 0
2676-
index = 0
2677-
align_count = 0
26782671

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
2672+
if src.shape[-1] % num_pack != 0:
2673+
pads = []
2674+
for s in src.shape[:-1]:
2675+
pads.append((0, 0))
2676+
pads.append((0, num_pack - src.shape[-1]))
26872677

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
2678+
src = np.pad(src, pads, 'constant')
2679+
2680+
masked_data = src.astype(np.int64) & src_mask
2681+
pack = np.arange(src.shape[-1], dtype=np.int64) % [num_pack]
2682+
shift = [src_datawidth] * pack
2683+
v = (masked_data << shift) & mem_mask
2684+
v = np.reshape(v, [-1, num_pack])
2685+
v = np.bitwise_or.reduce(v, -1)
2686+
mem[offset:offset + v.shape[-1]] = v
27002687

27012688

27022689
def _set_memory_narrow(mem, src, mem_datawidth, src_datawidth, mem_offset,
@@ -2710,21 +2697,19 @@ def _set_memory_narrow(mem, src, mem_datawidth, src_datawidth, mem_offset,
27102697
if num_align_words is not None:
27112698
src = align(src, num_align_words)
27122699

2713-
src_aligned_shape = aligned_shape(src.shape, src_datawidth, mem_datawidth)
27142700
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)
2701+
src_mask = np.full([1], 2 ** src_datawidth - 1, dtype=np.int64)
2702+
mem_mask = np.full([1], 2 ** mem_datawidth - 1, dtype=np.int64)
27182703
offset = mem_offset // int(math.ceil(mem_datawidth / 8))
27192704

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
2705+
pack = np.arange(num_pack, dtype=np.int64)
2706+
shift = [mem_datawidth] * pack
2707+
dup_src_based = np.zeros(list(src.shape) + [num_pack], dtype=np.int64)
2708+
dup_src = dup_src_based + np.reshape(src, list(src.shape) + [1])
2709+
v = dup_src >> shift
2710+
v = np.reshape(v, [-1])
2711+
v = v & mem_mask
2712+
mem[offset:offset + v.shape[-1]] = v
27282713

27292714

27302715
def align(src, num_align_words):

0 commit comments

Comments
 (0)