同步fifo,ram8*16,
地址位扩展一位判断空满。
RTL:
module sync_fifo_addr(
clk, //时钟
rst_n, //复位
wr_en, //写使能
rd_en, //读使能
data_in, //写数据
empty, //空标志
full, //满标志
data_out //读数据
);
parameter RAM_WIDTH = 8; //RAM的宽度,即存储数据的位宽8bits
parameter RAM_DEPTH = 16; //RAM的深度,即存储16个数据,16个bytes
parameter ADDR_WIDTH = 4; //RAM的地址线宽度,存放16位数据,需要地址位4位
input clk; //时钟
input rst_n; //复位
input wr_en; //写使能
input rd_en; //读使能
input [RAM_WIDTH-1:0] data_in; //写数据
output empty; //空标志
output full; //满标志
output reg [RAM_WIDTH-1:0] data_out; //读数据
reg [RAM_WIDTH-1:0] mem[RAM_DEPTH-1:0]; //[7:0]mem[15:0],16*8ram
wire [ADDR_WIDTH-1:0]w_addr; //地址线是wire型变量
wire [ADDR_WIDTH-1:0]r_addr;
reg [ADDR_WIDTH:0] w_addr_a;
reg [ADDR_WIDTH:0] r_addr_a; //扩展地址位,判断空满,被赋值所以定义为reg
assign r_addr=r_addr_a[ADDR_WIDTH-1:0]; //二者地址位低四位相同
assign w_addr=w_addr_a[ADDR_WIDTH-1:0];
always@(posedge clk or negedge rst_n) //读数据
begin
if(!rst_n)
begin
r_addr_a<=5'b0; //读地址清零
end
else
begin
if(rd_en==1 && empty==0) //读使能为1且不为空
begin
data_out<=mem[r_addr];
r_addr_a<=r_addr_a+1;
end
end
end
always@(posedge clk or negedge rst_n) //写数据
begin
if(!rst_n)
begin
w_addr_a<=5'b0; //写地址清零
end
else
begin
if(wr_en==1 && full==0) //写使能为1且不为满
begin
mem[w_addr]<=data_in;
w_addr_a<=w_addr_a+1;
end
end
end
//判断空满标志
assign empty = (r_addr_a==w_addr_a)?1:0; //空:读写地址扩展位相等
assign full =(r_addr_a[ADDR_WIDTH]!=w_addr_a[ADDR_WIDTH]&&r_addr_a[ADDR_WIDTH-1:0]==w_addr_a[ADDR_WIDTH-1:0])?1:0;//满:读写地址扩展位最高位相反,低位相同
endmodule
Testbench:
`timescale 1ns/1ns
module tb_sync_fifo_addr();
reg clk;
reg rst_n;
reg wr_en;
reg rd_en;
reg [7:0] data_in;
wire empty;
wire full;
wire [7:0] data_out;
always #10 clk = ~clk;
initial begin
clk = 0;
rst_n = 0;
#40 rst_n = 1;
wait (rst_n);
@(posedge clk)
begin
wr_en <= 1;
rd_en <= 0;
data_in <= 8'b00000000;//data_in赋初值
end
repeat(16)begin
@(posedge clk) data_in <= {$random}%256;//生成16个随机8bit数据
end
#40
wr_en <= 0; //begin end 语句块内部顺序执行
rd_en <= 1;
#400 //读数据拉高20个时钟周期后停止,读16个数据需要320ns
$finish;
end
sync_fifo_addr inst_sync_fifo_addr
(
.clk (clk),
.rst_n (rst_n),
.wr_en (wr_en),
.rd_en (rd_en),
.data_in (data_in),
.empty (empty),
.full (full),
.data_out (data_out)
);
endmodule
modelsim仿真: