最近在想,我究竟能从计组课程中学到什么。依葫芦画瓢地搭一个CPU不难,但稍微设想一下从无到有设计指令,构建数据通路控制器,再到优化为多周期、流水线,在权衡中各模块互相调节...整个过程复杂困难曲折到令人咋舌。(就比如流水线CPU的构想,要是我来设计,遇到数据冒险的问题后,估计直接放弃方案了)

搭建之初在想数据通路模块的设计方案最终收敛到如今这般的原因。现在也无甚明悟。

理解设计从产生到成熟过程的一般过程与逻辑,形成一定自主设计构架事物的能力,是课程难忘的重点之一吧。可能天赋有限现在学得还是太死了...

课下

设计总图(支持指令集{addu, subu, ori, lw, sw, beq, jal, jr, lui, nop, j, lh, lb, sh, sb}):

CPU就是执行相关指令集架构的元件。需求产生指令集,指令集产生CPU。在系统结构设计时,我们分离出“机制”和“策略”两个概念,分别进行设计。机制指实现相关基础功能的零部件,解决系统“能否做”的问题;策略指如何组装并控制零部件完成功能实现,解决系统“怎么做”的问题。

设计CPU系统结构时,机制对应数据通路设计,策略对应控制器设计与电路连接

采取了指令和数据分开存储的设计,一来降低难度,二来为流水线CPU铺垫

一、数据通路设计

通过分析一般指令集操作共性,总结信息流通的基本路径和模式,形成相应的抽象模型。

  • 取指令(IFU:PC、NPC、IM)
  • 译码/读操作数(IM、IM_export、RF)
  • 执行(ALU)
  • 访存(DM)
  • 回写(RF)

1.PC

程序计数器。就是一个32位寄存器,接收NPC的信号,指向当前执行指令的地址。

由于指令和数据分离,指令从0x00000000开始,与MARS指令存储段0x00003000起始冲突。如果用MARS生成如jal j 等包含真实指令地址数据的跳转指令机器码,会出错(因为PC值以0x00003000为基准)。

一种解决方式就是换一个可初始化任意值的寄存器,将起始地址设为0x00003000,导出的MARS指令机器码前加上0x00003000条空指令再导入IM即可模拟真实情况。

2.NPC

计算下一条指令的地址

信号名 方向 描述
[31:0] PC Input 32位输入,当前PC值
[15:0] IMM Input 26位立即数(imm16和imm26的综合考量)
[31:0] RA Input jr指令中,所选寄存器32位值输入,目标地址值
[1:0] Op Input 选择不同NPC输出:
2'b00:输出顺序地址PC+4
2'b01:输出指令beq所得地址
2'b10:输出指令jal所得地址
2'b11:输出指令jr所得地址
Zero Input beq指令中,rs和rt的比较结果:
0:不相等
1:相等
[31:0] PC4 Output jal指令中,将PC+4存入$ra内所需输出
[31:0] NPC Output 下一条指令目标地址

3.IM

指令内存。该CPU将指令和数据分开存储。就是一个ROM。此处设置最大指令条数数为 \(2^{16}\),因而输入端A取PC输出信号2-17位。

起始地址:0x0000_0000

4.GRF

通用寄存器堆

信号名 方向 描述
[4:0] A1 Input 输入rs段要读取的寄存器编号
[4:0] A2 Input 输入rt段要读取的寄存器编号
[4:0] A3 Input 输入rd段要写入的寄存器编号
[31:0] WD Input 需要写回的值
RFWr Input 写入使能端
Clk Input 时钟信号端
Rst Input 寄存器复位端
[31:0] RD1 Output 输出A1所选对应寄存器的值
[31:0] RD2 Output 输出A2所选对应寄存器的值

5.EXT

实现不同位扩展功能。

信号名 方向 描述
[15:0] I Input 输入16位立即数
[1:0] EXTOp Input 选择扩展方式:
2'b00:无符号扩展
2'b01:有符号扩展
2'b10:加载到高位
[31:0] O Output 输出扩展后的32位数

6.ALU

算数逻辑单元。

信号名 方向 描述
[31:0] A Input 输入数1
[31:0] B Input 输入数2
[1:0] ALUOp Input 运算选择器:
2'b00:addu加法运算 A + B
2'b01:subu减法运算 A - B
2'b10:ori或运算 A | B
[31:0] Y Output 输出运算结果
Zero Output A和B比较结果:
0:不相等
1:相等

7.DM

数据内存。双端模式RAM实现(RAM 的 Data Interface 属性设置为 Separate load and store ports),容量为\(2^{16} \times 32bit\)。

起始地址:0x0000_0000

