CPU 与简单模型机实验

news2024/9/23 19:21:13

实验报告

实验名称:

CPU 与简单模型机实验

日期:

----.--.--

班级:

-----------

学号:

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

姓名:

----------

一、实验目的:

1、

掌握一个简单CPU 的组成原理;

2、

在掌握部件单元电路的基础上,进一步将其构造一台基本模型计算机;

3、

为其定义五条机器指令,编写相应的微程序,并上机调试建立和掌握整机概念。

二、实验内容:

1、

在SRAM中构建一段机器程序代码来实现简单应用功能,利用原有的微程序序列,执行该段机器程序代码,将结果显示在输出设备上。

三、项目要求及分析:

1)利用原有的微指令以及机器代码实现简单应用

在实验指导书中所给出了IN(输入)、ADD(二进制加法)、OUT(输出)、JMP(无条件转移),HLT(停机)共五条微指令,微指令存储在控制存储器中,每一个指令经过译码之后就会产生相应的控制信号,控制计算机系统进行工作。

存储程序思想是把程序以及数据一起存入内存,只需要启动程序,程序就可以自动执行,而不需要人工干预。在这一个任务中,把机器指令按照顺序存入存储器,然后让CPU自动取指并执行。

要实现这一功能,需要把指导书提供的微程序和机器指令分别存放在控制存储器和存储器中,然后程序即可执行。

2)思考题:试修改现有的指令系统中的加法指令,并增加存数,取数,减法操作。

对于原来的加法微指令,是把R0寄存器中的值送入ALU_A和ALU_B,然后执行加法操作,结果写回R0。修改之后的指令是针对R0以及内存中的值进行相加,所以需要更改控制存储器中地址为30的[R0->A]指令,更改其操作内容,并修改next字段,完成对加法逻辑的修改。

由于需要新增三条指令,首先对机器码(60、70、80),通过图1,得到经过P<1>测试之后会跳转的位置,即某一条机器指令对应微指令的起始地址,然后在控制存储器中选择还没有使用的存储单元,作为存储微指令的地址,并通过next域把微指令连接,构成微程序。

图1

对于减法指令(SUB),规定其为双字节指令,第一个字节为操作码,第二个字节为内存地址ADDR,指令功能为使用R0的值减去内存中地址为ADDR的数字的值,结果写回R0中。

对于存数指令(STA),规定其为双字节指令,第一个字节为操作码,第二个字节为内存地址ADDR,指令功能为把R0的值存入内存中地址为ADDR的位置。

对于取数指令(LAD),规定其为双字节指令,第一个字节为操作码,第二个字节为内存地址ADDR,指令功能为把内存地址为ADDR的值存入R0。

然后可以根据我所明确的指令的格式,设计流程图,并确定控制信号,把其转化为二进制代码表,然后得出对应的微程序,通过计算机写入到实验箱中的控制存储器中。

之后,可以按照定义的机器指令格式,编写机器指令程序,使用计算机写入到实验箱的存储器中,然后按下复位键,不断给出时钟脉冲,程序就可以执行。

四、具体实现

应包含以下内容:画出增加机器指令的微程序流程图、编制二进制代码表、编写微程序、编写机器指令验证程序

1)利用原有的微指令以及机器代码实现简单应用

实验指导书中已经给出。

2)思考题:试修改现有的指令系统中的加法指令,并增加存数,取数,减法操作。

微程序流程图:(图2)

图2

编制二进制代码表:

机器指令

说明

地址

23-22

21(WR)

RD(20)

19(IOM)

S3-S0

A

B

C

MA5-MA0

二进制编码

ADD
00

PC->AR,PC++

30

00

0

0

0

0000

110

110

101

0E

006D4E

MEM->AR

0E

00

0

1

0

0000

110

000

000

0F

10600F

MEM->B

0F

00

0

1

0

0000

010

000

000

10

102010

R0->A

10

00

0

0

0

0000

001

010

000

05

001405

A+B->R0

05

00

0

0

0

1001

011

001

000

01

04B201

SUB
80

PC->AR,PC++

38

00

0

0

0

0000

110

110

101

08

006D48

MEM->AR

08

00

0

1

0

0000

110

000

000

09

106009

MEM->B

09

00

0

1

0

0000

010

000

000

0A

10200A

R0->A

0A

00

0

0

0

0000

001

010

000

0B

00140B

A-B->R0

0B

00

0

0

0

1011

011

001

000

01

05B201

STA
60

PC->AR,PC++

36

00

0

0

0

0000

110

110

101

06

006D46

MEM->AR

06

00

0

1

0

0000

110

000

000

07

106007

R0->MEM

07

00

1

0

0

0000

000

010

000

01

200401

LAD
70

PC->AR,PC++

37

00

0

0

0

0000

110

110

101

0C

006D4C

MEM->AR

0C

00

0

1

0

0000

110

000

000

0D

10600D

MEM->R0

0D

00

0

1

0

0000

011

000

000

01

103001

编写微程序:

; //** Start Of MicroController Data **//

  $M 00 000001    ; NOP

  $M 01 006D43    ; PC->AR,PC加1

  $M 03 107070    ; MEM->IR, P<1>

  $M 1D 105141    ; MEM->PC

  $M 32 183001    ; IN->R0

  $M 33 280401    ; R0->OUT

  $M 35 000035    ; NOP

  $M 3C 006D5D    ; PC->AR,PC加1

;以上为原来的指令

  $M 30 006D4E    ; ADD指令 PC->AR,PC++

  $M 0E 10600F    ; MEM->AR

  $M 0F 102010    ; MEM->B

  $M 10 001405    ; R0->A

  $M 05 04B201    ; ADD指令结束 A+B->R0

  $M 38 006D48    ; SUB指令 PC->AR,PC++

  $M 08 106009    ; MEM->AR

  $M 09 10200A    ; MEM->B

  $M 0A 00140B    ; R0->A

  $M 0B 05B201    ; SUB指令结束 A-B->R0

  $M 36 006D46    ; STA指令 PC->AR,PC++

  $M 06 106007    ; MEM->AR

  $M 07 200401    ; STA指令结束 R0->MEM

  $M 37 006D4C    ; LAD指令 PC->AR,PC++

  $M 0C 10600D    ; MEM->AR

  $M 0D 103001    ; LAD指令结束 MEM->R0

; //** End Of MicroController Data **//

编写机器指令验证:

(a)加法功能验证:

  ; //***** Start Of Main Memory Data *****//

  $P 00 20    ; IN 把in输入到R0

  $P 01 60    ; STA 把R0存入MEM[51]

  $P 02 51    ; STA地址

  $P 03 20    ; IN把in输入到R0

  $P 04 00    ; ADD R0=R0+MEM[51].

  $P 05 51    ; 加数在内存中的地址

  $P 06 30    ; OUT  输出R0

  $P 07 E0    ; JMP

  $P 08 00    ; 跳转到程序开始(方便重复实验)

; //***** End Of Main Memory Data *****//

代码功能:先从in读入一个数字放到MEM[51],然后再读入一个数,放到R0,计算:R0=R0+MEM[51].

(b)减法功能验证:

  ; //***** Start Of Main Memory Data *****//

  $P 00 20    ; IN 把in输入到R0

  $P 01 60    ; STA  把R0存入MEM[51]

  $P 02 51    ; STA地址

  $P 03 20    ; IN  把in输入到R0

  $P 04 80    ; SUB  R0=R0-MEM[51].

  $P 05 51    ; 减数在内存中的地址

  $P 06 30    ; OUT输出R0

  $P 07 E0    ; JMP

  $P 08 00    ; 跳转到程序开始(方便重复实验)

; //***** End Of Main Memory Data *****//

代码功能:先从in读入一个数字放到MEM[51],然后再读入一个数,放到R0,计算:R0=R0-MEM[51].

(c)取数功能验证

