两种fifo实现方式的差异

news/2024/7/5 3:07:33

减少数据通路翻转来降低功耗:
以FIFO (当容量较小而使用寄存器作为存储部分)设计为例,虽然理论上可以使用比较简单的数据表项逐次移位的方式,实现FIFO 的先入先出功能,但是却应该使用维护读写指针的方式(数据表项寄存器则不用移位)实现先入先出的功能。因为数据表项逐次移位的方式会造成寄存器的大量翻转,相比而言,使用读写指针的方式实现则保持了表项寄存器中的值静止不动,从而大幅减少动态功耗,因此应该优先采用此方法。

数据表项逐次移位方式:

数据存储在数组中,通过逐次移位的方式实现数据的入队和出队操作。
入队操作时,将新数据写入队尾,并将队尾指针指向下一个位置。
出队操作时,读取队首的数据,并将队首指针指向下一个位置。
这种方式下,数据表项的顺序是按照入队的顺序依次排列的,即新数据会覆盖掉旧数据。

module fifo (
  input clk,
  input reset,
  input [DATA_WIDTH-1:0] data_in,
  input push,
  input pop,
  output reg [DATA_WIDTH-1:0] data_out,
  output reg full,
  output reg empty
);

  parameter DATA_WIDTH = 8;  // 数据宽度
  parameter DEPTH = 16;      // FIFO深度

  reg [DATA_WIDTH-1:0] buffer [DEPTH-1:0];  // FIFO缓冲区
  reg [4:0] head_ptr;   // 指向队首的指针
  reg [4:0] tail_ptr;   // 指向队尾的指针
  reg [4:0] count;      // 当前队列中的数据项数量

  always @(posedge clk or posedge reset) begin
    if (reset) begin
      data_out <= 0;
      full <= 0;
      empty <= 1;
      head_ptr <= 0;
      tail_ptr <= 0;
      count <= 0;
    end else begin
      // 入队操作
      if (push && !full) begin
        buffer[tail_ptr] <= data_in;
        tail_ptr <= tail_ptr + 1;
        count <= count + 1;
      end

      // 出队操作
      if (pop && !empty) begin
        data_out <= buffer[head_ptr];
        head_ptr <= head_ptr + 1;
        count <= count - 1;
      end

      // 更新队列状态
      full <= (count == DEPTH);
      empty <= (count == 0);
    end
  end

endmodule

在上述Verilog代码中,定义了一个fifo模块,该模块包含了输入和输出信号,以及FIFO缓冲区和相关指针等变量。在时钟上升沿或复位事件发生时,根据不同的条件进行入队和出队操作。push信号表示入队操作,在FIFO非满的情况下,将数据写入队尾,并更新队尾指针和数据项数量。pop信号表示出队操作,在FIFO非空的情况下,读取队首的数据,更新队首指针和数据项数量。

维护读写指针的方式:

数据存储仍然使用数组,但不再需要逐次移位。
入队操作时,将新数据写入当前队尾指针所指向的位置,并更新队尾指针为下一个位置。
出队操作时,读取当前队首指针所指向的数据,并更新队首指针为下一个位置。
队首指针和队尾指针通过取模运算来循环更新,确保在达到深度上限时能够回到初始位置。
这种方式下,数据表项的顺序与入队的顺序相同,不会发生顺序覆盖。

