引言

本次课内容:

  • 第六期 “一生一芯”
  • “芯片设计”包含什么?
  • 为什么学 “一生一芯”?
  • 怎么学 “一生一芯”?

第六期 “一生一芯”

自我介绍

老博士, 但参与教学的时间比读研究生还长(一些) 😂

  • 大二蹭了jyy老师的OS实验课, 学会了RTFM/RTFSC
  • 大三大四带了两年的OS实验课
  • 本科毕业的暑假, 袁春风老师推动《计算机系统基础》的教学改革
    • 给这门课设计大实验, 于是有了PA和NEMU
  • 2017年, jyy提出AM, 第一版Project-N系列实验正式诞生
    • 作为co-founder之一参与维护
  • 2019年, 包老师发起第一期 “一生一芯”
    • 作为技术指导带学生, Project-N作为基础设施发挥重要作用

 

博士方向研究指令集模拟器和二进制翻译

  • 卷不过各位大佬, 所以跑来折磨大家了 😈

“一生一芯”资源

  • “一生一芯”主页 - ysyx.org
    • 包含 “一生一芯”的所有内容, 若有任何疑问, 请到主页上查找

 

  • 教学资源 - ysyx.org/docs/
    • 包含课件, 讲义, 直播和录播链接等

 

课程主页和直播

  • 请大家不定期关注课程主页中发布的消息
    • 例如节假日🕊不🕊

 

B站直播时间: 每周六15:00~17:00

  • 约26周, 每周2小时
  • 可能会🕊1~x天
  • 会上传录播, 尽量保证不翻车

 

  • 当然不要指望有手把手的教学
    • 不过就算不来上课, 只要独立完成学习, 就能变强

第六期教学特色

  1. B阶段可流片 - 以认识处理器芯片为目标
    • 流片指标略高于第三期
    • 用RV32E以节省流片成本
      • 后面的教学演示也尽量切换到RV32
    • 最终在RT-Thread上运行一些小游戏
      • 我们将RT-Thread移植到AM上了!
        • 实现要求比第三期更简单, 例如不需要中断
    • 可在给定的面积预算内优化处理器设计
  2. A阶段流片指标提升 - 以构建完整计算机系统和性能优化为目标
    • 高于第四/五期流片指标
    • 中期从RV32E转到RV64IMAC
    • 最终运行Linux发行版OpenEuler, Debian, Fedora等
    • 有IPC和主频要求

第六期教学特色(2)

  1. 新增开源EDA
    • 开源EDA团队设计了多个点工具
    • 大家是开源EDA工具的首批用户
      • 7月: 综合(yosys) + 时序分析工具 => 快速评估设计的时序要求
      • 10月: 发布其他点工具, 可线下学习后端流程
      • 12月: 芯片设计云平台上线, 基于开源EDA工具进行可流片设计

环境, 开发语言和工具依赖

  • 软件配置 - Linux环境
    • 软件开发(模拟器, 系统软件, 应用程序)
      • C语言, 很少量的C++(类的基本使用) - gcc编译器
    • 硬件开发
      • Verilog或Chisel - 开源verilator仿真器 + 开源gtkwave波形查看器
    • 后端物理设计 – 商业EDA, 主要由工程师或线下实习生完成
      • 即将把开源EDA融入教学流程
  • 硬件配置 - 笔记本电脑就能做, 无需FPGA
    • FPGA与ASIC流片原理不同, ASIC EDA工具评估的结果更准确
      • 第六期加入yosys综合器
    • FPGA主要用于仿真加速, 一般用于复杂设计(如香山)
      • 对于简单设计和短时间仿真, 软件仿真+yosys综合通常可满足要求

从计算机发展史看处理器芯片设计

80年代的处理器 - Intel 8086(1978)

  • 16位寄存器和16位数据总线
  • 20位地址总线, 可寻址1MB内存
  • 主频5~10MHz

1981年, IBM PC机发售, 搭载Intel 8088处理器(8位数据总线版本的8086)以及微软的MS-DOS操作系统

Intel 8086指令集

约256条指令, 指令长度1~6字节(指令集手册)

Intel 8086微结构

通过指令队列实现总线接口单元和执行单元的并发工作(流水)

  • 今天的x86处理器也保留了类似的设计

Intel 8086微结构

并发工作的时序图(8086参考手册)

80年代的操作系统和应用程序 - MS-DOS

80年代的操作系统和程序 - Windows 1.x(1985)

初代Microsoft Windows(2021年的一篇纪念博客)

  • 基于MS-DOS内核, 本质是一个MS-DOS的Shell可执行程序
  • Windows自带应用初代: 计算器, 画图(只支持黑白), 记事本, 写字板
    • Windows自带的第一个游戏是黑白棋
  • 支持协同多任务(后台程序需要挂起)
    • 程序有bug可能会导致系统崩溃
    • 而且窗口不能重叠 😂
  • 支持鼠标, 可点击和拖拽
    • 但直到windows 3.x才支持双击运行和Ctrl+C/Ctrl+V

 

可以在浏览器中借助IBM PC全系统模拟器体验

90年代的处理器 - Intel Pentium(奔腾)(1993)

  • 主频60MHz~300MHz
  • 新架构P5, IPC比上一代架构80486提升将近一倍
    • 首次引入超标量架构: 双发射5级流水
    • 优化FPU, 浮点乘法的效率甚至是80486的15倍
    • 地址生成器采用4输入加法器, 一周期算出有效地址
      • 段基地+基址寄存器+变址寄存器+偏移量
      • 80486采用3输入加法器, 需要花费两个周期计算
    • 优化微码和乘法器, 提升常用指令(call, ret, mul等)的IPC
    • 添加分支预测器
    • 2路组相联独立缓存(分指令缓存和数据缓存), 减少冲突
    • 64位数据总线, 提升访存带宽

Intel Pentium(奔腾)微结构

1996年加入了MMX多媒体指令集, 流水线增加为6级(硬件手册)

  • SIMD: 单指令多数据

Intel Pentium(奔腾)微结构

双发射流水线时空图

90年代的处理器 - Intel Pentium Pro(奔腾Pro)(1995)

  • 主频150MHz~200MHz
  • 新架构P6(硬件手册)
    • 14级乱序超标量, 支持寄存器重命名
    • 3个译码单元, 将x86指令翻译成RISC风格的uop, 最多翻译出6条uop/周期
    • 可向6个执行单元发射5条uop/周期
    • 片外同封装的256KB L2缓存(1997年升级到1MB), 与CPU同频
      • 可同时访问L2和内存, 减少延迟
      • 非阻塞缓存, 可同时处理4个请求

 

Pentium Pro取得了巨大的商业成功, P6架构及其变种延续了十多年

90年代的操作系统 - Windows 95(1995)

  • 支持本地32位程序
  • 支持设备热插拔
  • 文件系统支持长文件名
  • 添加开始菜单, 任务栏, 文件管理器
  • 第一代IE浏览器, 空当接龙
  • 蓝屏也走进了千家万户

90年代的程序 - 仙剑奇侠传(1995)

经典RPG游戏

  • 在第六期的A阶段中, 你将会在自己设计的处理器上运行仙剑

今天的计算机(工艺)

单核性能挤牙膏, 主频和功耗上不去

  • 摩尔定律还在继续 -> 暗硅(受限于功耗而需要关闭的晶体管)
  • 多核通常跑不了满频

今天的计算机(微结构)

处理器空前复杂

  • 每个新功能都要与很多旧功能交互
  • 各种漏洞: 2018年的熔断和幽灵
    • Intel一开始发布的补丁会导致死机, 被Linus喷是垃圾 😂
    • Intel资深工程师也没法一下子想明白处理器的所有细节

今天的计算机(操作系统)

Linux 4.17(2018年4月发布)删除了过时处理器的代码

  • 减少了50万行代码
  • 但还有2030万行 😂

今天的计算机(操作系统)

Linux内核包含海量的模块, 交互关系非常复杂

A New Golden Age for Computer Architecture

译文: 计算机架构的新黄金时代

  • 介绍了芯片的发展历程, 以及计算机体系结构的未来发展趋势
  • 作者是2017年的两位图灵奖得主
    • David Patterson & John Hennessy

启发

有很多新名词?

  • 不用担心, 学习完 “一生一芯”之后, 你将有能力理解它们

 

更重要的两个观念:

  1. 硬件需要软件的支持才能发挥作用
  • 狭义的处理器芯片设计: RTL开发
  • 广义的处理器芯片设计: 计算机系统软硬件协同设计
    • “一生一芯”讨论的范畴
  1. 复杂系统是迭代演进的(多周期->流水线->超标量->乱序执行)

为什么学 “一生一芯”?

处理器芯片设计

always @(posedge clk) begin
  case (raddr[1:0])
    2’b00: rdata <= reg0[31:0];
    2’b01: rdata <= reg1[31:0];
    2’b10: rdata <= reg2[31:0];
    2’b11: rdata <= reg3[31:0];
  endcase
end

电路设计的本质: 实例化和连线

  • 这些面包板也能做, 但为什么后来设计流程逐渐转成RTL开发?
    • 开发效率, 调试效率…

 

  • 现在的真实处理器动辄千万门, 高性能处理器更复杂
    • 作为一个项目, 如何提升开发效率和调试效率, 是至关重要的

你也许设计过处理器, 但不一定能回答以下问题

  1. 上一页的RTL代码用于供CPU访问若干设备寄存器, 它有问题吗?
  2. 如何编写一个打印Hello的C程序放到你的CPU上运行?
    • 第三期 “一生一芯”答辩, 80%的学生不知道
  3. 你写的流水线CPU具体在哪里地方比单周期CPU快多少?
  4. CPU仿真过了100000000周期后出错, 如何快速调试?

 

以上问题说明: 处理器芯片设计包含很多软件问题

  • 两个本质原因
    • 处理器芯片和其他芯片不同, 离开软件就无法工作
    • 代码即软件 - RTL代码也是, 即使它描述的是硬件
      • 需要使用合适的软件技术管理/维护/测试/评估/优化代码

学习 “一生一芯”的目的(1) - 重新认识芯片设计

  • 处理器芯片设计有哪些评价标准?
    • 正确 - 这是最基本的
    • 软件支持 - 只能跑排序程序/能启动Linux
    • 微结构复杂度 - 单周期, 流水线, cache, 分支预测…
    • PPA
      • 性能(Performance) - IPC, 主频
      • 功耗(Power) - “一生一芯”暂时不关注
      • 面积(Area) - 不能超过流片面积预算
    • 可配置性
    • 代码可读性/可维护性

 

  • 如何科学兼顾多个维度(正确性只是其中之一), 尽可能把处理器做好?
    • “一生一芯”的学习路线, 来源于对这个问题的回答

学习 “一生一芯”的目的(2) - 培养大家成为专业人士

“一生一芯”将用全新的方法和流程, 按计算机发展史的顺序设计处理器

  • 树立全面的软硬件全系统认识
  • 理解科学的安排规划和优化方法
  • 掌握正确的工具技能高效解决实际的工程问题

 

通过我们设置的训练让你变强

  • 全方位, 全身心, 肉眼可见地变强
  • 锻炼专业人士所需的专业素质

熟练工 vs. 专业人士

老板分配任务 熟练工 专业人士
跑RT-Thread 软件跟我没关系 出了bug我能调对
尝试新工具 我没接触过 我来看手册
改进工具 工具会用不就行吗 我来分析瓶颈
实现新需求 我需要详细设计文档 我规划一下

 

熟练工: 可以很好地完成指定任务, 保证项目流程往前推进

专业人士: 具备独立解决未知问题的专业素质

  • 专业技能: 正确理解专业知识点, 并具备全局系统观
  • 专业方法: 知道如何找到相关的代码/资料/工具
  • 专业世界观: 明白做什么事情是正确/高效/科学的, 如何分解复杂任务

专业训练

基本原理 做事方案 正确性风险 代表例子
阐述 明确 基本正确 高中物理实验
阐述 明确 可能出错 程序设计作业, 培训班
阐述 需要思考 基本正确 数学/算法题
阐述 需要思考 可能出错 PA, “一生一芯”
需要探索 需要思考 可能出错 业界和科研的真实问题

把知识包装成 “新问题”呈现给大家

  • 通过试错深入理解问题:
    • 我想要x, 那么就需要做y, 这是因为z
    • 而做u是不行的, 它会因为v而导致w
  • 解决上百个 “新问题”, 锻炼出专业世界观

我当年做的处理器设计实验(2012年)

实验课老师没有正经的处理器设计经验

  • 过分强调信号层次的电路图, 做实验就是看图写代码
    • 谭浩强: 写C代码之前要画流程图
  • 忽悠学生设计自定义指令集, 连微结构是什么都不理解
  • 把指令数量作为处理器复杂度唯一指标, 不知道中断异常如何处理
  • 没有任何后端概念, 对HDL代码如何映射到工艺原语完全没有认识
  • 调试全靠波形和瞪眼调试法, 说是锻炼耐心
  • 没有任何软件和工具链的意识
    • 连Hello程序都跑不起来, 更别说像样的程序

 

据说这个实验曾经是计算机系最难的实验 😂

做这样的实验, 怎么解决国家卡脖子危机?

“一生一芯”(或者好课)的真正意义

树立正确的专业世界观, 吸收过去数十年构建的知识体系, 接触领域前沿的真正研究

这期的S阶段又要🕊了, 但不管怎样:

如果你的回答是肯定的, 那就来参加 “一生一芯”

怎么学 “一生一芯”?

真正的处理器是一个复杂的系统

  • 教科书上的处理器
    • 6条指令(MIPS)
  • 课程大作业的处理器
    • ~40条指令
  • “一生一芯”中的处理器
    • 果壳 = ~100条指令+流水线+中断异常+cache+MMU+AXI总线
  • 科研原型系统的高性能处理器
  • 量产的工业级高性能处理器
    • M1 = ARMv8指令集+8译码+17个FU+~630项ROB+黑科技+…

仅仅会看波形是不够的

如果在你设计的处理器上

  • 跑超级玛丽, 100,000周期后assert失败
  • 跑仙剑, 10,000,000周期后图形不正确
  • 启动Linux Debian跑gcc, 1,000,000,000周期后段错误

 

你愿意从1,000,000,000个周期的波形中寻找错误的信号吗?

  • 就算你愿意, 波形文件也已经大得磁盘存不下了 😂

 

教科书/大作业并不会教你如何应对这些问题

  • 做小玩具, 方法再怎么简陋, 也能做出来

复杂系统需要用科学的方法来构建和维护

  1. 了解软硬件全系统的每一处细节, 为调bug提供大方向
  2. 先完成后完美, 体会每一项技术对系统带来的性能提升
  3. 构建正确的工具, 提升开发和验证效率

 

2012年一篇总结七大互联网公司经验教训的博文

(对应2) Keep it simple - complexity will come naturally over time.
(对应3) Automate everything, including failure recovery.
(对应2) Iterate your solutions - be prepared to throw away a working component when
  you want to scale it up to the next level.
(对应3) Use the right tool for the job, but don't be afraid to roll your own
  solution.
(对应1) Use caching, where appropriate.
(对应1) Know when to favor data consistency over data availability, and vice versa.

 

这些做事的观念和方法, 就是工业界所需要的

  • 就算以后你不从事芯片方向的工作, 也可以从中受益

“一生一芯”对绝大部分同学来说并不轻松

不仅需要学习很多新知识, 在新环境中使用新工具

还需要锻炼出独立解决问题的意识和能力

 

更重要的是, 完成观念和心态上的转变

  • “一生一芯”不是传统意义上的课程大作业
    • 课堂和讲义不会告诉你所有细节
    • 你需要主动从相关资料/代码中找到重要的信息
  • 你遇到的所有问题(除了框架代码自身错误), 都是在锻炼你的能力
    • 老师助教不会手把手帮你解决所有问题
    • 独立解决这些问题, 是对你最大的训练

 

如果你只是想轻松愉快地写RTL, 网上已经有很多教程和MOOC

能否完成 “一生一芯”与学校/年级/专业无直接关系

取决于你是否已转变观念和心态, 锻炼出独立解决问题的意识和能力

王晨宇@南通大学, 学习时大二(转专业), 获得第四期流片资格

烟雨松@北京101中学, 学习时高三, 预计2023年9月获得流片资格

 

另一个角度: 大家都有潜力完成 “一生一芯”的学习

  • 拿 “自己是xxx专业/零基础”来当借口是没有用的
    • 这除了让你降低对自己的要求之外, 没有实际的帮助
    • 还不如想想是不是自己哪里没做好, 导致接受的训练没到位

专业世界观1 - 学术诚信

MIT对学术诚信的诠释, 尤其是关于写代码的学术诚信

  • 独立完成学习任务
  • 在允许的范围内参考相关资料
  • 不参考别人的代码, 不分享自己的代码

意义: 让你接受预期的训练, 锻炼出预期的能力

这是需要大家发自内心去认可和执行的: 我们很难约束大家

 

“凭什么不能参考别人的代码? 我都看懂了啊!”/“能抄对也是本事”

  • “看懂”和 “自己独立完成”的效果是天差地别的
    • 你表面上看到了做y能得到x, 但不知道原因z, 更不知道试错的uvw
    • 你收获了肤浅的理解, 让你重做一遍, 很可能还是搞不定

专业世界观2 - 独立尝试

STFW - Search The Friendly Web

  • 只要我用的工具是大众的, 我几乎不可能是世界上第一个遇到问题的
  • 网上一定有人遇到过相同/类似问题, 我应该搜一下看看他们怎么解决

RTFM - Read The Friendly Manual

  • 只要我用的工具是大众的, 应该有手册记录这个工具的所有细节
  • 如果我想了解它的某个问题, 我应该去搜索手册的描述

RTFSC - Read The Friendly Source Code

  • 只要我获得了项目代码, 理论上我就可以知晓它的一切行为
  • 如果我想了解它具体是如何工作的, 我应该去读一下(关键)代码

 

如果你在提问时收到了这些回复, 其背后的含义是:

  1. 你想要的答案很容易找到, 你很应该自己去获取
  2. 相比于我直接告诉你答案, 你自己获取答案能学到更多

STFW/RTFM/RTFSC背后的理论 - 知识局部性

  • 时间局部性 - 你遇到一个知识点时, 最近很可能还会遇到它
  • 空间局部性 - 你学习一个知识点时, 也会了解到附近的知识点

 

但更重要的是它们的逆否命题在调bug中的应用

  • 时间局部性 - 当你不了解一个知识点时, 说明你最近没有学习它
    • 没有STFW/RTFM/RTFSC
  • 空间局部性 - 当你不了解一个知识点时, 说明你也没有学习与它相关的内容

 

正确理解 “相比于我直接告诉你答案, 你自己获取答案能学到更多

  • add指令的格式是什么? -> 很可能连sub指令的格式也不知道
    • 别人通常无法把相关知识点全部告诉你
    • RTFM可以解决更多的疑问

专业世界观3 - 科学提问

提问的智慧》/《别像弱智一样提问

  • 提问能反映出你的学习态度: 主动尝试 vs. 被动依赖

不是所有问题都值得问

  • 你以为自己热爱学习? 不, 别人只觉得你是伸手党

开源社区中的一个真实案例:

  • 新手的提问: 两个不同的安装包有什么区别? 我是新手.
  • 开发者的回答: 自己上网找答案. 在开源社区中不应该随便问这种配置问题, 除非你有明确的证据证明代码或者文档有缺陷.

