CPU
机器指令:CPU可以直接识别并执行的命令,所有机器指令构成这个CPU的指令集
RISC:精简指令集计算机
CISC:复杂指令集计算机
无用的多余指令使得指令的运行速度被拖慢
指令简单,在一个时钟周期内完成一条指令
RISC只有LOAD、STORE方式访问存储,而复杂指令集有多种方式访问
RISC指令设计很紧凑,不容易实现指令系统的兼容,后期加指令比较难
ALU:算术逻辑单元
组合逻辑电路,没有记录功能
Ki是控制单元,指出运算类型
ALU电路的外特性
快速进位链
并行加法器:一次对两个数字的各个位都进行计算,但是进位限制了下一位的计算(因为下一位的计算需要上一位的进位结果)
进位链就是传送进位的电路
为了使用与非门实现:
进位链是影响加法器速度的瓶颈,所以才有了并行进位链
上图使用的是与或非门(不是同时使用了这三种门,只是说使用了这三种基本门)
虽然表达式看起来复杂,但是都是使用的初始状态的变量,可以实现同时计算,并且只需要使用与非门即可
但是这种方式的电路很复杂,所以有了以下的折中方式
如果使用串行方式,16位运算需要32t才行
C3、C7、C11、C15是同时产生的
C15要作为输入给第一大组
大组内小组同时计算(都使用初始状态),然后输出最高位给下一个大组(下一个大组都使用上一个大组传递过来的位作为初始位)
CPU的结构
用户可见寄存器:在编写程序时可以使用的寄存器
用户不可见寄存器:例如在流水线的流水段上的寄存器都是不可见的
CU:产生微操作序列(要保证微操作之间的顺序正确)
精简指令集一般使用组合逻辑设计(硬连线设计),而复杂指令集一般使用微指令设计(存储逻辑)
指令周期
CPU工作周期的标记:说明现在处于CPU的哪个工作周期,以便于正确访问内存
来源:https://blog.csdn.net/noworries/article/details/8889021
我们知道什么是断点,通过断点我们可以很方便地对程序进行调试。在嵌入式开发领域中,我们还得知道存在程序断点(program breakpoint)和数据断点(data breakpoint)之分。
1、程序断点
程序断点就是指处理器的指令断点。通俗的说,就是当程序运行到函数的某个地方就会停下来。程序断点又分为软件程序断点和硬件程序断点。
在用VS进行软件调试时可以设置很多断点,这些断点都是软件程序断点。处理器在运行的过程中如果碰到一条非法(或无效)指令,就会出现一个异常中断,软件程序断点就是利用这个特性实现的。当设置一个软件程序断点的时候,调试工具就在我们所想设置的内存位置上放置一条非法指令,同时将被替换的指令保留起来(这就是上面说的储存程序断点的意思)。当程序运行到了被非法指令替换的地方时,处理器所产生的异常中断一方面在中断服务中恢复被替换的指令,另一方面将控制权交给调试工具。从理论上说,软件程序断点可以设置n个,n的大小由内存容量决定。
在嵌入式系统中,如果调试的程序不是位于内存中,而是位于像闪存这样的存储器中(比如引导加载器的部分代码),此时就无法使用软件程序断点了,因为闪存中的内存并不能像内存那样方便更改。此时只能通过配置处理器的断点寄存器的方式实现的。当处理器运行到断点寄存器所指示的位置的指令就会产生中断,调试工具就通过该中断使我们获得干预的机会。处理器所能设置的硬件程序断点数据是有限制的,可能最多也就4个
2、数据断点
当调试程序时,如果发现所定义的一个数据结构中的某一变量总是被意外地更改,查出这类问题的根源 可并不容易。如果处理器能提供一种功能——当某一变量的值被更改时能自动停止下来就好了,这样就可以通过调用栈找到问题的根源。这就是引入数据断点的目的。数据断点与硬件程序断点很相似,需要在处理器的寄存器中设置所监视数据变量的内存地址。当被监视的内存单元被修改时处理器将产生中断,调试工具利用这一中断让我们获得检查程序的机会。
处理器一般都提供了硬件程序断点这一功能,但数据断点却未必。选择处理器时考虑其是否支持数据断点是很有必要的,这会让我们获得另一种有效的调试手段。
指令流水线
来源:https://blog.csdn.net/huanghongxun/article/details/80828258
如果我们等待一条指令完全执行完成了以后再执行下一条指令,那么这会导致硬件资源的浪费。对于单周期CPU,指令的执行过程将是5个步骤依次执行。当指令执行到某个步骤时,剩下4个步骤的硬件资源将被闲置(由于我们会在电路中大量使用触发器,而触发器是属于耗能比较大的器件,因此充分利用硬件资源还能够降低我们设计的CPU的功耗,提升能耗比)。
指令之间,甚至是指令内部的微指令之间也可以是并行的:
单核cpu只能并发,不能并行
实际的计算机不仅仅使用二级流水
条件转移指令数量是比较大的,对指令流水的影响比较大:解决方法——分支预测等
条件传送是一种条件跳转的一种替换策略,他首先就计算出一个条件的两种结果,然后等到执行到分支判断的地方,根据条件选择一个结果。只有在一些受限的条件下这种策略才可行,比如这个例子中的判断数字是否大于128然后求和。但是如果可行,就可以通过一条简单的条件传送指令来实现,而不是需要条件跳转指令来实现分支判断。
eg.
流水线的级数表示的是将一个指令分成的段数
指令存储器和数据存储器分开(哈弗结构):比较典型的就是指令cache和数据cache分开
写后写:不同指令写入同一位置,但是顺序不能变
后推法:推后第二条读写操作
旁路技术:将某条指令执行结果不送回寄存器而是直接送到其他指令所需的地方
指令4-7是预先读进来的,等待指令3执行完发现要转移到指令15时,4-7都要被舍弃
流水线的多发技术
黑色是执行部分,有多个
锁存器:保存前面流水段的结果,同时为下一段提供操作数据和操作信号
来源:https://baike.baidu.com/item/%E9%94%81%E5%AD%98%E5%99%A8
锁存器(Latch)是一种对脉冲电平敏感的存储单元电路,它们可以在特定输入脉冲电平作用下改变状态。锁存,就是把信号暂存以维持某种电平状态。锁存器的最主要作用是缓存,其次完成高速的控制器与慢速的外设的不同步问题,再其次是解决驱动的问题,最后是解决一个 I/O 口既能输出也能输入的问题。锁存器是利用电平控制数据的输入,它包括不带使能控制的锁存器和带使能控制的锁存器。
运算过程也可以通过流水线的方式进行并行操作:
如果每段的操作时间不等,那么时钟周期要按最长的一段来设置,会降低整体的运行速度
中断
一个中断源对应一个中断请求触发器
优先响应对系统影响最大的、最重要的中断
硬件方式:设计排队器:
排队器中同时只有一个是1(高电平),其他都是0
软件方式:查询
查找服务程序入口地址
- 硬件
- 软件
软件方式更加灵活
是将中断识别程序的开始地址送入PC
隐指令:不是指令,但是也是要完成的步骤
某一级别的中断在执行的时候,对应级别的屏蔽字会被赋值:
注意屏蔽字在何时设置:必须在开中断之前
假设用到了ACC寄存器(累加器)
这个5就是这个中断对应的处理程序的位置(软件查询方法)
SERVE:中断服务程序的入口地址
中断后,断点自动保存到0地址,然后先将ACC寄存器的内容保存到SAVE中,再将0地址的内容通过ACC寄存器保存到RETURN中(注意为什么要用ACC,因为数据不能直接在内存中流动,必须至少有一方是寄存器),最后关中断时将SAVE中的内容放回ACC,然后直接跳转到RETURN的内容,也就是程序断点位置恢复执行
控制单元
微操作命令
将操作码送给CU进行译码,明确要执行的是什么指令
执行周期比较复杂,因为我们假设指令长度和字长是一样的,所以取指令的时间是固定的,但是执行时间是不固定的
存数和加法都是和ACC寄存器交互
微指令就是指令的子描述
A0是条件,如果是1就转移,是0就不变
对于中断周期,每种指令的过程都一样:
控制单元的功能
一组指的是并行执行时
CU:
来源:https://baike.baidu.com/item/CU/15286244
CU是Control Unit控制单元,是CPU的一部分,用于执行计算机指令或者Client Unit 监控系统的监控客户端单元的一个计算机学名词。
不采用CPU内部总线的意思就是CPU的内部各个部分采用分散连接:
采用内部总线连接的话:
多级时序系统
耗费时间最长的指令一般就是访存指令
一个机器周期内要做多个指令,它们也是有先后顺序的,这个顺序也是由时钟控制的,所以时钟周期要小于机器周期:
时钟周期是计算机中最基本的时间单位
一个时钟周期也可能完成多个微操作
每个机器周期对应于指令的一个执行阶段
机器速度也和是否采用流水线、是否是多核等等因素相关,不能简单地只看主频
同步控制方式一定有一个定宽定距的时钟作为基准
这种方式比较浪费,因为一般的指令不需要那么多的节拍
类比DMA
联合控制方法:一般使用同步,部分耗时比较长的指令(例如IO指令)使用异步
人工控制:为了调试使用
组合逻辑设计
要求指令没有先后顺序或者指令非常短、在一个节拍中就可以实现
节拍信号的宽度就是一个时钟周期
不同机器的机器周期中包含的节拍数是不一样的
Ci表示控制信号:
原则二的意思是如果可能并行的话就尽量并行,安排在同一个节拍中
注意我们约定了一个机器周期内有三个节拍
取指和间指都花费了一个机器周期
下面对一些典型的汇编指令的微操作进行分析:
- CLA:给ACC寄存器赋值为0
- COM:给ACC取反
- SHR:ACC寄存器算术右移
0-》G是停机指令:
- CSL:循环左移
- STP:停机
- ADD X:内存中的X和ACC加
- STA X:将ACC储存到X
- LDA X:将内存中的X保存到ACC
- JMP X:跳转到指定的X位置
- BAN X:如果上一条计算结果(ACC,判断标志寄存器中的标志,这里简化为只判断A0)小于0,就跳转到X
- 保存断点,写入到内存地址0处
- 关中断
- 完成断点的写
- 形成中断服务程序的入口地址
IND:表示加入间指阶段
EX:表示进入执行阶段
写出微操作的逻辑表达式,也就是在哪些指令中使用了该微操作:
然后依据此设计电路:
速度快:使用硬件方式连接,这种方式被RISC所采用;CISC的整型计算也是采用的此方法
微程序设计
扩展性强、可以实现复杂化指令
区分我们上面所说的”微操作“和这里的”微程序“、”微指令“
微指令的1表示对应的操作要在该处完成
一条机器指令对应一个微指令,取指、间址阶段的微程序是公用的
存储逻辑
微程序、微指令保存在控制存储器中,是只读的
CMAR:控制存储器地址寄存器,保存微指令在控制存储器中的地址
CMDR:控制存储器数据寄存器,保存读出的微指令
顺序逻辑:选择正确指令来源
微地址形成部件:形成微操作对应的微指令的地址
顺序控制:给出下一条微指令的地址
XXX:表示不能直接通过下地址得到要执行的下一条指令是什么(有可能有间址有可能没有、有可能有中断有可能没有、不知道要执行哪一个指令的微程序),需要使用微地址形成部件得到
例如:
微指令的控制方式
直接给出操作、不需要译码,速度最快
译码器输出只有一个是有效的
不同组的命令不一定是互斥的,是可能并行执行的
执行较慢
也可以使用增量计数器或者分支转移
在小范围内的跳转和转移还可以使用测试网络的方式:
微指令由测试地址和非测试地址拼接而成
对于特殊的部分:
间址也可以使用硬件产生
多路选择器要依据指令的类型选择哪一路:
微指令格式
垂直型微指令一般用于比较复杂的指令
静态微程序和动态微程序
毫微程序设计
将垂直型微指令解释为水平型毫微指令
串行和并行微程序
微程序设计举例
Ti表示一条微指令
对于这10条指令,一共有20种不同的微操作,合起来有38条不同的微指令
如果使用水平型直接控制的话,控制字段至少要有20个bit,控制存储器中要存储至少38条微指令
还可以再简化: