Menu Close

图像采集与传输理论答疑(2)

原本的论坛问题:图像采集与传输理论课程的疑问

因为在论坛上有书写格式和展现形式的限制,并且该同学的问题量太大,为了更好的解释,选择将内容从论坛区挪到文章区。图像采集与传输理论答疑(1)收录了前25个问题和解答,本文将继续解答后续的问题。

这里解答的问题,希望能给有类似疑惑的同学提供参考,也鼓励大家在IC知识库论坛上踊跃提问,互相解答。这里的问题有些是和ov5640图像采集与传输理论相关,需要参照相关的工程,有些问题是比较广泛的疑问,扩展学习可以通过在文中提供的链接,找到本网站上其它专题的文章。

注意:以下解答中,将问题和解答用不同颜色加以区分,蓝色为解答,A表示Answer(解答)。

 

26.

%title插图%num

%title插图%num

  • 状态2和状态4时这部分程序是不是重复了?状态4的这部分程序是不是可以去掉的?然后把摄像头输出几次组成一个像素的程序写在状态2的后面就可以了。

A:不可以, 在状态机2中,当camera_de 有效时,立马就离开了,也就是说只是拿到了一个图像数据, 状态机4是在连续拿图像数据的。

 

  • 这段程序结尾处,if(wr_cnt[0]) app_we <= 1;

当第一个camera_data_r赋值给app_din时,wr_cnt[0]==1,当第二个camera_data_r赋值给app_din时,wr_cnt[0]==0。但是程序中是if(wr_cnt[0]),也就是当wr_cnt[0]值为1时,感觉有点不对的。

A: 没有问题的, 注意理解阻塞赋值,和非阻塞赋值的区别。参考文章:https://www.icfedu.cn/archives/4222

%title插图%num

 

27.

%title插图%num

app_wr_start_r <= {app_wr_start_r[1:0], 1’b0}; 这种写法感觉像是延迟信号一样。

  • 如果只是为了持续信号较长时间,可以将app_wr_start_flag赋值给一个信号,然后进行计数时钟周期,在计数时钟周期的内这个信号一直处于高电平课检测状态,这时想设置计数几个周期就几个周期,最后计数周期结束后让这个信号赋值为0。这样的信号会一直持续高电平,更有利于信号的被检测。

A:可以, 你会发现最后实现的逻辑,和这个是一样的, 很有可能,更加繁琐。但只要实现相关的功能即可。

 

  • 是不是摄像头的时钟频率比ddr的时钟频率低,所以摄像头频率下所产生的信号不容易被ddr所检测到?所以才采用了这种写法。如果摄像头的时钟频率比ddr的时钟频率高或者相等的话,是不是就不用写这段程序,因为可以被检测到数据信号。

A:摄像头的时钟频率比ddr的时钟频率低,摄像头频率下所产生的信号更容易被ddr所检测到。这种写法是为了适应 摄像头频率 大于 或小于 ddr时,都可以使用。不同的频率,只要修改reg【n:0】 app_wr_start_r 即可。

 

28.

%title插图%num

%title插图%num

  • 可以理解这段程序的意思:当摄像头将一行数据信息传输到fifo时,写请求置为0,并且通过ddr_wr_ack_pos告诉摄像头此时fifo中数据已经传输给ddr,等待摄像头的再次传输数据。

A: 是的

 

  • 不明白的地方是ddr的行地址不是【13:0】吗?列地址是【9:0】,这个页地址是什么?为什么程序中的行地址是【10:0】?为什么没有列地址?没有明白图中画方框地方的意思。也就是ddr准备接收fifo中数据时的内部寄存器是怎么变化的?

A:在ddr_ctrl.v 中补齐的

%title插图%num

 

29.

%title插图%num

状态3的30hz是怎么得到的?摄像头的时钟频率不是24m吗?

A :摄像头的pclk 不是24M,24M是fpga 输出给ov5640芯片的参考时钟,ov5640返回的时钟(pixel clock) 不是24M

%title插图%num

 

30.

%title插图%num

这段程序没有看明白,注释说明能看懂,程序看不懂。app_wr_line_num、hdmi_rd_num、hdmi_page_id的含义是什么?

A:app_wr_line_num[12:11] 对应的ddr 芯片的物理地址正好是一个整页的地址。Hdmi_page_id 将app_wr_line_num[12:11] 同步到vga_clk 时钟域下使用。

%title插图%num

%title插图%num

 

31.

%title插图%num

这个数据读使能和数据有效的区别是什么?读使能为1时数据才能从fifo中读出来,从fifo读出数据后,读数据有效才为1,是不是这样理解的?

A : 发送fifo rd 信号, 到fifo 读出数据是需要时钟周期的,不能立马得到,所以会有时钟的差别

 

32.

%title插图%num

%title插图%num

hdmi_end在两个地方的含义不一样,应该是第一张图片中的含义。但是在这个状态2中,假设刚开始时,数据还没有从fifo写到hdmi中去,也就不会有一行的数据,那么hdmi_end的值会一直为0,就会一直停留在状态2中出不去,感觉这是不对的,求老师的见解。

A:对,按第一张图的说明为准(HDMI场信号)

 

33.

%title插图%num

%title插图%num

  • 这里hdmi的行数据仍然采用1280,但是adv7511的像素是rgb888,一共24位比特,也就是3B,所以应该是一行数据的显示区域值640×3B,才是rd_cnt的计数值。

A:从ddr里读出的输出是16bit的, 在display.v 中从fpga 输出到adv7511时,变化为24bit了

%title插图%num

 

  • 额外提问一个问题,老师,比如像程序中的fifo,写数据时,宽度为16比特,深度为1028次,一个16比特的数据写进这样的fifo中,是一个时钟周期就能写进去?还是一比特一比特的写进去,需要16个时钟周期?

A:一次性写入16bit (一个时钟周期)

 

34.

%title插图%num

%title插图%num

老师,这个听了好几遍,没有听懂你的意思。现在是知道first模式的第一个数据在读使能来之前就已经出来了,是表示第一个数据不用读使能也可以读出来吗?图中是前显模式比正常模式的数据快了一个周期,问题是前显模式的第一个数据到底是个什么状态,怎么去使用的问题?

还有你说是因为ddr才选用这种的原因也没有听懂,希望能再讲解一下,老师。

A:fifo的问题相对比较复杂,配置模式也是比较多的,first word fall through 模式, 会将写入fifo的数据,自动保留到读端口上, 而不需要读信号使能, 但要主要连续读出和断断续续的读出, 数据是否还是正确的, 这一点,希望同学自己做一个FIFO的例子, 仿真一下试试。在这篇文章中使用的FIFO配置还是比较特殊的,不但使用了first word fall throght的模式, 同时配合了ip和的内部功能:

%title插图%num

这样的配置,可以保证在没有读fifo时,端口上已经有所需要的数据了, 同时在断断续续的读时,保证数据是正确的。

 

35.

%title插图%num

%title插图%num

  • 老师,你在讲ddr程序的时候,说到app_rd_data_valid比app_rd_data_end晚了一个时钟周期,怎么看出来的?app_rd_data_valid和app_rd_data的时钟周期是同步的,app_rd_data_end是app_rd_data最后一个时钟时显示高电平。

A: 可能上课的时候说的不对,在实际的运行结果上看, app_rd_data_end 一直是有效的,这个信号是由mig ip 核输出的。

%title插图%num

 

  • ddr_ready是一直处于高电平吗?或者说在什么时候处于高电平,什么时候处于低电平?因为从图中看ddr_ready是一直处于高电平的。

A: 在mig IP reset 时, 不是高电平, 他代表mig IP 核准备好了, 校准已经完成了,才会设置为 高电平

 

36.

%title插图%num

  • 这两个状态是不是不可能同时发生?就是ddr一边读取fifo中的摄像头数据,一边向hdmi的fifo写进数据。

A: 对,是有优先级顺序的, 即使ddr_wr_start_flag 和 ddr_rd_start_flag 同时到来, 也先除了ddr_wr_start_flag, 然后处理 ddr_rd_start_flag, 注意,这两个信号是长周期有效的信号,利用的是ddr 读取速度快的特点, 在hdmi 显示输出一行的时间内, 一定有机会读取到数据

  • assign test_pin = toggle[1]; 表达什么意思。

