基于FPGA的非线性滤波器(三)
时间:2022-04-28
本文章向大家介绍基于FPGA的非线性滤波器(三),主要内容包括基于FPGA的非线性滤波器(三)、之并行全比较排序模块设计、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
基于FPGA的非线性滤波器(三)
之并行全比较排序模块设计
由于排序运算在图像的行列方向上是同性的,因此,同时考虑首先进行一维图像方向上的排序,再对列方向上的行排序结果进行排序,即可得到一个窗口内的排序结果。
一维方向的排序运算模块,记为sort_1d。同样地,对于最终的二维排序运算模块,记为sort_2d。
1.sort_1d模块设计
计算步骤如下:
(1)首先得到待排序的n个数据:这可以通过将数据流打n-1拍实现。
(2)进行全比较:当前数据与其他所有一次进行比较,并记录比较结果,比较的过程需先考虑输入次序问题。
(3)将(2)中的记录结果进行相加:根据不同的比较宽度,相加工作可以通过多个时钟完成。
(4)查找(3)中相加结果按指定次序输出:如果要实现中值滤波,中间索引号输出,对于其他次序的滤波可以采用其他编号的数据输出。
以1x3的排序单元为例,至少需要6个比较器、3个加法器和6个寄存器,其设计框图如下图所示。
其中OUT_ID为输入信号,进行判决输出。例如对于种植滤波,选择中间结果进行输出。例如,设定我们的处理核为KSZ,则有
OUT_ID = KSZ>>1 中值滤波器
OUT_ID = 0 最大值滤波器
OUT_ID = KSZ-1 最小值滤波器
module sort_1d(
rst_n,
clk,
din,
din_valid,
dout,
dout_valid
);
parameter DW = 14;
parameter KSZ = 3;
parameter OUT_ID = (KSZ>>1); //中值滤波器
parameter DW_MAX_NUM = 8; //输入数据个数的最大位宽
input rst_n;
input clk;
input [DW-1:0] din;
input din_valid;
output [DW-1:0] dout;
output dout_valid;
reg [KSZ+3:0] din_valid_r; //输入有效寄存器
reg [DW-1:0] din_r [0:KSZ+2]; //输入数据寄存器
wire cmp_result [0:KSZ-1][0:KSZ-1]; //比较中间结果信号
reg [7:0] cmp_sum[0:KSZ-1]; //三个比较和寄存器
reg [7:0] cmp_sum_r[0:KSZ-1];
reg [7:0] cmp_sum_r2[0:KSZ-1];
reg [DW-1:0] dout_temp; //输出寄存器
//首先缓存输入数据和输入有效数据,同时得到待排序的数据
//缓存输入数据
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
din_r[0] <= {DW{1'b0}};
end
else
begin
if(din_valid)
din_r[0] <= din;
end
end
generate
begin : xhdl0
genvar i;
for(i=1;i<=KSZ+2;i=i+1)
begin
always @(posedge clk or negedge rst_n)
if(~rst_n)
din_r[i] <= {DW{1'b0}};
else
din_r[i] <= din_r[i-1];
end
end
endgenerate
//缓存输入有效信号
always @(posedge clk or negedge rst_n)
if(~rst_n)
din_valid_r <= {KSZ+4{1'b0}};
else
din_valid_r <= (din_valid_r[KSZ+2:0],din_valid);
//关键比较代码如下
//将第一个数据与其他数据做比较 结果存放在cmp_result[0]中
generate
begin :xhdl1
genvar i;
for(i=1;i<=KSZ-2;i=i+1)
begin : cmp_1st
assign cmp_result[0][i] = (din_r[0] >= din_r[i]) ? 1'b1: 1'b0;
end
end
endgenerate
//与自身的比较结果置0
assign cmp_result[0][0] = 1'b0;
//其他数据比较电路
generate
begin : xhl4
genvar i;
for(i = 2; i <= KSZ; i = i+1)
begin : cmp_others
begin : xhdl2
genvar j;
for(j = 1; j <= i-1; j = j+1)
begin : cmp_previous
assign cmp_result[i-1][j-1] = (din_r[i-1] > din_r[j-1]): 1'b1:1'b0;
end
end
assign cmp_result[i-1][i-1] = 1'b0;
begin : xhdl3
genvar j;
for(j = i+1;j<=KSZ; j = j+1)
begin
assign cmp_result[i-1][j-1] <= (din_r[i-1] >= din_r[j-1]) ?1'b1:1'b0;
end
end
end
end
end
endgenerate
//将比较结果相加
if(KSZ == 3)
begin : sum_ksz_3
always @(posedge clk or negedge rst_n)
if(~rst_n)
begin
cmp_sum[i] <=8'b0;
cmp_sum_r[i] <= 8'b0;
cmp_sum_r2[i] <= 8'b0;
end
else
begin
if(din_valid_r[KSZ-1])
begin
cmp_sum_r[i] <= (cmp_result[i][0]) + (cmp_result[i][2]);
cmp_sum_r2[i] <= cmp_result[i][1];
end
if(din_valid_r[KSZ])
begin
cmp_sum[i] <= cmp_sum_r[i] + cmp_sum_r2[i];
end
end
end
//查找目标值
generate
if(KSZ == 3)
begin : dout_ksz_3
always @(posedge clk or negedge rst_n)
if(~rst_n)
dout_temp <= {DW{1'b0}};
else
begin
if(din_valid_r[KSZ+1])
begin
if(cmp_sum[0] == OUT_ID)
dout_temp <= din_r[2];
else if(cmp_sum[1] == OUT_ID)
dout_temp <= din_r[3];
else if(cmp_sum[2] == OUT_ID)
dout_temp <= din_r[4];
end
end
end
endgenerate
//数据有效输出
assign dout_valid = din_valid_r[KSZ+2];
assign dout = dout_temp;
endmodule
- 100个Numpy练习【2】
- 浅谈 maxMemory , totalMemory , freeMemory 和 OOM 与 native Heap
- 100个Numpy练习【1】
- XGoServer 一个基础性、模块完整且安全可靠的服务端框架
- Bing 每日一图 & 随机图片 API
- 可视化数据库MapD安装——GPU模式
- 12步轻松搞定Python装饰器
- 使用shell脚本检测数据库连接访问情况(r10笔记第98天)
- 贝叶斯分类器及Python实现
- Docker 简介与安装
- 三种决策树算法(ID3, CART, C4.5)及Python实现
- Logistic 回归算法及Python实现
- MySQL主从不一致的修复过程(r10笔记第96天)
- ML中相似性度量和距离的计算&Python实现
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SQL 打印一个月的日历
- Kubernetes节点的驱逐与预留
- 使用reveal.js制作精美的网页版PPT
- Ceph快照爱你不容易系列 03:快照数据一致性浅析
- 没想到竟是因为它!让我的服务器变成了别人的挖矿工具
- 从零到一,Serverless 平台在滴滴内部落地
- React 使用 Proxy 代理(create-react-app)
- .Net Core + EF + mysql 从数据库生成实体
- Git 常用命令
- Nodejs 一些细节 (持续更新)
- Jenkins 凭据使用
- React源码解读【一】API复习与基础
- choco 安装 和 mkcert 本地https
- js 函数柯里化(Currying)
- GPS数据Python解析及地图可视化