LDPC译码器的FPGA实现

本文将介绍LDPC译码器的FPGA实现,译码器设计对应CCSDS131x1o1s文档中提到的适用于深空通信任务的LDPC编码。本文档将简述Verilog代码的基本结构和信号说明。

修订历史

以下表格展示了本文档的修订过程




日期

版本号

修订内容

2015/03/16

V1.0

初始版本,ISim仿真基本正确

简介
本文中FPGA实现特指通过Verilog HDL实现LDPC译码器功能,然而对于VHDL来说也似类似的的。Verilog HDL不像MATLAB代码那样有很强的通用性,或者说我暂时编不出通用性太好的代码。因此,这里的FPGA实现仅针对CCSDS文档(06版)中1024信息位1/2码率的适用于深空通信LDPC码,采用最小和算法下的实现。由于在截位补零下最小和算法性能奇差,因此此处不做补零处理,即码率实际为0.4。

LDPC相关文档包括《程序说明:LDPC编码(CCSDS)算法概述》、《程序说明:LDPC译码算法概述》、《学习笔记:LDPC编译码基本原理》以及《CCSDS_LDPC_V1》(代码),同时与本文档同名的学习笔记将阐述编程过程和思路,均可作为本文档的参考。

译码器的输入输出至少应该包括以下信号

input clk; //时钟

input rst; //复位信号,高有效

input decode_start; //开始译码信号,持续高电平一个clock有效

output output_ready; //开始输出

output frame_error; //输出结果不满足校验矩阵

output data_out; //输出译码后数据

output busy; //译码模块正在译码,此时不响应decode_start信号

对应应该有如下的状态

parameter IDLE = 5'b00001; //空闲状态,等待译码

parameter VML_INIT = 5'b00010; //初始化变量节点取值

parameter UML_UPDATE = 5'b00100; //更新校验节点,同时计算校验方程

parameter VML_UPDATE = 5'b01000; //更新变量节点

parameter DECODER_END = 5'b10000; //输出译码结果

下文将具体叙述程序结构和信号说明。

程序结构

图 1 程序结构图

图 1 程序结构图

顶层模块为decoder_top,以下具体阐述各个模块和改进思路

图 2 状态机

图 2 状态机

这是decoder_top内唯一有意义的代码,输出5个状态,输入包括

decode_start

vmlram_addra

hrowram_addra

frame_error

MAX_ITER_NUM

这是状态机跳转的所有条件,第2、3个是可选择的,可以考虑替换掉,但这两个是很很方便的。

图 3 信道信息控制模块

图 3 信道信息控制模块

通过state和umlram_addrb控制尝试inputram_addra对应输出不同的信息。输入umlram_addrb是必须的,因为需要控制在uml2vml中信道信息的输出。

显然这两个模块可以合成一个,不应该直接将InputRam放在decoder_top之下。

图 4 Vml寄存器写控制

图 4 Vml寄存器写控制

vmlram写控制需要即控制vmlram_wea,dina,addra三路信号。针对不同阶段,vml的输入是不一样的,该模块起到了一个输入选择作用对inputram_douta,vmlram_updae_dina,decoded_data_check三个信号进行处理,同时根据state不同产生写入地址。模块设计较为合理。

图 5 vml2uml模块

图 5 vml2uml模块

这个模块还包括了hrowram、vml2uml_caculate和check_data三个部分。模块完成了decoded_data的校验和vmlram_doutb到变量节点的更新。输出的hrowram_addra作为了state和uml地址生成的控制(挺方便,是否合适,有无更好选择?),hrowram_douta用于生成uml的写地址。

图 6 umlram_write_control模块

图 6 umlram_write_control模块

umlram_write_control模块控制产生uml写地址,为什么没有写数据,因为vml2uml模块的输出直接连接到ram上面去了。写地址和使能通过hrowram_addra和hrowram_douta控制产生。

图 7 uml2vml模块

图 7 uml2vml模块

变量节点更新模块技术按vml更新值即vmlram_update_dina和decoded_data_check.

信号说明

Decoder_top顶层控制模块

表格 1 decoder_top模块信号说明

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

decode_start

input

开始译码信号,持续高电平一个clock有效

optput_ready

output

开始输出

frame_error

output

输出结果不满足校验矩阵

data_out

output

输出译码后数据

busy

output,reg    

    译码模块正在译码,此时不响应decode_start信号

state

reg[4:0]

状态寄存器

MAX_ITER_NUM

reg[7:0]

最大迭代次数

vmlram_update_dina

wire[7:0]

vml更新过程中的数据输入

decoded_data_check

wire

待校验的译码结果

inputram_addra

wire[11:0]

被译码数据地址控制

inputram_douta

wire[7:0]

被译码数据输出

hrowram_addra

wire[12:0]

行列地址转化ROM地址

hrowram_douta

wire[12:0]

作为vml_addrb的输入

vmlram_addra

wire[12:0]

变量存储器写地址

vmlram_dina

wire[8:0]

变量存储器写输入

vmlram_doutb

wire[7:0]

变量存储器写输出

decoded_data

wire

也存在变量存储器的译码结果

vmlram_wea

wire

变量存储器写使能

umlram_addra

wire[12:0]

校验存储器写地址

umlram_addrb

wire[12:0]

校验存储器读地址

umlram_dina

wire[7:0]

校验存储器写数据

umlram_doutb

wire[7:0]

校验存储器读数据

umlram_wea

wire

校验存储器写使能

Inputram_control:根据输入产生inputram的地址控制

表格 2 inputram_control控制模块信号说明

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

umlram_addrb

input[12:0]

校验存储器读地址

state

input[4:0]

状态寄存器

inputram_addra

output[11:0],reg[11:0]

被译码数据地址控制

input_count

reg[2:0]

地址更新计数器

input_count_max

reg[2:0]

最大计数次数控制

input_init_addr

reg[11:0]

VML_INIT状态下inputram_addra地址

input_update_addr

reg[11:0]

VML_UPDATA状态下inputram_addra地址

Vmlram_write_control: vml寄存器写控制,通过输入inputram_douta, vmlram_update_dina等信息自动判断输出写地址、写使能和数据。

表格 3 vmlram_write_control模块的信号说明

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

inputram_douta

input[7:0]

VML下数据输入

state

input[4:0]

状态

vmlram_update_dina

input[7:0]

vml更新过程中的数据输入

decoded_data_check

input

待校验的译码结果

vmlram_addra

output[12:0] ,reg[12:0]

vmlram_dina

output[8:0], reg[8:0]

vmlram_wea

output, reg

vmlram_init_addra

reg[12:0]

addr_update_count

reg[1:0]

VML_UPDATE下实际上是要对地址做延迟的,这是控制延迟的寄存器

vmlram_update_addra

reg[12:0]

vmlram_init_addratemp

reg[12:0]

这个是开始数错了时钟周期,添加一个clk延时

vmlram_update_addratemp

reg[12:0]

这个是开始数错了时钟周期,添加一个clk延时

Vml2uml: 接收vml读出的数据,处理后写入uml中。同时完成校验伴随式的计算

Vml2uml包含了以下几个模块:

  • hrowram
  • vml2uml_caculate
  • check_data

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

state

input[4:0]

状态信息

decoded_data

input

 

vmlram_doutb

input[7:0]

 

hrowram_addra

output[12:0], reg[12:0]

 

hrowram_douta

output[12:0], wire[12:0]

 

umlram_dina

output[7:0]

 

frame_error

output

输出帧错误指示

vmltempcount

reg[2:0]

计算是三个一更新还是六个

Vml2uml_calculate.v 校验节点更新的计算部分内容

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

state

input[4:0]

状态信息

vmltempcount

input[2:0]

计算是三个一更新还是六个

vmlram_doutb

input[7:0]

vmlram输出

umlram_dina

output[7:0],reg[7:0]

umlram输入

vmlmark

reg

每组计算出符号

vmltemp

reg[47:0]

缓存6个clock的vmlram输出

vmltempmark

reg[5:0]

缓存6个clock的vmlram输出符号

vmlmin1

reg[7:0]

最小值计算

vmlmin2

reg[7:0]

次小值计算

vmlmin1temp

reg[7:0]

缓存最小值计算结果

vmlmin2temp

reg[7:0]

缓存次小值计算结果

vmltempcomp

reg[7:0]

取出用于比较的vml输出(绝对值)

vmlMarkcomp

reg

缓存符号计算结果

vmltempmarkcomp

reg

取出用于比较的vml符号

vmlram_doutb_inv

wire[7:0]

负数取绝对值

check_data.v 计算是否满足校验方程

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

state

input[4:0]

状态信息

vmltempcount

input[2:0]

计算是三个一更新还是六个

decoded_data

input

待校验数据

hrowram_addra

input[12:0]

校验起始控制

frame_error

output, reg

帧错误指示

sum_mod2

reg

计算模二和

Umlram_write_control.v: uml寄存器写控制

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

hrowram_douta

input[12:0]

hrowram输出,用于生成umlram地址

hrowram_addra

input[12:0]

hrowram地址,计数判断

umlram_addra

output[12:0], reg[12:0]

生成的umlram地址

umlram_wea

output,reg

umlram使能信号

hrowram_douta_temp

reg[116:0]

存储hrowram输出,延时生成umlram地址

Uml2vml.v: 校验节点到变量节点更新,同时生成译码后结果

信号

类型

功能

clk

input

时钟

rst

input

复位信号,高有效

state

input[4:0]

umlram_doutb

input[7:0]

inputram_douta

input[7:0]

umlram_addrb

output[12:0]

vmlram_update_dina

output[7:0]

decoded_data_check

output

umltempcount

reg[2:0]

判断uml延迟

umltemp

reg[47:0]

uml输出缓存

umlsum

reg[10:0]

uml输出求和

umlsumtemp

reg[10:0]

缓存求和结果

vmltempcount_max

reg[2:0]

控制此时几个数据做一次操作

vmltempcount

reg[2:0]

控制此时几个数据做一次操作

vmlram_update_dina

reg[7:0]

vml需要写入的数据

umltempsub

reg[7:0]

做减法的uml取值

umltempsub_delay

reg[2:0]

uml取值延时控制

vmltempcount_maxtemp

reg[2:0]

uml取值延时控制

改进

 

模块划分是否合理?

功能实现是否足够合适?

存储器设计显然不够合理,都是8bit。

参考他人毕业论文的模块化方法。

了解并行、部分并行的方法

完成输入输出部分模块的设计。

完成整个硬件仿真平台的思路构想。

代码: http://xilinx.eetrend.com/files-eetrend-xilinx/blog/201505/8684-18036-ld...

2 条评论

(1楼)您好!我最近也在做LDPC的译码器,您的分享很有价值,能否

MengYang 在 星期二, 04/26/2016 - 20:53 发表。

您好!我最近也在做LDPC的译码器,您的分享很有价值,能否留下邮箱我们后面继续交流?谢谢!

(2楼)楼主真厉害!

时空倒转 在 星期三, 11/07/2018 - 19:20 发表。

楼主真厉害!