用scala写一个基本五级流水线CPU

用scala写一个基本五级流水线CPU

ctime:2020-06-26 20:09:48 +0900|1593169788

标签(空格分隔): 技术 硬件


最近学SpinaHDL,一直想写个什么东西练练手。刚好以前一直想写个CPU,之前也在重新学计算机组成原理,刚好就用来作为练习。
其实想写CPU的想法已经很久了,基本上每一次重新学FPGA或者verilog的时候,都会有这么一个想法,但是每次都是因为各种原因不了了之。

有一些是个人兴趣原因,比如又发现了其他更好玩的东西,也有时候是因为被verilog的繁琐劝退。这次用scala来写,后者的问题应该不会发生了。当然,
之前还有一些时候放弃是因为迷失在CPU纷繁复杂的结构中不能自拔,因为每次定下各种模块的定义都不能很好地满足需求,每次增加一点功能都要来回修改,最终
连一个流水线都没连通,就放弃了。

这次设计的CPU,打算先写一个指令 ori ,先将流水线跑起来,再逐步增加新指令。这个思路来自于《自己动手写CPU》,流水线的各种结构都会大致与
书中描述的一样,只是实现方式由verilog,改成scala而已。

因为scala学得也还不深,因此可能代码主要还是用OOP的思路来写,有一些地方可以继续优化。但是代码中也保持DRY原则(Don’t repeat yourself),同一个接口不定义两次(比如很多模块要相互连接,那么需要定义互相连接的接口)等等。

目前实现的指令是ORI,将某个寄存器值与立即数或操作,写入另一个寄存器中

一些基本定义

  • 五级流水线
  • 数据总线宽度 32bit
  • 寄存器数量 32个

总体框图

此处输入图片的描述

流水线两级中间的缓冲实现

每两级流水线之间,会有一组缓冲寄存器。在书《自己动手写CPU》中,是对所有的缓冲寄存器一个一个实现,受限于verilog贫瘠的表达能力。

但我们现在使用的scala,怎么可能再这样做呢。

class Stage[T <: Bundle](gen: => T) extends Component{
  val left:T= gen.flip()
  val right = createOutPort(left)
  def createOutPort(inBundle:Bundle)= {
    new Bundle {
      for(i <- inBundle.elements){
        val a =out (Reg(i._2.clone()))
        a match{
          case s:Bits => s.init(0)
          case b:Bool => b.init(False)
        }
        valCallbackRec(a,i._1)
        a := i._2
      }
    }
  }
}

调用方式是:

  val if2id = new Stage(new IFOut())
  val id2ex = new Stage(new IDOut())
</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值