计算机组成实验系列一: 基于通用寄存器的单总线 CPU
- CPU 数据通路
- CPU 控制器
1. CPU 数据通路
- 多路选择器(mux)
- 寄存器(reg)
- 通用寄存器组(RF)
- 算术/逻辑运算单元(ALU)
- 三态门(TSG)
- 存储器(RAM)
- ALU 控制器(ALUCU)
- 总数据通路
1.1 多路选择器(mux)
不使用单独的模块,使用 case 语句实现
1 | case (control) |
1.2 寄存器(reg)
用于暂存不同阶段的数据,其中 Wr 信号为写入信号,高电平有效
1 | module reg ( |
1.3 通用寄存器组(RF)
寄存器 | 效果 |
---|---|
W_data | 数据写入端 |
R_data | 据输出端(可以输出高阻态) |
Reg | 寄存器地址输入 |
OE | 输出使能,高电平有效,低电平时输出高阻态 |
Wr | 写入使能 |
1 | module RF( |
1.4 算术/逻辑运算单元(ALU)
ALUCtrl | 功能 | ALUCtrl | 功能 |
---|---|---|---|
000 | AND | 100 | 小于置一 |
001 | OR | 101 | NOT(A) |
010 | ADD | 110 | NOR |
011 | SUB | 111 | XOR(异或) |
1 | module alu( |
1.5 三态门(TSG)
Ctrl 引脚高电平有效,低电平时输出高阻态
1 | module( |
后面发现了这个模块有很多的 error,最终发现问题在于使用参数表示位宽和按照 c 语言的习惯将 1 当作 True.
遂将模块重写,最大支持参数为 32,实测当 N 小于 32 时不会报错(甚至连 warning 都没)
1 | module tsg( |
1.6 存储器(RAM)
RAM 总体可以看作一个组合电路,其数据的输入输出由 MAR 和 MDR 进行缓存(对实际存储器进行了理想的简化)
RAM 的访问可以在一个时钟周期内实现,故而使用同步方式进行控制
引脚 | 功能 |
---|---|
R | 读取使能端(其实不需要) |
W | 写入使能端,高电平有效 |
Addr | 地址输入引脚 |
R_data | 读取数据线 |
W_data | 写入数据线 |
1 | module ram( |
1.7 ALU 控制器(ALUCU)
由下面指令控制流程可知,ALUCU 根据 ALUOp 和 funct 输入输出 ALU 控制信号 ALUCtrl,真值表如下
ALUOp | 功能 |
---|---|
00 | ALU 执行加操作,用来在修改 PC 寄存器计算地址等 |
10 | ALU 执行 funct 指定的运算操作 |
01 | 输出(A==0)的值 |
11 | 未定义的操作 |
8. 总数据通路
数据通路和支持的指令如图所示
2. CPU 控制器
- 指令控制流程
- 引脚功能
- MCU 设计
2.1 指令控制流程
主控制器,负责控制整个数据通路部件的控制,其中引脚定义见数据通路
取指令阶段
1-第一个时钟周期:送指令地址
MAR <- (PC);PCOeh,PCOel,MARWr
A <- (PC);AWr
2-第二个时钟周期:取指令
IR <- M[MAR];MemRd,MemOe,IRWr
3-第三个时钟周期:送 PC 修正量
B <- 4;ExtSel=10,ImmOeh,ImmOel,BWr
4-第四个时钟周期:修正 PC
PC <- (PC)+4;ALUOp=00,ALUCtrl==010,ALUOe,PCWr
5-第五个时钟周期:指令译码和读寄存器
A <- (RF[IR[25:21]]);RegSel=00,RegOe,Awr指令执行阶段
2.1 取数指令(LW)
6-第六个时钟周期:计算存储器地址
B <- (SigExt[IR[15:0]]);ExtSel=00,ImmOeh,ImmOel,BWr
7-第七个时钟周期:送存储器地址
MAR <- (A)+(B);ALUOp=00,ALUCtrl=010,ALUOe,MARWr
8-第八个时钟周期:读存储器
MDR <- M[MAR];MemRd,MDRSrc,MDRWr
9-第九个时钟周期:写寄存器
RF[IR[20:16]] <- (MDR);MDROe,RegSel=01,RegWr2.2 存数指令(SW)
6-第六个时钟周期:计算存储器地址
B <- (SigExt[IR[15:0]]);ExtSel=00,ImmOeh,ImmOel,BWr
7-第七个时钟周期:送存储器地址
MAR <- (A)+(B);ALUOp=00,ALUCtrl=100,ALUOe,MARWr
8-第八个时钟周期:读寄存器
MDR <- (RF[IR[20:16]]);RegSel=01,RegOe,MDRSrc=0,MDRWr
9-第九个时钟周期:写存储器
M[MAR] <- (MDR);MemWr2.3 算术/逻辑运算指令(R 型指令)
6-第六个时钟周期:读寄存器
B <- (RF[IR[20:16]]);RegSel=01,RegOe,BWr
7-第七个时钟周期:运算并写寄存器
RF[IR[15:11]] <- (A)OP(B);ALUOP=10,ALUCtrl=xxx,ALUOe,RegSel=10,RegWr3.4 分支指令(BEQ)
6-第六个时钟周期:程序转移
A <- (RF[IR[20:16]]);RegSel=10,RegOe,BWr
if Z==0 then 指令周期结束,ALUOp=01,ALUCtrl=101
7-第七个时钟周期:送 PC
A <- (PC);PCOeh,PCOel,AWr
8-第八个时钟周期:送 PC 修正量
B <- (SigExt (IR[15:0]<<2));ExtSel=01,ImmOeh,ImmOel,BWr
9-第九个时钟周期:计算转移地址
PC <- (A)+(B);ALUOp=00,ALUCtrl=010,ALUOe,PCWr2.5 跳转指令(J)
6-第六个时钟周期:转移
PC <- (PC[31:28])||(IR[25:0]<<2);PCOeh,ExtSel=11,ImmOel,PCWr
2.2 引脚功能
输出引脚
输出引脚 | 作用 | 输出引脚 | 作用 |
---|---|---|---|
CLK | 时钟信号 | ALUOe | ALU 输出使能 |
PCOeh | PC 高 4 位输出总线 | RegOe | 通用寄存器输出使能 |
PCOel | PC 低 28 位输出总线 | RegWr | 通用寄存器写入使能 |
PCWr | PC 写入使能 | RegSel | 通用寄存器写入源选择 |
IRWr | IR 写入使能 | MARWr | MAR 写入使能 |
ImmOeh | 立即数高 4 位输出总线 | MemRd | 存储器读使能 |
ImmOel | 立即数低 28 位输出总线 | MemWr | 存储器写使能 |
ExtSel | 符号扩展方式选择 | MDRSrc | MDR 写入源选择 |
ALUOp | ALU 操作 | MDROe | MDR 输出使能 |
ALUCtrl | ALU 操作控制 | MDRWr | MDR 写入使能 |
AWr | A 暂存器写入使能 | MemOe | 存储器输出使能 |
BWr | B 暂存器写入使能 |
ExtSel 功能表
ExtSel | 符号扩展方式 | 解释 |
---|---|---|
00 | SigExt(IR[15:0]) | 将输入的 16 位立即数符号扩展为 32 位 |
01 | SigExt(IR[15:0])<<2 | 在 00 的基础上左移两位 |
10 | 立即数 4 | 直接输出立即数 4 |
11 | IR[25:0]<<2 | 将 26 位地址值左移 2 位 |
其中输出立即数 4 是为了普通的连续执行指令的时候作为 PC 的修正值输出源
2.3 MCU 设计
参考资料:《计算机组成与设计》 王换招、陈妍、赵青苹 编著版