信号本地处理范围

signal local to process scope

我经常想知道为什么 VHDL variable 可以在 processarchitecture(如 shared)级别上声明,而 signal 只能在 architecture 级别上声明 - 即使它仅在单个 process 的范围内使用。

声明事物(例如signalsvariables)在尽可能窄的范围内并尽可能靠近它们被使用的地方,在我看来确实增加了可读性。

因此我的问题是:VHDL语言的设计有什么固有的原因,为什么不能做下面的事情?

architecture does_not_compile of test is
    signal a, d : std_logic_vector(15 downto 0); 

    -- This would work, but does not need to be here:
    -- signal c : std_logic_vector(15 downto 0); 
begin
    process (clk)
        variable b : std_logic_vector(15 downto 0); 

        -- This would be nice, but is not permitted:
        signal c : std_logic_vector(15 downto 0); 
    begin 
            if (rising_edge(clk)) then
                b := foo_operation(a); -- could just be used to store an intermediary value
                c <= bar_operation(b); -- could e.g. be a pipeline register
                d <= baz_operation(c); -- the "output register" of this process
            end if;
    end process;

    -- somewhere else: 
    a <= input_xyz;
    output_xyz <= d
end architecture;

以防万一:我了解signalvariable...之间的区别

Is there any reason inherent to the design of the VHDL language, why the following can not be done?

process (clk)
    variable b : std_logic_vector(15 downto 0); 

    -- This would be nice, but is not permitted:
    signal c : std_logic_vector(15 downto 0); 
begin 

(在进程中声明一个信号。)

你会如何解决可见性问题?

一个过程语句是一个声明区域。

所有并发语句都有等价过程或块语句等价物和等价过程,为模拟而阐述。

所有这些进程都是单独的声明区域,尽管您显然只是提倡允许将信号声明作为显式声明的进程声明项。

函数调用是表达式,过程调用是语句,并发过程调用具有等效的模拟过程。

信号只能通过遇到等待语句在同一进程中的顺序语句之间进行通信。今天的信号将在封闭的声明区域(块声明项或端口声明)中声明,或者在声明为包声明项时通过 use 子句使其可见。

请注意,您可以在进程内部使用等待语句和变量来达到相同的效果。

有趣的是将信号用于其预期目的 - 在进程之间进行通信。

案例一

同一声明区域中的两个或多个进程也具有与一个进程中声明的同名信号。其他进程使用哪个信号声明?

案例二

同一声明区域中的三个或更多进程,其中两个进程声明相同的信号名称。第三个或其他进程使用哪个声明?

从可见性的角度来看,进程中的信号声明似乎无法解析。

考虑如何通过使用 'shared' 信号声明将信号声明的范围扩展到封闭的声明区域。如果只共享一个信号声明而不共享两者并且在封闭的声明区域中没有可见声明,则可以解决第二种情况。它根本没有解决第一种情况,并且不允许选定的名称使用流程作为前缀(如果是,则需要实例化名称,顺便说一句,需要标记流程语句)。

这有什么用?这是模棱两可的。

VHDL 限制可以声明信号的位置,以便可见性规则最多提供一个可能的声明。声明的范围不会扩展到封闭或相邻的声明区域。

作为一种治疗方法,而不是使用 paebbel 的块语句,您还可以将信号声明为包声明项,在特定进程中通过 use 子句私下可见。

是的,你应该能够做到,不,你不能,我不相信 VHDL2008 正在修复它(但是 VHDL2008 中有很多很棒的东西 fixed/added)。您可以始终使用 true generate 语句(如评论中所述)。尽管如果您始终使用 true generate 语句,您的模块可能太大,您应该将其分解。

我只是想指出您仍然可以 use/implement 您的管道在变量中注册。如果你交换 d 和 c 赋值。我知道它不是那么好,但我偶尔会使用它并且合成效果很好。变量在进程的连续运行之间保持它们的值。

architecture does_not_compile of test is
    signal a, d : std_logic_vector(15 downto 0); 
begin
    process (clk)
        variable b : std_logic_vector(15 downto 0); 
        variable c : std_logic_vector(15 downto 0); 
    begin 
            if (rising_edge(clk)) then
                b := foo_operation(a); -- could just be used to store an intermediary value
                d <= baz_operation(c); -- the "output register" of this process
                c := bar_operation(b); -- could e.g. be a pipeline
            end if;
    end process;

    -- somewhere else: 
    a <= input_xyz;
    output_xyz <= d
end architecture;