您的位置:首页 > 其它

【冬瓜哥手绘】致敬龙芯!冬瓜哥手工设计了一个CPU译码器!

2015-08-25 07:40 225 查看
悠悠天地中,又见他身影翩若惊鸿。冷酷的面孔,温柔绝不会出口中。他的刀厮杀如风,他的痛谁能懂,怎么我心像刀尖颤动。悠悠天地中,只盼再跟他厮守相拥,澟风血影中,宝刀比他的回忆重。他的话言不由衷,把血泪心里送,他把铃铛放在我手中。不在乎天翻地覆,走遍天涯他在何处,不在乎万劫不复,有了希望自会相逢与幸福飞舞。

铃铛在响动,总是唤起了莫名感动。尽在不言中,温柔不需要出口中。他的话言不由衷,把血泪心里送,他把铃铛放在我手中。悠悠天地中,又见他身影翩若惊鸿。冷酷的面孔,温柔绝不会出口中。他的坏误解重重,他的梦我才懂,风中飘着铃铛响动,他又浮现我的心中,浪迹江湖找海阔天空!

龙芯发布了新一代的通用CPU,基于MIPS指令集,主频从1.2G降低到了1G。冬瓜哥是个外行,除了略懂存储系统之外,其他方面小白一个,但是,看到我们国家队也是从零开始,愣是把龙芯给弄出来了,冬瓜哥就在想,有谁天生就是大牛?有谁天生就能做CPU?大家谁不是从头一针一线的缝,学习,积累,最终有了成就的呢?所以,所有人在学习上的起跑点,都是一样的,有人穷,一样满腹经纶,有人土豪,却可能是个毫无内涵的土豹子。有人倾尽一生学习研究,有人吃喝玩乐却天天抱怨学不进去没精力没时间。道理很简单,取得了成就的人,一定是将其所有精力集中到这件事上。总有人感叹这些牛人是怎么做到的,答案也很简单,他把所有时间用来做这件事,你呢,你是刷手机、喝茶、琢磨着去哪吃一顿、吃完了睡,起来再刷手机。

我们的龙芯国家队,不用说,里面的牛人们,他们的兴趣就是以做CPU为乐,其人生的目标就是做出好用的CPU,至于吃喝玩乐,那都是身外之事,吃盒饭也是吃,吃大餐也是吃,这些东西,在他们眼中毫无意义,因为他们不好这个,他们的人生目标是伟大的。

但就是冬瓜哥这样一个小白,看到龙芯的壮举之后,情不自禁,想来个纸上谈兵,体验一把龙芯设计师们的思路,游历一番,忆苦思甜。冬瓜哥要作甚?冬瓜哥要手工打造一个简单的两指令两周期的CPU译码器。该译码器首先对接收到的机器指令判断其是否合法,如果合法则继续走常规路径,如果非法,则跳转到error handler程序所在地址执行。该假想中的CPU有两条有效指令,实际中会有数百条。要想比较收到的指令是否匹配这两条指令中的任何一条的话,可以并行比较,这也是硬加速防火墙匹配ACL时的普遍做法,可参见冬瓜哥之前写的《聊聊CPU/FPGA/CAPI》,里面详细介绍了硬加速的4种手段。这里就使用了其中的“并行”手段。见下图。


IF 是取指令单元,这个电路将指令从内存或者缓存中取出,放到一个锁存器中(图中带黑色箭头的器件)。锁存器将该指令输入到XNOR阵列中进行比较。XNOR,同或门,其只有在两个输入信号相同时(都为1或者都为0),才输出1,不同则输出0,是一个天然的比较器。假设指令长度是4位,则比较每一条指令需要4路同或门。两条指令(图中是1111和0000),每条并行比较,需要放置8路同或门,将指令锁存信号同时引出两路到两套同或门阵列,再将输出导向到与门,与门的特点是只有所有输入都是1(四位信号与被比较的全相同),输出才是1(两个串联的开关)。再将后面两个与门的输出导入到或门,或门的特点是只要有阿萨德一个输入为1,输出就是1(两个并联的开关)。通过判断或门的输出是1还是0,就可以决定下一步该干什么,我们需要将这个信号锁存在一个锁存器中,而不能直接引向下游的逻辑电路,因为这个判断器电路已经达到了FO4,也就是Fanout4,在主频数G赫兹的CPU中,一个时钟信号之内,组合逻辑电路必须稳定输出,否则计算将错乱,如果完不成输出,就必须将电路分割开,一步一步的算,每一步只能并行4级门电路,多个级之间加入锁存器,暂存上一步算出的结果,在下一个时钟周期,锁存器会将上游电路输出的结果锁存起来输出到下游电路,与此同时,上游电路的输出会在该时钟周期内改变,但是不会穿透锁存器,锁存器仅在时钟跳变时候,将输入导向到输出并立即锁定,这种时钟触发的锁存器又被称为触发器。流水线就是靠组合逻辑+触发器一步一步的向前滚动的。触发器由时钟信号统一控制,同一时刻,所有触发器在时钟上沿或者下沿时被触发,结果是所有锁存器都将各自输入导向到输出并立即锁定,这样就行了一排小人儿搬砖头的效果,我把砖头转手给你,你此时正朝向我,传递完之后,我再转头朝向我的上游接收砖头,同时你再转头传递给你的下游。大家步调一致,靠的就是时钟信号。这就是流水线操作的底层支撑机制。

