Skip to content

Commit 6134272

Browse files
committed
library: util_pack: pack_shell: Parallelized the prefix sum calculation
The old algorithm used NUMBER_OF_SAMPLES adders in series to calculate the prefix sum and this caused a timing violation at high lane rates when NUMBER_OF_SAMPLES was large (e.g 64). The new algorithm uses at most log2(NUMBER_OF_SAMPLES) adders in series for the right most element but more adders overall. Signed-off-by: Bogdan Luncan <bogdan.luncan@analog.com>
1 parent 94bd806 commit 6134272

File tree

9 files changed

+83
-22
lines changed

9 files changed

+83
-22
lines changed

library/util_pack/util_cpack2/util_cpack2.v

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// ***************************************************************************
22
// ***************************************************************************
3-
// Copyright (C) 2018-2024 Analog Devices, Inc. All rights reserved.
3+
// Copyright (C) 2018-2025 Analog Devices, Inc. All rights reserved.
44
//
55
// In this HDL repository, there are many different and unique modules, consisting
66
// of various HDL (Verilog or VHDL) components. The individual modules are
@@ -38,7 +38,8 @@
3838
module util_cpack2 #(
3939
parameter NUM_OF_CHANNELS = 4,
4040
parameter SAMPLES_PER_CHANNEL = 1,
41-
parameter SAMPLE_DATA_WIDTH = 16
41+
parameter SAMPLE_DATA_WIDTH = 16,
42+
parameter PARALLEL_OR_SERIAL_N = 0
4243
) (
4344
input clk,
4445
input reset,
@@ -282,7 +283,8 @@ module util_cpack2 #(
282283
util_cpack2_impl #(
283284
.NUM_OF_CHANNELS (REAL_NUM_OF_CHANNELS),
284285
.SAMPLE_DATA_WIDTH (SAMPLE_DATA_WIDTH),
285-
.SAMPLES_PER_CHANNEL (SAMPLES_PER_CHANNEL)
286+
.SAMPLES_PER_CHANNEL (SAMPLES_PER_CHANNEL),
287+
.PARALLEL_OR_SERIAL_N (PARALLEL_OR_SERIAL_N)
286288
) i_cpack (
287289
.clk (clk),
288290
.reset (reset),

library/util_pack/util_cpack2/util_cpack2_hw.tcl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
## Copyright (C) 2018-2024 Analog Devices, Inc. All rights reserved.
2+
## Copyright (C) 2018-2025 Analog Devices, Inc. All rights reserved.
33
### SPDX short identifier: ADIBSD
44
###############################################################################
55

@@ -31,6 +31,11 @@ ad_ip_parameter SAMPLE_DATA_WIDTH INTEGER 16 true [list \
3131
DISPLAY_NAME "Sample Data Width"
3232
]
3333

34+
ad_ip_parameter PARALLEL_OR_SERIAL_N INTEGER 0 true [list \
35+
DISPLAY_NAME "Parallel prefix sum calculation" \
36+
ALLOWED_RANGES {"0:Serial" "1:Parallel"} \
37+
]
38+
3439
# defaults
3540

3641
proc util_cpack_elab {} {
@@ -68,4 +73,3 @@ proc util_cpack_elab {} {
6873
set_interface_property adc_ch_$n associatedReset ""
6974
}
7075
}
71-

library/util_pack/util_cpack2/util_cpack2_impl.v

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// ***************************************************************************
22
// ***************************************************************************
3-
// Copyright (C) 2018-2024 Analog Devices, Inc. All rights reserved.
3+
// Copyright (C) 2018-2025 Analog Devices, Inc. All rights reserved.
44
//
55
// In this HDL repository, there are many different and unique modules, consisting
66
// of various HDL (Verilog or VHDL) components. The individual modules are
@@ -38,7 +38,8 @@
3838
module util_cpack2_impl #(
3939
parameter NUM_OF_CHANNELS = 4,
4040
parameter SAMPLES_PER_CHANNEL = 1,
41-
parameter SAMPLE_DATA_WIDTH = 16
41+
parameter SAMPLE_DATA_WIDTH = 16,
42+
parameter PARALLEL_OR_SERIAL_N = 0
4243
) (
4344
input clk,
4445
input reset,
@@ -100,7 +101,8 @@ module util_cpack2_impl #(
100101
.NUM_OF_CHANNELS (NUM_OF_CHANNELS),
101102
.SAMPLES_PER_CHANNEL (SAMPLES_PER_CHANNEL),
102103
.SAMPLE_DATA_WIDTH (SAMPLE_DATA_WIDTH),
103-
.PACK (1)
104+
.PACK (1),
105+
.PARALLEL_OR_SERIAL_N (PARALLEL_OR_SERIAL_N)
104106
) i_pack_shell (
105107
.clk (clk),
106108
.reset (reset),

library/util_pack/util_cpack2/util_cpack2_ip.tcl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
## Copyright (C) 2018-2024 Analog Devices, Inc. All rights reserved.
2+
## Copyright (C) 2018-2025 Analog Devices, Inc. All rights reserved.
33
### SPDX short identifier: ADIBSD
44
###############################################################################
55

@@ -39,6 +39,7 @@ foreach {k v} { \
3939
"NUM_OF_CHANNELS" "Number of Channels" \
4040
"SAMPLES_PER_CHANNEL" "Samples per Channel" \
4141
"SAMPLE_DATA_WIDTH" "Sample Width" \
42+
"PARALLEL_OR_SERIAL_N" "Parallel prefix sum calculation" \
4243
} { \
4344
set p [ipgui::get_guiparamspec -name $k -component $cc]
4445
# ipgui::move_param -component $cc -order $i $p -parent $

library/util_pack/util_pack_common/pack_shell.v

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// ***************************************************************************
22
// ***************************************************************************
3-
// Copyright (C) 2017-2023 Analog Devices, Inc. All rights reserved.
3+
// Copyright (C) 2017-2023, 2025 Analog Devices, Inc. All rights reserved.
44
//
55
// In this HDL repository, there are many different and unique modules, consisting
66
// of various HDL (Verilog or VHDL) components. The individual modules are
@@ -39,7 +39,8 @@ module pack_shell #(
3939
parameter NUM_OF_CHANNELS = 4,
4040
parameter SAMPLES_PER_CHANNEL = 1,
4141
parameter SAMPLE_DATA_WIDTH = 16,
42-
parameter PACK = 0
42+
parameter PACK = 0,
43+
parameter PARALLEL_OR_SERIAL_N = 0
4344
) (
4445
input clk,
4546
input reset,
@@ -65,6 +66,7 @@ module pack_shell #(
6566

6667
localparam TOTAL_DATA_WIDTH = CHANNEL_DATA_WIDTH * NUM_OF_CHANNELS;
6768
localparam NUM_OF_SAMPLES = NUM_OF_CHANNELS * SAMPLES_PER_CHANNEL;
69+
localparam LOG2_NUM_OF_SAMPLES = $clog2(NUM_OF_SAMPLES);
6870

6971
/*
7072
* Reset and control signals for the state machine. Data and control have
@@ -189,6 +191,11 @@ module pack_shell #(
189191
*/
190192
wire [SAMPLE_ADDRESS_WIDTH-1:0] prefix_count_s[0:NUM_OF_SAMPLES];
191193

194+
/*
195+
* Used for the vectorized approach when PARALLEL_OR_SERIAL_N == 1
196+
*/
197+
wire [SAMPLE_ADDRESS_WIDTH-1:0] prefix_count_tmp[0:LOG2_NUM_OF_SAMPLES+1][0:NUM_OF_SAMPLES-1];
198+
192199
/*
193200
* Samples are interleaved, so the sample mask is just the channel mask
194201
* concatenated with itself SAMPLES_PER_CHANNEL times.
@@ -201,13 +208,50 @@ module pack_shell #(
201208
*/
202209
assign ce_ctrl = startup_ctrl | ce;
203210

211+
if (PARALLEL_OR_SERIAL_N == 1) begin
212+
/*
213+
* Calculate the prefix sum using a vectorized approach.
214+
* This way we should have at most log2(NUM_OF_SAMPLES)
215+
* adders in series for the rightmost element and even less
216+
* for the elements before it since we just propagate it to
217+
* the last row from where it was calculated.
218+
*/
219+
220+
/* Copy the samples_enable to the first row to make addressing it easier */
221+
genvar j;
222+
for (j = 0; j < NUM_OF_SAMPLES; j = j + 1) begin
223+
assign prefix_count_tmp[0][j] = ~samples_enable[j];
224+
end
225+
226+
/*
227+
* E.g: for samples_enable = '1 1 1 1 1 1 1 1':
228+
* prefix_count_tmp[0] = '1 1 1 1 1 1 1 1' (copy of samples_enable)
229+
* prefix_count_tmp[1] = '1 2 2 2 2 2 2 2'
230+
* prefix_count_tmp[2] = '1 2 3 4 4 4 4 4'
231+
* prefix_count_tmp[3] = '1 2 3 4 5 6 7 8'
232+
*/
233+
genvar k;
234+
for (j = 1; j < LOG2_NUM_OF_SAMPLES + 1; j = j + 1) begin
235+
for (k = 0; k < NUM_OF_SAMPLES; k = k + 1) begin
236+
if (k < 2 ** (j-1)) begin
237+
assign prefix_count_tmp[j][k] = prefix_count_tmp[j-1][k];
238+
end else begin
239+
assign prefix_count_tmp[j][k] = prefix_count_tmp[j-1][k] + prefix_count_tmp[j-1][k - 2 ** (j-1)];
240+
end
241+
end
242+
end
243+
end
244+
204245
/* First channel has no other channels before it */
205246
assign prefix_count_s[0] = 'h0;
206247

207248
genvar i;
208249
for (i = 0; i < NUM_OF_SAMPLES; i = i + 1) begin: gen_prefix_count
209-
assign prefix_count_s[i+1] = prefix_count_s[i] + (samples_enable[i] ? 1'b0 : 1'b1);
210-
250+
if (PARALLEL_OR_SERIAL_N == 1) begin
251+
assign prefix_count_s[i+1] = prefix_count_tmp[LOG2_NUM_OF_SAMPLES][i];
252+
end else begin
253+
assign prefix_count_s[i+1] = prefix_count_s[i] + (samples_enable[i] ? 1'b0 : 1'b1);
254+
end
211255
if (i < 2 || NUM_OF_CHANNELS <= 2) begin
212256
/* This will only be one bit, no need to register it */
213257
always @(prefix_count_s[i]) begin

library/util_pack/util_upack2/util_upack2.v

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// ***************************************************************************
22
// ***************************************************************************
3-
// Copyright (C) 2018-2023 Analog Devices, Inc. All rights reserved.
3+
// Copyright (C) 2018-2023, 2025 Analog Devices, Inc. All rights reserved.
44
//
55
// In this HDL repository, there are many different and unique modules, consisting
66
// of various HDL (Verilog or VHDL) components. The individual modules are
@@ -38,7 +38,8 @@
3838
module util_upack2 #(
3939
parameter NUM_OF_CHANNELS = 4,
4040
parameter SAMPLES_PER_CHANNEL = 1,
41-
parameter SAMPLE_DATA_WIDTH = 16
41+
parameter SAMPLE_DATA_WIDTH = 16,
42+
parameter PARALLEL_OR_SERIAL_N = 0
4243
) (
4344
input clk,
4445
input reset,
@@ -203,7 +204,8 @@ module util_upack2 #(
203204
util_upack2_impl #(
204205
.NUM_OF_CHANNELS(REAL_NUM_OF_CHANNELS),
205206
.SAMPLE_DATA_WIDTH(SAMPLE_DATA_WIDTH),
206-
.SAMPLES_PER_CHANNEL(SAMPLES_PER_CHANNEL)
207+
.SAMPLES_PER_CHANNEL(SAMPLES_PER_CHANNEL),
208+
.PARALLEL_OR_SERIAL_N (PARALLEL_OR_SERIAL_N)
207209
) i_upack (
208210
.clk (clk),
209211
.reset (reset),

library/util_pack/util_upack2/util_upack2_hw.tcl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
## Copyright (C) 2018-2023 Analog Devices, Inc. All rights reserved.
2+
## Copyright (C) 2018-2023, 2025 Analog Devices, Inc. All rights reserved.
33
### SPDX short identifier: ADIBSD
44
###############################################################################
55

@@ -35,6 +35,10 @@ ad_ip_parameter INTERFACE_TYPE INTEGER 0 false [list \
3535
ALLOWED_RANGES {"0:AXIS" "1:FIFO"} \
3636
]
3737

38+
ad_ip_parameter PARALLEL_OR_SERIAL_N INTEGER 0 true [list \
39+
DISPLAY_NAME "Parallel prefix sum calculation" \
40+
ALLOWED_RANGES {"0:Serial" "1:Parallel"} \
41+
]
3842

3943
# defaults
4044

@@ -91,4 +95,3 @@ proc util_upack_elab {} {
9195
set_interface_property dac_ch_${n} associatedReset ""
9296
}
9397
}
94-

library/util_pack/util_upack2/util_upack2_impl.v

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// ***************************************************************************
22
// ***************************************************************************
3-
// Copyright (C) 2018-2023 Analog Devices, Inc. All rights reserved.
3+
// Copyright (C) 2018-2023, 2025 Analog Devices, Inc. All rights reserved.
44
//
55
// In this HDL repository, there are many different and unique modules, consisting
66
// of various HDL (Verilog or VHDL) components. The individual modules are
@@ -38,7 +38,8 @@
3838
module util_upack2_impl #(
3939
parameter NUM_OF_CHANNELS = 4,
4040
parameter SAMPLES_PER_CHANNEL = 1,
41-
parameter SAMPLE_DATA_WIDTH = 16
41+
parameter SAMPLE_DATA_WIDTH = 16,
42+
parameter PARALLEL_OR_SERIAL_N = 0
4243
) (
4344
input clk,
4445
input reset,
@@ -92,7 +93,8 @@ module util_upack2_impl #(
9293
.NUM_OF_CHANNELS (NUM_OF_CHANNELS),
9394
.SAMPLES_PER_CHANNEL (SAMPLES_PER_CHANNEL),
9495
.SAMPLE_DATA_WIDTH (SAMPLE_DATA_WIDTH),
95-
.PACK (0)
96+
.PACK (0),
97+
.PARALLEL_OR_SERIAL_N (PARALLEL_OR_SERIAL_N)
9698
) i_pack_shell (
9799
.clk (clk),
98100
.reset (reset),

library/util_pack/util_upack2/util_upack2_ip.tcl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
## Copyright (C) 2018-2023 Analog Devices, Inc. All rights reserved.
2+
## Copyright (C) 2018-2023, 2025 Analog Devices, Inc. All rights reserved.
33
### SPDX short identifier: ADIBSD
44
###############################################################################
55

@@ -40,6 +40,7 @@ foreach {k v} { \
4040
"NUM_OF_CHANNELS" "Number of Channels" \
4141
"SAMPLES_PER_CHANNEL" "Samples per Channel" \
4242
"SAMPLE_DATA_WIDTH" "Sample Width" \
43+
"PARALLEL_OR_SERIAL_N" "Parallel prefix sum calculation" \
4344
} { \
4445
set p [ipgui::get_guiparamspec -name $k -component $cc]
4546
# ipgui::move_param -component $cc -order $i $p -parent $

0 commit comments

Comments
 (0)