信号名 方向 描述
[31:0] A Input 输入选择数据存取目标地址
[31:0] WD Input 输入将要写入的数据内容
DMWr Input 写入使能端
Clk Input 时钟信号端
Rst Input RAM复位端
[1:0] SSel Input store类指令(sw sh sb)选择:
2'b00:选择sw指令需写入的数据
2'b01:选择sh指令需写入的数据
2'b10:选择sb指令需写入的数据
2'b11:空置
[1:0] LSel Input load类指令(lw lh lb)选择:
2'b00:选择lw指令需读出的数据
2'b01:选择lh指令需读出的数据
2'b10:选择lb指令需读出的数据
2'b11:空置
[31:0] RD Output 输出读取出的数据

感觉此处的设计还有些巧妙,通过A的后两位直接给出一个字地址中的位选信号,寻得数字与现实逻辑的直接映射。同时小心,lb lh 等指令不要有理解偏差。

二、电路连接与控制器设计

电路连接方法论

采用形式建模综合方法,制作数据通路连接总表。基于每条指令单独设计建模后,再进行一次性系统级综合,多信号重合处可通过外置位选器解决问题

如上,在RF.A3RF.WDALU.B接口前外置了三个位选器M1、M2、M3,增加3个位选控制信号M1SelM2SelM3Sel

在位选器各口信号连接时,最好将0值留给最常用的数据信号,方便控制器缺省连接,为自己添加指令省心。

控制器设计

控制器的作用:

  • 根据op和funct段识别指令(与逻辑)
  • 根据指令情况控制数据通路设计时产生的各种位选信号

1.控制信号定义汇总

控制信号 描述
[1:0] NPCOp 执行跳转指令时控制选择NPC输出值:
(即NPC的Op信号)
2'b00:输出顺序地址PC+4
2'b01:输出指令beq所得地址
2'b10:输出指令jal所得地址
2'b11:输出指令jr所得地址
[1:0] M1Sel 选择GRF模块A3(写入寄存器)的输入信号:
2'b00:接入IM.D[20:16]信号(也是A2处信号)
2'b01:接入IM.D[15:11]信号
2'b10:接入常量0x1F,即$ra
2'b11:空置
[1:0] M2Sel 选择GRF模块WD(写入内容共)的输入信号:
2'b00:接入NPC.PC4,jal指令存入PC+4的地址
2'b01:接入DM.RD,内存数据的回写
2'b10:接入ALU.C,计算数据回写
2'b11:接入EXT.O,位扩展数据回写(lui)
RFWr GRF的写入使能端
[1:0] EXTOp 位扩展方式:
2'b00:零扩展
2'b01:符号扩展
2'b10:加载至高16位
2'b11
M3Sel 选择ALU模块B的输入信号:
0:接入RF.RD2,接收寄存器取出内容
1:接入EXT.O,接收位扩展后的16位立即数内容
[1:0] ALUOp ALU的运算模式:
2'b00:加法运算
2'b01:减法运算
2'b10:或运算
2'b11:空置
DMWr DM的写入使能端

2.控制器逻辑真值表

3.控制器CTRL实现结构

与逻辑生成指令信号:

或逻辑生成控制信号

课上

课下充分测试不出bug,并熟悉下三类指令(跳转、计算、访存)一般数据通路,课上就很快。

魔改指令:bezal,slo,lword。主要修改都在ALU中。

其中slo指令需实现操作数左移s位并补1,可以同时左移一个0xffffffff后取反,最后和左移后操作数或起来。

加指令

  • 根据指令需求,添加或修改数据通路
  • 控制器中添加指令并连接控制信号
  • 调试检查

