HuSharp | Blog - Topic - Résumé | RSS

自己动手画 CPU《计算机组织与结构实验》(一)

# cpu, 2020-09-28

配套慕课

一、计算机数据表示

1、汉字国标码转区位码实验

【实验要求】

理解汉字机内码、区位码,最终能利用相关工具批量获取一段文字的 GB2312 机内码,并利用简单电路实现 GB2312 编码与区位码的转换;

输入引脚为16位的 GB2312 双字节国标码;输出为区号和位号(区号位号均从1开始计数),请在电路中复制对应隧道标签信号使用,注意不要增改引脚,不要修改子电路封装,以免影响子电路在其它电路模块中的正常调用。

image-20200928154753459

原理:

区位码 = GB2312 汉字机内码 - 0xA0A0

信号 输入/输出 位宽 说明
GB2312 输入 16 位 汉字机内码
区号 输出 7 位 汉字区位码中的区号—行号 ROW
位号 输出 7 位 汉字区位码中的位号—列号 COL

用到求补器,或者手算[0xA0A0]补。

注意:5f60 即为 A0A0 的补码,至于 dfe0 也能通过,是由于第 8 位 和第 16 位 不用考虑

2、汉字机内码获取实验

【实验要求】

​完成国标码到区位码的转换电路后,可以在汉字显示电路中进行测试,尝试在下图所示电路中的 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;
}

image-20200928155921478

将区位码复制到保存ROM数据的txt文本

标注开头为 v2.0 raw

image-20200928160011121

导入 txt 文件数据到 ROM

image-20200928160102594

最终完成电路

image-20200928155358761

3、偶校验编码设计

【实验要求】

掌握奇偶校验基本原理和特性,能在 Logisim 中实现偶校验编码电路,检错电路,理解校验码传输的原理。

【思路】

偶校验,即加上校验位,一共有偶数个1;而校验位由原始数据的 1 的个数异或决定——当实际数据中“1”的个数为偶数的时候,这个校验位就是“0”,否则这个校验位就是“1”。

0100101 偶校验码就是 01001011

可用异或门求校验位。

image-20200928160753056

4、偶校验检错电路设计

【实验目的】

检错码为将原始 数据位+校验位 异或后构成 17 位的校验码进行异或,得到检错位。1 表示有错,0 表示无错。

原理是:校验码是 1 的个数为 偶数就为 0,因此,若

信号 输入/输出 位宽 说明
校验码 输入 17 位 最高位为偶校验位的偶校验数据
检错位 输出 1 位 1 表示有错,0 表示无错
数据位 输出 16 位 无冗余信息的原始数据

没有干扰时,显示字体一致。

image-20200928162400494

由于发生两位错,因此无法检验出错误,显示误报

image-20200928162521383

发生三位错(奇数位),检测出错误。

image-20200928162712934

