mipsgreen的个人空间 https://blog.eetop.cn/806108 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

VexRiscv 2/3级流水线配置

热度 11已有 2985 次阅读| 2020-12-5 17:47 |系统分类:芯片设计| riscv, spinalhdl, scala, pipeline

VexRiscv设计支持5级可配置流水线构架,5级流水线的结构为IF=>DEC=>EXE=>MEM=>WB
其中IF, MEM, WB为可选配置, 因此,实现2级或者3级流水线的结构为:
    两级: DEC => EXE
    三级: IF => DEC => EXE  (传统结构)
VexRiscv的流水线配置分散到Plugin和Configuration中实现, 其中MEM/WB可以通过Configuration配置,
IF可以通过IBUS总线的InjectorStage属性配置。
由于其他pipeline plugin插件基本上也是基于pipeline设计, 因为对pipeline有一定的依赖性。在我们禁止
掉某一级pipeline,某些plugin也需要做响应的调整,否则将会导致VexRiscv编译失败。

下面详细列出为实现2/3级流水线设计,plugin需要做的配置调整。

流水线配置
    • 通过VexRiscv的配置禁止MEM/WB

//CPU configuration
val cpuConfig = VexRiscvConfig(
        withMemoryStage = false,
        withWriteBackStage = false,
        plugins = List(
        new IBusSimplePlugin(
        resetVector = 0x80000000l,
withMemoryStage:  配置MEM流水级
withWriteBackStage: 配置WB流水级

    • 通过IBUS的配置禁用IF

plugins = List(
new IBusSimplePlugin(
        resetVector = 0x80000000l,
        cmdForkOnSecondStage = true, //if(args.contains("--tripp")) true else false,
        cmdForkPersistence = true, //if(args.contains("--tripp")) true else false,  //
        prediction = NONE,
        catchAccessFault = false,
        compressedGen = true,
        injectorStage = if(args.contains("--tripp")) true else false
),
cmdForkOnSecondStage:  跳转地址更新配置,设置true, 多一个更新周期,但会获得更好的pipeline时序
cmdForkPersistence: 总线访问信号保持,需要增加寄存器,但有更好的总线协议兼容性;
prediction: 我们采用2/3级流水,目的是获得最小的设计,预测功能此处禁用。
compressGen: 支持RVC压缩指令,为了和cortex-m0+对比,我们这里打开16位压缩指令的支持(对比Thumb2指令)
injectorStage: 这里可以关闭 IF 流水线级,两级结构的实现这里设置 false以禁用IF

    • Plugin属性调整

new DBusSimplePlugin(
        catchAddressMisaligned = false,
        catchAccessFault = false
),
我们采用简单的DBUS实现, 后面会重新配置输出DBUS的AhbLite接口转换实现
此处没有需要特别针对流水线的配置
new DecoderSimplePlugin(
        catchIllegalInstruction = true
),
简单的指令解码实现, RVC到RV的转换在IBUS中实现。
此处也没有针对流水线的配置
new RegFilePlugin(
        regFileReadyKind = plugin.SYNC,
        readInExecute = if(args.contains("--tripp")) false else true, // for Two-stage (DEC/EXE) support
        zeroBoot = true,
        x0Init = false
),
regFileReadKind :  我们采用的是同步读时序,这样对SRAM有更好的兼容性,也能获得更好的时序,但会一定的面积成本;
如果采用ASYNC模式,需要根据物理实现做调整,在VexRiscv.git的RegFilePlugin描述部分有 相关说明;
readInExecute: 默认SRC寄存器在DEC级读取,但可以根据时序情况调整到EXE级读。实测是在2级流水线实现时,
这里需要配置为true, 否则无法通过编译;
new SrcPlugin(
        separatedAddSub = false,
        executeInsertion = true
),
exectueInsertion:  这里的情况和RegFilePlugin.readInExecute类似,需要保持一致
new FullBarrelShifterPlugin (
        earlyInjection = true   // cause we have no MEM stage
),
默认FullBarrelShifterPlugin的结果是插到MEM级,我们禁用了MEM,要使用earlyInjection
配置讲结果插入到EXE级
//new MulPlugin,
new MulSimplePlugin,
new DivPlugin,
new HazardSimplePlugin(
        bypassExecute           = true,
        bypassMemory            = true,
        bypassWriteBack         = true,
        bypassWriteBackBuffer   = true,
        pessimisticUseSrc       = false,
        pessimisticWriteRegFile = false,
        pessimisticAddressMatch = false
),
MulPlugin的实现依赖EXE/MEM/WB流水级,结果插入到WB级。
我们禁用了MEM/WB,因此不能使用MulPlugin, 这里采用一个简单的乘法器实现替代
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset")), 2),
new BranchPlugin(
        earlyBranch = true, // move branch out of MEM stage to EXE stage
        catchAddressMisaligned = false
),
DebugPlugin这里我们加入2个硬件断点支持;(用于对比Sifive E2x/E3x系列)
BranchPlugin为了优化时序, 是在MEM级执行,这里我们使用earlyBranch将执行提前到EXE级
new CsrPlugin(
config = CsrPluginConfig(
        catchIllegalAccess = false,
        mvendorid      = null,
        marchid        = null,
        mimpid         = null,
        mhartid        = null,
        misaExtensionsInit = 66,
        misaAccess     = CsrAccess.NONE,
        mtvecAccess    = CsrAccess.NONE,
        mtvecInit      = 0x00000020l,
        mepcAccess     = CsrAccess.READ_WRITE,
        mscratchGen    = false,
        mcauseAccess   = CsrAccess.READ_ONLY,
        mbadaddrAccess = CsrAccess.READ_ONLY,
        mcycleAccess   = CsrAccess.NONE,
        minstretAccess = CsrAccess.NONE,
        ecallGen       = false,
        wfiGenAsWait         = false,
        ucycleAccess   = CsrAccess.NONE,
        uinstretAccess = CsrAccess.NONE
)
CSR可以根据具体实现配置,这里是一个比较简单的实现, 用于支持硬件断点等...

VexRiscvConfig结束,下面是对SOC接口的实现:

//CPU instanciation
val cpu = new VexRiscv(cpuConfig)
cpu.rework {
    for (plugin <- cpuConfig.plugins) plugin match {
            case plugin: IBusSimplePlugin => {
                    plugin.iBus.setAsDirectionLess() //Unset IO properties of iBus
                    master(plugin.iBus.toAhbLite3Master()).setName("iBusAhbLite3")
            }
            case plugin: DBusSimplePlugin => {
                plugin.dBus.setAsDirectionLess()
                    master(plugin.dBus.toAhbLite3Master(avoidWriteToReadHazard = true)).setName("dBusAhbLite3")
                }
                case plugin: DebugPlugin if args.contains("--jtag")=> plugin.debugClockDomain {
                       plugin.io.bus.setAsDirectionLess()
                       val jtag = slave(new Jtag()).setName("jtag")
                       jtag <> plugin.io.bus.fromJtag()
                 }
                case _ =>
        }
}

首先采用上面的配置,例化一个VexRiscv CPU

需要特别注意的是,由于SpinalHDL的实现限制,所有spinalhdl的object instance都必须申明在SpinalVerilog/SpinalVHDL内,如下所示:
val report = SpinalConfig(mode = if(args.contains("--vhdl")) VHDL else Verilog).generate {
    //CPU configuration
     val cpuConfig = VexRiscvConfig(
     withMemoryStage = false,
     withWriteBackStage = false,
     plugins = List(.....)

否则, 编译器spinalhdl 将会报告java.lang.NullPointerExecption的异常。

具体原因请见SpinalHDL作者的解释:

Dolu1990 commented on May 30

Basicaly, hardware statements realy need to be nested into a SpinalVerilog{ } / SpinalVhdl { } and idealy in a component.
As far i can see, i think that doing all of that in a shell will not be practical, as you realy need to define a full body


点赞

发表评论 评论 (1 个评论)

回复 l13787908861 2020-12-14 16:24
路过学习,很实用,谢谢分享

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 4

    粉丝
  • 3

    好友
  • 0

    获赞
  • 13

    评论
  • 412

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-25 12:58 , Processed in 0.023906 second(s), 16 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部