Computer Organization Multi-cycle CPU

未完待续

前段时间学多周期CPU,实验课在FPGA板上自己搭建一个多周期CPU。一方面觉得实在有意思,另一方面怕自己以后忘了,所以这里总结一下

目录

Introduction——why multi-cycle?

单周期CPU的一个时钟时长取决于最长指令需要的时间。多周期CPU能够让不同的指令拥有不同的时执行时间。而实现的方法是将时钟周期变短,给不同的指令分配不同的时钟周期数,从而实现不同指令,不同执行时间,从而加快CPU。

这里的一条指令需要多个时钟周期才能执行完而不是一个时钟周期就是“多周期”名字的由来。
Computer Organization Multi-cycle CPU and it's FPGA implementation

举个例子:——Examples?

上图中如果需要执行一条J指令,需要三个时钟周期:IF(取指令)、ID(指令译码)、J(跳转)

而一条ALU指令需要四个时钟周期:IF(取指令)、ID(指令译码)、Exe_I(执行ALU计算)、R_WB(将计算结果写回寄存器 reg file)

而一条LW指令需要5个时钟周期:IF(取指令)、ID(指令译码)、Exe_Mem(计算rs+偏移量)、Mem_RD(从内存中读取)、LW_WB(将数据写入reg file)

实现细节——What’s the problem?
一般部分——What’s easy?

使用状态机在controller中完成状态之间的跳转(具体是用一个state寄存器保存当前状态编号,当一个时钟上升沿到来时,将state置为下一个状态(这里可能需要根据其他的一些输入,例如opcode),而控制信号随着状态编号的改变而自然改变)

困难部分——What’s hard?
  • 一个时钟周期中产生的数据,例如ID阶段计算出的Branch PC如何在Exe_Beq阶段使用?

    • 使用寄存器(类似D锁存器),并且小心地设置修改寄存器内容的条件
  • 如何分配每个状态需要完成的任务,尽可能让总的任务数少,而且让一条指令需要的时钟周期尽可能少?

    • 这里只提供标准的解决方案,而不详细说明为什么。
    • 首先区分出所有指令都会使用到的操作,例如取指令指令译码,接着继续将指令细分。如下,
    • IF阶段取指令,将整条指令放到IR(instruction register)中,以便后面使用。(立即数将会在lui,R-I type,计算偏移量,R type指令将计算结果送回reg file时寄存器的地址等中使用到,但是由于PC值会被修改,所以内存送回的32位数不再是指令,所以有必要把指令保存起来)。同时由于ALU是空闲的,而且这个时候只有PC,所以让ALU计算PC+4。
    • ID阶段指令译码。指令译码的意思是,ID后面的一个阶段将会根据指令的操作数不同将状态数有不同的修改。同时由于ALU是空闲的,而且这个时候已经有了整条指令(在IR register中),所以让其计算Branch之后的地址
    • 其余的指令将会在后面具体解析

具体实现——Let‘s do it

数据通路

Computer Organization Multi-cycle CPU and it's FPGA implementation

精析——What’s different of datapath compared with SCPU?
  • 增加了4个寄存器
    • IR寄存器用于存指令(32-bit),在IF阶段写入,写入的内容是通过PC值去在RAM中读取的。
    • 这个地方曾经让我困惑。其机理是按下reset键,将PC寄存器清零,其输出口是常读的,送入RAM作为地址访问,RAM的输出口也是常读的,送回Datapath(data2CPU端口),直接被送到了IR寄存器的输入D口。在这种情况下,IF阶段,IRWrite信号被置1,这一条指令直接就被写入IR了
    • MDR寄存器写使能端是直接置1的,所以这个寄存器的内容随着PC值等的变化,RAM返回不同的值而改变。(这里不一定是PC值的变化引起的,因为还有LW指令,上图中可以从M_addr这个输出口看出,送入内存的地址其实有两个来源:PC和ALU_OUT经过一个二选一的多路选择器进行选择)
    • PC寄存器的写入数据端口连着一个四选一的多路选择器,根据不同的状态控制输入和输入不同的值。例如在IF阶段写使能信号是1,多路选择器选择的是ALU的输出口,而通过控制,ALU的输入分别PC寄存器的输出口(也就是老的PC值)和4,这样就把PC+4写入了PC寄存器。(从这里我们也可以看见,虽然有可能这其实是一条J指令,因为现在仅在取指令,而不知道具体的指令,但是PC已经被加了4)
    • ALU_OUT寄存器用于保存ALU的计算结果。例如ID阶段已经计算出的跳转地址,可以用再Beq或者Bne指令中;又如——–
  • 减少了一些小的ALU
    • 例如减少了专门用于计算PC+4的寄存器,原因是一条指令被分为多个周期执行,这意味着ALU在一条指令的执行周期中可以被重复利用

控制器

控制器采用了有限状态机的架构,这样可以如本文开头的状态转移图一样较为容易地完成状态之间的转换工作。

有限状态机

Computer Organization Multi-cycle CPU and it's FPGA implementation
Computer Organization Multi-cycle CPU and it's FPGA implementation

具体的控制信号

Computer Organization Multi-cycle CPU and it's FPGA implementation

将状态编号转化为具体的控制信号

Computer Organization Multi-cycle CPU and it's FPGA implementation

ALU 控制信号

Computer Organization Multi-cycle CPU and it's FPGA implementation

这样就基本完成了多周期CPU的设计

值得强调的一点是,进行verilog代码编写的时候,一定要保持格外的清醒。写代码出错的可能性甚至高于画图。也当是磨炼自己的耐心吧。

[完]

相关文章: