`
Marshal_R
  • 浏览: 129946 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

三步教你用Verilog写一个CPU:第三步

阅读更多

三步教你用Verilog写一个CPU

第三步:登峰造极

 

基础

课程要求:数字电路、计算机组成原理、程序设计

编程语言:Verilog

开发平台:xilinx ISE

FPGA开发板:Nexys3

 

 

教学大纲

第一步

指令集设计与五级流水线的实现

第二步

内存设计与CPU测试

第三步

指令冲突避免

 

 

指令冲突介绍

    在我们之前的测试中可以看到,指令之间加入了许多额外的NOP指令,这都是为了避免指令冲突,插入NOP可以有软件的实现方式(编译器),也可以通过硬件实现,即CPU检测到冲突的时候就执行NOP指令。不过对于CPU的设计者来说,这极大地降低了CPU的性能,是不可容忍的。下面我来详细讲解指令冲突的不同场合以及避免措施。

 

    流水线处理中,由于各个阶段的依赖关系、硬件资源的竞争等原因,会出现操作无法同时执行的情况。造成流水线故障的原因称为冒险,冒险分为构造冒险、数据冒险和控制冒险 3 种类型。


构造冒险

        由于硬件资源的竞争,操作无法同时执行的情况。由于内存设计采用了指令内存和数据内存分离的方式,因此不会产生构造冒险。


数据冒险

        由于指令执行所需要的数据还未准备好所引起的冒险情况。当即将执行的指令依赖于还未处理完成的数据时,会导致指令无法立刻开始执行,引发数据冒险。


图1 数据冒险

 

        数据冒险可以简单地通过插入 NOP 的方式避免,不过这样大大降低了流水线的工作性能。另外的方法就是通过数据转发,尽管数据回写在 WB 阶段,但实际上运算结果在 EX阶段就已经确定,可以传递给下一条指令。


图2 数据转发

 

        数据转发有一个例外就是 LOAD 指令,由于 LOAD 指令从内存调取数据是在 MEM 阶段才完成的,而此时下一条指令也已经到了 EX 阶段,与数据转发不吻合。解决 LOAD 冒险的方法是暂停机制,阻塞流水线一个周期,到下一个周期的时候再继续执行 LOAD 之后的指令。


图3  LOAD冒险暂停机制

 

控制冒险

        无法确定下一条指令而引发的冒险情况。在执行可能会改变下一条指令的分支指令时,在这一条指令执行结果确定之前下一条指令无法开始执行,从而引起控制冒险。控制冒险也可以通过在分支 指令之后插入 3 条NOP 指令避免,不过更加高效的方法是采用静态分支预测,即假定分支指令不转移,CPU 继续执行跟在分支指令之后的指令,当分支指令执行到MEM 阶段确定了分支需要转移,则排空流水线 IF、ID、EX 阶段,重新读取转移目标地址处的指令开始顺序执行。

 

 

指令冲突的避免

数据冒险

        LOAD 冒险要在 IF 阶段进行检测,如果当前已经有一条 LOAD 指令进入 ID 阶段,并且下一条指令(即处于 IF 阶段的指令)与之存在数据冲突,则阻塞流水线一个周期,具体做法是保持 PC 值不变,在 IF 阶段插入 NOP 指令。


图4  LOAD冒险避免代码实现

 

        数据转发在 ID 阶段进行检测,数据转发到 reg_A、reg_B 或者 smdr 寄存器,如果与上一条指令(ex_ir)冲突,从 ALUo 处转发数据,否则如果与上上条指令(mem_ir)冲突,从reg_C 或者数据内存 d_datain 处转发数据,否则如果与上上上条指令(wb_ir)冲突,从 reg_C1处转发数据。


图5 数据转发部分代码实现

 

控制冒险

        可以在 MEM 阶段设置一个跳转标志寄存器,当且仅当分支指令被确认为跳转时标志寄存器有效。标志寄存器有效则排空流水线 IF、ID、EX 阶段,这样就避免了跟在分支指令之后本不该被执行的指令在 EX、MEM、WB 阶段修改 zf、nf、cf、8 个通用寄存器以及数据内存的值,具体做法是把 id_ir、ex_ir、mem_ir 置为 NOP,dw 不使能,同时还要保证把 PC设置为跳转目标地址。


图6 控制冒险避免代码实现

 

 

 代码实现

    至此,整个CPU的设计以及测试都已经介绍完了,这里代码就不贴上来了,因为光是pcpu模块就有五百多行代码,篇幅占用太大了,三步所有的代码都可以在文章末尾下载到。这些都是我个人写的代码,不一定十分准确,仅供参考,希望能对想接触CPU设计的各位有所帮助!

 

 

 

  • 大小: 17.5 KB
  • 大小: 79.2 KB
  • 大小: 39.6 KB
  • 大小: 34.1 KB
  • 大小: 46 KB
  • 大小: 68.5 KB
  • 大小: 17.7 KB
分享到:
评论

相关推荐

    夏宇闻Verilog教程.pdf

    第三章 Verilog HDL的基本语法 第四章 不同抽象级别的Verilog HDL模型 第五章 基本运算逻辑和它们的Verilog HDL模型 第六章 运算和数据流动控制逻辑 第七章 有限状态机和可综合风格的Verilog HDL 第八章 可综合的...

    夏闻宇Verilog教程

    第三章 Verilog HDL的基本语法.doc 第九章虚拟器件和虚拟接口模型以及它们在大型数字系统设计中的作用.doc 第二章 Verilog HDL设计方法概述.doc 第五章 基本运算逻辑和它们的Verilog HDL模型.doc 第八章 可综合...

    自己动手写CPU

    第三篇是进阶篇,通过为教学版OpenMIPS添加Wishbone总线接口,从而实现了实践版OpenMIPS处理器,并与SDRAM控制器、GPIO模块、Flash控制器、UART控制器、Wishbone总线互联矩阵等模块组成一个小型SOPC,然后下载到FPGA...

    山威电子系大二下的微机原理-汇编语言-上机实验实验报告

    读完上面的四步,对顺序CPU、乱序超标量CPU都会有一个从理论到设计实践的完整体验,尤其是trade-off的思想。完成这四步以后,就可以阅读更高阶的体系结构论文,以及进入公司实习,学习现代处理器的设计方法学。

    cpu的简单设计

    指令中后第二、三个操作数均为寄存器时,需要判断LOAD的第一个操作数是否与这些指令的后两个寄存器有冲突 为一部分算数运算指令和逻辑运算指令 */ if((i_datain[15:11] == `ADD ||i_datain[15:11] == `ADDC ...

    Quartus_II使用教程

    点选next,让自己选择第三方软件,如ModelSim,Synplify等,不做任何修改,直接 next,最后finish,整个工程配置完成。 当我们以后再建立工程的时候,由于我们下载使用的芯片都是一样的,工程的基本信息 都是一样的...

    DFT的matlab源代码-FPGA:数字IC相关资料

    此repo实现了一个简单的MIPS五级流水CPU: 实现简单MIPS五级流水CPU对应视频: 项目相关 Serdes相关 波形捕获率 插值滤波器 题目 经典题目 笔试题目 代码 参考书目清单 硬件架构的艺术英文原版: risc-v介绍博客: ...

    复旦nois教材01.rar

    第三章 Nios CPU结构..................................................................................................................36 3.1 NIOS处理器概述.................................................

    基于MIPS的处理器-:这是“高级计算机体系结构”课程的项目

    该项目包括3个阶段:1:实现基于MIPS的基本处理器(基准)2:实现定制的处理器添加了动态调度(用于无序执行命令)3:在CPU中实现高速缓存和跳转预测 测试代码,以升序生成数字序列,并将排序代码以及数字输入...

    simple-processor-master.zip

    自己做项目中的代码和资料的总结,包括,三部分,代码,testbench仿真,文档解释,Verilog数字系统设计教程(第二版) 夏宇闻PDF完整版,因为我的资源比较详细,并且可以直接拿来当课程设计,所以我准备设置高一点积分...

Global site tag (gtag.js) - Google Analytics