Arrays 如何使用索引在数组类型内增加std_逻辑_向量?VHDL
背景:Arrays 如何使用索引在数组类型内增加std_逻辑_向量?VHDL,arrays,multidimensional-array,vhdl,synthesis,Arrays,Multidimensional Array,Vhdl,Synthesis,背景: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ui_top is Port ( clk : in std_logic; buttons : in std_logic_vector (4 downto 0); -- centre, left, up, right, down switches
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ui_top is
Port ( clk : in std_logic;
buttons : in std_logic_vector (4 downto 0); -- centre, left, up, right, down
switches : in std_logic_vector (7 downto 0);
leds : out std_logic_vector (7 downto 0);
digit : out std_logic_vector (3 downto 0) := "1110";
segments : out std_logic_vector (7 downto 0) := (others => '0');
uart_tx : out std_logic);
end ui_top;
architecture Behavioral of ui_top is
type my_arr_type is array (0 to 3) of std_logic_vector(3 downto 0);
signal my_signal : my_arr_type;
signal index : std_logic_vector (1 downto 0) := "00";
begin
-- send indexed signal to leds
leds(3 downto 0) <= my_signal(to_integer(unsigned(index)));
-- set other outputs arbitrarily
leds(7 downto 4) <= (others => '1');
uart_tx <= '1';
digit <= "1110";
segments <= (others => '0');
-- set index
index <= "00";
process(clk)
begin
if (rising_edge(clk)) then
if switches(1) = '1' then -- up
my_signal(to_integer(unsigned(index)))
<= std_logic_vector(unsigned( my_signal(to_integer(unsigned(index))) ) + 1);
end if;
end if; -- rising clock edge
end process;
-- set non indexed values arbitrarily
my_signal(1) <= "0000";
my_signal(2) <= "0000";
my_signal(3) <= "0000";
end Behavioral;
我有四个4位标准逻辑向量的类型数组:
type my_arr_type is array (0 to 3) of std_logic_vector (3 downto 0);
以及相应的信号:
signal my_signal : my_arr_type;
我还有一个2位向量用作数组索引:
signal index : std_logic_vector (1 downto 0) := "00";
这允许我动态访问每个4位向量,如下所示:
my_signal(to_integer(unsigned(index))) <= "0001";
问题:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ui_top is
Port ( clk : in std_logic;
buttons : in std_logic_vector (4 downto 0); -- centre, left, up, right, down
switches : in std_logic_vector (7 downto 0);
leds : out std_logic_vector (7 downto 0);
digit : out std_logic_vector (3 downto 0) := "1110";
segments : out std_logic_vector (7 downto 0) := (others => '0');
uart_tx : out std_logic);
end ui_top;
architecture Behavioral of ui_top is
type my_arr_type is array (0 to 3) of std_logic_vector(3 downto 0);
signal my_signal : my_arr_type;
signal index : std_logic_vector (1 downto 0) := "00";
begin
-- send indexed signal to leds
leds(3 downto 0) <= my_signal(to_integer(unsigned(index)));
-- set other outputs arbitrarily
leds(7 downto 4) <= (others => '1');
uart_tx <= '1';
digit <= "1110";
segments <= (others => '0');
-- set index
index <= "00";
process(clk)
begin
if (rising_edge(clk)) then
if switches(1) = '1' then -- up
my_signal(to_integer(unsigned(index)))
<= std_logic_vector(unsigned( my_signal(to_integer(unsigned(index))) ) + 1);
end if;
end if; -- rising clock edge
end process;
-- set non indexed values arbitrarily
my_signal(1) <= "0000";
my_signal(2) <= "0000";
my_signal(3) <= "0000";
end Behavioral;
在上述尝试中,我做错了什么?正确的解决方案是什么
我在网上找不到任何与索引数组中递增单元格相关的示例
(设计用于ISE项目导航中Digilent Nexys 3的合成)
(编辑)更长的代码片段以提高整洁度:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ui_top is
Port ( clk : in std_logic;
buttons : in std_logic_vector (4 downto 0); -- centre, left, up, right, down
switches : in std_logic_vector (7 downto 0);
leds : out std_logic_vector (7 downto 0);
digit : out std_logic_vector (3 downto 0) := "1110";
segments : out std_logic_vector (7 downto 0) := (others => '0');
uart_tx : out std_logic);
end ui_top;
architecture Behavioral of ui_top is
type my_arr_type is array (0 to 3) of std_logic_vector(3 downto 0);
signal my_signal : my_arr_type;
signal index : std_logic_vector (1 downto 0) := "00";
begin
-- send indexed signal to leds
leds(3 downto 0) <= my_signal(to_integer(unsigned(index)));
-- set other outputs arbitrarily
leds(7 downto 4) <= (others => '1');
uart_tx <= '1';
digit <= "1110";
segments <= (others => '0');
-- set index
index <= "00";
process(clk)
begin
if (rising_edge(clk)) then
if switches(1) = '1' then -- up
my_signal(to_integer(unsigned(index)))
<= std_logic_vector(unsigned( my_signal(to_integer(unsigned(index))) ) + 1);
end if;
end if; -- rising clock edge
end process;
-- set non indexed values arbitrarily
my_signal(1) <= "0000";
my_signal(2) <= "0000";
my_signal(3) <= "0000";
end Behavioral;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体ui_top是
端口(时钟:在标准逻辑中;
按钮:在标准逻辑向量中(4向下到0);--中间、左、上、右、下
开关:标准逻辑向量(7到0);
LED:输出标准逻辑向量(7到0);
数字:输出标准逻辑向量(3到0):=“1110”;
段:输出标准逻辑向量(7到0):=(其他=>'0');
uart_tx:输出标准_逻辑);
结束ui_顶部;
ui_top的架构是
类型my_arr_type是标准逻辑向量(3到0)的数组(0到3);
信号my_信号:my_arr_类型;
信号索引:标准逻辑向量(1到0):=“00”;
开始
--向LED发送索引信号
LED(3到0)原因(可能)是有另一个进程或并发分配驱动(分配到)my_信号
,所以请查看整个代码,或将其张贴在此处以供进一步检查
注意,驱动程序(分配)可能被分配到另一个索引;看一看
顺便说一句,你可以删除
else --remain the same
my_signal(to_integer(unsigned(index)))
<= my_signal(to_integer(unsigned(index)));
else——保持不变
my_信号(到_整数(无符号(索引)))
这与最长的静态前缀有关,它不仅是一个综合问题,还反映在模拟中
进程中my_信号的驱动程序由my_信号的最长静态前缀确定
通过对数组中的索引使用非静态值,您已经为未标记进程中的my_信号(0)、my_信号(1)、my_信号(2)和my_信号(3)创建了驱动程序
每个并发信号分配都有一个等效的进程,这些进程有一个最长的静态前缀,其中包括用作my_信号数组索引的数字文本
对于每个并发赋值语句,未标记进程和每个等效进程之间的两个共同驱动程序会产生一个解析信号值,在模拟中,这将为std_逻辑元素的冲突值生成“X”或“U”值。你的合成反应迟钝,并报告说你已将驱动程序短接在一起
参见IEEE标准1076-2008 8。名称,8.1概述(最长静态前缀,第8段),14.7模型执行,14.7.2驱动程序,第1段,14.7.3信号值传播,14.7.3.1概述,第5段
如果您使用了未解析的元素类型(位、位向量),那么在细化过程中,您将得到信号网络上多个驱动程序的一个或多个错误报告。这相当于合成工具报告的内容。您的问题是多驱动器问题。也许有助于理解它。由于您使用的是解析类型(std_logic
),因此在编译或模拟时不会出现错误或警告。您使用的工具(ISE)是一个逻辑合成器。它尝试将您描述的行为映射到现有硬件资源。由于硬件目标不支持多个驱动器,因此会出现错误。我的建议是:
- 不需要解析类型时,请勿使用它们
- 使用适当的类型(如作者明智地建议的)
下面的代码应该更好。根据您的具体需要进行调整。请注意,ieee.numeric\u std
的无符号
类型不幸是一种已解析类型。因此,请小心使用,避免出现多种驾驶情况。或者,更好的是,如果您的工具支持它,请使用未解析\u unsigned
未解析版本的unsigned
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ui_top is
Port(clk : in std_ulogic;
buttons : in std_ulogic_vector (4 downto 0); -- centre, left, up, right, down
switches : in std_ulogic_vector (7 downto 0);
leds : out std_ulogic_vector (7 downto 0);
digit : out std_ulogic_vector (3 downto 0);
segments : out std_ulogic_vector (7 downto 0);
uart_tx : out std_ulogic);
end ui_top;
architecture Behavioral of ui_top is
constant n: positive := 4;
type my_arr_type is array (0 to 3) of unsigned(n-1 downto 0);
-- type my_arr_type is array (0 to 3) of unresolved_unsigned(n-1 downto 0);
signal my_signal : my_arr_type;
signal index : natural range 0 to n-1;
begin
-- send indexed signal to leds
leds(n-1 downto 0) <= std_ulogic_vector(my_signal(index));
-- set other outputs arbitrarily
leds(7 downto n) <= (others => '1');
uart_tx <= '1';
digit <= "1110";
segments <= (others => '0');
-- set index
index <= 0;
process(clk)
begin
if (rising_edge(clk)) then
-- set non indexed values arbitrarily
for i in 0 to n-1 loop
if i = index then
if switches(1) = '1' then -- up
my_signal(i) <= my_signal(i) + 1;
end if;
else
my_signal(i) <= (others => '0');
end if;
end loop;
end if; -- rising clock edge
end process;
end Behavioral;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体ui_top是
港口(时钟:标准逻辑;
按钮:在标准逻辑向量中(从4向下到0);--中心、左、上、右、下
开关:标准逻辑向量(7到0);
LED:输出标准逻辑向量(7到0);
数字:输出标准逻辑向量(3到0);
分段:输出标准逻辑向量(7到0);
uart_tx:输出标准(逻辑);
结束ui_顶部;
ui_top的架构是
常数n:正:=4;
类型my_arr_type是无符号(n-1到0)的数组(0到3);
--类型my_arr_type是未解析的无符号(n-1到0)数组(0到3);
信号my_信号:my_arr_类型;
信号指标:自然范围0~n-1;
开始
--向LED发送索引信号
LED(n-1到0)这是我对错误的理解,但我看不到分配给我的_信号的任何其他内容(至少不是4位向量索引,我认为这种复杂性中的一些误解是我的问题)。我已经添加了我的全部代码供您仔细检查,如果您愿意的话。同时,我会读你的另一个答案。你的合成工具不知道索引
是一个常量。因此,它计算每个信号名称上的多个驱动程序,而不是每个索引名称上的多个驱动程序。请将您的信号索引更改为常量,它应该可以识别它(这只是为了测试)。@paebels好的。这是有道理的。您是对的-将索引
更改为常量值确实可以使代码合成成为可能。当索引不是常量时,有没有关于如何克服此问题的建议?即使使用常量索引,我的工具在“放置和路线”过程中也会暂停。解决方案:将分配移动到my_signal
。只分配给我