前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >UDP的FPGA实现(下) | 基于UDP的图像传输工程分析

UDP的FPGA实现(下) | 基于UDP的图像传输工程分析

作者头像
根究FPGA
发布2020-06-30 11:51:24
1.6K0
发布2020-06-30 11:51:24
举报
文章被收录于专栏:根究FPGA根究FPGA根究FPGA

本章节分析基于以太网图像传输工程,其实上周就已经做完,只不过实在是难以总结,代码的理解有时候真的要自己去逐词逐句的分析,不然也就只能理解其过程,无法重新复现,工程下载链接:

http://www.corecourse.cn/forum.php?mod=viewthread&tid=27941&highlight=以太网

接下来对OV5640_eth_udp进行重点分析,整个项目分成四部分,分别是OV5640配置驱动模块、SDRAM配置驱动模块、UDP发送模块,UDP-SDRAM数据读取模块。

一、OV5640配置模块

ov5640_init_table

在配置表中,数据的高16位为寄存器的地址,低8位为要向该寄存器写入的控制字。

调用时:

`elsif OV5640    
  wire [23:0]lut;
  localparam lut_size = 252;  
  localparam device_id = 8'h78;
  localparam addr_mode = 1'b1;
  ov5640_init_table cmos_init_table(
    .addr(cnt),
    .clk(Clk),
    .q(lut)
  );
  assign addr = lut[23:8];
  assign wrdata = lut[7:0];

IIC配置(cmos_init)

1、在上电20ms执行IIC初始化程序

实现方式,在初始化模块执行一个在上电之后,使用一个计数器进行计数,经过20ms也就是20_000_000ns,所以将计数到20ms左右,20’hffffe时候产生一个高脉冲,清零配置模块计数器,开始数据写入配置操作。

在每次读写操作完成且收到应答信号后,配置表映射地址加一,读取出下一个要配置的寄存器地址及数据。

在从配置表读取出的数据量小于lut_size时,执行状态机,该状态机的机制就是:

空闲时为IDLE,在检测到Go信号之后跳转到state1,也就是发出读写请求(wrreg_reg),然后跳转到state2等待读写操作完毕,再返回state2。

在i2c_control.v模块检测到读写请求后,开启计数器计数使能,同时根据cmd指令中是否包含产生起始信号指令,是的话就跳转到GNE_STA,根据cnt计数器对SDA、SCL进行操作。

在cnt=3时,将SCL拉低,为接下来的数据写入做准备,同时根据CMD中是否存在写地址跳转到相应的WR_DATA状态。

在WR_DATA状态中,使用线性序列机进行数据操作,将一bit数据操作分成四部分,

(1)、将数据放到SDA总线,SDA输出使能

(2)、将SCL拉高,SCL的上升沿将数据送入到OV5640中

(3)、SCL保持高电平

(4)、将SCL拉低,为下一次数据写入做准备。

在cnt==31时,跳转到Check_ACK状态。

在Check_ACK状态,cnt从0计数到3,在cnt=3时跳转,分成四部分:

(1)、 关闭输出使能,即将i2c_sdat_oe <= 1'd0,同时将SCL拉低(防止SDA变化导致误触发)

(2)、将SCL拉高,在SCL的上升沿将SDA应答数据读出

(3)、将应答信号给ack_o,SCL保持为高

(4)、将SCL拉低,为下一次的数据传输做准备。

之后根据是否有GNT_STO产生停止信号,分为四个步骤:

(1)、SDA输出使能打开,将SDA拉低

(2)、将SCL拉高。

(3~4)、保持,4时跳转到IDLE。

OV5640数据读取

在5640配置完成之后,丢弃前10帧图像。

二、UDP发送模块

该部分包含以太网发送eth_send、CRC校验crc32_d4、校验和checksum、异步fifo send_dcfifo四个模块。

send_dcfifo(异步fifo)

可异步清零,作为一个异步fifo,该模块的读写操作分开。

对于写数据操作:

当img_send模块的写入数据有效且package_state为1时即为有效的数据写入请求。

为何写请求操作还要受到package_state的控制?

因为package是eop一个周期的延迟,eop为1时vcnt_full为1,此时一帧数据传输完毕,将进行场消隐操作,所以关闭异步fifo写入使能,在检测到帧起始信号后再将package_state信号拉高,允许数据写入。(等待fifo有足够的写入空间)

那么此时从SDRAM中读取出的数据如何处理?(删除此部分)

从sdram的读取请求信号是收到state控制的,在state==1时,向sdram发出读取请求信号,而跳转到state==1说明跳转前fifo_available,在写入一行像素数据后,状态机跳回到state==0,此时,可能不会有fifo_available信号,需要等待fifoavaliable从而将sop拉高,所以此时,如fifoavailable==0时,不会发出SDRAM读取请求,sop也不会为1,在fifoavailbale==1时,sop为1,继续下一次的数据写入。

对于读数据操作:

udp数据长度为1282,当DCFIFO中数据长度大于1282x2时(读取数据宽度为4),发送使能信号拉高一个周期,在TX_GO拉高时对源主机mac地址、数据长度进行寄存。同时将发送使能控制寄存器拉高,开启帧数据发送,对于其中的数据部分,根据cnt控制是否使能数据发送。

三、UDP-SDRAM发送模块

该模块从SDRAM读取像素数据,将像素数据发送到UDP发送模块的异步FIFO中。

在每次上电后,需要对SDRAM中的数据进行清除,所以使用frame_sync作为标志信号进行清零操作。

延时一段时间后,将send_en置一。

在send_en==1时,判断fifo_available信号,在send模块的fifo有空闲空间时,state==1,每发送完一行数据,跳转回state==0。

在state==1时,对hcnt进行计数,计数到一行的最大值,在计数到最大值之后将hcnt_full置一,为什么要有hcnt_full,是因为在hcnt=0时发送的是行号,在hcnt=1时发送第一列,在hcnt=WIDTH-1时候发送第W-1列,在hcnt_full时发送最后一列的像素数据。

在hcnt_full等于1时,将vcnt加1,加满后清零。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 根究FPGA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ov5640_init_table
  • IIC配置(cmos_init)
    • 1、在上电20ms执行IIC初始化程序
    • OV5640数据读取
    • 二、UDP发送模块
      • send_dcfifo(异步fifo)
      • 三、UDP-SDRAM发送模块
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档