请选择 进入手机版 | 继续访问电脑版
 专注集成电路FPGA应用生态推广
 微信公众号
米联客
1

03uifdma_vbuf实现单通道摄像头采集(AXI4 FDMA数据缓存篇)

摘要: 通过前文中实验的学习,相信读者已经掌握了fdma读写bram或者ddr的基本使用,本文使用米联客编写的uivbuf ip 配合uifdma ip 实现摄像头图像的多缓存方法。 本文实验目的: 1:熟悉ov5640摄像头硬件资源 2:掌 ...

软件版本:vitis2019.2(vivado2019.2)

操作系统:WIN10 64bit

硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA

登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!

3.1概述    

    通过前文中实验的学习,相信读者已经掌握了fdma读写bram或者ddr的基本使用,本文使用米联客编写的uivbuf ip 配合uifdma ip 实现摄像头图像的多缓存方法。

本文实验目的:

1:熟悉ov5640摄像头硬件资源

2:掌握通过米联客iic控制器实现对ov5640寄存器的配置,实现分辨率的修改。

3:掌握uivbuf程序设计方法

4:掌握图像处理中最常用的三缓存设计,如何实现3帧图形缓存,确保图形不撕裂

3.2OV5640摄像头简介

说到OV5640 OV7725等入门级摄像头大部分读者应该并不陌生,这些摄像头基础成为教学实验开发板必配摄像头。如下图所示,为我们米联客提供的OV5640摄像头,采用的是DVP接口。通过普通的连接器接入到开发板的的FPGA IO实现数据采集。

OV5640是一款靶面大小为1/4英寸的图像光学传感器芯片。最高支持2592*1944@15fps QSXVGA格式图像采集,或者640*480@90fps VGA图像采集。芯片内部集成了图像处理的功能,包括自动曝光控制(AEC)、自动白平衡(AWB)等功能。

OV5640的数据输出格式支持MIPI(移动产业处理器接口)、DVP(数字视频并行)我们米联客暂时只有DVP接口的OV5640摄像头,受限于硬件接口速度,目前最高可以实现720p@30fps,对于部分转接卡只能实现720p@15fps的采集速度,能够满足大部分实验性质的图像数据采集要求。

3.2.1OV5640的框图

 

我们通过框图可以看到OV5640摄像头大概的功能结构包括:

1:PLL模块,输入的XCLK时钟经过PLL后提供给芯片的内部逻辑工作

2:时序产生以及系统控制逻辑模块(timing generator and system control logic)

3:图像传感器核心单元(image sensor core)包含:感光阵列(image array)、放大器(AMP)、放大器增益控制(gain contro)、ADC模块(10-bit ADC) 、50HZ/60HZ干扰自动检测单元

4:图像处理单元包含(image sensor processor):ISP图像处理单元、数据压缩单元、格式转换单元

5:图像输出接口(image out interface)包含:数据FIFO、DVP接口、MIPI接口

6:寄存器配置接口(SCCB interface)

7:微控制器(micro controller)

3.2.2摄像头参数概述

厂家

OmniVision

色彩

彩色

曝光模式

卷帘

靶面尺寸

1/4``

相机ID

0x78

支持的分辨率

最大分辨率支持2592*1944@15。受限于硬件设计我们的摄像头最大支持1280*@30或者1280*720@15,满足一般实验要求绰绰有余。

镜头

M12 4MM 500W

视场角

70°

感光特性

可见光(红外弱)

接口

DVP

ISP

内置ISP算法

尺寸

30mm*30mm*35mm

3.2.3摄像头接口定义

米联客CEP(Camera expansion interface)接口定义如下:

标准DVP OV5640摄像头定义如下:

读者可以发现,相比标准的DVP接口,米联客的CEP接口烧了RESET、CMOS_CTL0、CMOS_CTL1、CMOS_CTL2这几个信号脚。

另外细心的读者可以发现米联客的CEP扩展接口预先以差分形式走线,具体差分信号传输能力。

信号功能如下:

信号名称

功能描述

输入/输出

D3V3

3.3V输入接口给摄像头芯片供电

电源

GND

数据、模拟GND

电源

SCLK

I2C时钟/SCCB协议时钟

input

SDAT

I2C数据/SCCB协议数据

inout

VSYNC

帧同步信号

output

HREF

行同步信号

output

PCLK

像素时钟,对于RGB565一个像素需要2个时钟

output

XCLK

FPGA输入给摄像头的参考时钟一般是24MHZ

input

D2~D9

对应d0~d8,8bit有效数据

output

3.2.4分辨率

OV5640使用寄存器0x3800 ~ 0x3814进行图像窗口调整。上图中说明了那些寄存器如何定义窗口大小。对于物理像素大小是固定的,由传感器中所有像素阵列的大小决定。ISP输入大小是从像素阵列读取的像素数据总量。一般情况下,ISP的输入量越大,所能达到的最大帧速率越小。数据输出大小为OV5640的图像输出大小。这个大小从ISP输入大小中窗口化,由x_offset和y_offset定义。

下表我们给出以上寄存器的功能定义说明:

address

register name

default value

R/W

description

0x3800

TIMING HS

0x00

RW

Bit[3:0]有效,对应X_ADDR_ST[11:8]bits

0x3801

TIMING HS

0x00

RW

Bit[7:0]有效,对应X_ADDR_ST[7 :0]bits

0x3802

TIMING VS

0x00

RW

Bit[2:0]有效,对应Y_ADDR_ST [10:8]bits

0x3803

TIMING VS

0x00

RW

Bit[7:0]有效,对应X_ADDR_ST [7 :0]bits

0x3804

TIMING HW

0x0A

RW

Bit[3:0]有效,对应X_ADDR_END[11:8]bits

0x3805

TIMING HW

0x3F

RW

Bit[7:0]有效,对应X_ADDR_ END [7 :0]bits

0x3806

TIMING VH

0x07

RW

Bit[2:0]有效,对应Y_ADDR_ END [10:8]bits

0x3807

TIMING VH

0x9F

RW

Bit[7:0]有效,对应X_ADDR_ END [7 :0]bits

0x3808

TIMING DVPHO

0x0a

RW

Bit[3:0]有效,对应图像水平像素hsize[11:8]bits

0x3809

TIMING DVPHO

0x20

RW

Bit[7:0]有效,对应图像水平像素hsize [7 :0]bits

0x380A

TIMING DVPVO

0x07

RW

Bit[3:0]有效,对应图像垂直像素vsize[11:8]bits

0x380B

TIMING DVPVO

0x98

RW

Bit[7:0]有效,对应图像垂直像素vsize [7 :0]bits

0x380C

TIMING HTS

0x0B

RW

Bit[3:0]有效,对应图像水平像素总大小total_hsize[11:8]bits

0x380D

TIMING HTS

0x1C

RW

Bit[7:0]有效,对应图像水平像素总大小total_hsize [7 :0]bits

0x380E

TIMING VTS

0x07

RW

Bit[3:0]有效,对应图像垂直像素总大小total_vsize[11:8]bits

0x380F

TIMING VTS

0xB0

RW

Bit[7:0]有效,对应图像垂直像素总大小total_vsize [7 :0]bits

0x3810

TIMING HOFFSET

0x00

RW

Bit[3:0]有效,对应图像水平像素裁剪大小xoffset_size[11:8]bits

0x3811

TIMING_HOFFSET

0x10

RW

Bit[7:0]有效,对应图像水平像素裁剪大小xoffset_size [7 :0]bits

0x3812

TIMING VOFFSET

0x00

RW

Bit[3:0]有效,对应图像垂直像素裁剪大小xoffset_size[11:8]bits

0x3813

TIMING VOFFSET

0x04

RW

Bit[7:0]有效,对应图像垂直像素裁剪大小xoffset_size [7 :0]bits

1:有效像素大小:图像采集窗口的物理大小physical pixel size为2623*1951,其中有效像素部分2592*1944。由上表中X_ADDR_ST (0x3800、0x3801)、Y_ADDR_ST(0x3802、0x3803)、X_ADDR_END(0x3804、0x3805)、Y_ADDR_END(0x3806、0x3807)寄存器和X_OFFSET(0x3810、 0x3811)和Y_OFFSET(0x3812、0x3813)寄存器共同决定。

2:预缩放窗口(pre-scaling-size):可以通过设置X_OFFSET(0x3810、 0x3811)和Y_OFFSET(0x3812、0x3813)对图像做裁剪,可以看到裁剪的后的图像可以观察到的像素面较少了。

    3:DVP图像数据输出窗口(data-output-size):通过X_OUT_PUT(0x3808, 0x3809), Y_OUT_PUT(0x380A, 0x380B)设置。

    当pre-scaling-size和data-output-size不一致的时候,OV5640的ISP部分会自动完成对图像的缩放处理。

3.2.5RGB565格式

OV5640支持的图像数据格式包括YUV、RGB、RAW,可以通过修改寄存器0x4300进行配置。在演示基本的图像采集,图像算法中,以RGB656格式最常用。

address

register name

default value

R/W

description

0x4300

FORMAT CONTROL

0xF8

RW

Bit[7:4]:数据输出格式

0RAW

1Y8

2YUV444/RGB888

3YUV422

4YUV420

5YUV420(仅MIPI支持)

6RGB565 Bit[3:0]:输出顺序

0:{b[4:0],g[5:3]},{g[2:0],r[4:0]}

1:{r[4:0],g[5:3]},{g[2:0],b[4:0]}

2:{g[4:0],r[5:3]},{r[2:0],b[4:0]}

3:{b[4:0],r[5:3]},{r[2:0],g[4:0]}

4:{g[4:0],b[5:3]},{b[2:0],r[4:0]}

5:{r[4:0],b[5:3]},{b[2:0],g[4:0]}

6~14:不支持

15:{g[2:0],b[4:0]},{r[4:0],g[5:3]}

7RGB555格式1

8RGB555格式2

9RGB444格式1

10RGB444格式2

11~14:不支持

15Bypass formatter module

3.2.6OV5640的时钟

address

register name

default value

R/W

description

0x3034

SC PLL CONTRL0

0x1A

RW

Bit[6:4]: PLL电荷泵控制

Bit[3:0]: MIPI位模式

0x8: 8-bit mode

