LDPC中校验节点处理单元(CNU)基本原理概述以及FPGA实现

目录

一、理论基础

二、核心程序

三、仿真测试结果

作者ID :fpga和matlab
CSDN主页:https://blog.csdn.net/ccsss22?type=blog
擅长技术:
1.无线基带,无线图传,编解码
2.机器视觉,图像处理,三维重建
3.人工智能,深度学习
4.智能控制,智能优化
5.其他
一、理论基础
码长较长的低速LDPC编码在信噪比较低的应用场合呈现出其他编码无法匹敌的优势,已经证明非规则的LDPC码性能甚至优于Turbo码高速LDPC编码性能也比较好.尤其是在磁记录等一些应用场合,码长较短的高速LDPC编码有着较为广阔的应用前景。在不久的将来,LDPC编码将用于更多高速高质量的通信场合。而UWB通信技术因其传输速率高、功耗低等优点在短距离的网络中得到越来越多的关注。特别是UWB无线通信因其具有良好的时域可分辨性尤其适合于密集多径环境中的短距离多用户接入。本文在SvstemGenerator中对LDPC码整个编译码系统进行了参数化的硬件实现,并构建了超宽带通信系统LDPC码硬件仿真平台,验证了LDPC码在UWB通信中的优异性能。

  CNU的功能为计算"校验一变量"信息。CNU实现与VNU基本相似,6个"变量一校验"信息相加减去相对应的1个"变量一校验"信息所得到的值舍入处理后作为查找表运算的输入,最后将查找表运算结果按计算的符号位正负输出至VNU处理单元。由于是二进制系统,本文采用异或运算代替乘法运算计算符号位,

校验节点处理单元(Check Node processing Unit,CNU)其主要功能是处理从变量节点信息返回到校验节点的信息。在校验节点更新模块更新过程中,其主要涉及到水平更新环节,具体计算原来参考公式3.18。CNU模块的FPGA实现结构如图所示。从图的结构图可知,CNU更新模块模块的工作流程为:首先CNU模块处理来自VNU的信息计算绝对值,然后通过比较器计算绝对值中的最小值,,其中比较器的结构如图2所示。然后将图2比较器的输出值与归一化因子相乘,得到公式的输出结果。与此同时,通过异或运算模块,实现符号位乘法。最后通过补码运算模块实现与符号积的乘法运算功能,输出译码所需要的软信息。通过上述的校验节点处理过程,实现校验节点数据的实时更新。

 

 

如图的结构可知,d0~d15为VNU到CNU的信号的绝对值,每一个比较器模块,分别完成两个输入数据的较小值,然后通过四级比较器实现16个输入数据最小值的搜索,整个过程需要4个clock时钟周期延迟。

CNU信息存储器功能与VNU信息存储器功能类似,其主要完成校验节点信息的存储。根据4.4.2章节的介绍可知,在本系统中,总共有16个CNU模块,因此其对应的含有16组CNU信息存储模块。每一个存储模块均采用Vivado的RAM核进行实现。同理,将双口RAM存储器位宽为8,双口RAM的存储深度设置被子矩阵大小的2倍,即深度为1024。

对于CNU信息存储模块,在存储器写入过程中,系统控制模块产生一个写地址使能信号,当该信号为1时候,CNU的输出信号将根据写地址被写入到双口RAM中,当CNU处理完当前的数据信息之后,系统控制模块控制写使能信号将变为0,此时写地址计数器将停止计数。在存储器读取过程中,系统控制模块产生一个读地址使能信号,当该信号为1时候,读地址计数器开始计数,此时系统从CNU信息存储模块读取数据,并将数据传输给对应的VNU模块。

在实际的译码迭代过程中,当数据送入到VNU变量节点更新模块进行处理之后,数据将被写入到VNU对应的双口RAM模块中,然后再通过译码控制器,将数据从双口RAM中读取送入到CNU校验节点更新模块中,数据经过CNU模块处理之后,数据将被写入到CNU对应的双口RAM模块中。最后再通过译码控制器将双口RAM中的数据再次送入到VNU模块中,从而完成一次完整的迭代过程。

二、核心程序

.....................................

