FPGA中利用fifo时钟域转换---慢时钟域转快时钟域

FPGA中利用fifo时钟域转换---慢时钟域转快时钟域

一、时间计算方法

FIFO的输入数据的时钟是40MHz,FIFO输出数据取60MHz,刚好是40MHz的1.5倍,将慢时钟域转快时钟域。另外,fifo输出的数据,要输出给上位机,一帧数据要传输640*512=327680个像素数据,要求帧频为100Hz,对应的时间是1/100Hz=10ms,即要求10ms内将327680个数据传输完毕。验证fifo的输出时钟60MHz是否满足要求的方法:输出一帧数据的时间 = 一帧的总数据量/频率,T=(640 ×1.5 ×512 )/ 60M=8.192 ms

什么是频率:单位时间内周期变化的次数。1 Hz 表示每秒发生一次

二、注意的问题

1、FPGA中的计数器其实就是在计时。FIFO输入端的时钟频率小,输出时钟频率快,为了保证输入FIFO的数据与输出数据速度相等,即FIFO不至于读空,行计数器计数的最大值也必须放大1.5倍,即640*1.5=960,从FIFO中读数据时前640个计数时数据有效,这640个计数期间可以至一个标志rd_en位为1,作为FIFO读使能信号,960中的后320个计时为FIFO读数据消隐期,此时rd_en=0,即不读数据。这样输入FIFO的数据读出FIFO的数据时间上就可以匹配上,不至于将FIFO读空。

2、先预存一行640个数据到FIFO中,存第二行数据的同时,读取第一行的数据,这样FIFO就不会被读空;

3、FIFO输出后面的模块必须要60M的时钟来接收数据,不然数据会不正确。后面模块的时钟慢了数据会丢失,时钟快了会多出无效的数据。

三、代码设计:

verilog 复制代码
module Slow2Fast(
    input i_reset,
    input i_clk_60m ,
    input i_clk_40m,

    input i_valid ,
    input [15:0] data ,


    output o_hsync,
    output o_vsync,
    output [11:0]o_vcnt,
    output [15:0] o_data
);
 
    reg  fifo_clr;
    reg  vsync ;
    reg  hsync ;
    reg  vsync_d ;
    reg  hsync_d;
    wire fifo_rd_req ;
    wire fifo_wr_req  ;
    wire [15:0] fifo_wr_data ;
    wire [15:0] fifo_rd_data ;
 
    reg [11:0]  hcnt;
    reg [11:0]  vcnt ;
    reg i_valid_d1;
    reg i_valid_d2,i_valid_d3;

    reg valid_shift_out,valid_buf;    
    
//行场计数器,就是计时    
    always@(posedge i_clk_60m)begin
        i_valid_d1 <= i_valid;
        i_valid_d2 <= i_valid_d1;
        i_valid_d3 <= i_valid_d2;
        if ((i_valid_d2 == 1'b1) && (i_valid_d3 == 1'b0)) begin //valid 信号的上升沿。上升沿到来,行场计数器清零
            hcnt <= 0;
            vcnt <= 0;
        end
        else begin
            if (hcnt == (960 - 1))begin //输入时钟为40M,输出时钟为60M,60M=1.5*40M。 640*513 乘1.5时得: 960*563
                if (vcnt = (566 - 1)) //563
                    vcnt <= vcnt;
                else begin
                    vcnt <= vcnt + 1;
                end
                hcnt <=0;
            end
            else
                hcnt <= hcnt + 1;      
    end

        
        //vcnt:0到513 hcnt:0到639      
        always@(posedge i_clk_60m) begin
            if (vcnt >= 1 and vcnt <= 512)// vcnt从1开始,因为要预存一行
                vsync <= 1'b1;
            else
                vsync <= 1'b0;

            if((hcnt >= 0 && hcnt <= 639) && (vcnt >= 1 && vcnt <= 512))//FIFO读使能信号,在60M下在前640个计数,读信号为1,后320个计数为读FIFO消隐期
                hsync <= 1'b1;
            else
                hsync <= 1'b0;
            if(vcnt = 513) 
                fifo_clr <=  1'b1;
            else
                fifo_clr <=  1'b0;
        end 

//		打拍
        always@(posedge i_clk_60m)  begin //60M
            hsync_d <= hsync;
            vsync_d <= vsync;
        end
    
 assign  fifo_wr_req  = i_valid;
 assign  fifo_wr_data = i_data;
 assign  fifo_rd_req  = hsync;
   
 assign  o_hsync      = hsync_d;
 assign  o_vsync      = vsync_d; 
 assign  o_data       = fifo_rd_data;
	
 assign  o_vcnt = vcnt;
   
    fifo_out inst_fifo_out 
      (
          .rst		( fifo_clr ),
          .wr_clk	(  i_clk_40m ),//写FIFO时钟为40M
          .rd_clk 	(i_clk_60m) ,//读FIFO时钟为60M
          .din  	(fifo_wr_data)   ,
          .wr_en   	(fifo_wr_req)  ,
          .rd_en   	(fifo_rd_req) ,
          .dout    	(fifo_rd_data) ,
          .full  	(),
          .empty   	(),
          .wr_rst_busy	(),
          .rd_rst_busy 	()
      );

endmodule    
c 复制代码
---晓凡	2025年2月20日于武汉书
相关推荐
ChipCamp13 小时前
Chisel芯片开发入门系列 -- 14. CPU芯片开发和解释4(Load/Store指令再探)
arm开发·青少年编程·fpga开发·scala·dsp开发·risc-v·chisel
霖0015 小时前
深入讲讲异步FIFO
笔记·vscode·单片机·嵌入式硬件·学习·fpga开发
水果里面有苹果16 小时前
3-verilog的使用-1
fpga开发
嵌入式-老费18 小时前
再谈fpga开发(总结篇)
fpga开发
minglie120 小时前
基于 AXI-Lite 实现可扩展的硬件函数 RPC 框架(附完整源码)
fpga开发
朱古力(音视频开发)1 天前
NDI开发指南
fpga开发·音视频·实时音视频·视频编解码·流媒体
9527华安1 天前
FPGA实现AD9361采集转SRIO与DSP交互,FPGA+DSP多核异构信号处理架构,提供2套工程源码和技术支持
fpga开发·架构·信号处理·dsp·ad9361·多核异构
小眼睛FPGA2 天前
【盘古100Pro+开发板实验例程】FPGA学习 | 基于紫光 FPGA 的键控 LED 流水灯
科技·学习·ai·fpga开发·fpga
最好有梦想~2 天前
分享一个FPGA寄存器接口自动化工具
fpga开发
hahaha60162 天前
FPGA(或者数字电路)中组合逻辑和时序逻辑是怎么划分的
fpga开发