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

ZYNQ_project:test_fifo_255X8

首先,这个vivado的fifo和quartus有很大不同。

用BRAM来实现异步fifo。

vivado的fifo有复位,在时钟信号稳定后,复位至少三个时钟周期(读写端口的慢时钟),复位完成后30个时钟周期后再进行写操作(慢时钟)。

有两个模式:标准模式和预读模式。

标准模式,读出的数据会比读使能延后一个时钟周期,fifo的深度也会比配置的少一个。

预读模式,读出的数据会与读使能同步,深度会比配置的多一个。

犯下的错误:顶层模块,fifo的复位接到了系统复位上。

没有认真阅读正点原子开发指南,忽略了深度的问题。

模块框图:

时序图:

 

代码:

module  fifo_wr_ctrl(input       wire                sys_clk     , // clk_wr // 50Mhzinput       wire                sys_rst_n   ,output      wire                rst_fifo    ,output      wire                wr_clk      ,output      wire    [7:0]       wr_din      ,output      reg                 wr_en       
);// parameter    parameter   RST_FIFO_CNT = 3    ,RST_WAIT_CNT = 30   ,DATA_IN_CNT  = 200  ; // 设置深度256,但实际深度只有255.写进数据0~254// localparamlocalparam  RST         = 4'b0001 ,RST_WAIT    = 4'b0010 ,DATA_IN_S   = 4'b0100 ,FINISH_S    = 4'b1000 ;// reg signal definereg     [7:0]       cnt_core    ;reg                 finish      ;reg     [3:0]       state       ;// wire signal definewire                rst_flag        ;wire                wait_flag       ;wire                data_over_flag  ;// reg     [7:0]       cnt_core    ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) cnt_core <= 8'd0 ;else if(rst_flag || wait_flag || data_over_flag || finish)cnt_core <= 8'd0 ;else cnt_core <= cnt_core + 1'b1 ;end// reg                 finish          ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) finish <= 1'b0 ;else if(data_over_flag)finish <= 1'b1 ;else finish <= finish ;end// reg     [3:0]       state       ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) state <= 4'b0001 ;else case (state)RST         :   if(rst_flag)state <= RST_WAIT ;else state <= RST ;RST_WAIT    :   if(wait_flag)state <= DATA_IN_S ;else state <= RST_WAIT ;DATA_IN_S   :   if(data_over_flag)state <= FINISH_S ;else state <= DATA_IN_S ;FINISH_S    :   state <= FINISH_S ;default     :   state <= RST ;endcaseend// wire                rst_flag        ;assign  rst_flag  = ((cnt_core == (RST_FIFO_CNT - 1)) && (state == RST)) ;// wire                wait_flag       ;assign  wait_flag = ((cnt_core == (RST_WAIT_CNT - 1)) && (state == RST_WAIT)) ;// wire                data_over_flag  ;assign  data_over_flag = ((cnt_core == (DATA_IN_CNT - 1)) && (state == DATA_IN_S)) ;// output      reg                 rst_fifo    ,// always @(posedge sys_clk or negedge sys_rst_n) begin//     if(~sys_rst_n) //         rst_fifo <= 1'b1 ;//     else if(state == RST && rst_flag)//         rst_fifo <= 1'b1 ;//     else if(state == RST)//         rst_fifo <= 1'b0 ;//     else //         rst_fifo <= 1'b1 ;  // endassign  rst_fifo = (state == RST) ? 1'b1 : 1'b0 ;// output      wire                wr_clk      ,assign  wr_clk = (sys_rst_n) ? sys_clk : 1'b0  ;// output      wire    [7:0]       wr_din      ,assign  wr_din = (state == DATA_IN_S) ? cnt_core : 8'd0 ;// output      reg                 wr_en       ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) wr_en <= 1'b0 ;else if(wait_flag || data_over_flag)wr_en <= ~wr_en ;else wr_en <= wr_en ;endendmodule
module  fifo_rd_ctrl(input       wire            sys_clk     ,// clk_rdinput       wire            sys_rst_n   ,input       wire            wr_full     ,input       wire            almost_empty,// 将要读空output      reg             rd_en       ,output      wire            rd_clk      
);assign  rd_clk = (sys_rst_n) ? sys_clk : 1'b0 ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) rd_en <= 1'b0 ;else if(almost_empty) // 将要读空后拉低读使能。因为是时序逻辑,应该正好读空fiford_en <= 1'b0 ;else if(wr_full) // 写满后拉高写使能rd_en <= 1'b1 ;else rd_en <= rd_en ;end
endmodule
module top(input       wire            sys_clk     ,input       wire            sys_rst_n   ,output      wire    [7:0]   data_out    
);// 例化间连线wire				clk_100Mhz	;wire				clk_50Mhz	;wire  				locked		;wire  				rst_n 		;wire                rst_fifo    ; // fifo的复位信号wire                wr_clk      ; // 写端口相关信号wire    [7:0]       wr_din      ; // 写端口相关信号wire                wr_en       ; // 写端口相关信号wire      [7:0]     dout		;wire                full		;wire                almost_full	;wire                empty		;wire                almost_empty;wire      [7:0]     rd_data_count;wire      [7:0]     wr_data_count;wire                wr_rst_busy	;wire                rd_rst_busy	;wire            	rd_en       ;wire            	rd_clk      ;mmcm_100M_50M mmcm_100M_50M_inst (.resetn				( sys_rst_n 	) ,.clk_in1			( sys_clk 		) ,.clk_out1			( clk_100Mhz 	) ,.clk_out2			( clk_50Mhz  	) ,.locked				( locked	 	) 
);assign 	rst_n = sys_rst_n && locked ;fifo_wr_ctrl fifo_wr_ctrl_inst(.sys_clk     		( clk_50Mhz 	) , // clk_wr // 50Mhz.sys_rst_n   		( rst_n     	) ,.rst_fifo    		( rst_fifo  	) ,.wr_clk      		( wr_clk    	) ,.wr_din      		( wr_din    	) ,.wr_en      		( wr_en     	) 
);fifo_rd_ctrl fifo_rd_ctrl_inst(.sys_clk     		( clk_100Mhz 	) ,// clk_rd.sys_rst_n   		( rst_n 		) ,.wr_full     		( full 			) ,.almost_empty		( almost_empty  ) ,// 将要读空.rd_en       		( rd_en    		) ,.rd_clk     		( rd_clk   		)  
);fifo_256X8 fifo_256X8_inst(.rst				( rst_fifo 		) ,  // 在fpga配置完成后,fifo必须要进行复位操作�?�复位信号至少保�?3个时钟周期以慢时钟为准�?�复位完成后至少经过30个时钟周期后,才能进行数据写操作�?.wr_clk				( wr_clk 		) ,  // 写数据时�?50Mhz // 复位高有效�??.rd_clk				( rd_clk 		) ,  // 读数据时�?100Mhz.din				( wr_din 		) ,  // 写入数据.wr_en				( wr_en 		) ,  // 写使�?.rd_en				( rd_en 		) ,  // 读使�?.dout				( data_out 		) ,  // 输出数据.full				( full			) ,  // 写满.almost_full		( almost_full	) ,  // 将写�?.empty				( empty			) ,  // 读空.almost_empty		( almost_empty	) ,  // 将读�?.rd_data_count		( rd_data_count	) ,  // 可读数据.wr_data_count		( wr_data_count	) ,  // 已写数据.wr_rst_busy		( wr_rst_busy	) ,  // 写复位忙�?.rd_rst_busy		( rd_rst_busy	)    // 读复位忙�?
); endmodule

 

`timescale 1ns/1ns
module  test_top();reg             sys_clk     ;reg             sys_rst_n   ;wire    [7:0]   data_out    ;top top_inst(.sys_clk            ( sys_clk   ) ,.sys_rst_n          ( sys_rst_n ) ,.data_out           ( data_out  )  
);parameter CYCLE = 20 ;initial beginsys_clk = 1'b1 ;sys_rst_n <= 1'b0 ;#( CYCLE * 5) ;sys_rst_n <= 1'b1 ;#(3000*CYCLE) ;$stop;endalways #(CYCLE/2) sys_clk = ~sys_clk ;
endmodule

 

仿真图:

相关文章:

  • 基于JavaWeb+SpringBoot+Vue电子商城微信小程序系统的设计和实现
  • 第十章 : 如何使用MockMvc 快速编写Reslful API 测试用例
  • Mac 安装 protobuf 和Android Studio 使用
  • Linux(3):Linux 的文件权限与目录配置
  • 认识Modbus通信协议(笔记)
  • WPF MVVM模式介绍
  • 系统安全-常见的几种sql注入攻击的方式
  • SQL SERVER 2008安装教程
  • 学习raft协议(1)
  • os.path.join函数用法
  • gRPC 的原理 介绍带你从头了解gRPC
  • 【Qt之QWizardPage】使用
  • Ubuntu 20.04 LTS ffmpeg gif mp4 互转 许编译安装ffmpeg ;解决gif转mp4转换后无法播放问题
  • Unity在Windows选项下没有Auto Streaming
  • Android NDK JNI 开发native层崩溃日志栈分析 空指针异常(Cause: null pointer dereference)
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • Create React App 使用
  • create-react-app做的留言板
  • github指令
  • HTTP请求重发
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • log4j2输出到kafka
  • PHP 7 修改了什么呢 -- 2
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • windows下如何用phpstorm同步测试服务器
  • yii2权限控制rbac之rule详细讲解
  • 关于List、List?、ListObject的区别
  • 解析带emoji和链接的聊天系统消息
  • 两列自适应布局方案整理
  • 普通函数和构造函数的区别
  • 我们雇佣了一只大猴子...
  • ​插件化DPI在商用WIFI中的价值
  • #每日一题合集#牛客JZ23-JZ33
  • (Java)【深基9.例1】选举学生会
  • (zt)最盛行的警世狂言(爆笑)
  • (超详细)语音信号处理之特征提取
  • (二)学习JVM —— 垃圾回收机制
  • (分布式缓存)Redis持久化
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转载)Google Chrome调试JS
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net 8 发布了,试下微软最近强推的MAUI
  • .net mvc部分视图
  • .NET学习全景图
  • .NET中两种OCR方式对比
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [100天算法】-二叉树剪枝(day 48)
  • [17]JAVAEE-HTTP协议
  • [AIGC 大数据基础]hive浅谈
  • [Android]竖直滑动选择器WheelView的实现