任务描述


这是padding模块下的一个子模块,负责zero padding的输出。详细功能描述参考前面的【CAG_SLAM】-03-Padding Modules的信息。

端口定义


名称 方向 位宽(bits) 描述
clk in 1 时钟信号
rst in 1 reset信号
width in 12 图片宽度
height in 12 图片高度
data_i in 4 x 8 输入数据,原图片数据,每次输入4个字节
fast_busy_i in 1 fast模块busy标志位信号输入
valid_i in 1 输入数据有效标志位
data_o out 4 x 8 输出数据,加上padding之后的数据,每次输出4个字节
pdg_busy_o out 1 padding模块busy标志位,与valid_i形成握手协议
valid_o out 1 输出数据有效标志位

实现方案


方案描述

同样见【CAG_SLAM】-03-Padding Modules的信息

编程思路

首先,输入宽长,第一个数据,停止输入

然后,计算得到cut的数据,开始zero输出,直到第一个有效数据开始前停止。

输入第二个有效数据,计算得到第一个数据输出。

接下来进入流水输出,直到当行的行末,再次停止输入(继续输入裁剪掉无效像素,直到输出?),并且输出0。(中间可能有计算下一个何时,如何开始的操作)。

直到下一个有效数据到达,继续输入输出流水。

重复。

最后输出0,结束。

具体实现

现在,理一下编程的思路。

首先是输入部分有一个计数器,输出部分有一个计数器分别记录输入和输出在现在的状态;

现在需要写一个三段式的状态机,一共有四个状态,IDLE,SEND_PICS,SEND_ZEROS,SEND_PICS,SEND_TRANSATION。开始写的五个状态和三个状态都是不太合理的,这里应该需要这四个状态。

理清楚输入信号、内部寄存器之间的关系,输入信号使得整个系统打开(IDLE->SEND_ZEROS,计数器开始计数),然后,剩下的操作主要是交给计数器完成(输入信号可以控制计数器的暂停和继续),其他状态转移和变化也主要是通过计数器来操作完成。

其中,SEND_ZEROS->SEND_PICS的转变通过观察输出计数器来完成,SEND_PICS->SEND_TRANSITION的转变主要通过观察输出计数器来完成,SEND_TRANSITION->SEND_PICS主要通过观察输入计数器来完成,SEND_ZEROS->SEND_PICS的转变主要通过输出寄存器或者axi的last信号来完成。

这长达一个月的小项目终于要basically搞出来了,这其实并不算是一个复杂的项目,但是其中历经的折磨和坎坷你又怎知。

问题没有想象的复杂,最终的实现方案就是讲输入信号用于控制计数器的增减数(出了启动信号,以及最后的结束信号);在控制状态转变时,是使用的计数器的计数值判断(同时,注意区分输入计数器和输出计数器分别对其状态的影响)。

其他需要注意的地方就是一些细节了:

  • 计数值是在上一个状态最后一个计数值的时候发生转变,注意设计的细节
  • 注意状态的划分合理的状态划分完成设计的保障,不合理的状态划分(缺失或者多余)都将影响最终的结果。

项目总结

项目之所以可以拖这么久,是因为这个复杂度确实有一点超过我这种初学者的水平,并且没有什么资料可以参考借鉴(可能是有的,但是我没能找到类似的)。经过此番折磨,我想我的心智都快变得更加成熟了。我想,要实现这些一个又一个小目标,谈何容易。当我们不断地翻越过高山,也在翻阅真实的自己。

参考文献

  1. Verilog并行加法树实现_dawn‘s BLOG的博客-CSDN博客_verilog 加法树
  2. 基于AXI VDMA的图像采集系统 - yf869778412 - 博客园 (cnblogs.com)
  3. 基于AXI VDMA的图像采集系统_杏儿黄的博客-CSDN博客_s2mm