Vhdl 处理范围的本地信号
我经常想知道,为什么VHDLVhdl 处理范围的本地信号,vhdl,grammar,semantics,Vhdl,Grammar,Semantics,我经常想知道,为什么VHDL变量既可以在进程上声明,也可以在架构(作为共享)级别上声明,而信号只能在架构级别上声明,即使它只是在单个进程的范围内使用 在我看来,在尽可能狭窄的范围内并尽可能靠近使用它们的地方声明事物(例如,信号或变量s),确实会大大提高可读性 因此我的问题是:VHDL语言的设计是否有内在的原因,为什么不能做到以下几点 architecture does_not_compile of test is signal a, d : std_logic_vector(15 dow
变量
既可以在进程
上声明,也可以在架构
(作为共享
)级别上声明,而信号
只能在架构
级别上声明,即使它只是在单个进程
的范围内使用
在我看来,在尽可能狭窄的范围内并尽可能靠近使用它们的地方声明事物(例如,信号
或变量
s),确实会大大提高可读性
因此我的问题是: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;
体系结构不编译测试
信号a、d:标准逻辑向量(15到0);
--这会起作用,但不需要在这里:
--信号c:标准逻辑向量(15到0);
开始
过程(clk)
变量b:标准逻辑向量(15到0);
--这很好,但不允许:
信号c:标准逻辑向量(15到0);
开始
如果(上升沿(clk)),则
b:=foo_操作(a);——可以仅用于存储中间值
C
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;
(声明进程中的信号。)
您将如何解决可见性问题
流程语句是一个声明性区域
所有并发语句都有等价的进程或块语句等价和等价的进程,为模拟而精心设计
所有这些进程都是独立的声明性区域,尽管您显然只支持将信号声明作为显式声明的进程声明项
函数调用是表达式,过程调用是语句,并发过程调用具有用于模拟的等效过程
信号只能通过遇到wait语句在同一进程中的顺序语句之间进行通信。今天的信号将在封闭的声明性区域(块声明性项或端口声明)中声明,或在声明为包声明性项时由use子句可见
注意:您可以在进程内部使用wait语句和变量来达到相同的效果
有趣的是将信号用于其预期目的——在进程之间进行通信
案例1
同一声明性区域中的两个或多个进程,其声明的信号与一个进程中的信号名称相同。其他进程使用哪种信号声明
案例2
同一声明性区域中的三个或多个进程,其中两个进程声明相同的信号名。第三个或其他进程使用哪种声明
从可见性的角度来看,流程中的信号声明似乎不可解析
考虑如何通过使用“共享”信号声明将信号声明的范围扩展到封闭的声明区域。如果只共享一个信号声明,而不是共享两个,并且在封闭的声明性区域中没有可见的声明,那么这可以解决第二种情况。它根本不解决第一种情况,并且所选名称不允许使用流程作为前缀(如果是,则需要实例化名称,顺便说一句,需要标记流程语句)
这有什么用处?这是模棱两可的
VHDL限制可以声明信号的位置,以便可见性规则最多提供一种可能的声明。声明的范围不会扩展到封闭的或相邻的声明区域
作为一种治疗方法,您可以不使用paebbel的block语句,而是将信号声明为包声明项,在特定过程中,通过use子句使其私下可见。是的,您应该能够做到,不是的,您不能做到,我不相信VHDL2008正在修复它(但在VHDL2008中修复/添加了很多很棒的东西)。您可以使用always true生成语句(如注释中所述)。尽管如果您使用always true生成语句,您的模块可能太大了,您应该将其分解
我只是想指出,您仍然可以在变量中使用/实现管道寄存器。如果你交换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;
体系结构不编译测试
信号a、d:标准逻辑向量(15到0);
开始
过程(clk)
变量b:标准逻辑向量(15到0);
变量c:标准逻辑向量(15到0);
开始
如果(上升沿(clk)),则
b:=foo_操作(a);——可以仅用于存储中间值
d您可以将您的进程或多个进程包装在一个块中,或者生成语句来声明范围较小的信号。也许您应该去,加入工作组,并提倡添加。我认为没有理由不这样做,尽管@Paebbels方法将是一种处理进程的冗长方式,但它在过程中根本不起作用。阴影/名称解析歧义的问题确实是一个反对它的论点,它使用的语言与VHDL一样“严格”。尽管@Paepbels建议的基于块的解决方案表明,这样的范围解析已经完成了。-感谢您纠正了这个问题(我实际上是想在那里写变量;现在就调整好了)。感谢您指出了使用变量进行管道化的完整性方法。然而,插入或删除管道阶段需要容易出错的重新调整,并导致难以读取的“颠倒”数据流。因此,这实际上是导致这个问题的原因之一。