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

阅读更多

三步教你用Verilog写一个CPU

第三步:登峰造极

 

基础

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

编程语言:Verilog

开发平台:xilinx ISE

FPGA开发板:Nexys3

 

 

教学大纲

第一步

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

第二步

内存设计与CPU测试

第三步

指令冲突避免

 

 

指令冲突介绍

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

 

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


构造冒险

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


数据冒险

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


三步教你用Verilog写一个CPU:第三步_第1张图片图1 数据冒险

 

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


三步教你用Verilog写一个CPU:第三步_第2张图片图2 数据转发

 

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


三步教你用Verilog写一个CPU:第三步_第3张图片图3  LOAD冒险暂停机制

 

控制冒险

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

 

 

指令冲突的避免

数据冒险

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


三步教你用Verilog写一个CPU:第三步_第4张图片图4  LOAD冒险避免代码实现

 

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


三步教你用Verilog写一个CPU:第三步_第5张图片图5 数据转发部分代码实现

 

控制冒险

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


三步教你用Verilog写一个CPU:第三步_第6张图片图6 控制冒险避免代码实现

 

 

 代码实现

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

 

 

 

  • 三步教你用Verilog写一个CPU:第三步_第7张图片
  • 大小: 17.5 KB
  • 三步教你用Verilog写一个CPU:第三步_第8张图片
  • 大小: 79.2 KB
  • 三步教你用Verilog写一个CPU:第三步_第9张图片
  • 大小: 39.6 KB
  • 三步教你用Verilog写一个CPU:第三步_第10张图片
  • 大小: 34.1 KB
  • 三步教你用Verilog写一个CPU:第三步_第11张图片
  • 大小: 46 KB
  • 三步教你用Verilog写一个CPU:第三步_第12张图片
  • 大小: 68.5 KB
  • 三步教你用Verilog写一个CPU:第三步_第13张图片
  • 大小: 17.7 KB
  • CPU设计代码.zip (33 KB)
  • 下载次数: 48
  • 查看图片附件

你可能感兴趣的:(Verilog,CPU,FPGA)