同步FIFO
引言
同步FIFO在数据缓冲中起到重要作用。相比于异步FIFO而言,同步FIFO结构更简单,是单个时钟域下的同步电路。
下文主要介绍同步FIFO的rtl设计。
RTL代码
端口
输入时钟,复位,8位数据,写使能读使能。
输出8位数据,空满标志。
内部变量
包括一个存储变量ram位宽为8(ram变量名前的[7:0]),深度为8(ram变量名后的[7:0])。
读写指针wrptr rdptr,用于标志读写ram的地址。
计数变量cnt用于产生空满标志,注意这里对于深度为8的ram,位宽为3最多记到十进制数字7,但是wrptr指代下一个写入的地址,当对满信号进行判断时是判断cnt是否达到8,因此必须要4位的计数器。
整数i用于后续的ram初始化。
空满标志
计数器记到8代表写满,计数器为0时表示读空。
计数器
第一个逻辑判断是同时读写且FIFO处在非满和非空状态时,cnt保持不变。
第二个逻辑判断是写,计数器加一。
第三个逻辑判断是读,计数器减一。
读写指针
写指针当写使能有效且非满状态时,地址加一。当写指针为7,也就是写满时,下一个要写的地址跳转回0地址。读指针同理。
RAM读写
ram的初始化这里使用for循环,因为存储类变量不能操作单独的位,需要对每一行存储单元(每一行位宽为8)进行初始化,因此使用逻辑复制操作。
TestBench文件
1 `timescale 1ns/1ps 2 module tb_syncfifo(); 3 4 reg clk; 5 reg rst; 6 reg [7:0]data_in; 7 reg wr_en,rd_en; 8 wire [7:0] data_out; 9 wire full,empty; 10 11 initial begin 12 clk=0; 13 rst=0; 14 data_in=0; 15 wr_en=0; 16 rd_en=0; 17 #10 18 rst=1; 19 #10 20 rst=0; 21 end 22 23 always #10 clk = ~clk; 24 25 task gen_data; 26 integer i; 27 begin 28 @(negedge rst); 29 #10; 30 @(posedge clk); 31 for(i=0;i<10;i=i+1)begin 32 wr_en=1; 33 data_in=i[7:0]; 34 if(i>2)begin 35 rd_en=1; 36 end 37 @(posedge clk); 38 end 39 wr_en=0; 40 data_in=0; 41 end 42 endtask 43 44 initial begin 45 gen_data(); 46 end 47 48 syncfifo inst_syncfifo 49 ( 50 .clk (clk), 51 .rst (rst), 52 .data_in (data_in), 53 .wr_en (wr_en), 54 .rd_en (rd_en), 55 .data_out (data_out), 56 .full (full), 57 .empty (empty) 58 ); 59 60 61 62 endmodule
仿真结果