【PIPE】流水线设计中的基本模块

2023-11-20

 

大概分成以下几节:

1,概述及协议 
2,valid forward-valid超前 
3, bubble collapse - 消除气爆  
4, input/output skid - 不知中文怎么说 
5, pipe halt - 流水停顿 
6,idle present - 显示空闲

1.protocol

两个模块需要协同工作,少不了的就是你给我一些数据,我告诉你我收到了。或者你问我要一些数据,我过一会给你。
“你给我,我告诉你我收到了”,在通信,称之为握手。在数字设计中也一样。
握手有很多种,pipe里用到的这种握手协议,被我称为valid_ready。描述如下


valid_ready协议:
1, 当sender端有数据要发送时,将valid置1,并保证数据有效,可以不用检测ready。
2, 当receiver模块允许接受数据,将ready置1,可以不用检测valid是否有效。
3, 在任一个cycle,如果valid=1 && ready=1, 则接受端将会在紧接着的下一个clock posedge将数据采入,并通过ready信号来表示自己是否可以接受新的数据。
4, 在任一个cycle,如果valid=1 && ready=1,如果发送端仍有数据需要发送,则会在下一个clock posedge将新数据放入data bus,来表示自己有新的数据需要发送。如果没有新的数据需要发送,则将valid置0,表示没有数据需要发送。如果前一次的数据没有被接受端接受,即 ready=0,发送端需要保持valid=1,否则,数据将被丢弃,并没有被接收端收到。

 

如上图所示,c1周期,发送端有数据想要发送,将valid置1,并将D0稳定;可是c1周期接收端不肯接受数据(可能因为他正在忙于其他事务的处理), 数据没有被接受,发送端只能继续将valid置1,并保持D0不变。c2周期,接受端不再繁忙,可以接受数据了,于是他将ready置1,表明这个周期他 可以接受新数据。于是D0便在c2结束的那个上升沿被接收端取走。尽管接受端还想接受数据(c3周期,ready仍为1),但是发送端没有新数据需要发送,于是接收端继续保持ready=1,表明自己仍可以接受数据。紧接着,发送端在c4周期又有数据需要发送,于是就置vliad=1,而此时接收端正在等着呢,于是这个数据D1在c4周期,就传送完成。这次发送方发送完D1,紧接着还有D2需要发送,可是接收端不干了,他不能、不想、不愿意接受新的数据,于是D2和表明D2有效的valid只能一直保持在那里,等啊等,等啊等……直到c7,接收端可以接受了。于是D2终于传过去了。

2. basic pipe

basic pipe所谓的pipe,他的目的就是实现pipeline,即流水,有了valid_ready,我们就能很容易的将操作进行流水作业。通过插入pipe,可以将原来需要较多层的逻辑分拆开来,每一级pipe做一点。如下图,这是插入了一级pipe的。其中valid和data是同样的逻辑,所以就合并画在一起了。

下图,这是插入了2级pipe的。

每一级你可以对data进行一些处理,再传给下一级。
对于每一级pipe,其基本的逻辑是这样的。o: output, i:input
vo <= (ri) ? vi : vo;
do <= (ri) ? di : do;
ro = ri;
这个就是最基本的pipe的逻辑。
下面是基本pipe的电路图。

3. valid forward

细心的读者会注意到,当sender想要发送数据的时候,会将vi置1,这样,当receiver能够接受数据时,需要多等一个cycle,即数据先要寄存在pipe中,然后下一个cycle,接受端才能看到数据有效。如果要传输一笔数据需要2个cycle,当数据连续传送时,这没有问题,但是如果数据都是零碎的片断,那么效率就变得比较低下。也就是说,当pipe里面为空,但是receiver端不可以接受数据时,数据还是得停留再sender端,而这个空的pipe,我们称之为bubble


如何解决这个问题? 
当我们发现如果pipe级没有有效数据,即vo=0,那么我们让vi直接送到receiver端,而不再寄存一级。这样做的好处是效率提高了,坏处就是timing变差了。而且相比于没有插入pipe,timing更糟糕了。因为多了一些mux。其实,最糟糕的是,这种做法毫无用处,除非和下面要讲的bubble collpase配合使用。因为如果没有bubble collapse,它根本就没让pipe工作,因为reset之后,pipe始终为空,于是每一次,数据都绕过了pipe,直接送到了serder端。而且,这比没有插入pipe的timing来的更糟糕。这和我们最初要引出pipe,来实现流水以提高timing性能,这个目的相矛盾。


下面我们要讲提及了很多次的bubble collapse了,看看他神奇在什么地方。其实道理很简单,如果receiver端不ready,而pipe为空,我们就将数据先进入pipe级的寄存器,缓存于pipe级。在sender看来,这个数据已经被pipe级取走,可以放新的数据了。下次,receiver端ready了,直接和pipe要数据即可。这样,bubble就消失了。
如图所示:

逻辑代码如下:
ro = ri || !vo;             // ready
vo <= (ro)? vi : vo;       // valid
do <= (ro && vi)? di : do;  // data

仔细、仔细、再仔细体会一下以上代码

4. input/output skid

pipe能有效的改善data的timing(当然,顺带也改善了valid的timing),使得data在其传输路径上被寄存N拍,如果有复杂的组合逻辑,则可以将组合逻辑拆成一系列的组合逻辑,并在每个之间插入pipe,尽管每一笔数据的延时增加了,但是带宽并没有变小。可是,如果ready信号的产生,传播逻辑比较复杂,我们也同样在某些地方将ready打上一拍,以改善他的timing。可是仅仅对ready打一拍,协议就会被破坏了,使得valid 和ready对应不上。

现在我们仅仅简单的将ready打了一拍给sender端,那么sender端看到就是延时一拍以后的ready,即ro<=ri。如果vi=1&&ro=1,从sender的角度看来,就是data被取走了,可以放一个新的数据了。

让我们用最简单的basic pipe来举例说明。假设sender有3笔数据需要发送,而receiver收到一笔后既不能再接受,需要进行一些处理,等几个cycle之后才能再接受新的数据。

其时序如图所示:

我们来简单分析一下:
最初,sender没有数据要发送,vi=0;receiver空闲,可以接受数据,ri=1。但是由于在c3时刻,ri=0,ro=1;receiver不可以接收新的数据,而sender没有及时发现,他还是将数据D2押送给了pipe,但是pipe里面囤积的D1并没有被收走,于是pipe处于一个两难的境地,要么将D1丢弃,要么将D2丢弃,无论如何,总是会丢失一笔数据。

D1占据着Pipe里唯一可以容身的小屋(data register),D2来了,也想进来。D1看了看D2,说:“小样,你是新、新、新、新、新来的吧……,我这里只有一间屋,住不下咱俩,要不这间给你,我自己在离sender近一点的地方再造一间新屋,但是得先说好,船来了(ri=1),我先走。”D2想了想,没办法,一山不容二虎,除非一公和一母,谁让咱俩没性别,要不然……说不定,还能生个小娃,这是后话。

于是,我们又造了一间新的小屋,起名叫skid buffer。当ri从1变0时,即ri=0,ro=1,表示receiver端忽然不能接受新数据了,但是sender要晚点才能知道,这时 候,skid给D1住,D2住老屋。当ri从0变1时,即ri=1、ro=0,表示receiver有可以接受新数据了,这是得先把skid里得数据放走。此时skid里住着D1呢,D2这时看到得还是ro=0,所以他继续呆在老屋里不动。除了这两种情况,其他情况都无所谓,随便我们怎么处理skid都可以,如果想要逻辑简单,那么就像我上面所说得那样处理。但是会出现的这个问题:D2在以后的cycle中,尽管不需要再住进skid了,但是还是会给个分身给skid,而自己会直接从老屋乘船走了。这样会造成skid里不停的让无用的D2们进进出出(无效翻转);为了降低skid再无用的时候不要住无用的D2们的分身,可以加一点控制逻辑,使得D2们在不需要的时候不要浪费skid的资源。(逻辑为 ri ^ ro==0时,disable skid)

