36

我一直在阅读有关 VHDL 编程的文本(前面没有,所以不能给出标题)。我一直很难从文本中理解的一个问题是何时使用变量与信号。我想我对何时使用信号(即内部信号)有一个清晰的了解,但对于变量来说并没有那么多。

我确实注意到文本通常在定义进程之前声明和初始化信号,而在进程内部声明变量(我猜从未初始化......)。

无论如何,无论是通过定义还是通过示例来清除它都会很棒!

4

5 回答 5

43

与普通并行代码不同,当您要创建序列化代码时使用变量。(序列化意味着命令按顺序执行,一个接一个而不是一起执行)。变量只能存在于进程内部,值的赋值不是并行的。例如,考虑以下代码:

signal a,b : std_logic_vector(0 to 4);

process (CLK)
    begin
        if (rising_edge(clk)) then
            a <= '11111';
            b <= a;
        end if;
end process;

将在进程运行之前放入b值,而不是'. 另一方面,代码:a'11111

signal a,b : std_logic_vector(0 to 4);

process (CLK)
    variable var : std_logic_vector(0 to 4);
    begin 
        if (rising_edge(clk)) then
            var := '11111';
            a <= var;
            b <= var;
        end if;
end process;

会将值'11111'放入ab中。

坦率地说,根据我的经验,大多数时候你不需要使用变量,我唯一使用它的地方是在一个循环中,我需要检查多个信号中的任何一个是否为 1:

type    BitArray        is array (natural range <>) of std_logic;

--...

entity CAU_FARM is
    port
        (
            --   IN   --
              REQUEST         : in BitArray(0 to (FLOW_num -1));
              --..
        );
end CAU_FARM;
--...

farm_proc: process(CLK_FARM, RESET)
    variable request_was_made_var : std_logic;
    begin
    if RESET = C_INIT then 
       -- ...

    elsif rising_edge(CLK_FARM) then

            -- read state machine --
        case read_state is
            when        st_read_idle =>

                request_was_made_var := '0';
                for i in 0 to (FLOW_num -1) loop
                    if (REQUEST(i) = '1') then
                        request_was_made_var := '1';
                    end if;
                end loop;
                if (request_was_made_var = '1') and (chosen_cau_read_sig /= 8) then
                    read_state <= st_read_stage_1;
                    for i in 0 to (FLOW_num -1) loop
                        if (i = choice_out_sig) then
                            ACKNOWLEDGE(i) <= '1';
                        end if;
                    end loop;
                else
                    read_state <= st_read_idle;
                end if;
            ------------------------
            when        st_read_stage_1 =>
            --...
于 2013-03-19T12:08:38.733 回答
13

变量旨在用于在流程中存储值。因此它的范围是有限的。与合成硬件的关系往往不太直接。

变量也会立即获得值,而信号则不会。以下两个过程具有相同的效果:

signal IP, NEXTP : STD_LOGIC_VECTOR(0 to 5);

process (CLK)
    Variable TEMP : STD_LOGIC_VECTOR(0 to 5);
    begin
        if (rising_edge(clk)) then
            TEMP := IP;
            IP <= NEXTP;
            NEXTP <= TEMP(5) & TEMP(0 to 4);
        end if;
end process;

signal IP, NEXTP : STD_LOGIC_VECTOR(0 to 5);

process (CLK)

    begin
        if (rising_edge(clk)) then
            IP <= NEXTP;
            NEXTP <= IP(5) & IP(0 to 4);
        end if;
end process;

这是因为更新已安排好,但实际上尚未更改。其中<= 包括一个时间元素。

于 2013-03-18T21:08:19.933 回答
8

变量:临时位置;它们用于在“过程”中存储中间值。

信号:更新信号值。运行由信号变化激活的进程。当进程运行时,系统中的所有信号保持不变。

差异:

变量:它们是本地的;没有延迟;在进程内声明

信号:它们是全局的(在开始之前);因电线延迟;在关键字开始之前声明

于 2015-04-16T09:03:41.900 回答
1

附带说明一下,变量不仅可以存在于进程中(还可以存在于过程中),此外,它们可以是可从多个进程访问的共享变量(参见: http: //www.ics.uci.edu/~jmoorkan/vhdlref/ var_dec.html )。

于 2015-08-31T15:15:00.250 回答
-1

变量——它们是进程的局部变量,一旦变量获得新值,它们的值就会更新。

共享变量 - 类似于变量,但它们可以从不同的进程中访问。

信号 - 它们的范围更大,每个进程都可以访问架构中声明的信号或特定块(如果有)。进程挂起或遇到等待语句后会有值更新。

于 2017-05-12T11:37:54.077 回答