FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用
一 简述
最近恶补基础知识,借了<<Verilog传奇>>,《基于FPGA的嵌入式图像处理系统设计》和<<基千FPGA的数字图像处理原理及应用>>这三本书。
<<Verilog传奇>>是关于Verilog基础知识的,总共九章。由于书籍内容太多没时间看,故一般都是了解整本书的大致内容,遇到问题时能回忆起在那看过,再返回来仔细研究。后面两本书是图像处理的FPGA应用,有很多基本的图像处理操作,如常见的直方图技术,各种滤波,图像分割等。重点是图像处理算法的FPGA映射,还有图像仿真验证平台。
(一)<<Verilog传奇>>总结:
第一章用来介绍Verilog语言的基本知识, 包括发展历史、设计流芯片结构和可综合性等。 这里的重点是帮大家建立Yerilog语言与其他学科之间的联系。帮助大家掌握设计数字逻辑系统需要考量的有关内容。
第二章,除了介绍IEEE有关Verilog语言的标准体系及非RTL级的设计之外,还重 点说明了常量、 变量及结构化模块的内容, 是学习Verilog语言的基础。
第三、 四章, 分别介绍了用assign和always定义的组合逻辑电路的描述方法。 其中包含各种运算符操作的写法, 以及条件、 多选的描述。 最后, 以多路选择器为例, 说明 了如何分析一个组合逻辑电路系统。
第五章, 介绍了时序逻辑电路系统的Verilog语言描述方法, 包括D触发器及D触 发器链的写法。 本章还介绍了如何拆分组合电路以适应系统操作时间要求的概念。 在此基础上, 介绍了三种系统速度与面积平衡的方法: 并行化设计、流水线设计与时分复用 设计。
第六章, 结合工程实践, 介绍了经常遇到的若干问题, 其中包括复位系统设计、 可变移位操作、 有限状态机设计、 多时钟系统处理及循环操作的处理。
第七章, 介绍了与[P核设计有关的灵活编程问题。 其中涉及任务与函数的写法、 利 用宏定义方法改变系统参数、 利用参数方法改变系统参数及生成块方法改变系统结构。最后综合运用这几种方法, 给出了一个简单的JP核一数字分频系统 设计的例子。
第八章, 说明了Verilog语言中不可综合的部分。 其一为仿真所需的数据类型、复杂 运算和并行块设计; 其二包含预编译命令; 其三为系统任务与函数。 本章还介绍了测试向量的概念及其编写方法, 以及Yerilog语言与其他语言接口的问题。
第九章, 以 “ 直接数字式频率合成器” 系统为例, 综合前面各章介绍的知识, 采用 了R OM查找表、 折线法和CORDIC算法分别进行了实现。本章不仅希望读者学会如何 综合使用Yerilog语言, 还进一步介绍了部分算法与算法定点化的知识。
(二)<<Verilog传奇>>阅读建议
首先, 粗读/跳读第一章到第二章的第二讲, 了解基本概念。 本书的基本假设是读者都掌握了《数字电子技术》这一门课程。其次详细阅读第二章第三讲到第五章,这是基础内容。第六章,七章为进阶内容。第八章,是测试和验证。第九章是一个复杂的例子, 重点是阅读作者的思想、 设计过程及代码风格。
由于,我曾经学过Verilog语言,故直接从第六章,第七章开始。第六章(按键与复位,可变移位宽度的移位操作,有限状态机及其代码,多时钟系统,循环控制),第七章(函数与任务,宏定义与宏判断,参数,生成块,数字分频器核的设计)。今天下午看了函数与任务,后面详细介绍。
(三) <<基千FPGA的数字图像处理原理及应用>>总结
重点讲解图像处理算法移植到FPGA中的基本思路和方法,突出工程应用。每一章均附有C/C++实现代码,同时用循序渐进、自顶向下的方式设计FPGA算法模块, 针对每一个模块设计了详细的实现框图,确保读者能理解算法设计的原理。
此外,每个算法都配有Verilog实现方法,并给出仿真结果。本书还提出了一个通用的利用Modelsim和VS实现图像处理的仿真测试平台。这个仿真平台是我学习的重点,在书本的第五章,系统仿真。主要是动手搭建视频验证的仿真平台,给算法提供模拟的视频源,联合matlab查看算法处理效果。借鉴书本的思路,用在自己的图像处理项目中。
本书内容概述如下:
(I)第1~5章是基础章节, 重点介绍数字图像处理和FPGA程序设计的基础知识。
第1章简单介绍了图像处理的基础知识, 包括图像处理的发展现状, 还地介绍了图像从获取到显示存储的基本流程。
第2章首先介绍了FPGA的发展现状, 生产厂家及其开发流程。接着介绍了基千FPGA的图像处理的基本开发流程。
第3章主要介绍了在FPGA中应用的编程语言。本章并没有详细介绍Verilog语法,而是从工程应用的角度介绍常用的设计方法和实例。
第4章主要介绍了把软件算法映射到FPGA常用的技巧。首先介绍了应用较广泛的流水线设计方法, 接着介绍了FPGA硬件计算技术, 包括一些常用的计算转换、查找表、浮点计算、C ordie计算等方法。最后介绍了在图像处理中用途非常多的存储器映射, 并提出了一些其他设计技巧。
第5章首先简要介绍了仿真测试软件Modelsim的使用, 接着重点介绍了一个通用的视频图像处理仿真测试系统。这个测试系统包括完整的视频模拟、视频捕获, 以及testbench设计, 并结合基于MFC 的VC上位机来实现测试系统的搭建。
(2)第6~10章主要介绍算法实现。
第6章介绍直方图操作, 主要介绍几种常用直方图操作的FPGA实现: 直方图统计、直方图均衡、直方图规定及直方图线性拉伸。
第7章介绍基千图像处理的线性滤波。首先, 介绍了均值滤波算法、高斯滤波算法、Sobel 算子及FFT等常见的几种线性滤波原理。其次, 介绍了均值滤波算法和Sobel算子的FPGA实现。第8章主要介绍基千图像处理的非线性滤波算法, 包括排序滤波的基本原理及其FPGA 实现方法。
第9章主要介绍基千图像处理的形态学滤波算法, 包括形态学滤波的基本概念,包括形态学膨胀、形态学腐蚀、开运算及闭运算等。重点介绍了基千FPGA 的Tophat滤波的原理及实现方法。
第10章主要介绍基千图像处理的常见的分割算法,包括全局阙值分割、局部自适应阀值分割及Canny 算子。重点介绍基千FPGA 的局部自适应阙值分割和Canny 算子的设计与实现。
第11 章主要介绍与视频和图像处理相关的输入/输出接口, 包括CameraLink、火线接口、USB 接口、千兆以太网等视频输入接口和CVT 标准,以及VGA, PAL, DVI,HDMI 等视频输出接口。其中, 给出了VGA 和PAL 接口的Verilog 代码实现。
二 函数
函数,理解为对于给定的输入(一个或多个)进行处理后返回输出值。在MATLAB中,有sum函数,max函数等。
在Verilog中,函数一是常用来计算数学公式的值。如波特率计算公式:divp10x = (10 * fsysclk) / (16 * baud)
二是函数能够被多次调用,避免冗余。
(一)函数的声明与调用:
函数的声明有两种方式:
//express1
function[range] function_name(ports_list);
begin
...
end
endfunction
//example1
function [7:0] getbyte (input [15:0] address);
begin
. . .
getbyte = result_expression;
end
endfunction
//express2
function[range] function_name;
ports_list;
begin
...
end
endfunction
//example2
function [7:0] getbyte;
input [15:0] address;
begin
. . .
getbyte = result_expression;
end
endfunction
函数只能有一个输出,可以通过多个信号的拼接完成多个信号输出。
编写函数代码的原则:
(1) 函数定义只能模块中完成,不能出现在过程块(即always)。
(2) 函数至少一个输入端口;不能包含输出端口和双向端口;
(3) 在函数结构中,不能使用任何形式的时间控制语句(#,wait)也不能使用disable中止语句。
(4) 函数定义不能出现always语句。
(5) 函数内部可以调用函数,但不能调用任务;
(6) 函数调用即可在过程块语句,也可以在assign赋值语句出现;
(7) 函数调用语句不能单独出现,只能作为赋值语句的右端操作数;
下面用一个函数计算游泳池的面积,掌握函数的使用:

下面是计算上图的面积的Verilog代码,体现了函数的声明,调用。

1 module function_total
2
3 (
4
5 input CLK, input RST,
6
7 input[7:0] width,
8
9 output reg[16:0]area
10
11 );
12
13
14
15 //Load other module(s)
16
17
18
19 //Definition for Variables in the module
20
21
22
23 //Functions for area calculation
24
25 function[15:0] circle(input[7:0] diameter);
26
27 begin
28
29 circle = (24'd201 * {16'h0, diameter} * {16'h0, diameter}) / 256;
30
31 end
32
33 endfunction
34
35
36
37 function[15:0] square(input[7:0] width);
38
39 begin
40
41 square = {8'h0, width} * {8'h0, width};
42
43 end
44
45 endfunction
46
47
48
49 function[16:0] total(input[7:0] width);
50
51 begin
52
53 total = {2'h0, square(width)} + {2'h0, circle(width)};
54
55 end
56
57 endfunction
58
59
60
61 //Logical
62
63 always @(posedge CLK, negedge RST)
64
65 begin
66
67 if (!RST)
68
69 //Reset
70
71 begin
72
73 area <= 17'h0000;
74
75 end
76
77 else
78
79 //Data comes
80
81 begin
82
83 area <= total(width);
84
85 end
86
87 end
88
89
90
91 endmodule
func_total
其中的Π/4 = (24'd201/256),diameter为圆的直径。代码注意点:一是体现了函数中调用函数。二是信号位宽的变化。
square = {8'h0, width} * {8'h0, width};
//平方,则每个变量前补充相同输入变量位宽,即输出square为输入位宽的两倍。
total = {2'h0, square(width)} + {2'h0, circle(width)};
//为避免相加溢出,位宽又扩宽两位,仅仅把低17位的值赋给total。
三 任务
与函数的调用类似,任务的调用只有一种形式,如表7.2 所示。与函数的调用不同的是:任务的调用是在代码里单独一行书写的。

下面是几点需要强调的规则:
(I) 任务的输入、输出端口和双向端口数量不受限制,甚至可以没有输入、输出及
双向端口;
(2)在任务定义的描述语句中,可以使用出现不可综合操作符合语句(使用最为频
繁的就是延迟控制语旬),但这样会造成该任务不可综合;
(3)在任务中既可以调用其他的任务或函数,也可以调用自身;
(4) 在任务定义结构内不能出现initial 和always 过程块;
(5)可以在任务中中断正在执行的任务,但其是不可综合的;当任务被中断后,程
序流程将返回到调用任务的地方继续向下执行;
(6)任务调用语句只能出现在过程块内;
(7)任务调用语句和一条普通的行为描述语句的处理方法一致;
(8)当被调用输入、 输出或双向端口时, 任务调用语句必须包含端口名列表, 且信号端口顺序和类型必须和任务定义结构中的顺序和类型一致; 需要说明的是, 任务的输 出端口必须和寄存器类型的数据变量对应;
(9)综合任务只能实现组合逻辑, 也就是说, 调用可综合任务的时间为 “ 0"; 而在面向仿真的任务中可以带有时序控制,如时延,因此面向仿真的任务的调用时间不为“ 0”。
下面为任务声明及调用例子

1 task total(input[7:0] width, output[l7:0J area);
2 begin
3 area <= {2'h0, square(width)} + {2'h0, circle(width)};
4 end
5 endtask
6
7 always @(posedge CLK, negedge RST)
8 begin
9 if (!RST)
10 //Reset
11 begin
12 area <= 17'h0000;
13 end
14 else
15 //Data comes
16 begin
17 total(width, area);//task call(调用)
18 end
19 end
Task example
为了避免多次调用任务造成的地址冲突,添加automatic使任务成为可重入的。这时在调用任务时,会自动给任务声明变量分配动态地址空间,从 而有效避免了地址空间的冲突。
一个模块里的任务可以在其他模块调用。
1 module module_main;
2 task task_1...
3 task task_2...
4 endmodule
5 //other
6 module mainm1;
7 m1.task_1(...)
8 m2.task_1(...)
9 endmodule
上面对于仿真验证特别管用。
三 总结

今天下午就看了一讲,着重是自己看一遍,然后动手敲一下代码,之后仿真验证结果。计算游泳池面积的仿真代码:
`timescale 1ns / 1ps module tb_top();
//========================================================
//parameters
parameter CLK_FREQ = 50.000;//ddr reference clock frequency, unit: MHz
parameter CLK_PERIOD = 1000.0/CLK_FREQ; //unit: ns // parameter FREQ = 100_000_000 ;
// parameter BAUDRATE = 115200 ;
//=======================================================
reg clk; // 50M
reg rst_n ;
reg [7:0] input_data; wire[16:0] output_data; //========================================================
GSR GSR(.GSRI(1'b1)); //==============================================
//rst_n
initial
begin
rst_n = 1'b0;
input_data = 0;
#200;
rst_n = 1'b1;
input_data = 8'd1;//1+(pi/4)=1
#200; input_data = 8'd4;//16+12=28
#200;
input_data = 8'd6;//36+28=64
#200;
#200; input_data = 8'd10;//100+78.5=178.5
#200;
rst_n = 1'b0;
#200;
$stop;
end //----------------------------------------------------
//ref clk
initial
begin
clk = 1'b0;
end always #(CLK_PERIOD/2.0) clk = ~clk; //==================================================
//TX
function_total inst_function_total (.CLK(clk), .RST(rst_n), .width(input_data), .area(output_data)); endmodule
仿真结果如下所示:

后面还有很多要看,但以理解原理和动手实践为主。通过编代码和仿真,能够感觉更真实。
FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用的更多相关文章
- 基于小波变换的数字图像处理(MATLAB源代码)
基于小波变换的数字图像处理(MATLAB源代码) clear all; close all; clc;M=256;%原图像长度N=64; %水印长度[filename1,pathname]=uiget ...
- 【笔记】基于Python的数字图像处理
[博客导航] [Python相关] 前言 基于Python的数字图像处理,离不开相关处理的第三方库函数.搜索网络资源,列出如下资源链接. Python图像处理库到底用哪家 python计算机视觉编程— ...
- 基于FPGA的RGB图像转灰度图像算法实现
一.前言 最近学习牟新刚编著<基于FPGA的数字图像处理原理及应用>的第六章直方图操作,由于需要将捕获的图像转换为灰度图像,因此在之前代码的基础上加入了RGB图像转灰度图像的算法实现. 2 ...
- 自己动手写CPU(基于FPGA与Verilog)
大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...
- 基于FPGA的音频信号的FIR滤波(Matlab+Modelsim验证)
1 设计内容 本设计是基于FPGA的音频信号FIR低通滤波,根据要求,采用Matlab对WAV音频文件进行读取和添加噪声信号.FFT分析.FIR滤波处理,并分析滤波的效果.通过Matlab的分析验证滤 ...
- 基于FPGA的按键扫描程序
最近在学习FPGA,就试着写了个按键扫描的程序.虽说有过基于单片机的按键扫描处理经验,对于按键的处理还是有一些概念.但是单片机程序的编写通常都采用C写,也有用汇编,而FPGA却是采用VHDL或者Ver ...
- 基于FPGA的红外遥控解码与PC串口通信
基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...
- 基于FPGA的OLED真彩色动态图像显示的实现
源:基于FPGA的OLED真彩色动态图像显示的实现 作为第3代显示器,有机电致发光器件(Organic Light Emitting Diode,OLED)由于其主动发光.响应快.高亮度.全视角.直流 ...
- 基于FPGA的均值滤波算法的实现
前面实现了基于FPGA的彩色图像转灰度处理,减小了图像的体积,但是其中还是存在许多噪声,会影响图像的边缘检测,所以这一篇就要消除这些噪声,基于灰度图像进行图像的滤波处理,为图像的边缘检测做好夯实基础. ...
随机推荐
- 如何为应用选择最佳的FPGA(上)
如何为应用选择最佳的FPGA(上) How To Select The Best FPGA For Your Application 在项目规划阶段,为任何一个项目选择一个FPGA部件是最关键的决策之 ...
- .NET平台系列24:从.NET Framework迁移到.NET Core/.NET5的技术指南
系列目录 [已更新最新开发文章,点击查看详细] 本文讲解了在将代码从 .NET Framework 移植到 .NET(旧称为 .NET Core)时应考虑的事项. 对于许多项目,从 .NET ...
- 这应该是把Java内存区域讲的最清楚的一篇文章
基本问题: 介绍下 Java 内存区域(运行时数据区) Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么) 对象的访问定位的两种方式(句柄和直接指针两种方式) 拓展问题: ...
- 【题解】斐波拉契 luogu3938
题目 题目描述 小 C 养了一些很可爱的兔子. 有一天,小 C 突然发现兔子们都是严格按照伟大的数学家斐波那契提出的模型来进行 繁衍:一对兔子从出生后第二个月起,每个月刚开始的时候都会产下一对小兔子. ...
- 【单调栈】【前缀和】【二分查找】8.28题解-long
long 题目描述 AP神牛准备给自己盖一座很华丽的宫殿.于是,他看中了一块N*M的矩形空地.空地中每个格子都有自己的海拔高度.AP想让他的宫殿的平均海拔在海平面之上(假设海平面的高度是0,平均数都会 ...
- 一文带你.Net混合锁和lock语句
本文主要讲解.Net基于Monitor.Enter和lock实现互斥锁 Monitor.Enter实现 相比前面的锁来说,混合锁的性能更高,任何引用类型的对象都可以做为锁对象,不需要事先创建指定类型的 ...
- 『心善渊』Selenium3.0基础 — 7、XPath轴定位详解
目录 1.XPath轴定位介绍 2.位置路径表达式概念 3.步的路径表达式范例 4.练习 使用XPath轴方式,可根据文档中元素的相对位置,来进行元素的定位.例如:先找到一个相对好定位的元素,在根据与 ...
- JWT原理实现代码
JWT学习文章: 第一篇:JWT原理 第二篇:JWT原理实现代码 上一篇学习了JWT的基本理论,这一篇将根据原理进行代码实现. 要想实现jwt的加密解密,要先生成一个SecurityKey,大家可以在 ...
- DHCP的简单介绍与配置
一.DHCP简介 二.DHCP报文类型 三.DHCP工作原理 四.实例操作 一.DHCP简介 DHCP(Dynamic Host Configuration Protocol),动态主机配置协议,是一 ...
- 创建Akamai cdn api授权
注:通过Akamai Cli purge和通过Akamai API进行刷新之前,都要事先创建类似于如下的刷新的凭据,这两种刷新方式所创建的凭据是相同的. 目的:创建Akamai CDN API授权以便 ...