集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1768|回复: 4

基于直方图算法进行FPGA架构设计

[复制链接]
雷磊 发表于 2021-4-8 15:12:18 | 显示全部楼层 |阅读模式
直方图统计在图像增强和目标检测领域有重要应用,比如直方图均衡,梯度直方图。直方图的不同种类和统计方法请见之前的文章。本章就是用FPGA来进行直方图的计算,并且利用FPGA的特性对计算过程进行加速。安排如下:

首先基于直方图算法进行FPGA架构设计,这里主要考虑了如何加速以及FPGA资源的利用两个因素;最后基于system Verilog搭建一个验证系统。

FPGA设计架构

不论是图像灰度直方图还是梯度直方图,本质上是对数据的分布进行计数。从FPGA角度来看,只关心以下几点:

1) 根据数据大小确定其分布区间,统计分布在不同区间的数据个数,区间的大小可以调节,比如灰度直方图区间为1,梯度直方图通常大于1;

2) 如何利用FPGA对直方图统计进行加速,以及如何考虑到芯片有限资源;

首先来考虑加速方式,直方图统计过程用伪代码表示为:

For(int i=0;i Index = get_index(data);- l( H9 P, m; s, E( D4 H
Hist[index]++;
}

Get_index函数是为了确定数据属于哪个区间,如果区间大小为1,那么index就是数据自身。如果区间是平均分布,那么就需要进行数据的大小比较。如果区间大小是2的幂次,那么index只需要数据进行移位得到。

FPGA在加速计算中最主要就是利用并行化和流水线,并行化就是将一个任务拆解成多个子任务,多个子任务并行完成。而流水线是在处理一个子任务的时候,下一个来的子任务也可以进行处理,处理模块不会等待。流水线本质上是对子任务也进行“分割”,分割的每一块可以在处理模块中同时进行。

统计N个数据,可以将N分成M份,在FPGA上同时进行M个统计,用伪代码表示为:

For(int k=0;k //并行化: V5 V, Y! e' m3 r$ l* G$ ]3 ~
For(int i=0;i Index = get_index(data[k]);$ @$ e& a1 |0 \$ g: L- a
Hist[k][index]++;! |: F* }4 r, h, E
}
}

如果区间不是2的幂次,就需要比较器,这样并行M次,就需要M个同等比较器,这对资源消耗很大。因此目前设计仅仅支持2的幂次的区间。整个设计架构如图1.2。



图2.1 流水线处理



图2.2 直方图统计架构

主要分为以下几个模块:

1)statis:这个是核心计算模块,统计数据分布。ram中存放直方图统计数据,地址对应着数据分布区间。这里有一个问题需要考虑,在对ram中直方图统计数据计数时,需要读出然后计数。如果ram读端口没有寄存器,那么读出来直接加1,再写入。但是这样并不好,因为ram不经过寄存器时序不好。所以增加了一级寄存器,这样就造成了写入的延时,那么有可能下一次数据来临也会读取同样地址的数据,此时读取到的直方图数据就是还没有写入的。为了解决这个问题,判断进入的前后两个数据是否相同,如果相同就不写入而继续计数,如果不同就写入。并行多个statis模块的代码为:

genvar i;
generate
for(i=0;i

statis #(; |: j6 g! S) t' `( E, `4 X9 e
.PIX_BW(PIX_BW),
.HIST_BW(HIST_BW),
.ADDR_BW(HIST_LEN_BW),$ r4 C! Z; ]5 Q, l* k  T% m
.BIN_W(BIN_W)

)u_statis(
.clk(clk),
.rst(rst),& j% [/ D, V/ r' v9 V
.clr(clr),

.enable(1'b1),' p6 \+ _. c5 R" d% n; t
.pix_valid(pix_valid),
.pix(img_i[i*PIX_BW +: PIX_BW]),

.hist_rd(branch_hist_rd),+ m0 \5 t; Z1 t: a7 i. ]4 |& }
.hist_raddr(branch_hist_raddr),
.hist(branch_hist[i*HIST_BW +: HIST_BW])8 ?! u- ~6 H: {& F- z! r# A$ w: J# L
);

end9 l7 r9 L1 {, }! l
endgenerate

2)serders:这个是并转串。M个statis模块会产生M组hist结果,这些结果还要进行求和,那么就要用到加法树,如果M较大,会造成加法树很大,多以这里加了serders可以调节加法树资源。

3) addTree:加法树。
module addTree #(7 f: I/ `5 z* Z# u
parameter DATA_BW = 32,//bit width of data3 t9 e+ u$ g, n; \/ X
parameter TREE_DEPTH = 3,//depth of the add tree
parameter ADD_N = 4//add number: c& E" n1 M+ X# T) _5 L1 B
)
(' A  o3 `5 }5 U0 L
input clk,0 R1 v2 S' m. k
input rst,# g5 |+ e9 ?8 B
input [ADD_N*DATA_BW-1:0] adnd_x,
input [ADD_N*DATA_BW-1:0] adnd_y,$ d* l& u; u$ ^1 b% e# P
input adnd_valid,# \& C5 ^1 D6 D. n, o4 i% L
output reg[DATA_BW-1:0] finl_sum,
output reg finl_sum_valid

);

reg [TREE_DEPTH-1:0]midl_valid;

genvar dept_i, leaf_i;
generate
for(dept_i=TREE_DEPTH-1;dept_i>=0;dept_i=dept_i-1)begin: ADD_DPET: [7 z7 I% u: ^+ E1 \, F# ^9 J$ K* j
localparam LEAF_N = 2**dept_i;

wire[DATA_BW-1:0] midl_sum[LEAF_N-1:0];

for(leaf_i=0;leaf_i

reg [DATA_BW-1:0] midl_add_x;
reg [DATA_BW-1:0] midl_add_y;

if(dept_i==TREE_DEPTH-1)begin
always @(posedge clk)begin
midl_add_x midl_add_y end/ E3 K* t% {2 g
end
else begin
always @(posedge clk)begin5 ^3 k9 _6 N. e" ^- X' N- {
midl_add_x midl_add_y end
end

adder #(2 F/ ^& Q9 I& Y# v2 N# O
.DATA_BW(DATA_BW)% z" s, I4 ~7 [: Q# g
)
u_adder(
.adnd_x(midl_add_x),2 r+ z5 o; C2 t/ ]2 }" F( L% [
.adnd_y(midl_add_y),
.sum(midl_sum[leaf_i])

);

end

if(dept_i==TREE_DEPTH-1)1 ]6 d" a4 k# V' Q& ^
always @(posedge clk)begin. {7 ~, J' w) x4 W3 C
midl_valid[dept_i] end. J7 F% ?0 W: m* a, J) ?( E) w9 O
else
always @(posedge clk)begin
midl_valid[dept_i] end

end

endgenerate

always @(posedge clk)begin
finl_sum end

always @(posedge clk)begin/ t6 b/ e# m3 U6 q: L% ^  C. H
if(rst)6 ~- F3 N; m% ~3 {
finl_sum_valid else
finl_sum_valid end

endmodule

4) accum:累加器。如果加法树没有完成M个hist数据的求和,那么就需要通过累加器来完成。



图2.3 对ram的处理

验证结构

1) img_trans:这个是随机化图像数据定义,主要通过SV中constraint来对图像大小做一些约束;

class img_trans;

rand int img_w;8 j" q" h: V7 v+ P/ P! ?" `6 P
rand int img_h;
rand int img_blank;$ [' b+ _; C  [
rand logic[`PIX_BW-1:0] img[`MAX_IMG_W*`MAX_IMG_H];

constraint img_cfg_cnst{
img_w img_w > 0;
img_w % `PARALL == 0;/ e+ C4 O5 b( M
img_h img_h > 0;9 I( u( Y; T4 P: @- k1 d: ?
img_blank img_blank >= 0;

}

extern function void write(input string f_name);

endclass

2) driver:产生image并且发送给DUT,同时通过mailbox发送给ref_model用于对比;
class img_obj;/ Y4 _5 L+ U" \
logic [`PIX_BW-1:0] img_que[$];
endclass

class driver;

int img_w;
int img_h;
int img_blank;* C+ H& J: V) I& [0 X
logic [`PARALL*`PIX_BW-1:0] img;
logic [`PIX_BW-1:0] img_ele;9 n* W1 J) v7 p! [/ M
img_obj imgObj;
img_trans imgTrans;

extern task drive(mailbox img_mbx, virtual img_inf.test imgInf);

endclass

3) ref_model:自己统计直方图和DUT的结果进行比对;

class ref_modl;

logic [`PIX_BW-1:0] img;9 V' ^# i  E/ M5 j% a0 L
int addr;9 E. h. j% H% t
img_obj imgObj;
int hist[`HIST_LEN];

extern task calc(input logic clk, mailbox img_mbx);
extern task comp(virtual img_inf.test imgInf);
extern task run(input logic clk, mailbox img_mbx, virtual img_inf.test imgInf);
extern function void clear();

endclass



图3.1 验证架构图

最后添加一下modelsim仿真波形文件和结果,纯粹为了增加篇幅。




图3.2 modelsim仿真波形和结果
dameihuaxia 发表于 2021-4-9 10:54:10 | 显示全部楼层
基于直方图算法进行FPGA架构设计
 楼主| 雷磊 发表于 2021-10-20 14:57:21 | 显示全部楼层
基于直方图算法进行FPGA架构设计
LYF 发表于 2021-10-27 17:14:16 | 显示全部楼层
基于直方图算法进行FPGA架构设计
dameihuaxia 发表于 2021-10-28 13:52:38 | 显示全部楼层
Verilog典型电路设计_华为
http://www.fpgaw.com/forum.php?m ... 4&fromuid=58166
(出处: fpga论坛|fpga设计论坛)
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-16 13:00 , Processed in 0.061933 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表