二维缓冲
二维缓冲的功能是将串行的像素点数据转化为并行的多个像素点的滑窗,将滑窗内的坐标中心点作为当前并行数据对应的像素点,一般用于插值计算或者二维卷积。
由于二维缓冲主要是逻辑控制,不涉及数值计算,最简单的方法是使用 Verilog 实现,但是由于二维缓冲在图像处理算法中应用十分广泛,做成 sysgen 模块更适合在 sysgen 中直接调用。
根据图像处理原理,大部分计算用的滑窗都是 3×3 3\times 33×3 或者 5×5 5\times 55×5,设计思想一致。
下文以 3×3 的二维缓冲为例说明设计方法。
Subsystem 封装如下:
rst 为高电平复位,用于复位缓冲数据。
in_pix 为输入的串行像素点值。
in_lv 为输入的行有效信号。
out_pix00~22 为输出的并行像素点数据,序号对应各像素点在当前滑窗内的坐标,其中滑窗中心点 pix11 作为当前并行数据对应的像素点。
out_x、out_y、out_fv、out_lv分别指示当前点 pix11 的列坐标,行坐标,帧有效和行有效信号,具体时序与图像数据流水线格式的说明一致。
3×3 二维缓冲的实现原理是用 FIFO 进行行缓冲,用寄存器进行列缓冲。
行缓冲设计:
• 前 1 个 FIFO 的读数据接口连接下个 FIFO 的写数据接口;
• 每个 FIFO 都设置 FWFT 属性,使用读使能信号与读数据同步;
• 每个 FIFO 都使用 lv 信号同时作为读使能和写使能信号,但是只有 FIFO 首次装入 1 行数据后才产生读使能。
2 行数据缓冲
注意:out_lv 与 in_lv 没有时延,只有组合逻辑 and ,以保证所有连接的行缓冲模块的读写使能同步。
FIFO 模块配置如下,必须选中 First Word Fall Through,保证 dout 与 re 高电平对齐。
通过 FIFO 的 FWFT 属性,实现 out_pix 与 out_lv 时序对齐。
3 行缓冲连接
输入数据由 line_buf_2 进入,再转入 line_buf_1,最后到达 line_buf_0,上游行缓冲模块的输出接入下游行缓冲模块的输入。
012 的序号表示时间由先至后,以 line_buf_1 的输出作为当前像素点。
考虑 line_buf_1 输出边缘行的情况:
• 在 line_buf_1 输出为 0 行数据时,line_buf_0 的 out_pix 无效,用 line_buf_1 的数据替换 line_buf_0 的输出数据;
• 在 line_buf_1 输出最后 1 行的数据时,line_buf_2 的 out_pix 无效,用 line_buf_1 的数据替换 line_buf_2 的输出数据。
将 line_buf_1 输出的 lv 送入行列坐标生成模块 coord_gen,将 coord_gen 输出的行坐标与常数值比较,判断是否为首行或者末行,用 Mux 模块在指定的行坐标情况下用 line_buf_1 的输出分别替换 line_buf_0 或者 line_buf_2 的输出。
最后的部分是送出行列坐标以及帧有效和行有效信号,注意控制延迟与 out_pix 时序对齐:
4 列数据缓冲
输入数据由 reg_2 进入,再转入 reg_1,最后到达 reg_0,上游寄存器的输出接入下游寄存器的输入。
012 的序号表示时间由先至后,以 reg_1 的输出作为当前像素点。
考虑 reg_1 输出边缘列的情况:
• 在 reg_1 输出为 0 列数据时,reg_0 的输出无效,用 reg_1 的数据替换 reg_0 的输出数据;
• 在 reg_1 输出最后 1 列的数据时,reg_2 的输出无效,用 reg_1 的数据替换 reg_2 的输出数据。
将输入的列坐标 in_x 与常数比较(注意与 reg_1 输出对齐时序),判断当前 reg_1 输出是首列或者末列,用 Mux 模块在指定的列坐标下用 reg_1 数据分别替换 reg_0 或者 reg_2 的输出数据。
最后的部分是送出行列坐标以及帧有效和行有效信号,注意控制延迟与 out_pix 时序对齐。
组装构成
将 3 行缓冲模块并行输出的 3 行数据分别接入 3 列数据缓冲模块,完成 3×3 3\times 33×3 二维缓冲模块的组装:
注意:二维缓冲模块输出的行列坐标及帧有效和行有效信号与 out_pix11 对齐。
二维缓冲的截取
大多数二维缓冲的使用场景都是奇数行奇数列并且行列数目相同的二维缓冲,某些特殊的算法可能并不符合前述的要求,这时可以对已有的二维缓冲模块输出进行截取后送出符合当前算法要求的二维缓冲数据。
二维缓冲输出数据截取的关键在于确定当前像素点的坐标位置。
仍然以 3×3 二维缓冲为例,如果需要截取得到 2×2 的二维缓冲,首先需要确定在 2×2 缓冲内当前像素点(即 3×3 二维缓冲输出的 pix11)的坐标
如果当前像素点坐标为 (0, 0),则截取 3×3 缓冲的像素点为:
如果当前像素点坐标为 (1, 1),则截取 3×3 缓冲的像素点为:
如果需要单纯的行缓冲或者列缓冲,则可以使用相同的办法截取行缓冲模块或者列数据缓冲的输出数据。
版权声明:本文为CSDN博主「bt_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/botao_li/article/details/100521709