Logisim 单周期CPU设计
Logisim 单周期CPU设计
shiki设计方案
模块
根据需要的add,sub,ori,lw,sw,beq,nop,lui指令,需要设计IFU,GRF,ALU,DM,Controller,lui模块
IFU
- 输入端口设置
- PC:传入可能要更改到的pc值(beq)
- PCset:判断pc值是否需要跳转
- clk:时钟信号
- reset:异步复位信号
- 输出端口设置
- text:pc值指向的指令内容
- PCout:输出当前pc值
- 模块内部实现
GRF
- 输入端口设置
- A1:PD1输出对应寄存器地址
- A2:PD2输出对应寄存器地址
- WD:写入寄存器的值
- A3:写入寄存器地址
- clk:时钟信号
- reset:异步复位信号
- WE:写使能信号
- 输出端口设置
- PD1:A1寄存器对应值
- PD2:A2寄存器对应值
- 模块内部实现
- 采用多路分配器,以A3为选择信号将WE分配至每个寄存器
- 采用多路选择器,以A1,A2为选择信号将寄存器堆中相应寄存器的值分别选择到PD1,PD2
- 将clk,reset,WD连接至每一个寄存器对应接口
ALU
- 输入端口设置
- input1:ALU输入第一个数据
- input2:ALU输入第二个数据
- op:选择ALU进行运算的模式:为00时进行加法运算,01时进行减法运算,10时进行或运算,11时进行比较运算,相等输出1,否则输出0
- 输出端口设置
- output:ALU计算结果
- 内部实现
DM
- 输入端口设置
- addr:读写内存地址
- W:写入内存的数据
- WR:读写控制信号,为1时写入,0时读出
- clk:时钟信号
- reset:异步复位信号
- 输出端口设置
- out:读出内存的值
- 具体实现
采用RAM部件实现内存,选择ROM模式为Separate load and store ports
,WR直接连接st端,通过非门连接ld端(保证写入数据与读出数据分离进行)
Controller
Controller_op
根据输入的opcode与func判断其指令类型,并将对应输出端口置为高电平
Controller_rec
使用logisim中的真值表生成电路功能,根据输出,使输出端口reg_dst,ALUsrc,MemtoReg,RegWrite,MemWrite,PCset,EXTop,ALUop输出对应值
类型输出 | add | sub | ori | beq | lw | sw | jr | jal | lui |
---|---|---|---|---|---|---|---|---|---|
RegDst | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
ALUsrc | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
MemtoReg | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
RegWrite | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
MemWrite | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
PCset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
EXTop | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
lui | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
ALUop | 00 | 01 | 10 | 11 | 00 | 00 | 00 | 00 | 00 |
- reg_dst:高电平时,多路选择器选择rd值作为写入寄存器的地址,反之选择rt值作为写入地址
- ALUsrc:高电平时,多路选择器选择立即数与rs输入至ALU中进行运算,反之选择rt,rs寄存器的值输入至ALU进行运算
- MemtoRe:高电平时,写入寄存器的值选择为ROM中读出的值,反之选择为ALU输出的值
- RegWrite:RegWrite作为GRF的使能输入
- MemWrite:MemWrite作为DM读写控制信号WR输入
- PCset:PCset作为IFU跳转控制信号输入
- ALUop:两位输出,值为00时选择进行加法运算,值为01时进行减法运算,值为10时进行或运算,值为11时进行比较运算
- EXTop:高电平时位扩展为符号扩展,低电平为0扩展
- lui:高电平选择imm加载至高位的值作为寄存器写入值
main
根据上述模块功能及各指令的运算方式进行连线
此图甚丑,酌情观看
测试方法
构造MIPS汇编指令进行测试,构造方法如下:
- 对于ori,add,sub,lui等指令,测试其在0附近和32位数、16位数极端数据的值的运算情况,同时测试其对零号寄存器的写入。
- 对于beq类指令,测试其比较值相等与不相等的情况,同时测试其向前,向后,向自身的跳转情况
- 对于lw,sw类指令,测试其在初始地址,末尾地址的读写情况
- 其余数据可随机构造
若不想自行构造数据,可寻找LazyFishi(https://lazyfish-lc.github.io/)寻求帮助。