fifo_wr_ctrl

模块描述

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

参数说明

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

I/O端口及变量说明

I/O ports & variables of fifo_wr_ctrl
input                               wr_clk          ;
input                               wr_rstn         ;
input                               wr_en_i         ;
output                              wr_full_o       ;
output [FIFO_ADDR_WD    -1:0]       wr_ptr_o        ;   // write pointer, use gray-code
input  [FIFO_ADDR_WD    -1:0]       rd_ptr_sync_i   ;   // read pointer (sync), use gray-code

reg                                 wr_full_o       ;
reg    [FIFO_ADDR_WD    -1:0]       wr_ptr_o        ;
reg    [FIFO_ADDR_WD    -1:0]       wr_ptr_next     ;

端口名称

端口类型

描述

具体说明

wr_clk

输入

写时钟

-

wr_rstn

输入

写时钟域的异步复位信号

-

wr_en_i

输入

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

其有效且未写满时,向FIFO中写入待写入数据并令写地址+1

wr_full_o

输出

写满标志信号

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

wr_ptr_o

输出

写指针

指向FIFO中下一个待写入数据的位置,编码方式为格雷码

rd_ptr_sync_i

输入

同步到写时钟域的读指针

-

变量名称

变量类型

描述

具体说明

wr_full_o

reg

写满标志信号

-

wr_ptr_o

reg

写指针

-

wr_ptr_next

reg

下一个写指针

-

工作时序

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

  • 当写使能信号wr_en_i有效且写满标志位wr_full_o无效(未写满)时,将写指针+1(指向下一个待写入位置)

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

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

    • 若二者不相等,意味着写指针未再次追上读指针(滞后的),允许写入,写满标志位置0(写满无效)

RTL代码

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

链接到

父模块

其他上层模块