Logisim 单周期CPU设计

设计方案

模块

根据需要的add,sub,ori,lw,sw,beq,nop,lui指令,需要设计IFU,GRF,ALU,DM,Controller,lui模块

IFU

  1. 输入端口设置
    • PC:传入可能要更改到的pc值(beq)
    • PCset:判断pc值是否需要跳转
    • clk:时钟信号
    • reset:异步复位信号
  2. 输出端口设置
    • text:pc值指向的指令内容
    • PCout:输出当前pc值
  3. 模块内部实现
    图片

GRF

  1. 输入端口设置
    • A1:PD1输出对应寄存器地址
    • A2:PD2输出对应寄存器地址
    • WD:写入寄存器的值
    • A3:写入寄存器地址
    • clk:时钟信号
    • reset:异步复位信号
    • WE:写使能信号
  2. 输出端口设置
    • PD1:A1寄存器对应值
    • PD2:A2寄存器对应值
  3. 模块内部实现
    • 采用多路分配器,以A3为选择信号将WE分配至每个寄存器
    • 采用多路选择器,以A1,A2为选择信号将寄存器堆中相应寄存器的值分别选择到PD1,PD2
    • 将clk,reset,WD连接至每一个寄存器对应接口
      图片

ALU

  1. 输入端口设置
    • input1:ALU输入第一个数据
    • input2:ALU输入第二个数据
    • op:选择ALU进行运算的模式:为00时进行加法运算,01时进行减法运算,10时进行或运算,11时进行比较运算,相等输出1,否则输出0
  2. 输出端口设置
    • output:ALU计算结果
  3. 内部实现
    图片

DM

  1. 输入端口设置
    • addr:读写内存地址
    • W:写入内存的数据
    • WR:读写控制信号,为1时写入,0时读出
    • clk:时钟信号
    • reset:异步复位信号
  2. 输出端口设置
    • out:读出内存的值
  3. 具体实现
    采用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
  1. reg_dst:高电平时,多路选择器选择rd值作为写入寄存器的地址,反之选择rt值作为写入地址
  2. ALUsrc:高电平时,多路选择器选择立即数与rs输入至ALU中进行运算,反之选择rt,rs寄存器的值输入至ALU进行运算
  3. MemtoRe:高电平时,写入寄存器的值选择为ROM中读出的值,反之选择为ALU输出的值
  4. RegWrite:RegWrite作为GRF的使能输入
  5. MemWrite:MemWrite作为DM读写控制信号WR输入
  6. PCset:PCset作为IFU跳转控制信号输入
  7. ALUop:两位输出,值为00时选择进行加法运算,值为01时进行减法运算,值为10时进行或运算,值为11时进行比较运算
  8. EXTop:高电平时位扩展为符号扩展,低电平为0扩展
  9. lui:高电平选择imm加载至高位的值作为寄存器写入值

main

根据上述模块功能及各指令的运算方式进行连线
此图甚丑,酌情观看
图片

测试方法

构造MIPS汇编指令进行测试,构造方法如下:

  • 对于ori,add,sub,lui等指令,测试其在0附近和32位数、16位数极端数据的值的运算情况,同时测试其对零号寄存器的写入。
  • 对于beq类指令,测试其比较值相等与不相等的情况,同时测试其向前,向后,向自身的跳转情况
  • 对于lw,sw类指令,测试其在初始地址,末尾地址的读写情况
  • 其余数据可随机构造

若不想自行构造数据,可寻找LazyFishi(https://lazyfish-lc.github.io/)寻求帮助。