Files

108 lines
4.7 KiB
Verilog

`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2019/11/18 23:18:07
// Design Name:
// Module Name: CNU_3din
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module CNU_3din
#(parameter WIDTH = 4'd8)(
input clk,
input [WIDTH-1:0] din01_VN_RU, //变量节点信息输入
input [WIDTH-1:0] din02_VN_RU, //变量节点信息输入
input [WIDTH-1:0] din03_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 //更新输出
);//输出相对输入延时9个clk
reg [WIDTH-1:0] abs01=8'd0,abs01_reg0=8'd0,abs01_reg1=8'd0;
reg [WIDTH-1:0] abs02=8'd0,abs02_reg0=8'd0,abs02_reg1=8'd0;
reg [WIDTH-1:0] abs03=8'd0,abs03_reg0=8'd0,abs03_reg1=8'd0;
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;
end
always @ (posedge clk) begin
abs01_reg0 <= abs01; abs01_reg1 <= abs01_reg0;
abs02_reg0 <= abs02; abs02_reg1 <= abs02_reg0;
abs03_reg0 <= abs03; abs03_reg1 <= abs03_reg0;
end
reg [WIDTH-1:0] min_level_1_01=8'd0,min_level_1_02=8'd0;
reg [WIDTH-1:0] min_level_2_01=8'd0,min_level_2_02=8'd0;
always @ (posedge clk) begin//第1级分类,两两一组将最小及次小值分开
min_level_1_01 <= (abs01 < abs02) ? abs01:abs02;
min_level_1_02 <= (abs01 < abs02) ? abs02:abs01;
end
always @ (posedge clk) begin
min_level_2_01 <= (abs03_reg0<min_level_1_01) ? abs03_reg0:min_level_1_01;
min_level_2_02 <= (abs03_reg0<min_level_1_01) ? min_level_1_01:((abs03_reg0<min_level_1_02)? abs03_reg0 : min_level_1_02);
end
reg [WIDTH-1:0] abs01_update=8'd0,abs02_update=8'd0,abs03_update=8'd0;
always @ (posedge clk) begin//各绝对值的最小值及次小值更新
abs01_update <= (abs01_reg1==min_level_2_01) ? min_level_2_02 : min_level_2_01;
abs02_update <= (abs02_reg1==min_level_2_01) ? min_level_2_02 : min_level_2_01;
abs03_update <= (abs03_reg1==min_level_2_01) ? min_level_2_02 : min_level_2_01;
end
wire [WIDTH-1:0] dout_abs_NF01,dout_abs_NF02,dout_abs_NF03;
//*****对更新后的非负数修正,系数为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));
reg [2:0] sgn=3'd0,sgn_reg0=3'd0;
always @ (posedge clk) begin//求输入数据的符号位及其流水延时过程
sgn[2:0] <= {din01_VN_RU[WIDTH-1],din02_VN_RU[WIDTH-1],din03_VN_RU[WIDTH-1]};
sgn_reg0 <= sgn;
end
reg xor_level_1_01=1'd0;
always @ (posedge clk) begin//求所有符号位异或和的过程
xor_level_1_01 <= sgn[0] ^ sgn[1] ^ sgn[2];
end
reg [2:0] sgn_update=3'd0,sgn_update_reg0=3'd0,sgn_update_reg1=3'd0,sgn_update_reg2=3'd0,sgn_update_reg3=3'd0;
always @ (posedge clk) begin //更新所有符号位及结果流水延时过程
sgn_update[2:0] <= sgn_reg0^{3{xor_level_1_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
reg [WIDTH-1:0] dout01_RU_temp=8'd0,dout02_RU_temp=8'd0,dout03_RU_temp=8'd0;
always @ (posedge clk) begin //计算最终更新结果的过程(符号位+绝对值)
dout01_RU_temp <= (sgn_update_reg3[2]) ? {sgn_update_reg3[2],~dout_abs_NF01[WIDTH-2:0]+8'd1} : {sgn_update_reg3[2],dout_abs_NF01[WIDTH-2:0]};
dout02_RU_temp <= (sgn_update_reg3[1]) ? {sgn_update_reg3[1],~dout_abs_NF02[WIDTH-2:0]+8'd1} : {sgn_update_reg3[1],dout_abs_NF02[WIDTH-2:0]};
dout03_RU_temp <= (sgn_update_reg3[0]) ? {sgn_update_reg3[0],~dout_abs_NF03[WIDTH-2:0]+8'd1} : {sgn_update_reg3[0],dout_abs_NF03[WIDTH-2:0]};
dout01_RU <= dout01_RU_temp;
dout02_RU <= dout02_RU_temp;
dout03_RU <= dout03_RU_temp;
end
endmodule