0xA: 10-bit mode

0x3035

SC PLL CONTRL1

0x11

RW

Bit[7:4]:系统时钟分频Bit[3:0]MIPI分频

0x3036

SC PLL CONTRL2

0x69

RW

Bit[7:0]:PLL倍频器(4~252)我们定义为clk_multi[7:0]

4~127范围内支持任意整数倍频;128~252范围内仅支持偶数倍频

0x3037

SC PLL CONTRL3

0x03

RW

Bit[4]:锁相环根分频器

0:Bypass

1:2分频

Bit[3:0]:PLL预分频

1, 2, 3, 4, 6, 8

0x3108

SC PLL CONTRL5

0x16

RW

始终为0x01

0x303B

SC PLLS CTRL1

0x19

RW

Bit[7:5]:调试模式

Bit[4:0]:PLLS 倍频

0x303C

SC PLLS CTRL2

0x11

RW

Bit[7]:调试模式

Bit[6:4]:PLL充电泵控制

Bit[3:0]:PLL系统分频

0x303D

SC PLLS CTRL3

0x30

RW

Bit[7:6]:调试模式

Bit[5:4]:

00:/1

01:/1.5

10:/2

11:/3

Bit[3]:调试模式

Bit[3]:PLL根分频器

0:/1

1:/2

Bit[1:0]:

00: /1

01:/2

11:/2.5

Bit[3:0]:PLL系统分频

0x3824

  

RW

PLL 手动分频,这个参数没有查到但是有用。

我们现在以开发板上的OV5640为例,配置参数来用上图的公式来计算下。

以上分析中比如3037[7]?3036[7:1]*2 : 3036[6:0] 描述的是如果0x3037寄存器的bit7为1这倍频系数为0x3036寄存器的bit[7:1]*2 否则 为bit[6:0]

掌握了原理,以上是1280*720 15fps的PCLK时钟,掌握了以上原理,我们只要简单修改(0x3035,0x21)就可以实现PCLK 84MHZ。

读者请注意,米联客目前的FEP扩展卡经过多次转接到CEP后最高的PCLK目前是42Mhz,也就是实现1280*720@15fps。

3.2.7软件复位

软件复位后需要等待5ms才能确保所有寄存器恢复到初始值。

Address

register name

default value

R/W

description

0x3008

SYSTEM CTROL0

0x02

RW

Bit[7]:软件复位

Bit[6]:软件关闭电源

3.2.8DVP时序

OV5640的DVP时序包含场同步信号VSYNC,上同步信号HSYNC、数据有效信号HREF,以及数据部分所以是标准的视频时序。我们可以只关心VSYNC HREF 以及DATA部分。下面是我们自己画的一张RGB565的时序图:

以上时序图中可以看到每个pclk输出有2个1个有效的RGB数据。

3.2.9SCCB传输协议

以上是SCCB配置寄存器的时序图,下图是如何配置寄存器。可以看出下图的配置寄存器过程非常类似I2C写操作。分别具有1个7bit器件地址+1bit的起始位、16bit的地址、8bit数据、停止位。其中X代表了OV5640发给配置主机的ACK可以不管。所以我们可以通过GPIO实现SCCB也可以通过I2C配置寄存器。

3.3硬件电路分析

3.3.1FEP扩展接口

摄像头扩展卡安装在FEP扩展接口上,这里主要用到了摄像头接口的定义,需要注意MK7160默认IO是3.3V的需要匹配3.3V的扩展卡和摄像头。

 

3.3.2fpga_pin.xdc摄像头和HDMI输出IO约束

create_clock -period 10.000 -name sysclk [get_ports sysclk]

set_property PACKAGE_PIN AA3 [get_ports sysclk]

set_property IOSTANDARD SSTL135 [get_ports sysclk]

 

set_property PACKAGE_PIN E18 [get_ports card1_power_en]

set_property IOSTANDARD LVCMOS33 [get_ports card1_power_en]

#---------------------------sensor---------------------------

set_property PACKAGE_PIN F17 [get_ports cmos1_pclk_i]

set_property PACKAGE_PIN E15 [get_ports cmos1_vsync_i]

set_property PACKAGE_PIN E16 [get_ports cmos1_href_i]

set_property PACKAGE_PIN E17 [get_ports cmos1_xclk_o]

set_property PACKAGE_PIN D16 [get_ports cmos1_data_i[0]]

set_property PACKAGE_PIN D15 [get_ports cmos1_data_i[1]]

set_property PACKAGE_PIN F15 [get_ports cmos1_data_i[2]]

set_property PACKAGE_PIN G15 [get_ports cmos1_data_i[3]]

set_property PACKAGE_PIN B16 [get_ports cmos1_data_i[4]]

set_property PACKAGE_PIN C16 [get_ports cmos1_data_i[5]]

set_property PACKAGE_PIN J16 [get_ports cmos1_data_i[6]]

set_property PACKAGE_PIN J15 [get_ports cmos1_data_i[7]]

set_property PACKAGE_PIN K16 [get_ports cmos1_scl]

set_property PACKAGE_PIN K17 [get_ports cmos1_sda]

 

set_property IOSTANDARD LVCMOS33 [get_ports cmos1_vsync_i]

