关于另一个question,我尝试制作切片器,声明常量增加范围。下面的代码似乎具有正确的功能,但似乎操作不稳定。
编译器会发出警告:
(vcom-1515)预定义属性的前缀"范围"是函数调用" ifRange"
并且参考具有属性'范围的常量似乎是不稳定的,而“左”和“右”正常工作。
这是有效的VHDL吗?还有其他任何方法可以达到同样的目的吗?
library ieee;
use ieee.std_logic_1164.all;
package RangePack is
impure function ifRange(a : integer;
reset : boolean := false)
return std_logic_vector;
type tProtectedInteger is protected
impure function Get return integer;
procedure Set(a : in integer);
procedure Add(a : in integer);
end protected tProtectedInteger;
end package RangePack;
package body RangePack is
type tProtectedInteger is protected
body
variable vInteger : integer := 0;
impure function Get return integer is
begin
return vInteger;
end function Get;
procedure Set(a : in integer) is
begin
vInteger := a;
end procedure Set;
procedure Add(a : in integer) is
begin
vInteger := vInteger + a;
end procedure Add;
end protected body tProtectedInteger;
shared variable svOffset : tProtectedInteger;
impure function ifRange(a : integer;
reset : boolean := false)
return std_logic_vector is
variable vDummy : std_logic_vector(63 downto 0);
variable vOffset : integer;
begin
if(reset) then
svOffset.Set(0);
end if;
vOffset := svOffset.Get;
svOffset.Add(a);
return vDummy(vOffset+a-1 downto vOffset);
end ifRange;
end package body RangePack;
library ieee;
use ieee.std_logic_1164.all;
use work.RangePack.all;
entity tb is
end entity tb;
architecture sim of tb is
constant cB : std_logic_vector(ifRange(8, reset => true)'range) := (others => '1');
constant cA : std_logic_vector(ifRange(4)'range) := (others => '0');
signal sVector : std_logic_vector(11 downto 0) := x"CA7";
signal sA : std_logic_vector(3 downto 0);
signal sB : std_logic_vector(7 downto 0);
begin
-- works
sA <= sVector(cA'left downto cA'right);
sB <= sVector(cB'left downto cB'right);
--does't work
--sA <= sVector(cA'range);
--sB <= sVector(cB'range);
end architecture sim;