在 std_logic_vector 中生成规则模式
Generate regular pattern in std_logic_vector
我正在寻找一种资源有效的方法来设置 std_logic_vector 中特定位置的位。
假设我有一个 std_logic_vector 例如 signal a := std_logic_vector(LEN-1 downto 0) := (others => '0')
,
其中 LEN 是泛型。
我想定期将它设置为 1
,例如,在第五、第十……位置,其中间隔可能来自一组(小的)预定义数字,
例如,(5,10,20,25,30,40,50)
。
实现此目的最节省资源的方法是什么?
显然这可以使用 for
循环和 mod
函数来实现。
但是,我想使用这种方法进行合成,因此 mod 函数可能会很昂贵。另一种可能性是展开循环。但是,由于 LEN
是通用的,我不知道步骤数。此外,我想排除不可能的组合,例如,如果 LEN = 20
,应该排除 invervalls > 20
。
鉴于您的数字是预定义的,您只是在常数位位置和一个(少数)常数之间进行取模。这可以通过一组两个循环来完成,每个循环生成一个简单的 and/or 树。合成器很可能也可以消除一些通用逻辑。我可能会将步距编码为一个热,或者可能是一种树形,这样 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;
这只会产生少量或不同宽度的门。
Yann 的回答有几个问题,我想在这里解决,以便为那些不太精通 VHDL 语法的人提供答案。这不是对 Yann 选择的实现的批评,而是为了澄清语法问题。
首先,上面的例子并不完整。它描述了一个 component
语句,但没有相应的 entity
。 component
的使用仅在声明区域中,不能在 package
或 architecture
之外独立存在。正如所写,它不会编译。相反,它应该更改为:
entity columns is
...
end entity columns;
其次,不能在没有相应类型声明的情况下声明数组。即Yann中的例子post:
values : array (0 to choices-1) of integer
无法完成。类型必须在使用前声明。为了使 component/entity 可见该类型,它必须在 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;
我正在寻找一种资源有效的方法来设置 std_logic_vector 中特定位置的位。
假设我有一个 std_logic_vector 例如 signal a := std_logic_vector(LEN-1 downto 0) := (others => '0')
,
其中 LEN 是泛型。
我想定期将它设置为 1
,例如,在第五、第十……位置,其中间隔可能来自一组(小的)预定义数字,
例如,(5,10,20,25,30,40,50)
。
实现此目的最节省资源的方法是什么?
显然这可以使用 for
循环和 mod
函数来实现。
但是,我想使用这种方法进行合成,因此 mod 函数可能会很昂贵。另一种可能性是展开循环。但是,由于 LEN
是通用的,我不知道步骤数。此外,我想排除不可能的组合,例如,如果 LEN = 20
,应该排除 invervalls > 20
。
鉴于您的数字是预定义的,您只是在常数位位置和一个(少数)常数之间进行取模。这可以通过一组两个循环来完成,每个循环生成一个简单的 and/or 树。合成器很可能也可以消除一些通用逻辑。我可能会将步距编码为一个热,或者可能是一种树形,这样 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;
这只会产生少量或不同宽度的门。
Yann 的回答有几个问题,我想在这里解决,以便为那些不太精通 VHDL 语法的人提供答案。这不是对 Yann 选择的实现的批评,而是为了澄清语法问题。
首先,上面的例子并不完整。它描述了一个 component
语句,但没有相应的 entity
。 component
的使用仅在声明区域中,不能在 package
或 architecture
之外独立存在。正如所写,它不会编译。相反,它应该更改为:
entity columns is
...
end entity columns;
其次,不能在没有相应类型声明的情况下声明数组。即Yann中的例子post:
values : array (0 to choices-1) of integer
无法完成。类型必须在使用前声明。为了使 component/entity 可见该类型,它必须在 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;