; //***** Start Of Main Memory Data *****//

  $P 00 20    ;  IN 把in输入到R0

  $P 01 60    ;  STA  把R0存入MEM[53]

  $P 02 53    ;  STA地址

  $P 03 70    ;  LAD R0=MEM[53]

  $P 04 53    ;  LAD地址

  $P 05 30    ;  OUT输出R0

  $P 06 E0    ;  JMP

  $P 07 00    ;  跳转到程序开始(方便重复实验)

; //***** End Of Main Memory Data *****//

代码功能:把一个数字从in单元读入,然后存放在MEM[53]中,然后再取出该数字,然后输出。

五、调试运行结果:

1)利用原有的微指令以及机器代码实现简单应用

图3 按照实验指导书连线

在这一次测试时,微程序以及机器指令均对应实验指导书上给定的内容。

预期效果:通过in单元向模型机输入一个数字,然后模型机把这一个数字作为加数和被加数相加,然后输出运算结果。

调用IN指令,存入数据

图4 从in单元向R0存入0x01

然后使用未修改的ADD指令,完成R0 = R0 + R0的运算。

图5 把R0的值放入A和B,然后执行ADD操作,把结果写回R0

执行OUT指令,显示R0的值。

图6 显示R0的值

观察实验箱,输出结果为0x02,是0x01 + 0x01的结果,该次实验结果正确。

图7 实验箱out单元

2)思考题:试修改现有的指令系统中的加法指令,并增加存数,取数,减法操作。

在这一个项目中,所使用的微指令见具体实现-编写微程序模块

(a)首先进行减法功能验证:

通过IN指令读入减数。

图8 把数字从0x08从in单元写入R0

通过STA指令存储R0中的数据到MEM[0x51].

图9 把R0存入内存地址为0x51的存储单元

通过IN指令读取被减数

图10 利用in单元把0x10读入到R0中

在SUB指令中,微程序加载MEM[0x51]的数据,存放在ALU_B中,充当减数。

图11 从地址为0x51的内存中取出之前存入的数字0x08

在SUB指令中,执行相减,并写回R0中。

图12 做减法运算

OUT指令,把R0的值发送给OUT单元

图13 把最终结果发送到OUT单元

图14 观察实验箱数据

(b)加法指令验证:

在STA指令执行前,已经执行了IN指令,并把in单元数据写到了R0中。

然后执行STA,把R0中的值写入到MEM[0x51]

图15 把R0中的值写入到地址为0x51的内存中

ADD指令中的加载存储器内数据的执行过程,把MEM[0x51]的值读入到ALU_B中,在这一次操作之后,再读取R0的值到ALU_A中。

图16 从内存中读出事先存好的01

ADD指令进行求和并写回R0中

图17 进行相加操作

在执行OUT操作之后,观察实验箱,发现输出结果确实为 0x04 = 0x03 + 0x01,这一次实验正确。

图18 观察out单元

(c)进行输入输出指令测试:

在该条指令之前,已经通过in指令在R0中写入了0x03

这时调用STA指令,给定内存地址0x53,存入数据

图19 把0x03写入到地址为0x53的内存中

调用LAD指令,给定内存地址0x53,读取数据

图20 在地址为0x53的内存处读出数据

在执行完OUT指令之后,观察实验箱。发现读取出来的数据就是存入的数据,本此实验成功。

图21 out单元

在上述调试中,先测试了实验指导书中给出的例子程序,并使用计算机软件对控制箱内部具体的实现流程进行了观察。

然后按照具体实现中的编程文件,通过PC机进行下载,并选用三个机器码片段进行测试。在下载完程序后,按下脉冲信号发生按钮,程序按照预期流程执行,并且正常输出结果。

六、所遇问题及解决方法:

遇到的问题一:

按照我的理解输入二进制编码对应的16进制,执行后没有达到预料结果。

解决方法:

再一次检查自己的代码,没有找到问题。观察实验指导书中所给出的标准的微指令,按照我的理解把其转化为16进制,然后与计算机上提供的微指令进行对比,发现我在转化16进制的时候出现了问题,错误地把最后6位(MA5-MA0)当做了8位进行转化,导致进制转化错误。

重新转化,编程,得到了正确的结果。

遇到的问题二:

如果直接手动进行转化,耗时耗力,还容易出错。

