1.本节目的:①创建FIFO的IP核②用FIFO实现16位数据输入转8位数据输出。
2.首先,创建FIFO的IP核,在quartus新建工程后,在右方的IP Catalog中搜索 FIFO。
然后点击FIFO,命名后选择Verilog文件类型,点击ok。
跳出FIFO的建立界面如下:
点击next后:
点击next后:
点击next后:
之后一直点next即可,最后finish,完成IP核的创建,我们会得到重要的文件就是fifo的.v(文件名为一开始的命名)。
3.根据要求建立好FIFO后,调用FIFO即可完成设计,以下是设计代码:
module fifo_16to8
(
clk_w,
clk_r,
rst_n,
data_in,
data_in_vld,
data_out,
data_out_vld,
ready
);
input clk_w; //写时钟
input clk_r; //读时钟
input rst_n; //低电平复位
input [16-1:0] data_in; //16位数据输入
input data_in_vld; //输入有效信号
input ready; //准备信号 区分忙闲 由别的模块发送过来 1为闲 0为忙
output data_out; //8位输出
output data_out_vld; //输出有效信号
reg data_out_vld;
reg [8-1:0] data_out;
reg w_en;
wire r_en;
wire [8-1:0] q;
wire [5:0] wrusedw;
wire rdempty;
reg cnt;
wire add_cnt;
wire end_cnt;
//FIFO的深度为64,因此到60的时候就不要写进去数据了,让写使能为0
//深度没到60是,输入有效就给读使能
always @(*)begin
if(wrusedw >= 60)begin
w_en = 0;
end
else begin
w_en = data_in_vld;
end
end
//送出两个数据,读一次fifo,以此用到计数器
//开始条件:空闲(ready)且有数据时(rdempty == 0)
//计数两次,输送两次
always @(posedge clk_r or negedge rst_n)begin
if(!rst_n)begin
cnt <= 0;
end
else if(add_cnt)begin
if(end_cnt)
cnt <= 0;
else
cnt <= cnt + 1;
end
end
assign add_cnt = ready && rdempty == 0 ;
assign end_cnt = add_cnt && cnt== 2-1 ;
assign r_en = end_cnt; //读使能和输出对齐,送完两次数据,打开读使能
always @(posedge clk_r or negedge rst_n)begin
if(rst_n==1'b0)begin
data_out <= 0;
end
else begin
data_out <= q[15-8*cnt -: 8]; //从15-8*cnt这一位,往下数8位,给到data_out
end
end
always @(posedge clk_r or negedge rst_n)begin
if(rst_n==1'b0)begin
data_out_vld <= 0;
end
else begin
data_out_vld <= add_cnt; //要输出两次,因此和add_cnt对齐
end
end
//例化fifo
fifo_ip u_fifo
(
.aclr (~rst_n),
.data (data_in),
.rdclk (clk_r),
.rdreq (r_en),
.wrclk (clk_w),
.wrreq (w_en),
.q (q),
.rdempty (rdempty),
.rdusedw (),
.wrempty (wrempty),
.wrusedw (wrusedw)
);
endmodule
RTL图如下: