247 lines
6.2 KiB
Verilog
247 lines
6.2 KiB
Verilog
`timescale 1ns / 1ps
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Company:
|
|
// Engineer:
|
|
// _ _ ____
|
|
// | | ___ ___| |__ / ___| __ _ ___
|
|
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
|
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
|
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
|
//
|
|
// Create Date: 2022/11/13 16:05:53
|
|
// Design Name:
|
|
// Module Name: adder_tree_ppl
|
|
// Project Name:
|
|
// Target Devices:
|
|
// Tool Versions:
|
|
// Description:
|
|
//
|
|
// Dependencies:
|
|
//
|
|
// Revision:
|
|
// Revision 0.01 - File Created
|
|
// Additional Comments:
|
|
// REF: https://blog.csdn.net/jiang1960034308/article/details/118078073
|
|
// https://github.com/raiker/tarsier/tree/master/src/
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
module adder_tree_ppl
|
|
#(
|
|
parameter DATA_I_WIDTH = 8,
|
|
parameter DATA_NUM = 5,
|
|
parameter DELAY_STAGE = $clog2(DATA_NUM), // necessary for pipeline delay stage
|
|
|
|
localparam DATA_O_WIDTH = DATA_I_WIDTH + $clog2(DATA_NUM),
|
|
localparam DATA_NUM_A = DATA_NUM / 2,
|
|
localparam DATA_NUM_B = DATA_NUM - DATA_NUM_A,
|
|
localparam DATA_O_WIDTH_A = DATA_I_WIDTH + $clog2(DATA_NUM_A),
|
|
localparam DATA_O_WIDTH_B = DATA_I_WIDTH + $clog2(DATA_NUM_B)
|
|
)
|
|
(
|
|
// clock & reset
|
|
input clk,
|
|
input rst,
|
|
|
|
// input data
|
|
input din_valid,
|
|
input signed [DATA_NUM*DATA_I_WIDTH-1 : 0] din_data,
|
|
|
|
// output data
|
|
output dout_valid,
|
|
output signed [DATA_O_WIDTH-1 : 0] dout_data
|
|
);
|
|
|
|
if (DATA_NUM == 1) begin
|
|
if (DELAY_STAGE == 1) begin
|
|
// buffer when an extra delay stage is needed
|
|
reg dout_valid_buf = 'b0;
|
|
reg signed [DATA_O_WIDTH-1 : 0] dout_data_buf = 'b0;
|
|
|
|
always@(posedge clk) begin
|
|
dout_valid_buf <= (rst) ? 'b0 : din_valid;
|
|
dout_data_buf <= (rst) ? 'b0 : din_data;
|
|
end
|
|
|
|
assign dout_valid = dout_valid_buf;
|
|
assign dout_data = dout_data_buf;
|
|
end
|
|
else begin
|
|
assign dout_valid = din_valid;
|
|
assign dout_data = din_data;
|
|
end
|
|
end
|
|
else begin
|
|
reg dout_valid_buf = 'b0;
|
|
reg signed [DATA_O_WIDTH-1 : 0] dout_data_buf = 'b0;
|
|
|
|
wire din_valid_a;
|
|
wire din_valid_b;
|
|
wire signed [DATA_I_WIDTH * DATA_NUM_A - 1:0] din_data_a;
|
|
wire signed [DATA_I_WIDTH * DATA_NUM_B - 1:0] din_data_b;
|
|
|
|
wire dout_valid_a;
|
|
wire dout_valid_b;
|
|
wire signed [DATA_O_WIDTH_A-1:0] dout_data_a;
|
|
wire signed [DATA_O_WIDTH_B-1:0] dout_data_b;
|
|
|
|
assign din_valid_a = din_valid;
|
|
assign din_valid_b = din_valid;
|
|
assign din_data_a = din_data[DATA_I_WIDTH * DATA_NUM_A - 1: 0];
|
|
assign din_data_b = din_data[DATA_NUM * DATA_I_WIDTH - 1: DATA_I_WIDTH * DATA_NUM_A];
|
|
|
|
//divide set into two chunks, conquer
|
|
adder_tree_ppl #(
|
|
.DATA_I_WIDTH (DATA_I_WIDTH ),
|
|
.DATA_NUM (DATA_NUM_A ),
|
|
.DELAY_STAGE (DELAY_STAGE - 1)
|
|
) subtree_a (
|
|
// clock & reset
|
|
.clk (clk ),
|
|
.rst (rst ),
|
|
|
|
// input data
|
|
.din_valid (din_valid_a ),
|
|
.din_data (din_data_a ),
|
|
|
|
// output data
|
|
.dout_valid (dout_valid_a ),
|
|
.dout_data (dout_data_a )
|
|
);
|
|
|
|
adder_tree_ppl #(
|
|
.DATA_I_WIDTH (DATA_I_WIDTH ),
|
|
.DATA_NUM (DATA_NUM_B ),
|
|
.DELAY_STAGE (DELAY_STAGE - 1)
|
|
) subtree_b (
|
|
// clock & reset
|
|
.clk (clk ),
|
|
.rst (rst ),
|
|
|
|
// input data
|
|
.din_valid (din_valid_b ),
|
|
.din_data (din_data_b ),
|
|
|
|
// output data
|
|
.dout_valid (dout_valid_b ),
|
|
.dout_data (dout_data_b )
|
|
);
|
|
|
|
always@(posedge clk) begin
|
|
if (rst) begin
|
|
dout_valid_buf <= 'b0;
|
|
dout_data_buf <= 'b0;
|
|
end
|
|
else begin
|
|
dout_valid_buf <= dout_valid_a & dout_valid_b;
|
|
dout_data_buf <= dout_data_a + dout_data_b;
|
|
end
|
|
end
|
|
|
|
assign dout_valid = dout_valid_buf;
|
|
assign dout_data = dout_data_buf;
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Company:
|
|
// Engineer:
|
|
// _ _ ____
|
|
// | | ___ ___| |__ / ___| __ _ ___
|
|
// _ | |/ _ \/ __| '_ \ | | _ / _` |/ _ \
|
|
// | |_| | (_) \__ \ | | | | |_| | (_| | (_) |
|
|
// \___/ \___/|___/_| |_| \____|\__,_|\___/
|
|
//
|
|
// Create Date: 2022/11/13 16:40:15
|
|
// Last Modified Data: 2022/11/02
|
|
// Design Name:
|
|
// Module Name: tb_adder_tree_pip
|
|
// Project Name:
|
|
// Target Devices:
|
|
// Tool Versions:
|
|
// Description: testbench for [adder_tree_ppl]
|
|
//
|
|
// Dependencies:
|
|
//
|
|
// Revision:
|
|
// Revision 0.01 - File Created
|
|
// Additional Comments:
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// module tb_adder_tree_ppl;
|
|
|
|
// localparam DATA_I_WIDTH = 16;
|
|
// localparam DATA_NUM = 9;
|
|
|
|
// reg clk = 1'b1;
|
|
// reg rst = 1'b1;
|
|
// reg din_valid = 1'b0;
|
|
// reg [DATA_NUM*DATA_I_WIDTH-1 : 0] din_data = 'b0;
|
|
// wire dout_valid;
|
|
// wire [DATA_I_WIDTH+$clog2(DATA_NUM)-1 : 0] dout_data;
|
|
|
|
// adder_tree_ppl #(
|
|
// .DATA_I_WIDTH (DATA_I_WIDTH ),
|
|
// .DATA_NUM (DATA_NUM )
|
|
// ) u_adder_tree_ppl
|
|
// (
|
|
// // clock & reset
|
|
// .clk (clk ),
|
|
// .rst (rst ),
|
|
|
|
// // input data
|
|
// .din_valid (din_valid ),
|
|
// .din_data (din_data ),
|
|
|
|
// // output data
|
|
// .dout_valid (dout_valid ),
|
|
// .dout_data (dout_data )
|
|
// );
|
|
|
|
// initial begin
|
|
// #102
|
|
// rst = 1'b0;
|
|
// #200
|
|
// @(posedge clk) begin
|
|
// din_valid = 1'b1;
|
|
// din_data = {
|
|
// 16'd1,
|
|
// 16'd2,
|
|
// 16'd3,
|
|
// 16'd4,
|
|
// 16'd5,
|
|
// 16'd6,
|
|
// 16'd7,
|
|
// 16'd8,
|
|
// 16'd9
|
|
// };
|
|
// end
|
|
|
|
// @(posedge clk) begin
|
|
// din_valid = 1'b1;
|
|
// din_data = {
|
|
// 16'd1230,
|
|
// 16'd1231,
|
|
// 16'd1232,
|
|
// 16'd1233,
|
|
// 16'd1234,
|
|
// 16'd1235,
|
|
// 16'd1236,
|
|
// 16'd1237,
|
|
// 16'd1238
|
|
// };
|
|
// end
|
|
|
|
|
|
// @(posedge clk) din_valid = 1'b0;
|
|
// end
|
|
|
|
// always #5 clk = ~clk;
|
|
|
|
// endmodule
|