赞
踩
目录
这里我们对框图中的常用信号端口做一下讲解,其他很少用到的信号如果大家感兴趣的话也可以在课后打开 IP 核的数据手册进行学习,各常用端口的功能描述如下:
https://pan.baidu.com/s/1vXxmhg_mZm_OVg4xQeiCVQ 提取码:zdyz
- module fifo_wr(
- //mudule clock
- input wr_clk , // 时钟信号
- input rst_n , // 复位信号
- //FIFO接口
- input wr_rst_busy , // 写复位忙信号
- input empty , // FIFO 空信号
- input almost_full , // FIFO 将满信号
- output reg fifo_wr_en , // FIFO 写使能
- output reg [7:0] fifo_wr_data // 写入 FIFO 的数据
- );
-
- reg empty_d0;
- reg empty_d1;
- //因为 empty信号是和读信号的时钟同步的,对于写始终来说他是异步信号,所以要进行打拍处理
- always@(posedge wr_clk or negedge rst_n)
- if(!rst_n)begin
- empty_d0 <= 0;
- empty_d1 <= 0;
- end
- else begin
- empty_d0 <= empty;
- empty_d1 <= empty_d0;
- end
- //fifo写使能信号赋值,当 FIFO 为空时开始写入,写满后停止写
- always@(posedge wr_clk or negedge rst_n)
- if(!rst_n)
- fifo_wr_en <= 0;
- else if(!wr_rst_busy)begin
- if(empty_d1)
- fifo_wr_en <= 1;
- else if(almost_full)
- fifo_wr_en <= 0;
- else
- fifo_wr_en <= fifo_wr_en;
- end
- else
- fifo_wr_en <= 0;
-
- //对 fifo_wr_data 赋值,0~254
- always@(posedge wr_clk or negedge rst_n)
- if(!rst_n)
- fifo_wr_data <= 0;
- else if(fifo_wr_en && fifo_wr_data < 254)
- fifo_wr_data <= fifo_wr_data + 1;
- else
- fifo_wr_data <= 0;
-
- endmodule
- module fifo_rd(
- //system clock
- input rd_clk , //时钟信号
- input rst_n , //复位信号
- //FIFO接口
- input rd_rst_busy , //读复位忙信号
- input [7:0] fifo_rd_data, //从 FIFO 读出的数据
- input full , //FIFO 满信号
- input almost_empty, //FIFO 将空信号
- output reg fifo_rd_en //FIFO 读使能
- );
-
- reg full_d0;
- reg full_d1;
-
- //因为 full 信号是属于 FIFO 写时钟域的,所以对 full 打两拍同步到读时钟域下
- always@(posedge rd_clk or negedge rst_n)
- if(!rst_n)begin
- full_d0 <= 0;
- full_d1 <= 0;
- end
- else begin
- full_d0 <= full;
- full_d1 <= full_d0;
- end
-
- //对 fifo_rd_en 进行赋值,FIFO 写满之后开始读,读空之后停止读
- always@(posedge rd_clk or negedge rst_n)
- if(!rst_n)
- fifo_rd_en <= 0;
- else if(!rd_rst_busy)begin
- if(full_d1)
- fifo_rd_en <= 1;
- else if(almost_empty)
- fifo_rd_en <= 0;
- end
- else
- fifo_rd_en <= 0;
-
- endmodule
- module ip_fifo(
- input sys_clk,
- input sys_rst_n
- );
-
- wire locked;
- wire clk_50M;
- wire clk_100M;
- wire rst_n;
- wire wr_rst_busy;
- wire empty;
- wire almost_full;
- wire [7 : 0]fifo_wr_data;
- wire rd_rst_busy;
- wire [7 : 0]fifo_rd_data;
- wire fifo_rd_en;
- wire fifo_wr_en;
- wire almost_empty;
- wire [7 : 0]rd_data_count;
- wire [7 : 0]wr_data_count;
- wire full;
-
- //通过系统复位信号和时钟锁定信号来产生一个新的复位信号,代表当输出频率时钟稳定后,且复位完成后才能执行
- assign rst_n = sys_rst_n & locked;
- //例化 PLL IP 核
- clk_wiz_0 clk_wiz_0
- (
- .clk_out1(clk_50M), // output clk_out1
- .clk_out2(clk_100M), // output clk_out2
- .locked(locked), // output locked
- .clk_in1(sys_clk) // input clk_in1
- );
- //例化 FIFO IP 核
- fifo_generator_0 your_instance_name (
- .rst(~rst_n), // input wire rst
- .wr_clk(clk_50M), // input wire wr_clk
- .rd_clk(clk_100M), // input wire rd_clk
- .din(fifo_wr_data), // input wire [7 : 0] din
- .wr_en(fifo_wr_en), // input wire wr_en
- .rd_en(fifo_rd_en), // input wire rd_en
- .dout(fifo_rd_data), // output wire [7 : 0] dout
- .full(full), // output wire full
- .almost_full(almost_full), // output wire almost_full
- .empty(empty), // output wire empty
- .almost_empty(almost_empty), // output wire almost_empty
- .rd_data_count(rd_data_count), // output wire [7 : 0] rd_data_count
- .wr_data_count(wr_data_count), // output wire [7 : 0] wr_data_count
- .wr_rst_busy(wr_rst_busy), // output wire wr_rst_busy
- .rd_rst_busy(rd_rst_busy) // output wire rd_rst_busy
- );
-
-
- //例化写 FIFO 模块
- fifo_wr fifo_wr(
- .wr_clk(clk_50M) , // 时钟信号
- .rst_n(rst_n) , // 复位信号
- .wr_rst_busy(wr_rst_busy) , // 写复位忙信号
- .empty(empty) , // FIFO 空信号
- .almost_full(almost_full) , // FIFO 将满信号
- .fifo_wr_en(fifo_wr_en) ,
- .fifo_wr_data(fifo_wr_data) // 写入 FIFO 的数据
- );
-
- //例化读 FIFO 模块
- fifo_rd fifo_rd(
- .rd_clk (clk_100M) , //时钟信号
- .rst_n (rst_n) , //复位信号
- .rd_rst_busy (rd_rst_busy) , //读复位忙信号
- .fifo_rd_data (fifo_rd_data) , //从 FIFO 读出的数据
- .full (full) , //FIFO 满信号
- .almost_empty (almost_empty) , //FIFO 将空信号
- .fifo_rd_en (fifo_rd_en) //FIFO 读使能
- );
-
- endmodule
- `timescale 1ns / 1ps
- module ip_fifo_tb();
-
- parameter CLK_PERIOD = 20; //时钟周期 20ns
- //reg define
- reg sys_clk;
- reg sys_rst_n;
-
- //信号初始化
- initial begin
- sys_clk = 1'b0;
- sys_rst_n = 1'b0;
- #200;
- sys_rst_n = 1'b1;
- //模拟按下复位
- #10000 ;
- sys_rst_n = 0;
- #160 ;
- sys_rst_n = 1;
- end
-
- //产生时钟
- always #(CLK_PERIOD/2) sys_clk = ~sys_clk;
-
- ip_fifo u_ip_fifo (
- .sys_clk (sys_clk ),
- .sys_rst_n (sys_rst_n)
- );
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。