Menu Close

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

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

 

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

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

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

 

1.

%title插图%num

  • 这个上电设置,我的理解是对硬件内部的各个组成块不同时间进行通电,最后以达到整个系统全部通电的过程。我觉得这个上电时间设置不是应该提前做好最优模式就行了,为什么还要供用户来选择时间?我觉得最优模式能使硬件达到最好的状态,用户自己配出来的时间可能导致硬件不能发挥应有的性能。

A: 每个芯片一般都有自己的上电要求,不同的芯片,上电要求也不相同。一般情况下, 芯片设计这都会在文档中告诉用户, 如何上电, 以及上电顺序,这种事情在芯片行业很常见。 例如,咱们使用的xilinx artix 100t 芯片, 同样也有上电要求。用户只要根据手册,满足要求即可。

 

  • 像这类的有上电选择的硬件一般是怎么知道的?就是要用这个硬件,怎么知道它是需要上电选择的?或者是哪一类的硬件是具有这种功能的?我们应该怎么区分,还是靠经验?因为说明书一般是英文的,不易发现是不是需要上电的,所以应该有另一种方法来区分吧。。。。。。

A: 一般来说, 在使用一个芯片的时候, 要仔细阅读芯片手册, 一般芯片手册都是会讲解的。没有什么规律证明, 哪些芯片需要上电顺序, 哪些不需要。 这个需要硬件设计者仔细阅读文档。 或者咨询芯片厂家,做硬件设计的人员一定需要注意。

 

2.

%title插图%num

%title插图%num

  • 老师,在这个上电程序里,出现了camera_pwup、cam_resetb、initial_en这三种上电信号,经过计算,时间上分别对应0.4s、0.8s、3.6s。这个时间偏大了会不会影响实际的效果?在实际应用选择中该如何去选择时间的大小?

A: 这些时间常数远远大于手册的要求(满足手册中的需求, 同时还有很大的余量),在实际使用中不会影响芯片的使用。 原因是芯片手册一般给出的都是所需要的最小时间, 时间大都是没有问题的。之所以实际的时间远远大于手册上的需求,是因为在硬件电路上, 还增加了RC 的上电延迟电路, 使得整体上电复位时间增加了。

 

  • 对于程序出现的else cam_pwr_cnt <= cam_pwr_cnt,从一开始学习的时候没有太明白是想表达什么意思?可不可以删除掉这句?因为前面的语句意思已经表达清楚了,cam_pwr_cnt总是在自加1:cam_pwr_cnt <= cam_pwr_cnt + 1 。

A: 是的, 可以删除。

reg [31:0] cam_pwr_cnt = 0 ;

always @ ( posedge clk_50m )

    if( rst_n == 1’b0 )

        cam_pwr_cnt <= 0;

    else

    begin

        if (cam_pwr_cnt < 200_000_000)

            cam_pwr_cnt <= cam_pwr_cnt + 1 ;

        else

           cam_pwr_cnt <= cam_pwr_cnt ;

    end

cam_pwr_cnt 在小于200_000_000时,总是在加一, 当大于等于200_000_000时,cam_pwr_cnt 的值再也不会更改了。 增加else ,是明确这个行为。 当然也是可以删除的。

 

3.

%title插图%num

老师,这段程序是不是想的复杂了,当sign_Strobe <= 2’b00,闪光灯的状态是没有激活,也就是灭的状态,sign_Strobe == 2’b10的状态也是灭,最后落实到硬件的状态是一样的,所以没有这样麻烦的写程序。其实闪光灯在现实就灭和亮的两种状态,1比特数据就可以做到,没有必要再去添加其他的信号进行说明。我觉得初始状态不用管,不写程序进行设置就是灭的状态,或者写程序让初始状态保持灭,按键按下就是亮,再次按下按键弹回就是灭了,所以直接用st_mux信号就可以了。因为在实际中闪光灯的选择是根据拍摄环境的具体状态人为判断的,或者根据拍摄后观察的图像质量进行人为判断选择。

A:如果只是实现闪光灯的功能, 也是可以的,同学可以改造这个程序自己试试。但要注意,如果在初始化完成之前(I2C配置), 用户已经按下按键,则结果正好相反。另外在状态机中还要增加相应的控制, 否则当得到st_mux = 0/1 时,会不断的写I2C去配置ov5640。 关于代码中的疑问, 同学可以动手试试, 这样理解会更加深刻。

 