A:测试信号, 目前没有使用

 

37.

%title插图%num

这种写法是什么意思?括号里边出现的信号。

A: always 语法, ()里面表示的是敏感量列表: 具体参照:https://www.icfedu.cn/archives/5094

 

38.

%title插图%num

我记得以前老师说过,直接在FPGA中使用乘法或者除法是非常占用内部资源的,这里能不能通过右移4位的方式缩小数值?

A:是的,以前老师说得没有错, 但这里,我们发现 除数,被除数都是固定值, 在系统预编译(综合)的时候, 已经替换为常数了, 并没有生成电路逻辑。

 

39.

%title插图%num

  • 划线部分为什么是>=,一般不都是<=号码?这两个使用有什么区别?是多出一个时钟周期的区别吗?

A: >= , <= 根据实际需要, 没有强行的规定。 这里的>= 保证状态机可以准确的跳转到状态机4, 实际上addr_num == BURST_RD_128BIT 时,就可以跳转了。注意”<=”出现在赋值语句中,不是代表“小于等于”,而是表示非阻塞赋值。

  • 状态3和状态4不太明白。这里不管是读数据还是写数据都是ddr发出的数据,说明已经写完了摄像头的数据或者将数据已经写进下一个fifo中去,对应的信号是app_wr_ack和ddr_rd_ack。

如果读出数据有延迟,是不是ddr写进数据也有延迟的?

A: 数据写入ddr 流程是状态0 – > 1 -> 3 – > 0; 数据从ddr中读出的流程是: 0 -> 2 -> 4 – > 0 ,不管写入或者读出, ddr_ctrl.v 都向mig IP 核发送地址, 写ddr时 ,发送数据给ddr, 读ddr时, 等待数据从ddr 中返回。

  • BURST_RD_128BIT数值不应该减1吗?

A: 从ddr中读数据, 可以多读一些, 只要我们所需要的数据被写入到fifo中即可

 

40.

%title插图%num

%title插图%num

这个ddr_ready是ddr芯片校准完毕的信号,在pic_storage程序中直接使用了,并没有打一拍,但是在ddr_ctrl程序中没有使用,反而打了一拍,这是为什么?

A: 在pic_storage.v中 ddr_ready 数据 被锁存一次, 最后形成 cam_ready;

在 ddr_ctrl.v 中 ddr_ready 数据 被锁存一次, 最后形成 ddr_ready_r;

Cam_reay, ddr_ready_r 的目的是保持这些信号和当前的时钟域是同步的。

 

41.

%title插图%num

%title插图%num

  • 根据第一张图,app_en_r是什么意思?好像也不是ddr输出的信号。
  • app_en_r是什么意思?好像不是ddr输出的信号。
  • app_wdf_end为什么可以等于app_wdf_wren?

A: app_en_r 是一个中间信号, 这个信号的形成是有一些规则的, 主要的目的是为了防止ddr 写入,读取时发生的断断续续的情况, 而断断续续的情况是由ip 产生的, 我们没有方法阻止。使用app_en_r 信号是为了保证数据正常写入或者读出, 具体可以看看mark_deubg 输出的波形。App_wdf_end , app_wdf_wren 是可以一起赋值的, mig IP 是可以承认的。

%title插图%num

 

  • 为什么app_rdy 、 app_en_r 、 app_wdf_rdy 、 app_wdf_wren这4个信号&在一起,wrnum信号就可以计数了?还有画红线的地方,老师能说说这几个信号的关系吗?app_cmd、app_addr、app_en、app_rdy、app_wdf_mask、app_wdf_rdy、app_wdf_data、app_wdf_wren、app_wdf_end。因为根据程序中写的,比如app_wdf_wren = app_rdy & app_en_r & wr_en; 好像利用其他信号的组合可以表示另一种信号,这是什么关系?

A: 上图中,是mig IP 核所需要的信号, 有些是输出信号, 有些是输入信号。这是官方的标准,同时指出了 写数据的时候, 和写地址的对应关系。 我们在实际实现功能的时候, 只要满足官方提供的标准(其中一种情况)即可,所以我们使用app_en_r 配合这些信号一起来使用。 我们实现的方法是: 在app_en,app_rdy 有效的时候, app_wdf_wren , app_wdf_rdy 也必须同时有效 ,框图中的第一种情况。虽然官方手册没有强制规定使用第一种情况, 但在我们的程序中, 觉得第一种情况比较好处理。

注意:app_rdy, app_wdf_rdy 不是一直有效的, 他们什么时候失效,是不可预知的。可以多使用mark_debug 测试一下, 就能理解了。

%title插图%num

 

42.

%title插图%num

划线这段没有想明白,为什么是相等的。

A:当app_addr[2:0] == 0 时,

app_addr[26:3] <= app_addr[26:3] + 1 等效与 app_addr <= app_addr + 1;

举例:

reg [4:0] a = 0;

a = a + 8 ;

等效于: a[4:3] <= a[4:3] + 1;

 

43.

%title插图%num

这个延迟是所有hdmi都有的吗?通过IIC传输一次数据就延迟5ms?但是学HDMI时好像没有提到这个。

A:不是每个寄存器都需要, 这里是为每个寄存器赋值后都延迟/delay 了一端时间, 这只是会增加adv7511 初始化的时间, 注意阅读adv7511的寄存器手册, 有些寄存器设置后, 是需要delay 时间的。

 

44.

%title插图%num

%title插图%num

%title插图%num

  • 文件中器件地址显示为72,程序中为什么是39?

A: 7’h39 = 7’b011_1001; 地址8’h72 = 8’b0111_0010 , 注意如果使用7bit作为i2c地址时,真实发生的地址为: {7’b011_1001, wr/rd}; 需要增加1bit 作为wr/rd (读地址, 还是写地址)。 如果使用8bit地址时:8’h72 就是写地址, 8’h73 就是读地址

 

  • 文件中寄存器地址和程序中的寄存器地址匹配不上,并且寄存器地址的个数也不一样。

A:文档中给出的是一个例子的参考, 我们不一定需要严格按照这个文档执行, 还是要理解相关寄存器的含义

 

45.

%title插图%num

  • pin是什么?为什么要把vga_clk 输出到pin 上?

A: pin 是指真实的fpga 管脚

  • 为什么直接使用assign HDMI = vga_clk;会影响vga_clk 的品质?而原语就不会的?

A: vga_clk 是时钟线, 如果将其直接输出到pin上, vga_clk线上的抖动会影响vga_clk的相关状态机逻辑。 原语 不是将时钟输出到pin上, 而是一个双边缘的d触发器的q端输出的pin上(不是时钟线,可以认为是数据)

  • hdmi_pclk_out中,为什么复位和置位是0?

A:没有对这个原语做置位, 也没有做复位

  • 这个原语在哪里找的?原语起到什么作用。

%title插图%num

A:源语的种类很多, 可以到xilinx的官方网站上得到所有源语的信息(搜索)

%title插图%num

 

  • vga_clk的pll产生的,然后通过例化的方式将信号传递了出去,为什么还会有原语的存在?

A: 这里的原语使用, 是不想把vga_clk 直接输出到芯片(FPGA)外部去。

 

46.

%title插图%num

  • 这个伴随时钟是什么?为什么摄像头会有这个时钟?摄像头的时钟不是pll产生的24m时钟吗?这两个时钟有什么关系吗?这个伴随时钟有什么用?在以后的设备硬件中怎么判断有没有伴随时钟的?

A: 24M是FPGA输出的参考时钟, camera_pclk 是ov5640 输入给FPGA的时钟,camera_pic_clk 为从端口进来的时钟放入到FPGA内部的全局时钟线上。

%title插图%num

  • 看了程序,发现输出的camera_pic_clk没有参与其他程序。

A:这个时钟一直都在使用,只是更改了名字

%title插图%num

 

  • 根据老师说的,因为这个伴随时钟进入了一个区域性是时钟通道,不是全局性的时钟通道,所以不能走到FPGA的所有寄存器内,所有要变成全局性的时钟。问题是怎么判断是区域性的时钟通道?还是全局性的时钟通道?

还有既然输出的camera_pic_clk没有参与其他程序,是不是就没有什么用?也不用将区域性的变为全局性的了?

A: 看问题1,2 的解答

 

47.

%title插图%num

%title插图%num

%title插图%num

  • 摄像头接入的是GPIO1和GPIO2,第二张图的右边是摄像头与GPIO的引脚对应图?

A: 是的, 第一张图是FPGA(prx100t)的原理图截图, 第二张为摄像头(ov5640)的原理图

 

  • 第二张图左边图中,希望能给出第三图中对应数据信号引脚,尤其的摄像头的8位数据引脚接口在哪里?因为老师给的说明书没有怎么看明白这个问题,或者老师直接在说明书中指出。

A: 给学员提供的工程中有约束文件(*.xdc 文件),里面包括有管脚约束(关于管脚的定义的)。

%title插图%num

 

48.

%title插图%num

这个程序最后的串口输出读数据,我觉得也可以这样表达:

txd_data <= txd_data_ov5640 || txd_data_adv_7511,因为串口只有一个,每次只能读一个数据,不是摄像头的,就是ADV7511的,不用利用读使能来进行选择。

A: txd_data 是FPGA 输出信号, 所以必须使用txd_data <= txd_start_ov5640 ? txd_data_ov5640 : txd_data_adv_7511 这样的写法。不能使用 txd_data <= txd_data_ov5640 || txd_data_adv_7511

原因: 当需要txd_data_adv_7511输出时, 恰好这时的txd_data_ov5640 = 1(数据不发生时, 保持txd 为高电平,这个是常态); 那么txd_data 将永远为 1, 数据不能正确发出。

 

49.

%title插图%num

%title插图%num

  • 有个疑问,摄像头和FPGA用类IIC的通讯方式通讯,FPGA是主机,摄像头是从机,摄像头将图像数据写进FPGA中, 那就是主机读取从机的值,是第二张图中的写数据还是读数据?

A: 不是, SCCB 协议是控制ov5640 芯片寄存器的, 不负责图像数据的输出,图像数据是从camera_data, camera_pclk, camera_href, camera_vsync 输出的,ov5640的图像数据输出, 不再需要FPGA控制, 也就是说, 不论FPGA是否读取ov5640的图像数据, ov5640的图像数据依然会源源不断的输出, 至于FPGA能否接住, ov5640 不管。

 

  • 还有串口的写数据和读数据,写数据是写摄像头的寄存器地址和值,读数据时先写寄存器的地址,然后就会读出寄存器的值。是第二张图的那种形式?

A:

%title插图%num

  • 根据图中,寄存器地址是2个字节,就是Sub-address(H)和Sub-address(L),但是后面的Writa Data是什么值?是寄存器地址的值还是图像数据的值?

其实想问图像数据的值应该也是通过IIC的通过输出的,但是把寄存器地址的值放在哪里了?所以一直很困惑。

A: 寄存器地址的值, SCCB 中没有任何的图像数据,都是配置信息。

 

  • 一般怎么判断寄存器的地址和值,是不是一般低位的8比特是值,其余的高位就是寄存器的地址?

A:根据SCCB 协议的定义,

%title插图%num

 

50.

%title插图%num

这个IIC的速度设置,是怎么参考设置的?或者说为什么是99,可以设置其他值吗,是怎么设置的?

A: 不是一个精准的时间,但是计算的方法是: 100k 12C 波特率 一个时钟周期大约是10us, 而i2c_master_bit_ctrl.v中的clk_en 信号的产生,大约是 (0- 99) 100次 * 20ns(50M 时钟) = 2 us 。 c_state 状态机 大约是4个clk_en, 或者5个 clk_en 执行一次完整的scl 周期,最终计算的结果大约是100K scl 频率。 注意, i2c 并不需要scl 时钟非常准确。

 

Posted in FPGA, Verilog, 开发板, 文章

发表评论

相关链接