VHDL语法入门 (五) 信号与变量

信号与变量

VHDL提供了信号(signal)和变量(variable)两种对象来处理非静态数据,同时提供了常数(constant)和属性(generic)两种对象来处理静态数据

常量和信号是全局的,既可以用在顺序执行的1代码中,也可以用在并发执行的代码中。

变量是局部的,只能用在顺序代码中(包括process,function或procedure的内部),并且他们的值不能直接向外传递。

常量

--格式
CONSTANT 常量名: type := 值;


--例
constant set_bit: bit := '1';
constant datamemory : memory := (('0','0','0','0'),
                                 ('0','0','0','1'),
                                 ('0','0','1','1'));

常量可以在包集,实体或结构体中声明。在包集中声明的常量是真正全局的,可以被所有调用该包集的实体使用。定义在实体中的常量对于该实体全部结构体而言是全局的。定义在结构体内的常量仅在结构体内是全局的。

信号

VHDL中的信号代表的是逻辑电路中的“硬”连线,既可以用于电路单元的输入输出端口,也可以用电路内各单元之间的连接。实体中的所有端口都被默认为信号。

--格式
SIGNAL name: type [range] [:= initial_value];


--例
signal control: bit := '0';    --对信号赋初值的操作不可综合,只能用来仿真
signal count: integer range 0 to 100;
signal y: std_logic_vector (7 downto 0);

对于信号,赋值符号为<=

当信号用在顺序描述语句(如process内部)时,其值不是立刻更新的,信号值是在相应的进程,函数或过程完成之后才进行更新。

变量

与信号和常量相比,变量仅用于局部电路的描述。它只能在process,function或procedure内部使用,而且它是立即生效的,所以新的值可以在下一行代码中立即使用。

--格式
VARIABLE name: type [range][:= 初始值];


--例
variable control: bit := '0';    --与信号相同,对变量赋初值的操作不可综合,只能用在仿真中
variable count: integer range 0 to 100;
variable y: std_logic_vector (7 downto 0) := "10001000";

对于变量,赋值符号为:=

信号和变量的比较

信号

变量

赋值符号

:=

功能

表示电路内部连接

表示局部信息

范围

全局

局部(仅在进程,函数或过程中使用)

行为

在顺序代码中,信号值不是立即更新的,更新要在进程,函数或过程完成之后才有效

即使更新(新的值在代码的下一行就生效)

用途

由于包集,实体或结构体中。在实体中,所有端口默认为信号

仅用于描述代码中(进程,函数或过程中)

寄存器的产生

当一个信号的赋值是以另一个信号的跳变为条件时,或者说当发生同步赋值时,该信号经过编译后就会生成寄存器。这样的同步赋值只能在进程,函数或过程中出现(一般跟在IF signal'EVENT...或WAIT UNTIL...等语句之后)。如果变量的值没有被进程(函数或过程)以外的代码调用,那么不一定会生成寄存器。如果一个变量是在一个信号跳变时被赋予的,并且该值最终又被赋给了另外的信号(信号是全局的,可以进行数值传递),那么综合后就会产生寄存器。如果一个变量在还没有进行赋值操作时已被使用,那么在综合时也会产生寄存器。

--------例1--------
process(clk)
begin
    if(clk'event and clk = '1')then
        output1 <= temp;    --output1被存储,因为它是信号(clk)跳变时被赋值的
        output2 <= a;    --output2被存储,因为它是信号(clk)跳变时被赋值的
    end if;
end process;


--------例2--------
process(clk)
begin
    if(clk'event and clk = '1')then
        output1 <= temp;    --output1被存储,因为它是信号(clk)跳变时被赋值的
    end if;
    output2 <= a;    --output2未被存储
end process;


--------例3--------
process(clk)
    variable temp: bit;
begin
    if(clk'event and clk = '1')then
        temp := a;
    end if;
    x <= temp;    --temp促使x被存储
end process;

实例

下面将展示两端代码,代码实现相同的功能,但是综合后产生的触发器数量不同

-----------------方案1,综合后的电路为图a---------------------
library ieee;
use ieee.std_logic_1164.all;

entity dff is
    port(d, clk: in std_logic;
         q: buffer std_logic;
         qbat: out std_logic);
end dff;

architecure two_dff of dff is
begin
    process(clk)
    begin
        if (clk'event and clk = '1')then
            q <=d ;    --此处产生一个寄存器
            qbar <= not d;    --此处产生一个寄存器
        end if;
    end process;
end two_dff;

-----------------方案2,综合后的电路为图b---------------------
library ieee;
use ieee.std_logic_1164.all;

entity dff is
    port(d,clk: in std_logic;
         q: buffer std_logic;
         qbar: out std_logic);
 end dff;
 
 architecture one_dff of dff is
 begin
     process(clk)
     begin
         if(clk'event and clk = '1')then
             q <= d;    --此处产生一个寄存器
         end if;
     end process;
     qbar <= not q;    --此处产生一个逻辑门而非寄存器
 end one_dff;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值