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