解决方法:

Python程序中的数字可以使用_进行分隔,可视性强,并且可以进行进制转化。

编写如下的python代码。

a = 0b00_000_0000_110_110_101_001110 #a的值根据每一条微指令的控制信号进行更改

print(hex(a))

输出结果为

0x6d4e

这样就可以正确的生成二进制对应的十六进制了。

遇到的问题三:我在最初设计指令的时候,未按照定义进行,而是把SUB的机器码为61,STA机器码为14,LAD机器码为72.

解决方法:

在这一章具有许多保留内容,在下一次实验中会使用这些保留内容(低字节另有用处),所以应该为后面的设计留下空间。

再针对要求的机器码重新进行译码,得到对应的微指令起始地址,然后改写微指令,即可修复。

反思:在设计中,要严格遵守规范,并且要提前做好规划。

七、实验总结:

1.

在基本运算器实验中,我首次见到了计算机的模型机,通过连线与操作实验箱,我对其有了初步的了解。在这一次实验中,我通过把算术逻辑单元(ALU)与控制模块进行连接,通过开关控制数据通路的输入,控制通路的输入,并且把算术逻辑单元的输出通过数据总线上的指示灯以及发两个标志位对应的指示灯进行展示,对其结果进行观察。

在这一次实验中,我发现一旦改变ALU的输入,其很快就可以把值算出来,但是只有按下时钟脉冲之后,数值才会被传输处理。这使得我初次对数据通路以及控制通路有了了解。数据通路仅仅负责运算,由于各级门的延迟,导致运算并不是瞬间完成的,所以又需要控制器每隔固定的一段时间,向各个模块发送信息,并等计算完成之后,执行下一个操作。

我在这一次实验中通过拨动开关,对数据通路以及控制通路有了比较直观地理解,这一次实验激起了我的学习兴趣。

在静态随机存储器实验中,我首先拨动开关,在地址寄存器上写入要访问内存的地址,然后在数据总线上传输所需要的数据,控制存储器进行读写。

在这一次实验中,我首次在实验中体会到了总线的意义。总线把计算机中的相应部件连接成一个总体,在每一时刻,只能有一组数据在总线上传输。通过总线,可以轻易地把数据在CPU内部进行传送,避免了过于复杂的连线。

同时,我也了解了内存的读写方法。必须要事先在地址寄存器上规定需要访问的地址,然后才可以对内存进行访问。

通过第一节课的两次实验,我对于模型机的部件有了基本的了解,学会了在实验箱上进行连线,并掌握了通过开关控制各个模块的功能。

2.

在微程序控制器实验中,通过实验指导书,我发现模型机上的控制存储器也可以像内存一样进行读写,这样就可以把实现得到的二进制微指令写入控制存储器中。当然,更改控制存储器的值还可以通过PC机与其相连进行。

在这一次实验中,我了解到,机器指令在CPU内部并不是直接执行的,而是要把机器指令翻译为微指令,然后对每一条微指令进行译码,产生控制信号,作用于各个模块进行控制,最终完成所需要的功能。

我发现微程序是通过类似于链表的结构进行连接,当执行某一条微指令的时候,可以通过在本条微指令中的next域获取下一条微指令的地址,在对应的微程序执行完成之后,又会跳到指令译码状态,继续执行。

对于机器指令,在P<1>测试环节对其进行译码,改变微地址寄存器的地址,从而实现分支功能。

在这一次的实验中,打破了我固有的想法,机器指令之下还有抽象层次,通过微指令的运作,机器指令才可以被翻译成控制信号,进行一步步操作。

3.

在这一次实验中,摒弃了之前几次实验中的开关,完全采用存储程序的思想,事先把程序以及数据存放在内存中,只需要给定初始的PC值,然后启动计算机,就可以自动执行,完成所需要的任务。

我首先把例子程序下载到实验箱中进行测试,初步了解了存储程序的执行过程,然后按照所给定的要求,修改原有的ADD指令,并增加STA,LAD,SUB指令。

在设计过程中,我了解了设计微指令的一般步骤。

首先按照要求,画出微程序的流程图,确定给定机器指令通过P<1>测试之后所跳转的地址,并给每一个微指令分配在控制存储器中的地址,明确每一条微指令的下一条微指令以及含义。

然后根据微指令的功能,选择控制信号,使数据的值从一个地方传送到另一个地方,然后写出微指令的16进制代码。

然后使用语言描述所涉及的微指令地址以及内容。

最后设计相应的机器码,对微指令的功能进行测试。

在本次测试中,我通过动手操作,完成了一个存储程序计算机模型的设计,然后对其进行了测试。

同时,我也在与之前手动拨动开关对计算机控制进行了对比。如果是手动拨动开关,那么计算机的执行速度就会受限于人的操作速度,相反,如果把指令事先存入内存,那么对于一些循环的部分,计算机就可以自己取指,执行,而不需要人去干预,这极大地提升了计算机的运行速度,同时也使得计算机可以更加通用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

驱动定时器

基于GPIO子系统编写LED驱动&#xff0c;编写应用程序进行测试 设置定时器&#xff0c;5秒钟打印一次hello world text.c #include<stdlib.h> #include<stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include<…

【数据结构初阶】十、快速排序(比较排序)讲解和实现(三种递归快排版本 + 非递归快排版本 -- C语言实现)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【数据结构初阶】九、排序的讲解和实现&#xff08;直接插入 \ 希尔 \ 直接选择 \ 堆 \ 冒泡 -- C语言&#xff09;-CSDN博客 常见排序算法的实现&#xff08;续上期&#xff09; …

AT800(3000) +昇腾300V 之 第一个例子图片分类

第一个列子 背景开发流程准备模型开发推理流程编码 编译与运行 背景 第一个例子是 图片分类的应用 因第一个&#xff0c;直接获取已训练好的开源模型&#xff0c;选择Caffe框架的ResNet-50模型。 ResNet-50模型的基本介绍如下&#xff1a; 输入数据&#xff1a;RGB格式、22…

【微服务开篇-RestTemplate服务调用、Eureka注册中心、Nacos注册中心】

1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。 1.1.单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署。 单体架构的优缺点如下&am…

4.Mbtiles瓦片包加载

愿你出走半生,归来仍是少年&#xff01; 1.Mbtiles mbtiles是在GIS开发中最常用的瓦片包格式&#xff0c;在移动端、桌面端都是常用的格式。 2.代码 通过OsgEarth的MBTilesImageLayer图层进行加载&#xff0c;也是封装成了一个静态的方法方便调用。 /// <summary&g…

PC5080USB适配器充电芯片5V/1A输入具有0V充电功能

概要&#xff1a; PC5080 是一款 5V USB 适配器输入&#xff0c;高精度双节锂离子电池充电管理芯片。具有0V充电功能&#xff0c;涓流充电、恒流充电、恒压充电和自动截止、自动再充等一套完整充电循环的充电管理芯片。芯片内部特设 9V 抗浪涌&#xff0c;芯片应用更安全可靠。…

Redis快速上手篇七(集群-六台虚拟机)

Redis集群 主从复制的场景无法吗满足主机单点故障时需要引入集群配置 一般数据库要处理的读请求远大于写请求 &#xff0c;针对这种情况&#xff0c;我们优化数据库可以采用读写分离的策略。我们可以部 署一台主服务器主要用来处理写请求&#xff0c;部署多台从服务器 &#…

vue笔记(二)

7、事件处理 7.1、事件的基本处理 事件的使用 使用v-on&#xff1a;xxx或者用xxx绑定事件&#xff0c;其中XXX是事件名事件的回调需要配置在methods对象中&#xff0c;最终出现在VM上methods配置的函数&#xff0c;不需要箭头函数 <div id"root"><h1>…

创建一个Keil项目

1、创建项目 2、选择存放的文件夹&#xff0c;还有设置项目名 3、选择型号&#xff08;因为没有STC,用下面这个替代&#xff0c;功能差不多&#xff09; 4、选择不用启动文件 5、就会得到下面这个&#xff0c;可以在Source Group 1下面编写代码了 6、右键source Group 1,添加c语…

