并行加法的Verilog实现 (二路归并)

  并行加法运算的Verilog实现,实现思路:二路归并

代码

/*
 * ADD_Parallel.v
 * create on: 2021.11.23
 * author: 今朝无言
 * function: 实现任意个数加数的并行加法
*/
//两两归并,延时达到(NN-1)*delay,为最优状态      bottom-up设计思路
module ADD_Parallel(
	datas_packed,
	sum
);
parameter dataWidth=16;
parameter N=8;
localparam NN=clogb2(N-1); //NN为N-1的位数

input [0:dataWidth*N-1]datas_packed;
output [dataWidth+NN-1:0]sum;

generate
	genvar i;
	
	//二路归并相加
	//Ns[i]=Ns[i-1]>>1+Ns[i-1]&1'b1
	//即Ns[i]=(N>>i)+|(N-(N>>i)<<i)    Ns[i]记录第i层加法的输出结果个数
	wire [0:(dataWidth+1)*(N%2==0?N/2:N/2+1)-1]sums[1:NN-1];
	ADD_Layer #(dataWidth,N) ADD_Layer_inst1(
			.datas_packed(datas_packed),.sums_packed(sums[1])); //第一层加法
	for(i=2;i<=NN-1;i=i+1)
	begin: add_Layer //后续各层加法
		ADD_Layer #(dataWidth+i-1,(N>>(i-1))+|(N-(N>>(i-1))<<(i-1))) ADD_Layer_inst(
				.datas_packed(sums[i-1][0:(dataWidth+i-1)*((N>>(i-1))+|(N-(N>>(i-1))<<(i-1)))-1]),
				.sums_packed(sums[i][0:(dataWidth+i)*((N>>i)+|(N-(N>>i)<<i))-1]));
	end
	assign sum=sums[NN-1][0:dataWidth+NN-2]+sums[NN-1][dataWidth+NN-1:2*(dataWidth+NN)-3];
endgenerate

//------------------------log2-----------------------------
function integer clogb2 (input integer depth);
begin
    for (clogb2=0; depth>0; clogb2=clogb2+1) 
        depth = depth >>1;                          
end
endfunction

endmodule

//********************任意数目的加数进行一层加法************************
module ADD_Layer(
datas_packed,
sums_packed
);
parameter dataWidth=16;
parameter N=4;

input [0:dataWidth*N-1]datas_packed;
output [0:(dataWidth+1)*(N%2==0?N/2:N/2+1)-1]sums_packed;

generate
	genvar i;
	
	//数据解包
	wire [dataWidth-1:0]datas_unpacked[1:N];
	for(i=1;i<=N;i=i+1)
	begin: unpack
		assign datas_unpacked[i]=datas_packed[(i-1)*dataWidth:i*dataWidth-1];
	end
	
	//两两相加
	wire [dataWidth:0]sum_arr[1:(N%2==0?N/2:N/2+1)]; //sum的位数为dataWidth+1
	for(i=1;i<=N/2;i=i+1)
	begin: sum_layer
		assign sum_arr[i]=datas_unpacked[2*i-1]+datas_unpacked[2*i];
	end
	if(N%2==1)begin
		assign sum_arr[N/2+1]=datas_unpacked[N];
	end
	
	//打包sum_arr
	for(i=1;i<=(N%2==0?N/2:N/2+1);i=i+1)
	begin: pack
		assign sums_packed[(i-1)*(dataWidth+1):i*(dataWidth+1)-1]=sum_arr[i];
	end
endgenerate

endmodule

testbench

/******************************FILE HEAD**********************************
 * file_name		: ADD_Parallel_tb.v
 * function			: ADD_Parallel模块的testbench
 * author			: 今朝无言
 * date				: 2021/11/23
 *************************************************************************/
`default_nettype none
`timescale 1ns/1ps

module ADD_Parallel_tb();

reg		[8*9-1:0]	datas_packed;
wire	[8+4-1:0]	sum;

ADD_Parallel #(
	.dataWidth	(8),
	.N			(9))
ADD_Parallel_inst(
	.datas_packed	(datas_packed),
	.sum			(sum)
);

initial begin
    datas_packed	<= {8'd1,8'd2,8'd3,8'd4,8'd5,8'd6,8'd7,8'd8,8'd9};//45
	#20;
	
    datas_packed	<= {8'd12,8'd2,8'd3,8'd4,8'd5,8'd6,8'd7,8'd8,8'd9};//56
	#20;
	
	$stop();
end

endmodule
//END OF ADD_Parallel_tb.v FILE***************************************************

仿真 & Netlist

时序仿真结果

在这里插入图片描述

Netlist(N=17,Width=16)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43557686/article/details/127119345
今日推荐