set_property IOSTANDARD LVCMOS33 [get_ports cmos1_href_i]

set_property IOSTANDARD LVCMOS33 [get_ports cmos1_pclk_i]

set_property IOSTANDARD LVCMOS33 [get_ports cmos1_xclk_o]

set_property IOSTANDARD LVCMOS33 [get_ports cmos1_data_i[*]]

set_property IOSTANDARD LVCMOS33 [get_ports cmos1_scl]

set_property IOSTANDARD LVCMOS33 [get_ports cmos1_sda]

set_property PULLUP true [get_ports cmos1_scl]

set_property PULLUP true [get_ports cmos1_sda]

 

set_property PACKAGE_PIN Y23 [get_ports HDMI_TX_CLK_P]

set_property PACKAGE_PIN W25 [get_ports {HDMI_TX_P[0]}]

set_property PACKAGE_PIN Y22 [get_ports {HDMI_TX_P[1]}]

set_property PACKAGE_PIN Y25 [get_ports {HDMI_TX_P[2]}]

 

set_property IOSTANDARD TMDS_33 [get_ports HDMI_TX_CLK_P]

set_property IOSTANDARD TMDS_33 [get_ports {HDMI_TX_P[*]}]

 

 

set_property DCI_CASCADE {32 34} [get_iobanks 33]

 

set_property CFGBVS VCCO [current_design]

set_property CONFIG_VOLTAGE 3.3 [current_design]

set_property BITSTREAM.GENERAL.COMPRESS true [current_design]

set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]

set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]

set_property BITSTREAM.CONFIG.SPI_FALL_EDGE Yes [current_design]

3.4硬件连接

3.5 PL图形化设计

前面我们花费了很多内容介绍了OV5640摄像头的关键参数配置,不过下面的内容才是核心板关键,主要讲解uiFDMA和uivbuf图像视频通路的搭建。

3.5.1系统框图

3.5.2PL图形化编程

1:uiFDMA参数设置

2:uifdma_vbuf参数设置

 

可以在配套的fpga_prj/uisrc/ip路径下找到源码,这部分代码比较复杂,我们放到后面的程序分析中分析

3:自定义uiSensorRGB565 IP

这个IP负责将OV5640摄像头传输过来的RGB565数据转换成RGB888

可以在配套的fpga_prj/uisrc/ip路径下找到源码

module uiSensorRGB565(

input rstn_i,

input cmos_clk_i,//cmos senseor clock.

input cmos_pclk_i,//input pixel clock.

input cmos_href_i,//input pixel hs signal.

input cmos_vsync_i,//input pixel vs signal.

input [7:0]cmos_data_i,//data.

output cmos_xclk_o,//output clock to cmos sensor.

output [23:0] rgb_o,

output de_o,

output vs_o,

output hs_o

);

assign cmos_xclk_o = cmos_clk_i;

 

reg cmos_href_r1 = 1'b0,cmos_href_r2 = 1'b0,cmos_href_r3 = 1'b0;

reg cmos_vsync_r1 = 1'b0,cmos_vsync_r2 = 1'b0;

reg [7:0]cmos_data_r1 = 8'b0;

reg [7:0]cmos_data_r2 = 8'b0;

 

(* ASYNC_REG = "TRUE" *) reg rstn1,rstn2;

 

always@(posedge cmos_pclk_i)begin

rstn1 <= rstn_i;

rstn2 <= rstn1;

end

 

always@(posedge cmos_pclk_i)begin

cmos_href_r1 <= cmos_href_i;

cmos_href_r2 <= cmos_href_r1;

cmos_href_r3 <= cmos_href_r2;

cmos_data_r1 <= cmos_data_i;

cmos_data_r2 <= cmos_data_r1;

cmos_vsync_r1 <= ~cmos_vsync_i;

cmos_vsync_r2 <= cmos_vsync_r1;

end

 

parameter FRAM_FREE_CNT = 5;

reg [7:0]vs_cnt;

wire vs_p = !cmos_vsync_r2&&cmos_vsync_r1;

always@(posedge cmos_pclk_i)begin

if(!rstn2)begin

vs_cnt <= 8'd0;

end

else if(vs_p)begin

if(vs_cnt < FRAM_FREE_CNT)

vs_cnt <= vs_cnt + 1'b1;

else

vs_cnt <= vs_cnt;

end

end

 

wire out_en = (vs_cnt == FRAM_FREE_CNT);

//output data 8bit changed into 16bit in rgb565.

 

reg href_cnt = 1'b0;

reg data_en = 1'b0;

reg [15:0]rgb2 = 32'd0;

always@(posedge cmos_pclk_i)begin

    if(vs_p||(~out_en))begin

     href_cnt <= 1'd0;

     data_en <= 1'b0;

     rgb2 <= 16'd0;

    end    

    else begin

     href_cnt <= cmos_href_r2 ? href_cnt + 1'b1 : 1'b0 ;