4.

%title插图%num

%title插图%num

%title插图%num

  • 程序中有3c0708这个寄存器,中文手册有,英文手册中没有,这个怎么理解的?

A: 在官方的文档上使用0x3c07寄存器的。

%title插图%num

 

 

%title插图%num

%title插图%num

%title插图%num

  • 程序中寄存器的前两个只能在MIPI中找到,但是程序匹配的VGA,这是不是矛盾了?即使找到了,但是有时显示有,有时显示不需要这两个寄存器,如何正确匹配寄存器?老师。

A: 同学需要看的是官方的ov5640_datasheet.pdf,在其他文档中, 给出的是一些配置不同模式的例子,同学也是可以上网在网上搜索到很多中ov5640配置的例子。例子只是提供一个参考, 具体的还是需要看官方技术手册。

 

 

%title插图%num

%title插图%num

%title插图%num

  • 接下来的寄存器中英文手册与程序中的差异较大,中文手册中381001和381120寄存器不同,不过是为什么?为什么中英文手册差距会这么大?与程序中写的差距也大?

A: 没有看到上图中的差异(0x3810,0x00, 0x3811,0x10)

 

 

%title插图%num

%title插图%num

  • 中英文手册我都是根据4.1标题寻找的,为什么差距会这么大?接下来我只查找中文的,英文的不查找。

A: 这些都是厂家提供的参考文档, 不必纠结格式的问题了。

%title插图%num

%title插图%num

  • 寄存器211和212与手册是匹配不上的,为什么?

A: 同学需要查看ov5640_datasheet.pdf. 0x3821 = 0x07, 0x01, 区别在于是否做图像镜像。

%title插图%num

同学可以动手试试。

 

 

%title插图%num

%title插图%num

  • 寄存器249匹配不上。

%title插图%num

%title插图%num

%title插图%num

%title插图%num

  • 手册中只有到寄存器250,后面的4个寄存器没有了,手册查找也找不到,老师是通过什么资料找到的?为什么可以添加到最后?因为手册上都没有添加。
  • 希望老师能教给我们如何正确的选择寄存器,为什么选择这些寄存器,为什么不选择那些寄存器的原因。还是这些东西是不需要我们查找的?

A: 上面3个问题都需要查看ov5640_datasheet.pdf, 所有的寄存器配置都是可以找到的。同时参考配置只是参考, 实际工作中, 是可以根据自己的需求更改的。

 

5.

%title插图%num

%title插图%num

  • 这个器件地址3c查了老师你给的几个说明书,只有这个里边像一点,但是在MIPI中查到的,我查的这个对不对?不对的话,应该在什么说明书里查找,还有图中的表格不能理解什么意思。

A: 和MIPI 没有任何关系, 当拿到一个芯片时,需要对芯片控制(ov5640) , ov5640采用的是SCCB 控制方式(非常类似与 I2C), 所以需要查找的是这个芯片(ov5640)的I2C (SCCB)地址。

%title插图%num

0x78 = 8’b0111_1000 , 即 写ov5640 地址为 0x78, 读 ov5640时, 地址为0x79. 在FPGA程序中使用的是 {7’b3c, 1’b0, reg_data} , {7’b3c,1’b0} 不就是0x78 吗。

 

  • 一般来说,硬件的器件地址怎么查找?或者一般是什么形式存在的。

A: 查看技术手册, 各个公司都没有一定之规。

 

6.

%title插图%num

这个表示每一位都或运算,表示不能理解最后得到的是什么信号,什么意思?不应是||这个符号吗?

A: reg_wr_i2c, uart_wr_i2c 都是1bit的,这时,‘|’,“||” 运算的结果是相同的。但要注意区别含义上的不同,

‘|’表示 前后两个数(reg_wr_i2c, uart_wr_i2c) 按位或;

“||” 表示reg_wr_i2c 或者 uart_wr_i2c 其中一个 的结果为真/‘1’, i2c_write_req 就为 1。 这是逻辑表达式.

具体可以参考:https://www.icfedu.cn/archives/4222 或者https://www.icfedu.cn/archives/13145

 

7.

%title插图%num

这是闪光灯写入程序,状态3的reg_index <= 253感觉没有什么意义,可以直接状态2后跳到状态0,等待下一个按键的选择。

A: 是的, 可以去掉。 这些疑问, 同学可以动手试试。

 

8.

%title插图%num

这个不应该是&&,这是与操作,一个&的每一位进行与操作,感觉是不对的。

A: 当rxd_done, (rxd_data == 01) 都是1bit时, 可以使用 & ,或者 && 的。

具体参考:

https://www.icfedu.cn/archives/4222 或者https://www.icfedu.cn/archives/13145

 

9.

%title插图%num

这里为什么突然会使用MMCM作为DDR3的参考时钟,如果PLL做的话,有什么区别或差异吗?

A: 作为使用来说,没有差别, 可以使用MMCM , 也可以使用PLL, 但要注意, MMCM和 PLL 的最小输入时钟频率不同, 内部实现方法不同, 功耗不同, 有些频率输出PLL能实现, MMCM则不能。

具体参考: https://www.icfedu.cn/wp-content/uploads/2021-08-14/1628877387-ds181_Artix_7_Data_Sheet.pdf

 

10.

%title插图%num

%title插图%num

%title插图%num

  • Pll中rst_n_50m、rst_n_hdmi、rst_n_ref这3个复位信号是不是效果值是一样的?因为他们都是locked & PB赋值的。在顶层文件中也只是一个按键信PB[1]。

A: 都是将locked & PB 的结果赋值给某个变量,但注意的是,时钟域是不同的。这样,产生的rst信号在其他状态机中使用,可能就是同步reset 信号了, 而不再是异步reset。注意,学习FPGA 和学习软件语言的不同, FPGA是由时钟域概念的,软件没有。

 

  • rst_n_ref在学习DDR3课程中,没有接触到这个复位,能不能讲解一下。

A: 就是对mig 的IP 核 进行复位,使得IP 重新校准FPGA芯片和 ddr3芯片的IO pin 线长。同时初始化IP核里的各种状态机,复位 mig IP 核中的PLL 等等。

 

  • 在程序中这3个复位信号直接赋值0了,是不是多此一举,因为平常语句中一般会有:

always@(posedge clk_50m or posedge rst)begin

if(~rst)

这里就将复位信号置于低电平了。

A: 在仿真的时候,是需要初值的, 否则会造成‘x’的传递

 

11.

%title插图%num

%title插图%num

  • 程序中说这个摄像头硬件的类IIC通讯方式是高电平复位,从哪个说明书的哪里看出来的?我自己查了,没找到。或者说一般是怎么查找的,一般通过看什么能找到这个知识点?

A: 指的是i2c_master_top 模块 的复位信号为高电平。没有相关的文档说明。 只要保证i2c_master_top 能够复位, 在复位结束后能正常工作即可。

 

  • 我的理解initial_en是上电完成信号,这里进行取反,就是上电完成本来是高电平,现在取反是低电平,然后赋值给rst,rst就是低电平,在之后的程序中用的直接是if(rst),这里就是低电平复位?和刚开始说的又相反了?这是为什么?

A:

%title插图%num

 

  • 在i2c_master_top的程序中,使用的是always@(posedge clk or posedge rst),但是之前使用的是always @ ( posedge clk_50m),怎么去区分?可不可以换成之前的形式?为什么?

A: 如果rst 这个信号也是在clk 时钟域下生成的, 使用always @ (posedge clk or posedge rst) 和 always @ (posedge clk) 都是可以的, 但是,代表的含义是不同的,最后生成的逻辑电路也是不同的。 可参考:https://www.icfedu.cn/archives/5178

 

12.

%title插图%num

一般这种形式的语法怎么理解?state == S_RD_ACK成立时,i2c_read_req_ack取值为1,也就是发出读应答结束信号,这样理解对不对?

A: 对 , 可以理解为 i2c_read_req_ack = (state == S_RD_ACK) ? 1’b1 : 1’b0; 即 当state == 15 时, i2c_read_ack = 1;

 

如果括号里边变成state && S_RD_ACK成立时,是不是i2c_read_req_ack同样也会取值为1,发出读应答?如果真的是这样的,是不是不管括号里写的是什么,只要成立,i2c_read_req_ack都会取值1?

A: 不可以,原因 state 不是1bit的变量, 举例 i2c_read_req_ack = state && S_RD_ACK; && 是逻辑运算, 当state != 0 时 为真 (1) ; S_RD_ACK 是15 , 并不是0, 所以 S_RD_ACK 也是为真的(1)。 所以 i2c_read_req_ack = state && S_RD_ACK; 等同与 i2c_read_req_ack = 真 && 真; i2c_read_req_ack = 1 && 1; i2c_read_req_ack = 1 (真); 结论,只要state != 0, 这个结果永远为真(1)。

 

13.

%title插图%num

这段程序中的done和irxack分别是什么意思?

A: 可以跟踪一下代码,done 表示产生i2c ack 信号, irxack 表示得到设备返回的ack结果。

 

14.

%title插图%num

这个S_WR_ACK是S_WR_STOP产生的,我觉得STOP完后,产生一个结束信号就可以,为什么还多出来一个S_WAIT?然后在转到空闲状态。

A: 有时会配合其他状态机,需要等待其他信号复位,作为I2C来说, 100k ,400k的波特率都是一个大概的范围, 即使有一些误差,也是没有问题的。

 

15.

%title插图%num

关于这个reg_data。这是寄存器地址加数据,我疑惑的地方的为什么数据会提前给出值来?我是这样想的,摄像头拍摄到的画面是时刻变化的,因为所转化成的数据也是时刻变化的,但是这里已经提前给出了数据值,这是为什么?

A: 这些数据都是配置ov5640参数的, 不是图像数据, 这些参数,不会随着图像改变而改变的。

 

16.

%title插图%num

%title插图%num

后面的S_RD_DEV_ADDR0和S_RD_DEV_ADDR1对应的是读数据,是不是只写第一个S_RD_DEV_ADDR0就可以?因为既然是读数据,第二个写器件地址一定会出现的。

A: 这里的S_RD_DEV_ADDR0, S_RD_DEV_ADDR1 ,对应的sub-address(H), 和 sub-address(L),必须写全,可以理解为ov5640的寄存器地址,因为ov5640的寄存器地址都是16bit的。

 

17.

%title插图%num

这里能不能把always@(*)换成else的形式?或者说always@(*)和else在这里的两种写法有什么不同吗?是优化好一些吗?

A:使用else 表示的是一段式状态机; 使用always @(*)是两段式状态机。一般情况下,不能直接改写, 可以参考:https://www.icfedu.cn/archives/4222

%title插图%num

 

18.

%title插图%num

这里的txr和rxr分别是发送和接收的意思吗?

A: 是,一般来说tx表示transmit/发送,rx表示receive/接收。通信中经常会使用类似的变量名,如果不确定,总是可以根据追踪上下代码来理解和确定。

 

19.

%title插图%num

  • i2c_master_byte_ctrl和i2c_master_bit_ctrl这两段程序没怎么看懂,老师能大概讲一下吗?

A: 这是verilog 1995 的语法结构,可以等效为verilog 2001 语法:

module i2c_master_bit_ctrl (

    input clk,                                 // system clock

    input rst,                                  // synchronous active high reset

    input nReset,                         // asynchronous active low reset

    input ena,                               // core enable signal

    input [15:0] clk_cnt,           // clock prescale value

    input [ 3:0] cmd,                 // command (from byte controller)

    output reg cmd_ack,          // command complete acknowledge

    output reg busy,                 // i2c bus busy

    output reg al,                      // i2c bus arbitration lost

    input din,

    output reg dout,

    input scl_i,                         // i2c clock line input

    output scl_o,                     // i2c clock line output

    output reg scl_oen,          // i2c clock line output enable (active low)

    input sda_i,                       // i2c data line input

    output sda_o,                    // i2c data line output

    output reg sda_oen         // i2c data line output enable (active low)

);

 

  • 这两段程序最前面都有`include “timescale.v”和`include “i2c_master_defines.v”,这两个表示什么意思?去不去掉对程序有影响吗?并且`include “i2c_master_defines.v”还标蓝色了。

A: 相当于将timescale.v 文件的内容,放置到当前文件的位置,去掉会有影响。

`timescale 1ns / 10ps

`define I2C_CMD_NOP 4’b0000

`define I2C_CMD_START 4’b0001

`define I2C_CMD_STOP 4’b0010

`define I2C_CMD_WRITE 4’b0100

`define I2C_CMD_READ 4’b1000

 

  • 程序开头的写法发送了变化,把没有标注的输入输出信号写在括号里,然后在下面再重新写一遍。这种写法与原先的有区别吗?

A:verilog 1995 的语法, 两种写法都是可以的(verilog 2001)

 

 

%title插图%num

%title插图%num

  • 这种状态机的形式与之前的采用十进制的写法有区别吗?

A: 如果只是分析逻辑, 这两种写法没有区别, 上图中所示的写法都是one-hot编码方式(独热码),one-hot编码的好处是使得综合的状态机更加稳定,对于使用的结果来看,和自然编码没有区别。 但是在大型系统设计中, 经常使用one-hot 编码(有时综合器会自动生成one -hot 编码)。

%title插图%num

  • 尤其是程序中经常出现的#1代表什么意思?

A: 仿真的时候使用, 代表延迟 1 个时间单位, 作为fpga 综合时, 被系统自动忽略了。参考文章:https://www.icfedu.cn/archives/4460

 

20.

%title插图%num

这个78和79是怎么得出来的?通过哪个说明书的。

A:{7’B3C, 1’B0}= 0X78; {7’B3C, 1’B1} = 0X79

 

21.

%title插图%num

  • 关于这个信号打一排,是为了消除采集信号时可以出现的亚稳态情况,是不是从其他硬件进入到FPGA的信号都要这样做的?

A:对, 建议这样使用

 

  • 为什么只对场信号进行了提取边沿?行信号只是打一排的?

A: 下面的程序用到了场信号的边沿

%title插图%num

%title插图%num

  • 对赋值场信号的是camera_v == 2’b01,这种提取边沿的写法最早在uart的课程上提到,但是uart中是en = (in==2’b10) ? 1:0;这个和这次程序中的上升沿信号表示不一样的,这是为什么?

A:camera_v == 2’b01 提取的是上升沿; en = (in==2’b10) ? 1:0; 提取的是下降沿

 

22.

%title插图%num

这里将摄像头的复位信号一直赋值为1,是不是摄像头就一直处于复位状态而无法正常工作了?为什么?

A: reg cam_reset = 1 表示 cam_reset 信号的初值为1, 之后会被修改的。建议同学看下reg和wire类型变量的区别。见文章https://www.icfedu.cn/archives/4345

 

23.

%title插图%num

  • FIFO中有个empty信号,当FIFO读完读空数据时,empty取值为1,是不是也可以用这个信号取代ddr_rd_ack?

A: 原则上是可以的, 但要注意empty 的信号产生的时间, 有时不是很准,需要看一下FIFO定义有时会相差一个,两个时钟周期

 

  • 这边也用了提取边沿的写法,ddr数据频率是100m,摄像头数据频率是24m,就是高频率的数据要被低频率采集到,所以才用了这种写法吗?

A:是, 这是一种比较典型的异步时钟域数据交换的手段

 

24.

%title插图%num

这个拍照OK按键为什么要取反?

A: %title插图%num

 

25.

%title插图%num

%title插图%num

%title插图%num

  • 这段程序是老师你说是防止fifo中有其他数据时需要对fifo进行复位,但是这个其他数据是怎么产生的?这个整个数据传递过程中怎么才会让fifo中有残留的数据?

A: 举例, 如果FIFO 读出的数据的个数出错(一般不是将FIFO读空, 而是根据需要,从FIFO中读取足够的数量的数据),那么,原则上是,从FIFO中读取足够数量的数据后,FIFO为空, 如果中间有任何一笔计算错误, 会使得以后进入FIFO,和读出FIFO的数据窜位,数据不正确。 如果对FIFO复位, 可能当前这笔数据是错误的, 但是不会影响之后的数据。 这一点还是比较重要的, 但图像数据发生错误, 再回头找原因, 是比较困难的。

 

  • 根据手册中,图没看懂,老师可以指出至少3个时钟周期在图中哪里体现的?还有最大值的时钟周期(C_SYNCHRONIZER_STAGE(whichever is maximum) )是什么值的最大值?

A:

%title插图%num

  • 程序中if(&wr_cnt[5:0]) ,这个&wr_cnt是不是表示0&wr_cnt,&表示每一位的与操作,0的每一位都是0,所以这个操作结果是0值?

这个64个时钟周期是怎么得出来的?应该表示的是最大值的时钟周期。

A:这是缩位操作(归约运算),具体参考:https://www.icfedu.cn/archives/4695

当wr_cnt[5:0] == 6’b11_1111时, wr_cnt[5] & wr_cnt[4] & wr_cnt[3] & wr_cnt[2] & wr_cnt[1] & wr_cnt[0]的结果为真(1),其他情况结果都是为0, 也就是说当wr_cnt 计数器从0 累加到63时 进入下一个状态。

 

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

发表评论

相关链接