【P3】Logisim搭建单周期MIPS-CPU的更多相关文章

  1. 使用logisim搭建单周期CPU与添加指令

    使用logisim搭建单周期CPU与添加指令 搭建 总设计 借用高老板的图,我们只需要分别做出PC.NPC.IM.RF.EXT.ALU.DM.Controller模块即可,再按图连线,最后进行控制信号 ...

  2. 手写一个简易的多周期 MIPS CPU

    一点前言 多周期 CPU 相比单周期 CPU 以及流水线 CPU 实现来说其实写起来要麻烦那么一些,但是相对于流水线 CPU 和单周期 CPU 而言,多周期 CPU 除了能提升主频之外似乎并没有什么卵 ...

  3. 64位的单周期 RISC-V 模拟器

    分享一个我最近完成过的小项目--64位的单周期 RISC-V 模拟器,这个项目我最近参与一生一芯计划过程中完成的一个小项目. 需要用到的相关知识:Verilog.Verilator.计算机组成原理.汇 ...

  4. 使用Verilog搭建一个单周期CPU

    使用Verilog搭建一个单周期CPU 搭建篇 总体结构 其实跟使用logisim搭建CPU基本一致,甚至更简单,因为完全可以照着logisim的电路图来写,各个模块和模块间的连接在logisim中非 ...

  5. P4-verilog实现mips单周期CPU

    最近对学习的掌控可能出现了问题,左支右绌,p2挂了,p2.p3.p4.p5每周在计组花的连续时间少了很多,学习到的东西也少了很多,流水线都还没真正开始写,和别人比落后了一大截,随笔自然就荒废了,我得尽 ...

  6. 单周期CPU设计的理论基础

    写在前面:本博客内容为本人老师原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法UR ...

  7. 单周期cpu设计代码解读

    目录 写在前面 单周期cpu设计代码讲解 概念回顾 Verilog代码讲解 写在前面 欢迎转载,转载请说明出处. 单周期cpu设计代码讲解 概念回顾 一.电子计算机的部件 分为:中央处理器(cpu). ...

  8. verilog实现的16位CPU单周期设计

    verilog实现的16位CPU单周期设计 这个工程完成了16位CPU的单周期设计,模块化设计,包含对于关键指令的仿真与设计,有包含必要的分析说明. 单周期CPU结构图 单周期CPU设计真值表与结构图 ...

  9. 单周期CPU设计

    终于有点时间了,恰好多周期的设计也已经完成,其实只想写写多周期的,无奈单周期补上才好,哈哈哈~ —————+—————黄金分割线—————+————— 首先要理解什么叫单周期CPU(与后面多周期CPU ...

  10. 为什么现在使用多周期CPU,而单周期CPU被弃用?

    最初设计的CPU结构简单,内部不复杂.之所以制造它是为了让机器自动跑程序,算数. 早期CPU都是单周期的,人们没考虑那么多,性能啥的.就让CPU每个时钟周期跑一个指令,这些时钟周期等长.这样下来,有的 ...

随机推荐

  1. Qt/C++地图动态绘制折线多边形矩形圆形标注点/可编辑拖动调整大小和位置

    一.前言说明 无论哪一家的地图,都提供了调用函数绘制各种覆盖物,但是有时候的场景是希望进入添加覆盖物模式,然后每次在地图上按下都自动生成对应的覆盖物比如圆形,这样就不需要用户提前知道经纬度坐标等参数, ...

  2. Ubuntu 装卸Opencv

    buntu中卸载opencv的方法: 1.打开ubuntu: 2.找到当初安装opencv的build目录,进入该build目录执行卸载操作: 3.通过rm命令清理/usr中所有opencv相关项即可 ...

  3. yarn : 无法加载文件 C:\Users\duany\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本

    在win10 下安装yarn后,在编辑器中检查yarn的安装的时候会出现: 解决方法 1:搜索powershell,以管理员方式运行powershell2:使用命令更改计算机的执行策略 执行: set ...

  4. 即时通讯技术文集(第37期):IM代码入门实践(Part1) [共16篇]

    为了更好地分类阅读 52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第37 期. [- 1 -] 一种Android端IM智能心跳算法的设计与实现探讨(含样例代码) ...

  5. vue基础3

    1.watch 案例:百度搜索框 注释的是用watch实现的 然后这个我用的是oninput事件 a.深浅监听 浅监听 深监听(不建议使用) 2.过滤器 全局: Vue.fliter('过滤器名字', ...

  6. Python 问题汇总

    一. Python 环境问题 使用pytest 在terminal中执行脚本调用python3.9, 而使用pycharm 的virtualenv 执行脚本调用的是python3.10, 由于环境不一 ...

  7. runoob-设计模式

    https://www.runoob.com/design-pattern/design-pattern-tutorial.html 设计模式(Design pattern)代表了最佳的实践,通常被有 ...

  8. springboot-权限控制shiro

    1. 场景描述 (1)权限控制是IT项目特别是企业项目,绕不开的重要模块,接下来结合springboot介绍下权限控制框架shiro. (2)springboot集成shiro的东西有点多,一篇博客完 ...

  9. Golang-函数5

    http://c.biancheng.net/golang/func/ Go语言函数(Go语言func) 函数构成了代码执行的逻辑结构,在Go语言中,函数的基本组成为:关键字 func.函数名.参数列 ...

  10. 链路状态路由协议OSPF-02

    路由信息传递与路由计算分离. 基于SPF算法. 以"累计链路开销"作为选路参考值. 所谓Link State(链路状态)指的就是路由器的接口状态.在OSPF中路由器的某一接口的链路 ...