data_en <= (href_cnt==1'd1);

if(cmos_href_r2) begin

rgb2 <= {rgb2[7:0],cmos_data_r2};

end

    end    

end

 

assign rgb_o = {rgb2[15:11],3'd0,rgb2[10:5],2'd0,rgb2[4:0],3'd0};

assign    de_o = out_en && data_en ;

assign    vs_o = out_en && cmos_vsync_r2 ;

assign    hs_o = out_en && cmos_href_r3 ;

4:自定义uicfg5640 IP设置

这个IP用于配置5640寄存器,这里使用到了我们米联客的uii2c控制器,i2c控制代码就不介绍了,主要看下寄存中关键参数设置。

我们把这两个定义分辨率的接口引出了,在BD中可以直接设置分辨率。

3.5.3设置地址分配

3.5.4添加PIN约束

1:选中PROJECT MANAGERà Add SourcesàAdd or create constraints,添加XDC约束文件。

2:打开提供例程,复制约束文件中的管脚约束到XDC文件,或者查看原理图,自行添加管脚约束,并保存。

以下是添加配套工程路径下已经提供的pin脚文件。配套工程的pin脚约束文件在uisrc/04_pin路径

3.6程序分析

3.6.1FDMA的读写时序

以下关于程序的分析和"01使用FDMA读写AXI-BRAM"一样,重复是为了读者不会因此遗漏这部分重要信息。

1:FDMA的写时序

fdma_wready设置为1,当fdma_wbusy=0的时候代表FDMA的总线非忙,可以进行一次新的FDMA传输,这个时候可以设置fdma_wreq=1,同时设置fdma burst的起始地址和fdma_wsize本次需要传输的数据大小(以bytes为单位)。当fdma_wvalid=1的时候需要给出有效的数据,写入AXI总线。当最后一个数写完后,fdma_wvalid和fdma_wbusy变为0。

2:FDMA的读时序

fdma_rready设置为1,当fdma_rbusy=0的时候代表FDMA的总线非忙,可以进行一次新的FDMA传输,这个时候可以设置fdma_rreq=1,同时设置fdma burst的起始地址和fdma_rsize本次需要传输的数据大小(以bytes为单位)。当fdma_rvalid=1的时候需要给出有效的数据,写入AXI总线。当最后一个数写完后,fdma_rvalid和fdma_rbusy变为0。

3.6.2uifdma_vbuf程序分析

1:参数设置

2:写数据通道缓存机制

以上参数具体定义

localparam WVBUF_SIZE = (WBUF_SIZE - 1'b1);

localparam WV_BURST_TIMES = (WV_SIZE*WH_DIV);

localparam FDMA_WH_BURST = (WH_SIZE*32/AXI_DATA_WIDTH)/WH_DIV;

localparam WH_BURST_ADDR_INC = (WH_SIZE*4)/WH_DIV;

localparam WH_LAST_ADDR_INC = (WH_STRIDE-WH_SIZE)*4 + WH_BURST_ADDR_INC;

对于初学者来说参数localparam WH_LAST_ADDR_INC = (WH_STRIDE-WH_SIZE)*4 + WH_BURST_ADDR_INC可能会难以理解,这个我没在下面一篇文中的demo中会具体提到这个参数的应用。在本文中这个参数Hstride=Hsize

3:读数据通道缓存机制

以上参数具体定义

localparam RVBUF_SIZE = (RBUF_SIZE - 1'b1);

localparam RV_BURST_TIMES = (RV_SIZE*RH_DIV);

localparam FDMA_RH_BURST = (RH_SIZE*32/AXI_DATA_WIDTH)/RH_DIV;

localparam RH_BURST_ADDR_INC = (RH_SIZE*4)/RH_DIV;

localparam RH_LAST_ADDR_INC = (RH_STRIDE-RH_SIZE)*4 + RH_BURST_ADDR_INC;

对于初学者来说参数localparam RH_LAST_ADDR_INC = (RH_STRIDE-RH_SIZE)*4 + RH_BURST_ADDR_INC可能会难以理解,这个我没在下面一篇文中的demo中会具体提到这个参数的应用。在本文中这个参数Hstride=Hsize

4:xpm_fifo_async FIFO介绍

使用XILINX源语来描述FIFO具有很多好处,可以通过XILINX VIVADO 工具的Langguage Templates查看源语定义。

xpm_fifo_async #(

.CDC_SYNC_STAGES(2), // DECIMAL

.DOUT_RESET_VALUE("0"), // String

.ECC_MODE("no_ecc"), // String

.FIFO_MEMORY_TYPE("auto"), // String

.FIFO_READ_LATENCY(1), // DECIMAL

.FIFO_WRITE_DEPTH(2048), // DECIMAL

.FULL_RESET_VALUE(0), // DECIMAL

.PROG_EMPTY_THRESH(10), // DECIMAL

.PROG_FULL_THRESH(10), // DECIMAL

.RD_DATA_COUNT_WIDTH(1), // DECIMAL

.READ_DATA_WIDTH(32), // DECIMAL

.READ_MODE("std"), // String

.RELATED_CLOCKS(0), // DECIMAL

.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages

.USE_ADV_FEATURES("0707"), // String

.WAKEUP_TIME(0), // DECIMAL

.WRITE_DATA_WIDTH(32), // DECIMAL

.WR_DATA_COUNT_WIDTH(1) // DECIMAL

)

xpm_fifo_async_inst (

.almost_empty(almost_empty), // 1-bit output: Almost Empty : When asserted, this signal indicates that

// only one more read can be performed before the FIFO goes to empty.

.almost_full(almost_full), // 1-bit output: Almost Full: When asserted, this signal indicates that

// only one more write can be performed before the FIFO is full.

.data_valid(data_valid), // 1-bit output: Read Data Valid: When asserted, this signal indicates

// that valid data is available on the output bus (dout).

.dbiterr(dbiterr), // 1-bit output: Double Bit Error: Indicates that the ECC decoder detected

// a double-bit error and data in the FIFO core is corrupted.

.dout(dout), // READ_DATA_WIDTH-bit output: Read Data: The output data bus is driven

// when reading the FIFO.

.empty(empty), // 1-bit output: Empty Flag: When asserted, this signal indicates that the

// FIFO is empty. Read requests are ignored when the FIFO is empty,

// initiating a read while empty is not destructive to the FIFO.

.full(full), // 1-bit output: Full Flag: When asserted, this signal indicates that the

// FIFO is full. Write requests are ignored when the FIFO is full,

// initiating a write when the FIFO is full is not destructive to the

// contents of the FIFO.

.overflow(overflow), // 1-bit output: Overflow: This signal indicates that a write request

// (wren) during the prior clock cycle was rejected, because the FIFO is

// full. Overflowing the FIFO is not destructive to the contents of the

// FIFO.

.prog_empty(prog_empty), // 1-bit output: Programmable Empty: This signal is asserted when the

// number of words in the FIFO is less than or equal to the programmable

// empty threshold value. It is de-asserted when the number of words in

// the FIFO exceeds the programmable empty threshold value.

.prog_full(prog_full), // 1-bit output: Programmable Full: This signal is asserted when the

// number of words in the FIFO is greater than or equal to the

// programmable full threshold value. It is de-asserted when the number of

// words in the FIFO is less than the programmable full threshold value.

.rd_data_count(rd_data_count), // RD_DATA_COUNT_WIDTH-bit output: Read Data Count: This bus indicates the

// number of words read from the FIFO.

.rd_rst_busy(rd_rst_busy), // 1-bit output: Read Reset Busy: Active-High indicator that the FIFO read

// domain is currently in a reset state.

.sbiterr(sbiterr), // 1-bit output: Single Bit Error: Indicates that the ECC decoder detected

// and fixed a single-bit error.

.underflow(underflow), // 1-bit output: Underflow: Indicates that the read request (rd_en) during

// the previous clock cycle was rejected because the FIFO is empty. Under

// flowing the FIFO is not destructive to the FIFO.

.wr_ack(wr_ack), // 1-bit output: Write Acknowledge: This signal indicates that a write

// request (wr_en) during the prior clock cycle is succeeded.

 

.wr_data_count(wr_data_count), // WR_DATA_COUNT_WIDTH-bit output: Write Data Count: This bus indicates

// the number of words written into the FIFO.

.wr_rst_busy(wr_rst_busy), // 1-bit output: Write Reset Busy: Active-High indicator that the FIFO

// write domain is currently in a reset state.

.din(din), // WRITE_DATA_WIDTH-bit input: Write Data: The input data bus used when

// writing the FIFO.

.injectdbiterr(injectdbiterr), // 1-bit input: Double Bit Error Injection: Injects a double bit error if

// the ECC feature is used on block RAMs or UltraRAM macros.

.injectsbiterr(injectsbiterr), // 1-bit input: Single Bit Error Injection: Injects a single bit error if

// the ECC feature is used on block RAMs or UltraRAM macros.

.rd_clk(rd_clk), // 1-bit input: Read clock: Used for read operation. rd_clk must be a free

// running clock.

.rd_en(rd_en), // 1-bit input: Read Enable: If the FIFO is not empty, asserting this

// signal causes data (on dout) to be read from the FIFO. Must be held

// active-low when rd_rst_busy is active high.

.rst(rst), // 1-bit input: Reset: Must be synchronous to wr_clk. The clock(s) can be

// unstable at the time of applying reset, but reset must be released only

// after the clock(s) is/are stable.

.sleep(sleep), // 1-bit input: Dynamic power saving: If sleep is High, the memory/fifo

// block is in power saving mode.

.wr_clk(wr_clk), // 1-bit input: Write clock: Used for write operation. wr_clk must be a

// free running clock.

.wr_en(wr_en) // 1-bit input: Write Enable: If the FIFO is not full, asserting this

// signal causes data (on din) to be written to the FIFO. Must be held

// active-low when rst or wr_rst_busy is active high.

);

UG974中有关于xpm_fifo_async的具体描述,在配套工程的uisrc/doc路径下,已经提供了下载好的"ug974-vivado-ultrascale-libraries.pdf"。

接口描述如下(摘录于ug974):

Port

Direction

Function

almost_empty

Output

Almost Empty : When asserted,this signal indicates that only one more read can be performed before the FIFO goes to empty.

almost_full

Output

Almost Full: When asserted, this signal indicates that only one more write can be performed before the FIFO is full.

data_valid

Output

Read Data Valid: When asserted,this signal indicates that valid data is available on the output bus (dout).

dbiterr

Output

Double Bit Error: Indicates that the ECC decoder detected a double-bit error and data in the FIFO core is corrupted.

Din[WRITE_DATA_WIDTH-1 :0]

Input

Write Data: The input data bus used when writing the FIFO.

dout

Output

Read Data: The output data bus is driven when reading the FIFO

empty

Output

Empty Flag: When asserted, this signal indicates that the FIFO is empty.

Read requests are ignored when the FIFO is empty, initiating a read while empty is not destructive to the FIFO.

full

Output

Full Flag: When asserted, this signal indicates that the FIFO is

full.

Write requests are ignored when the FIFO is full, initiating a write when the FIFO is full is not destructive to the contents of the FIFO.

injectdbiterr

Input

Double Bit Error Injection: Injects a double bit error if the ECC feature is used on block RAMs or UltraRAM macros.

injectsbiterr

Input

Single Bit Error Injection: Injects a single bit error if the ECC feature is used on block RAMs or UltraRAM macros.

overflow

Output

Overflow: This signal indicates that a write request (wren) during the prior clock cycle was rejected, because the FIFO is full. Overflowing the FIFO is not destructive to the contents of the FIFO.

prog_empty

 

Programmable Empty: This signal is asserted when the number of words in the FIFO is less than or equal to the programmable empty threshold value.

It is de-asserted when the number of words in the FIFO exceeds the programmable empty threshold value.

prog_full

 

Programmable Full: This signal is asserted when the number of words in the FIFO is greater than or equal to the programmable full threshold value.

It is de-asserted when the number of words in the FIFO is less than the programmable full threshold value.

rd_clk

Input

Read clock: Used for read operation. rd_clk must be a free running clock.

rd_data_coun[RD_DATA_COUNT_WIDTH-1:0]

Output

Read Data Count: This bus indicates the number of words read from the FIFO.

rd_en

Input

Read Enable: If the FIFO is not empty, asserting this signal causes data (on dout) to be read from the FIFO.

Must be held active-low when rd_rst_busy is active high.

rd_rst_busy

Output

Read Reset Busy: Active-High indicator that the FIFO read domain is currently in a reset state.

rst

Input

Reset: Must be synchronous to wr_clk. Must be applied only when wr_clk is stable and free-running.

sbiterr

Output

Single Bit Error: Indicates that the ECC decoder detected and fixed a single-bit error.

sleep

Input

Dynamic power saving: If sleep is High, the memory/fifo block is in power saving mode.

underflow

Output

Underflow: Indicates that the read request (rd_en) during the previous clock cycle was rejected because the FIFO is empty.Under flowing the FIFO is not destructive to the FIFO.

wr_ack

Output

Write Acknowledge: This signal indicates that a write request(wr_en) during the prior clock cycle is succeeded.

wr_clk

Input

Write clock: Used for write operation. wr_clk must be a free running clock.

wr_data_coun[WR_DATA_COUNT_WIDTH-1:0]

Output

Write Data Count: This bus indicates the number of words written into the FIFO.

wr_en

Input

Write Enable: If the FIFO is not full, asserting this signal causes data (on din) to be written to the FIFO.

Must be held active-low when rst or wr_rst_busy is active high.

wr_rst_busy

Output

Write Reset Busy: Active-High indicator that the FIFO write domain is currently in a reset state.

接口参数描述如下:

Attribute

Allowed Values

Default

Description

CDC_SYNC_STAGES

2 to 8

2

Specifies the number of synchronization stages on the CDC path Must be < 5 if FIFO_WRITE_DEPTH = 16

DOUT_RESET_VALUE

String

"0"

Reset value of read data path.

ECC_MODE

"no_ecc",

"en_ecc"

"no_ecc"

 "no_ecc" - Disables ECC

 "en_ecc" - Enables both ECC Encoder and Decoder

FIFO_MEMORY_TYPE

"auto",

"block",

"distributed"

"auto"

Designate the fifo memory primitive(resource type) to use.

 "auto" - Allow Vivado Synthesis to choose

 "block" - Block RAM FIFO

 "distributed" - Distributed RAM FIFO

FIFO_READ_LATENCY

0 to 10

1

Number of output register stages in the read data path.

If READ_MODE = "fwft", then the only applicable value is 0.

FIFO_WRITE_DEPTH

16 to 4194304

2048

Defines the FIFO Write Depth, must be power of two.

 In standard READ_MODE, the effective depth = FIFO_WRITE_DEPTH - 1

 In First - Word - Fall – Through READ_MODE, the effective depth =FIFO_WRITE_DEPTH + 1

FULL_RESET_VALUE

0 to 1

0

Sets full, almost_full and prog_full to FULL_RESET_VALUE during reset

PROG_EMPTY_THRESH

3 to 4194301

10

Specifies the minimum number of read words in the FIFO at or below which prog_empty is asserted.

 Min_Value = 3 + (READ_MODE_VAL * 2)

 Max_Value = (FIFO_WRITE_DEPTH - 3) -(READ_MODE_VAL * 2)

If READ_MODE = "std", then READ_MODE_VAL = 0; Otherwise READ_MODE_VAL = 1.

NOTE: The default threshold value is dependent on default FIFO_WRITE_DEPTH value. If FIFO_WRITE_DEPTH value is changed, ensure the threshold value is within the valid range though the programmable flags are not used.

PROG_FULL_THRESH

5 to 4194301

10

Specifies the maximum number of write words in the FIFO at or above which prog_full is asserted.

 Min_Value = 3 + (READ_MODE_VAL* 2 * (FIFO_WRITE_DEPTH/ FIFO_READ_DEPTH)) + CDC_SYNC_STAGES

 Max_Value = (FIFO_WRITE_DEPTH- 3) - (READ_MODE_VAL *2 * (FIFO_WRITE_DEPTH /FIFO_READ_DEPTH))

If READ_MODE = "std", then READ_MODE_VAL = 0; Otherwise READ_MODE_VAL = 1. NOTE: The default threshold value is dependent on default FIFO_WRITE_DEPTH value. If FIFO_WRITE_DEPTH value is changed, ensure the threshold value is within the valid range though the programmable flags are not used.

RD_DATA_COUNT_WIDTH

1 to 23

1

Specifies the width of rd_data_count FIFO_READ_DEPTH = FIFO_WRITE_DEPTH *WRITE_DATA_WIDTH / READ_DATA_WIDTH

READ_DATA_WIDTH

1 to 4096

32

Defines the width of the read data port, dout

READ_MODE

"std", "fwft"

"std"

 "std" - standard read mode

 "fwft" - First - Word - Fall – Through read mode

RELATED_CLOCKS

0 to 1

0

Specifies if the wr_clk and rd_clk are related having the same source but different clock ratios

USE_ADV_FEATURES

String

"0707"

Enables data_valid, almost_empty,rd_data_count, prog_empty, underflow,wr_ack, almost_full, wr_data_count, prog_full,overflow features.

 Setting USE_ADV_FEATURES[0] to 1 enables overflow flag; Default value of this bit is 1

 Setting USE_ADV_FEATURES[1] to 1 enables prog_full flag; Default value of this bit is 1

 Setting USE_ADV_FEATURES[2] to 1 enables wr_data_count; Default value of this bit is 1

 Setting USE_ADV_FEATURES[3] to 1 enables almost_full flag; Default value of this bit is 0

 Setting USE_ADV_FEATURES[4] to 1 enables wr_ack flag; Default value of this bit is 0

 Setting USE_ADV_FEATURES[8] to 1 enables underflow flag; Default value of this bit is 1

 Setting USE_ADV_FEATURES[9] to 1 enables prog_empty flag; Default value of this bit is 1

 Setting USE_ADV_FEATURES[10] to 1 enables rd_data_count; Default value of this bit is 1

 Setting USE_ADV_FEATURES[11] to 1 enables almost_empty flag; Default value of this bit is 0

 Setting USE_ADV_FEATURES[12] to 1 enables data_valid flag; Default value of this bit is 0

WAKEUP_TIM

0 to 2

 

 0 - Disable sleep

 2 - Use Sleep Pin

WR_DATA_COUNT_WIDTH

1 to 23

1

Specifies the width of wr_data_count

WRITE_DATA_WIDTH

1 to 4096

32

Defines the width of the write data port, din

FIFO复位时序图:

本文只用到"fwft" - First - Word - Fall – Through read mode这种模式

写时序图:READ_MODE=FWFT, FIFO_WRITE_DEPTH=16, PROG_FULL_THRESH=7

读时序图:READ_MODE=FWFT, FIFO_WRITE_DEPTH=16, PROG_EMPTY_THRESH=5

参数计算

function integer clog2;

input integer value;

begin

value = value-1;

for (clog2=0; value>0; clog2=clog2+1)

value = value>>1;

end

endfunction

 

localparam WFIFO_DEPTH = FIFO_DEPTH;

localparam W0_WR_DATA_COUNT_WIDTH = clog2(WFIFO_DEPTH)+1;

localparam W0_RD_DATA_COUNT_WIDTH = clog2(WFIFO_DEPTH/4)+1;

 

localparam RFIFO_DEPTH = FIFO_DEPTH/4;

localparam R0_WR_DATA_COUNT_WIDTH = clog2(FIFO_DEPTH/4)+1;

localparam R0_RD_DATA_COUNT_WIDTH = clog2(FIFO_DEPTH)+1;

3.7实验结果


路过

雷人

握手

鲜花

鸡蛋

说点什么...

已有1条评论

最新评论...

uisrc2021-8-12 20:29引用

本章节源码下载地址链接:https://pan.baidu.com/s/1NT-ArWeJuLTtPX-Fv1oGFA 提取码1111

查看全部评论(1)

本文作者
2021-8-12 09:43
  • 6
    粉丝
  • 690
    阅读
  • 1
    回复
  • 1
  • 2
  • 3
热门评论
排行榜

关注我们:微信订阅号

官方微信公众号

官方微信公众号

客服服务热线:

0519-80699907

常州-总部:常州溧阳市天目云谷3#楼北201B/201C

南京-分部:南京市栖霞区仙林大道181号5幢2220/2221室

邮编:213300 Email:tjy@uisrc.com

Copyright   ©2020-2026 内容版权归©UISRC.COM    ( 苏ICP备19046771号-2 )