我是
靠谱客的博主
敏感皮卡丘,最近开发中收集的这篇文章主要介绍
LDPC译码器的FPGA实现,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
应用笔记 V0.0 2015/3/17 | 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 程序结构图 顶层模块为decoder_top,以下具体阐述各个模块和改进思路 图 2 状态机 这是decoder_top内唯一有意义的代码,输出5个状态,输入包括 decode_start vmlram_addra hrowram_addra frame_error MAX_ITER_NUM 这是状态机跳转的所有条件,第2、3个是可选择的,可以考虑替换掉,但这两个是很很方便的。 图 3 信道信息控制模块 通过state和umlram_addrb控制尝试inputram_addra对应输出不同的信息。输入umlram_addrb是必须的,因为需要控制在uml2vml中信道信息的输出。 显然这两个模块可以合成一个,不应该直接将InputRam放在decoder_top之下。 图 4 Vml寄存器写控制 vmlram写控制需要即控制vmlram_wea,dina,addra三路信号。针对不同阶段,vml的输入是不一样的,该模块起到了一个输入选择作用对inputram_douta,vmlram_updae_dina,decoded_data_check三个信号进行处理,同时根据state不同产生写入地址。模块设计较为合理。 图 5 vml2uml模块 这个模块还包括了hrowram、vml2uml_caculate和check_data三个部分。模块完成了decoded_data的校验和vmlram_doutb到变量节点的更新。输出的hrowram_addra作为了state和uml地址生成的控制(挺方便,是否合适,有无更好选择?),hrowram_douta用于生成uml的写地址。 图 6 umlram_write_control模块 umlram_write_control模块控制产生uml写地址,为什么没有写数据,因为vml2uml模块的输出直接连接到ram上面去了。写地址和使能通过hrowram_addra和hrowram_douta控制产生。 图 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。 参考他人毕业论文的模块化方法。 了解并行、部分并行的方法 完成输入输出部分模块的设计。 完成整个硬件仿真平台的思路构想。 |
转载于:https://www.cnblogs.com/sea-wind2/p/4351505.html
最后
以上就是敏感皮卡丘为你收集整理的LDPC译码器的FPGA实现的全部内容,希望文章能够帮你解决LDPC译码器的FPGA实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复