@@ -80,12 +80,18 @@ module address_scrambler #(
8080 end
8181
8282 logic [NumDASPartitions- 1 : 0 ][AddrWidth- 1 : 0 ] lsb_addr;
83- logic [NumDASPartitions- 1 : 0 ][AddrWidth- 1 : 0 ] start_row_addr;
8483 logic [NumDASPartitions- 1 : 0 ][AddrWidth- 1 : 0 ] row_addr;
8584 logic [NumDASPartitions- 1 : 0 ][AddrWidth- 1 : 0 ] prt_addr;
8685 logic [NumDASPartitions- 1 : 0 ][AddrWidth- 1 : 0 ] msb_addr;
8786 logic [NumDASPartitions- 1 : 0 ][AddrWidth- 1 : 0 ] aligned_addr;
8887
88+ // Narrow row-index field signals (MaxPartitionRowWidth-bit) to replace the
89+ // 32-bit adders that were on the critical path. Only the row-index bits at
90+ // [TileIdBits+ConstantBitsLSB +: MaxPartitionRowWidth] are affected by the
91+ // subtract/add — all other bits pass through unchanged.
92+ localparam int unsigned RowFieldLSB = TileIdBits + ConstantBitsLSB;
93+ logic [NumDASPartitions- 1 : 0 ][MaxPartitionRowWidth- 1 : 0 ] start_row_field;
94+
8995 always_comb begin
9096
9197 // Default: Unscrambled
@@ -105,13 +111,26 @@ module address_scrambler #(
105111
106112 lsb_addr[p] = address_i & ((1 << (tile_bits[p]+ ConstantBitsLSB)) - 1 );
107113 msb_addr[p] = address_i & ~ ((1 << (row_bits[p]+ TileIdBits+ ConstantBitsLSB)) - 1 );
108- start_row_addr[p] = start_das_i[p] & (((1 << row_bits[p]) - 1 ) << (TileIdBits + ConstantBitsLSB));
109- aligned_addr[p] = address_i - start_row_addr[p];
114+
115+ // Narrow subtract: extract the row-index field from the partition
116+ // start address (masked to row_bits width via rows_das-1), then
117+ // subtract from the address row field to get the partition-relative
118+ // row index. Only MaxPartitionRowWidth bits (~8 bits) instead of 32.
119+ start_row_field[p] = start_das_i[p][RowFieldLSB + : MaxPartitionRowWidth]
120+ & (rows_das_i[p] - 1 );
121+ aligned_addr[p] = address_i;
122+ aligned_addr[p][RowFieldLSB + : MaxPartitionRowWidth] =
123+ address_i[RowFieldLSB + : MaxPartitionRowWidth] - start_row_field[p];
110124
111125 prt_addr[p] = (aligned_addr[p] >> row_bits[p] ) & (((1 << (TileIdBits - tile_bits[p])) - 1 ) << (ConstantBitsLSB + tile_bits[p]));
112126 row_addr[p] = (aligned_addr[p] << (TileIdBits - tile_bits[p])) & (((1 << (row_bits[p]) ) - 1 ) << (TileIdBits + ConstantBitsLSB ));
113127 address_o = msb_addr[p] | row_addr[p] | prt_addr[p] | lsb_addr[p];
114- address_o = address_o + start_row_addr[p];
128+
129+ // Narrow add: restore the absolute row-index offset.
130+ // Only the row-index field is modified — MSB and LSB bits are
131+ // already correct from msb_addr and lsb_addr.
132+ address_o[RowFieldLSB + : MaxPartitionRowWidth] =
133+ address_o[RowFieldLSB + : MaxPartitionRowWidth] + start_row_field[p];
115134
116135 end
117136 end
0 commit comments