同步FIFO代码
`define BUF_WIDTH 4 //地址宽度为3+1,`define BUF_SIZE 8 //数据个数,FIFO深度
module fifo_counter( clk,rst_n,buf_in,buf_out,wr_en,rd_en,buf_empty,buf_full,fifo_cnt);
input clk,rst_n;
input wr_en,rd_en;
input buf_in; // data input to be pushed to buffer
output reg buf_out; // port to output the data using pop.
output wire buf_empty,buf_full;// buffer empty and full indication
output reg [`BUF_WIDTH-1:0] fifo_cnt;// number of data pushed in to buffer
//写入数据等于8时,满
reg [`BUF_WIDTH-2:0] rd_ptr,wr_ptr;//这个很重要,数据指针3位宽度,0-7索引,8个数据深度,循环指针0-7-0-7
reg buf_mem;
//判断空满
assign buf_empty = (fifo_cnt == 0);//buf_empty若是reg类型则错,不能使用assign持续赋值
assign buf_full= (fifo_cnt == `BUF_SIZE);
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
fifo_cnt <= 0;
else if((!buf_full&&wr_en)&&(!buf_empty&&rd_en)) //同时读写,数量不变
fifo_cnt <= fifo_cnt;
else if(!buf_full && wr_en) //写数据
fifo_cnt <= fifo_cnt + 1;
else if(!buf_empty && rd_en) //读数据
fifo_cnt <= fifo_cnt-1;
else
fifo_cnt <= fifo_cnt;
end
always @(posedge clk or negedge rst_n) begin //读数据
if(!rst_n)
buf_out <= 0;
if(rd_en && !buf_empty)
buf_out <= buf_mem;
end
always @(posedge clk) begin
if(wr_en && !buf_full)
buf_mem <= buf_in;
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wr_ptr <= 0;
rd_ptr <= 0;
end
else begin
if(!buf_full && wr_en)
wr_ptr <= wr_ptr + 1;
if(!buf_empty && rd_en)
rd_ptr <= rd_ptr + 1;
end
end
endmodule
使用Modelsim仿真的程序:
`define BUF_WIDTH 4 //地址宽度为3+1,
`define BUF_SIZE (8) //数据个数,FIFO深度
module tb_fifo_counter;
reg clk,rst_n;
reg wr_en,rd_en;
reg buf_in; // data input to be pushed to buffer
wire buf_out; // port to output the data using pop.
wire buf_empty,buf_full;// buffer empty and full indication
wire [`BUF_WIDTH-1:0] fifo_cnt;// number of data pushed in to buffer
fifo_counter dut(clk,rst_n,buf_in,buf_out,wr_en,rd_en,buf_empty,buf_full,fifo_cnt);
always #10 clk = ~clk;
reg tempdata = 0;
initial begin
clk = 0;
rst_n = 0;
wr_en = 0;
rd_en = 0;
buf_in = 0;
#15;
rst_n = 1;
push(1);
fork
push(2);
pop(tempdata);
join //push and pop together
push(10);
push(20);
push(30);
push(40);
push(50);
push(60);
push(70);
push(80);
push(90);
push(100);
push(110);
push(120);
push(130);
pop(tempdata);
push(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
push(140);
pop(tempdata);
push(tempdata);//
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
push(5);
pop(tempdata);
end
task push (input data);
if(buf_full)
$display("---Cannot push %d: Buffer Full---",data);
else begin
$display("Push",,data);
buf_in = data;
wr_en = 1;
@(posedge clk);
#5 wr_en = 0;
end
endtask
task pop(output data);
if(buf_empty)
$display("---Cannot Pop: Buffer Empty---");
else begin
rd_en = 1;
@(posedge clk);
#3 rd_en = 0;
data = buf_out;
$display("------Poped:",,data);
end
endtask
endmodule
程序仿真打印结果:
# Push 1
# Push 2
# ------Poped: 1
# Push10
# Push20
# Push30
# Push40
# Push50
# Push60
# Push70
# ---Cannot push80: Buffer Full---
# ---Cannot push90: Buffer Full---
# ---Cannot push 100: Buffer Full---
# ---Cannot push 110: Buffer Full---
# ---Cannot push 120: Buffer Full---
# ---Cannot push 130: Buffer Full---
# ------Poped: 2
# Push 2
# ------Poped:10
# ------Poped:20
# ------Poped:30
# ------Poped:40
# Push 140
# ------Poped:50
# Push50
# ------Poped:60
# ------Poped:70
# ------Poped: 2
# ------Poped: 140
# ------Poped:50
# ---Cannot Pop: Buffer Empty---
# ---Cannot Pop: Buffer Empty---
# ---Cannot Pop: Buffer Empty---
# ---Cannot Pop: Buffer Empty---
# ---Cannot Pop: Buffer Empty---
# ---Cannot Pop: Buffer Empty---
# Push 5
# ------Poped: 5 同步FIFO代码
页:
[1]