近日,因为项目的需要,重新拾起编码理论,这个项目当中,发送端的信息序列添加了CRC码字,好在接收端进行CRC校验,检测接收到的信息序列是否在传输过程中出现了错误。CRC编码作为循环码字的一种,通常用在数据传输的检错中,其生成原理与循环码字的生成完全一致,其原理下面会进行说明。

1. 编码原理

循环码的码字多项式都是多项式g(D)的倍式,该g(D)的阶数为r=n-k,对于一个信息序列M(D),其码字多项式可以表示为

A(D) = D^(n-k)*M(D) + r(D),

r(D)为监督码多项式,它等于D^(n-k)*M(D)除以g(D)得到的余式,说的通俗一点,循环码的构造就是凑出一个余式r(D)使得码字多项式A(D)能够被生成多项式g(D)整除,在传输过程中码字A(D)一旦发生了错误,则接收端的码字不能够被生成多项式整除,就可以知道在传输过程中发生了错误,在循环码字的纠错范围内时,可以根据错误的图案(接收到的码字除以生成多项式的余式),找到对应错误的信息比特位。余式r(D)可以表示为

r(D) = D^(n-k)*M(D) mod g(D),

下面举个例子看看循环码字是怎么生成的。对于一个(7, 4)的系统循环码,7表示码字长度n=7,4表示编码的信息序列长度k=4,那么监督序列的长度r=n-k=3,系统码表示生成的n比特码字中,前面k个比特的码字与信息码字完全一致,只是在信息码字后添加了r个比特的校验位。言归正传,(7, 4)系统循环码的生成多项式为g(D) = D^3 + D^2 + 1,若信息码为1001,那么怎么求编码后的码字呢?我们知道,只要求出后面r个比特的监督码字就行了,前面的k个比特的码字照抄信息码字就行了。信息码字1001写成多项式的形式为

M(D) = D^3 + 1,

监督多项式通过求余得到:

r(D) = D^3*(D^3 + 1) mod (D^3 + D^2 + 1) = D + 1,

码字多项式:

A(D) = D^3*(D^3 + 1) + D + 1 = D^6 + D^3 + D + 1,

码字多项式写成序列的形式为1001011。值得一提的是,在编码过程中,所采用是GF(2)域上的加减法运算,相当于说减法也可看成加法,所有的加法都是模2加运算,即

1 + 1 = 0, 1 + 0 = 1, 0 + 1 = 1, 0 + 0 = 0,

对于k比较长的情况,写成这种多项式的形式不便于计算,这里提供另外一种表达形式,实际上都是求余式操作,不过在形式上做了简化而已。

1  1  1  1

_____________________

1101       |         1   0  0  1  0  0  0

+    1   1  0  1

----------------------------

1  0  0  0

+    1  1  0  1

-----------------------------

1  0  1  0

+   1  1  0  1

-----------------------------

1  1  1  0

+    1  1  0  1

-------------------------------

0  1  1

该方法只是将多项式操作变成了数字操作,信息序列1001后添加3个0代表乘上D^3,生成多项式D^3 + D^2 + 1写成序列形式就是1101,每次商上面的一位操作,进行模2加,余式继续同样的操作,直到补零的信息序列截止到最后一位,剩下的余式011即为监督序列,两种方法原理相同,当然结果也是相同的。

2. 硬件电路

上面的硬件电路图就是生成多项式g(D) = D^3 + D^2 + 1,对应的循环码字生成电路,至于为什么是这样,笔者表示上课时,老师也没讲,自己也并未深究,为了应付考试,强行记住了,然而到了做项目的时候,才发现自己对该电路完全没搞懂,于是乎,琢磨了一番,总算是搞明白了,下面且听我细细道来。

首先,讲一下硬件电路对应的时序控制,由于该循环码字是系统码,生成的码字在前k=4个比特是将信息序列直接输出,也即与门1在1拍~4拍是开启的,信息序列进行编码,但输出相关的与门2是关闭的,与门2的输出在前4拍一直是0,在或门处,信息序列直接输出;到了5拍~7拍,需要输出监督序列了,这是信息序列已经全部处理完毕,监督序列完全寄存在了D1~D3这3个寄存器中,只要将这3比特的监督序列直接输出即可,这时与门1在5拍~7拍关闭,与门2在5拍~7拍开启,或门输出的是寄存器直接出来的监督序列。

接下来,我们看看电路的左半部分是如何由信息序列生成监督序列的。我们看生成多项式g(D) = D^3 + D^2 + 1,对应到图上寄存器D3和D2后面的异或门,通过反馈操作实现除法求余操作。它的生成原理与第一小节编码原理给出的基本相同,但不同的地方是,由于信息比特是按照时钟逐比特输入的,没办法做到像编码原理给出的将这个信息序列对生成多项式求余,而是每进来一个信息比特,进行判断,然后操作。具体是啥意思呢,我讲个例子就清楚了。,

