1VHDL处理静态数据的两种对象:const和generic。VHDL处理非静态数据的两种对象:信号和变量。常量和信号是全局的,既可以用于顺序代码,也可用于并发代码;变量只能在顺序代码中使用,相对于信号而言,变量只能是局部的,所以变量值不能传递到process、function和procedure外部。但是,在有些情况下,选择信号还是变量却是比较难以抉择的。第7章信号(Signal)和变量(Variable)27.1常量用于确定默认值,语法结构:CONST常量名:type:=值;例子:CONSTset_bit:BIT:=‘1’;CONSTdatamemory:memory:=((‘0’,’0’,’1’,’1’),(‘0’,’0’,’1’,’1’));常量可以在包集、实体或结构体中声明:•包集中:全局;•实体中:对该实体内的所有结构体而言是全局的;•结构体中:结构体内是全局的。37.2信号VHDL中‘信号’代表电路单元、功能模块间的硬件连线,也可表示电路单元的IN/OUT端口;实体的所有端口都默认为信号,语法结构:Signal信号名:type[range][:=初始值];注意:当信号用于顺序描述语句如process中时,其值不是立刻更新的;只有当其所在的process、函数或过程完成之后才进行更新。4信号的赋值符号:=注意1:对信号赋初值的操作是不可综合的,通常只用于仿真。例如:signalcontrol:BIT:=‘0’;注意2:不要对同一个信号进行多重赋值。(buffer模式的端口信号除外!)例如:process(...).....foriIN0TO10LOOPcontrol=control+1;--error!或最后一次有效!......5例7.1“1”计数器•功能描述:计算一个二进制矢量中‘1’的个数6实现代码:---错误使用信号的例子LIBRARYieee;USEieee.std_logic_1164.all;entitycount_onesisport(din:INstd_logic_vector(7downto0);ones:OUTintegerrange0to8);endcount_ones;architecturenot_okofcount_onesissignaltemp:integerrange0to8;beginprocess(din)begintemp=0;FORiIN0TO7LOOPIF(din(i)=‘1’)thentemp=temp+1;ENDif;ENDLOOP;ones=temp;endprocess;endnot_ok;进程结束后才更新7两种代码更正方法:1、使用变量来记录中间值,可以将signaltemp...改为variabletemp...;同时修改相应的赋值语句;2、取消temp,同时将端口信号ones重新定义为:ones:BUFFERintegerrange0to8;使得ones可以被内部调用。在进程结束后,ones值将被更新。(编码风格不好,不提倡此种方式!可以参考P110-P111例子)87.3变量(variable)•变量代表电路单元内部的操作,代表暂存的临时数据。与信号和常量相比,变量仅用于局部的电路描述,只能用于进程、函数和过程内部。•注意:对变量的赋值是立即生效的,无需等待进程结束。新的值可以在下一行代码中立即使用。•变量的赋值符号“:=”,语法结构:variable变量名:type[range][:=初始值];注意:对变量赋初值的操作也是不可综合的,通常只用于仿真。9例:“1”计数器的实现代码:LIBRARYieee;USEieee.std_logic_1164.all;entitycount_onesisport(din:INstd_logic_vector(7downto0);ones:OUTintegerrange0to8);endcount_ones;architectureokofcount_onesisvariabletemp:integerrange0to8;beginprocess(din)begintemp:=0;FORiIN0TO7LOOPIF(din(i)=‘1’)thentemp:=temp+1;ENDif;ENDLOOP;ones=temp;endprocess;endok;107.4信号和变量的比较(补充)1)赋值方式的不同:变量:=表达式;信号=表达式;2)硬件实现的功能不同:信号代表电路单元、功能模块间的互联,代表实际的硬件连线;变量代表电路单元内部的操作,代表暂存的临时数据。113)有效范围的不同:信号:程序包、实体、结构体;全局量。变量:进程、子程序;局部量。ARCHITECTURE{SIGNALDeclarations}label1:PROCESS{VARIABLEDeclarations}label2:PROCESS{VARIABLEDeclarations}┇124)赋值行为的不同:信号赋值延迟更新数值、时序电路;变量赋值立即更新数值、组合电路。5)信号的多次赋值a.一个进程:最后一次赋值有效b.多个进程:多源驱动线与、线或、三态13例:信号的多次赋值(补充)architecturertlofexissignala:std_logic;beginprocess(…)begina=b;…a=c;endprocess;endrtl;architecturertlofexissignala:std_logic;beginprocess(…)begina=b;…endprocess;process(…)begina=c;...endprocess;endex;14例:信号赋值与变量赋值的比较(补充)信号赋值:architecturertlofsigissignala,b:std_logic;--定义信号beginprocess(a,b)begina=b;b=a;endprocess;endrtl;--结果是a和b的值互换15变量赋值:(补充)architecturertlofvarisbeginprocessvariablea,b:std_logic;--定义变量begina:=b;b:=a;endprocess;endrtl;--结果是a和b的值都等于b的初值16例:变量赋值实现循环语句功能(补充)process(indicator,sig)variabletemp:std_logic;begintemp:=‘0’;foriin0to3looptemp:=tempxor(sig(i)andindicator(i));endloop;output=temp;endprocess;17以上语句等效为:process(indicator,sig)variabletemp:std_logic;begintemp:=‘0’;temp:=tempxor(sig(0)andindicator(0));temp:=tempxor(sig(1)andindicator(1));temp:=tempxor(sig(2)andindicator(2));temp:=tempxor(sig(3)andindicator(3));output=temp;endprocess;18如改为信号,则无法实现原功能:(补充)……signaltemp:std_logic;……process(indicator,sig,temp)begintemp=‘0’;temp=tempxor(sig(0)andindicator(0));temp=tempxor(sig(1)andindicator(1));temp=tempxor(sig(2)andindicator(2));temp=tempxor(sig(3)andindicator(3));output=temp;endprocess;19例7.3:多路复用器的对比设计方案一:使用信号(notOK)LIBRARYieee;USEieee.std_logic_1164.all;entitymuxisport(a,b,c,d,s0,s1:INstd_logic;y:OUTstd_logic);endmux;architecturenot_okofmuxissignalsel:integerrange0to3;beginprocess(a,b,c,d,s0,s1)beginsel=0;if(s0=‘1’)thensel=sel+1;endif;if(s1=‘1’)thensel=sel+2;endif;caseseliswhen0=y=a;when1=y=b;when2=y=c;when3=y=d;endcase;endprocess;endnot_ok;值不能立即更新,不能在process的其它代码中继续使用不能进行同一信号的多次赋值,要么出错,要么“线与”,要么只考虑最后一次赋值,取决于编译器20例7.3:方案二:使用变量(OK)LIBRARYieee;USEieee.std_logic_1164.all;entitymuxisport(a,b,c,d,s0,s1:INstd_logic;y:OUTstd_logic);endmux;architectureokofmuxisbeginprocess(a,b,c,d,s0,s1)variablesel:integerrange0to3;beginsel:=0;if(s0=‘1’)thensel:=sel+1;endif;if(s1=‘1’)thensel:=sel+2;endif;caseseliswhen0=y=a;when1=y=b;when2=y=c;when3=y=d;endcase;endprocess;endok;值可以立即更新,能够在process的其它代码中继续使用21例7.4带q和qbar的DFFDFFqdclkqbar功能描述:D触发器qbar为q的反相输出端。22方案1:not_ok---------------------------------------------------libraryieee;useieee.std_logic_1164.all;--------------------------------------------------entitydffisport(d,clk:INstd_logic;q:BUFFERstd_logic;qbar:OUTstd_logic);enddff;-----------------------------------------------architecturenot_okofdffisbeginprocess(clk)beginif(clk’eventANDclk=‘1’)thenq=d;qbar=NOTq;endif;endprocess;endnot_ok;-------------------------------------方案2:ok------------------------------------------------------libraryieee;useieee.std_logic_1164.all;--------------------------------------------------entitydffisport(d,clk:INstd_logic;q:BUFFERstd_logic;qbar:OUTstd_logic);enddff;-----------------------------------------------architectureokofdffisbeginprocess(clk)beginif(clk’eventANDclk=‘1’)thenq=d;endif;endprocess;qbar=NOTq;