再看下一步,下一步是根据指令是否合法,做出相应判断。如果或门输出的是0,则需要跳转到错误处理程序所在的地址执行,这个地址会被预先载入CPU某内部寄存器内,电路需要做到这样:如果或门输出为0,则将这个指针导入到PC计数器中,让CPU从这里取指令执行,同时,向下游发出一个NOOP操作,这个NOOP操作就是禁止下游的电路改变任何寄存器、锁存器、内存,说白了就是disable写使能信号。上述的电路为例外处理控制,这块由于时序比较复杂,冬瓜哥道行不够,就不在这献丑了,另外,立即数、写内存等也都不考虑。这个译码器不带有例外控制,指令直接被导入正式译码部分,直接将指令翻译成操作寄存器和ALU的信号,注意,有些复杂指令先要翻译成更细粒度的微指令,然后再翻译成最终信号,翻译过程可以直译,也可以查表翻译,这个表就是所谓CPU的微码。


在上图中,PC指针寄存器利用自身反馈,输入到一个加法器,加法器的另一路输入固定,就是指令长度,对于定长指令集来讲比较简单,对于不定长指令集的话,通常按照CPU位宽除以8来做被加数。这样,PC指针寄存器就可以不断的循环触发取指令单元(IF,Instruction Fetch)向对应地址发出读指令将指令取回。接下来第二个时钟周期就是利用一个组合电路判断是否取到的指令合法,如果不合法直接产生例外跳转,图中没有画出,这个例外跳转还需要在PC寄存器前增加一个二选一MUX,也没有画出。第三个时钟周期,进入正式译码阶段,直接翻译成针对寄存器堆(Register File,RF)的读和写地址选择信号以及寄存器堆的写使能信号。假设该CPU机器码定义如下,add A B指令,将B寄存器与A寄存器做加法,结果写入B寄存器,假设该CPU定义add指令为1111,则DC(Decoder)单元收到1111之后,利用组合逻辑译码电路,分别生成RA1(Read Address 1,对应A寄存器)和RA2(ReadAddress 2,对应B寄存器)信号,输入到RF(寄存器堆)当中,被选出的A寄存器数据直接被输出到RD1(ReadData 1)导线上,同理,B寄存器数据则被输入到RD2(Read Data 2)导线上,ALU中的各种运算器直接输出A和B的各种运算结果,然后DC需要产生对应的Select信号输入到一个多输入一输出的MUX上从而将加法的结果选出,同时直接反馈到寄存器堆的WD(Write Data)输入端,WA被设置为B寄存器地址,这样结果就可以被写入到寄存器B。如果后续指令也同时需要操作B寄存器,则需要由RF中的锁存器保证当前的B不会穿透到输出端从而在一个时钟周期内被错误的累加多次,而是需要Forward(前递)给后续指令。

实际中,后面这段超大组合逻辑还是要被分成多步工序的,因为要满足FO4规则,否则频率只能降低以便让更多级数的逻辑门获得充分的响应时间,这里冬瓜哥就不再画出了。利用
d00a
组合逻辑+时序锁存器+时钟+反馈+多路选择器等,就可以形成流水线,提升整体频率,但是代价就是时延增加,一旦发生未被预测命中的跳转则需要很高昂的代价来排空流水线重新来过。

感觉如何?是不是有种茅塞顿开的感觉,原来CPU的译码是这样玩的。同样的道理,各种IO控制器接收到指令之后,也需要解析该指令,但是这种解析,都是软解析,就是代码中不断的把接收到的指令opcode和参数与所有预先定义的指令和参数进行循环比较,直到匹配某一条,然后继续向后产生各种子操作。世界的底层,就是一台可执行的,有输入输出逻辑的,某种实体,一层一层封装,才有了上层世界,上层世界继续封装,就是更宏观的世界,至于为什么会被封装成现在的宇宙模样,就不得而知了。

致谢 :冬瓜哥在该领域的知识体系得到了如下之业界专家的指点,在此由衷表示感谢: 中存超为 沈杰 、中科院计算所 包云岗老师 和 余子濠同学 。

我张开一双翅膀,背驮著一个希望。飞过那陌生的城池,去到我向往的地方。在旷野中,我嗅到芬芳;从泥土里,我摄取营养。为了吐丝蚕儿要吃桑叶,为了播种花儿要开放。 我走过丛林山岗;也走过白雪茫茫。看到了山川的风貌,也听到大地在成长。







本文转载须全文转载,包括二维码和所有图片文字,并注明出自 “ 大话存储 ” 公众号。长按识别二维码关注 “ 大话存储 ” 获取业界最高逼格的存储知识。 看了好的请点赞/转发/红包,平时群里发红包装逼,不如把红包猛烈的砸向冬瓜哥吧!冬瓜哥后续会有更多高逼格的东西出炉。大话存储,只出精品。

长按图片发红包:



支付宝扫码发红包:



长按扫码关注“大话存储”



强赠冬瓜哥真容:



(请注意,冬瓜哥不是西瓜哥,这是两个人,很多人给混淆了,冬瓜哥很早就叫冬瓜了,某菊花司的某人2年前参考鄙人昵称在业界混淆视听,现在以至于很多人认为大话存储为那人所著,后来有内部人士透露给冬瓜哥才知道,其目的一开始就是在冬瓜哥离开某菊之后消除冬瓜哥在某菊和业界的影响力,菊花黑寡妇作风典型代表。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: