@@ -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
26212619def 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
27022689def _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
27302715def align (src , num_align_words ):
0 commit comments