信息序列还是1001,初始状态时,D1~D3三个寄存器的值都为0,输入的第一个信息比特是1,与D3的异或是1,这里为什么输入序列与D3做异或呢?其实这里隐含了一个选择操作,D1~D3代表当前的余式,D3表示余式的最高位,如果当前的输入与当前的余式最高位D3相同的话,则当前输入与余式的模2加为0,即当前输入更新使得余式最高位为0,则此时商上面上0,不用对生成多项式做模2加运算,余式只要右移一位完成余式的更新操作(一个比特与0异或等于自身,所以这种情况下,电路中异或不起作用);另一种情况是,当前的余式最高位D3与当前输入序列异或为1,表示当前输入更新后余式包含最高位,需要对生成多项式求余,求余操作通过电路中的异或进行,完成D1~D3的更新。具体步骤如下:

(1) 初始状态:                       输入ui             D1    D2    D3                   输出uo

0       0        0

(2)                                              1                     1       0        1                         1

(3)                                              0                     1       1        1                         0

(4)                                              0                     1       1        0                         0

(5)                                              1                     1       1        0                         1

D1~D3剩下的011即为监督比特,剩下3拍,逐比特输出:

(6)                                              0                     0       1        1                         0

(7)                                              0                     0       0        1                         1

(8)                                              0                     0       0        0                         1

3. FPGA实现

根据第二部分的电路原理分析,我们可以将循环码的编码分成两个阶段,第一个阶段为编码阶段,码字输出选择信息序列的输入直接作为输出;第二阶段为监督码字输出阶段,在第一阶段的最后,监督码字实际上已经完全生成,存储在寄存器中,第二阶段的任务就是将监督码字逐个输出,由此可以通过状态机实现该操作。状态机可以设置三种状态:IDLE, ENCODING, OUT。IDLE状态表示状态机处于空闲状态,不进行任何操作;ENCODING状态时,状态机进行输入信息序列的循环编码,同时输出信息码字;OUT状态时,输出监督码字。下面将采用verilog语言实现循环码的编码过程:
module cyc_encoding(
input                       clk,
input                       rst_n,
input                       e_start_i,                //编码启动信号,比第一个信息序列早一个时钟周期
input                       symbol_i,                //输入信息序列
output reg              e_start_o,               //输出启动信号
output reg              symbol_o                //输出编码序列
);
// 常量定义
parameter INFO_BITS_LEN = 4;          //信息序列长度
parameter CODED_BITS_LEN = 7;     //编码码字长度
wire enable;
wire encoding_start;
wire encoding_end;
reg [2:0] symbol_cnt;
// 状态机定义
parameter IDLE = 3'b001;
parameter ENCODING = 3'b010;
parameter OUT = 3'b100;
reg [2:0] state;
/**********************************************************/
// 编码状态机
/**********************************************************/
always @(posedge clk)
begin
if(!rst_n)
state <= IDLE;
else begin
case(state)
IDLE:  state <= e_start_i ? ENCODING : IDLE;
ENCODING:  state <= encoding_start ? OUT : ENCODING;
OUT:  state <= encoding_end ? IDLE : OUT;
default:  state <= IDLE;
endcase
end
end
assign enable = (state != IDLE);
/**********************************************************/
// 符号计数器
/**********************************************************/
always @(posedge clk)
begin
if(!rst_n)
symbol_cnt <= 3'd0;
else
symbol_cnt <= enable ? (symbol_cnt + 1'b1) : 3'd0;
end
assign encoding_start = (symbol_cnt == INFO_BITS_LEN -1);
assign encoding_end = (symbol_cnt == CODED_BITS_LEN -1);
reg [2:0] encoding_reg;
/**********************************************************/
// 寄存器更新操作
/**********************************************************/
always @(posedge clk)
begin
if(!rst_n)
encoding_reg <= 3'd0;
else begin
case(state)
IDLE:  encoding_reg <= 3'd0;
ENCODING:
begin
encoding_reg[0] <= encoding_reg[2] ^ symbol_i;
encoding_reg[1] <= encoding_reg[0];
encoding_reg[2] <= encoding_reg[1] ^ encoding_reg[2] ^ symbol_i;
end
OUT:  encoding_reg <= {encoding_reg[1:0], 1'b0};
default:  encoding_reg <= 3'd0;
endcase
end
end
/**********************************************************/
// 输出编码后的符号
/**********************************************************/
always @(posedge clk)
begin
if(!rst_n)
symbol_o <= 1'b0;
else begin
case(state)
IDLE:  symbol_o <= 1'b0;
ENCODING:  symbol_o <= symbol_i;  //信息序列
OUT:  symbol_o <= encoding_reg[2];  //监督序列
default:  symbol_o <= 1'b0;
endcase
end
end
/**********************************************************/
// 启动信号输出
/**********************************************************/
always @(posedge clk)
begin
if(!rst_n)
e_start_o <= 1'b0;
else
e_start_o <= e_start_i;
end

循环码生成原理与FPGA实现相关推荐

  1. 【边学边记_12】——VGA原理与FPGA实现

    VGA原理与FPGA实现 推荐参考小梅哥视频学习 使用FPGA驱动VGA不适合用来显示复杂多变的图像内容,但是却常用于显示实时图像内容,例如显示图像传感器实时采集到的图像.此种方式数据流由图像传感器实 ...

  2. LFSR线性反馈移位寄存器循环码编码原理

    线性反馈移位寄存器(LFSR)循环码编码原理    作为知识储备,近日在学习循环码编码的原理,教材为John G.Proakis和Masoud Salehi所著的<数字通信>第五版,循环码 ...

  3. 1024点fft原理及fpga实现

    1024点fft原理及fpga实现 关于傅里叶变换的原理,可以参考以下的博文: 如何理解傅里叶变换公式. FFT即快速傅里叶变换,是有限长序列作离散傅里叶变换(DFT)的快速算法. DFT公式为 X[ ...

  4. [html] 你知道短链接的生成原理吗?

    [html] 你知道短链接的生成原理吗? 目的将长度较长的链接压缩成较短的链接,并通过跳转的方式,将用户请求由短链接重定向到长链接上去1.二种方式生成短链hash-可能会重复发号器发号压缩 URL2. ...

  5. [html] 你知道短链接的生成原理吗?

    [html] 你知道短链接的生成原理吗? 目的将长度较长的链接压缩成较短的链接,并通过跳转的方式,将用户请求由短链接重定向到长链接上去1.二种方式生成短链hash-可能会重复发号器发号压缩 URL2. ...

  6. 基于 Tracing 数据的拓扑关系生成原理

    背景 随着互联网架构的流行,越来越多的系统开始走向分布式化.微服务化.如何快速发现和定位分布式系统下的各类性能瓶颈成为了摆在开发者面前的难题.借助分布式追踪系统的调用链路还原能力,开发者可以完整地了解 ...

  7. 二维码的生成原理是什么

    二维码是一种用来表示文本或者网址的图像,它通常是一个黑白相间的方块组成的图案.二维码的生成原理是将文本或者网址先编码成一个二进制数据流,然后在图像中用不同的黑白色块来表示这些二进制数据.在生成二维码时 ...

  8. java domino 单点登录_Domino单点登录LTPAtoken生成原理

    Domino单点登录LTPAtoken生成原理 一.WebSphere与Domino之间的SSO 首先让我们来了解一下Websphere与Domino之间是怎么完成SSO的: 1.Web用户向Webs ...

  9. 第一章:costmap_2d代价地图生成原理

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 (1)[代价地图]costmap_2d功能包源码解读 (1)代价地图 ...

最新文章

  1. 1.26 Java使用自定义包
  2. TIOBE 1 月榜单:Python年度语言四连冠,C 语言再次第一
  3. NB-IoT将给智能锁行业带来哪些影响?
  4. java并发编程实战学习(3)--基础构建模块
  5. 想写好前端,先练好内功
  6. M1: 复制带随机指针的链表
  7. zTree动态添加节点
  8. ios笔试题算法_【2018年最新】iOS面试题之常见算法
  9. linux纯没网安装mysql_实用性Linux安装mysql
  10. python3数据库同步_Python同步Mysql不同数据库的表
  11. Mysql 计算经纬度距离
  12. 华为的人力资源体系的变革
  13. 人脸识别技术 近期文献整理30篇
  14. Python笔记五(写excel,加密模块,字典排序,常用的标准模块,操作mysql,时间模块)...
  15. c语言strstr的使用及模拟实现strstr函数
  16. android 读文字软件,文字语音朗读软件
  17. python中的怎么打出来_如何在Python中打印上标?
  18. Java实现OPC UA Client直接与PLC通讯
  19. css中文字体乱码解决方案:
  20. 铜陵新松工业机器人项目_首期投资约12亿元 新松机器人(苏州)未来科技城项目在苏州相城开工奠基...

热门文章

  1. 破解极域——jiyu trainer
  2. 邢台市工业机器人集成商_十大优秀工业机器人系统集成商分析
  3. 海尔小神童XQB40-F型波轮全自动洗衣机控制系统分析
  4. 艾默生质量流量计的正确安装
  5. android仿百度外卖波浪_Android实现波浪球效果
  6. 边缘和物联网学术资源
  7. 九章算法 | Google 面试题:Same Number
  8. 全球与中国信封夹市场前景动态与未来发展趋势报告2022-2028年
  9. 关于Matlab与STK互联问题
  10. 久违了,AV终结者病毒