0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

浅析SpinalHDL中Pipeline中的复位定制

Spinal FPGA 来源:Spinal FPGA 2024-03-17 17:31 次阅读

之前有系列文章介绍了SpinalHDL中Pipeline的使用,最近在一个功能模块中真实的使用了这个lib。虽然在使用上基于Flow/Stream的抽象已基本满足大多数使用场景,但在FPGA端有时为了优化时序往往不得不做一些逻辑打散,此时发现Pipeline中的标准化组件就有点难以满足需求了。

》举个例子

考虑下面的一个使用pipeline简单的逻辑代码:

d868be28-e2d2-11ee-a297-92fbcf53809c.png

这是一个很简单的逻辑,port_in打两拍输出至port_out。逻辑里有这样一个动作需求:

当port_out.valid为高且port_out.data1为true时,checked为真

这里checked输出为一个组合逻辑,如果外部在使用时还需要其他许多类似的条件那么就有可能会对时序收敛带来困难了(这里仅用来举个例子阐述这种类似的需求)。

那么也许想当然的将checked的判断条件声明一个Stageable变量在stage1中完成判断,stage2中直接使用,就像这么来做:

d8721ee6-e2d2-11ee-a297-92fbcf53809c.png

如此,我们将组合逻辑前移,checked输出为时序逻辑。看似完美是吧~

然而,如果你在VCS仿真器仿真你会发现,checked可能刚一上电就是高电平导致后续逻辑异常。其原因就是cond_matched没有赋初值。

在pipeline的架构里,在Connection中实现了不同Stage之间的连接,其中也包含了时序协议的实现。以这里我们调用的M2S为例:

d87ce394-e2d2-11ee-a297-92fbcf53809c.png

其将valid声明为Reg并赋给初始值False,然而对于payload仅声明为寄存器并未赋初值。

由于有valid信号指示,paylaod不赋初值无可厚非,奔着控制路径添加复位,数据路径不添加复位的原则,这里并没有问题。然而我们在针对一些时序优化的场景需要将部分paylaod赋初值,这里就不太符合我们的需求了。

》M2SExt

既然满足不了需求,那就扩展。这里的实现可能略显丑陋,但能解决问题。Stageable类型在Pipeline中例化为对象时会以我们声明的Stageable变量名作为结尾,我们只需在M2S的on实现基础上添加匹配规则即可。由于M2S是Class不可继承,这里重新定义了一个M2SExt来实现:

