数字前端/FPGA设计——握手与反压问题


 声明:本文来自0431大小回


前言:在芯片设计或者FPGA设计过程中,流水设计是经常用到的,但是考虑数据安全性,需要与前后级模块进行握手通信,这时候就需要对流水数据进行反压处理,本文将具体介绍握手与反压。

目录

  • 握手协议
  • 握手与反压
  • 反压
  • 带存储体的反压
    • 字节的问题
    • 代码分析
    • 逐级反压与跨级反压
  • 不带存储体的反压
    • 代码分析

握手协议

本文讲述valid-ready握手,下面列出三种握手情况,目的是解释清楚握手的时序。

  • valid先发起请求

  • ready先发起请求

  • 同时发起请求

  • 分析

仔细观察上述3幅时序图,我们了解valid-ready握手机制需要注意三件事:

  1. valid与ready不可过度依赖,比如valid不可以等待ready到达再拉高,但是在axi协议中的握手信号,ready是可以等待valid拉高再拉高的,valid不可依赖ready的原因是防止死锁(deadlock),本文的代码他俩彼此可以互相独立发出请求拉高;
  2. valid拉高时与有效数据同步,时钟要对齐;
  3. 当数据计算好后,valid可以拉高等待ready拉高,但是每当握手成功之后,数据需要更新,如果此时没有新的有效数据,valid要拉低。

握手与反压

当入口流量大于出口流量,这时候就需要反压,或者,当后级未准备好时,如果本级进行数据传递,那么它就需要反压前级,所以此时前级需要将数据保持不动,直到握手成功才能更新数据。而反压在多级流水线中就变得稍显复杂,原因在于,比如我们采用三级流水设计,如果我们收到后级反压信号,我们理所当然想反压本级输出信号的寄存器,但是如果只反压最后一级寄存器,那么会面临一个问题,就是最后一级寄存器数据会被前两级流水冲毁,导致数据丢失,引出数据安全问题,所以我们此时需要考虑反压设计。

反压

常用的反压方法有三种:

  • 不带存储体的反压

也就是后级反压信号对本级模块中所有流水寄存器都进行控制,由于不包含存储体,为了保证数据安全性,后级反压信号可以同时反压本模块中所有流水寄存器。

优点:节省面积资源

缺点:寄存器端口控制复杂

适用情况:流水线深度较大时

  • 带存储体的逐级反压

如果流水级数不深,可以在每一需要握手交互模块增加存储体,原理上相当于,如果后级发出反压信号,可以直接对本级流水线数据源头进行反压,其余中间级不需控制,但后级需要包含RAM或FIFO等存储体,可以接收流水,并需设置水线(water line),确定反压时间,防止数据溢出,保证数据安全性。

优点:各级流水寄存器端口控制简单

缺点:需要额外存储体

适用情况:流水线深度较小,每一模块都包含存储体时

  • 带存储体的跨级反压

很多时候在具体设计过程中,颗粒度划分不精细,反压这时候是对模块而言,而不是说模块内部有多少级流水。此外,并不是每一模块都带有存储体。比如,其中可能a模块没有存储体,b模块没有存储体,但ab模块内部还有多级流水,如果c模块有存储体,并且需要反压前级模块,这时候可以选择反压a模块的源头输入数据,然后将ab的流水都存储到带有存储体的c模块,但是如果ab不是都没有存储体的话,就不应该跨级反压,而应该逐级反压,具体原因后续会讲。

优点:控制简单方便

缺点:需要额外存储体,模块间耦合度高

适用情况:某些模块带存储体,某些模块不带存储体时

带存储体的反压

如上文所述,很多时候我们不喜欢对每一级细分流水都进行反压,所以可以选择带存储体的反压,也就是增加RAM或者FIFO,在反压上级模块的同时,本级有足够的深度来存储上一级的流水数据。具体内容如下图所示:

此时我们假设车库就是最后一级模块,需要对前一级进行反压,车库是带有存储体的模块,那么此时就需要设计水线waterline,也就是当waterline为多少时开始反压前一级模块(车库入口闸机)。由上图可知,当waterline最大为90时,必须向上一模块发出反压请求,因为在途的还有10辆车,这个就相当于我们设计的10级流水,其中有10级寄存器有流水数据输出,所以车库的剩余容量还可以存储住途中流水,保证了数据安全。

举个例子——字节的问题

问题:设计一个并行6输入32比特加法器,输出1个带截断的32比特加法结果,要求用三级流水设计,带前后反压。

主要输入:

  1. 6个32bit数据
  2. 上一级的valid_i
  3. 下一级的ready_i

输出:

  1. 1个32bit结果
  2. 给上一级的ready_o
  3. 给下一级的valid_o
  • 分析

其实在多级流水设计中,如果每一级只有一个寄存器,并且都在一个模块中,也就是说当颗粒度划分的很细的时候,一般使用带存储体的反压,比如六级流水,那么就设计好水线,在FIFO未满时提前发出反压信号,一般水线设为FIFO_DEPTH - 流水级数,下面是我设计的代码。

核心思想就是如果FIFO未达到水线(WATERLINE)时,给上一级的反压信号ready_o就持续拉高,否则拉低;FIFO非空时就可以给下一级valid_o拉高,然后下一级的反压信号ready_i可以作为FIFO的读使能信号,具体请参考下文代码。

//还未仿真,欢迎指出问题
module handshake_fifo #(
    parameter           FIFO_DATA_WIDTH = 32,
    parameter           FIFO_DEPTH = 8
)(
    input  wire         clk,
    input  wire         rst,
    input  wire         valid_i,
    input  wire         ready_i,
    input  wire  [31:0] a,
    input  wire  [31:0] b,
    input  wire  [31:0] c,
    input  wire  [31:0] d,
    input  wire  [31:0] e,
    input  wire  [31:0] f,
    output logic [31:0] dout,
    output logic        ready_o,
    output logic        valid_o
    );
    
    localparam          WATERLINE = FIFO_DEPTH - 3; //three levels' pipeline
    logic               handshake;
    logic               handshake_ff1;
    logic               handshake_ff2;
    logic               wr_en;
        
    assign handshake = ready_o & valid_i;

    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            handshake_ff1 <= '0;
            handshake_ff2 <= '0;
        end
        else begin
            handshake_ff1 <= handshake;
            handshake_ff2 <= handshake_ff1;
        end
    end
    
    reg [31 : 0] r1_ab;
    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            r1_ab <= '0;
        end
        else if(handshake)begin
            r1_ab <= a + b;
        end
    end
    
    reg [31 : 0] r1_cd;
    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            r1_cd <= '0;
        end
        else if(handshake)begin
            r1_cd <= c + d;
        end
    end
    
    reg [31 : 0] r1_ef;
    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            r1_ef <= '0;
        end
        else if(handshake)begin
            r1_ef <= e + f;
        end
    end
    
    reg [31 : 0] r2_abcd;
    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            r2_abcd <= '0;
        end
        else if(handshake_ff1) begin
            r2_abcd <= r1_ab + r1_cd;
        end
    end
    
    reg [31 : 0] r2_ef;
    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            r2_ef <= '0;
        end
        else if(handshake_ff1) begin
            r2_ef <= r1_ef;
        end
    end
    
    reg [31 : 0] r3;
    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            r3 <= '0;
        end
        else if(handshake_ff2) begin
            r3 <= r2_ef + r2_abcd;
        end
    end
    
    always @ (posedge clk or posedge rst) begin
        if(rst) begin
            wr_en <= 1'b0;
        end
        else if(handshake_ff2) begin
            wr_en <= 1'b1;
        end
        else begin
            wr_en <= 1'b0;
        end
    end

    always_ff @(posedge clk)begin
        if(rst)begin
            ready_o <= 1'b0;
        end
        else if(usedw > WATERLINE)begin
            ready_o <= 1'b0;
        end
        else begin
            ready_o <= 1'b1;
        end
    end

    assign valid_o = ~empty;
     sync_fifo # (
        .MEM_TYPE   ("auto"         ),
        .READ_MODE  ("fwft"         ),
        .WIDTH      (FIFO_DATA_WIDTH),
        .DEPTH      (FIFO_DEPTH     )
    )fifo_inst(
        .clk    (clk                ), // input  wire
        .rst_n  (rst_n              ), // input  wire
        .wren   (wr_en              ), // input  wire
        .din    (r3                 ), // input  wire [WIDTH-1:0]
        .rden   (ready_i            ), // input  wire
        .dout   (dout               ), // output reg  [WIDTH-1:0]
        .empty  (empty              ), // output wire
        .usedw  (usedw              )
    );

endmodule

逐级反压与跨级反压

这时候的反压包括逐级反压和跨级反压,具体区别可以参考下图:

由上图可见,3个模块都包含存储体,我们假设此时module3到达了它的水线,那么它有两种方式反压前面的模块,一种是从最源头进行反压,另一种是逐级反压。

建议:当每一模块都有存储体时,建议逐级反压。

原因:如果逐级反压的话,方法就是module3到达水线则反压module2,module2到达水线反压module1,每一级的水线和存储体大小设计就如上文车库模型所述,简单清晰。但是,如果选择跨级反压,那么module3的存储体深度 = waterlie3 + 在途1 + waterline1 + 在途2 + waterline2 + 在途3,可见每一级的存储体会变大并且水线计算复杂,另外路径变长,模块间耦合度增高,不利于复用与维护。但是,如果不是每一模块都包含存储体,那么可以选择跨级反压。

不带存储体的反压

分析与代码

同样是上文字节的问题,如果此时要求不允许使用FIFO,那应该怎么设计呢?

核心思想就是保证每一级流水中的每一级寄存器的数据安全,可以把每一级寄存器当成一个深度为1的FIFO,下一级有无数据可以看对应的valid信号。下一级无数据或者下一级已经准备好了,那么就可以向上一级取数据,本质上是pre-fetch结构。具体内容可以参考如下代码,注意:我没有把重复部分的代码写全,但是写出了所有核心代码,可供参考。

module handshake_pb #(
)(
    input  wire         clk,
    input  wire         rst,
    input  wire         valid_i,
    output wire         ready_o,
    input  wire  [31:0] a,
    input  wire  [31:0] b,
    input  wire  [31:0] c,
    input  wire  [31:0] d,
    input  wire  [31:0] e,
    input  wire  [31:0] f,
    output wire  [31:0] dout,
    input  wire         ready_i,
    output reg          valid_o
    );

    assign ready_o = ~valid_r1 || ready_r1;
    //pre_fetch结构
    //valid_r1为0代表下一级无数据
    //ready_r1代表下一级准备好了读

    always_ff @ (posedge clk) begin 
        if(rst)begin
            valid_r1    <= 1'b0;
        end
        else if(ready_o)begin
            valid_r1    <= valid_i;
        end
    end
    
    always_ff @ (posedge clk) begin
        if(ready_o & valid_i)begin
            r1_ab       <= a + b;   //数据信号不复位
        end
    end

    assign ready_r1 = ~valid_r2 || ready_r2;

    reg [31 : 0] r2_abcd;

    always_ff @ (posedge clk) begin 
        if(rst)begin
            valid_r2    <= 1'b0;
        end
        else if(ready_r1)begin
            valid_r2    <= valid_r1;
        end
    end
    
    always_ff @ (posedge clk) begin
        if(ready_r1 & valid_r1)begin
            r2_abcd     <= r1_ab + r1_cd;
        end
    end

    assign ready_r2 = ~valid_r3 || ready_i;
    
    reg [31 : 0] r3;

    always_ff @ (posedge clk) begin 
        if(rst)begin
            valid_r3    <= 1'b0;
        end
        else if(ready_r2)begin
            valid_r3    <= valid_r2;
        end
    end
    
    always_ff @ (posedge clk) begin
        if(ready_r2 & valid_r2)begin
            r3          <= r2_ef + r2_abcd;
        end
    end

    assign dout     = r3;
    assign valid_o  = valid_r3;
endmodule

值得大家注意的是ready和valid的输入输出,此外就是每一级流水的握手信号处理。

对于不带存储体的反压,

不带存储体的反压的主要缺点还是timing差,不适合长流水。流水线最下游的ready会一路传导到最上游,会导致组合逻辑过长,引起时序问题。可以考虑中间再加一级寄存器,输出一级寄存器,可以参考xilinx的axis handshake ip。

此外,这里的代码按照握手协议,valid不能够看ready信号,但是ready是可以等valid来了再拉高的。如果下一级ready信号初始一直为0,输出的valid也会一直为0,这样就死锁了。这个代码主要还是为了解决这道题,不能用作标准模块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/325562.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

尺寸公差 DTAS3D产品功能介绍

DTAS 3D (Dimensional Tolerance Analysis System 3D)基于蒙特卡洛原理&#xff0c;按照产品的公差及装配关系进行建模&#xff0c;然后进行解析、仿真计算&#xff0c;最终预测产品设计是否能够满足其关键尺寸要求&#xff0c;同时预测产品合格率&#xff0c;并进行根源分析。…

【NI国产替代】NI‑9232,3通道,102.4 kS/s/ch,±30 V,C系列声音与振动输入模块

3通道&#xff0c;102.4 kS/s/ch&#xff0c;30 V&#xff0c;C系列声音与振动输入模块 NI‑9232可以测量来自集成电子压电(IEPE)和非IEPE传感器的信号&#xff0c;例如加速度计、转速计和接近式探针。 NI‑9232还可兼容智能TEDS传感器。\n\nNI‑9232集成了软件可选的AC/DC耦合…

Fpga开发笔记(二):高云FPGA发开发软件Gowin和高云fpga基本开发过程

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/135620590 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

spring Security源码分析-13种过滤器详解

13种核心过滤器 spring security的13个核心过滤器(按执行顺序陈列): WebAsyncManagerIntegrationFilterSecurityContextPersistenceFilterHeaderWriterFilterLogoutFilterUsernamePasswordAuthenticationFilterDefaultLoginPageGeneratingFilterDefaultLogoutPageGeneratingF…

Windows Server 2019配置DNS服务器

正文共&#xff1a;1234 字 31 图&#xff0c;预估阅读时间&#xff1a;1 分钟 我们在给Windows Server添加角色和功能时&#xff0c;会发现有一项“远程桌面服务安装”&#xff0c;它的介绍为“为虚拟桌面基础结构&#xff08;Virtual Desktop Infrastructure&#xff0c;VDI&…

java处理16进制字符串的一些方法和基础知识

前言&#xff1a;本篇文章是对于基础数据的处理的一些简单经验总结里边包含了一些基础的数据储存和数据转化的一些知识&#xff0c;同样也包含有部分快捷的数据处理方法。主要用于个人知识的一个记录和方便进行对应的数据转换和处理。 1、bit,字节和字的关系 1.1 bit和字节的…

怎么注册微商城?开启微商城之旅

在这个数字化时代&#xff0c;微商城的出现为商家提供了一个全新的机会&#xff0c;商家企业可以通过微商城来展示和销售自己的产品。而对于一些商家而言&#xff0c;不知道怎么注册微商城。下面给大家做一个简单的分享。 第一步&#xff1a;选择合适的微商城搭建工具 在注册…

移动通信系统关键技术多址接入OFDM学习(7)

1.OFDM是一种多载波传输方案&#xff0c;可以将高速串行传输转换为低速并行传输&#xff0c;增加符号持续时间&#xff0c;抗多径干扰能力强。 串行和并行有着不同的比特持续时间&#xff0c;同时拥有相同的数据速率。因此&#xff0c;虽然OFDM将串行信号转换为并行信号&#…

【好书推荐-第四期】《Go专家编程(第2版)》华为资深技术专家力作,第1版评分9.4,适合Go程序员面试

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection(CVPR2023)

文章目录 -Abstract & Conclusion现存问题解决方法结论 -问题方法Overviewaha&#xff0c;our work Dynamic PriorCoarse Prior MatchingFiner Dynamic Posterior Matching hh 源代码 - 该论文作者此前提出了RFLA&#xff0c;一种基于高斯接受场的标签分配策略 动态先验&a…

使用HTTP/2在Linux上的Nginx服务器进行优化

随着互联网的发展&#xff0c;HTTP/2协议逐渐成为主流。与传统的HTTP/1.1相比&#xff0c;HTTP/2提供了更高的传输效率和更好的安全性。在Linux上使用Nginx服务器进行优化&#xff0c;我们可以充分利用HTTP/2的优势&#xff0c;提高网站的性能和用户体验。 1. 安装Nginx并启用…

tessreact训练字库

tessreact主要用于字符识别&#xff0c;除了使用软件自带的中英文识别库&#xff0c;还可以使用Tesseract OCR训练属于自己的字库。 一、软件环境搭建 使用Tesseract OCR训练自己的字库&#xff0c;需要安装Tesseract OCR和jTessBoxEditor(配套训练工具)。jTessBoxEditor需要…

[ACM 学习] 最长上升子序列

LIS&#xff08;最长上升子序列&#xff09;的三种经典求法 - 一只不咕鸟 - 博客园 (cnblogs.com) 理解一下第三种方法&#xff08;贪心二分查找&#xff09; 因为构建的是上升子序列&#xff0c;所以是可以用二分查找找到最大的小于当前 A[i] 的在子序列中的 F[j]&#xff0…

【数据结构和算法】奇偶链表

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;分离节点后合并 三、代码 3.1 方法一&#xff1a;分离节点后合并 四、复杂度分…

CC工具箱使用指南:【提取特定文字】

一、简介 有时候我们会遇到一些混杂着各种中文、英文、数字、特殊符号的文字&#xff0c;需要对其进行提纯&#xff0c;如下图所示&#xff1a; 或者做规划的人应该做过一件事&#xff0c;从CAD测绘图中可以读取到类似【混3】、【砖2】的文字&#xff0c;如果想要从中提取出层…

Linux反向、分离解析与主从复制

前言 上篇介绍了DNS正向解析&#xff0c;本文将继续介绍反向解析与主从复制等内容。域名反向解析即从IP地址到域名的映射。为了完成逆向域名解析&#xff0c;系统提供一个特别域&#xff0c;该特别域称为逆向解析域。 目录 前言 一、反向解析 1. 配置bind服务 2. 修改区…

2024年甘肃省职业院校技能大赛信息安全管理与评估 样题一 理论题

竞赛需要完成三个阶段的任务&#xff0c;分别完成三个模块&#xff0c;总分共计 1000分。三个模块内容和分值分别是&#xff1a; 1.第一阶段&#xff1a;模块一 网络平台搭建与设备安全防护&#xff08;180 分钟&#xff0c;300 分&#xff09;。 2.第二阶段&#xff1a;模块二…

《江苏联通数据安全体系建设》入选“星河”优秀案例

近日&#xff0c;国家信息通信研究院和中国通信标准化协会大数据技术标准推进委员会&#xff08;CCSA TC601&#xff09;共同举办的第七届大数据“星河(Galaxy)”案例征集活动结果公布&#xff0c;江苏联通与天空卫士联合申报的《江苏联通数据安全体系建设》案例&#xff0c;被…

基于springboot的疫情物资捐赠和分配系统

&#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;一 、设计说明 1.1 课题背景 二…

vtk9.3 + Visual Studio2019 + Cmake3.28 win11 上的环境安装(这个过程网上比较多,自己记录下过程加深下印象)

开始 介绍 欢迎来到 VTK&#xff01;我们建议您首先阅读《VTK book》&#xff0c;这是一本全面的 VTK 指南&#xff0c;涵盖了其功能的所有方面。此外&#xff0c;您可能会发现探索 VTK 示例很有帮助&#xff0c;这是一组有用的参考资料&#xff0c;演示了如何使用 VTK 的不同模…