Python 编写确定个位、十位以上方法及各数位的和程序

Python 编写确定数字位方法 Python 编写确定个位、十位Python 编写确定个位、十位、百位方法解析&#xff1a;Python 各数位的和程序 利用%&#xff08;取余符号&#xff09;、//&#xff08;整除&#xff09;符号。 Python 编写确定个位、十位 num 17 a num % 10 b num /…

【点云】有序/无序点云区别(详细详解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

Linux安装frp并实现内网穿透

准备 一台公网服务器&#xff08;配置无要求网络稳定就行&#xff09; 内网客户端&#xff08;准备要穿透出去的设备&#xff09; 服务端&#xff08;公网服务器&#xff09; 这里是为服务端配置frp 只关注frps和frps.ini即可 frp项目地址 &#xff1a;https://github.com/f…

一文详解汽车电CAN总线

1.什么是CAN总线 CAN总线(控制器区域网络)是一个中央网络系统&#xff0c;连接不同的电子控制单元(ECU)&#xff0c;车辆中的其他设备。现代汽车可以有100个ECU&#xff0c;因此CAN总线通信变得非常重要。 2.CAN总线流行的背景 集中式:CAN总线系统允许对连接到网络的ECU进行集…

完整攻防知识体系-你值得拥有

文章目录 前言内容简介目录 前言 根据中国互联网络信息中心&#xff08;CNNIC&#xff09;发布的第51次《中国互联网络发展状况统计报告》&#xff0c;截至2022年12月&#xff0c;我国网民规模为10.67亿&#xff0c;互联网普及率达75.6%。 我国有潜力建设全球规模最大、应用渗透…

springCore完整学习教程2,入门级别

上集说到&#xff1a;2. 3&#xff0c;咱们从2.3集开始 2. Externalized Configuration 2.3. External Application Properties Spring Boot会自动找到并加载应用程序。属性和应用程序。当应用程序启动时&#xff0c;从以下位置获取Yaml文件: 从类路径 类路径root 类路径/…

Android开发知识学习——编码、加密、Hash、序列化和字符集

文章目录 学习资源来自&#xff1a;扔物线加密古代密码学现代密码学对称加密非对称加密密码学密钥和登录密码Base64URL 使用的百分号编码压缩与解压缩图片与音频、视频编解码 序列化Hash字符集课后题 学习资源来自&#xff1a;扔物线 加密 古代密码学 起源&#xff1a;古代战…

微信公众号如何通过迁移变更主体?

公众号迁移后原来内容还在么&#xff1f;通过公众号迁移&#xff0c;可以实现这些目的&#xff1a;主体变更、开通留言功能、多号合并、订阅号升级为服务号、服务号转为订阅号。公众号迁移流程&#xff1a;①办理公证&#xff1b;②提交迁移申请&#xff1b;③第三方审核&#…

14. 机器学习 - KNN 贝叶斯

Hi&#xff0c;你好。我是茶桁。 咱们之前几节课的内容&#xff0c;从线性回归开始到最后讲到了数据集的处理。还有最后补充了SOFTMAX。 这些东西&#xff0c;都挺零碎的&#xff0c;但是又有着相互之间的关系&#xff0c;并且也都蛮重要的。并且是在学习机器学习过程当中比较…

Unity点乘的实战案例1

向量的点乘,也叫向量的内积、数量积&#xff0c;对两个向量执行点乘运算&#xff0c;就是对这两个向量对应位一一相乘之后求和的操作&#xff0c;点乘的结果是一个标量。点乘&#xff0c;也叫数量积。结果是一个向量在另一个向量方向上投影的长度&#xff0c;是一个标量。 • …

JVM进阶(3)

一)什么是垃圾&#xff1f; 垃圾指的是在应用程序中没有任何指针指向的对象&#xff0c;这个对象就是需要被回收的垃圾&#xff0c;如果不及时的针对内存中的垃圾进行清理&#xff0c;那么这些垃圾对象所占用的内存空间可能一直保留到应用程序结束&#xff0c;被保留的空间无法…