什么是 {global|local} 静态 {primary|expression|range|subexpressio



在SO上发现了许多问题,这些问题涉及有关非本地全局静态内容的错误消息或警告。

有很多问题可以问如何摆脱此类错误消息,但令人惊讶的是,似乎没有人问过静态的真正含义。

IEEE标准在§9.4中讨论了静态表达式,但定义并不容易理解(因为它是递归的,而且 - 有趣的是 - 因此根据定义本身似乎是静态的(。

认为有一个 SO 问题在一个地方回答静态在 VHDL 中真正含义的所有含义是有价值的。

如上面的注释中所述,静态表达式基本上是在编译时可以完全评估的东西(无论是在编译它定义的设计单元期间 - 而不是说它是局部静态的 - 或者在评估使其全局静态的完整设计期间(。

这基本上使静态表达式在评估("编译"(后成为常量。与C++中的constexpr非常相似。

这对合成有什么影响?

一个有趣的用法是 - 考虑标准第 9.4 章中一个看起来无辜的脚注:

全局静态表达式的规则意味着声明的常量或泛型可以使用 非全局静态的表达式,例如,调用不纯函数。得到的常量值可能是 全局静态,即使其初始值表达式不是。仅接口常量、变量和信号声明 要求其初始值表达式为静态表达式。

您实际上可以使用不可合成的 VHDL 语句(例如指针或实数(,只要它们满足静态要求,即可以在编译时完全评估为可合成的构造:

architecture rtl of sintab is
type sinus_table_type is array(natural range <>) of signed(31 downto 0);
function sinus_table(start_value, end_value, step : real) return  sinus_table_type is
constant table_size     : natural := 
integer(ieee.math_real.ceil(
end_value - start_value) / step);
variable sintab : sinus_table_type(0 to table_size - 1);
begin
for i in sintab'low to sintab'high loop
sintab(i) := to_signed(integer(
ieee.math_real.sin(start_value + real(i) * step) *
32767.0), sintab(i)'length);
end loop;
return sintab;
end function sinus_table;
function isin(sintab : sinus_table_type; us : signed) return signed is
variable ret : signed(us'range);
begin
ret := sintab(to_integer(us mod sintab'length));
return ret;
end function isin;
constant PI             : real := 3.1415926;
constant stab           : sinus_table_type := sinus_table(0.0, 2.0 * PI, 0.01);
begin
calc : process
begin
wait until rising_edge(clk);
res <= isin(stab, arg);
end process calc;
end architecture rtl;

在上面的例子中,不可合成的表达式(使用ieee.math_real,通常不可合成(用于构造缩放signed值的常量数组作为查找表,满足静态的要求,因为这些表达式可以在编译时完全计算。

最新更新