Files

938 lines
39 KiB
Verilog

`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2019/11/18 23:18:07
// Design Name:
// Module Name: VN_PRO
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module VN_PRO
#(
parameter MAX_ITER_NUM = 6'd14, //最大迭代次数
parameter WIDTH = 4'd8
)
(
input clk,
input rst_VN,
input start_VN, // VN更新启动脉冲
input start_frame_VN, // VN更新启动脉冲(新的1帧的开始)
input [WIDTH-1:0] CHNL_dout_01,//信道信息输入
input [WIDTH-1:0] CHNL_dout_02,
input [WIDTH-1:0] CHNL_dout_03,
input [WIDTH-1:0] CHNL_dout_04,
//校验节点信息输入,H阵第1行
input [WIDTH-1:0] CN1_dout_01_00,
input [WIDTH-1:0] CN1_dout_02_00, //后面的00代表H阵原模图的IM
input [WIDTH-1:0] CN1_dout_02_01, //后面的01代表H阵原模图的II1
input [WIDTH-1:0] CN2_dout_01_00,
input [WIDTH-1:0] CN2_dout_02_00,
input [WIDTH-1:0] CN2_dout_03_00,
input [WIDTH-1:0] CN2_dout_04_02, //后面的02代表H阵原模图的II2
input [WIDTH-1:0] CN2_dout_04_03, //后面的03代表H阵原模图的II3
input [WIDTH-1:0] CN2_dout_04_04, //后面的04代表H阵原模图的II4
//校验节点信息输入,H阵第3行
input [WIDTH-1:0] CN3_dout_01_00,
input [WIDTH-1:0] CN3_dout_02_05, //后面的05代表H阵原模图的II5
input [WIDTH-1:0] CN3_dout_02_06, //后面的06代表H阵原模图的II6
input [WIDTH-1:0] CN3_dout_03_07, //后面的07代表H阵原模图的II7
input [WIDTH-1:0] CN3_dout_03_08, //后面的08代表H阵原模图的II8
input [WIDTH-1:0] CN3_dout_04_00,
output ask_din, //向数据缓存区请求信道数据
//校验节点信息读地址,H阵第1行
output reg [8:0] CN1_addr_rd_01_00=9'd511,
output reg [9:0] CN1_addr_rd_02_00=10'd1023,
output reg [9:0] CN1_addr_rd_02_01=10'd511,
//校验节点信息读地址,H阵第2行
output reg [8:0] CN2_addr_rd_01_00=9'd511,
output reg [8:0] CN2_addr_rd_02_00=9'd511,
output reg [8:0] CN2_addr_rd_03_00=9'd511,
output reg [9:0] CN2_addr_rd_04_02=10'd1023,
output reg [9:0] CN2_addr_rd_04_03=10'd511,
output reg [8:0] CN2_addr_rd_04_04=9'd511,
//校验节点信息读地址,H阵第3行
output reg [8:0] CN3_addr_rd_01_00=9'd511,
output reg [9:0] CN3_addr_rd_02_05=10'd1023,
output reg [9:0] CN3_addr_rd_02_06=10'd511,
output reg [9:0] CN3_addr_rd_03_07=10'd1023,
output reg [9:0] CN3_addr_rd_03_08=10'd511,
output reg [8:0] CN3_addr_rd_04_00=9'd511,
//变量节点写使能
output reg [0:0] VN_wea=1'd0,
//变量节点写地址,H阵第1行
output reg [8:0] VN1_addr_wr_01_00=9'd511,
output reg [9:0] VN1_addr_wr_02_00=10'd1023,
output reg [9:0] VN1_addr_wr_02_01=10'd511,
//变量节点写地址,H阵第2行
output reg [8:0] VN2_addr_wr_01_00=9'd511,
output reg [8:0] VN2_addr_wr_02_00=9'd511,
output reg [8:0] VN2_addr_wr_03_00=9'd511,
output reg [9:0] VN2_addr_wr_04_02=10'd1023,
output reg [9:0] VN2_addr_wr_04_03=10'd511,
output reg [8:0] VN2_addr_wr_04_04=9'd511,
//变量节点写地址,H阵第3行
output reg [8:0] VN3_addr_wr_01_00=9'd511,
output reg [9:0] VN3_addr_wr_02_05=10'd1023,
output reg [9:0] VN3_addr_wr_02_06=10'd511,
output reg [9:0] VN3_addr_wr_03_07=10'd1023,
output reg [9:0] VN3_addr_wr_03_08=10'd511,
output reg [8:0] VN3_addr_wr_04_00=9'd511,
//变量节点写数据,H阵第1行
output reg [WIDTH-1:0] VN1_din_01_00=8'd0,
output reg [WIDTH-1:0] VN1_din_02_00=8'd0,
output reg [WIDTH-1:0] VN1_din_02_01=8'd0,
//变量节点写数据,H阵第2行
output reg [WIDTH-1:0] VN2_din_01_00=8'd0,
output reg [WIDTH-1:0] VN2_din_02_00=8'd0,
output reg [WIDTH-1:0] VN2_din_03_00=8'd0,
output reg [WIDTH-1:0] VN2_din_04_02=8'd0,
output reg [WIDTH-1:0] VN2_din_04_03=8'd0,
output reg [WIDTH-1:0] VN2_din_04_04=8'd0,
//变量节点写数据,H阵第3行
output reg [WIDTH-1:0] VN3_din_01_00=8'd0,
output reg [WIDTH-1:0] VN3_din_02_05=8'd0,
output reg [WIDTH-1:0] VN3_din_02_06=8'd0,
output reg [WIDTH-1:0] VN3_din_03_07=8'd0,
output reg [WIDTH-1:0] VN3_din_03_08=8'd0,
output reg [WIDTH-1:0] VN3_din_04_00=8'd0,
//判决结果写使能
output reg [0:0] DR_wea=8'd0,
//判决结果写地址
output reg [8:0] DR_addr_wr=9'd511,
output reg [0:0] DR_din_01=1'd0, //判决结果写数据
output reg [0:0] DR_din_02=1'd0,
output reg [0:0] DR_din_03=1'd0,
output reg [0:0] DR_din_04=1'd0,
output reg [0:0] DR_din_05=1'd0,
output data_start_ck_VN, //产生判决结果数据开始存储标志,高脉冲
output data_start_VN, //产生判决结果数据可以输出标志,高脉冲
output end_VN //模块结束标志,高脉冲
);
assign ask_din = (rst_VN) ? 1'd0 : ((start_VN) ? 1'd1:1'd0);
reg [5:0] iter_num = 6'd0;
// 迭代次数控制
always @ (posedge clk) begin
if (rst_VN || start_frame_VN) begin
iter_num <= 6'd0;
end else begin
if(end_VN)
if (iter_num < MAX_ITER_NUM)
iter_num <= iter_num + 6'd1;
else
iter_num <= iter_num;
else
iter_num <= iter_num;
end
end
reg [10:0] cnt_VN= 11'd0,cnt_2_VN= 11'd0;
reg flag_VN=1'd0;
// 产生该模块的计数基准
always @ (posedge clk) begin
if(rst_VN) begin
cnt_VN <= 11'd0;
cnt_2_VN <= 11'd0;
flag_VN <= 1'b0;
end else begin
if(start_VN) begin
flag_VN <= 1'b1;
cnt_VN <= 11'd0;
cnt_2_VN <= 11'd0;
end else begin
if(flag_VN) begin
if(cnt_VN<11'd560)begin
flag_VN <= flag_VN;
cnt_VN <= cnt_VN + 11'd1;
end else begin
cnt_VN <= cnt_VN;
flag_VN<= 1'b0;
end
if(cnt_2_VN<11'd560)begin
flag_VN <= flag_VN;
cnt_2_VN <= cnt_2_VN + 11'd1;
end else begin
cnt_2_VN <= cnt_2_VN;
flag_VN<= 1'b0;
end
end else begin
cnt_VN <= cnt_VN;
cnt_2_VN <= cnt_2_VN;
end
end
end
end
parameter DELAY_RD = 11'd3;
// 对所有IM进行CN地址操作
always @ (posedge clk) begin
if (rst_VN) begin
CN1_addr_rd_01_00 <= 9'd511;
CN1_addr_rd_02_00 <= 10'd1023;
CN2_addr_rd_01_00 <= 9'd511;
CN2_addr_rd_02_00 <= 9'd511;
CN2_addr_rd_03_00 <= 9'd511;
CN3_addr_rd_01_00 <= 9'd511;
CN3_addr_rd_04_00 <= 9'd511;
end else begin
if (cnt_VN >= 11'd1 + DELAY_RD && cnt_VN <= 11'd512 + DELAY_RD) begin
CN1_addr_rd_01_00 <= CN1_addr_rd_01_00 + 9'd1;
CN1_addr_rd_02_00 <= CN1_addr_rd_02_00 + 10'd1;
CN2_addr_rd_01_00 <= CN2_addr_rd_01_00 + 9'd1;
CN2_addr_rd_02_00 <= CN2_addr_rd_02_00 + 9'd1;
CN2_addr_rd_03_00 <= CN2_addr_rd_03_00 + 9'd1;
CN3_addr_rd_01_00 <= CN3_addr_rd_01_00 + 9'd1;
CN3_addr_rd_04_00 <= CN3_addr_rd_04_00 + 9'd1;
end else begin
CN1_addr_rd_01_00 <= 9'd511;
CN1_addr_rd_02_00 <= 10'd1023;
CN2_addr_rd_01_00 <= 9'd511;
CN2_addr_rd_02_00 <= 9'd511;
CN2_addr_rd_03_00 <= 9'd511;
CN3_addr_rd_01_00 <= 9'd511;
CN3_addr_rd_04_00 <= 9'd511;
end
end
end
reg first_flag_cn_01=1'd1,first_flag_cn_02=1'd1,first_flag_cn_03=1'd1,first_flag_cn_04=1'd1;
reg first_flag_cn_05=1'd1,first_flag_cn_06=1'd1,first_flag_cn_07=1'd1,first_flag_cn_08=1'd1;
reg first_flag_vn_01=1'd1,first_flag_vn_02=1'd1,first_flag_vn_03=1'd1,first_flag_vn_04=1'd1;
reg first_flag_vn_05=1'd1,first_flag_vn_06=1'd1,first_flag_vn_07=1'd1,first_flag_vn_08=1'd1;
// 对II1-II8进行CN地址操作
always @ (posedge clk) begin
if (rst_VN) begin
CN1_addr_rd_02_01 <= 10'd639;
CN2_addr_rd_04_02 <= 10'd24;
CN2_addr_rd_04_03 <= 10'd926;
CN2_addr_rd_04_04 <= 9'd294;
CN3_addr_rd_02_05 <= 10'd352;
CN3_addr_rd_02_06 <= 10'd639;
CN3_addr_rd_03_07 <= 10'd12;
CN3_addr_rd_03_08 <= 10'd929;
first_flag_cn_01 <= 1'd1;
first_flag_cn_02 <= 1'd1;
first_flag_cn_03 <= 1'd1;
first_flag_cn_04 <= 1'd1;
first_flag_cn_05 <= 1'd1;
first_flag_cn_06 <= 1'd1;
first_flag_cn_07 <= 1'd1;
first_flag_cn_08 <= 1'd1;
end else begin
if (cnt_VN >= 11'd1 + DELAY_RD && cnt_VN <= 11'd512 + DELAY_RD) begin
//对II1地址进行操作,确保初始化地址先加1
if (first_flag_cn_05) begin
CN1_addr_rd_02_01 <= CN1_addr_rd_02_01 + 10'd1;
first_flag_cn_05 <= 1'd0;
end else begin
if (CN1_addr_rd_02_01 == 10'd1023)
CN1_addr_rd_02_01 <= 10'd624;
else if (CN1_addr_rd_02_01 == 10'd639)
CN1_addr_rd_02_01 <= 10'd512;
else
CN1_addr_rd_02_01 <= CN1_addr_rd_02_01 + 10'd1;
end
// 对II2地址进行操作
if (first_flag_cn_06) begin
CN2_addr_rd_04_02 <= CN2_addr_rd_04_02 + 10'd1;
first_flag_cn_06<= 1'd0;
end else begin
if (CN2_addr_rd_04_02 == 10'd127)
CN2_addr_rd_04_02 <= 10'd0;
else if (CN2_addr_rd_04_02 == 10'd24)
CN2_addr_rd_04_02 <= 10'd203;
else if (CN2_addr_rd_04_02 == 10'd255)
CN2_addr_rd_04_02 <= 10'd128;
else if (CN2_addr_rd_04_02 == 10'd202)
CN2_addr_rd_04_02 <= 10'd376;
else if (CN2_addr_rd_04_02 == 10'd383)
CN2_addr_rd_04_02 <= 10'd256;
else if (CN2_addr_rd_04_02 == 10'd375)
CN2_addr_rd_04_02 <= 10'd477;
else if (CN2_addr_rd_04_02 == 10'd511)
CN2_addr_rd_04_02 <= 10'd384;
else
CN2_addr_rd_04_02 <= CN2_addr_rd_04_02 + 10'd1;
end
// 对II3地址进行操作
if (first_flag_cn_07) begin
CN2_addr_rd_04_03 <= CN2_addr_rd_04_03 + 10'd1;
first_flag_cn_07 <= 1'd0;
end else begin
if (CN2_addr_rd_04_03 == 10'd1023)
CN2_addr_rd_04_03 <= 10'd896;
else if (CN2_addr_rd_04_03 == 10'd926)
CN2_addr_rd_04_03 <= 10'd535;
else if (CN2_addr_rd_04_03 == 10'd639)
CN2_addr_rd_04_03 <= 10'd512;
else if (CN2_addr_rd_04_03 == 10'd534)
CN2_addr_rd_04_03 <= 10'd694;
else if (CN2_addr_rd_04_03 == 10'd767)
CN2_addr_rd_04_03 <= 10'd640;
else if (CN2_addr_rd_04_03 == 10'd693)
CN2_addr_rd_04_03 <= 10'd777;
else if (CN2_addr_rd_04_03 == 10'd895)
CN2_addr_rd_04_03 <= 10'd768;
else
CN2_addr_rd_04_03 <= CN2_addr_rd_04_03 + 10'd1;
end
// 对II4地址进行操作
if (first_flag_cn_08) begin
CN2_addr_rd_04_04 <= CN2_addr_rd_04_04 + 9'd1;
first_flag_cn_08 <= 1'd0;
end else begin
if (CN2_addr_rd_04_04 == 9'd383)
CN2_addr_rd_04_04 <= 9'd256;
else if (CN2_addr_rd_04_04 == 9'd294)
CN2_addr_rd_04_04 <= 9'd400;
else if (CN2_addr_rd_04_04 == 9'd511)
CN2_addr_rd_04_04 <= 9'd384;
else if (CN2_addr_rd_04_04 == 9'd399)
CN2_addr_rd_04_04 <= 9'd0;
else if (CN2_addr_rd_04_04 == 9'd127)
CN2_addr_rd_04_04 <= 9'd211;
else if (CN2_addr_rd_04_04 == 9'd255)
CN2_addr_rd_04_04 <= 9'd128;
else
CN2_addr_rd_04_04 <= CN2_addr_rd_04_04 + 9'd1;
end
// 对II5地址进行操作
if (first_flag_cn_01) begin //确保初始化地址先加1
CN3_addr_rd_02_05 <= CN3_addr_rd_02_05 + 10'd1;
first_flag_cn_01 <= 1'd0;
end else begin
if (CN3_addr_rd_02_05 == 10'd383)
CN3_addr_rd_02_05 <= 10'd256;
else if (CN3_addr_rd_02_05 == 10'd352)
CN3_addr_rd_02_05 <= 10'd448;
else if (CN3_addr_rd_02_05 == 10'd511)
CN3_addr_rd_02_05 <= 10'd384;
else if (CN3_addr_rd_02_05 == 10'd447)
CN3_addr_rd_02_05 <= 10'd78;
else if (CN3_addr_rd_02_05 == 10'd127)
CN3_addr_rd_02_05 <= 10'd0;
else if (CN3_addr_rd_02_05 == 10'd77)
CN3_addr_rd_02_05 <= 10'd209;
else if (CN3_addr_rd_02_05 == 10'd255)
CN3_addr_rd_02_05 <= 10'd128;
else
CN3_addr_rd_02_05 <= CN3_addr_rd_02_05 + 10'd1;
end
// 对II6地址进行操作
if (first_flag_cn_02) begin
CN3_addr_rd_02_06 <= CN3_addr_rd_02_06 + 10'd1;
first_flag_cn_02 <= 1'd0;
end else begin
if (CN3_addr_rd_02_06 == 10'd767)
CN3_addr_rd_02_06 <= 10'd774;
else if (CN3_addr_rd_02_06 == 10'd895)
CN3_addr_rd_02_06 <= 10'd768;
else if (CN3_addr_rd_02_06 == 10'd773)
CN3_addr_rd_02_06 <= 10'd931;
else if (CN3_addr_rd_02_06 == 10'd1023)
CN3_addr_rd_02_06 <= 10'd896;
else if (CN3_addr_rd_02_06 == 10'd930)
CN3_addr_rd_02_06 <= 10'd611;
else if (CN3_addr_rd_02_06 == 10'd639)
CN3_addr_rd_02_06 <= 10'd512;
else
CN3_addr_rd_02_06 <= CN3_addr_rd_02_06 + 10'd1;
end
// 对II7地址进行操作
if (first_flag_cn_03) begin //确保初始化地址先加1
CN3_addr_rd_03_07 <= CN3_addr_rd_03_07 + 10'd1;
first_flag_cn_03 <= 1'd0;
end else begin
if (CN3_addr_rd_03_07 == 10'd127)
CN3_addr_rd_03_07 <= 10'd0;
else if (CN3_addr_rd_03_07 == 10'd12)
CN3_addr_rd_03_07 <= 10'd197;
else if (CN3_addr_rd_03_07 == 10'd255)
CN3_addr_rd_03_07 <= 10'd128;
else if (CN3_addr_rd_03_07 == 10'd196)
CN3_addr_rd_03_07 <= 10'd383;
else if (CN3_addr_rd_03_07 == 10'd383)
CN3_addr_rd_03_07 <= 10'd256;
else if (CN3_addr_rd_03_07 == 10'd382)
CN3_addr_rd_03_07 <= 10'd413;
else if (CN3_addr_rd_03_07 == 10'd511)
CN3_addr_rd_03_07 <= 10'd384;
else
CN3_addr_rd_03_07 <= CN3_addr_rd_03_07 + 10'd1;
end
// 对II8地址进行操作
if (first_flag_cn_04) begin
CN3_addr_rd_03_08 <= CN3_addr_rd_03_08 + 10'd1;
first_flag_cn_04 <= 1'd0;
end else begin
if (CN3_addr_rd_03_08 == 10'd1023)
CN3_addr_rd_03_08 <= 10'd896;
else if (CN3_addr_rd_03_08 == 10'd929)
CN3_addr_rd_03_08 <= 10'd610;
else if (CN3_addr_rd_03_08 == 10'd639)
CN3_addr_rd_03_08 <= 10'd512;
else if (CN3_addr_rd_03_08 == 10'd609)
CN3_addr_rd_03_08 <= 10'd666;
else if (CN3_addr_rd_03_08 == 10'd767)
CN3_addr_rd_03_08 <= 10'd640;
else if (CN3_addr_rd_03_08 == 10'd665)
CN3_addr_rd_03_08 <= 10'd827;
else if (CN3_addr_rd_03_08 == 10'd895)
CN3_addr_rd_03_08 <= 10'd768;
else
CN3_addr_rd_03_08 <= CN3_addr_rd_03_08 + 10'd1;
end
end else begin
CN1_addr_rd_02_01 <= 10'd639;
CN2_addr_rd_04_02 <= 10'd24;
CN2_addr_rd_04_03 <= 10'd926;
CN2_addr_rd_04_04 <= 9'd294;
CN3_addr_rd_02_05 <= 10'd352;
CN3_addr_rd_02_06 <= 10'd639;
CN3_addr_rd_03_07 <= 10'd12;
CN3_addr_rd_03_08 <= 10'd929;
first_flag_cn_01 <= 1'd1;
first_flag_cn_02 <= 1'd1;
first_flag_cn_03 <= 1'd1;
first_flag_cn_04 <= 1'd1;
first_flag_cn_05 <= 1'd1;
first_flag_cn_06 <= 1'd1;
first_flag_cn_07 <= 1'd1;
first_flag_cn_08 <= 1'd1;
end
end
end
wire [WIDTH-1:0] din01_CN_CU01; //第1列更新处理单元信号定义
wire [WIDTH-1:0] din02_CN_CU01;
wire [WIDTH-1:0] din03_CHNL_CU01;
wire [WIDTH-1:0] dout01_CU01;
wire [WIDTH-1:0] dout02_CU01;
wire [0:0] dout03_result_CU01;
wire [WIDTH-1:0] din01_CN_CU02; //第2列更新处理单元信号定义
wire [WIDTH-1:0] din02_CN_CU02;
wire [WIDTH-1:0] din03_CN_CU02;
wire [WIDTH-1:0] din04_CHNL_CU02;
wire [WIDTH-1:0] dout01_CU02;
wire [WIDTH-1:0] dout02_CU02;
wire [WIDTH-1:0] dout03_CU02;
wire [0:0] dout04_result_CU02;
wire [WIDTH-1:0] din01_CN_CU03; //第3列更新处理单元信号定义
wire [WIDTH-1:0] din02_CHNL_CU03;
wire [WIDTH-1:0] dout01_CU03;
wire [0:0] dout02_result_CU03;
wire [WIDTH-1:0] din01_CN_CU04; //第4列更新处理单元信号定义
wire [WIDTH-1:0] din02_CN_CU04;
wire [WIDTH-1:0] din03_CN_CU04;
wire [WIDTH-1:0] din04_CHNL_CU04;
wire [WIDTH-1:0] dout01_CU04;
wire [WIDTH-1:0] dout02_CU04;
wire [WIDTH-1:0] dout03_CU04;
wire [0:0] dout04_result_CU04;
wire [WIDTH-1:0] din01_CN_CU05; //第5列更新处理单元信号定义
wire [WIDTH-1:0] din02_CN_CU05;
wire [WIDTH-1:0] din03_CN_CU05;
wire [WIDTH-1:0] din04_CN_CU05;
wire [WIDTH-1:0] din05_CN_CU05;
wire [WIDTH-1:0] din06_CN_CU05;
wire [WIDTH-1:0] din07_CHNL_CU05;
wire [WIDTH-1:0] dout01_CU05;
wire [WIDTH-1:0] dout02_CU05;
wire [WIDTH-1:0] dout03_CU05;
wire [WIDTH-1:0] dout04_CU05;
wire [WIDTH-1:0] dout05_CU05;
wire [WIDTH-1:0] dout06_CU05;
wire [0:0] dout07_result_CU05;
// CU模块的输入
assign din01_CN_CU01 = (iter_num == 6'd0) ? 8'd0 : CN2_dout_01_00;
assign din02_CN_CU01 = (iter_num == 6'd0) ? 8'd0 : CN3_dout_01_00;
assign din01_CN_CU02 = (iter_num == 6'd0) ? 8'd0 : CN2_dout_02_00;
assign din02_CN_CU02 = (iter_num == 6'd0) ? 8'd0 : CN3_dout_02_05;
assign din03_CN_CU02 = (iter_num == 6'd0) ? 8'd0 : CN3_dout_02_06;
assign din01_CN_CU03 = (iter_num == 6'd0) ? 8'd0 : CN1_dout_01_00;
assign din01_CN_CU04 = (iter_num == 6'd0) ? 8'd0 : CN2_dout_03_00;
assign din02_CN_CU04 = (iter_num == 6'd0) ? 8'd0 : CN3_dout_03_07;
assign din03_CN_CU04 = (iter_num == 6'd0) ? 8'd0 : CN3_dout_03_08;
assign din01_CN_CU05 = (iter_num == 6'd0) ? 8'd0 : CN1_dout_02_00;
assign din02_CN_CU05 = (iter_num == 6'd0) ? 8'd0 : CN1_dout_02_01;
assign din03_CN_CU05 = (iter_num == 6'd0) ? 8'd0 : CN2_dout_04_02;
assign din04_CN_CU05 = (iter_num == 6'd0) ? 8'd0 : CN2_dout_04_03;
assign din05_CN_CU05 = (iter_num == 6'd0) ? 8'd0 : CN2_dout_04_04;
assign din06_CN_CU05 = (iter_num == 6'd0) ? 8'd0 : CN3_dout_04_00;
assign din03_CHNL_CU01 = CHNL_dout_01;
assign din04_CHNL_CU02 = CHNL_dout_02;
assign din02_CHNL_CU03 = CHNL_dout_03;
assign din04_CHNL_CU04 = CHNL_dout_04;
assign din07_CHNL_CU05 = 8'd0; //信道传输的数据只有2048bit,这里H矩阵是2560bit,所以在后512位上补0
VNU_2din CU_01 (
.clk(clk),
.din01_CN_CU(din01_CN_CU01),
.din02_CN_CU(din02_CN_CU01),
.din03_CHNL_CU(din03_CHNL_CU01),
.dout01_CU(dout01_CU01),
.dout02_CU(dout02_CU01),
.dout03_result_CU(dout03_result_CU01));
VNU_3din CU_02 (
.clk(clk),
.din01_CN_CU(din01_CN_CU02),
.din02_CN_CU(din02_CN_CU02),
.din03_CN_CU(din03_CN_CU02),
.din04_CHNL_CU(din04_CHNL_CU02),
.dout01_CU(dout01_CU02),
.dout02_CU(dout02_CU02),
.dout03_CU(dout03_CU02),
.dout04_result_CU(dout04_result_CU02)
);
VNU_1din CU_03 (.clk(clk),
.din01_CN_CU(din01_CN_CU03),
.din02_CHNL_CU(din02_CHNL_CU03),
.dout01_CU(dout01_CU03),
.dout02_result_CU(dout02_result_CU03));
VNU_3din CU_04 (
.clk(clk),
.din01_CN_CU(din01_CN_CU04),
.din02_CN_CU(din02_CN_CU04),
.din03_CN_CU(din03_CN_CU04),
.din04_CHNL_CU(din04_CHNL_CU04),
.dout01_CU(dout01_CU04),
.dout02_CU(dout02_CU04),
.dout03_CU(dout03_CU04),
.dout04_result_CU(dout04_result_CU04)
);
VNU_6din CU_05 (
.clk(clk),
.din01_CN_CU(din01_CN_CU05),
.din02_CN_CU(din02_CN_CU05),
.din03_CN_CU(din03_CN_CU05),
.din04_CN_CU(din04_CN_CU05),
.din05_CN_CU(din05_CN_CU05),
.din06_CN_CU(din06_CN_CU05),
.din07_CHNL_CU(din07_CHNL_CU05),
.dout01_CU(dout01_CU05),
.dout02_CU(dout02_CU05),
.dout03_CU(dout03_CU05),
.dout04_CU(dout04_CU05),
.dout05_CU(dout05_CU05),
.dout06_CU(dout06_CU05),
.dout07_result_CU(dout07_result_CU05)
);
// 设置写操作的时延
parameter DELAY_WR = 11'd17;
// 控制VN的写使能
always @ (posedge clk) begin
if(rst_VN) begin
VN_wea <= 1'd0;
end else begin
if (cnt_2_VN >= 11'd1 + DELAY_WR && cnt_2_VN <= 11'd512 + DELAY_WR)
VN_wea <= 1'd1;
else
VN_wea <= 1'd0;
end
end
// 控制VN存储的写地址(所有IM)
always @ (posedge clk) begin
if (rst_VN) begin
VN1_addr_wr_01_00 <= 9'd511;
VN1_addr_wr_02_00 <= 10'd1023;
VN2_addr_wr_01_00 <= 9'd511;
VN2_addr_wr_02_00 <= 9'd511;
VN2_addr_wr_03_00 <= 9'd511;
VN3_addr_wr_01_00 <= 9'd511;
VN3_addr_wr_04_00 <= 9'd511;
end else begin
if (cnt_2_VN >= 11'd1 + DELAY_WR && cnt_2_VN <= 11'd512 + DELAY_WR) begin
VN1_addr_wr_01_00 <= VN1_addr_wr_01_00 + 9'd1;
VN1_addr_wr_02_00 <= VN1_addr_wr_02_00 + 10'd1;
VN2_addr_wr_01_00 <= VN2_addr_wr_01_00 + 9'd1;
VN2_addr_wr_02_00 <= VN2_addr_wr_02_00 + 9'd1;
VN2_addr_wr_03_00 <= VN2_addr_wr_03_00 + 9'd1;
VN3_addr_wr_01_00 <= VN3_addr_wr_01_00 + 9'd1;
VN3_addr_wr_04_00 <= VN3_addr_wr_04_00 + 9'd1;
end else begin
VN1_addr_wr_01_00 <= 9'd511;
VN1_addr_wr_02_00 <= 10'd1023;
VN2_addr_wr_01_00 <= 9'd511;
VN2_addr_wr_02_00 <= 9'd511;
VN2_addr_wr_03_00 <= 9'd511;
VN3_addr_wr_01_00 <= 9'd511;
VN3_addr_wr_04_00 <= 9'd511;
end
end
end
// 控制VN存储的写地址(II1-II8)
always @ (posedge clk) begin
if (rst_VN) begin
VN1_addr_wr_02_01 <= 10'd639;
VN2_addr_wr_04_02 <= 10'd24;
VN2_addr_wr_04_03 <= 10'd926;
VN2_addr_wr_04_04 <= 9'd294;
VN3_addr_wr_02_05 <= 10'd352;
VN3_addr_wr_02_06 <= 10'd639;
VN3_addr_wr_03_07 <= 10'd12;
VN3_addr_wr_03_08 <= 10'd929;
first_flag_vn_01 <= 1'd1;
first_flag_vn_02 <= 1'd1;
first_flag_vn_03 <= 1'd1;
first_flag_vn_04 <= 1'd1;
first_flag_vn_05 <= 1'd1;
first_flag_vn_06 <= 1'd1;
first_flag_vn_07 <= 1'd1;
first_flag_vn_08 <= 1'd1;
end else begin
if (cnt_2_VN >= 11'd1 + DELAY_WR && cnt_2_VN <= 11'd512 + DELAY_WR) begin
//对II1地址进行操作,确保初始化地址先加1
if (first_flag_vn_05) begin
VN1_addr_wr_02_01 <= VN1_addr_wr_02_01 + 10'd1;
first_flag_vn_05 <= 1'd0;
end else begin
if (VN1_addr_wr_02_01 == 10'd1023)
VN1_addr_wr_02_01 <= 10'd624;
else if (VN1_addr_wr_02_01 == 10'd639)
VN1_addr_wr_02_01 <= 10'd512;
else
VN1_addr_wr_02_01 <= VN1_addr_wr_02_01 + 10'd1;
end
// 对II2地址进行操作
if (first_flag_vn_06) begin
VN2_addr_wr_04_02 <= VN2_addr_wr_04_02 + 10'd1;
first_flag_vn_06<= 1'd0;
end else begin
if (VN2_addr_wr_04_02 == 10'd127)
VN2_addr_wr_04_02 <= 10'd0;
else if (VN2_addr_wr_04_02 == 10'd24)
VN2_addr_wr_04_02 <= 10'd203;
else if (VN2_addr_wr_04_02 == 10'd255)
VN2_addr_wr_04_02 <= 10'd128;
else if (VN2_addr_wr_04_02 == 10'd202)
VN2_addr_wr_04_02 <= 10'd376;
else if (VN2_addr_wr_04_02 == 10'd383)
VN2_addr_wr_04_02 <= 10'd256;
else if (VN2_addr_wr_04_02 == 10'd375)
VN2_addr_wr_04_02 <= 10'd477;
else if (VN2_addr_wr_04_02 == 10'd511)
VN2_addr_wr_04_02 <= 10'd384;
else
VN2_addr_wr_04_02 <= VN2_addr_wr_04_02 + 10'd1;
end
// 对II3地址进行操作
if (first_flag_vn_07) begin
VN2_addr_wr_04_03 <= VN2_addr_wr_04_03 + 10'd1;
first_flag_vn_07 <= 1'd0;
end else begin
if (VN2_addr_wr_04_03 == 10'd1023)
VN2_addr_wr_04_03 <= 10'd896;
else if (VN2_addr_wr_04_03 == 10'd926)
VN2_addr_wr_04_03 <= 10'd535;
else if (VN2_addr_wr_04_03 == 10'd639)
VN2_addr_wr_04_03 <= 10'd512;
else if (VN2_addr_wr_04_03 == 10'd534)
VN2_addr_wr_04_03 <= 10'd694;
else if (VN2_addr_wr_04_03 == 10'd767)
VN2_addr_wr_04_03 <= 10'd640;
else if (VN2_addr_wr_04_03 == 10'd693)
VN2_addr_wr_04_03 <= 10'd777;
else if (VN2_addr_wr_04_03 == 10'd895)
VN2_addr_wr_04_03 <= 10'd768;
else
VN2_addr_wr_04_03 <= VN2_addr_wr_04_03 + 10'd1;
end
// 对II4地址进行操作
if (first_flag_vn_08) begin
VN2_addr_wr_04_04 <= VN2_addr_wr_04_04 + 9'd1;
first_flag_vn_08 <= 1'd0;
end else begin
if (VN2_addr_wr_04_04 == 9'd383)
VN2_addr_wr_04_04 <= 9'd256;
else if (VN2_addr_wr_04_04 == 9'd294)
VN2_addr_wr_04_04 <= 9'd400;
else if (VN2_addr_wr_04_04 == 9'd511)
VN2_addr_wr_04_04 <= 9'd384;
else if (VN2_addr_wr_04_04 == 9'd399)
VN2_addr_wr_04_04 <= 9'd0;
else if (VN2_addr_wr_04_04 == 9'd127)
VN2_addr_wr_04_04 <= 9'd211;
else if (VN2_addr_wr_04_04 == 9'd255)
VN2_addr_wr_04_04 <= 9'd128;
else
VN2_addr_wr_04_04 <= VN2_addr_wr_04_04 + 9'd1;
end
// 对II5地址进行操作
if (first_flag_vn_01) begin //确保初始化地址先加1
VN3_addr_wr_02_05 <= VN3_addr_wr_02_05 + 10'd1;
first_flag_vn_01 <= 1'd0;
end else begin
if (VN3_addr_wr_02_05 == 10'd383)
VN3_addr_wr_02_05 <= 10'd256;
else if (VN3_addr_wr_02_05 == 10'd352)
VN3_addr_wr_02_05 <= 10'd448;
else if (VN3_addr_wr_02_05 == 10'd511)
VN3_addr_wr_02_05 <= 10'd384;
else if (VN3_addr_wr_02_05 == 10'd447)
VN3_addr_wr_02_05 <= 10'd78;
else if (VN3_addr_wr_02_05 == 10'd127)
VN3_addr_wr_02_05 <= 10'd0;
else if (VN3_addr_wr_02_05 == 10'd77)
VN3_addr_wr_02_05 <= 10'd209;
else if (VN3_addr_wr_02_05 == 10'd255)
VN3_addr_wr_02_05 <= 10'd128;
else
VN3_addr_wr_02_05 <= VN3_addr_wr_02_05 + 10'd1;
end
// 对II6地址进行操作
if (first_flag_vn_02) begin
VN3_addr_wr_02_06 <= VN3_addr_wr_02_06 + 10'd1;
first_flag_vn_02 <= 1'd0;
end else begin
if (VN3_addr_wr_02_06 == 10'd767)
VN3_addr_wr_02_06 <= 10'd774;
else if (VN3_addr_wr_02_06 == 10'd895)
VN3_addr_wr_02_06 <= 10'd768;
else if (VN3_addr_wr_02_06 == 10'd773)
VN3_addr_wr_02_06 <= 10'd931;
else if (VN3_addr_wr_02_06 == 10'd1023)
VN3_addr_wr_02_06 <= 10'd896;
else if (VN3_addr_wr_02_06 == 10'd930)
VN3_addr_wr_02_06 <= 10'd611;
else if (VN3_addr_wr_02_06 == 10'd639)
VN3_addr_wr_02_06 <= 10'd512;
else
VN3_addr_wr_02_06 <= VN3_addr_wr_02_06 + 10'd1;
end
// 对II7地址进行操作
if (first_flag_vn_03) begin //确保初始化地址先加1
VN3_addr_wr_03_07 <= VN3_addr_wr_03_07 + 10'd1;
first_flag_vn_03 <= 1'd0;
end else begin
if (VN3_addr_wr_03_07 == 10'd127)
VN3_addr_wr_03_07 <= 10'd0;
else if (VN3_addr_wr_03_07 == 10'd12)
VN3_addr_wr_03_07 <= 10'd197;
else if (VN3_addr_wr_03_07 == 10'd255)
VN3_addr_wr_03_07 <= 10'd128;
else if (VN3_addr_wr_03_07 == 10'd196)
VN3_addr_wr_03_07 <= 10'd383;
else if (VN3_addr_wr_03_07 == 10'd383)
VN3_addr_wr_03_07 <= 10'd256;
else if (VN3_addr_wr_03_07 == 10'd382)
VN3_addr_wr_03_07 <= 10'd413;
else if (VN3_addr_wr_03_07 == 10'd511)
VN3_addr_wr_03_07 <= 10'd384;
else
VN3_addr_wr_03_07 <= VN3_addr_wr_03_07 + 10'd1;
end
// 对II8地址进行操作
if (first_flag_vn_04) begin
VN3_addr_wr_03_08 <= VN3_addr_wr_03_08 + 10'd1;
first_flag_vn_04 <= 1'd0;
end else begin
if (VN3_addr_wr_03_08 == 10'd1023)
VN3_addr_wr_03_08 <= 10'd896;
else if (VN3_addr_wr_03_08 == 10'd929)
VN3_addr_wr_03_08 <= 10'd610;
else if (VN3_addr_wr_03_08 == 10'd639)
VN3_addr_wr_03_08 <= 10'd512;
else if (VN3_addr_wr_03_08 == 10'd609)
VN3_addr_wr_03_08 <= 10'd666;
else if (VN3_addr_wr_03_08 == 10'd767)
VN3_addr_wr_03_08 <= 10'd640;
else if (VN3_addr_wr_03_08 == 10'd665)
VN3_addr_wr_03_08 <= 10'd827;
else if (VN3_addr_wr_03_08 == 10'd895)
VN3_addr_wr_03_08 <= 10'd768;
else
VN3_addr_wr_03_08 <= VN3_addr_wr_03_08 + 10'd1;
end
end else begin
VN1_addr_wr_02_01 <= 10'd639;
VN2_addr_wr_04_02 <= 10'd24;
VN2_addr_wr_04_03 <= 10'd926;
VN2_addr_wr_04_04 <= 9'd294;
VN3_addr_wr_02_05 <= 10'd352;
VN3_addr_wr_02_06 <= 10'd639;
VN3_addr_wr_03_07 <= 10'd12;
VN3_addr_wr_03_08 <= 10'd929;
first_flag_vn_01 <= 1'd1;
first_flag_vn_02 <= 1'd1;
first_flag_vn_03 <= 1'd1;
first_flag_vn_04 <= 1'd1;
first_flag_vn_05 <= 1'd1;
first_flag_vn_06 <= 1'd1;
first_flag_vn_07 <= 1'd1;
first_flag_vn_08 <= 1'd1;
end
end
end
// 控制VN的写数据
always @ (posedge clk) begin
if (rst_VN) begin
VN1_din_01_00 <= 8'd0;
VN1_din_02_00 <= 8'd0;
VN2_din_01_00 <= 8'd0;
VN2_din_02_00 <= 8'd0;
VN2_din_03_00 <= 8'd0;
VN3_din_01_00 <= 8'd0;
VN3_din_04_00 <= 8'd0;
VN1_din_02_01 <= 8'd0;
VN2_din_04_02 <= 8'd0;
VN2_din_04_03 <= 8'd0;
VN2_din_04_04 <= 8'd0;
VN3_din_02_05 <= 8'd0;
VN3_din_02_06 <= 8'd0;
VN3_din_03_07 <= 8'd0;
VN3_din_03_08 <= 8'd0;
end else begin
if (cnt_2_VN >= 11'd1 + DELAY_WR && cnt_2_VN <= 11'd512 + DELAY_WR) begin
VN1_din_01_00 <= dout01_CU03;
VN1_din_02_00 <= dout01_CU05;
VN2_din_01_00 <= dout01_CU01;
VN2_din_02_00 <= dout01_CU02;
VN2_din_03_00 <= dout01_CU04;
VN3_din_01_00 <= dout02_CU01;
VN3_din_04_00 <= dout06_CU05;
VN1_din_02_01 <= dout02_CU05;
VN2_din_04_02 <= dout03_CU05;
VN2_din_04_03 <= dout04_CU05;
VN2_din_04_04 <= dout05_CU05;
VN3_din_02_05 <= dout02_CU02;
VN3_din_02_06 <= dout03_CU02;
VN3_din_03_07 <= dout02_CU04;
VN3_din_03_08 <= dout03_CU04;
end else begin
VN1_din_01_00 <= 8'd0;
VN1_din_02_00 <= 8'd0;
VN2_din_01_00 <= 8'd0;
VN2_din_02_00 <= 8'd0;
VN2_din_03_00 <= 8'd0;
VN3_din_01_00 <= 8'd0;
VN3_din_04_00 <= 8'd0;
VN1_din_02_01 <= 8'd0;
VN2_din_04_02 <= 8'd0;
VN2_din_04_03 <= 8'd0;
VN2_din_04_04 <= 8'd0;
VN3_din_02_05 <= 8'd0;
VN3_din_02_06 <= 8'd0;
VN3_din_03_07 <= 8'd0;
VN3_din_03_08 <= 8'd0;
end
end
end
// 控制DR的写使能
always @ (posedge clk) begin
if(rst_VN) begin
DR_wea <= 1'd0;
end else begin
if (cnt_2_VN >= 11'd1 + DELAY_WR && cnt_2_VN <= 11'd512 + DELAY_WR && iter_num == MAX_ITER_NUM - 1)
// 对写全能用迭代次数进行限制,防止输出译码结果时有新的数据写入
DR_wea <= 1'd1;
else
DR_wea <= 1'd0;
end
end
// 控制DR存储的写地址
always @ (posedge clk) begin
if (rst_VN) begin
DR_addr_wr <= 9'd511;
end else begin
if (cnt_2_VN >= 11'd1 + DELAY_WR && cnt_2_VN <= 11'd512 + DELAY_WR)
DR_addr_wr <= DR_addr_wr + 9'd1;
else
DR_addr_wr <= 9'd511;
end
end
// 控制DR存储的写数据
always @ (posedge clk) begin
if (rst_VN) begin
DR_din_01 <= 1'd0;
DR_din_02 <= 1'd0;
DR_din_03 <= 1'd0;
DR_din_04 <= 1'd0;
DR_din_05 <= 1'd0;
end else begin
if (cnt_2_VN >= 11'd1 + DELAY_WR && cnt_2_VN <= 11'd512 + DELAY_WR) begin
DR_din_01 <= dout03_result_CU01;
DR_din_02 <= dout04_result_CU02;
DR_din_03 <= dout02_result_CU03;
DR_din_04 <= dout04_result_CU04;
DR_din_05 <= dout07_result_CU05;
end else begin
DR_din_01 <= 1'd0;
DR_din_02 <= 1'd0;
DR_din_03 <= 1'd0;
DR_din_04 <= 1'd0;
DR_din_05 <= 1'd0;
end
end
end
//状态指示
assign data_start_ck_VN = (cnt_VN == 11'd1 + DELAY_WR - 11'd1 && iter_num == MAX_ITER_NUM - 1) ? 1'd1 : 1'd0;
assign data_start_VN = (cnt_VN == 11'd512 + DELAY_WR + 11'd1 && iter_num == MAX_ITER_NUM - 1) ? 1'd1 : 1'd0;
assign end_VN = (cnt_VN == 11'd512 + DELAY_WR + 11'd2 && iter_num <= MAX_ITER_NUM - 2) ? 1'd1 : 1'd0;
endmodule