0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

卷积码编码及译码算法的基本原理

FPGA设计论坛 来源:CSDN技术社区 作者: whustxsk 2022-04-28 15:02 次阅读

引言

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

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

卷积码编码

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

85aff190-c6c0-11ec-bce3-dac502259ad0.png

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

85bef1e0-c6c0-11ec-bce3-dac502259ad0.png

译码算法

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

编码及译码算法的Matlab实现

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

85dd6198-c6c0-11ec-bce3-dac502259ad0.png

2、编码算法的FPGA实现

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

顶层代码

module convenc(

//system signals

inputclk,

inputrst_n,

inputdata_in,

outputreg [1:0] data_out

);

reg [6:0] conv_reg;

always @(posedge clk or negedge rst_n) begin

if (!rst_n) begin

conv_reg <= 7'd0;

end

else begin

conv_reg <= {data_in,conv_reg[6:1]};

end

end

always @(posedge clk or negedge rst_n) begin

if (!rst_n) begin

data_out <= 2'd0;

end

else begin

data_out[1] <= conv_reg[6]^conv_reg[5]^conv_reg[4]^conv_reg[3]^conv_reg[0];//o171

data_out[0] <= conv_reg[6]^conv_reg[4]^conv_reg[3]^conv_reg[1]^conv_reg[0];//o133

end

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

begin

clk = 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)begin

data_in = bits[i];

#10;

$fwrite(out_file,"%b %b ",data_out[1],data_out[0]);

end

end

always #5 clk = ~clk;

endmodule

仿真结果

85f121f6-c6c0-11ec-bce3-dac502259ad0.png

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。

860bc88a-c6c0-11ec-bce3-dac502259ad0.png

861bceb0-c6c0-11ec-bce3-dac502259ad0.png

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

输出数据:

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

8633d780-c6c0-11ec-bce3-dac502259ad0.png

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

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

IP核生成流程

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

86524404-c6c0-11ec-bce3-dac502259ad0.png

8672cb02-c6c0-11ec-bce3-dac502259ad0.png

868c6e04-c6c0-11ec-bce3-dac502259ad0.png

86a630dc-c6c0-11ec-bce3-dac502259ad0.png

86c0c60e-c6c0-11ec-bce3-dac502259ad0.png

在图形化配置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 begin

aclk = 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");//获取文件句柄

end

always #5 aclk = ~aclk;

//送数据

always @(posedge aclk or negedge aresetn) begin

if (!aresetn) begin

s_axis_data_tvalid <= 1'b0;

s_axis_data_tdata <= 16'd0;

i <= 9'd0;

j <= 9'd1;

end

else if (s_axis_data_tready) begin

