logisim单周期CPU的实现
本项目实现了一个支持8条MIPS指令的单周期CPU,核心组件包括取指单元(IFU)、控制器(Controller)、寄存器组(GPR)、数据存储器(DM)、算术逻辑单元(ALU)和扩展单元(EXT)。数据通路采用经典单周期架构,各模块通过控制信号协同工作。
功能:指令读取与PC更新,支持顺序执行、条件分支(BEQ)和无条件跳转(J)
接口:
| 信号 | 方向 | 描述 |
|---|---|---|
| npc_sel | I | BEQ指令标志(1:BEQ, 0:非BEQ) |
| zero | I | ALU计算结果为0标志 |
| J_sel | I | J指令标志(1:J, 0:非J) |
| ins[31:0] | O | 32位指令输出 |
关键功能:
- 复位时PC=0x00003000
- BEQ满足条件时:PC ← PC+4+(sign_ext(offset)<<2)
- J指令时:PC ← { (PC+4)[31:28], address, 00 }
功能:解析指令并生成控制信号
接口:
| 信号 | 方向 | 描述 |
|---|---|---|
| opcode[5:0] | I | 指令操作码 |
| funct[5:0] | I | 功能码 |
| RegDst | O | 写寄存器选择(1:rd, 0:rt) |
| ALUop[1:0] | O | ALU操作控制(00:+ 01:- 10: |
控制信号映射:
| 指令 | RegDst | ALUSrc | RegWrite | ALUop |
|---|---|---|---|---|
| addu | 1 | 0 | 1 | 00 |
| subu | 1 | 0 | 1 | 01 |
| ori | 0 | 1 | 1 | 10 |
| lui | 0 | 1 | 1 | 11 |
功能:32位寄存器读写操作
接口:
| 信号 | 方向 | 描述 |
|---|---|---|
| busW[31:0] | I | 写入数据 |
| RegWr | I | 写使能(1:有效) |
| busA[31:0] | O | 读端口A输出 |
操作特性:
- 同步写:CLK上升沿生效
- 异步读
- 复位时所有寄存器清零
功能:小端序数据存储
接口:
| 信号 | 方向 | 描述 |
|---|---|---|
| memWr | I | 写使能(1:写入) |
| addr[31:0] | I | 字节地址 |
| data_out[31:0] | O | 读取数据 |
功能:32位算术/逻辑运算
支持操作:
case(ALUctr)
0: out = A + B; // 加
1: out = A - B; // 减
2: out = A | B; // 或
3: out = B << 16; // 立即数高位加载
endcase功能:16位立即数扩展
data_out = Extop ?
{{16{data_in[15]}}, data_in} : // 符号扩展
{16'b0, data_in}; // 零扩展| 指令 | 操作码 | 功能描述 |
|---|---|---|
| addu | 000000 | rd ← rs + rt |
| subu | 000000 | rd ← rs - rt |
| ori | 001101 | rt ← rs | (zero-extend)immediate |
| lw | 100011 | rt ← mem[rs + sign-extend(imm)] |
| sw | 101011 | mem[rs + sign-extend(imm)] ← rt |
| beq | 000100 | if(rs==rt) PC←PC+4+(imm<<2) |
| lui | 001111 | rt ← immediate << 16 |
| J | 000010 | PC ← {PC+4[31:28], address, 00} |
main:
lui $t0, 0x1000 # 加载高位地址
ori $t0, $t0, 0x0004 # 构造完整地址 0x10000004
ori $t1, $zero, 5 # 初始化计数器 ($t1=5)
ori $t2, $zero, 1 # 常数1 ($t2=1)
loop:
addu $t3, $t2, $t2 # $t3=1+1=2
subu $t3, $t3, $t1 # $t3=2-5=-3
sw $t3, 0($t0) # 存储结果到 0x10000004
lw $t4, 0($t0) # $t4 = MEM[0x10000004] = -3
subu $t1, $t1, $t2 # 计数器递减 $t1=4,3,2,1,0
beq $t1, $zero, end # 当$t1=0时跳出循环
j loop # 跳转至loop标签
end:
# 循环结束后的算术操作
addu $t3, $t2, $t2 # 重复9次 ($t3=2)
...
程序行为:
- 共20条指令
- 执行至第11条指令后跳转至第5条指令
- 循环执行4次后继续运行剩余指令
寄存器终值:
| 寄存器 | 预期值 | 实际值 |
|---|---|---|
| $t0 | 0x10000004 | 匹配预期 |
| $t1 | 0x00000000 | 匹配预期 |
| $t2 | 0x00000001 | 匹配预期 |
| $t3 | 0x00000002 | 匹配预期 |
| $t4 | 0xFFFFFFFD | 匹配预期 |
存储器状态:
地址 0x10000004: 0xFFFFFFFD (-3的补码)