caseclassM2SExt(collapse: Boolean= true,
holdPayload: Boolean= false,
flushPreserveInput: Boolean= false) extendsConnectionLogic {
val initMap = LinkedHashMap[String, Data]()

def addInitValue[T <: Data](target: Stageable[T], initValue: T) = {
    initMap.update(target.getName(), initValue)
  }

  def on(m: ConnectionPoint,
         s: ConnectionPoint,
         flush: Bool, flushNext: Bool, flushNextHit: Bool,
         throwHead: Bool, throwHeadHit: Bool) = new Area {

    s.valid.setAsReg() init (False)
    s.payload.foreach(_.setAsReg())


    m.ready match {
      case null =>
s.valid := m.valid
(s.payload, m.payload).zipped.foreach(_ := _)
caser=>{
if(flush != null&& flushPreserveInput) s.valid clearWhen (flush)
if(throwHead != null) s.valid clearWhen (throwHead)
when(r) {
s.valid := m.valid
}
when(if(holdPayload) m.valid && r elser) {
(s.payload, m.payload).zipped.foreach(_ := _)
}
}
}


if(flush != null&& !flushPreserveInput) s.valid clearWhen (flush)
if(flushNext != null&& !flushPreserveInput) s.valid clearWhen (flushNext && s.ready)
if(flushNextHit != null) flushNextHit := True

// assert(!(flushNext != null && flushPreserveInput))

if(m.ready != null) {
m.ready := s.ready
if(collapse) m.ready setWhen (!s.valid)
}

Component.current.addPrePopTask(()=>{
s.payload.foreach(paylaod=>{
initMap.foreach { case(signalEndName, initValue) =>{
if(paylaod.getName().endsWith(signalEndName)) {
paylaod.init(initValue)
}
}
}
})

})
}

这里为M2S定义了一个addInitValue方法,从而能使得我们能够为某个ConnectionLogic中制定的Stageable映射电路对象添加复位值。在on实现函数最后通过添加PrePopTask来遍历搜索当前ConnectionLogic中对应的payload并赋初始值。

最终我们可以在实现里如此:

d8817490-e2d2-11ee-a297-92fbcf53809c.png

stage1To2Connection通过调用addInitValue来为cond_matched添加复位值,以此满足需求:

d8a639ec-e2d2-11ee-a297-92fbcf53809c.png

pipe_stage2_cond_matched添加复位控制。




审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1602

    文章

    21320

    浏览量

    593195
  • 寄存器
    +关注

    关注

    30

    文章

    5028

    浏览量

    117721
  • 仿真器
    +关注

    关注

    14

    文章

    988

    浏览量

    82993
  • VCS
    VCS
    +关注

    关注

    0

    文章

    78

    浏览量

    9495
  • Pipeline
    +关注

    关注

    0

    文章

    27

    浏览量

    9293

原文标题:审视下Pipeline中的复位定制

文章出处:【微信号:Spinal FPGA,微信公众号:Spinal FPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    关于SpinalHDL的验证覆盖率收集简单说明

    在做RTL仿真验证时,覆盖率收集往往是我们在验证需要注意的地方,本篇就SpinalHDL的验证覆盖率收集做一个简单说明。sbt配置在SpinalHDL里进行仿真验证时,我们的待测试
    发表于 06-24 15:56

    关于SpinalHDL仿真中信号驱动那点事儿

    还是cocotb,其均是基于协程的思路来进行的仿真。那么,这里面在仿真信号赋值时,今天来一探究竟。》SpinalHDL的仿真信号驱动我们以下面这个简单的example来进行测试:这里dataOut
    发表于 06-24 16:34

    谈谈SpinalHDLStreamCCByToggle组件设计不足的地方

    到ack为低电平即可处理新的任务。  写在最后  关于跨时钟域处理在处理上相对来讲还是一个易错点,其处理也是新学者需要好好把握的。SpinalHDL的源代码还是很值得一读的。一方面
    发表于 06-30 15:11

    聊聊SpinalHDL的FIFO

    “痛苦”的事情。SpinalHDL关于RAM的抽象与思考在前文已提到过,这里不再做额外赘述。那么同样,对于FIFO这类电路的出口时序和入口时序,其本质上也都属于握手的一种,这一点也就体现了
    发表于 06-30 15:28

    SpinalHDL关于casez的使用

    SpinalHDL的switch在之前的文章中曾提到过SpinalHDLswitch的使用:通常情况下,switch对应着我们日常Verilog代码
    发表于 07-06 10:59

    SpinalHDL的代码组织结构如何实现Component参数化设计呢

    习惯了Verilog的小伙伴,初次看到SpinalHDL的代码时,总会不自觉的和Verilog代码对照,本篇就SpinalHDL的代码组织结构进行一个简要的梳理。Component<
    发表于 07-21 14:20

    请问SpinalHDL的Area到底是什么意思

    )及兼顾代码尽可能复用的准则,SpinalHDL里设计了Area的概念。通过类扩展集成Area,可以有效的避免上述问题。介绍Area之前,先介绍一个概念:在Scala,参数的传递均为引用类型,而我们定义
    发表于 07-22 14:22

    SpinalHDL仿真信号的驱动实现

    阻塞并没有明确的界定,而至于仿真器内部的时隙调度,个人一直是看过明白,看后即忘。为了抛开这个烦恼,个人使用下来的体验就是SpinalHDL的测试代码对于信号的驱动都是立即生效的,类似于阻塞赋值
    发表于 07-27 14:37

    SpinalHDLBundle与普通数据类型之间的连接赋值转换

    SpinalHDLBundle与SystemVerilog的packed struct很像,在某些场景下,与普通数据类型之间的连接赋值可以通过asBits,assignFromBits来实现
    发表于 10-18 14:22

    SpinalHDL设计错误总结相关资料分享

    1、SpinalHDL设计错误  SpinalHDL编译器会做很多设计检查,来确保生成的VHDL/Verilog是可仿真的可综合的。基本上,SpinalHDL不会生成破损的VHDL/Verilog
    发表于 10-24 15:37

    基于Windows系统的SpinalHDL开发环境搭建步骤

    1 所有软件安装在C:\\SpinalHDL根目录下即可2 所有软件安装过程,把path选项都勾选上3 仿真需要使用GTKWave+Verilator,安装MSYS2软件之后,打开用户终端输入如下
    发表于 10-24 15:40

    定制的STMF446RE MCU复位问题求解

    大家好,我们在定制板上使用 STM32F446RE MCU。我们附上了复位引脚的原理图,我们可以看到 RESET 引脚变高或变低,但在 IDE 未观察到 MCU 复位。我们在 Mai
    发表于 02-03 09:04

    SpinalHDL里时钟域中的定制与命名

    聊一聊在SpinalHDL里时钟域中时钟的定制与命名。 相较于Verilog,在SpinalHDL里,其对时钟域有着更细致的描述,从而也能够更精细的控制和描述。而对于时钟域,我们往往关系的是: 时钟
    的头像 发表于 03-22 10:14 1887次阅读

    SpinalHDL BlackBox时钟与复位

    SpinalHDL中使用之前已有的Verilog等代码的时候需要将这些代码包在一个BlackBox里面,但是如果这些代码里面有时钟和复位,我们需要怎么将时钟和复位端口和SpinalHDL
    的头像 发表于 05-04 11:13 509次阅读
    <b class='flag-5'>SpinalHDL</b> BlackBox时钟与<b class='flag-5'>复位</b>

    SpinalHDLpipeline的设计思路

    如果你曾看过VexRSICV的设计,对于从事逻辑设计的你会惊讶从未想过逻辑设计还能这么来做。针对VexRSICV所衍生出的pipeline Lib,该系列会对pipeline进行一次梳理。诚如之前一篇博客曾讲,这是“勇者的游戏”。
    的头像 发表于 08-16 15:11 713次阅读
    <b class='flag-5'>SpinalHDL</b>里<b class='flag-5'>pipeline</b>的设计思路