`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