Files

151 lines
8.1 KiB
Verilog

`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2019/11/18 23:18:07
// Design Name:
// Module Name: CNU_6din
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module CNU_6din
#(parameter WIDTH = 4'd8)
(//输入数据个数为10的行更新模块,包括符号更新
input clk,
input [WIDTH-1:0] din01_VN_RU, //变量节点信息输入
input [WIDTH-1:0] din02_VN_RU, //变量节点信息输入
input [WIDTH-1:0] din03_VN_RU, //变量节点信息输入
input [WIDTH-1:0] din04_VN_RU, //变量节点信息输入
input [WIDTH-1:0] din05_VN_RU, //变量节点信息输入
input [WIDTH-1:0] din06_VN_RU, //变量节点信息输入
output reg [WIDTH-1:0] dout01_RU=8'd0, //更新输出
output reg [WIDTH-1:0] dout02_RU=8'd0, //更新输出
output reg [WIDTH-1:0] dout03_RU=8'd0, //更新输出
output reg [WIDTH-1:0] dout04_RU=8'd0, //更新输出
output reg [WIDTH-1:0] dout05_RU=8'd0, //更新输出
output reg [WIDTH-1:0] dout06_RU=8'd0 //更新输出
); //输出相对输入延时9个clk
reg [WIDTH-1:0] abs01=8'd0,abs01_reg0=8'd0,abs01_reg1=8'd0,abs01_reg2=8'd0,min_level_1_01=8'd0;
reg [WIDTH-1:0] abs02=8'd0,abs02_reg0=8'd0,abs02_reg1=8'd0,abs02_reg2=8'd0,min_level_1_02=8'd0;
reg [WIDTH-1:0] abs03=8'd0,abs03_reg0=8'd0,abs03_reg1=8'd0,abs03_reg2=8'd0,min_level_1_03=8'd0;
reg [WIDTH-1:0] abs04=8'd0,abs04_reg0=8'd0,abs04_reg1=8'd0,abs04_reg2=8'd0,min_level_1_04=8'd0;
reg [WIDTH-1:0] abs05=8'd0,abs05_reg0=8'd0,abs05_reg1=8'd0,abs05_reg2=8'd0,min_level_1_05=8'd0;
reg [WIDTH-1:0] abs06=8'd0,abs06_reg0=8'd0,abs06_reg1=8'd0,abs06_reg2=8'd0,min_level_1_06=8'd0;
wire [WIDTH-1:0] min_level_2_01,min_level_2_02,min_level_3_01,min_level_3_02;
always @ (posedge clk) begin//求输入数据的绝对值过程
if(din01_VN_RU[WIDTH-1]) abs01 <= ~din01_VN_RU + 8'd1;else abs01 <= din01_VN_RU;
if(din02_VN_RU[WIDTH-1]) abs02 <= ~din02_VN_RU + 8'd1;else abs02 <= din02_VN_RU;
if(din03_VN_RU[WIDTH-1]) abs03 <= ~din03_VN_RU + 8'd1;else abs03 <= din03_VN_RU;
if(din04_VN_RU[WIDTH-1]) abs04 <= ~din04_VN_RU + 8'd1;else abs04 <= din04_VN_RU;
if(din05_VN_RU[WIDTH-1]) abs05 <= ~din05_VN_RU + 8'd1;else abs05 <= din05_VN_RU;
if(din06_VN_RU[WIDTH-1]) abs06 <= ~din06_VN_RU + 8'd1;else abs06 <= din06_VN_RU;
end
always @ (posedge clk) begin//对绝对值流水延时
abs01_reg0 <= abs01; abs01_reg1 <= abs01_reg0; abs01_reg2 <= abs01_reg1;
abs02_reg0 <= abs02; abs02_reg1 <= abs02_reg0; abs02_reg2 <= abs02_reg1;
abs03_reg0 <= abs03; abs03_reg1 <= abs03_reg0; abs03_reg2 <= abs03_reg1;
abs04_reg0 <= abs04; abs04_reg1 <= abs04_reg0; abs04_reg2 <= abs04_reg1;
abs05_reg0 <= abs05; abs05_reg1 <= abs05_reg0; abs05_reg2 <= abs05_reg1;
abs06_reg0 <= abs06; abs06_reg1 <= abs06_reg0; abs06_reg2 <= abs06_reg1;
end
reg [WIDTH-1:0] min_level_1_05_reg0=8'd0,min_level_1_06_reg0=8'd0;
always @ (posedge clk) begin
min_level_1_05_reg0 <= min_level_1_05;
min_level_1_06_reg0 <= min_level_1_06;
end
always @ (posedge clk) begin//第1级分类,两两一组将最小及次小值分开
min_level_1_01 <= (abs01<abs02) ? abs01 : abs02; min_level_1_02 <= (abs01<abs02) ? abs02 : abs01;
min_level_1_03 <= (abs03<abs04) ? abs03 : abs04; min_level_1_04 <= (abs03<abs04) ? abs04 : abs03;
min_level_1_05 <= (abs05<abs06) ? abs05 : abs06; min_level_1_06 <= (abs05<abs06) ? abs06 : abs05;
end
abs_min_4din #(.WIDTH(WIDTH))inst_4din_level_1_01 (.clk(clk),.din01(min_level_1_01),.din02(min_level_1_02),.din03(min_level_1_03),.din04(min_level_1_04),.dout_min(min_level_2_01),.dout_sec(min_level_2_02));
abs_min_4din #(.WIDTH(WIDTH))inst_4din_level_2_01 (.clk(clk),.din01(min_level_1_05_reg0),.din02(min_level_1_06_reg0),.din03(min_level_2_01),.din04(min_level_2_02),.dout_min(min_level_3_01),.dout_sec(min_level_3_02));
reg [WIDTH-1:0] abs01_update=8'd0;
reg [WIDTH-1:0] abs02_update=8'd0;
reg [WIDTH-1:0] abs03_update=8'd0;
reg [WIDTH-1:0] abs04_update=8'd0;
reg [WIDTH-1:0] abs05_update=8'd0;
reg [WIDTH-1:0] abs06_update=8'd0;
always @ (posedge clk) begin//各绝对值的最小值及次小值更新
abs01_update <= (abs01_reg2==min_level_3_01) ? min_level_3_02 : min_level_3_01;
abs02_update <= (abs02_reg2==min_level_3_01) ? min_level_3_02 : min_level_3_01;
abs03_update <= (abs03_reg2==min_level_3_01) ? min_level_3_02 : min_level_3_01;
abs04_update <= (abs04_reg2==min_level_3_01) ? min_level_3_02 : min_level_3_01;
abs05_update <= (abs05_reg2==min_level_3_01) ? min_level_3_02 : min_level_3_01;
abs06_update <= (abs06_reg2==min_level_3_01) ? min_level_3_02 : min_level_3_01;
end
wire [WIDTH-1:0] dout_abs_NF01;
wire [WIDTH-1:0] dout_abs_NF02;
wire [WIDTH-1:0] dout_abs_NF03;
wire [WIDTH-1:0] dout_abs_NF04;
wire [WIDTH-1:0] dout_abs_NF05;
wire [WIDTH-1:0] dout_abs_NF06;
//*****对更新后的非负数修正,系数为0.8125
Normalization_Factor_0_8125 #(.WIDTH(WIDTH)) NF01 (.clk(clk),.din_NF(abs01_update),.dout_NF(dout_abs_NF01));
Normalization_Factor_0_8125 #(.WIDTH(WIDTH)) NF02 (.clk(clk),.din_NF(abs02_update),.dout_NF(dout_abs_NF02));
Normalization_Factor_0_8125 #(.WIDTH(WIDTH)) NF03 (.clk(clk),.din_NF(abs03_update),.dout_NF(dout_abs_NF03));
Normalization_Factor_0_8125 #(.WIDTH(WIDTH)) NF04 (.clk(clk),.din_NF(abs04_update),.dout_NF(dout_abs_NF04));
Normalization_Factor_0_8125 #(.WIDTH(WIDTH)) NF05 (.clk(clk),.din_NF(abs05_update),.dout_NF(dout_abs_NF05));
Normalization_Factor_0_8125 #(.WIDTH(WIDTH)) NF06 (.clk(clk),.din_NF(abs06_update),.dout_NF(dout_abs_NF06));
reg [5:0] sgn=6'd0,sgn_reg0=6'd0,sgn_reg1=6'd0;
always @ (posedge clk) begin//求输入数据的符号位及其流水延时过程
sgn[5:0] <= {din01_VN_RU[WIDTH-1],din02_VN_RU[WIDTH-1],din03_VN_RU[WIDTH-1],din04_VN_RU[WIDTH-1],din05_VN_RU[WIDTH-1],din06_VN_RU[WIDTH-1]};
sgn_reg0 <= sgn;
sgn_reg1 <= sgn_reg0;
end
reg xor_level_1_01=1'd0,xor_level_1_02=1'd0,xor_level_2_01=1'd0;
always @ (posedge clk) begin//求所有符号位异或和的过程
xor_level_1_01 <= sgn[0] ^ sgn[1] ^ sgn[2];
xor_level_1_02 <= sgn[3] ^ sgn[4] ^ sgn[5];
xor_level_2_01 <= xor_level_1_01 ^ xor_level_1_02;
end
reg [5:0] sgn_update=6'd0,sgn_update_reg0=6'd0,sgn_update_reg1=6'd0,sgn_update_reg2=6'd0,sgn_update_reg3=6'd0;
always @ (posedge clk) begin //更新所有符号位及结果流水延时过程
sgn_update[5:0] <= sgn_reg1^{6{xor_level_2_01}};
sgn_update_reg0 <= sgn_update;
sgn_update_reg1 <= sgn_update_reg0;
sgn_update_reg2 <= sgn_update_reg1;
sgn_update_reg3 <= sgn_update_reg2;
end
always @ (posedge clk) begin //计算最终更新结果的过程(符号位+绝对值)
dout01_RU <= (sgn_update_reg3[5]) ? {sgn_update_reg3[5],~dout_abs_NF01[WIDTH-2:0]+8'd1} : {sgn_update_reg3[5],dout_abs_NF01[WIDTH-2:0]};
dout02_RU <= (sgn_update_reg3[4]) ? {sgn_update_reg3[4],~dout_abs_NF02[WIDTH-2:0]+8'd1} : {sgn_update_reg3[4],dout_abs_NF02[WIDTH-2:0]};
dout03_RU <= (sgn_update_reg3[3]) ? {sgn_update_reg3[3],~dout_abs_NF03[WIDTH-2:0]+8'd1} : {sgn_update_reg3[3],dout_abs_NF03[WIDTH-2:0]};
dout04_RU <= (sgn_update_reg3[2]) ? {sgn_update_reg3[2],~dout_abs_NF04[WIDTH-2:0]+8'd1} : {sgn_update_reg3[2],dout_abs_NF04[WIDTH-2:0]};
dout05_RU <= (sgn_update_reg3[1]) ? {sgn_update_reg3[1],~dout_abs_NF05[WIDTH-2:0]+8'd1} : {sgn_update_reg3[1],dout_abs_NF05[WIDTH-2:0]};
dout06_RU <= (sgn_update_reg3[0]) ? {sgn_update_reg3[0],~dout_abs_NF06[WIDTH-2:0]+8'd1} : {sgn_update_reg3[0],dout_abs_NF06[WIDTH-2:0]};
end
endmodule