VHDL中Loop动态条件的可综合转化

[复制链接]
2432|0
 楼主| flycat2008 发表于 2008-8-1 10:50 | 显示全部楼层 |阅读模式
<br />引言<br /><br />VHDL是一种硬件描述语言,于1983年被IEEE制定为国际标准IEEE1076。近年来国内引进和出版了不少教<br /><br />材,使其在国内得到迅速推广。由于VHDL最初目的是为了实现硬件的建模而被提出的,所以其措施能力<br /><br />超越了数字逻辑集成电路的范围。而现有的EDA工具基本上只能支持VHDL的子集,特别是针对FPGA/CPLD<br /><br />器件进行的不同的综合工具,其综合子集并非统一,不少初学者很难掌握。即使是部分有经验的设计者<br /><br />,对于通常高级语言中都会涉及的循环语句,在VHDL中往往也不能运用自如,甚至无法表达此类逻辑,<br /><br />从而限制了VHDL的应用水平。例如,VHDL的并行堆排序描述就是一个比较典型的例子。该实例十分类似<br /><br />通常数据结构的描述,推广前景诱人;但只能通过仿真,却不能在目前任何一个EDA工具进行综合,导致<br /><br />无实用价值。<br /><br />本文从高级语言涉及最多的Loop语句出发,讨论如何在VHDL中解决这类问题。<br /><br />1&nbsp;无法综合的Loop动态条件<br /><br />VHDL中Loop表达式有三种体现形式:While……Loop、For……Loop和单独的Loop语句。它还支持Next、<br /><br />Exit和标号,因此,循环语句的表达能力大于常规的C或PASCAL语言。程序1是利用For语句和While语句<br /><br />描述插入算法的部分代码。<br /><br />程序1&nbsp;不可综合的VHDL循环语句<br /><br />……<br /><br />for&nbsp;I&nbsp;in&nbsp;2&nbsp;to&nbsp;Length&nbsp;loop&nbsp;---Length为一个变量<br /><br />Temp:=MyList(I);<br /><br />J:=I;<br /><br />While(j&gt1)and&nbsp;MyList(j-1)&ltTemp&nbsp;loop<br /><br />MyList(j):=MyList(j-1);<br /><br />j:=j-1;<br /><br />End&nbsp;loop;<br /><br />MyList(j):=Temp;<br /><br />End&nbsp;loop;<br /><br />……<br /><br />对于第一个For语句,EDA工具Synplify综合时将会给出无边界的范围错误提示。<br /><br />@E:&quot;H:.vhd&quot;|for&nbsp;loops&nbsp;with&nbsp;unbound&nbsp;ranges&nbsp;should&nbsp;contain&nbsp;w&nbsp;wait&nbsp;statement<br /><br />即使部分优秀的综合工具,例如ORCAD&nbsp;Express、Mentor&nbsp;Grpahs&nbsp;QuickHDL等能够综合第一个For语句,<br /><br />也无法支持第二个While条例表达式。ORCAD&nbsp;Express将给出表达式不可静态计算的错误提示。<br /><br />..vhd(45):Error,expression&nbsp;does&nbsp;not&nbsp;evaluate&nbsp;to&nbsp;a&nbsp;constant.<br /><br />由于程序1在C程序员看来是没有问题的,因此,初学者往往不能解决好此类问题,从而使学习陷入困境<br /><br />,无法充分利用VHDL来表述逻辑。<br /><br />2&nbsp;直接代换法<br /><br />对于第一类无边界的范围错误问题,可以用循环的综合机制转化为相应的语句。例如下面代码:<br /><br />for&nbsp;I&nbsp;in&nbsp;0&nbsp;to&nbsp;1&nbsp;loop<br /><br />Out_Bus(i)&lt=In_Bus(i);<br /><br />End&nbsp;loop;<br /><br />其对应综合后的电路见图1。<br /><br />相应的,也可以用下列语句直接代入代换:<br /><br />Out_Bus(0)&lt=In_Bus(0);<br /><br />Out_Bus(1)&lt=In_Bus(1);<br /><br />程序1可以采用下列VHDL代码表示:<br /><br />K:=2;<br /><br />Temp:=MyList(2);<br /><br />If(MyList(1)&ltTemp&nbsp;then<br /><br />MyList(2):=MyList(1);<br /><br />J:=1;<br /><br />End&nbsp;if;<br /><br />MyList(J):=Temp;<br /><br />J:=3;<br /><br />Temp:=MyList(3);<br /><br />If(MyList(2)&ltTemp&nbsp;then<br /><br />MyList(3):=MyList(2);<br /><br />J:=2;<br /><br />End&nbsp;if;<br /><br />If(MyList(1)&ltTemp&nbsp;then<br /><br />MyList(2):=MyList(1);<br /><br />J:=1;<br /><br />End&nbsp;if;<br /><br />MyList(J):=Temp;<br /><br />……<br /><br />然而,这种使用方法要求设计者清楚循环条件一定会执行的次数,否则将无法实施。当循环次数比较大<br /><br />时,代码编写工作量将十分庞大,因此可以采用第二种方法——边界扩充法。<br />3&nbsp;边界扩充法<br /><br />边界扩充法是指在边界未定时,可以将边界定为最大可能的范围,即用静态表达来替代。例如程序1的代<br /><br />码可以改写为:<br /><br />constant&nbsp;MAX:integer=100;&nbsp;--MAX必须大于MyLen所有可能的取值<br /><br />……<br /><br />Out_loop:for&nbsp;I&nbsp;in&nbsp;2&nbsp;to&nbsp;MAX&nbsp;loop<br /><br />Exit&nbsp;out_loop&nbsp;when&nbsp;I&gtMyLen;&nbsp;--MyLen为变量<br /><br />Temp:=MyList(I);<br /><br />countj:=I;<br /><br />inter_loop:for&nbsp;j&nbsp;in&nbsp;I&nbsp;downto&nbsp;2&nbsp;loop<br /><br />countj:=j;<br /><br />exit&nbsp;inter_loop&nbsp;when&nbsp;MyList(j-1)&ltTemp;&nbsp;--退出循环<br /><br />MyList(j):=MyList(j-1);<br /><br />End&nbsp;loop;<br /><br />MyList(countj):=Temp;<br /><br />End&nbsp;loop;<br /><br />尽管这种方法可以处理未知边界和未定表达式的情况,但十分消耗空间,特别是当MyLen相对MAX比较小<br /><br />的时候,代价非常大。此时,可以利用时间换空间的方法进行转换。<br /><br />图1&nbsp;For语句的综合示例<br /><br />4&nbsp;计数器法<br /><br />计数器法是指引入时钟和计数器,用计数器对边界条件进行控制,也可以将动态表达式直接代入转化相<br /><br />应的静态表达式。例如,上述代码的For条件可以用下列代码替换:<br /><br />if(Reset='1')then<br /><br />I:=2;<br /><br />Elsif&nbsp;clk='1'and&nbsp;clk'event&nbsp;then<br /><br />Temp:=MyList(I);<br /><br />J:=2;<br /><br />While(j&gt1)and&nbsp;MyList(j-1)&ltTemp&nbsp;loop<br /><br />MyList(j):=MyList(j-1);<br /><br />j:=j-1;<br /><br />End&nbsp;loop;<br /><br />MyList(j):=Temp;<br /><br />I:=(I+1);<br /><br />If(I=MyLen+1)then&nbsp;I:=2;end&nbsp;if;<br /><br />End&nbsp;if;<br /><br />相比原来的代码,引入了1个时钟和1个复位。但综合开销最大的循环语句却被取代了,因此,综合产生<br /><br />门的数目将大幅度下降,但处理时间将相应延长到原来循环条件范围。<br /><br />本刊网络补充版(http://www.dpj.com.cn)中发表了四个源代码,分别为不可综合例子、直接代换法、<br /><br />边界扩充法和计算器法,内部都有相应注释。其中计数器法改进为双计数器方法。<br />结语<br /><br />以上三种方法各有优缺点,不可一概而论,可以根据实际情况处理。直接代换法一般用于循环次数少的<br /><br />情况;边界扩充法一般用于循环次数接近最大边界时;计数器方法一般用于芯片内部时钟相对信号时钟<br /><br />快许多的情况。<br /><br />本**来自中国IT实验室http://embed.chinaitlab.com/<br /><br />
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

103

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部