前言
现在重新命名我的处理器核叫做zen-core,禅芯,以后写核就叫做修禅芯,也算是谐音吧hhhh,主要是总是叫做npc实在是太没有特点了
我首先根据我之前探索出的框架重新创了一个repo,然后打算全部重构一遍,用之前的框架,我可以单独例化一个模块,比如说ALU,然后完全根据这个模块做优化,包括时序面积分析等等,也就是说,elaborate的粒度从design级别到module级别了,然后可以根据这个模块单独写独立于其他的专用配置文件,然后根据专用配置文件(.json)elaborate一个模块,详情见我之前的那篇文章,以及chisel-nix的写法
然后开这篇文章是为了记录我重构模块以及顺便优化面积的一系列经历
ALU
首先根据之前的alu写了现在的alu(完全没变)
面积是1858.542000,时序是880多mhz
究竟采用什么样的优化思路呢,我想了很久,however,我觉得无论如何,第一步首先是了解你的设计,意思是你的头脑中要有一个你的设计大致的电路框图,其实也不一定需要门级的描述,可以稍微更高一点的抽象,也就是微操作不一定需要门级,可以更高级,产生这个想法是我正好想到了firrtl,我觉得这个中间表示是一个很好的分析切入点
这是一小段alu的firrtl代码,是chisel所有meta-programming展开后的结果,但是会发现他的语义似乎还挺简单的(甚至分析难度比verilog还要低),他将所有的微操作都很漂亮的列举出来了,说实话,我现在希望有一个工具可以可视化这一段firrtl,(如果你想要一个工具,那么很可能就存在这个工具)哇,但是我找了一圈都没找到,大多都过时了
但是这个是真的好分析,我仅仅改掉了一个符号,面积直接到1704.528000
其实在优化之前我需要保证他是对的,所以就需要写tb或者formal验证来验证设计,我打算使用chisel nix的formal写法,但是发现Symbiyosys不支持很多产生的sv语法,难受死了
太难受了,弄了大半天vc formal,倒是可以检测出错误了,但是我始终不知道反例的波形在哪?特别难受,感觉工具太少了,哎…心态有点爆炸,找到了一个fvtrace的命令,但是运行时直接给我卡住了
优化了一波,时序直接从885.670到了1208.797,主要的优化手段就是把加法减法的结果给比较,通过合理编码aluop减少mux的压力,平衡mux(如果把mux看成一颗树,时序作为参数,就是平衡树两边的时序),忽然发现formal测试过不去,但是修改之后时序和面积反而再都优化了一点,(顺便复习一下取反+1,取反,让一个值变成了最大值-这个值,就像陷入一样,但是是以多加一位的视角看是陷入,然后如果加的值大于这个被减数,就会溢出到上一位,就是说3-1会溢出,1-3反而不会溢出)
一些架构上的优化
之后需要优化的模块,似乎都和架构考量有关了,所以我感觉我需要先弄清楚我的架构改怎么优化才能达到最佳,在此之前,我打算把之前的架构弄懂(因为太久没写了。。。)
以前的架构
我之前的架构就是经典的IFU,IDU,EXU,LSU,WBU,然后通过握手信号connect,然后只要io.valid===1,说明这个模块正在忙,IFU的输入是上一个周期的自己输出的pc+4信号(always not taken),然后IFU的输出会连到icache上,icache是一个一周期返回数据的cache,并负责axi通信
然后首先是数据冒险,我的实现特别的丑陋….,是通过将idu,exu,lsu,wbu的数据从模块中拉出来,观察各个模块需要写入的寄存器编号和idu需要读出的寄存器编号进行比较,并通过一些控制信号来判断是否能转发,并且通过mux选出需要转发的数据
之后是控制冒险,真正的pc需要在exu的时候计算出来,我就在把exu的这个信号拉出来,并通过简单的对比是否不等于pc+4来判断是否存在冒险,这个路径是关键路径之一,并且s只判断了pc+4,没有扩展能力,肯定需要重构的
还有一点就是控制信号等太多了,需要尽可能减少在流水线中传播的信号以优化面积
优化的架构
啊,真是一个头疼的问题….
首先我觉得我的ifu应该不会有大改动,假如我面积不够,我肯定没办法实现BPU之类的东西
所以我打算首先写我的IFU
既然要先IFU,那就得先icache,既然涉及到了icache,就不可避免的涉及到了bus,看了nutshell的代码,发现整个核都是用一个叫做simplebus的总线协议交流的,我发现这个其实很合理,如果core直接用axi来与外界通信,就会存在一个问题,对于不同的soc协议,并不是很好适应,并且axi对于核来说太重了,所以我想顺便修改一下bus
移植了一下nutshell的simplebus和一个toaxi的模块,让我评估一下toaxi的模块的面积,看是否在接受范围之内,其实我就只需要在core的最后加这个模块即可,210!,非常不错的面积开销,2702.301MHZ,也非常不错,而且正确性可以有很大的保证,毕竟是从nutshell中迁移过来的,ok,现在我完全不需要考虑axi了,全部用simplebus即可
idu肯定需要大改,暂时想到几个问题,先列举如下,1,输出的东西太多了,这些东西都要进流水线间寄存器,要爆炸的,所以肯定需要通过一些奇思妙想,把最本质的东西传出去,2,处理数据冒险太粗糙了,是否需要将idu拆开,拆出一个isu来专门维护一个scoreboard来做这件事,但是是否真的需要这么做,还需要考虑面积,但是我肯定会先试试的。3,我的一个奇思妙想,是否将译码中ISA specific的东西拆出去,不管是什么ISA,都提取出最本质的东西,而这些最本质的东西都是相同的,因为我的处理器是相同的,从而实现仅替换译码部分实现处理器的替换