引言

      卷积码是一种信道纠错编码,在通信中具有广泛的应用。在发送端根据生成多项式进行卷积码编码,在接收端根据维特比(Viterbi)译码算法进行译码,能够有效抵抗信道噪声的影响,在误码率门限之下可以对传输过程中发生的突发错误进行纠错。

1、编码及译码算法的基本原理

  • 卷积码编码

       卷积码是一种纠错编码,它将输入的k个信息比特编成n个比特输出,特别适合以串行形式进行传输,时延小。卷积码编码器的一般形式如下图所示。

如下图所示为k=1时的编码框图,k=1也是最常用的一种编码器情形:

  • 译码算法

卷积码的译码方法有两类:一类是大数逻辑译码,又称门限译码;另一类是概率译码,概率译码又能分为维特比译码和序列译码两种。维特比(Viterbi)译码和序列译码都属于概率译码。当卷积码的约束长度不太大时,与序列译码相比,维特比译码器比较简单,计算速度更快。接下来的译码算法采用的是概率译码中的维特比译码。采用概率译码的一种基本想法是:把已接收序列与所有可能的发送序列做比较,选择其中汉明码距最小的一个序列做为发送序列。

  • 编码及译码算法的Matlab实现

       根据如上所述的编译码基本原理,我们可以在Matlab中进行很方便的仿真,Matlab提供了集成化的函数可供调用,进行仿真,如下所示:

% 0101随机数,待编码数据
bits = randi([0 1],256,1);
% trellis = poly2trellis(7,{'1 + x^3 + x^4 + x^5 + x^6', ...
%     '1 + x + x^3 + x^4 + x^6'})
% 产生生成多项式
gen_math = poly2trellis(7, [171 133]);% 8进制,分别对应相应位置的抽头
% 卷积码编码
codeData = convenc(bits,gen_math);
% Viterbi译码
decodeData = vitdec(codeData,gen_math,34,'trunc','hard');
% 算误码
err = biterr(decodeData,bits);

2、编码算法的FPGA实现

根据卷积码编码的基本原理 ,我们可以根据相应的生成多项式来进行Verilog编码,从而可以很方便的实现卷积码编码的FPGA实现:

  • 顶层代码
module  convenc(//system signalsinput    clk, input  rst_n,input data_in,output  reg [1:0] data_out
);
reg [6:0] conv_reg;always @(posedge clk or negedge rst_n) beginif (!rst_n) beginconv_reg <= 7'd0;endelse beginconv_reg <= {data_in,conv_reg[6:1]};end
end  always @(posedge clk or negedge rst_n) beginif (!rst_n) begindata_out <= 2'd0;endelse begindata_out[1] <= conv_reg[6]^conv_reg[5]^conv_reg[4]^conv_reg[3]^conv_reg[0];//o171data_out[0] <= conv_reg[6]^conv_reg[4]^conv_reg[3]^conv_reg[1]^conv_reg[0];//o133end
end
endmodule
  • 测试代码
`timescale 1ns/1ps;
module tb();reg clk;
reg rst_n;
reg data_in;
wire [1:0] data_out;
reg bits[255:0];
integer out_file;
integer i;convenc demo(.clk(clk),.rst_n(rst_n),.data_in(data_in),.data_out(data_out));initial
beginclk = 1'b1;rst_n = 1'b1;#5 rst_n = 1'b0;#5 rst_n =1'b1;$readmemb("F:/FPGA_DSP/Viterbi/bits.txt",bits);out_file = $fopen("F:/FPGA_DSP/Viterbi/result.txt","w");//获取文件句柄for(i = 0; i <= 255; i = i + 1)begindata_in = bits[i];#10;$fwrite(out_file,"%b\n%b\n",data_out[1],data_out[0]);end
end
always #5 clk = ~clk;
endmodule
  • 仿真结果

3、维特比译码(Viterbi)算法的FPGA实现

维特比译码(Viterbi)算法在数学原理上是比较复杂的,从理解算法到实现需要做大量的工作,但是Xilinx的Vivado工具给我们提供了Viterbi decoder IP核,我们可以很方便地调用这个IP核进行算法的FPGA实现和落地。

  • Viterbi decoder IP核输入输出数据格式

Viterbi decoder IP核的接口是基于AXI-Stream协议的,在之前的文章中已经有提及AXI-Stream协议的握手过程,如果有不懂的可以去看前面的文章,下面主要介绍一下该IP和输入输出数据的基本格式组成:

输入数据:

当IP核作为接收输入数据的时候,扮演的是从机的角色,输入数据的格式如下图所示,下图对应的是编码速率为2的情况。如果编码速率为N,那么数据的位宽相应为N*8。

当IP核配置为硬判决时,输入数据位宽为1,其余位用0补齐, 当IP核配置为软判决时,输入数据位宽为3-5,其余位用0补齐,DATA_IN1对应高位,DATA_IN0对应低位。

输出数据:

IP核的译码输出数据总是1位,格式如下图所示。

最低位为译码数据,其他数据可以不做深入了解。

另外除了待译码数据的输入端口和译码数据输出端口外,该IP核还可以进行误码率(BER)的计算,其余端口位误码率计算配置端口和结果输出端口,具体详情请参考官方手册pg027。

  • IP核生成流程

Vivado软件为我们提供了Viterbi译码IP核,可以进行图形化配置然后进行调用和使用,配置参数要与编码过程中的相关参数严格对应,具体过程如下所示:

在图形化配置IP核完成后,我们提取相应的网表文件在Modelsim环境下进行了仿真,如何在Modelsim环境下仿真Vivado IP核我们在前面也有提及,如有不懂的也可翻阅前面的文章进行学习,相关测试程序如下。

`timescale 1 ns / 1 ps
module dec_tb ();
glbl glbl();
reg  aclk;
reg aresetn;reg [15:0]s_axis_data_tdata;
reg s_axis_data_tvalid;
wire s_axis_data_tready;wire [7:0]m_axis_data_tdata;
wire m_axis_data_tvalid;
reg m_axis_data_tready;reg [15:0] s_axis_dstat_tdata;
reg s_axis_dstat_tvalid;
wire s_axis_dstat_tready;wire [15:0]m_axis_dstat_tdata;
wire m_axis_dstat_tvalid;
reg m_axis_dstat_tready;reg codeData[511:0];
reg [9:0]i;
reg [9:0]j;
integer out_file;
initial beginaclk = 1'b1;aresetn = 1'b1;#5 aresetn = 1'b0;#5 aresetn = 1'b1;$readmemb("F:/FPGA_DSP/Viterbi/codeData.txt",codeData);out_file = $fopen("F:/FPGA_DSP/Viterbi/decodeData.txt","w");//获取文件句柄
endalways #5 aclk = ~aclk;//送数据
always @(posedge aclk or negedge aresetn) beginif (!aresetn) begins_axis_data_tvalid <= 1'b0;s_axis_data_tdata <= 16'd0;i <= 9'd0;j <= 9'd1;endelse if (s_axis_data_tready) beginif(i <= 9'd510)begins_axis_data_tvalid <= 1'b1;s_axis_data_tdata <= {7'd0,codeData[j],7'd0,codeData[i]};i <= i + 2;j <= j + 2;endelses_axis_data_tvalid <= 1'b0;end
end
//取数据
always @(posedge aclk or negedge aresetn) beginif (!aresetn) beginm_axis_data_tready <= 1'b1;endelse if (m_axis_data_tvalid) begin$fwrite(out_file,"%b\n",m_axis_data_tdata[0]);end
end
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
viterbi_0 your_instance_name (.aclk(aclk),                                // input wire aclk.aresetn(aresetn),                          // input wire aresetn//接收数据时为从设备.s_axis_data_tdata(s_axis_data_tdata),      // input wire [15 : 0] s_axis_data_tdata.s_axis_data_tvalid(s_axis_data_tvalid),    // input wire s_axis_data_tvalid.s_axis_data_tready(s_axis_data_tready),    // output wire s_axis_data_tready//发送数据时为主设备.m_axis_data_tdata(m_axis_data_tdata),      // output wire [7 : 0] m_axis_data_tdata.m_axis_data_tvalid(m_axis_data_tvalid),    // output wire m_axis_data_tvalid.m_axis_data_tready(m_axis_data_tready),    // input wire m_axis_data_tready//BER测量.s_axis_dstat_tdata(s_axis_dstat_tdata),    // input wire [15 : 0] s_axis_dstat_tdata.s_axis_dstat_tvalid(s_axis_dstat_tvalid),  // input wire s_axis_dstat_tvalid.s_axis_dstat_tready(s_axis_dstat_tready),  // output wire s_axis_dstat_tready.m_axis_dstat_tdata(m_axis_dstat_tdata),    // output wire [15 : 0] m_axis_dstat_tdata.m_axis_dstat_tvalid(m_axis_dstat_tvalid),  // output wire m_axis_dstat_tvalid.m_axis_dstat_tready(m_axis_dstat_tready)  // input wire m_axis_dstat_tready
);
endmodule

仿真波形:

卷积码编码及维特比译码(Viterbi)算法的原理及其FPGA实现相关推荐

  1. fano译码 matlab,卷积码编码和维特比译码的原理、性能与仿真分析

    1.引言 卷积码的编码器是由一个有k位输入.n位输出,且具有m位移位寄存器构成的有限状态的有记忆系统,通常称它为时序网络.编码器的整体约束长度为v,是所有k个移位寄存器的长度之和.具有这样的编码器的卷 ...

  2. c++实现卷积码编码和维特比译码_鑫艾勒维特家用别墅电梯:安全至上,无可替代...

    近年来,随着房地产行业的兴起,家用别墅电梯作为房地产配套产业也逐渐走进了平常家庭别墅中,如今一句俗语"无梯不成墅"将电梯在别墅中的重要地位彰显的淋漓尽致.艾勒维特家用液压小电梯因其 ...

  3. 卷积码译码之维特比译码算法(Viterbi decoding algorithm)

    卷积码译码之维特比译码算法 (Viterbi decoding algorithm) 本文主要介绍了卷积码的一种译码方法--维特比译码(Viterbi decoding). 关键词: 卷积码译码 维特 ...

  4. Viterbi算法原理与实现-通俗易懂

    Viterbi算法原理与实现 算法原理 维特比算法(Viterbi algorithm)是一种动态规划算法,解决的是篱笆型的图的最短路径问题,图的节点按列组织,每列的节点数量可以不一样,每一列的节点只 ...

  5. BiLSTM, CRF,BiLSTM+CRF原理讲解以及viterbi算法python实现

    目录 1 训练数据 2 模型结构 2.1 BiLSTM 2.1.1 结构 2.1.2 预测 2.1.3 缺点 2.2 CRF 2.2.1 基础概念 2.2.2 如何计算特征函数 2.2.3 如何求解归 ...

  6. 维特比(Viterbi)算法

    算法思想 维特比(Viterbi)算法属于一种动态规划算法,目标在于寻找最优路径.我个人用得最多就是与BiLSTM+CRF模型的结合,比如命名实体识别.分词等,计算了每个token的归一化概率矩阵和转 ...

  7. deeplearning算法优化原理

    deeplearning算法优化原理 目录 • 量化原理介绍 • 剪裁原理介绍 • 蒸馏原理介绍 • 轻量级模型结构搜索原理介绍 Quantization Aware Training量化介绍 1.1 ...

  8. Viterbi 算法无线通信信号处理Demo

    问题描述 信道H长度L=3,H = (h0,h1,h2),其中h0=,h1=,h2=; 基本信号类型 x =10或-10,一个完整的信号序列为X = (x0,x1,x2,...,x9);噪声W = ( ...

  9. 隐马尔可夫(HMM)、前/后向算法、Viterbi算法

    HMM的模型  图1 如上图所示,白色那一行描述由一个隐藏的马尔科夫链生成不可观测的状态随机序列,蓝紫色那一行是各个状态生成可观测的随机序列 话说,上面也是个贝叶斯网络,而贝叶斯网络中有这么一种,如下 ...

最新文章

  1. Java中this的简单应用
  2. Java 并发工具箱之concurrent包
  3. html 微信发送给朋友,H5链接分享给微信好友,显示标题、描述、缩略图
  4. 一个 IT 青年北漂四年的感悟
  5. 2018年排名Top 100的Java类库——在分析了277,975份源码之后得出的结论
  6. mysql可以存储整数数值的是_MySQL知识树 数值类型 整数
  7. dubbo分布式系统链路追踪_zipkin
  8. *** error 65: access violation at C:0x001B : no 'execute/read' permission
  9. qt分割获取文件路径(去文件名)
  10. 81相似标准形02——初等变换、初等矩阵、相抵 (等价)、相抵标准形
  11. OPPO 实时数仓揭秘:从顶层设计实现离线与实时的平滑迁移
  12. UAV运动学方面的约束
  13. H3C网络暑期培训大作业-某银行支行内部网络整改方案
  14. win环境下jdk7与jdk8共存问题
  15. 8m照片宽和高是多少_8寸照片的大小
  16. 英文版win11怎么变成中文版?英文版win11改中文版教程
  17. Linux部署禅道在访问web页面进入www时报错:mysql无法连接(重新解压安装包或者输入命令:setenforce 0即可)
  18. 向量叉乘算子、点乘算子与矩阵运算的关系
  19. 让人心动的jQuery插件和HTML5动画
  20. 立个Flag,2019加油!

热门文章

  1. Unity WebGL/WebPlayer与html通信对比,在html添加网页端按钮直接测试
  2. vim报错E37: No write since last change E162: No write since last change for buffer “xxx“
  3. 计算机房消防应急预案,计算中心机房火灾应急预案
  4. linux 邮件服务器pop3,linux下的邮件服务器
  5. 《软件工程》期末复习题型整理
  6. 计算机的选项卡,电脑的选项卡是什么?在哪里可以找出
  7. 申宝股票-年线短线注意量能信号变化
  8. 对象(object)
  9. 西门子PLC 简单启停功能实现
  10. 彻底删除百度搜索框历史记录