module fifo (
  input clk,
  input reset,
  input [DATA_WIDTH-1:0] data_in,
  input push,
  input pop,
  output reg [DATA_WIDTH-1:0] data_out,
  output reg full,
  output reg empty
);

  parameter DATA_WIDTH = 8;  // 数据宽度
  parameter DEPTH = 16;      // FIFO深度

  reg [DATA_WIDTH-1:0] buffer [DEPTH-1:0];  // FIFO缓冲区
  reg [4:0] head_ptr;   // 指向队首的指针
  reg [4:0] tail_ptr;   // 指向队尾的指针
  reg [4:0] count;      // 当前队列中的数据项数量

  always @(posedge clk or posedge reset) begin
    if (reset) begin
      data_out <= 0;
      full <= 0;
      empty <= 1;
      head_ptr <= 0;
      tail_ptr <= 0;
      count <= 0;
    end else begin
      // 入队操作
      if (push && !full) begin
        buffer[tail_ptr] <= data_in;
        tail_ptr <= (tail_ptr + 1) % DEPTH;
        count <= count + 1;
      end

      // 出队操作
      if (pop && !empty) begin
        data_out <= buffer[head_ptr];
        head_ptr <= (head_ptr + 1) % DEPTH;
        count <= count - 1;
      end

      // 更新队列状态
      full <= (count == DEPTH);
      empty <= (count == 0);
    end
  end

endmodule

http://lihuaxi.xjx100.cn/news/1576388.html

相关文章

LCR 012.寻找数组的中心下标

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCR 012. 寻找数组的中心下标 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 获取第一个元素左边的元素 leftSum 和 右边的元素和 rightSum&#xff0c;按序遍历数组的同时不断更新 leftSu…

Selenium —— 网页frame与多窗口处理!

一、多窗口处理. 1.1、多窗口简介 点击某些链接&#xff0c;会重新打开⼀个窗⼜&#xff0c;对于这种情况&#xff0c;想在新页⾯上操作&#xff0c;就 得先切换窗⼜了。 获取窗⼜的唯⼀标识⽤句柄表⽰&#xff0c;所以只需要切换句柄&#xff0c;就可以在多个页⾯灵 活操作了…

机器学习---冷启动(Cold Start)、热启动(Warm Start)问题

在机器学习和推荐系统领域&#xff0c;“冷启动”&#xff08;Cold Start&#xff09;和"热启动"&#xff08;Warm Start&#xff09;是两个常用的概念&#xff0c;它们用来描述不同阶段或情境下的推荐问题。 冷启动&#xff08;Cold Start&#xff09;&#xff1a; …

【文献】TOF标定 Time-of-Flight Sensor Calibration for a Color and Depth Camera Pair

文章目录 Article info.Introduction处理TOF误差Take home messagesResourcesIDEAS Article info. Time-of-Flight Sensor Calibration for a Color and Depth Camera Pair IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 37, NO. 7, JULY 2015 Intr…

线性代数+分治:446E

https://codeforces.com/problemset/problem/446/E 把官方题解翻译了一遍 考虑暴力&#xff0c;肯定想到dp&#xff0c;然后变成矩阵。设用代替 &#xff08;这样子数之间的差值不会变化&#xff0c;但对于问题的处理能方便很多&#xff09; 我们先令&#xff08;也就是初始…

【RK3588】Firefly 瑞芯微板子入门知识、和环境篇

公司买了块瑞芯微的移动开发板&#xff0c;准备将公司的主营业务的AI模型&#xff0c;从服务器主机&#xff0c;移动到开发板上面。所以&#xff0c;就选择了瑞芯微的RK3588的板子。 从目前市面上出现的板子来看&#xff0c;主要的还是以瑞芯微的板子为主&#xff0c;比如鸣辰…

生信教程:使用全基因组SNP数据进行ABBA-BABA分析

动动发财的小手&#xff0c;点个赞吧&#xff01; 简介 ABBA BABA 统计&#xff08;也称为“D 统计”&#xff09;为偏离严格的分叉进化历史提供了简单而有力的测试。因此&#xff0c;它们经常用于使用基因组规模的 SNP 数据&#xff08;例如来自全基因组测序或 RADseq&#xf…

深度分页优化

在我理解中深度分页的解决方案有两种?其实没有什么完美的方案&#xff0c;根据具体场景选择合适的即可 1.游标查询&#xff0c;请移步到我的文章游标查询的使用场景-CSDN博客 2.覆盖索引子查询 就是先分页查询出主键id&#xff0c;然后再in(id)即可 select *from student …