当前位置: 首页 > news >正文

Zynq开发实践(FPGA之流水线和冻结)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        谈到fpga相比较cpu的优势,很多时候我们都会谈到数据并发、边接收边处理、流水线这三个方面。所以,第三个优势,也就是流水线的概念,对大家来说其实并不陌生。而且大家如果学的是计算机科学与技术专业,那么肯定会学过计算机组成原理或者是计算机体系结构这些课程,里面谈到cpu设计的时候,也会涉及到流水线的概念。

1、流水线基础

        cpu的流水线其实是比较直观的。如果是单周期cpu,那么就相当于一个状态机了,任何时候就只有一个指令在处理。但是如果cpu是多周期,那么意味着任何一个周期内可能有几条指令在处理。之所以会这样,是因为采用了流水线的概念。假设cpu的处理分成了三个阶段,分别是取值、译码和执行。那么最理想的情况,就是同一时刻有三条指令在处理,一条在取指阶段,一条在译码阶段,一条在执行阶段。

2、流水线的注意事项

        如前面所说,流水线分的越细,就意味着单位时间内的吞吐量就越多。还是以cpu为例,如果cpu只是单周期处理,那么一个周期内只能有一条指令在处理,而流水线的思路可以让我们同时处理多条指令。因此,在设计流水线的时候,一个很重要的原则,就是不同阶段之间的时间尽可能等同。这样才不会出现木桶效应。

        所谓木桶效应,就是如果一个阶段的处理时间过长,那么其他阶段都要逼迫等待这个阶段完成。鉴于这个原因,我们也看到cpu的流水线越来越长,从三级流水线、五级流水线,到七级流水线、九级流水线、十一级流水线。整体上流水线的长度越长,效率会越来越高,不过复杂度也是越来越复杂。

3、流水线冻结

        流水线冻结是经常发生的现象。还是以cpu为例,假设cpu某一个阶段的处理突然需要花很多花很多的时间,例如除法、浮点、访存等等,这个时候就会产生流水线冻结。冻结的时候,除了这个阶段的指令还在处理,其他阶段的指令处理都被冻结了,这就是流水线冻结。等到那个阶段的所有工作都处理好了,流水线重新开始流动。

4、举例说明

        为了说明流水线处理的基本原理,我们首先写一个简单的数据处理过程,流程很简单,

always@(posedge clk or negedge rst)if(!rst) begindata1 <= 4'h0;data2 <= 4'h0;data3 <= 4'h0;endelse if(!freeze) begindata1 <= in_data;data2 <= data1;data3 <= data2;end

        首先,data1、data2、data3初始化为0。只要流水线没有freeze,整个数据传输的过程就会这样一直走下去。那么流水线什么时候freeze呢?

always@(posedge clk or negedge rst)if(!rst)hang <= 1'b0;else if(hang)hang <= 1'b0; // freeze one clockelse if(data1[0] && !hang)hang <= 1'b1; // only freeze in first clockassign freeze = data1[0] & !hang;

        这里freeze是一个wire信号,它取决于两点,第一点当前data1是不是奇数,第二点是确认hang是不是0,即当前是不是已经处于hang状态。hang的时间可以很长,比如是2个clock、3个clock,或者是等待某个事件发生等等。

        这里需要注意下hang要比freeze晚处理,并且hang恢复为0的操作要放在前面,这样处理的优先级才比较高。当然这里的freeze不仅仅要在这里处理,还得把它送给数据输入端,这样才能从源头控制好输入,防止数据丢失。

always@(posedge clk or negedge rst)if(!rst)num <= 4'h0;else if(!freeze) beginif(num == 4'h9)num <= 4'h0;elsenum <= num + 1;end

        完成了freeze生成、hang的生成和恢复、freeze发送给数据输入端这几个动作,整个处理就算是基本告一段落。

5、验证和测试

        开发的时候,如果verilog代码过多,可以切分到不同的module里面,这样也比较简单一点,

module pipeline_top(input clk,input rst,output led);wire[3:0] num;	
wire freeze;trigger trigger(.clk(clk),.rst(rst),.freeze(freeze),.num(num));pipeline pipeline(.clk(clk),.rst(rst),.in_data(num),.freeze(freeze),.led(led));endmodule

        有了top文件之后,接下来就是写好testbench文件,准备开始生成波形,

`timescale 1ns/1ps
module test();reg rst;
reg clk;
wire out;initialbeginrst = 1;clk = 0;#12 rst = 0;#21 rst = 1;#1000 $finish;endinitial
beginwhile(1)clk = #5 !clk;
endpipeline_top pipeline_top(.rst(rst),.clk(clk),.led(out));initial
begin$dumpfile("hello.vcd");$dumpvars(0, test);
endendmodule

        不出意外的话,就可以看到对应的波形。验证的时候,没有必要导入所有的信号。一方面信号比较多,很多信号是重复的,比如clock、rst,还有wire信号;另外一方面信号多了,都放在一起也不容易分析。所以选取一个module为主,其他需要的信号拖过来即可。稍微调整下顺序,就可以一个、一个去分析了,

http://www.dtcms.com/a/363026.html

相关文章:

  • FPGA入门-分频器
  • 【Python - 基础 - 工具】解决pycharm“No Python interpreter configured for the project”问题
  • 【踩坑随笔】VScode+ESP-IDF头文件标红但能正常运行
  • 广播电视制作领域,什么是SMPTE标准?
  • vscode使用black对python代码进行格式化
  • 2025年了,学C#上位机需要什么条件
  • Day33 网络编程:OSI/TCP/IP模型、协议族与UDP编程
  • 虚拟继承:破解菱形继承之谜
  • Redis核心数据类型解析——string篇
  • Linux驱动开发学习笔记
  • 【C++框架#1】gflags 和 gtest 安装使用
  • 情况三:已经 add ,并且也 commit 了
  • 10 51单片机之DS1302实时时钟
  • 2025 年普通人还可以期待 NFT 交易市场吗?
  • 第四届可再生能源与电气科技国际学术会议(ICREET 2025)
  • 【数学建模学习笔记】时间序列分析:LSTM
  • 碳酸钆:稀土家族里看不见的科技推手
  • Sentinel vs Resilience4j vs Bucket4j:分布式限流方案对比与实战
  • [re_2] rpc|http|nginx|protobuf|
  • 腾讯云上有性能比较强的英伟达GPU
  • Java集合源码解析之ArrayList
  • DELPHI 利用OpenSSL实现加解密,证书(X.509)等功能
  • PFLOTRAN 模拟多相、多组分、反应性流动与传输过程的高性能并行数值模拟软件
  • spring boot驴友结伴游网站的设计与实现(代码+数据库+LW)
  • 深入分析 json2(新)与标准的 jsonrpc的区别
  • Maven + JUnit:Java单元测试的坚实组合
  • Qt6实现绘图工具:12种绘图工具全家桶!这个项目满足全部2D场景
  • 机器学习 - Kaggle项目实践(7)NLP with Disaster Tweets 灾难消息
  • WPF迁移avalonia之图像处理(一)
  • STM32HAL 快速入门(十六):UART 协议 —— 异步串行通信的底层逻辑