第23章构建了一个CPU,它执行经典Intel 8080微处理器的指令子集。这个CPU需要前两章的算术逻辑单元和寄存器阵列,以及几个较小的组件。将所有部分连接在一起的是指令解码器,它为其他部分生成所有控制信号。
指令解码器无疑是最复杂的CPU的一部分。它在第23章的页面中分为几个部分展示,但在这里所有组件都组装成了一个极其复杂的电路。
除非您有一个巨大的屏幕,否则可能需要缩小浏览器窗口才能看到整个电路。
使用左上角的旋转控件选择操作码。指令助记符显示在旋转控件上方。您会注意到,此电路中没有实现许多Intel 8080指令。
旋转控件下方的解码器与一系列AND门一起使用,以确定操作码属于哪个指令家族。
默认情况下,指令假定为一个字节的取指和一个周期的执行。如果不是这种情况,则左下角的门确定必须从内存中获取多少字节以及执行需要多少周期。触发器、计数器和解码器生成对应于取指周期、程序计数器(PC)增量周期和执行周期的信号。4-to-16解码器下方的一些电路与书中第370页所示的略有不同。
在底部的最右侧,您会看到用于控制CPU中几个组件的信号。这些控制信号对所有指令都是相同的。特定于每个指令的控制信号由占据电路右上角大部分区域的大型二极管矩阵处理。每个指令家族为第一个和第二个执行周期以及相应的脉冲周期生成某些控制信号。
您可以通过按下Clock按钮来控制每条指令的获取和执行。
例如,选择指令C6h,即ADI指令(Add Immediate)。按下并释放Reset按钮将所有内容恢复到初始状态。
您会看到左下角的电路已确定此指令需要2-Byte Fetch(指令字节本身和随后的数据字节)和2-Byte Execute。但在实际CPU中,这些信息要等到指令从内存获取并存储在指令锁存器中后才会可用。
Cycle Decoding部分的4-to-16 Decoder输入全为0,表示0输出信号为1,指示Fetch Cycle 1。在最右侧,您会看到Program Counter Enable信号已将程序计数器的内容放到地址总线上以寻址随机存取内存,RAM Data Out Enable信号允许内存内容被放到数据总线上。这就是指令字节。
现在按下Clock按钮但不要释放。Pulse信号触发Instruction Latch 1 Clock存储指令,Increment-Decrement Clock信号将地址总线内容存储在Incrementer-Decrementer中。现在释放Clock按钮。
再次按下并释放Clock按钮。现在我们处于PC Increment Cycle,Increment Enable信号允许程序计数器的递增值被放到地址总线上。
现在按下Clock按钮但不要释放。Pulse信号触发Program Counter Clock将递增值存储在程序计数器中。现在释放Clock按钮。
按下并释放Clock按钮。现在我们处于Fetch Cycle 2,Program Counter Enable和RAM Data Out Enable信号已将下一个字节(本指令的数据字节)放到数据总线上。
按下Clock按钮触发Pulse信号,使Instruction Latch 2存储该字节,Increment-Decrement Clock将程序计数器值存储在Incrementer-Decrementer中。
按下并释放Clock按钮使我们进入另一个PC Increment Cycle。再次按下按钮将递增值存储回程序计数器。
再次按下并释放Clock按钮。现在我们处于Execute Cycle 1准备执行此指令。您会注意到顶部二极管矩阵和Execute Cycle 1信号使Inst Latch 2 Enable信号将数据字节值放到数据总线上。
按下Clock按钮但不要释放。Pulse信号触发ALU Clock将该值存储在Arithmetic Logic Unit中。释放Clock按钮。
再次按下并释放Clock按钮。现在我们处于Execute Cycle 2,ALU Enable信号允许Arithmetic Logic Unit的内容被放到数据总线上。该值是Accumulator加上数据字节。
按下Clock按钮但不要释放。Pulse信号触发Acc. Clock将该值存储在Accumulator中。释放Clock按钮。指令已执行完毕。
如果继续按下并释放Clock按钮,指令将再次执行,但在实际CPU中,将从内存获取不同的指令。
CPU的所有组件已在此组装并连接到随机存取存储器块。组件通过8位数据总线(较细的数据路径)、16位地址总线(较粗的数据路径)和控制信号(线路)连接。上面显示的指令解码器现在封装在中央的大盒子中。
此电路演示了CPU如何执行整个程序。存储在内存中的字节构成了书中第318页显示的程序。该程序将两个双字节数字相加,即5,000和2,500的十六进制等效值。
当您点击Clock按钮时,下方的Instruction Decoder指示周期和获取的操作码。控制信号触发Instruction Decoder左侧的Instruction Latches、Program Counter和Incrementer-Decrementer,以及右侧的Register Array和Arithmetic Logic Unit。
请记住,从Instruction Decoder到Register Array的S0、S1、S2、D0、D1和D2信号可能会受到不涉及Register Array的指令的影响。Source信号仅在RA Clock信号在Register Array中保存值时才有意义;Destination信号仅在RA Enable信号将值放在数据总线上时才有意义。
类似地,从Instruction Decoder到Arithmetic Logic Unit的R0、R1和R2信号仅在ALU Clock信号在ALU中保存值时才有意义。
当您重复点击Clock按钮时,最左侧的Memory组件显示正在寻址的字节。两条总线显示该总线上的值。当程序执行内存位置000Eh处的HLT指令时,程序已完成。相加的两个值的和存储在内存位置0x0010和0x0011中。该值为1D4Ch或十进制的7,500。