鼓励的提问 vs. 不应该的提问

  • 鼓励的提问
    • 心理辅导, 学习困惑等非具体技术问题
      • 可以私戳老师助教, 时间充裕的话还可以线上聊聊
    • bug report: 要有证据, 当一名专业的社区contributor
    • 经过思考的高质量问题
    • 属于训练环节, 但经历过合理尝试还无法解决的问题: 提问模板
  • 不应该的提问 (背后含义: 你应该接受训练)
    • 没有看出合理尝试和思考的提问
      • 可以不知道怎么尝试和思考, 但不代表可以跳过训练获得答案
      • 接受训练: 方法 -> 看讲义总结归纳, 细节 -> RTFM/RTFSC
    • 自己动手试试就能得到答案的提问

 

一篇参考文章: 什么样的问题我不太想回答?

虚假的帮助 vs. 真实的帮助

虚假的帮助: 面向结果, 解决当下问题优先

真实的帮助: 面向能力, 领悟学习方法优先

本质区别: 如果将来不再提供帮助, 学生能否独立解决类似的问题?

真实案例: 学生A询问某报错信息

  • 分析: 根据提问内容, 学生A只进行了很少的尝试, 没有其他想法
  • 虚假的帮助: 学生B指出可能是klib模块有bug, 提示学生A去看看
    • 学生A的收获是 “报错信息->klib模块有bug”的表面因果关系, 难以深入理解和记忆, 并未学会真正思路和方法, 同时也错过一次锻炼机会
  • 真实的帮助: 引导学生A学会对bug进行深入的分析和定位
    • 这比虚假的帮助困难得多, 大部分学生并不知道如何引导

任何直接获得答案的做法都是在放弃训练的机会

  • 遇到一个总线的bug, 希望同学提供点思路
    • 正确做法: RTFM(AXI手册), 确认自己正确理解细节; RTFSC, 梳理这个bug是如何出现的
  • 不知道CSR应该放在哪里, 希望助教告知一个好的设计方案
    • 正确做法: 自己尝试不同的方案, 然后总结它们的优劣
  • 希望助教/大佬能整理一本攻略手册
    • 正确做法: 自己整理(作为学习成果), 但不要分享出去
      • 这些攻略并不能真正帮助你学习, 而是在剥夺你接受训练的机会
  • 阅读开源项目(如果壳, 香山等)
    • 正确做法: 先尽力完成一个满意的设计, 再对比开源项目
      • 缺少试错, 你无法理解 “为什么好, 为什么不好”

 

躺平容易坚持难, 但如果你能坚持下来, 你就可以得到脱胎换骨的提升

我们也知道大家不爱听这些大道理

这些做法和大家在课堂上接受的观念差别很大, 甚至是矛盾的

  • 我不是学计算机的, 这些跟我没关系
  • 我不懂还不能问吗

 

大家也处于血气方刚的年纪, 有自己的想法

  • 让我STFW/RTFM, 明摆着是敷衍我
  • 我借鉴开源代码是顺应时代的潮流

 

为躺平找理由也很容易

  • 我喜欢和大家共同学习
  • 我看英文手册很慢, 想找个大佬给我讲讲
  • 反正助教老师也管不着

所以

我们来玩真的: 在线调试考核, 通过才能获得流片机会

  • 助教在你提交的项目中随机注入3个bug 😈
    • 涵盖硬件, 软件和环境
  • 你需要在指定时间内(约45分钟)排除bug 😈
    • 强迫大家理解所有细节, 吸收科学的调试方法
      • 参考代码, 抱大腿, “看波形就够”都没戏 😈
    • 抓紧每一次调试锻炼的机会
      • 突击是没用的, 考的就是真本事 😈
      • 抱一次大腿 = 少一次训练

 

这和大家将来遇到的实际问题非常接近

  • 如果你能解决实际问题, 你就是专家

总结

总结

“一生一芯”不仅仅是训练大家编写RTL

  • 而是用全新的方法和流程, 按计算机发展史的顺序设计处理器
    • 树立全面的软硬件全系统认识
    • 理解科学的安排规划和优化方法
    • 掌握正确的工具技能解决实际的工程问题

 

大部分同学并不会感到舒适

  • 但如果能坚持下来, 你就可以得到脱胎换骨的提升