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添加复位控制。




审核编辑:刘清

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

    关注

    1619

    文章

    21467

    浏览量

    597755
  • 寄存器
    +关注

    关注

    31

    文章

    5220

    浏览量

    118934
  • 仿真器
    +关注

    关注

    14

    文章

    1000

    浏览量

    83372
  • VCS
    VCS
    +关注

    关注

    0

    文章

    78

    浏览量

    9530
  • Pipeline
    +关注

    关注

    0

    文章

    28

    浏览量

    9310

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

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

收藏 人收藏

    评论

    相关推荐

    SpinalHDL如何快速地实现总线连接

    教你在 SpinalHDL 总线连接时针对总线的部分信号位宽不同时的如何快速地实现总线连接。
    发表于11-28 15:48 707次阅读

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

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

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

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

    聊聊SpinalHDL的FIFO

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

    SpinalHDL关于casez的使用

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

    SpinalHDL仿真信号的驱动实现

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

    定制的STMF446RE MCU复位问题求解

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

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

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

    SpinalHDL的SpiMasterCtrl模块做使用说明详解

    最近偶尔需要用到SPI模块。正巧看到 SpinalHDL中所提供的SPI-Master设计。看完之后尤为佩服如此简洁而又全面的设计方式。本篇不对SPI协议进行讲解,仅针对 SpinalHDL 的SpiMasterCtrl模块做使用说
    的头像 发表于04-19 09:58 3561次阅读

    SpinalHDL的对应关系及声明形式

    针对 SpinalHDL 的两大类型Reg、Wire,来梳理下在 SpinalHDL 的对应关系及声明形式。
    的头像 发表于07-03 11:02 1382次阅读

    SpinalHDLBundle数据类型的转换

    SpinalHDL Bundle与SystemVerilog 的packed struct很像,在某些场景下,与普通数据类型之间的连接赋值可以通过asBits,assignFromBits来实现。
    的头像 发表于10-17 09:51 1153次阅读

    SpinalHDLBlackBox时钟与复位

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

    SpinalHDLpipeline的设计思路

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

    PipelinethrowIt的用法

    字如其名,来看下 Pipeline throwIt的用法,是怎么个丢弃方式。
    的头像 发表于10-21 16:24 388次阅读
    <b class='flag-5'>Pipeline</b><b class='flag-5'>中</b>throwIt的用法

    什么是pipeline?Go构建流数据pipeline的技术

    本文介绍了在 Go 构建流数据 pipeline的技术。 处理此类 pipeline 的故障很棘手,因为 pipeline
    的头像 发表于03-11 10:16 393次阅读