我正在寻找一种资源有效的方法来设置std_logic_vector中特定位置的位。
我们假设我有一个std_logic_vector,例如signal a := std_logic_vector(LEN-1 downto 0) := (others => '0')
,
其中LEN是通用的。
我想在常规的intervalls中将它设置为1
,例如,在第五,第十,......位置,其中intervall可能来自(一小组)预定义数字,
例如,(5,10,20,25,30,40,50)
。
实现这一目标的最省钱方法是什么?
显然,这可以使用for
循环和mod
函数来实现。
但是,我想使用这种方法进行合成,因此mod函数可能很昂贵。另一种可能性是展开循环..但是,由于LEN
是通用的,我不知道步骤的数量。此外,我想排除不可能的组合,例如,如果LEN = 20
,则应排除invervalls > 20
。
答案 0 :(得分:1)
Yann的回答有一些我想在这里提出的问题,为那些不太熟悉VHDL语法的人提供答案。这不是对Yann选择的实现的批评,而是澄清语法问题。
首先,上面的例子并不完整。它描述了component
语句,但没有相应的entity
。 component
的使用仅在声明性区域中使用,并且不能在package
或architecture
之外独立存在。如上所述,它不会编译。相反,它应该改为:
entity columns is
...
end entity columns;
其次,如果没有相应的类型声明,就无法声明数组。也就是Yann的帖子中的例子:
values : array (0 to choices-1) of integer
无法完成。必须先声明类型才能使用它。并且为了使该类型对组件/实体可见,必须在component
或entity
之前定义它。在entity
的情况下,需要在包中定义它。例如:
package columns_pkg is
type values_array is array(natural range <>) of integer;
end package columns_pkg;
然后可以在columns_pkg
中引用entity
。如:
library ieee;
use ieee.std_logic_1164.all;
use work.columns_pkg.all;
entity columns is
generic (
LEN : integer; -- bits of output
choices : integer; -- number of column combinations
-- distances at which bits may be 1
values : values_array(0 to choices-1)
);
...
现在,这仍然不太正确。只有在VHDL-2008中,泛型才能相互依赖。也就是说,values
的范围只能依赖于VHDL-2008中的choices
。早期的语言版本要求它们不相关,这意味着上面values
的声明将在VHDL-2002及更早版本中失败。
但事实证明choices
甚至不是必需的。相反,人们可以做到这一点(把它们放在一起并清理几个错别字):
library ieee;
use ieee.std_logic_1164.all;
package columns_pkg is
type values_array is array(natural range <>) of integer;
end package columns_pkg;
library ieee;
use ieee.std_logic_1164.all;
use work.columns_pkg.all;
entity columns is
generic
(
LEN : integer; -- bits of output
values : values_array
);
port
(
-- one hot encoded distance choice
distance : in std_logic_vector(values'length-1 downto 0);
-- data which is 1 at selected distance
bits : out std_logic_vector(LEN-1 downto 0)
);
end entity columns;
architecture behavioural of columns is
begin -- architecture behavioural
bitgen: for i in bits'range generate
begin
-- purpose: calculate one individual bit
-- type : combinational
-- inputs : distance
-- outputs: bits(i)
bitcalc: process (distance) is
variable j : integer;
begin -- process bitcalc
bits(i) <= '0';
for j in values'range loop
if i mod values(j) = 0 and distance(j) = '1' then
bits(i) <= '1';
end if;
end loop; -- j
end process bitcalc;
end generate;
end architecture behavioural;
请注意values
不受约束。长度将在详细时间确定。人们可以利用属性来确定长度和范围。
此外,如果LEN
与values
范围之间存在关联,那么LEN
通用也可能会被淘汰。
最后,为了使用columns
,我会做:
entity top is
end entity top;
use work.columns_pkg.all;
architecture behavioural of top is
constant columns_values : values_array(0 to 5) := (0, 5, 10, 15);
-- one hot encoded distance choice
signal distance : std_logic_vector(columns_values'length-1 downto 0);
-- data which is 1 at selected distance
signal bits : out std_logic_vector(31 downto 0);
begin
columns_inst : entity work.columns
generic map
(
LEN => bits'length,
values => columns_values
)
port map
(
distance => distance,
bits => bits
);
end architecture behavioural;
答案 1 :(得分:0)
鉴于您的数字是预定义的,您只是在恒定位位置和一个(少数)常数之间进行模数运算。这可以通过一组两个循环来完成,每个循环产生一个简单和/或树。合成器很可能也可以消除一些常见的逻辑。我可能会将步距编码为一个热点,或者可能是树形式,这样5也意味着n * 5。我想代码可能类似于:
component columns is
generic (
LEN : integer; -- bits of output
choices : integer; -- number of column combinations
-- distances at which bits may be 1
values : array (0 to choices-1) of integer);
port (
-- one hot encoded distance choice
distance : in std_logic_vector(choices-1 downto 0);
-- data which is 1 at selected distance
bits : out std_logic_vector(LEN-1 downto 0));
end component columns;
architecture behavioural of columns is
begin -- architecture behavioural
bitgen: for i in 0 to choices-1 generate
begin
-- purpose: calculate one individual bit
-- type : combinational
-- inputs : distance
-- outputs: bits(i)
bitcalc: process (distance) is
variable j : integer;
begin -- process bitcalc
bits(i) <= '0';
for j in 0 to chocies-1 loop
if i mod values(j) = 0 and distance(j) then
bits(i) <= '1';
end if;
end loop; -- j
end process bitcalc;
end generate;
end architecture behavioural;
这应该只产生一些不同宽度的门或门。