雷北城 发表于 2020-9-5 16:24

浅谈VHDLVerilog的可综合性以及对初学者的一些建议

<p style="margin-top:3px; margin-bottom:3px"><span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">一、</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">不是硬件设计语言</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">过去笔者曾碰到过不少</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">或</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">Verilog HDL</span></span><span style="font-size:9.0pt">的初学者问一些相似的问题,诸如如何实现除法、开根号,如何写循环语句等等。在这个论坛上,也时常能看到一些网友提出这一类的问题。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">对于这些问题,首先要明确的是</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">和</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">Veriglog</span></span><span style="font-size:9.0pt">并非是针对硬件设计而开发的语言,只不过目前被我们用来设计硬件。</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">是</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">Hardware Description Language</span></span><span style="font-size:9.0pt">的缩写,正式中文名称是</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">&ldquo;</span></span><span style="font-size:9.0pt">硬件描述语言</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">&rdquo;</span></span><span style="font-size:9.0pt">。也就是说,</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">并不是</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">&ldquo;</span></span><span style="font-size:9.0pt">硬件设计语言</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(Hardware Design Language)&rdquo;</span></span><span style="font-size:9.0pt">。别看只差这一个单词,正是这一个单词才决定了绝大部分电路设计必须遵循</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">RTL</span></span><span style="font-size:9.0pt">的模式来编写代码,而不能随心所欲得写仅仅符合语法的</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">代码。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">二、</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">的来历</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">之所以是</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">&ldquo;</span></span><span style="font-size:9.0pt">硬件描述语言</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">&rdquo;</span></span><span style="font-size:9.0pt">,要从</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">的来历说起。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">于</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">1980</span></span><span style="font-size:9.0pt">年开始在美国国防部的指导下开发,完成于</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">1983</span></span><span style="font-size:9.0pt">年,并于</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">1987</span></span><span style="font-size:9.0pt">年成为</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">IEEE</span></span><span style="font-size:9.0pt">的标准。当初开发这种语言,是出于美国国防部采购电子设备的需要。美军的装备采购自私人企业,时常要面对这样一种风险:如果某种武器大量装备部队,而其中某个零件的供应商却在几年后倒闭了,那这种武器的再生产、维修和保养都会出现大问题。而电子设备、尤其是集成电路的内部结构较为复杂,若出现前面所说的情况要找其他公司生产代用品非常困难。于是美国防部希望供应商能以某种形式留下其产品的信息,以保证一旦其破产后能由其他厂商迅速生产出代用品。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">显然,当初的设计文档显然是不能交出来的,这在美国会涉及商业机密和知识产权问题。于是美国防部就想出了一种折衷的方法</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">&mdash;&mdash;</span></span><span style="font-size:9.0pt">描述硬件的语言,也就是</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">。通过</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">,供应商要把自己生产的集成电路芯片的行为描述出来:比如说,加了什么样的信号后过多少时间它能输出什么等等。这样,如果有必要让其他厂商生产代用品,他们只需照着</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">文档,设计出行为与其相同的芯片即可。这样的代用品相当于是新厂商在不了解原产品结构的情况下独立设计的,所以不太会涉及知识侵权。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">Verilog HDL</span></span><span style="font-size:9.0pt">也形成于差不多的年代,是由</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">Gateway Design Automation</span></span><span style="font-size:9.0pt">公司大约在</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">1983</span></span><span style="font-size:9.0pt">年左右开发的。其架构同</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">相似,但主要被用来进行硬件仿真。或许私人公司更注重实用,</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">Verilog</span></span><span style="font-size:9.0pt">要比</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">VHDL</span></span><span style="font-size:9.0pt">简洁得多。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">由此可见,这两种最流行的用于电路设计的语言,没有一种是为了设计硬件而开发的</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(</span></span><span style="font-size:9.0pt">更何况</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">80</span></span><span style="font-size:9.0pt">年代还没有现在的那些功能强大的</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">EDA</span></span><span style="font-size:9.0pt">软件呢</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">)</span></span><span style="font-size:9.0pt">。因此,当初制订</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">语言标准的时候,并没有考虑这些代码如何用硬件来实现。换句话说,有些代码写起来简单,实现起来却可能非常复杂,或者几乎不可能实现。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">三、</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">代码的可综合性</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">现在回到最初的问题上。为什么诸如除法、循环之类的</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">代码总是会出错?</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">由上一部分可知,任何符合</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">语法标准的代码都是对硬件行为的一种描述,但不一定是可直接对应成电路的设计信息。行为描述可以基于不同的层次,如系统级,算法级,寄存器传输级</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(RTL)</span></span><span style="font-size:9.0pt">、门级等等。以目前大部分</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">EDA</span></span><span style="font-size:9.0pt">软件的综合能力来说,只有</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">RTL</span></span><span style="font-size:9.0pt">或更低层次的行为描述才能保证是可综合的。而众多初学者试图做的,却是想让软件去综合算法级或者更加抽象的硬件行为描述。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">比如说,要想实现两个变量相除的运算,若在代码中写下</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">C=A/B</span></span><span style="font-size:9.0pt">,你将会发现只有一些模拟软件在前仿真中能正确执行这句代码,但几乎任何软件都不能将其综合成硬件。不要怪软件太笨。试想一下,如果我们自己笔算除法是怎么做的?从高位到低位逐次试除、求余、移位。试除和求余需要减法器,商数和余数的中间结果必须有寄存器存储;而此运算显然不能在一个时钟周期里完成,还需要一个状态机来控制时序。一句简单的</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">C=A/B</span></span><span style="font-size:9.0pt">同所有这些相比显得太抽象,对于只能接受</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">RTL</span></span><span style="font-size:9.0pt">或更低层次描述的</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">EDA</span></span><span style="font-size:9.0pt">软件来说确实太难实现。而如果代码是类似于</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(Verilog)</span></span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">always @(posedge clk)</span></span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">c&lt;=A/B;</span></span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">这样的,要求除法在一个时钟延上完成,那更是不可能实现的。</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(</span></span><span style="font-size:9.0pt">注:有些</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">FPGA</span></span><span style="font-size:9.0pt">的配套软件提供乘除法的运算模块,但也只能支持直接调用,不支持把形如</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">C=A/B</span></span><span style="font-size:9.0pt">的语句综合成除法模块。</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">)</span></span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">又比如,一个很多初学者常见的问题是试图让</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">进行循环运算,形同</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(Verilog)</span></span><span style="font-size:9.0pt">:</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">for (i=0; i &lt; wordlength; i++)<br />
&nbsp;&nbsp;&nbsp; parity = parity xor data<em><span style="font-family:&quot;Arial&quot;,sans-serif">;</span></em></span></span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">一些功能比较简单的综合软件会完全拒绝综合循环语句;而一些功能较强的软件仅当</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">wordlength</span></span><span style="font-size:9.0pt">是常数的时候能综合;当</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">wordlength</span></span><span style="font-size:9.0pt">为变量时,任何软件都不能综合上面的语句。这是因为硬件规模必须是有限的、固定的。当综合软件遇到循环语句时,总是将其展开成若干条顺序执行的语句,然后再综合成电路。若</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">wordlength</span></span><span style="font-size:9.0pt">是常数,则展开的语句数是确定的,具有可综合性;而若它是变量时,展开的语句数不确定,对应的硬件电路数量也不能确定,无法被综合。或许有人说用计数器就能实现变量循环,但这情形又和上面的除法运算相同。那需要额外的硬件,用来存储中间结果和进行时序控制,象上面那样的循环语句对此描述得太抽象,软件接受不了。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">四、如何判断自己写的代码是可综合的?</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">用一句简单的话概括:电脑永远没有你聪明。具体来说,通常</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">EDA</span></span><span style="font-size:9.0pt">软件对</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">代码的综合能力总是比人差。对于一段代码,如果你不能想象出一个较直观的硬件实现方法,那</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">EDA</span></span><span style="font-size:9.0pt">软件肯定也不行。比如说,加法器、多路选择器是大家都很熟悉的电路,所以类似</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">A+B-C</span></span><span style="font-size:9.0pt">,</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(A&gt;B)?C:D</span></span><span style="font-size:9.0pt">这样的运算一定可以综合。而除法、开根、对数等等较复杂的运算,必须通过一定的算法实现,没有直观简单的实现方法,则可以判断那些计算式是不能综合的,必须按它们的算法写出更具体的代码才能实现。此外,硬件无法支持的行为描述,当然也不能被综合</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">(</span></span><span style="font-size:9.0pt">比如想在</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">FPGA</span></span><span style="font-size:9.0pt">上实现</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">DDR</span></span><span style="font-size:9.0pt">内存那样的双延触发逻辑,代码很容易写,但却不能实现</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">)</span></span><span style="font-size:9.0pt">。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">不过,这样的判断标准非常主观模糊,遇到具体情况还得按设计人员自己的经验来判断。如果要一个相对客观的标准,一般来说:在</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">RTL</span></span><span style="font-size:9.0pt">级的描述中,所有逻辑运算和加减法运算、以及他们的有限次组合,基本上是可综合的,否则就有无法综合的可能性。当然,这样的标准仍然有缺陷,更况且</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">EDA</span></span><span style="font-size:9.0pt">的技术也在不断发展,过去无法综合的代码或许将来行,某些软件不支持的代码换个软件或许行。比如固定次数的循环,含一个常数参数的乘法运算等等,有些</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">EDA</span></span><span style="font-size:9.0pt">软件支持对它们的综合,而有些软件不行。</span></span></span></span></p>

<p style="margin-top:3px; margin-bottom:3px"><br />
<span style="font-size:12pt"><span style="line-height:12pt"><span style="font-family:宋体"><span style="font-size:9.0pt">所以,正确的判断仍然要靠实践来积累经验。当你可以较准确判断代码的可综合性的时候,你对</span><span lang="EN-US" style="font-size:9.0pt"><span style="font-family:&quot;Arial&quot;,sans-serif">HDL</span></span><span style="font-size:9.0pt">的掌握就算完全入门了。</span></span></span></span></p>

<p style="text-align:justify; margin-top:3px">&nbsp;</p>

LilMonster00 发表于 2024-2-22 20:20

太好了,解答了一些不清楚的界限

LilMonster00 发表于 2024-2-22 20:25

最后一段太行了,只能说确实可以作为一个评判入门标准
页: [1]
查看完整版本: 浅谈VHDLVerilog的可综合性以及对初学者的一些建议