单周期与多周期CPU:谁才是时钟信号的忠犬?!🕰️
引言:CPU世界的两位主角
在我们深入计算机处理器的核心之前,必须先认识舞台上的两位主角。想象一个高效的工厂流水线:
-
工人(组合逻辑):他们从不休息,只要手上有零件(输入数据),他们就会立刻开始加工(计算),并把成品(输出数据)放到传送带上。他们没有记忆,只负责埋头干活。CPU中的ALU、加法器、多路选择器(MUX)就是这样的“工人”。
-
仓库管理员(时序逻辑):他们非常守纪律,只在每天早上八点钟(时钟上升沿)的铃声响起时,才把传送带上的成品验收入库(更新/存储),并把新的零件(存储的数据)分发出去。他们负责“记住”当前的状态。CPU中的PC、寄存器堆、以及我们稍后会提到的各种中间寄存器,都是这样的“管理员”。
第一幕:单周期CPU——一场盛大但笨拙的同步华尔兹
在单周期CPU的设计中,我们的目标是“宏大”的:一条指令的所有工作,从取指到最终结果写回,都必须在一个时钟周期(一个铃声周期)内完成。
联动的具体细节:
-
铃声响起(时钟上升沿):
-
PC
这位仓库管理员,听到铃声,立刻将早已在门口等待的PC+4
地址(或跳转地址)验收入库,更新了自己的值。 -
同时,
寄存器堆
里的另一位管理员,如果上一条指令有写回要求(RegWr=1
),也会在同一声铃响时,将计算结果写入指定的目标寄存器。 -
这是整个周期中,唯一发生“状态更新”的瞬间。
-
-
铃声之间(整个时钟周期内):
-
PC
更新后,立刻稳定地输出新的指令地址。 -
这个地址像水流一样,持续地流过指令存储器(组合逻辑),取出了指令。
-
指令码持续地流向控制单元和寄存器堆,译码并读出操作数。
-
操作数持续地流向ALU,进行计算。
-
ALU的结果持续地流向数据存储器或最终的写回MUX。
-
这是一场由组合逻辑主导的、从左到右的、不间断的数据计算和传递。
-
-
下一声铃响之前:
- 所有“工人”(组合逻辑)必须完成他们的接力计算。最终要写回寄存器的数据,必须已经稳定地出现在
寄存器堆
的“入库门口”(写数据端口)。同时,下一条指令的地址也必须计算完毕,稳定在PC
的“入库门口”。这个准备过程,叫做建立时间(Setup Time)。
- 所有“工人”(组合逻辑)必须完成他们的接力计算。最终要写回寄存器的数据,必须已经稳定地出现在
案例分析:单周期CPU执行 add $1, $2, $3
-
T1上升沿:PC更新为
add
指令的地址(假设为A
)。 -
T1到T2周期内:
-
PC输出地址
A
,指令存储器输出add
的机器码。 -
机器码被译码,
rs
($2
)和rt
($3
)字段指定寄存器堆读出$2
和$3
的值。 -
$2
和$3
的值流入ALU,ALU根据控制信号进行加法运算,得出结果Sum
。 -
结果
Sum
流向写回MUX,并被选择。 -
与此同时,PC旁边的加法器计算出
A+4
。 -
在T2到来前,结果
Sum
稳定在寄存器堆的写数据端口,写地址$1
(来自rd
字段)也已就绪。地址A+4
稳定在PC的输入端口。
-
-
T2上升沿:
-
寄存器堆
将Sum
写入$1
。 -
PC
的值更新为A+4
。 -
add
指令的生命周期结束。
-
小结:在单周期CPU中,时钟像一个发令枪。枪响(上升沿)后,所有组合逻辑开始一场盛大的数据接力赛,必须在下一枪响之前完成。时钟的作用是“启动”和“锁存结果”。
第二幕:多周期CPU——分步执行的优雅芭蕾
单周期的“华尔兹”虽然同步,但因为要迁就最慢的舞者(lw
指令),导致节奏异常缓慢。多周期CPU则将舞蹈分解成多个小节拍,每个小节拍(一个短时钟周期)完成一个基本动作。
为了让每个小节拍的成果能被“记住”并传递给下一个节拍,我们需要引入更多的“仓库管理员”——中间寄存器(如指令寄存器IR、存储器数据寄存器MDR、ALU输出寄存器ALUOut等)。
联动的具体细节:
在这里,时钟的每一次敲击都意义非凡,它代表着数据从一个阶段到下一个阶段的正式交接。
-
铃声响起(时钟上升沿):
-
所有参与本次状态更新的“仓库管理员”(PC, IR, MDR, ALUOut等)同时打开库门,接收各自面前传送带上的数据。
-
例如,在取指(IF)阶段结束的那个上升沿,
IR
会锁存从内存取出的指令,PC
会锁存PC+4
的结果。
-
-
铃声之间(一个短时钟周期内):
-
组合逻辑们只做一个小任务。例如,在执行(EX)阶段,ALU只需要根据A、B两个临时寄存器(它们在这个周期内是稳定的)的内容进行计算。
-
计算结果被送到下一个阶段的中间寄存器门口(例如
ALUOut
寄存器)等待。
-
案例分析:多周期CPU执行 lw $2, 100($3)
这条指令被分解为5个阶段,对应5个时钟周期。
-
周期1:取指(IF)
-
铃声之间:PC输出地址,指令存储器读出指令。
-
下一个上升沿:指令被锁存到
IR
寄存器,PC
更新为PC+4
。
-
-
周期2:译码/读寄存器(ID)
-
铃声之间:
IR
的内容(此时稳定不变)被译码,寄存器堆根据rs
字段读出$3
的值,并暂存。 -
下一个上升沿:
$3
的值被锁存到临时寄存器A
,立即数100
被符号扩展后锁存到临时寄存器Imm
。
-
-
周期3:执行/地址计算(EX)
-
铃声之间:
A
和Imm
的内容(此时稳定)送入ALU,ALU进行加法运算,计算出有效地址。 -
下一个上升沿:计算出的地址被锁存到
ALUOut
寄存器。
-
-
周期4:访存(MEM)
-
铃声之间:
ALUOut
的内容(此时稳定)作为地址访问数据存储器,读出数据。 -
下一个上升沿:从内存读出的数据被锁存到
MDR
(存储器数据寄存器)。
-
-
周期5:写回(WB)
-
铃声之间:
MDR
的内容(此时稳定)被送到寄存器堆的写数据端口,IR
中的rt
字段($2
)被送到写地址端口。 -
下一个上升沿:
MDR
的数据被正式写入寄存器$2
。指令执行完毕。
-
小结:在多周期CPU中,时钟是推动指令执行阶段前进的引擎。每一次“心跳”,都将数据从前一级的中间寄存器中取出,经过一小段组合逻辑的计算,再存入下一级的中间寄存器。整个过程像是一场分工明确、节奏紧凑的芭蕾舞。