# cpu, 2020-09-28
【实验要求】
理解汉字机内码、区位码,最终能利用相关工具批量获取一段文字的 GB2312 机内码,并利用简单电路实现 GB2312 编码与区位码的转换;
输入引脚为16位的 GB2312 双字节国标码;输出为区号和位号(区号位号均从1开始计数),请在电路中复制对应隧道标签信号使用,注意不要增改引脚,不要修改子电路封装,以免影响子电路在其它电路模块中的正常调用。
原理:
区位码 = GB2312 汉字机内码 - 0xA0A0
信号 | 输入/输出 | 位宽 | 说明 |
---|---|---|---|
GB2312 | 输入 | 16 位 | 汉字机内码 |
区号 | 输出 | 7 位 | 汉字区位码中的区号—行号 ROW |
位号 | 输出 | 7 位 | 汉字区位码中的位号—列号 COL |
用到求补器,或者手算[0xA0A0]补。
注意:5f60 即为 A0A0 的补码,至于 dfe0 也能通过,是由于第 8 位 和第 16 位 不用考虑
【实验要求】
完成国标码到区位码的转换电路后,可以在汉字显示电路中进行测试,尝试在下图所示电路中的 ROM 存储器中存入下面给出的指定句子,注意这里不允许使用逐字查码表的方式获得编码,应掌握批量转换的方法和原理。
指定句子如下:请思考数字,英文字符怎么输入和显示的。 12345ABCDEFGabcdefg轻轻的我走了,正如我轻轻的来;我轻轻的招手,作别西天的云彩。那河畔的金柳,是夕阳中的新娘;波光里的艳影,在我的心头荡漾。
【思路】
可通过编写程序方法从计算机中得到汉字的机内码, C语言规定符%x显示无符号以十六进制表示的整数。
#include<stdio.h>
int main(void)
{
unsigned char temp[1000];
printf("请输入汉字:\n");
scanf("%s",temp);
printf("\n其区位码为:\n");
int i;
for(i=0; temp[i]!='\0'; i++)
{
printf("%.2x",temp[i]);
if((i+1)%16==0) printf("\n");
else if((i+1)%8==0) printf(" ");
else if((i+1)%2==0) printf(" ");
else continue;
}
return 0;
}
将区位码复制到保存ROM数据的txt文本
标注开头为 v2.0 raw
导入 txt 文件数据到 ROM
最终完成电路
【实验要求】
掌握奇偶校验基本原理和特性,能在 Logisim 中实现偶校验编码电路,检错电路,理解校验码传输的原理。
【思路】
偶校验,即加上校验位,一共有偶数个1;而校验位由原始数据的 1 的个数异或决定——当实际数据中“1”的个数为偶数的时候,这个校验位就是“0”,否则这个校验位就是“1”。
0100101 偶校验码就是 01001011
可用异或门求校验位。
【实验目的】
检错码为将原始 数据位+校验位 异或后构成 17 位的校验码进行异或,得到检错位。1 表示有错,0 表示无错。
原理是:校验码是 1 的个数为 偶数就为 0,因此,若
信号 | 输入/输出 | 位宽 | 说明 |
---|---|---|---|
校验码 | 输入 | 17 位 | 最高位为偶校验位的偶校验数据 |
检错位 | 输出 | 1 位 | 1 表示有错,0 表示无错 |
数据位 | 输出 | 16 位 | 无冗余信息的原始数据 |
没有干扰时,显示字体一致。
由于发生两位错,因此无法检验出错误,显示误报
发生三位错(奇数位),检测出错误。
当干扰码是让第 8 位 和第 16 位变化时,不会变化(取决于A0A0的补码取得是值是否考虑了第 8 位 和 第 16 位。
现在情况为:
1.dfe0 即 8 位 和 16 位 始终为 1,随机干扰为 8080 时不会变化
2.5f60 即 8 位 和 16 位 始终为 0,随机干扰为 8080 时会变化
另外两种情况就不贴出来了,通过一小时思考(555),终于明白一个问题:
即要想明白补码加法和异或运算发生时刻。以及进位的发生。
先说明一开始困扰我半小时的错误思路:
一开始认为:
发现规律为:当为0x80时,df60 5f60 会变化,dfe0 5fe0 不会变化。即 —— 第 8 位的变化改变字符。
这是由于补码去参与加法运算,若补码为 1 ,那么会发生进位(dfe0 5fe0),区号 +1;若补码为 0,不发生进位(df60 5f60)。
而随机干扰是异或运算(改变数据),当为0x80的干扰码时,区位码为 0 会变为 1 后,再发生进位。
但是在验证这个规律时:突然发现没有考虑除了 第 8 位 以外的 其他位进位情况:(以下是没考虑时错误思路)
若此时为 dfe0 5fe0,由于区位码第 8 位为 1,0x80异或之前会发生进位,0x80异或之后变为 0 ,不会发生进位。
若此时为 df60 5f60,由于区位码第 8 位为 1,0x80异或之前不会发生进位,0x80异或之后变为 1 ,不会发生进位。
现在便明白了:第 8 位是否发生进位才是最终问题所在。(进位取决于A0A0补码的取值)
比如此时 a393: 100 0110 1001 0110,与 第 5-8位:0110必然不会发生进位
而上图 bfc6:1011 1111 1100 0110 与第 5-8位 0110 发生进位,因此会变化。
【实验目的】
掌握海明码设计原理与检错纠错性能,能独立设计实现汉字 GB2312 编码的海明校验编码体系,并最终在实验环境中利用硬件电路实现对应的编解码电路。
原理是:
k+n<=2^r-1,此时k=16,r=5(有5位的校验位),因此总的数据位数有16+5+1(总的奇偶校验位)=22位。设校验位为Pi(i=1,2,3,4,5),分别位于22位数据的第2的i-1次方的位置上,故分别位于第1,2,4,8,16位上。
为区分一位错和两位错,需要额外引入总偶校验位P——在海明码检错码报错时,如果总检错码为 0 ,则表示 2 位错;如果总检错码为 1,则表示出现 1 位错。(这是在假定没有出现 3 位以上错的情况)
思路很简单,就是对于
类似
进行异或处理
总检测位则是对全部进行检测
引入 G6 进行错误位数判断。是由于当发生 2 位错时:假设 H3 (0011)、H5(0101) 同时发生错误,由于 H3 参与 G1G2,H5参与G1G3,G1发生两位错因此无法检错,G3、G5发生一位错,因此构成纠错码为 0110,与 发生一位错 H6 的检错码一致,因此产生矛盾。
至于 G6 为何选择全部数据的异或,是为区分是 1 位错,还是 2 位错,当 发生 1 位错时,那么G6则为 1,发生 2 位错时,G6 为 0。
首先介绍解码器
当为 全 0 时, 0 位输出 1.
当选择位为 1000 即表示 8 时,那么第 8 位便会置为 1。
因此现在 G5G4G3G2G1 就表示是第 x 位错误。
且 G5G4G3G2G1 的电路图就是 P1 异或上 得到 P1 的电路。
eg G5:
采取与门进行错误位数选择。
完成核心电路如图。
纠正数据功能:将输入数据换成G5G4G3G2G1,将该解码器的第1位至23位用分离器连接起来,如下图所示(此时,如果G5G4G3G2G1等于某个不为0的数据时,该数据对应数位将会输出为1)。将该22位数据与原来的海明码进行按位异或,则可得到原来无出错的数据,即进行纠正。也因此错 1 位可以纠正,错 2 位不能纠正。因为错 1 位可以指示出那一位,而错 2 位会指示两位的和。 (提示:x异或0=x,x异或1=x的非)
注意:由于要获得纠正后的数据,即16位数据,由于该数据是从0开始的,故其检验位分别位于0,1,3,7,15,21上,因此要去掉这些位置的数据,即可得到原来的16位数据。因此采用分离器输出的时候,位宽仍然是22位,但是位0,位1,位3,位7,位15,位21,是无的。
首先,了解实验的大体要求,该实验要求我们对16位数据进行CRC编码,生成22位数据;再将22位CRC编码进行解码成16位数据,且判断数据是否在传输过程中发生一位错,两位错的情况,若出错,则必须对数据进行纠正。因此该实验要进行两个的电路图的设计。
任务:实现16位原始数据的CRC编码,假定没有三位错,能纠正一位错
1.解题思路
① 已知该实验输入的是16位数据,输出22位CRC编码数据,其中包括16位原始数据,6位校验位,其中一位为总的奇偶校验位(校验位的位数也可由k+r<=2^r-1得到)。因此此时的 r=5(不包含奇偶校验位),选择的多项式G(x)位数则为 r+1=6位,此时我选择的多项式是 G(x)=100101(该多项式不固定,选择其它六位的多项式也可以)。
② CRC编码原理:原始16位数据Q(X),左移 r=5 位成21位Q’(x)(即后面补r个0),再与多项式 100101 做模 2 运算,得到的 r 位的余数,将该余数替换掉 Q’(X) 后面的 r 位,即将它后面的 r 个 0 替换成该余数。如图所示 r5r4r3r2r1 便是得到的余数,而r6是总的奇偶校验位,对所有数据进行异或便可得到该偶校验位 r6。
首先进行串行编码电路的介绍:
D触发器作用为 锁存。即保存输入值。
serial_in 慢慢进入触发器,位数向左移动,与模 2 的除法步骤一致。最终当serial_in 全部输入完成时,D4D3D2D1 即为所求余数。
时间复杂度较高,需要 n-1 个时钟周期才能完成。因此运算速度慢,高速设备普遍采用并行CRC编解码
因此可先对该 16 位数据按位与该多项式 (此处为 100101)进行模 2 除运算,再根据其实际数据进行异或操作。
因此根据该思路,先将 16 位原始数据所对应位置上取 1 时,与G(x)进行模2除运算得到各自的5位余数,再用选择器根据每一位数据选择输入的是余数还是0,最后将16个输入数据进行异或,即可得到5位最终的余数。
③选择器的使用原理:
因此各位取 1 时与多项式模2除运算后的余数如下所示:
编码电路总览
该电路会比较难理解,要进行检错以及数据纠正得到原始的16位数据。
1.检错原理
1、接收方在接受到 CRC 编码后,将该编码与多项式进行模2除运算,得到余数r’,再根据 r6( r6 为总的奇偶检验位,将所有数据进行异或可得)的值进行判断数据是否产生错误,及产生错误后是一位错还是两位错。其检查原理同海明码的检错原理相同。 有以下情况:
由上图可知,CRC 编码最后的 r 位少于多项式位数,因此可将最后 r 位看作一个整体,让它与多项式进行模 2 除运算后,得到的余数显然是它本身,因此让它与其它16位数据与G(x)模2除后所得的余数进行异或,即可得最后接收方检验的余数。
下图箭头所指位置得到的便是最终 5 位余数。
2.纠错,得原始16位数据
① 若CRC编码发生出错,而它的出错位可能为第 7,8,9…22位(不考虑第1到6位,因为我们要得的原始16位数据处于第7…22位上,因此只需要判断这些位是否出错,若出错对它们进行纠正,再输出即可)。
因此将CRC编码按照每一位取反后再与G(x)进行模2除运算(如下图),若余数为0,则说明该位出错,因此将余数取反为1,再与该位数据进行异或从而纠正该位的数据;若余数不为0,则说明该数据位并未发生传输错误,因此对该余数取反为0,再与该位的数据进行异或得到的数据仍为该数据位。(x 异或 0 = x,x 异或 1 = x 反)
若采用或门,那么:若余数为 1 则为 1,而余数为 0 则说明该位错误,需要取反,为 1 则不变
因此需要采用或非门 + 异或门进行判断
② CRC编码按位取反(即按位异或1)后再与G(x)进行模2除运算,根据公式可化成 CRC编码%G(x) 异或 该数据位取1%G(x)。
例如:假设第 7 位出错 (CRC%100101)异或(100 0000%100101) = (CRC%100101)异或 0a。
最终电路总览
1.五段流水线模拟
同步清零,气泡,高电平有效
使能端,低电平有效,stall,高电平有效
流水线演示:分为多个阶段
主要目的是:增加 两位错重传机制。类似指令流水线中的分支指令 作用:保证接收端接收顺序和ROM中一致
实现:
解题思路:
发送端地址回滚,类似指令流水线分支处理的分支跳转
在这里选用选择器,当无发生两位错误时,此时箭头所指的输入端为 0 ,此时选择器选择第 0 位的数据输入即将01输入,常量和加法器,寄存器够成的电路实现的是 x=x+01 的功能,即类似于计数器。因此无发生两位错时,不需要进行地址回滚。 当发生两位数据的出错时,此时输入的是 fd ,即-3(8位二进制)的补码表示,因为此时是加法器,因此减3,要用补码进行表示成 fd ,从而实现地址回滚。
为什么是减3,这里解释一下: 假设华字发生两位错,且其他数据的传送都如下图所示
此时,要将华字回滚到取数阶段,然而此时的取数阶段的对应序号为 4 ,而华字的对应序号为1,因此 4-3=1,故此时的加法器的输入端应该为 -3(八位二进制),则其对应补码为fd。
清空前段数据(气泡逻辑) 类似指令流水线分支处理的清空误取指令
由于流水线存在:同步清零,气泡,高电平有效
因此对全部步骤采用清零即可
进行同步清0,必须在两种状态都满足的条件下进行,该两种状态是:
传送数据有效。
发生两位错再进行同步清0是不言而喻的;数据有效,表明当前传送的数据是有效的。如果数据无效的话,数据都无效了,有无发生两位错和是否重传都是没有必要的。
暂停显示阶段的动作( Stall 信号控制) 类似指令流水线数据相关处理的流水线暂停
此时数据发生两位错误时,该数据不应该传入显示阶段中,显示阶段应该继续显示上个数据,即暂停显示阶段的动作。
至于标签 en5 所连接的便是该 16 位流水接口的使能端(高电平有效),当使能端为 1 时,忽略时钟的输入,即错误数据不会传入该阶段,仍然继续显示上个数据。 有两种情况应该暂停显示阶段的动作: ①发生两位的错误时 ②数据无效时 这两种情况,若其中有一种情况发生,都应该暂停显示阶段的动作。
最终电路展示