108 lines
4.7 KiB
Verilog
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
|
|
|