reg signed [31:0] min_sum_1;
reg signed [31:0] min_sum_2;
reg signed [31:0] min_sum_3;
reg signed [31:0] min_sum_4;
reg signed [31:0] min_sum_5;
reg signed [31:0] min_sum_6;
wire [5:0] Q_signs;
wire final_sign_1;
wire final_sign_2;
wire final_sign_3;
wire final_sign_4;
wire final_sign_5;
wire final_sign_6;
wire [31:0] Q1_abs;
wire [31:0] Q2_abs;
wire [31:0] Q3_abs;
wire [31:0] Q4_abs;
wire [31:0] Q5_abs;
wire [31:0] Q6_abs;

assign Q1_abs = (Q1[31]==1) ? ~Q1+1'b1 : Q1;
assign Q2_abs = (Q2[31]==1) ? ~Q2+1'b1 : Q2;
assign Q3_abs = (Q3[31]==1) ? ~Q3+1'b1 : Q3;
assign Q4_abs = (Q4[31]==1) ? ~Q4+1'b1 : Q4;
assign Q5_abs = (Q5[31]==1) ? ~Q5+1'b1 : Q5;
assign Q6_abs = (Q6[31]==1) ? ~Q6+1'b1 : Q6;


assign Q_signs[0] = (Q1[31]==1) ? 1'b1 : 1'b0;
assign Q_signs[1] = (Q2[31]==1) ? 1'b1 : 1'b0;
assign Q_signs[2] = (Q3[31]==1) ? 1'b1 : 1'b0;
assign Q_signs[3] = (Q4[31]==1) ? 1'b1 : 1'b0;
assign Q_signs[4] = (Q5[31]==1) ? 1'b1 : 1'b0;
assign Q_signs[5] = (Q6[31]==1) ? 1'b1 : 1'b0;

assign final_sign_1 = Q_signs[1]^Q_signs[2]^Q_signs[3]^Q_signs[4]^Q_signs[5];
assign final_sign_2 = Q_signs[0]^Q_signs[2]^Q_signs[3]^Q_signs[4]^Q_signs[5];
assign final_sign_3 = Q_signs[1]^Q_signs[0]^Q_signs[3]^Q_signs[4]^Q_signs[5];
assign final_sign_4 = Q_signs[1]^Q_signs[2]^Q_signs[0]^Q_signs[4]^Q_signs[5];
assign final_sign_5 = Q_signs[1]^Q_signs[2]^Q_signs[3]^Q_signs[0]^Q_signs[5];
assign final_sign_6 = Q_signs[1]^Q_signs[2]^Q_signs[3]^Q_signs[4]^Q_signs[0];



always@(negedge clk)
begin

if (Q2_abs<=Q3_abs && Q2_abs<=Q4_abs && Q2_abs<=Q5_abs && Q2_abs<=Q6_abs) begin min_sum_1 = Q2_abs; end
if (Q3_abs<Q2_abs && Q3_abs<=Q4_abs && Q3_abs<=Q5_abs && Q3_abs<=Q6_abs) begin min_sum_1 = Q3_abs; end
if (Q4_abs<Q2_abs && Q4_abs<Q3_abs && Q4_abs<=Q5_abs && Q4_abs<=Q6_abs) begin min_sum_1 = Q4_abs; end
if (Q5_abs<Q2_abs && Q5_abs<Q3_abs && Q5_abs<Q4_abs && Q5_abs<=Q6_abs) begin min_sum_1 = Q5_abs; end
if (Q6_abs<Q2_abs && Q6_abs<Q3_abs && Q6_abs<Q4_abs && Q6_abs<Q5_abs ) begin min_sum_1 = Q6_abs; end

if (Q1_abs<=Q3_abs && Q1_abs<=Q4_abs && Q1_abs<=Q5_abs && Q1_abs<=Q6_abs) begin min_sum_2 = Q1_abs; end
if (Q3_abs<Q1_abs && Q3_abs<=Q4_abs && Q3_abs<=Q5_abs && Q3_abs<=Q6_abs) begin min_sum_2 = Q3_abs; end
if (Q4_abs<Q1_abs && Q4_abs<Q3_abs && Q4_abs<=Q5_abs && Q4_abs<=Q6_abs) begin min_sum_2 = Q4_abs; end
if (Q5_abs<Q1_abs && Q5_abs<Q3_abs && Q5_abs<Q4_abs && Q5_abs<=Q6_abs) begin min_sum_2 = Q5_abs; end
if (Q6_abs<Q1_abs && Q6_abs<Q3_abs && Q6_abs<Q4_abs && Q6_abs<Q5_abs ) begin min_sum_2 = Q6_abs; end

if (Q2_abs<=Q1_abs && Q2_abs<=Q4_abs && Q2_abs<=Q5_abs && Q2_abs<=Q6_abs) begin min_sum_3 = Q2_abs; end
if (Q1_abs<Q2_abs && Q1_abs<=Q4_abs && Q1_abs<=Q5_abs && Q1_abs<=Q6_abs) begin min_sum_3 = Q1_abs; end
if (Q4_abs<Q2_abs && Q4_abs<Q1_abs && Q4_abs<=Q5_abs && Q4_abs<=Q6_abs) begin min_sum_3 = Q4_abs; end
if (Q5_abs<Q2_abs && Q5_abs<Q1_abs && Q5_abs<Q4_abs && Q5_abs<=Q6_abs) begin min_sum_3 = Q5_abs; end
if (Q6_abs<Q2_abs && Q6_abs<Q1_abs && Q6_abs<Q4_abs && Q6_abs<Q5_abs ) begin min_sum_3 = Q6_abs; end

if (Q2_abs<=Q3_abs && Q2_abs<=Q1_abs && Q2_abs<=Q5_abs && Q2_abs<=Q6_abs) begin min_sum_4 = Q2_abs; end
if (Q3_abs<Q2_abs && Q3_abs<=Q1_abs && Q3_abs<=Q5_abs && Q3_abs<=Q6_abs) begin min_sum_4 = Q3_abs; end
if (Q1_abs<Q2_abs && Q1_abs<Q3_abs && Q1_abs<=Q5_abs && Q1_abs<=Q6_abs) begin min_sum_4 = Q1_abs; end
if (Q5_abs<Q2_abs && Q5_abs<Q3_abs && Q5_abs<Q1_abs && Q5_abs<=Q6_abs) begin min_sum_4 = Q5_abs; end
if (Q6_abs<Q2_abs && Q6_abs<Q3_abs && Q6_abs<Q1_abs && Q6_abs<Q5_abs ) begin min_sum_4 = Q6_abs; end

if (Q2_abs<=Q3_abs && Q2_abs<=Q4_abs && Q2_abs<=Q1_abs && Q2_abs<=Q6_abs) begin min_sum_5 = Q2_abs; end
if (Q3_abs<Q2_abs && Q3_abs<=Q4_abs && Q3_abs<=Q1_abs && Q3_abs<=Q6_abs) begin min_sum_5 = Q3_abs; end
if (Q4_abs<Q2_abs && Q4_abs<Q3_abs && Q4_abs<=Q1_abs && Q4_abs<=Q6_abs) begin min_sum_5 = Q4_abs; end
if (Q1_abs<Q2_abs && Q1_abs<Q3_abs && Q1_abs<Q4_abs && Q1_abs<=Q6_abs) begin min_sum_5 = Q1_abs; end
if (Q6_abs<Q2_abs && Q6_abs<Q3_abs && Q6_abs<Q4_abs && Q6_abs<Q1_abs ) begin min_sum_5 = Q6_abs; end

if (Q2_abs<=Q3_abs && Q2_abs<=Q4_abs && Q2_abs<=Q5_abs && Q2_abs<=Q1_abs) begin min_sum_6 = Q2_abs; end
if (Q3_abs<Q2_abs && Q3_abs<=Q4_abs && Q3_abs<=Q5_abs && Q3_abs<=Q1_abs) begin min_sum_6 = Q3_abs; end
if (Q4_abs<Q2_abs && Q4_abs<Q3_abs && Q4_abs<=Q5_abs && Q4_abs<=Q1_abs) begin min_sum_6 = Q4_abs; end
if (Q5_abs<Q2_abs && Q5_abs<Q3_abs && Q5_abs<Q4_abs && Q5_abs<=Q1_abs) begin min_sum_6 = Q5_abs; end
if (Q1_abs<Q2_abs && Q1_abs<Q3_abs && Q1_abs<Q4_abs && Q1_abs<Q5_abs ) begin min_sum_6 = Q1_abs; end
.........................

三、仿真测试结果

 

 A14-43



posted @ 2022-10-21 22:05  fpga和matlab  阅读(389)  评论(0编辑  收藏  举报