计算机基础实战课
彭东
网名 LMOS,Intel 傲腾项目关键开发者
19719 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 57 讲
计算机基础实战课
15
15
1.0x
00:00/00:00
登录|注册

06|手写CPU(一):迷你CPU架构设计与取指令实现

你好,我是 LMOS。
经过上一节课的学习,我们已经知道了一个基于 RISC-V 指令集设计的 CPU,必须要实现哪些指令。从这节课开始,我们就可以着手设计和实现 MiniCPU 了。
我会先跟你讲讲什么是流水线,在 CPU 中使用流水线的好处是什么?然后,我们再以经典的五级流水线为例,讲解 CPU 流水线的五个阶段。接着设计出我们 MiniCPU 的总体结构,并根据规划的五级流水线,完成流水线的第一步——取指模块的设计。课程的配套代码可以从这里下载。
话不多说,让我们正式开始今天的学习吧。

什么是 CPU 流水线?

说到流水线,你是否会马上想到我们打工人的工厂流水线?没错,高大上的 CPU 流水线其实和我们打工人的流水线是一样的。
假如我们在冰墩墩工厂上班,生产流水线分为五个步骤,如下图所示:
在冰墩墩生产线上需要至少五个工人,各自负责模具制作、模具清洗、模具抛光、硅胶塑形和融入图案这五个环节中的一个。最简单的方法自然是:同一时刻只有一个冰墩墩在制作。但是冬奥会的热度让市场上的冰墩墩供应不足,为了早日实现“人手一墩”的目标,有什么提升生产效率的办法呢?
稍微想想就知道,生产线上一个人在制作冰墩墩的时候,另外四个工人都处于空闲状态,显然这是对人力资源的极大浪费。想要提高效率,我们不妨在第一个冰墩墩模具制作出来进入清洗阶段的时候,马上开始进行第二个冰墩墩模具的制作,而不是等到第一个冰墩墩全部步骤做完后,才开始制作下一个。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了基于RISC-V指令集的MiniCPU的设计与实现,重点围绕CPU流水线的原理和MiniCPU的架构设计展开。文章首先解释了CPU流水线的五个阶段,并详细介绍了MiniCPU的架构设计,包括各个单元模块的功能。重点阐述了MiniCPU中体现五级流水线的主要模块,如分支预测模块、取指通路模块、译码到执行之间的模块、指令执行模块和数据写回模块。此外,还详细讲解了取指模块的设计与实现,以及取指数据通路模块的功能和代码实现。整体而言,本文适合对计算机体系结构感兴趣的读者阅读,涵盖了硬件底层的CPU设计和实现细节,具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《计算机基础实战课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(21)

  • 最新
  • 精选
  • 苏流郁宓
    预读取指令的好处是加强分支预测能力,减少无用功,但不仅仅于此,比如某些软件代码转汇编,为了对齐会增加一些无用的指令,比如x86的nop(它有时会夹在几个其它指令中),还有 复杂的指令可以通过微码进行转换为几个简单的指令,总之,cpu不是也不应该所有的指令全部都执行 预读取指令,有利于提高cpu效率,在一开始不执行浪费的时间好过cpu做到一半,才发现是无用的指令强的啊,还有部分条件指令,可以跳过不执行(比如c语言提高if的权重,降低else if的权重就是代码优化的方法),所以提高cpu效率在软硬件结合一起努力的啊 可以直接取指然后译码再执行,但那样效率会低很多!分支预测是配合cpu流水线工作的,主要是看应用场景,电脑手机等肯定用到分支预测等,但那些老旧或简单的计算器压根分支预测用不到呀 一句话:看应用场景再决定造什么样的cpu?

    作者回复: 正确

    2022-08-08归属地:湖北
    12
  • =
    wire [31:0] adder = is_jal ? jimm : (is_bxx & bimm[31]) ? bimm : 4; assign pre_pc = pc + adder; 在计算指令地址偏移量的时候,为什么写is_bxx & bimm[31],而不是直接写is_bxx呢?

    作者回复: 向前 向后 跳转

    2022-08-08归属地:湖北
    4
    3
  • 伊宝峰
    对指令预读取,方便形成流水线,加快执行速度,因为从存储器中直接取指令会比较慢。

    作者回复: 是的

    2022-08-13归属地:湖北
    2
  • 一笑千古
    老师,我想问一下为什么要将立即数的最高位复制以满足32位寄存器的长度要求

    作者回复: 因为数据是有符号的

    2022-12-07归属地:湖北
  • 一个要强的男人
    老师,请问:对于单核cpu的流水线来说,如果在译码阶段占满了这个时钟周期,那么如何在对下一个任务进行取指呢?还是说在设计之初已经确定这个时钟周期肯定能执行完4个操作。这是我的疑问,对于单核来说,并没有像工人的流水线(有五个人在工作),这种怎么理解呀,搜索了很多资料都在拿工厂的流水线打比喻,没搞明白。

    作者回复: 单核也是一样的 一个周期分成几个节拍 工作的

    2022-12-01归属地:湖北
    2
  • 雨巷
    请问老师,jalr指令没有进行分支预测是吧?

    作者回复: 嗯嗯

    2022-11-25归属地:湖北
  • 小傅
    wire [31:0] bimm = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0}; 这句怎么理解呢,{20{instr[31]}}这又是什么意思呢?

    作者回复: 你学过verilog吗

    2022-11-15归属地:湖北
  • Geek_489363
    根据b型指令的格式,为什么会有得到{{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0}?不是很理解

    作者回复: b指令的数据格式 就是这样啊

    2022-11-08归属地:湖北
  • 吴建平
    确实少了一段代码,下面这部分,gitee也没有。而且输入in_pc_next也没有在模块定义里看到。我的理解是,pre_id是if_id的伴生电路,他们俩其实都属于取指阶段,逻辑上属于同一个时钟周期。正常情况下(流水线正常运作),每次时钟跳变,根据next读取新的指令,pre_id就算出下一条指令地址,此时if_id就用此输出作为in_pc_next输入。所以pre_id比if_id要快半个周期。 //下一条指令的PC always @(posedge clock) begin if (reset) begin reg_pc_next <= 32'h0; end else if (flush) begin reg_pc_next <= 32'h0; end else if (valid) begin reg_pc_next <= in_pc_next; end end

    编辑回复: 你的留言我们已经收到,已经跟LMOS确认啦。if_id模块的设计,老师考虑到代码简洁一些有助于初学用户理解,最新一版Gitee代码里已经把这段删掉了,且并不影响整体的功能。你可以拉取一下最新的代码。

    2022-08-23
  • 吴建平
    确实是少了一段代码,gitee下载的代码也没有。是reg_pc_next这部分,其输入不是out_pc_next

    作者回复: 我看看

    2022-08-23归属地:湖北
收起评论
显示
设置
留言
21
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部