Verilog实现图像处理的行缓存Line Buffer

在图像处理中,难免会遇到对图像进行卷积或者模板的局部处理,例如ISP中的一些算法,很大部分都需要一个窗口,在实时视频处理中,可以利用行缓存Line buffer可以暂存几行数据,然后同时输出每行中的对应列的像素。

下面以一个三行缓存进行解释

 DVP像素流从Shif_in输入,像素不流不断在行缓存中移动,行缓存的最后一个像素使用line_out来保存,通过这种方式,lin_out输出部分就是每行对应列中的像素,在算法模块中,对line_out寄存三拍,就可以得到3x3的窗口大小。

暂存区的设计可以使用一个双口同步RAM来实现:

module simple_dp_ram
#(parameter DW = 8,parameter AW = 4,parameter SZ = 2**AW
)
(input           clk,input           wen,input  [AW-1:0] waddr,input  [DW-1:0] wdata,input           ren,input  [AW-1:0] raddr,output [DW-1:0] rdata
);reg [DW-1:0] mem [SZ-1:0];always @ (posedge clk) beginif (wen) beginmem[waddr] <= wdata;endendreg [DW-1:0] q;always @ (posedge clk) beginif (ren) beginq <= mem[raddr];endend// always @(posedge clk) begin// 	// 先执行读操作// 	if (ren) begin// 		q <= mem[raddr];// 	end// 	// 后执行写操作// 	if (wen) begin// 		mem[waddr] <= wdata;// 	end// endassign rdata = q;
endmodule

这里涉及到一个问题,当读地址和写地址相同时,会导致冲突吗?

我这里找到的解释是,具体行为会依赖于底层的实现,在同一个时钟周期同时读写同一个地址在FPGA中通常是读优先的,即会先读取该地址的旧值,然后向该地址写如新值。(有大佬了解的可以帮忙解释以下:))。

行缓存LineBuffer源码如下所示:

///基于卷积或者模板的算法需要使用该模块
module shift_register
#(parameter BITS = 8,         parameter WIDTH = 480,    //行缓存宽度parameter LINES = 3       //行缓存行数
)
(input                clock,    input                clken, input  [BITS-1:0]    shiftin,        //输入数据流output [BITS-1:0]    shiftout,       //当前行最后一个像素的数据输出。output [BITS*LINES-1:0] tapsx        //行缓存的输出:包含每行最后一个像素的输出,拼接成一个长向量
);localparam RAM_SZ = WIDTH - 1;   //每行的实际大小localparam RAM_AW = clogb2(RAM_SZ);  //计算地址宽度///地址指针逻辑reg [RAM_AW-1:0] pos_r;   //pos_r:记录当前写入的位置。///(RAM_SZ[RAM_AW-1:0] - 1'b1)实际上就是WIDTH - 2//行缓存的最后一个像素使用line_out来保存,RAM实际上只保存了WDITH-1个像素(pos在0~WIDTH-2之间)wire [RAM_AW-1:0] pos = pos_r < RAM_SZ ? pos_r : (RAM_SZ[RAM_AW-1:0] - 1'b1);  ///当 pos_r 超过范围时限制其值,用于确保地址有效always @ (posedge clock) beginif (clken) begin     if (pos_r < RAM_SZ - 1)  pos_r <= pos_r + 1'b1;   //地址指针 pos_r 循环递增,直到到达最大地址后重置为 0elsepos_r <= 0;endendreg [BITS-1:0] in_r;  always @ (posedge clock) beginif (clken) beginin_r <= shiftin;      //寄存输入数据 shiftin,用于提供给第 0 行的 RAM 写入。endendwire [BITS-1:0] line_out[LINES-1:0];    //记录每行的最后一个像素///生成菊花链行缓存结构,在第二行开始才将上一行末尾连接到下一行的输入中,第一行输入in_r,每一行的最后一个像素寄存在line_out中generate          genvar i;for (i = 0; i < LINES; i = i + 1) begin : gen_ram_inst//在当前周期,line_out[i] 先从 pos 地址中读取之前存储的数据。随后将 (i > 0 ? line_out[i-1] : in_r) 写入 pos 地址。simple_dp_ram #(BITS, RAM_AW, RAM_SZ) u_ram(clock, clken, pos, (i > 0 ? line_out[i-1] : in_r), clken, pos, line_out[i]);endendgenerateassign shiftout = line_out[LINES-1];     //移位输出generategenvar j;for (j = 0; j < LINES; j = j + 1) begin : gen_taps_assignassign tapsx[(BITS*j)+:BITS] = line_out[j];endendgenerate//计算需要位宽function integer clogb2;    input integer depth;beginfor (clogb2 = 0; depth > 0; clogb2 = clogb2 + 1)depth = depth >> 1;endendfunction
endmodule

这里使用了一个clogb2函数来获取配置的WIDTH需要的位宽。在代码中涉及了同一时钟周期对双口RAM中同一地址的读写问题,既然项目最后能跑起来,应该就是读优先的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【银河麒麟高级服务器操作系统】有关dd及cp测试差异的现象分析详解

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn dd现象 使用银河麒麟高级服务器操作系统执行两次…

C++ 中面向对象编程如何处理异常?

一、引言 在 C 编程中&#xff0c;异常处理是一项重要的技术&#xff0c;它可以帮助我们更好地管理程序中的错误情况&#xff0c;提高程序的稳定性和可靠性。特别是在面向对象编程中&#xff0c;异常处理更是不可或缺的一部分。本文将介绍 C 中面向对象编程如何处理异常&#…

ORACLE逗号分隔的字符串字段,关联表查询

使用场景如下&#xff1a; oracle12 以前的写法&#xff1a; selectt.pro_ids,wm_concat(t1.name) pro_names from info t,product t1 where instr(,||t.pro_ids|| ,,,|| t1.id|| ,) > 0 group by pro_ids oracle12 以后的写法&#xff1a; selectt.pro_ids,listagg(DIS…

记录2024-leetcode-字符串DP

10. 正则表达式匹配 - 力扣&#xff08;LeetCode&#xff09;

微信开发者工具(小程序)的版本管理,Git Push 和 Pull

微信开发者工具&#xff08;小程序&#xff09;的版本管理&#xff0c;Git Push 和 Pull 一、设置 第一次用微信开发者工具自带的版本管理的拉取和推送功能&#xff0c;稍稍的研究了下。 1、首先要先设置 “用户”&#xff0c;名字和邮箱&#xff0c;不一定要真名&#xff0c…

MyBatis学习笔记:进阶知识2

MyBatis 作为一款优秀的持久层框架&#xff0c;在 Java 开发中占据着重要地位。它简化了数据库操作&#xff0c;提供了灵活且高效的数据访问方式。本文将深入探讨 MyBatis 的核心功能&#xff0c;包括分页查询、联表查询、动态 SQL 以及代码自动生成&#xff0c;并结合实际案例…

2020-12-07 光棍数

由光棍数的特征可推导其商的个位数不存在偶数且只有1、3、7、9这4个数。一个数可匹配多个光棍数且必定是中间隔着0的循环数。 void 光棍数(int n) {//缘由http://ask.csdn.net/questions/3444069 做乘法运行时间超长int w 0; long long x 111111111111111, j 0;//j x*n;/…

【Linux系统】—— 初识 shell 与 Linux 中的用户

【Linux系统】—— 初识shell 与 Linux 中的用户 1 Xshell 运行原理1.1 命令行的组成1.2 外壳程序 2 Linux中的用户2.1 两种用户2.2 创建普通用户2.3 用户切换2.3.1 普通->超级2.3.2 超级->普通 3 指令的短暂提权3.1 为什么要提权3.2 sudo 指令3.3 人人都能提权吗 1 Xshe…

.NET平台使用C#设置Excel单元格数值格式

设置Excel单元格的数字格式是创建、修改和格式化Excel文档的关键步骤之一&#xff0c;它不仅确保了数据的正确表示&#xff0c;还能够增强数据的可读性和专业性。正确的数字格式可以帮助用户更直观地理解数值的意义&#xff0c;减少误解&#xff0c;并且对于自动化报告生成、财…

Android显示系统(10)- SurfaceFlinger内部结构

一、前言: 之前讲述了native层如何使用SurfaceFlinger,我们只是看到了简单的API调用,从本文开始,我们逐步进行SurfaceFlinger内部结构的分析。话不多说,莱茨狗~ 二、类图: 2.1、总体架构: 先看下SurfaceFlinger的关键成员和我们BootAnimation侧关键成员如何对应起来…

深度学习中的多通道卷积与偏置过程详解

目录 ​编辑 多通道卷积的深入理解 &#x1f50d; 卷积核的多维特性 &#x1f30c; 卷积操作的细节 &#x1f527; 多通道卷积的优势 &#x1f31f; 偏置过程的深入理解 &#x1f3af; 偏置的两种实现方式 &#x1f6e0;️ 偏置的作用与重要性 &#x1f308; 多通道卷…

易语言鼠标轨迹算法(游戏防检测算法)

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

LeetCode 718. 最长重复子数组 java题解

https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/ 动态规划 class Solution {public int findLength(int[] nums1, int[] nums2) {int len1nums1.length,len2nums2.length;int[][] dpnew int[len11][len21];dp[0][0]0;//没有意义&#xff0c;…

【蓝桥杯选拔赛真题93】Scratch青蛙过河 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 Scratch青蛙过河 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 Scratc…

5.3 C++ 容器的嵌套

一&#xff09;容器嵌套的概念 在 C 中&#xff0c;容器嵌套是指将一种容器类型作为另一种容器的元素。这允许创建更复杂的数据结构&#xff0c;以满足各种编程需求。例如&#xff0c;可以将一个vector容器放入另一个vector容器中&#xff0c;或者将一个map容器的元素设置为lis…

spark读取普通文件

spark读取普通文件 txt文件 """ 将一行数据当做一个字段&#xff0c;需要自己切割 字段名称为value 表结构 可以从sql中搞 """ df spark.read.text("../../data/wordcount/input/data.txt") df spark.read.format("text"…

手机实时提取SIM卡打电话的信令声音--社会价值(一、方案解决了什么问题)

手机实时提取SIM卡打电话的信令声音 --社会价值(一、方案解决了什么问题) 一、前言 这段时间&#xff0c;我们在技术范围之外陷入了一个自证或者说下定义的怪圈&#xff0c;即要怎么样去介绍或者描述&#xff1a;我们是一个什么样的产品。它在当前这个世界上&#xff0c;处于…

【LeetCode】每日一题 2024_12_13 K 次乘运算后的最终数组 I(暴力)

前言 每天和你一起刷 LeetCode 每日一题~ 小聊两句 1、今天是 12.13 南京大屠杀国家公祭日。铭记历史&#xff0c;勿忘国耻。 2、今天早上去看了 TGA 年度游戏颁奖&#xff0c;小机器人拿下了年度最佳游戏&#xff0c;所有人都震惊了&#xff0c;大伙纷纷问到&#xff0c;谁…

算法刷题Day16: BM41 输出二叉树的右视图

题目链接 描述 思路&#xff1a; 递归构造二叉树在Day15有讲到。复习一下&#xff0c;就是使用递归构建左右子树。将中序和前序一分为二。 接下来是找出每一层的最右边的节点&#xff0c;可以利用队列层次遍历。 利用队列长度记录当前层有多少个节点&#xff0c;每次从队列里…

【修改源码】解决el-select值不匹配导致回显id、只能搜索label无法搜索value的问题

问题一&#xff1a;el-select值不匹配导致回显id&#xff08;此时只针对单选进行处理&#xff09; el-select数据的回显是根据id去匹配值的&#xff0c;最近项目出现了回显id的情况&#xff0c;原因是没有匹配的option 问题场景图如下&#xff1a; 解决方案 1、方法一&#xf…