cache写回法 verilog实现_用scala写一个基本五级流水线CPU(六)第一次重构

bbd395d270a55f02b1e7b5a8f3ad8f00.png

CPU写到这里,流水线已经基本可以跑起来了,但是目前在写的过程中也渐渐感觉到一些问题,具体是:

  • 流水线缓冲级的写法过于繁琐,虽然之前稍微了修改了一下,使显式连接没那么多,但问题还在
  • 增加指令较为麻烦,如果说是增加普通的I、R型指令,因此之前已经写好模式,直接增加即可。但在增加一些指令,比如MULT,MULTU,就发现了问题。因为这两个指令并不是向寄存器组的寄存器中写入,而是向寄存器HI,LO写入。那怎么办呢,修改前面的范式,让他除了能像寄存器组的寄存器写入,还能写入HI,LO吗?可想而知,最后那个范式会越来越复杂。

重构计划:

  • 目前流水线是由Component的形式组装起来的,但实际上,在spinalHDL,它建议不必要的时候,采用Area而不是另外建立Component,因为建立Component就意味着要重复定义输入输出端口。之前我虽然采用将端口抽象成类的方式,但仍有些累赘。
  • 为什么一开始要采用Component呢,因为这是用Verilog写CPU的正常方法。以Verilog的表现力,如果将所有的东西挤在一个Module中,可想而知最后只能变成一坨屎山。但是
  • 因此,现在考虑使用Area来重构流水线
  • 指令系统参考了VexRiscv的方法,打算用另外一个思路来写。
  • 以前的思路是按照流水线为主的思路,在流水线的每一级,针对不同的指令做不同的操作。
  • VexRiscv的思路是以指令为主,每个指令在每个阶段做什么事,直接Plug到该阶段。当然了,VexRiscv的实现比较复杂,我的scala功底还不够能完全理解他的实现方式,只能说先借鉴一下思想。

2020年7月5日 update:

重构计划1:使用Area来重构流水线 失败

  • 丢弃的分支在此:https://github.com/Ncerzzk/SimpleCPU/tree/AreaInsteadOfModule
  • 具体原因挺多的
    • 使用Area来写整个流水线的话,生成的Verilog非常难以阅读。如果是用Component 来写的话,至少各个模块还能分开,但如果是用Area来写的话,整个CPU所有的东西都挤在一起,如果想通过verilog来看某些语句的效果的话,简直是噩梦。
    • 流水线之间只能通过一些中间信号的来连接,VexRiscv中使用了一些自建的数据结构来维护,如input(signal) output(signal) insert(signal),等等。我也照猫画虎自己实现了一套,但是由于scala水平不够,写得略显臃肿,完全没有VexRiscv中那种轻便的感觉。越写越恶心
    • 为了更高程度的抽象,经常迷失在scala的语法中。虽然随着重构指令系统中,scala的水平又长进了一些,但即使这样,还是不太能驾驭高程度的抽象写法。

重构计划2:重构指令系统

本来想按照VexRiscv,直接将指令的行为plug到流水线中。但由于Area的重构搁浅,因此这方面没有实现。

目前的重构完的指令系统,使用SpinalHDL内置的MaskedLiteral来进行指令的匹配。

指令定义

def 

MaskedLiteral可直接调用===与Bits类型进行匹配。

指令译码行为的抽象

将指令译码的行为抽象出来,译码阶段的行为其实不多,抽象完变成这些:

object 

有些行为的参数直接使用Bool类型的True或者False,有些行为的参数是特定的:

object 

然后将某一类的指令的共有行为抽出来,作为一个普通的Actions列表,如I型指令的共有行为:

def 

当然了,每个指令还有一些独特的东西,比如OP码,和OPsel码,这些每个指令再单独添加:

def 

J型指令由于行为差别都比较大,对每个指令添加的东西比较多:

def 

然后在ID模块中,遍历匹配指令,匹配到之后,根据指令的行为列表,操作具体端口:

def 

这样一来,译码模块就显得清爽很多了:

val 

到目前为止的源码:

https://github.com/Ncerzzk/SimpleCPU/tree/c8142ba1f5ed55081fd439eaad77b876317bfa05​github.com

到目前为止的源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值