fifo_rd_ctrl

模块描述

读地址控制逻辑,用于产生读指针和读空信号

参数说明

parameters of fifo_rd_ctrl
parameter                           FIFO_ADDR_WD    =   3   ;
  • FIFO_ADDR_WD : FIFO地址位所需的最大位宽(与深度相对应)

I/O端口及变量说明

I/O ports & variables of fifo_rd_ctrl
input                               rd_clk          ;
input                               rd_rstn         ;
input                               rd_en_i         ;
output                              rd_empty_o      ;
output [FIFO_ADDR_WD    -1:0]       rd_ptr_o        ;   // read pointer, use gray-code
input  [FIFO_ADDR_WD    -1:0]       wr_ptr_sync_i   ;   // write pointer (sync), use gray-code

reg                                 rd_empty_o      ;
reg    [FIFO_ADDR_WD    -1:0]       rd_ptr_o        ;
reg    [FIFO_ADDR_WD    -1:0]       rd_ptr_next     ;

端口名称

端口类型

描述

具体说明

rd_clk

输入

读时钟

-

rd_rstn

输入

读时钟域的异步复位信号

-

rd_en_i

输入

读使能信号(与读时钟同步)

其有效且未读空时,从FIFO中读出数据到rd_dat_o并令读地址+1

rd_empty_o

输出

读空标志信号

由读指针和同步到读时钟域的写指针决定,若读指针追上写指针,则表示读空,在有新数据被写入前不允许继续读取数据

rd_ptr_o

输出

读指针

指向FIFO中下一个待读取的数据,编码方式为格雷码

wr_ptr_sync_i

输入

同步到读时钟域的写指针

-

变量名称

变量类型

描述

具体说明

rd_empty_o

reg

读空标志信号

-

rd_ptr_o

reg

读指针

-

rd_ptr_next

reg

下一个读指针

-

工作时序

  • 上电,完成读指针复位操作

  • 当读使能信号rd_en_i有效且读空标志位rd_empty_o无效(未读空)时,将读指针+1(指向下一个待读出位置)

  • 在完成一次读出(读指针发生变化)或者同步过来的写指针wr_ptr_sync_r发生变化后,比较当前读指针的地址与同步过来的写指针的地址

    • 若二者相等,意味着读指针已经追上写指针(滞后的),此时不可继续读FIFO数据,读空标志位置1(读空有效)

    • 若二者不相等,意味着读指针未追上写指针(滞后的),允许读出FIFO数据,读空标志位置0(读空无效)

RTL代码

fifo_rd_ctrl.v
 1module fifo_rd_ctrl(
 2   rd_clk          ,
 3   rd_rstn         ,
 4   rd_en_i         ,
 5   rd_empty_o      ,
 6   rd_ptr_o        ,
 7   wr_ptr_sync_i
 8);
 9
10   parameter                           FIFO_ADDR_WD    =   3   ;
11
12   input                               rd_clk          ;
13   input                               rd_rstn         ;
14   input                               rd_en_i         ;
15   output                              rd_empty_o      ;
16   output [FIFO_ADDR_WD    -1:0]       rd_ptr_o        ;   // read pointer, use gray-code
17   input  [FIFO_ADDR_WD    -1:0]       wr_ptr_sync_i   ;   // write pointer (sync), use gray-code
18
19   reg                                 rd_empty_o      ;
20   reg    [FIFO_ADDR_WD    -1:0]       rd_ptr_o        ;
21   reg    [FIFO_ADDR_WD    -1:0]       rd_ptr_next     ;
22
23   always@(*) begin
24      case(rd_ptr_o)
25            3'b000:     rd_ptr_next = 3'b001;
26            3'b001:     rd_ptr_next = 3'b011;
27            3'b011:     rd_ptr_next = 3'b010;
28            3'b010:     rd_ptr_next = 3'b110;
29            3'b110:     rd_ptr_next = 3'b111;
30            3'b111:     rd_ptr_next = 3'b101;
31            3'b101:     rd_ptr_next = 3'b100;
32            3'b100:     rd_ptr_next = 3'b000;
33      endcase
34   end
35   always@(*) begin
36      if      (rd_ptr_o == wr_ptr_sync_i) begin
37            rd_empty_o <= 1'b1;
38      end
39      else if (rd_ptr_o != wr_ptr_sync_i) begin
40            rd_empty_o <= 1'b0;
41      end
42   end
43
44   always@(posedge rd_clk or negedge rd_rstn) begin
45      if(~rd_rstn) begin
46            rd_ptr_o <= 3'b000;
47      end
48      else begin
49            if((rd_en_i == 1'b1) && (rd_empty_o == 1'b0)) begin
50               rd_ptr_o <= rd_ptr_next;
51            end
52      end
53   end
54
55endmodule

链接到

父模块

其他上层模块