当干扰码是让第 8 位 和第 16 位变化时,不会变化(取决于A0A0的补码取得是值是否考虑了第 8 位 和 第 16 位。

现在情况为:

1.dfe0 即 8 位 和 16 位 始终为 1,随机干扰为 8080 时不会变化

image-20200928170332374

2.5f60 即 8 位 和 16 位 始终为 0,随机干扰为 8080 时会变化

image-20200928170452176

另外两种情况就不贴出来了,通过一小时思考(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 发生进位,因此会变化。

image-20200928180931268

5、16位海明编码电路设计

【实验目的】

掌握海明码设计原理与检错纠错性能,能独立设计实现汉字 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位上。

image-20201003153924941

​ 为区分一位错和两位错,需要额外引入总偶校验位P——在海明码检错码报错时,如果总检错码为 0 ,则表示 2 位错;如果总检错码为 1,则表示出现 1 位错。(这是在假定没有出现 3 位以上错的情况)

思路很简单,就是对于

类似image-20201003162846379

进行异或处理

总检测位则是对全部进行检测

image-20201003162821169

6、16位海明解码电路设计

引入 G6 进行错误位数判断。是由于当发生 2 位错时:假设 H3 (0011)、H5(0101) 同时发生错误,由于 H3 参与 G1G2,H5参与G1G3,G1发生两位错因此无法检错,G3、G5发生一位错,因此构成纠错码为 0110,与 发生一位错 H6 的检错码一致,因此产生矛盾。

至于 G6 为何选择全部数据的异或,是为区分是 1 位错,还是 2 位错,当 发生 1 位错时,那么G6则为 1,发生 2 位错时,G6 为 0。

image-20201003232234022

首先介绍解码器

当为 全 0 时, 0 位输出 1.

image-20201003223817970

当选择位为 1000 即表示 8 时,那么第 8 位便会置为 1。

image-20201003223925770

因此现在 G5G4G3G2G1 就表示是第 x 位错误。

且 G5G4G3G2G1 的电路图就是 P1 异或上 得到 P1 的电路。

eg G5:

image-20201003231945406

采取与门进行错误位数选择。

完成核心电路如图。

纠正数据功能:将输入数据换成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,是无的。

image-20201003231503413

7、16位CRC并行编解码电路设计

首先,了解实验的大体要求,该实验要求我们对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。

image-20201004195840800

首先进行串行编码电路的介绍:

1.CRC串行编码电路

D触发器作用为 锁存。即保存输入值。

serial_in 慢慢进入触发器,位数向左移动,与模 2 的除法步骤一致。最终当serial_in 全部输入完成时,D4D3D2D1 即为所求余数。

image-20201004170716133

时间复杂度较高,需要 n-1 个时钟周期才能完成。因此运算速度慢,高速设备普遍采用并行CRC编解码

2.CRC并行编码电路

image-20201004194501717

因此可先对该 16 位数据按位与该多项式 (此处为 100101)进行模 2 除运算,再根据其实际数据进行异或操作。

image-20201004194524455

因此根据该思路,先将 16 位原始数据所对应位置上取 1 时,与G(x)进行模2除运算得到各自的5位余数,再用选择器根据每一位数据选择输入的是余数还是0,最后将16个输入数据进行异或,即可得到5位最终的余数。

③选择器的使用原理:

image-20201004200933116

因此各位取 1 时与多项式模2除运算后的余数如下所示:

image-20201004220650902

编码电路总览

image-20201004220603149

3.CRC并行解码电路

该电路会比较难理解,要进行检错以及数据纠正得到原始的16位数据。

1.检错原理

image-20201004205823945

1、接收方在接受到 CRC 编码后,将该编码与多项式进行模2除运算,得到余数r’,再根据 r6( r6 为总的奇偶检验位,将所有数据进行异或可得)的值进行判断数据是否产生错误,及产生错误后是一位错还是两位错。其检查原理同海明码的检错原理相同。 有以下情况:

由上图可知,CRC 编码最后的 r 位少于多项式位数,因此可将最后 r 位看作一个整体,让它与多项式进行模 2 除运算后,得到的余数显然是它本身,因此让它与其它16位数据与G(x)模2除后所得的余数进行异或,即可得最后接收方检验的余数。

下图箭头所指位置得到的便是最终 5 位余数。

image-20201004210942193

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 则不变

​因此需要采用或非门 + 异或门进行判断

image-20201004213813453

② CRC编码按位取反(即按位异或1)后再与G(x)进行模2除运算,根据公式可化成 CRC编码%G(x) 异或 该数据位取1%G(x)。

例如:假设第 7 位出错 (CRC%100101)异或(100 0000%100101) = (CRC%100101)异或 0a。

最终电路总览

image-20201005150355384

8、流水传输实验(海明码与CRC思路一致)

1.五段流水线模拟

同步清零,气泡,高电平有效

使能端,低电平有效,stall,高电平有效

image-20201005162854350

流水线演示:分为多个阶段

image-20201005162958819

主要目的是:增加 两位错重传机制。类似指令流水线中的分支指令 作用:保证接收端接收顺序和ROM中一致

实现:

  1. 让发送端地址回滚。(类似指令流水线分支处理的分支跳转)
  2. 清空除最后一个外流水接口中的所有数据。(类似指令流水线分支处理的清空误取指令)
  3. 最后一个流水接口停止接受数据。(类似指令流水线数据处理的流水线暂停)

解题思路:

  1. 发送端地址回滚,类似指令流水线分支处理的分支跳转

    image-20201005170649250

    ​ 在这里选用选择器,当无发生两位错误时,此时箭头所指的输入端为 0 ,此时选择器选择第 0 位的数据输入即将01输入,常量和加法器,寄存器够成的电路实现的是 x=x+01 的功能,即类似于计数器。因此无发生两位错时,不需要进行地址回滚。 ​ 当发生两位数据的出错时,此时输入的是 fd ,即-3(8位二进制)的补码表示,因为此时是加法器,因此减3,要用补码进行表示成 fd ,从而实现地址回滚。

    为什么是减3,这里解释一下: 假设华字发生两位错,且其他数据的传送都如下图所示

    image-20201005171046679

    ​ 此时,要将华字回滚到取数阶段,然而此时的取数阶段的对应序号为 4 ,而华字的对应序号为1,因此 4-3=1,故此时的加法器的输入端应该为 -3(八位二进制),则其对应补码为fd。

  2. 清空前段数据(气泡逻辑) 类似指令流水线分支处理的清空误取指令

    由于流水线存在:同步清零,气泡,高电平有效

    因此对全部步骤采用清零即可

    image-20201005171416289

    进行同步清0,必须在两种状态都满足的条件下进行,该两种状态是:

    • 发生两位错
    • 传送数据有效。

      发生两位错再进行同步清0是不言而喻的;数据有效,表明当前传送的数据是有效的。如果数据无效的话,数据都无效了,有无发生两位错和是否重传都是没有必要的。

  3. 暂停显示阶段的动作( Stall 信号控制) 类似指令流水线数据相关处理的流水线暂停

    此时数据发生两位错误时,该数据不应该传入显示阶段中,显示阶段应该继续显示上个数据,即暂停显示阶段的动作。

    image-20201005171603991

    至于标签 en5 所连接的便是该 16 位流水接口的使能端(高电平有效),当使能端为 1 时,忽略时钟的输入,即错误数据不会传入该阶段,仍然继续显示上个数据。 有两种情况应该暂停显示阶段的动作: ①发生两位的错误时 ②数据无效时 这两种情况,若其中有一种情况发生,都应该暂停显示阶段的动作。

最终电路展示

image-20201005171743029