跳转至

冯·诺依曼模型

核心思想

程序(指令)和数据以二进制形式不加区分地存储在同一存储器中。这意味着计算机可以通过改变存储器中的内容(即程序)来改变其任务,而无需重新连接或设计硬件。这是现代计算机灵活性的基石。

五个组成部分

存储器

  • 功能: 存储指令(程序)和数据。在冯·诺依曼模型中,两者没有区别,都是一串比特。
  • LC-3实现: 一个由2^16个地址组成的、可寻址的内存单元,每个地址包含一个16位的字。这既是LC-3的主内存(RAM)
  • 关键点: 内存地址空间是统一的,程序计数器(PC)指向的地址就是下一条要执行的指令所在的内存地址

处理单元

  • 功能: 执行实际的算术和逻辑运算。
  • LC-3实现: 算术逻辑单元(ALU)。LC-3的ALU可以执行加法、按位与、按位取反等操作。它是数据通路的核心,负责对来自寄存器或内存的数据进行计算。

输入

  • 功能: 将外部世界的信息送入计算机。
  • LC-3实现: 键盘。在LC-3中,键盘是通过内存映射I/O实现的。一个特定的内存地址(如0xFE02)被关联到键盘的数据寄存器。当程序从该地址“加载”数据时,它实际上是在读取键盘的输入。

输出

  • 功能: 将计算机内部的计算结果呈现给外部世界。
  • LC-3实现: 显示器。同样通过内存映射I/O实现。一个特定的内存地址(如0xFE06)被关联到显示器的数据寄存器。当程序向该地址“存储”一个字符的ASCII码时,显示器就会在屏幕上显示相应的字符。

控制单元

  • 功能: 这是整个计算机的“指挥中心”。它负责协调所有其他部件的活动。
  • LC-3实现: 这是本书数字电路和微架构设计的核心。
    • 控制单元的操作:
      1. 取指: 从内存中取出由PC指向的指令,放入指令寄存器(IR)。
      2. 译码: 分析IR中的指令,确定需要执行什么操作(是ADD还是LD?)以及操作数在哪里。
      3. 执行: 根据译码结果,发出一系列精细的控制信号,来指挥数据通路、ALU和内存完成指令要求的操作。例如,对于ADD指令,控制单元会发出信号:选择正确的寄存器作为ALU输入,设置ALU为加法模式,并将结果写回目标寄存器。

指令处理周期

指令处理周期:机器的“心跳”。

控制单元通过周而复始地执行以下步骤来运行程序,这个循环就是冯·诺依曼模型的运行体现:

  1. 取指: 从存储器(地址为PC)中取指令,放入IR。
  2. 译码: 解码IR中的指令。
  3. 评估地址: 如果需要访问内存,计算操作数的有效地址。
  4. 取操作数: 从存储器或寄存器中获取执行指令所需的操作数。
  5. 执行: 执行指令(例如,在ALU中完成操作)。
  6. 存储结果: 将执行结果写回寄存器或存储器。

完成这些步骤后,PC被更新为下一条指令的地址,循环重新开始。中断的处理是这个基本循环的扩展,它允许外部事件暂停当前程序流。

指令周期

时钟周期和指令周期

  • 时钟周期: 硬件层面的最小时间单位,是CPU工作的节拍器。两个时钟脉冲之间的间隔就是一个时钟周期。频率为1GHz的CPU,其时钟周期为1纳秒。
  • 机器指令周期: 软件层面的概念,指CPU从取出到执行完一条机器指令所需的完整时间。

核心关系:执行一条机器指令需要多个时钟周期。

示例

LD R1, [0x1234] 这条指令的意思是:将内存地址 0x1234 中的数据加载到寄存器R1中。

在一个简单的CPU设计中,这个过程需要至少4个时钟周期:

  1. 周期1 - 取指:

    • 动作: CPU将程序计数器(PC)中的地址送到内存总线,从内存中取出 LD R1, [0x1234] 这条指令本身。
    • 结果: 指令被存入CPU内部的指令寄存器(IR)。时钟沿到来,这个动作结束。
  2. 周期2 - 译码/计算地址:

    • 动作: 控制单元解析IR中的指令,识别出这是条加载指令,并计算出要访问的内存地址 0x1234
    • 结果: 地址 0x1234 被准备好送到地址总线。下一个时钟沿到来,这个动作结束。
  3. 周期3 - 内存读:

    • 动作: CPU将地址 0x1234 送到内存总线,并发出“读”信号。内存控制器开始工作,在经过其访问延迟后,将地址 0x1234 处的数据放到数据总线上。
    • 结果: 数据从内存中被读出,到达CPU的数据引脚。下一个时钟沿到来,这个动作结束。 (注意:内存访问慢,这个周期可能本身就需要多个时钟周期,这里为简化视为一个)
  4. 周期4 - 写回:

    • 动作: CPU将数据总线上的值存入目标寄存器R1。
    • 结果: 指令执行完毕,R1中拥有了新数据。下一个时钟沿到来,这条指令的周期正式结束。

总结

  • LD R1, [0x1234] (一条机器指令)
    • = 取指周期(1个时钟周期)
    • + 译码周期(1个时钟周期)
    • + 内存读周期(1个或更多时钟周期)
    • + 写回周期(1个时钟周期)
    • = 总共需要4个(或更多)时钟周期