1、本 科 毕 业 设 计(2011 届)题 目 KMP 算法的 FPGA 实现学 院 电子信息学院专 业 集成电路设计与集成系统班 级 07042211学 号 07042240学生姓名 褚小伟指导教师 李训根完成日期 2011 年 3 月诚 信 承 诺我谨在此承诺:本人所写的毕业论文KMP 算法的 FPGA 实现均系本人独立完成,没有抄袭行为,凡涉及其他作者的观点和材料,均作了注释,若有不实,后果由本人承担。承诺人(签名): 年 月 日杭州电子科技大学本科毕业设计摘 要随着网络技术的迅猛发展,所要检测的数据包越来越多,单纯的依靠软件来检测,越来越显得力不从心。伴随着 FPGA 技术的发展,在硬件
2、上实现模式匹配,来提高网络数据处理速度的需求越来越普遍。把搜索算法固化到 FPGA 里,从而可以大大提高算法的速度,适应科技的迅速发展。本文重点分析了几种典型的模式匹配算法。包括:BF算法、KMP算法、BM算法、BMH算法、AC算法和AC-BM算法。另外文章还介绍了FPGA的的相关基本知识以及硬件描述语言的选择。综合考虑现有的比较成熟的模式匹配算法,并且追踪国外基于FPGA技术来实现模式匹配的研究成果,认为在硬件实现方面,KMP算法效率较高,结构简单,可行性强,而且易于对主串进行多模式的匹配,所以选其作为模式匹配硬件模块的核心算法,通过硬线逻辑来进一步提高串模式匹配的效率。本文KMP算法程序设
3、计部分主要分为三个部分:模式串输入、next函数的计算、字符串的匹配。具体情况会在第四章中介绍。关键词:模式匹配算法;KMP 算法;FPGA杭州电子科技大学本科毕业设计ABSTRACTWith the rapid development of network technology, have to text more and more packets. Thus, simply relying on software to detect becomes more and more inadequate.As the development of FPGA technology, its bec
4、omes increasingly popular to realize the pattern matching on hardware to meet the demand for the improvement of the processing speed of network data. Putting the search algorithm to the FPGA, which can greatly improve the speed of the algorithm, is adapt to the quick development of technology.This p
5、aper focuses on several typical patterns matching algorithm involving: BF algorithm, KMP algorithm, BM algorithm, BMH algorithm, AC algorithm and the AC-BM algorithm.Besides, this paper will also introduce the basic knowledge related to FPGA as well as the selection of the description language of ha
6、rdware. Considering the current pattern matching algorithms which are relatively through and the reseaching findings from abroad of using FPGA to achieve pattern mactching, KMP has advantages of efficient arithmetic, simple organization, strong feasibility and easy multi-pattern macthing to primary
7、string in realizing hardware.Thats the reason why choose it to be the core arithmetic of matching pattern and hardware module, which makes further improvement on effiency of pattern maching in string by via hard wire logic.This part of KMP Algorithm Programming is divided into three parts: the patte
8、rn string entered, next function calculation, string matching. The circumstances described in the fourth chapter.Key words:Pattern matching algorithm;KMP algorithm;FPGA杭州电子科技大学本科毕业设计目 录第 1 章引言 .11.1 研究背景 11.2 模式匹配算法的发展与研究现状 1第 2 章 模式匹配算法 32.1 模式匹配定义 32.2 单模式匹配 32.2.1BF 算法 .32.2.2KMP 算法 42.2.3BM 算法 .
9、62.2.4BMH 算法 72.3 多模式匹配 72.3.1AC 算法 .72.3.2AC-BM 算法 82.4 影响模式匹配算法的因素 9第 3 章 FPGA 基本的知识 .113.1FPGA 简介 .113.2FPGA 与 CPLD 的关系以及工作原理 113.3 硬件语言选择 .12第 4 章 KMP 算法 VerilogHDL 实现 .144.1 模式串输入 .144.2next 函数的计算 .154.3 字符串匹配 .194.4 代码通用性的验证 .22第 5 章结束语 27致谢 28附录 31杭州电子科技大学本科毕业设计- 1 -第1章 引言1.1研究背景 1在网络处理中,模式匹配
10、是指将分组各域进行比特位的匹配处理。一般,模式匹配模块有两个输入,一个是规则的模式表达式,另一个是分组域。它的输出是输入分组的各域是否与输入模式的布尔值匹配。这类模式匹配的实质还是字符串匹配,它的基本运算就是从一个主字符串中找到某个特定模式串出现的位置。目前,串匹配算法一般是以模式串的长度为扫描窗口大小,在窗口中使用不同的扫描策略来进行匹配。假设模式串长为m,主串长为n,串匹配算法根据策略的不同,大致可以分为以下3类 23:从前往后匹配模式前缀的KMP算法,从后往前匹配模式后缀的BM算法及其各种变形,以及从后往前匹配模式前缀的RF算法等等。KMP4算法是从前往后进行扫描,使用自动机记住己匹配模
11、式前缀的正文内容,并依据这些内容来确定是否已经匹配成功。换句话说,就是先对模式串进行预计算,然后再与主串匹配,而且主串不需要回溯,它的时间复杂度比较好,一般是O(m+n)。BM 5算法及其变形是在扫描窗口中从后往前进行扫描,记住已匹配模式后缀的正文内容,并依据这些内容来进行窗口移动,这种方法虽然简单易行,但是时间复杂度比较差,最坏情况下为0(m+n),所以当串比较长时,效率就会很低。RF算法等是在从后往前进行扫描时,反向使用模式逆串的后缀自动机来匹配模式的前缀,这样可以增大窗口移动的距离,从而获得更好的平均时间复杂度,达到理论最优结果。该方法效率较高,但是比较复杂,硬件实现难度大。综合考虑现有
12、的比较成熟的模式匹配算法,认为在硬件实现方面,KMP算法具有其他算法没有的优势,所以本文选择KMP算法作为研究的主要对象。1.2模式匹配算法的发展与研究现状 14BF算法是最早提出来的模式匹配算法,也是最简单的一个算法。该算法的最坏时间复杂度为O(M*N)。1970年,SACOOK从理论上证明了串匹配问题可以在O(m+n)时间内解决,同一年,Morris和Pratt仿照COOK的证明构造了一个算法,随后,Knuth对这个算法进行了一些改进,在1976年,Knuth提出了第一个在线性时间内解决字符串的模式匹配算法,这个算法被称为KMP算法它的时间复杂度为O(m+n)。1977年,Boyer和Mo
13、ore提出了另一个与KMP算法截然不同的却同样拥有线性时间复杂度的算法(BM算法)。BM算法在实际的模式匹配中,跳过了很多无用的字杭州电子科技大学本科毕业设计- 2 -符,这种跳跃式的比较方式,使BM算法获得了极高的效率,特别是在大字符集上进行字符串的模式匹配时。在实际的应用中,BM算法比KMP算法更有效率。多模式匹配是另一个研究热点。Aho-Corasie算法(AC算法)是第一个在O(N)上解决这个问题的算法。AC算法可以被看作是KMP算法的更一般化形式。此后,BM算法跳跃的思想也被应用到了多模式匹配上,1979年CommentsWalter提出了一种新的多模式匹配算法,称为CW算法,这个算
14、法将AC算法和BM算法的思想结合起来,获得了更好的执行效率。沿着AC算法这条路线,Crochemore等人将AC算法和DAWG结合,获得了一种新的算法,称为DAWG-MATCH。实验结果表明,该算法比Comments-Walter的算法更有效率。此外,人们还提搬了其它一些多模式匹配算法。1994年,Sun Wu和Manber提出了第一个基于过滤思想的多模式匹配算法。这个算法将过滤思想和BM思想结合起来,在实际的应用中获得了极其高的效率。实验表明,在Sun Sparcl0上,他们的算法可以于10秒内完成在15.8M的文本中搜索10000个模式的工作。在WM算法的基础上,Sun Wu和Manber
15、实现了一个用于模糊匹配的工具agrep和一个文本检索的工具glimpse,在实际的应用中都获得了良好的效率。1996年,Robert Muth和Udi Manber给出了一个快速的多模式模糊匹配算法,这个算法也是基于过滤的思想,同时采用了两级散列的技术,从而获得了极高的执行效率,实验数据表明,该算法能在小于1秒的时间内完成在1M文本中对1000个模式的搜索和模糊匹配的过程。但是不幸的是,该算法只允许模式和文本子串之间存在1个不同点,这样的约束限制了该算法在实际中的应用。1999年,在数据压缩和位操作的思想上,Sun Kim和Yanggon Kim设计出了一个新的多模式匹配算法,实验证明,该算法
16、比Sun Wu和Manber的算法有更好的表现,特别是在小字符集上。目前对模式匹配算法的研究一部分还停留在单模式匹配算法,而对多模式匹配算法的研究主要集中在算法的综述、测试以及对现有算法的一些相应改进上。这些改进的算法虽然也取得一定的成果,但是总体效果都不是很理想,主要是算法速度受限于模式的数目或者实现算法需要的空间消耗的内存太大。字符串的模糊匹配是近年来倍受关注的领域,模糊匹配允许在搜索时搜索出与模式有一些差别的文本中的字符串。在这个领域,有四条主要的技术路线:动态规划算法;自动机算法;过滤算法;位并行算法。由于这不是本文研究的主要内容,故不做详细介绍。杭州电子科技大学本科毕业设计- 3 -
17、第2章 模式匹配算法模式匹配分为单模式匹配和多模式匹配,一次在文本串中查找一个模式串出现的过程,称为单模式匹配。同时查找一个模式串集合中的所有模式串的出现的过程称为多模式匹配。本章主要讨论几种典型的单模式匹配算法和多模式匹配算法。2.1模式匹配定义字符串的模式匹配问题的形式化定义如下:在字符集上,给定一个长度为N的文本字符串T1N,以及一个长度为M的模式 字符串 Pi1M。模式集数量用k来表示,模式集用P=pl,p2,pk来表示。如果对于l=distt,故相对BM算法具有一定的优越性。BMH算法预处理时间复杂度为O(m+o),空间复杂度先0(o),o是与Pattern、Text相关的有限字符集
18、长度。查找阶段时间复杂度为O(mn),在一般情况下,BMH算法比BM有更好的性能,它只使用了一个数组,简化了初始化过程。2.3多模式匹配2.3.1AC算法1975年,贝尔实验室的Alfred VAho和Margaret JCorasick提出了著名的多模式匹配算法一一AC自动机匹配算法(简称AC算法)。该算法最早被使用在图书馆的书目查询程序中,取得了很好的效果。AC算法描述(例如模式集SP=he,she,his,hers):预处理阶段,模式树的各个节点作为状态,根节点作为初态,标签为模式的杭州电子科技大学本科毕业设计- 8 -节点作为终态,利用转向函数g和失效函数f作为转移函数,将模式树扩展成
19、一个树型有限自动机。见图2-4由模式树扩展所得的AC自动机M是1个6元组:M= (Q,g,f,qo,F)其中:(1)Q是有限状态集(模式树上的节点);(2)是有穷的输入字符表(数据包中可能出现的所有字符);(3)g是转移函数,该函数定义如下:g(S,a):从当前状态S开始,沿着边上标签为a的路径所到的状态。假如(U,v)边上的标签为a,那么g(U,a)=v;如果根节点上出来的边上的标签没有a,则g(0,a)=O,即如果没有匹配的字符出现,自动机停留在初态;(4)f(不匹配时自动机的状态转移)也是转移函数,该函数定义如下:f(S):当w是L(s)最长真后缀并且W是某个模式的前缀,那么f(S)就是
20、以W为标签的那个节点;(5)qoQ是初态(根节点,标识符为0);(6)F量Q是终态集(以模式为标签的节点集)。这样,在文本字符串中查找模式字符串的过程转化成在模式树中的查找过程。查找一个文本字符串T时从模式树的根节点开始,沿着以T中字符为标签的路径往下走:若自动机能够抵达终态v,则说明T中存在模式L(v):否则不存在模式。图2-4 模式树AC算法模式匹配的时间复杂度是O(n),并且与模式集中模式字符串的个数和每个模式字符串的长度无关。无论模式字符串P是否出现在文本字符串T中,T中的每个字符都必须输入状态机中,所以无论是最好情况还是最坏情况,AC算法模式匹配的时间复杂度都是0(n),包括预处理时
21、间在内,AC算法总时间复杂度是O(M+n),其中M为所有模式字符串的长度总和。AC算法的查找效率明显高于BM算法。但是,AC算法在对文本字符串匹配的过程中没有跳跃,无法跳过不必要的比较,并且有限状态自动机算法是以空间换时间的经典算法,当模式集较大时可能产生内存膨胀问题。因此在实际的匹配过程中,AC算法不可能是性能最佳的搜索算法。杭州电子科技大学本科毕业设计- 9 -2.3.2AC-BM算法AC-BM算法是在AhoCorasick算法的基础上,结合BoyerMoore算法的跳跃思想,产生的一种多模式匹配算法。在一般情况下,由于应用了BM算法的跳跃式思维,所以不需要对文本的每个字符进行匹配。在BM
22、算法的基础上引入了AC算法,来提高匹配速度,跳过尽可能多的字符,在模式字符串较长和较短的情况下,该算法都具有很好的性能。AC-BM算法描述:设模式树中最短模式串的长度为L,第一次比较是从待匹配的文本字符串的末端向前取L个字符与模式树的根字符对齐,然后从树的根字符开始比较,当出现不匹配的字符时:(1)若目标字符不在任何模式串中,则模式树偏移量为L位;(2)移动到另一模式串前缀的下一位置;(3)将模式树移动到作为树中另一个模式后缀能够正确匹配目标串的某个前缀的下一个位置。要注意的是:AC-BM算法在移动过程中,模式树移动的偏移量不能超过最短模式串的长度L。我们设模式字符串集合中,字符串最小长度为m
23、inlen,最大长度为maxlen,待匹配文本长度为n,则在最优情况下,时间复杂度为O(nminlen),在最坏情况下,时间复杂度为O(n*maxlen)。AC-BM算法结合多模式匹配AC和单模式匹配BM两种算法的优点,既可以同时匹配多个模式又可以跳过不必要的字符,因此相比其它模式匹配算法具有较高的性能和效率。2.4影响模式匹配算法的因素对于一个模式匹配算法来说,在实际应用中,最为关注的问题有以下几个方面 1819:(1)正确性:即误判率和漏判率,这与模式的选择是密切相关的,如果模式的选择比较严格,那么误判率和漏判率一定会下降,但是过于严格的模式会影响识别的速度;同时过于简短的模式又会影响误判
24、率和漏判率,所以要选择一个最优的折衷点。(2)速度:即时间复杂性,这是评价一个模式匹配算法的重要的标准之一。随着网络速度的提高,通常要求模式匹配能以线速率执行,特别是在一些实时性的系统中,对模式匹配的速度有很高的要求。一般情况下算法的时间复杂性,首先是预处理时间复杂性,其次是匹配过程中的时间复杂性,最后是最坏情况和最好情况下的时间复杂性,特别是最坏情况下的复杂性,是算法研究中的一个重要方面。而在上述三种情况的时间复杂性中,模式的因素都是一个不可缺少的原因。简洁有效的模式不仅可以降低预处理的时间复杂度,而且还能缩短匹配过程的时间,至于最坏和最好的时间复杂度,在很大程度上受控于模式的规模。所以若要
25、杭州电子科技大学本科毕业设计- 10 -提高算法的速度,提高模式的有效性是一个重要途径。(3)资源消耗:在模式的预处理阶段和模式匹配阶段,对内存的需求也是应用中关注的重要问题之一,尽管目前内存的容量提高了很多,但是庞大的内存占有量会减慢算法的速度,所以现在人们常常借助于硬件实现算法。杭州电子科技大学本科毕业设计- 11 -第3章 FPGA的基本知识本章主要介绍FPGA的基本概念,FPGA与CPLD的关系,硬件描述语言的选择。3.1FPGA 简介 21FPGA(FieldProgrammable Gate Array) ,即现场可编程门阵列,它是在PAL、GAL、CPLD 等可编程器件的基础上进
26、一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。目前以硬件描述语言(Verilog 或 VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至 FPGA 上进行测试,是现代 IC 设计验证的技术主流。这些可编辑元件可以被用来实现一些基本的逻辑门电路(比如AND、OR、XOR、NOT)或者更复杂一些的组合功能比如解码器或数学方程式。在大多数的 FPGA 里面,这些可编辑的元件里也包含记忆元件例如触发器(Flipflop)或者其他更加完整的记忆块。 系统设计师可以根据需要通过可编辑的连接把
27、 FPGA 内部的逻辑块连接起来,就好像一个电路试验板被放在了一个芯片里。一个出厂后的成品 FPGA 的逻辑块和连接可以按照设计者而改变,所以 FPGA 可以完成所需要的逻辑功能。 FPGA 一般来说比 ASIC(专用集成芯片) 的速度要慢,无法完成复杂的设计,而且消耗更多的电能。但是他们也有很多的优点比如可以快速成品,可以被修改来改正程序中的错误和更便宜的造价。厂商也可 能会提供便宜的但是编辑能力差的 FPGA。因为这些芯片有比较差的可编辑能力,所以这些设计的开发是在普通的 FPGA 上完成的,然后将设计转移到一个类似 于 ASIC 的芯片上。另外一种方法是用 CPLD(复杂可编程逻辑器件备
28、)。3.2FPGA 与 CPLD 的关系以及工作原理CPLD 与 FPGA 的关系:早在 1980 年代中期,FPGA 已经在 PLD 设备中扎根。CPLD 和 FPGA 包括了一些相对大数量的可编辑逻辑单元。CPLD 逻辑门的密度在几千到几万个逻辑单元之间,而 FPGA 通常是在几万到几百万。 CPLD 和 FPGA 的主要区别是他们的系统结构。CPLD 是一个有点限制性的结构。这个结构由 一个或者多个可编辑的结果之和的逻辑组列和一些相对少量的锁定的寄存器。这样的结果是缺乏编辑灵活性,但是却有可以预计的延迟时间和逻辑单元对连接单元高 比率的优点。而 FPGA 却是有很多的连接单元,这样虽然让
29、它可以更加灵活的编辑,但是结构却复杂的多。 杭州电子科技大学本科毕业设计- 12 -CPLD 和 FPGA 另外一个区别是大多数的 FPGA 含有高层次的内置模块(比如加法器和乘法器)和内置的记忆体。一个因此有关的重要区别是很多新的 FPGA 支持完全的或者部分的系统内重新配置。允许他们的设计随着系统升级或者动态重新配置而改变。一些 FPGA 可以让设备的一部分重新编辑而其他部分继续正常运行。FPGA 的工作原理:(1)采用 FPGA 设计 ASIC 电路(专用集成电路),用户不需要投片生产,就能得到合用的芯片。 (2)FPGA 可做其它全定制或半定制 ASIC 电路的中试样片。 (3)FPG
30、A 内部有丰富的触发器和 IO 引脚。 (4)FPGA 是 ASIC 电路中设计周期最短、开发费用最低、风险最小的器件之一。 (5) FPGA 采用高速 CHMOS 工艺,功耗低,可以与 CMOS、TTL 电平兼容。 可以说,FPGA 芯片是小批量系统提高系统集成度、可靠性的最佳选择之一。 FPGA 是由存放在片内 RAM 中的程序来设置其工作状态的,因此,工作时需要对片内的 RAM 进行编程。用户可以根据不同的配置模式,采用不同的编程方式。 加电时,FPGA 芯片将 EPROM 中数据读入片内编程 RAM 中,配置完成后,FPGA进入工作状态。掉电后,FPGA 恢复成白片,内部逻辑关系消失,
31、因此,FPGA 能够反复使用。FPGA 的编程无须专用的 FPGA 编程器,只须用通用的 EPROM、PROM编程器即可。当需要修改 FPGA 功能时,只需换一片 EPROM 即可。这样,同一片FPGA,不同的编程数据,可以产生不同的电路功能。因此,FPGA 的使用非常灵活。FPGA 有多种配置模式:并行主模式为一片 FPGA 加一片 EPROM 的方式;主从模式可以支持一片 PROM 编程多片 FPGA;串行模式可以采用串行 PROM 编程FPGA;外设模式可以将 FPGA 作为微处理器的外设,由微处理器对其编程。 如何实现快速的时序收敛、降低功耗和 成本、优化时钟管理并降低 FPGA 与P
32、CB 并行设计的复杂性等问题,一直是采用 FPGA 的系统设计工程师需要考虑的关键问题。如今,随着 FPGA 向更高密 度、更大容量、更低功耗和集成更多 IP 的方向发展,系统设计工程师在从这些优异性能获益的同时,不得不面对由于 FPGA前所未有的性能和能力水平而带来的 新的设计挑战。3.3 硬件语言选择 22Verilog HDL 与 VHDL 是两种最常见的硬件描述语言,Verilog HDL 与 VHDL相比有以下一些优点:(1)可以用来进行各种层次的逻辑设计,也可以进行数字系统的逻辑综合、仿真验证和时序分析等。Verilog HDL 适合算法级 (Algorithm)、寄存器传输级杭州
33、电子科技大学本科毕业设计- 13 -(RTL)、逻辑级(Logic)、门级(Gate)和版图级(Layout)等各个层次的设计和描述。(2)VHDL 偏重于标准化考虑,而 Verilog HDL 与 EDA 工具的结合更为紧密。VHDL 是国际上第一个标准化的 HDL 语言(IEEE-1076),是为了实现美国国防部VHSIC 计划所推出的各个电子部件供应商具有统一的数据交换格式的要求。相比之下,Verilog HDL 则是在全球最大的 EDA/ESDA 供应商 Cadence 公司的扶持下针对 EDA 工具开发的 HDL 语言。(3) 与 VHDL 相比,Verilog HDL 的编程风格更
34、加简洁明了,更接近高级计算机语言的语法形式。有鉴于此,本设计采用 Verilog HDL 语言作为硬件描述语言。杭州电子科技大学本科毕业设计- 14 -第 4 章 KMP 算法 VerilogHDL 实现本章主要介绍 KMP 算法的 VerilogHDL 实现设计过程,一些调试碰到的问题及解决方法。4.1 模式串输入kmp 算法是一种改进的字符串匹配算法,由 D.E.Knuth 与 V.R.Pratt 和J.H.Morris 同时发现,因此人们称它为克努特莫里斯普拉特操作(简称 KMP算法) 。KMP 算法的关键是根据给定的模式串 pattern 定义一个 next 函数。next函数包含了模
35、式串本身局部匹配的信息。为了用 Verilog HDL 实现 KMP 算法,我们需要在熟悉算法原理的基础上进行程序设计。KMP 算法的原理已经在论文的第二章详细介绍过,这里就不再累述。图 4-1 模式串输入代码由于 Verilog HDL 语言不像 C 语言一样可以很方便的申请内存用于存放变量或者数据,而既然我们的工作是要进行字符串的查找,那么首先我们需要有两个字符串。如何存放这两个字符串?有两种方法:一种是将字符串存放在 FPGA 内部的存储器中,比如使用 Quartus II 自带的 MegaWizard Plug-in Manger 工具在 FPGA 内部定制一个 RAM 或者 ROM
36、存放字符串,或者直接定义一个数组,即使用 FPGA 的逻辑单元构造 RAM 用于存放字符串。当然后一种方式的代价会比较高,尤其是当 FPGA 的逻辑单元相对较少时,随意地挥霍这种宝贵的资源就不可取。对于本设计,由于我们只是需要验证算法,因此用作主串的字符串不需要很长(实际使用了一个长度为 16 的字符串) ,因此可以直接定义数组来存放这个字符串,这样做可以避免另外设计电路用于控制 RAM 的读取。另外一种方法是令字符杭州电子科技大学本科毕业设计- 15 -串从外部通过引脚输入到 FPGA 中,然后再存放在 FPGA 的内部 RAM 中,采用这样的设计方式,字符串的内容可以很方便地改动,本设计中
37、的模式串就采用这种方式从外部输入。首先我们需要设计一个模式串的输入接口,模式串输入的Verilog HDL 代码如图 4-1 所示:我们的 Verilog HDL 开发环境为 Quartus II 8.0 Wed Edition,Quartus II是一个功能强大的集成开发环境,支持从源代码编辑到仿真、布局布线和芯片烧录的全部功能。上述代码中,k 是一个计数值,宽度为 4 位,表示当前输入的字符的个数,在复位时初始化为 0。在每个时钟的上升沿,k 递增 1。p 是一个位宽为 8 的端口,外部数据就从这个端口输入。在每个时钟的上升沿,p 端口的值赋给 patternk寄存器。因为模式串的长度是
38、8,因此当计数值 k7 时就不再需要存储端口 p 的数据,但是为了显示模式串输入已经完成,必须给出一个提示信息,这个提示信息不需要输出到 FPGA 的外部,只需要提醒内部的相关检测机制就可以,wr_ed 就是这个提示信息,并且将它定义为一个 reg 型的变量,位宽为 1 位。当 k7 时就令 wr_ed 为 1,表示模式串已经全部输入。该部分的功能仿真结果见图 4-2:图 4-2 模式串输入仿真结果其中 pattern0pattern7 是 wire 型的输出口连接到 pattern0pattern7,这只是一组用于观测 FPAG 内部寄存器值的端口变量,而这一组端口变量对一设计本身并不是必需
39、的,因此当模式串输入接口的设计完成以后,可以撤销这一组端口。从仿真结果中可以看出,当 wr_ed 变为 1 时,说明模式串应当已经输入到FPGA 内部的数组中了,我们查看此时的 pattern0pattern7可以发现,模式串确实已经输入到内部的数组中了,这与我们的设想吻合。4.2next 函数的计算杭州电子科技大学本科毕业设计- 16 -为了便于 Verilog HDL 程序设计,我们首先用 C 语言描述 KMP 算法。之所以先用 C 语言描述 KMP 算法,是因为 Verilog HDL 最为一种高级的硬件描述语言,与 C 语言的风格有许多类似之处,其中有许多语句,如 if 语句、case
40、 语句和 C语言中的对应语句十分相似。如下所示是 next 函数的 C 语言代码,在 Visual Studio 2008 下编辑和调试代码。int* computeNext(const char* pattern)(int len , i, nextTemp;int *next ;assert(pattern !=NULL);len = strlen(pattern);if (len = 0) len =1;next = (int*)malloc(sizeof(int) * len );for (i =1; i 7 时,nextdone 就会等于 1,表示next 函数已经计算完毕,可以进行
41、后续的字符匹配工作了。nextdone 的功能与模式串输入函数中的 wr_ed 具有类似的功能。上述代码的结构与用 C 语言编写的代码十分相似,这就说明我们在理解了算法原理的基础上,可以很方便的将 C 语言编写的代码改写成 Verilog HDL 语言。但是这两种语言还是有很大的区别的,与 C 语言不同,在 Verilog HDL 中是没有定义诸如 char、int、float 这样的数据类型,所有的数据类型都是二进制数据,数据的每一位只有 0 和 1 两种取值,我们无法定义一个数为 char 型或者 float型。因此在表示负数的时候我们就会不能简单地赋值,而因当采用补码的形式表示,比如-1
42、 我们就可以表示成 4b1111,在数字系统综合的过程中这个数值就会被认为是-1。这一点是 Verilog HDL 语言与高级计算机语言存在巨大差别的地方。接下来我们需要验证我们设计的代码功能是否正确,这是很容易验证的。我们首先在 C 语言代码中对一个模式串“abaabcac”计算 next 值,得到如图 4-5的运算结果:图 4-5 Visual C+下 next 计算结果由上图可见对于“abaabcac”这个字符串,next 函数的计算结果是-1,0,0,1,1,2,0,1。另外我们还发现程序的运行结果提示在主串中找到的模式串的其实位置为-1,为什么呢?其实这是因为在这一次运行中我们设置的
43、主串中没有包含一个有效的模式串,因此运行结果是找不到匹配的字符串,在这种情况下我们在控制台输出一个-1 表示没有找到匹配的字符串。接下来我们来测试我们用 Verilog HDL 编写的代码功能是否正确。Quartus II 中新建一个仿真波形文件,然后设置仿真模式为功能仿真(由于我们只是要验证电路的工作机制是否正确,因此只要选择功能仿真即可) ,然后将端口变量添加到仿真窗口中,设置时钟和其他输入变量,点击“Generate Functional Simulation Netlist”,生成功能仿真的仿真网表文件,然后运行仿真,仿真结杭州电子科技大学本科毕业设计- 19 -果如图 4-6 所示:
44、图 4-6 next 函数在 Quartus II 下的仿真结果由上图可见,当 nextdone 为 1 时,说明 next 函数已经计算完成,这个时候我们可以查看 next数组的值,由于 next0next7 是一组线网型的端口变量,直接反映 next数值的值,因此我们观查 next0next7 的值,发现其数值为-1、0、0、1、1、2、0、1。这个运算结果与 C 语言的运算结果是一致的,这说明我们设计的 next 函数状态机是完全正确的!4.3 字符串匹配在设计完 next 函数的 Verilog HDL 实现之后,我们的设计的最核心部分已经完成了,接下来要做的工作就是根据 next数组
45、进行字符串的匹配操作。既然是字符串匹配,那么我们必然需要一个主串供我们查找,前面已经提到过 FPGA中数据的存储方式,为了方便调用存储的数据,我们将主串存放在内部数组中,占用 FPGA 的片上逻辑单元,在系统复位时对数组中的值进行初始化。同样的,我们先来看字符串匹配的 C 语言代码如下int stringMatchKmp(const char* src, const char* target)int srcLen, targetLen;int i = 0, j = 0, index;int *next;assert(src != NULL srcLen = strlen(src);target
46、Len = strlen(target);next = computeNext(target);print(next, strlen(target) );while (i srcLen j+;elsej = nextj;if (j = targetLen)index = i -targetLen;elseindex = -1;free(next);return index;仔细观察这段代码,我们可以发现这其实也是一个状态机,而这个状态机可以分解为三个状态,如下所述:(1)初始状态,直接跳转到下一个状态;(2)判断对主串的查找是否结束,判断对模式串的匹配是否已经结束。若已经完成对主串的查找,跳转
47、到下一状态;否则,若模式串的匹配长度未达到最大值(这里是 8) ,则继续匹配,否则给出匹配位置和匹配成功标志(matching=1) ,并初始化匹配长度,为下一次匹配做准备;(3)给出结束标志(over=1) ,进入死循环;总的来说,这段代码的主要工作都是在状态机的第二个状态完成的,因此状态机的第二个状态也是代码编写过程中需要仔细推敲的部分。按照编写 next 函数的方法,我们将字符串查找的 C 语言代码改写成 Verilog HDL 代码,如图 4-7所示:杭州电子科技大学本科毕业设计- 21 -图 4-7 字符串查找代码图 4-8 Visual C+下 KMP 算法的输出结果这里我们使用的
48、主串是“abaabcacabaabcac” ,模式串依然是“abaabcac” ,首先杭州电子科技大学本科毕业设计- 22 -我们在 Visual studio 下运行 C 语言的代码,得到下面的运行结果如图 4-8:Visual Studio 的运行结果显示匹配位置为 0 和 8。事实上在位置 0 和位置 8处确实分别有一个匹配的字符串。接下来我们在 Quartus II 下进行仿真,查看仿真结果与 Visual Studio 给出的结果是否相同。Quartus II 下的仿真结果如图4-9 所示:图 4-9 KMP 算法在 Quartus II 下的仿真结果4.4 代码通用性的验证仿真窗口
49、中的 wz 变量表示查找到的模式串在主串中的起始位置。由 Quartus II 的仿真结果可见,当 matching1 时,对应的 wz 分别为 0 和 8,这与我们在Visual Studio 得到的结果是一致的,而两个匹配结果得到之后,很快 over 信号就变成了 1,说明字符串查找的工作已经结束。这样看来似乎没有什么问题,但是需要注意的是,在这次仿真的过程中,我们所使用的主串“abaabcacabaabcac”中包含了两个完整的模式串“abaabcac” ,这似乎是一个太特殊的例子,为了证明我们所编写的代码具有通用性,我们将多测试几组字符,并且比较 Visual Studio 和 Quartus II 的输出结果是否是一致的。图 4-10 仿真结果出现问题杭州电子科技大学本科毕业设计- 23 -于是我们不改动模式串,而将主串串修改为“bbaabcacabaabcac” ,它包扩一个完整的模式串以及一些不匹配的字符,在 Visual Studio 下的测试结果与预想的一致,而在 Quartus II 的仿真结果却出现了问题如图 4-10:由仿真结果可见,ove