10

cpu设计和实现(流水线上的第一条指令)

 1 year ago
source link: https://blog.csdn.net/feixiaoxing/article/details/127932768
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

cpu设计和实现(流水线上的第一条指令)

嵌入式-老费 已于 2022-11-19 19:02:41 修改 197

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        读书的时候,《计算机组成原理》也看了,《计算机体系结构》也学了,老师也给我们讲了各种各样的流水线知识,但是实践的机会很少,感觉就是没有把理论转成实际的东西。工作之后,倒是有机会接触各种各样的开源代码,这里面也包括了开源cpu代码,比如openrisc(https://github.com/openrisc/or1200/tree/master/rtl/verilog)这样的开源代码。但是内容又过于复杂,学习的曲线比较陡,难度很高。所以至此,很多同学就云里雾里不知道流水线和cpu的指令是怎么完成的,总是搞不清楚。

6d7fd622b09d49f9ac9c089a7351d7fb.png

        前面分析过,一条指令的过程是按照取指、译码、执行、访存、写回这5个步骤来完成的。那么今天,就可以用一条5级流水线来实现ori指令。

1、 题外话的一个知识点

        之前我们在编写取指那篇文章的时候,谈到过组合逻辑和时序逻辑的区别。很多刚学verilog的同学,很容易把wire看成是组合逻辑,把reg看成是时序逻辑,这是不对的。是组合逻辑,还是时序逻辑,归根到底还是要看触发条件,比如之前的那个代码,我们稍微调整下,



newCodeMoreWhite.png

         这里的out_b从类型上看,好像是register。但是它的触发条件却是always(*),这就意味着,在这段电路描述中,只要rst或者in发生改变,out_b就会随之改变。这不就是组合逻辑的思路吗?同样,可以借助于gtkwave观察下图形确认一下,

d340c608fc8746babd48abfcce8a1d02.png

         简单分析下,这里的out_b在rst置位的时候,一直输出为0。但是当rst撤去之后,out_b就开始随着in的改变而改变。这个示例告诉我们,组合逻辑和时序逻辑,最终都要通过触发条件来进行区别和判断。如果心里还是拿不准,就仿真看一下波形图结果就好了。

2、流水线编写

        注1:关于本章所有的verilog代码,参考这个地址,https://github.com/feixiaoxing/design_mips_cpu/tree/master/rtl/day03 。

        注2:文中涉及代码,来自于《自己动手写cpu》,向原作者雷思磊表示感谢。

32ded2584007418980e98f96ef54192b.png

2.1 取指if

        取指这部分之前已经描述过了(https://feixiaoxing.blog.csdn.net/article/details/127914989?spm=1001.2014.3001.5502)。主要包含了两个部分,一个是地址的生成,一个是rom数据的读取。做好了这两个,取指的工作就完成了。其中,地址pc生成是时序逻辑,rom读取是组合逻辑。

2.2 指令传递if-id

        指令传送是一个时序逻辑。在这个模块,需要把指令传递给下一个模块,内容不复杂,



newCodeMoreWhite.png

2.3 译码id

        译码是流水线中很重要的工作。它主要的目的,就是从指令数据中提取到合适的信息。比如当前操作是寄存器操作,还是访存操作。如果是寄存器操作,是逻辑运算,还是数学运算。如果是逻辑运算,源操作数1是哪个,源操作数2是哪个,目的操作数是哪个,是什么样的逻辑运算等等。

        另外,在译码的过程中,对cpu通用寄存器的操作也是很重要的,这部分可以看一下,



newCodeMoreWhite.png

        从代码上看,regfile最多支持两个register的读取和一个register的写入。注意,这里读取动作是组合逻辑,写入动作是时序逻辑,这非常重要。此外,不管寄存器是这样,rom操作、ram操作也是这样,读取一般都是组合逻辑,而写入才是时序逻辑。

        说完了寄存器访问,下面就是具体的译码工作了,



newCodeMoreWhite.png

        译码的工作其实也分成了两个部分。一部分,就是之前讨论的指令解析。这里分析的指令是EXE_ORI,所以看到wreg_o、aluop_o、alusel_o等这样的赋值动作。另一部分,就是寄存器的读取动作,至于reg1_o和reg_o是访存register寄存器,还是直接从imm立即数中获取,这取决于具体的情况。就EXE_ORI而言,reg1_o来自于reg1_data_i,reg2_o来自于imm。

2.4 操作数传递id-exe

        操作数的传递也是一个时序逻辑。它的主要功能就是把读取到的操作数、操作方式、写入地址告诉exe模块,



newCodeMoreWhite.png

2.5 执行exe

        有了从id模块获取的操作数和写入地址,这里只要完成对应的操作就可以。注意,执行exe属于组合逻辑,



newCodeMoreWhite.png

        因为exe中可能会有逻辑运算、数学运算、移位运算等等,所以一般这里都会先进行一下区分,最后把结果汇总上来。如上面的代码所示,logicout就是汇总之前的计算,而最终输出的数据时wdata_o。

2.6 执行传递ex-mem

        做完了exe,下面就需要把结果传递给mem这个模块了。也许有同学说,这里不是不需要访存吗,为什么还要传递给mem。这主要是因为之前设计的就是5级流水线,即使最终用不到这一块内容,也需要透传一下。



newCodeMoreWhite.png

2.7 访问mem

        之前说过,这部分其实不需要,只是流水线已经设计好,所以需要的操作就是继续透传下去。接着,我们可以看下verilog代码,



newCodeMoreWhite.png

2.8 访存传递mem-wb

        有了mem阶段的处理,这部分就可以正式交给wb了。需要注意的是,mem访问是组合逻辑,而mem-wb是时序逻辑。



newCodeMoreWhite.png

2.9  wb写回

        很多同学会问,问什么没有wb写回的组合逻辑和时序逻辑。一般来说,wb阶段就是把数据直接写到寄存器里面,这个阶段一般是不会有什么问题的。而写回的数据、寄存器地址,直接给regfile这个模块就可以了,大家可以从openmips.v这个文件看的出来,



newCodeMoreWhite.png

        直接观察wb_wd_i、wb_wreg_i、wb_wdata_i这几个信号,最终是返回给了regfile1这个模块,这也从形式上面完成了流水线的闭环操作。

2.10 仿真和测试

        为了仿真和测试,需要做两步。第一步,给openmips准备一个小的soc模块,把cpu和rom加进去,比如像这样,



newCodeMoreWhite.png

        其次,给这个soc模块准备一个testbench测试,发一下激励信号。



newCodeMoreWhite.png

        注意,测试romdata也发生了变化,

        有了这两步,就可以用iverilog和gtkwave开始测试了,

c3e937c5c87f47e1a6aae460b7668476.png

3、调试方法

        调试的时候,可以优先测试register,也就是时序逻辑。如果时序逻辑没有问题,再对组合逻辑进行问题和验证。测试往往是一个循环往复的过程,需要不断进行,更需要找到root cause。


Recommend

  • 43
    • www.huxiu.com 5 years ago
    • Cache

    流水线上的深圳博士

    “你以为可以像教授一样岁月静好地搞研究,其实大部分时间要在工厂拧螺丝”

  • 3
    • albk.tech 3 years ago
    • Cache

    聊聊CPU的LOCK指令

    聊聊CPU的LOCK指令 | BK的网络日志 BK的网络日志 聊聊CPU的LOCK指令...

  • 3

    为什么CPU重启之后第一条指令是啥也不干的NOP?为啥还是接连两条?中央处理器 (CPU)话题下的优秀答主大家都知道x86的CPU重启动后第一条指令位于地址0xFFFFFFF0,这个地...

  • 6
    • idealclover.top 2 years ago
    • Cache

    CPU 指令集不靠谱扫盲

    CPU 指令集不靠谱扫盲 2019.12.03 | ...

  • 8
    • blog.csdn.net 2 years ago
    • Cache

    CPU的流水线指令设计

    为什么小小一个CPU,有那么多周期(Cycle)? 程序的性能,是由三个因素相乘来衡量的,“指令数×CPI×时钟周期”。 和周期相关的只有一个时钟周期,即CPU主频的倒数。 一个CPU的时钟周期可以认为是可以完成一条最简单的计算机指令的时间。...

  • 9
    • xuanxuanblingbling.github.io 2 years ago
    • Cache

    x86架构的CPU加电后的第一条指令到底在哪?

    本文讨论的第一条指令的概念是存储于CPU外部的指令,因为真正意义上的第一条指令应当位于CPU内部。这个问题其实看intel的CPU手册就知道了! 0x7c00是什么地址 在学操作系统的时候操,如果是编写一个x86架构下的...

  • 6

    CPU流水线与指令乱序执行 青蛙见了蜈蚣,好奇...

  • 5

    CPU居然暗藏大量未公开的指令!|字符串|cpu|操作系统|后门_网易订阅 CPU竟然暗藏大量未公开的指令。我上学的时候就有一门课叫处理器的远程控制。读书的时候,...

  • 1

    国产32核CPU交付:100%自主指令架构|芯片|服务器|cpu_网易订阅 国产CPU又有新进展了,日前某国产芯片CPU厂商已完成32核服务器CPU初样芯片验证,目前将马上交...

  • 2

    在芯片巨头如 Intel、AMD 和 Apple 的各种宣传介绍和文档中,常常提到「架构」一词。比如,Apple 就宣称其...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK