Skip to content

Commit 4682b7e

Browse files
committed
Added adder_tree module and testbench
1 parent 8936cd3 commit 4682b7e

File tree

2 files changed

+187
-0
lines changed

2 files changed

+187
-0
lines changed

adder_tree.sv

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//------------------------------------------------------------------------------
2+
// adder_tree.sv
3+
// Konstantin Pavlov, [email protected]
4+
//------------------------------------------------------------------------------
5+
6+
// INFO -------------------------------------------------------------------------
7+
// Pipelined tree adder with parametrized input width written in System Verilog
8+
//
9+
// - Number of inputs is NOT required to be power of two
10+
// - This code can generate entirely combinational circuit with minimal editing
11+
//
12+
13+
/* --- INSTANTIATION TEMPLATE BEGIN ---
14+
15+
adder_tree #(
16+
.INPUTS_NUM( 125 ),
17+
.IDATA_WIDTH( 16 )
18+
) AT1 (
19+
.clk( ),
20+
.nrst( ),
21+
.idata( ),
22+
.odata( )
23+
);
24+
25+
--- INSTANTIATION TEMPLATE END ---*/
26+
27+
28+
module adder_tree #(
29+
parameter INPUTS_NUM = 125,
30+
parameter IDATA_WIDTH = 16,
31+
32+
parameter STAGES_NUM = $clog2(INPUTS_NUM),
33+
parameter INPUTS_NUM_INT = 2 ** STAGES_NUM,
34+
parameter ODATA_WIDTH = IDATA_WIDTH + STAGES_NUM
35+
)(
36+
input clk,
37+
input nrst,
38+
input logic [INPUTS_NUM-1:0][IDATA_WIDTH-1:0] idata,
39+
output logic [ODATA_WIDTH-1:0] odata
40+
);
41+
42+
43+
logic [STAGES_NUM:0][INPUTS_NUM_INT-1:0][ODATA_WIDTH-1:0] data;
44+
45+
// generating tree
46+
genvar stage, adder;
47+
generate
48+
for( stage = 0; stage <= STAGES_NUM; stage++ ) begin: stage_gen
49+
50+
localparam ST_OUT_NUM = INPUTS_NUM_INT >> stage;
51+
localparam ST_WIDTH = IDATA_WIDTH + stage;
52+
53+
if( stage == '0 ) begin
54+
// stege 0 is actually module inputs
55+
for( adder = 0; adder < ST_OUT_NUM; adder++ ) begin: inputs_gen
56+
57+
always_comb begin
58+
if( adder < INPUTS_NUM ) begin
59+
data[stage][adder][ST_WIDTH-1:0] <= idata[adder][ST_WIDTH-1:0];
60+
data[stage][adder][ODATA_WIDTH-1:ST_WIDTH] <= '0;
61+
end else begin
62+
data[stage][adder][ODATA_WIDTH-1:0] <= '0;
63+
end
64+
end // always_comb
65+
66+
end // for
67+
end else begin
68+
// all other stages hold adders outputs
69+
for( adder = 0; adder < ST_OUT_NUM; adder++ ) begin: adder_gen
70+
71+
//always_comb begin // is also possible here
72+
always_ff@(posedge clk) begin
73+
if( ~nrst ) begin
74+
data[stage][adder][ODATA_WIDTH-1:0] <= '0;
75+
end else begin
76+
data[stage][adder][ST_WIDTH-1:0] <=
77+
data[stage-1][adder*2][(ST_WIDTH-1)-1:0] +
78+
data[stage-1][adder*2+1][(ST_WIDTH-1)-1:0];
79+
end
80+
end // always
81+
82+
end // for
83+
end // if stage
84+
end // for
85+
endgenerate
86+
87+
assign odata = data[STAGES_NUM][0];
88+
89+
endmodule
90+

adder_tree_tb.sv

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
// RXI - PIN400M
3+
// testbench for adder_tree.sv module
4+
5+
`timescale 1ns / 1ps
6+
7+
module adder_tree_tb();
8+
9+
logic clk200;
10+
initial begin
11+
#0 clk200 = 1'b0;
12+
forever
13+
#2.5 clk200 = ~clk200;
14+
end
15+
16+
logic rst;
17+
initial begin
18+
#0 rst = 1'b0;
19+
#10.2 rst = 1'b1;
20+
#5 rst = 1'b0;
21+
//#10000;
22+
forever begin
23+
#9985 rst = ~rst;
24+
#5 rst = ~rst;
25+
end
26+
end
27+
28+
logic nrst;
29+
assign nrst = ~rst;
30+
31+
logic rst_once;
32+
initial begin
33+
#0 rst_once = 1'b0;
34+
#10.2 rst_once = 1'b1;
35+
#5 rst_once = 1'b0;
36+
end
37+
38+
logic nrst_once;
39+
assign nrst_once = ~rst_once;
40+
41+
logic [31:0] DerivedClocks;
42+
clk_divider #(
43+
.WIDTH( 32 )
44+
) cd1 (
45+
.clk( clk200 ),
46+
.nrst( nrst_once ),
47+
.ena( 1'b1 ),
48+
.out( DerivedClocks[31:0] )
49+
);
50+
51+
logic [31:0] E_DerivedClocks;
52+
edge_detect ed1[31:0] (
53+
.clk( {32{clk200}} ),
54+
.nrst( {32{nrst_once}} ),
55+
.in( DerivedClocks[31:0] ),
56+
.rising( E_DerivedClocks[31:0] ),
57+
.falling( ),
58+
.both( )
59+
);
60+
61+
logic [15:0] RandomNumber1;
62+
c_rand rng1 (
63+
.clk( clk200 ),
64+
.rst( rst_once ),
65+
.reseed( 1'b0 ),
66+
.seed_val( DerivedClocks[31:0] ),
67+
.out( RandomNumber1[15:0] )
68+
);
69+
70+
logic start;
71+
initial begin
72+
#0 start = 1'b0;
73+
#100 start = 1'b1;
74+
#20 start = 1'b0;
75+
end
76+
77+
// Module under test ==========================================================
78+
79+
adder_tree #(
80+
.INPUTS_NUM( 7 ),
81+
.IDATA_WIDTH( 16 )
82+
) at (
83+
.clk( clk200 ),
84+
.nrst( nrst_once ),
85+
.idata( { 12'b0,RandomNumber1[7:0],
86+
12'b0,RandomNumber1[8:1],
87+
12'b0,RandomNumber1[9:2],
88+
12'b0,RandomNumber1[10:3],
89+
12'b0,RandomNumber1[11:4],
90+
12'b0,RandomNumber1[12:5],
91+
12'b0,RandomNumber1[13:6] } ),
92+
.odata( )
93+
);
94+
95+
96+
endmodule
97+

0 commit comments

Comments
 (0)