当前位置: 首页 > article >正文

ZYNQ初识8(zynq_7010)FIFO_IP核

以下内容基于bi站正点原子对fifoIP核的视频讲解。

以下是在vivado中创建fifo IP核的几个步骤:

另附上视频讲解过程中的程序,注意设置顶层文件:

主要包含三个文件,分别是顶层,数据读模块和数据写模块:

`timescale 1ns / 1ps
// Create Date: 2025/01/03 09:58:34
// Design Name: 
// Module Name: test_027_FIFO_IP
module test_027_FIFO_IP(
   input  		   sys_clk   ,  
   input  		   sys_rst_n      
    );
    wire         almost_full  ; 
    wire         almost_empt  ;
    wire         fifo_wr_en   ;
    wire  [7:0]  fifo_wr_data ;
    wire         fifo_rd_en   ;      
    wire  [7:0]  fifo_rd_data ;
     
    wire         full;
    wire         empty;
    
    wire  [7:0]  rd_data_count;
    wire  [7:0]  wr_data_count;
    
    //fifo数据写模块的例化调用
    fifo_wr  fifo_wr_u(
    	.sys_clk       (sys_clk),      
        .sys_rst_n     (sys_rst_n),      
        .almost_full   (almost_full),   
        .almost_empty  (almost_empt),   
                       
        .fifo_wr_en    (fifo_wr_en ),
        .fifo_wr_data  (fifo_wr_data)
    );
    
//fifo数据读模块的例化调用
    fifo_rd  fifo_rd_u(
    	.sys_clk      (sys_clk),      
        .sys_rst_n    (sys_rst_n),      
        .almost_full  (almost_full),   
        .almost_empty (almost_empty),   

        .fifo_rd_en   (fifo_rd_en)
       // .fifo_rd_data (fifo_rd_data)
    );
    
    //fifo模块例化调用 
    fifo_test fifo_test_u (                                        
      .wr_clk(sys_clk),                // input wire wr_clk                
      .rd_clk(sys_clk),                // 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 
    );     
    
    //ILA例化调用
    ila_fifo  ila_fifo_u (
	.clk(sys_clk), // input wire clk

	.probe0(fifo_wr_en), // input wire [0:0]  probe0  
	.probe1(fifo_rd_en), // input wire [0:0]  probe1 
	.probe2(full), // input wire [0:0]  probe2 
	.probe3(empty), // input wire [0:0]  probe3 
	.probe4(fifo_wr_data), // input wire [7:0]  probe4 
	.probe5(wr_data_count), // input wire [7:0]  probe5 
	.probe6(fifo_rd_data), // input wire [7:0]  probe6 
	.probe7(rd_data_count), // input wire [7:0]  probe7 
	.probe8(almost_full), // input wire [0:0]  probe8 
	.probe9(almost_empty) // input wire [0:0]  probe9
);
                                               
endmodule
    
`timescale 1ns / 1ps
// Create Date: 2025/01/03 10:53:04
// Design Name: 
// Module Name: fifo_wr
module fifo_wr(
	input  		   sys_clk       ,
	input  		   sys_rst_n     ,
	input          almost_full   ,
	input          almost_empty  ,
	
	output  reg         fifo_wr_en  ,
	output  reg  [7:0]  fifo_wr_data

    );
    //如何抓取信号的上升沿(下降沿)
    reg   almost_empty_d0;
    reg   almost_empty_up;
    wire  empty_flag;  //标志位->高电平抓取
    
    reg  [1:0]  state; //state3个状态切换
    reg  [3:0]  delay_cnt;
    
    assign  empty_flag = ~almost_empty_up & almost_empty_d0;
    
    always @ (posedge sys_clk or negedge sys_rst_n)
    	begin
			if(!sys_rst_n)  
				begin
					almost_empty_d0 <= 1'b0;
					almost_empty_up <= 1'b0;
				end	
    		else
    			begin
    			 	almost_empty_d0 <= almost_empty;
    			 	almost_empty_up <= almost_empty_d0;
    			end  	
    	end    
   
     always @ (posedge sys_clk or negedge sys_rst_n)
    	begin
			if(!sys_rst_n) 
				begin
					fifo_wr_en   <=	1'b0;
                	fifo_wr_data <= 8'd0;
                	state <= 2'd0;   
					delay_cnt <= 4'd0;
				end   
    	    else
    	    	begin
    	    	    case(state)
    	    	    	2'd0 : begin
    	    	    	          if(empty_flag)   
    	    	    	              state <= 2'd1;
    	    	    	          else
    	    	    	              state <= state;
    	    	    	       end
    	    	        2'd1 : begin
    	    	                  if(delay_cnt ==4'd10)
    	    	                      begin
    	    	                          delay_cnt <= 4'd0;
    	    	                          state <= 2'd2;
    	    	                          fifo_wr_en <= 1'b1;
    	    	                      end
    	    	                  else
    	    	                      delay_cnt <= delay_cnt + 4'd1;
    	    	        	   end
    	    	        2'd2 : begin
                                   if(almost_full)
                                   	    begin
                    						fifo_wr_en   <=	1'b0;            
               	    						fifo_wr_data <= 8'd0;
                                            state <= 2'd0;
                                        end
                                    else
                                        begin
                                            fifo_wr_en <= 1'b1;
                                            fifo_wr_data <= fifo_wr_data + 8'd1; 
                                        end
                               end
                        default :  state <= 2'd0;
                    endcase
                end          
        end
        
    
endmodule 
`timescale 1ns / 1ps
// Create Date: 2025/01/04 9:05:04
// Design Name: 
// Module Name: fifo_rd
module fifo_rd(
	input  		   sys_clk          ,
	input  		   sys_rst_n        ,
	input          almost_full      ,
	input          almost_empty     ,
	
	output  reg         fifo_rd_en  ,
	input        [7:0]  fifo_rd_data

    );
    //如何抓取信号的上升沿(下降沿)
    reg   almost_full_d0;
    reg   almost_full_up;
    wire  full_flag;  //标志位->高电平抓取
    
    reg  [1:0]  state; //state3个状态切换
    reg  [3:0]  delay_cnt;
    
    assign  full_flag = ~almost_full_up & almost_full_d0;
    
    always @ (posedge sys_clk or negedge sys_rst_n)
    	begin
			if(!sys_rst_n)  
				begin
					almost_full_d0 <= 1'b0;
					almost_full_up <= 1'b0;
				end	
    		else
    			begin
    			 	almost_full_d0 <= almost_full;
    			 	almost_full_up <= almost_full_d0;
    			end  	
    	end    
   
     always @ (posedge sys_clk or negedge sys_rst_n)
    	begin
			if(!sys_rst_n) 
				begin
					fifo_rd_en   <=	1'b0;
                	//fifo_rd_data <= 8'd0;
                	state <= 2'd0;   
					delay_cnt <= 4'd0;
				end   
    	    else
    	    	begin
    	    	    case(state)
    	    	    	2'd0 : begin
    	    	    	          if(full_flag)   
    	    	    	              state <= 2'd1;
    	    	    	          else
    	    	    	              state <= state;
    	    	    	       end
    	    	        2'd1 : begin
    	    	                  if(delay_cnt ==4'd10)
    	    	                      begin
    	    	                          delay_cnt <= 4'd0;
    	    	                          state <= 2'd2;
    	    	                          fifo_rd_en <= 1'b1;
    	    	                      end
    	    	                  else
    	    	                      delay_cnt <= delay_cnt + 4'd1;
    	    	        	   end
    	    	        2'd2 : begin
                                   if(almost_empty)
                                   	    begin
                    						fifo_rd_en   <=	1'b0;            
               	    						//fifo_rd_data <= 8'd0;
                                            state <= 2'd0;
                                        end
                                    else
                                        begin
                                            fifo_rd_en <= 1'b1;
                                            //fifo_rd_data <= fifo_rd_data + 8'd1; 
                                        end
                               end
                        default :  state <= 2'd0;
                    endcase
                end          
        end
        
    
endmodule 

tb激励文件(自己写的,没有实际测试过) 

`timescale 1ns / 1ps
// Create Date: 2025/01/04 10:31:57
// Design Name: 
// Module Name: tb_fifo
module tb_fifo();
  reg  sys_clk;
  reg  sys_rst_n;
initial 
    begin
    sys_clk   <= 1'b0;
    sys_rst_n <= 1'b0;
    #500
    sys_rst_n <= 1'b1;
    end
always #10
    sys_clk   <= ~sys_clk;

test_027_FIFO_IP test_027_FIFO_IP_u(
    .almost_full     (almost_full   ),
    .almost_empt     (almost_empt   ),
    .fifo_wr_en      (fifo_wr_en    ),
    .fifo_wr_data    (fifo_wr_data  ),
    .fifo_rd_en      (fifo_rd_en    ),
    .fifo_rd_data    (fifo_rd_data  ),
                                     
    .full            (full          ),        
    .empty           (empty         ),       
                                     
    .rd_data_count   (rd_data_count ),
    .wr_data_count   (wr_data_count )
);

endmodule

最后在放上vivado中对应fifoIP核程序对应的仿真电路 图解(Schematic):

另附注:

1、板子的PL端时钟需要从PS端调用,此时调用时钟的文件应为顶层文件,所以仿真受限。

2、涉及的状态机的写法的简单回顾。

3、在程序的编写过程中出现了一些问题如begin--end的无法自动对齐,就类似‘{}’,有时容易造成混乱,目前是tab手动控制,还没有更好的解决办法,和notepad++关联就无法使用vivado中编辑器的对程序的自动实时报错提醒的功能。


http://www.kler.cn/a/474256.html

相关文章:

  • Ungoogled Chromium127 编译指南 MacOS篇(八)- 开始编译
  • 汽车信息安全 -- S32K1如何更新BOOT_MAC
  • PCL 分段线性函数
  • 行为树详解(6)——黑板模式
  • 数字IC设计高频面试题
  • PixPin—— 高效截图工具的下载与使用攻略
  • 【银河麒麟高级服务器操作系统】服务器异常重启故障分析及处理建议
  • RoBERTa: A Robustly Optimized BERT Pretraining Approach—— 一种鲁棒优化的BERT预训练方法
  • C语言——结构体,位段,枚举和联合
  • failed to resolve sdk 的解决方法
  • 华为设备的监控和管理
  • 基于Spring Boot的车辆违章信息管理系统(LW+源码+讲解)
  • 开源AI智能名片商城小程序在个人品牌建设中的应用与“展温度”策略融合深度探索
  • 【线性代数】通俗理解特征向量与特征值
  • 【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件
  • 9 异常
  • PyTorch快速入门教程【小土堆】之完整模型验证套路
  • 网络安全系列 之 协议安全
  • ros2-4.2 用python实现人脸识别
  • 服务器证书不受信任是什么问题?
  • 有关Redis的相关概述
  • Linux(CentOS7)安装JDK和Maven
  • Unity导入特效,混合模式无效问题
  • 使用XMLHttpRequest进行AJAX请求的详解
  • 使用 uniapp 开发微信小程序遇到的坑
  • 毕业项目推荐:基于yolov8/yolov5/yolo11的动物检测识别系统(python+卷积神经网络)