44import math
55
66RANDOM_STIMULI = False # If False, counting stimuli are generated in a counting fashion
7+ WORD_ALIGNED = False # If True, matrices are aligned to word boundaries by zero-padding
78
89# ToDo(cdurrer): small matrices (N < BW) not working
910
1011def extract_elements_from_word (word , word_width , elem_width ):
1112 """Extract elements from a word based on the specified widths."""
1213 word_int = int (word , 16 ) # Convert hex string to integer
13-
1414 elements = []
1515 for i in range (word_width // elem_width ):
1616 # Extract each element using shift and mask
@@ -44,29 +44,42 @@ def generate_counting_hex(size, elem_width, word_width):
4444 elem_val = (i * elems_per_word + j ) & ((1 << elem_width ) - 1 )
4545 word_val |= (elem_val << (j * elem_width ))
4646 result .append (f"{ word_val :0{word_width // 4 }X} " ) # Format as hex string
47-
4847 return result
4948
5049def pack_elements_to_word (elements , elem_width , word_width ):
5150 """Pack multiple elements into a single word."""
5251 elems_per_word = word_width // elem_width
5352 word_val = 0
54-
5553 for i , elem in enumerate (elements [:elems_per_word ]): # Take only what fits in a word
5654 word_val |= (elem << (i * elem_width ))
57-
5855 return f"{ word_val :0{word_width // 4 }X} "
5956
6057def matrix_to_hex_words (matrix , elem_width , word_width ):
6158 """Convert a matrix of elements to a list of hex words."""
6259 elems_per_word = word_width // elem_width
6360 hex_words = []
6461 matrix_flat = sum (matrix , [])
65-
6662 for i in range (math .ceil (len (matrix_flat ) / elems_per_word )):
6763 hex_word = pack_elements_to_word (matrix_flat [i * elems_per_word :i * elems_per_word + elems_per_word ], elem_width , word_width )
6864 hex_words .append (hex_word )
65+ return hex_words
6966
67+ def matrix_to_hex_words_word_aligned (matrix , elem_width , word_width ):
68+ """Convert a matrix of elements to a list of hex words - aligned to word boundaries by zero-padding."""
69+ elems_per_word = word_width // elem_width
70+ hex_words = []
71+ for row in matrix :
72+ # Process each row, grouping elements into words
73+ for i in range (0 , len (row ), elems_per_word ):
74+ elements_for_word = row [i :i + elems_per_word ]
75+
76+ # Pad with zeros if the row doesn't fill a complete word
77+ while len (elements_for_word ) < elems_per_word :
78+ elements_for_word .append (0 )
79+
80+ # Pack elements into a word
81+ hex_word = pack_elements_to_word (elements_for_word , elem_width , word_width )
82+ hex_words .append (hex_word )
7083 return hex_words
7184
7285def write_file (output_dir , filename , content ):
@@ -114,6 +127,7 @@ def main():
114127 parser .add_argument ("--bandwidth_bits" , type = int , default = 4 , help = "Number of bits per transaction" )
115128 parser .add_argument ("--num_elem_word" , type = int , default = 4 , help = "Number of elements in a memory bank word" )
116129 parser .add_argument ("--elem_width" , type = int , default = 8 , help = "Width of each element (in bits)" )
130+ parser .add_argument ("--misaligned_accesses" , type = int , default = 0 , help = "Enable misaligned accesses (0=disabled, 1=enabled)" )
117131 parser .add_argument ("--datamover_mode" , type = int , default = 0 , help = "Datamover mode (0=normal, 1=CIM)" )
118132 parser .add_argument ("--transp_mode" , type = int , default = 0 , help = "Transposition mode (3'b000 = none, 3'b001 = 1 elem, 3'b010 = 2 elem, 3'b100 = 4 elem)" )
119133 parser .add_argument ("--transp_len" , type = int , default = 0 , help = "Transposition length" )
@@ -126,8 +140,9 @@ def main():
126140
127141 args = parser .parse_args ()
128142
143+ BANDWIDTH_ALIGNED = args .bandwidth_bits - (args .misaligned_accesses * (args .elem_width * args .num_elem_word ))
129144 MEMORY_SIZE = args .mem_size # Set global memory size
130- BANDWIDTH_ELEMS = args . bandwidth_bits // args .elem_width
145+ BANDWIDTH_ELEMS = BANDWIDTH_ALIGNED // args .elem_width
131146 BANDWIDTH_WORDS = BANDWIDTH_ELEMS // args .num_elem_word
132147 WORD_SIZE_BITS = args .num_elem_word * args .elem_width # Set global word size in bits
133148
@@ -151,11 +166,11 @@ def main():
151166 if args .num_elem_word & (args .num_elem_word - 1 ) != 0 or args .num_elem_word <= 0 :
152167 raise ValueError ("[GM] num_elem_word must be a power of two and greater than zero." )
153168 # bandwidth width must be a multiple of word size
154- if args . bandwidth_bits % WORD_SIZE_BITS != 0 :
155- raise ValueError ("[GM] bandwidth_bits must be a multiple of the word size (num_elem_word * elem_width)." )
169+ if BANDWIDTH_ALIGNED % WORD_SIZE_BITS != 0 :
170+ raise ValueError ("[GM] BANDWIDTH_ALIGNED must be a multiple of the word size (num_elem_word * elem_width)." )
156171 # # bandwidth width must be a multiple of word size
157- # if ((MATRIX_SIZE_N * ELEM_WIDTH) < args.bandwidth_bits ):
158- # raise ValueError("[GM] Matrix width (N) in bits must be at least as large as bandwidth_bits .")
172+ # if ((MATRIX_SIZE_N * ELEM_WIDTH) < BANDWIDTH_ALIGNED ):
173+ # raise ValueError("[GM] Matrix width (N) in bits must be at least as large as BANDWIDTH_ALIGNED .")
159174 # read_tot_length must not exceed 12-bit register capacity (4096)
160175 if ((args .read_tot_length >= 4096 ) & (args .datamover_mode != 0 )):
161176 raise ValueError ("[GM] read_tot_length (MxN / BW_ELEM) must be less than 4096 in transpose and CIM modes (12-bit register limit)." )
@@ -180,7 +195,6 @@ def main():
180195
181196 # Convert memory to flat vector
182197 memory_flat = convert_memory_to_vector (memory , ELEM_WIDTH , WORD_WIDTH )
183- print (memory_flat )
184198
185199 # Extract matrix (read dimensions) from memory
186200 input_matrix = [[0 for _ in range (MATRIX_SIZE_N )] for _ in range (MATRIX_SIZE_M )]
@@ -213,7 +227,11 @@ def main():
213227 print ("\n " )
214228
215229 # # Convert output matrix back to words
216- output_hex_words = matrix_to_hex_words (output_matrix , ELEM_WIDTH , WORD_WIDTH )
230+ if (WORD_ALIGNED ):
231+ output_hex_words = matrix_to_hex_words_word_aligned (output_matrix , ELEM_WIDTH , WORD_WIDTH )
232+ else :
233+ output_hex_words = matrix_to_hex_words (output_matrix , ELEM_WIDTH , WORD_WIDTH )
234+
217235 print (f"\n Output Matrix as Hex Words:" )
218236 for i , word in enumerate (output_hex_words ):
219237 print (f"Word { i } : { word } " )
0 commit comments