下面这个图稍微复杂了点,是一个basic pipe+skid。控制逻辑最少,但增加了额外的skid使用。

skid和pipe这两部分的位置是可以互换的。如果你能成功的做到,你对以上内容的掌握应该已经炉火纯清了。

5. pipe halt

在输入增加一个信号,用于将pipe停止。
即流水线停顿。来自upstream的valid会立即被忽略,送给上一级的ready立刻被取消。同样送给downstream的valid立刻会被取消,而ready也不予理睬。pipe内部所有数据流全部立即停止。

但是如果pipe内部有skid,为了保证数据的正确,skid级的valid立即取消,但是送给upstream的ready需要在下一个cycle再 停顿。恢复的时候也一样,valid立即恢复,而送给upstream的ready需要在下一个cycle才可以恢复。(有关skid的停顿逻辑需要你冥想3分钟,我刚开始几次,每次思考这个问题,都不能一下子想明白,总要绕几圈才豁然。)

6. idle present

Idle 信号表明Pipe中没有有效数据,即每一级pipe的valid无效。
其逻辑为

idle = ~(p1_valid |p2_valid|...)

其中,pn_valid 为第n级Pipe的vo

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【PIPE】流水线设计中的基本模块 的相关文章

  • 在vivado中使用tcl脚本(UG894)

    本文源自UG894 主要介绍如何在vivado中使用tcl脚本 1 vivado中如何获取tcl help vivado中任何自带的命令都可以通过 help 获取帮助信息 也可以直接输入 help 取得vivado命令合集 并通过 help
  • STA(静态时序分析) 详解:如何计算最大时钟频率,以及判断电路是否出现时钟违例(timing violation)?

    1 什么是STA STA 静态时序分析 是时序验证的一种方法 用于计算和分析电路是否满足时序约束的要求 2 为什么需要STA 电路能否正常工作 其本质上是受最长逻辑通路 即关键路径 的限制 以及受芯片中存储器件的物理约束或工作环境的影响 为
  • SmartFusion从FPGA到ARM(四)——MSS_TIMER定时器的使用

    文章目录 1 定时器资源简介 2 MSS TIMER库函数简介 3 简单的周期性中断 4 自定义产生波形 5 64位定时器的使用 6 单次中断模式 系列教程 SmartFusion从FPGA到ARM系列教程 1 定时器资源简介 SmartF
  • Xilinx ISE系列教程(9):LabTools下载、安装、使用教程(独立的下载工具)

    文章目录 1 ISE Vivado LabTools简介 2 ISE 14 7 Lab Tools下载 安装 3 Vivado 2018 3 LabTools下载 安装 1 ISE Vivado LabTools简介 Xilinx LabT
  • verilog 基本语法 {}大括号的使用

    的基本使用是两个 一个是拼接 一个是复制 下面列举了几种常见用法 基本用法 表示拼接 第一位 第二位 表示复制 4 a 等同于 a a a a 所以 13 1 b1 就表示将13个1拼接起来 即13 b1111111111111 拼接语法详
  • JESD204B(RX)协议接口说明。

    解释一下Vivado IP协议中的Shared Logic in Example 与 Shared Logic in Core 首先 什么是Shared Logic 字面意思很好理解 就是共享逻辑 主要包括时钟 复位等逻辑 当选择Share
  • FPGA Lattice Diamond 开发环境搭建

    FPGA Lattice Diamond 开发环境搭建 Lattice Diamond 软件下载 在浏览器中输入 Lattice 的官网地址 http www latticesemi com 进入官网首页在上方选择产品系列选项 出现如下图所
  • FPGA功耗估计(二)

    针对于Altera的Cyclone III 做出了静态功耗 对于Altera 其提供了一个功耗早期估计工具 可以在官网上下到 首先需要将宏设置为安全 在excel选型中选择文件 之后便可看到 根据相应的选择 红框部分 可以查看静态功耗 对于
  • FPGA_MIG驱动DDR3

    FPGA MIG驱动DDR3 说明 FPGA zynq 7z100 DDR3 MT41K256M16TW 107 内存大小为512MB 数据接口为16bit 环境 Vivado2018 2 IP核 Memory Interface Gene
  • [从零开始学习FPGA编程-38]:进阶篇 -语法-函数与任务

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 前言 第1章 什么是函数Function 1 1 什么是函数 1 2 函
  • 64 位 ALU 输出在 TestBench 波上显示高阻抗

    我必须制作一个 64 位 ALU 它接受 A 和 B 64 位输入 进位输入输入并输出 64 位结果以及 1 位进位输出 还有一个 5 位功能选择 FS 其中 FS 0 控制 B 是否反转 使用 2to1 多路复用器 F 1 对 A 执行相
  • Verilog、FPGA、统一寄存器的使用

    我有一个问题 关于我正在开发的 AGC SPI 控制器在我看来奇怪的行为 它是用 Verilog 完成的 针对的是 Xilinx Spartan 3e FPGA 该控制器是一个依赖外部输入来启动的 FSM FSM的状态存储在状态寄存器它没有
  • 异步FIFO设计之格雷码

    目录 二进制转格雷码 格雷码转二进制 相邻的格雷码只有1bit的差异 因此格雷码常常用于异步fifo设计中 保证afifo的读地址 或写地址 被写时钟 或读时钟 采样时最多只有1bit发生跳变 在不考虑路径延时的情况下 因为源数据 读写地址
  • 同时读取和写入寄存器

    我计划在 FPGA 上用 VHDL 设计一个类似 MIPS 的 CPU CPU 将具有经典的五级管道 没有转发和危险预防 在计算机体系结构课程中 我了解到第一个 MIPS CPU 用于在时钟上升沿读取寄存器文件并在时钟下降沿写入 我使用的F
  • VHDL - PhysDesignRules:367

    当我尝试从 VHDL 代码合成 实现和生成程序文件时 我收到警告 当我尝试合成时出现此错误 WARNING Xst 647 Input
  • VHDL门控时钟如何避免

    我收到了避免使用门控时钟的建议 因为它可能会导致松弛和时序限制问题 但我想问一下我可以认为什么是门控时钟 例如 此代码对时钟进行门控 因为 StopCount 对它进行门控 process ModuleCLK begin if rising
  • 模拟器和合成器之间初始化状态机的差异

    我的问题是关于合成状态机中使用的第一个状态 我正在使用莱迪思 iCE40 FPGA 用于仿真的 EDA Playground 和用于综合的莱迪思 Diamond Programmer 在下面的示例中 我生成一系列信号 该示例仅显示引用状态机
  • 使用双寄存器方法解决亚稳态问题

    为了解决Verilog中不同时钟域引起的亚稳态 采用双寄存器方法 但据我所知 亚稳态的最终输出尚未确定 输出独立于输入 那么 我的问题是如何保证使用双寄存器方法输出的正确性 Thanks 您不能完全确定您避免了亚稳态 正如您所提到的 亚稳态
  • FPGA 有哪些实际应用?

    我对我的程序为一个小型七段显示器提供动力感到非常兴奋 但是当我向不在现场的人展示它时 他们总是说 那么你能用它做什么 我永远无法给他们一个简洁的答案 谁能帮我吗 第一 它们不需要具有易失性存储器 事实上 大厂商 Xilinx Altera
  • 学习 Verilog 的资源 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我是 Verilog 新手 有人可以推荐学习资源 书籍 视频 博客或任何他们有良好个人经验并帮助他们更

随机推荐