基于FPGA的LDPC编译码器

链接:https://pan.baidu.com/s/1GurX1-uWdh4_FYNiXuViJA
提取码:1234

该FPGA设计实现的是一个LDPC码编译码器,采用的是并行输入与并行输出。设计主要分为两个模块:1.LDPC码编码器;2.LDPC码译码器。实现的功能:并行输入4位信息序列,经过编码器后获得12位编码后序列,然后经过译码器译码还原出原始的4位信息序列。LDPC编译码器设计功能框图如图 1所示。

在这里插入图片描述
在这里插入图片描述

部分代码

/*------------------------------------------------文件信息-------------------------------------------------
**  文件名称:      ldpc_encoder.v
**  最后修改日期:  2017-3-20
**  最新版本:      V1.0
**  功能描述:      LDPC码编码器       
** 

**-------------------------------------------------------------------------------------------------------*/
`timescale 1 ns/ 1 ps
module ldpc_encoder(
	clk,
	rst_n,
	msg,
	code
	);

	input  		  clk;													// 系统时钟 50MHz
	input  		  rst_n;												// 复位信号,低电平有效
	input  [3:0]  msg;													// 信息序列 
	output [11:0] code;													// 编码序列 

    /*********************************************************************************************
    //  模块名称:LDPC编码模块
    //  功能描述:对信息序列进行LDPC编码
	//			   采用(8,12)二进制不规则LDPC码,码率为0.33,行重为3和4,列重为2和3 	 
    //             编码部分采用的是高斯消元法,获得校验序列c,即可构造出编码序列code            
	//   			| 0	 0	1	0	0	1	0	0	1	0	1	0 |
	//				| 0	 1	0	0	0	1	0	0	0	0	0	1 |
	//  			| 0	 1	0	0	0	0	1	0	0	0	1	0 |
	//  校验矩阵H= | 0	 0	0	1	1	1	0	0	0	1	0	0 |       若code*H'=0 则code正确 可还原出原始msg
	//  			| 0	 0	0	1	0	0	0	1	1	0	0	1 |
	//  			| 1	 0	0	0	1	0	0	0	0	0	0	0 |
	//  			| 1	 0	1	0	0	0	1	1	0	0	0	0 |
	//   			| 0	 1	1	0	0	0	0	0	0	1	0	0 |
	//		 	                 
	//                          高斯消元
    //  设H=[A | B] 转换为 [I | P] (I为单位矩阵) 
    //  设u为编码序列 u=[c | s]  s为信息序列 c为校验序列
    //  因为  H*u' = u*H' = 0
    //  代入得:
	//			 _    _
	//			 | c' |
	//	  [I | P]|    | = 0
	//			 | s' |
	//			 -    -
	//	 I*c' + P*s' = 0
	//	 I*c' = P*s' (在GF(2)上) ->  I*c'=-P*s' 
	//   因为在GF(2)上有 P*s'+ P*s'=0 所以 P*s'=-P*s' I*c' = P*s' ->   c'=I'*P*s' =P*s' -> c' = P*s' 
	//	 再由u=[c | s]即可得到编码后的码字。
	//	 如果高斯消元过程中进行了列交换,
	//	 则只需记录列交换col_recoeder,并以相反次序对编码后的码字同样进行列交换即可。
	//	 解码时先求出u,再进行列交换得到u=[c | s],后面部分s即是还原出来的信息序列。
	//   
	//   根据校验矩阵H,经过高斯消元法后,可得P矩阵和列交换col_recoeder
	//     | 1 1 1 0 |
	//	p= | 0 1 0 1 |      col_recoeder= |0 0 0 0 0 0 0 9| (0不用变换)
	//     | 0 0 0 1 |
	//     | 1 1 1 0 |
	//	   | 1 1 1 0 |
	//     | 0 1 0 0 |
	//     | 0 1 1 1 |
	//     | 0 1 1 1 |
    //*********************************************************************************************/	

	// 时钟计数 第一个时钟计算校验比特序列 第二个时钟 进行列变换还原 输出编码后序列
	reg clk_count;
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			clk_count <= #1 1'b0;
		else
			clk_count <= #1 clk_count + 1'b1;
	end
	
	
	// msg与P矩阵进行运算 求出校验序列
	reg [7:0] check;													// 校验序列
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			check     <= #1 8'b0;
		else
		begin
			if(clk_count == 1'd0)
			begin														// msg与P矩阵进行运算 获得校验序列								
				check[7]  <= #1 msg[3]+msg[2]+msg[1];
				check[6]  <= #1 msg[2]+msg[0];
				check[5]  <= #1 msg[0];
				check[4]  <= #1 msg[3]+msg[2]+msg[1];
				check[3]  <= #1 msg[3]+msg[2]+msg[1];
				check[2]  <= #1 msg[2];
				check[1]  <= #1 msg[2]+msg[1]+msg[0];
				check[0]  <= #1 msg[2]+msg[1]+msg[0];
			end
			else
				check <= #1 8'b0;
		end
	end
	
	// 进行列变换还原并输出编码后码字	|0 0 0 0 0 0 0 9|  u=[c | s] 
	reg [11:0] code;													
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			code <= #1 12'b0;
			
		else
		begin
			if(clk_count == 1'b1)
				code <= #1 {check[7:1],msg[3],check[0],msg[2:0]}; 	// 序列第8位与第9位进行交换 从低往高数 最后输出编码后码字		
			else
				code  <= #1 code;			
		end
	end	
	
endmodule
  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值