if(i <= 9'd510)begin

s_axis_data_tvalid <= 1'b1;

s_axis_data_tdata <= {7'd0,codeData[j],7'd0,codeData[i]};

i <= i + 2;

j <= j + 2;

end

else

s_axis_data_tvalid <= 1'b0;

end

end

//取数据

always @(posedge aclk or negedge aresetn) begin

if (!aresetn) begin

m_axis_data_tready <= 1'b1;

end

else if (m_axis_data_tvalid) begin

$fwrite(out_file,"%b ",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

仿真波形:

86dd00a8-c6c0-11ec-bce3-dac502259ad0.png

原文标题:卷积码编码及维特比译码(Viterbi)算法的原理及其FPGA实现

文章出处:【微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1592

    文章

    21207

    浏览量

    592143
  • 算法
    +关注

    关注

    23

    文章

    4437

    浏览量

    90552
  • 卷积码
    +关注

    关注

    0

    文章

    19

    浏览量

    9247

原文标题:卷积码编码及维特比译码(Viterbi)算法的原理及其FPGA实现

文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是卷积码? 什么是卷积码的约束长度?

    什么是卷积码分组是把k 个信息元编成n 个码元的码字,每个码字的n ? k 个校验位仅与本码字的k 个信息元有关,而与其他码字无关。为了达到一定的纠错能力和编码效率,分组的码长一般
    发表于 05-30 16:06

    什么是硬判决和软判决Viterbi 译码算法

    Viterbi 译码算法可以简单概括为“相加-比较-保留”,译码器运行是前向的、无反馈的,实现过程并不复杂。我们来分析Viterbi 算法的复杂度: (n, k, N)
    发表于 05-30 16:11

    什么是Turbo 的迭代译码算法?当前Turbo译码算法有哪些?有哪些形式的Turbo

    BCJR 算法做了一定修正,对 α 和β 作归一化。对约束长度为N 的卷积码,每一分量,使似然加法完全变成求最大值运算,则得到MAX-LOG-MAP 算法。它大大降低了存储量和计算复杂度,而
    发表于 05-30 16:24

    如何设计基于FPGA的卷积码译码器?

    由于卷积码具有较好的纠错性能,因而在通信系统中被广泛使用。采用硬件描述语言VerilogHDL或VHDL和FPGA(FieldProgrammableGateArray——现场可编程门阵列)进行数字通信系统设计,可在集成度、可靠性和灵活性等方面达到比较满意的效果。
    发表于 10-14 06:02

    基于FPGA的Viterbi译码算法该怎么优化?

    由于卷积码优良的性能,被广泛应用于深空通信、卫星通信和2G、3G移动通信中。卷积码有三种译码方法:门限译码、概率译码和Viterbi
    发表于 11-01 08:05

    卷积码的Viterbi高速译码方案

    本文探讨了无线通信中广泛涉及的差错控制问题,介绍了卷积码的编译码原理。提出了一种卷积码编码,及其高速Viterbi 译码的实现方案,对
    发表于 01-06 15:06 12次下载

    卷积码的Viterbi高速译码方案

    本文探讨了无线通信中广泛涉及的差错控制问题,介绍了卷积码的编译码原理。提出了一种卷积码编码,及其高速Viterbi译码的实现方案,对
    发表于 07-21 17:20 22次下载

    基于OCDMA的新型卷积码译码方案

    对光码分多址(OCDMA)的误码特性和卷积码进行研究,根据两者的特点提出了一种新的基于OCDMA多址干扰信道模型的卷积码译码方法。针对这种新型卷积码
    发表于 08-26 16:40 17次下载

    卷积码/Viterbi译码,卷积码/Viterbi译码是什么

    卷积码/Viterbi译码,卷积码/Viterbi译码是什么意思 卷积码在一个二进制分组码(n,k)当中,包含k个信息位,码组长度为n,每
    发表于 03-18 14:09 2219次阅读

    基于FPGA的卷积码译码器的方案

    卷积码是深度空间通信系统和无线通信系统中常用的一种差错控制编码。它克服了分组码由于以码块为单位编译码而使分组间的相关信息丢失的缺点。(2,1,8)卷积码在2G、3G通信系统
    发表于 10-12 15:05 1545次阅读
    基于FPGA的<b class='flag-5'>卷积码</b><b class='flag-5'>译码</b>器的方案

    卷积编码之维特比译码介绍 浅析卷积码之应用

    以(n,k,m)来描述卷积码,其中k为每次输入到卷积编码器的bit数,n为每个k元组码字对应的卷积码输出n元组码字,m为编码存储度,也就是
    发表于 08-21 09:56 2842次阅读

    卷积码编码译码程序仿真程序 卷积码应用详解

    卷积码是一种差错控制编码,由P.Elias于1955年发明。因为数据与二进制多项式滑动相关故称卷积码
    发表于 08-21 10:34 3737次阅读
    <b class='flag-5'>卷积码</b><b class='flag-5'>编码</b><b class='flag-5'>译码</b>程序仿真程序 <b class='flag-5'>卷积码</b>应用详解

    在FPGA上实现咬尾卷积码的最优算法设计

    自1955年Elias发明卷积码以来,卷积码作为一种高效的信道编码已被用在许多现代通信系统中。卷积码分为零比特卷积码(Zero Tail C
    的头像 发表于 05-03 09:00 3807次阅读
    在FPGA上实现咬尾<b class='flag-5'>卷积码</b>的最优<b class='flag-5'>算法</b>设计

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

    卷积码编码器是由一个有k位输入、n位输出,且具有m位移位寄存器构成的有限状态的有记忆系统,通常称它为时序网络。编码器的整体约束长度为v,是所有k个移位寄存器的长度之和。具有这样的编码
    的头像 发表于 11-14 08:10 1.1w次阅读
    <b class='flag-5'>卷积码</b><b class='flag-5'>编码</b>和维特比<b class='flag-5'>译码</b>的原理、性能与仿真分析

    在FPGA中基于VB译码算法实现HDTV收缩卷积码的解码

    在HDTV 地面广播COFDM系统中,所用内码为收缩卷积码,除1/2主码率外,还有2/3。3/4、5/6、7/8码率的卷积编码。在实际的传输信道中,噪声一般是加性高斯白噪声(AWGN),输入AWGN
    的头像 发表于 07-11 08:01 2850次阅读
    在FPGA中基于VB<b class='flag-5'>译码</b><b class='flag-5'>算法</b>实现HDTV收缩<b class='flag-5'>卷积码</b>的解码