for-loop - for循环VHDL中的if语句
问题描述
我想为 8 个输入和一个 if 语句做一个 for 循环。我的目的是找到这 8 个端口中的最小值我知道错误是什么,但是当 (i) 取值为 7 。有任何想法吗?如果 (a_unss(i)
LIBRARY ieee;
USE ieee.std_logic_1164 .all;
USe ieee.numeric_std .all;
---------------------------------------
ENTITY bitmin IS
generic
(
size: integer :=8
);
PORT
(
A0,A1,A2,A3,A4,A5,A6,A7 : IN UNSIGNED (size-1 downto 0);
MinOut:out UNSIGNED (size-1 downto 0)
);
END Entity;
-------------------------------------------------------------------------
ARCHITECTURE compare OF bitmin IS
type a_uns is array (0 to 7) of unsigned(7 downto 0);
signal a_unss:a_uns;
begin
a_unss(0)<=(A0);
a_unss(1)<=(A1);
a_unss(2)<=(A2);
a_unss(3)<=(A3);
a_unss(4)<=(A4);
a_unss(5)<=(A5);
a_unss(6)<=(A6);
a_unss(7)<=(A7);
process(a_unss)
begin
MinOut<="00000000";
for i in 0 to 7 loop
if (a_unss(i)<a_unss(i+1))and (a_unss(i)<a_unss(i+1)) and (a_unss(i)<a_unss(i+1)) and (a_unss(i)<a_unss(i+1))and (a_unss(i)<a_unss(i+1)) and (a_unss(i)<a_unss(i+1)) and (a_unss(i)<a_unss(i+1)) then
MinOut<=a_unss(i);
end if;
end loop;
end process;
END compare;
错误:错误(10385):bitmin.vhd(48)处的VHDL错误:索引值8超出对象“a_unss”的范围(0到7)
错误 (10658):bitmin.vhd(48) 处的 VHDL 运算符错误:无法评估对运算符“<”的调用错误 (10658):bitmin.vhd(48) 处的 VHDL 运算符错误:无法评估对运算符的调用“ "and"" 错误 (12153):无法详细说明顶级用户层次结构 错误:Quartus Prime 分析和综合不成功。4 个错误,1 个警告错误:峰值虚拟内存:4826 兆字节错误:处理结束:2020 年 4 月 9 日星期四 19:39:04 错误:经过的时间:0 enter code here
0:00:17 错误:总 CPU 时间(在所有处理器上):00 :00:43
解决方案
正如其他人指出的那样,for 循环索引超出了数组长度的范围。您还需要生成一系列最小值。比较架构中的位宽应该取决于通用大小。
在下面的版本 1 中,使用了一条长链。
在下面的版本 2 中,使用了两个半长链,这提供了更短的整体传播延迟。
在下面的版本 3 中,使用了树结构,它提供了最短的整体传播延迟。
版本 1 - 一条长链
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity BitMin is
generic
(
SIZE: integer := 8
);
port
(
a0, a1, a2, a3, a4, a5, a6, a7: in unsigned(SIZE - 1 downto 0);
minout: out unsigned(SIZE - 1 downto 0)
);
end entity;
architecture Compare of BitMin is
subtype TBits is unsigned(SIZE - 1 downto 0); -- Changed TByte to TBits because the bit width is dependent upon the generic SIZE.
type TBitsArray is array(0 to 7) of TBits;
signal inputs: TBitsArray;
signal min_chain: TBitsArray;
function Minimum(a, b: TBits) return TBits is
begin
if a < b then
return a;
end if;
return b;
end function;
begin
inputs <= ( a0, a1, a2, a3, a4, a5, a6, a7 );
-- Version 1 (one long chain)
process(inputs, min_chain)
begin
min_chain(0) <= inputs(0); -- Assume the first element in the array is the minimum.
for i in 1 to 7 loop -- Cycle through the remaining items to find the minimum.
min_chain(i) <= Minimum(min_chain(i - 1), inputs(i));
end loop;
minout <= min_chain(7);
end process;
end Compare;
版本 2 - 两条半长链
-- Version 2 (two half-length chains: 0..3 and 7..4)
process(inputs, min_chain)
begin
min_chain(0) <= inputs(0); -- Assume the first element in the array is the minimum.
min_chain(7) <= inputs(7); -- Assume the last element in the array is the minimum.
for i in 1 to 3 loop -- Cycle through the remaining items to find the minimum.
min_chain(i) <= Minimum(min_chain(i - 1), inputs(i)); -- Work forwards from element 1.
min_chain(7 - i) <= Minimum(min_chain(7 - i + 1), inputs(7 - i)); -- Work backwards from element 6.
end loop;
minout <= Minimum(min_chain(3), min_chain(4)); -- Find the minimum of the two chains.
end process;
版本 3 - 树
-- Version 3 (tree structure)
process(inputs)
constant NUM_INPUTS: natural := inputs'length;
constant NUM_STAGES: natural := natural(ceil(log2(real(NUM_INPUTS))));
type TTree is array(0 to NUM_STAGES) of TBitsArray; -- This declares a matrix, but we only use half of it (a triangle shape). The unused part will not be synthesized.
variable min_tree: TTree;
variable height: natural;
variable height_int: natural;
variable height_rem: natural;
variable a, b: TBits;
begin
-- Stage 0 is simply the inputs
min_tree(0) := inputs;
height := NUM_INPUTS;
for i in 1 to NUM_STAGES loop
-- Succeeding stages are half the height of the preceding stage.
height_int := height / 2;
height_rem := height rem 2; -- Remember the odd one out.
-- Process pairs in the preceding stage and assign the result to the succeeding stage.
for j in 0 to height_int - 1 loop
a := min_tree(i - 1)(j);
b := min_tree(i - 1)(j + height_int);
min_tree(i)(j) := Minimum(a, b);
end loop;
-- Copy the odd one out in the preceding stage to the succeeding stage
if height_rem = 1 then
a := min_tree(i - 1)(height - 1);
min_tree(i)(height_int) := a;
end if;
-- Adjust the ever-decreasing height for the succeeding stage.
height := height_int + height_rem;
end loop;
-- Get the value at the point of the triangle which is the minimum of all inputs.
minout <= min_tree(NUM_STAGES)(0);
end process;
试验台
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity BitMin_TB is
end entity;
architecture V1 of BitMin_TB is
constant SIZE_TB: natural := 8;
component BitMin is
generic
(
SIZE: integer := 8
);
port
(
a0, a1, a2, a3, a4, a5, a6, a7: in unsigned (SIZE - 1 downto 0);
minout: out unsigned (SIZE - 1 downto 0)
);
end component;
signal a0_tb, a1_tb, a2_tb, a3_tb, a4_tb, a5_tb, a6_tb, a7_tb: unsigned(SIZE_TB - 1 downto 0);
signal minout_tb: unsigned(SIZE_TB - 1 downto 0);
begin
DUT: BitMin
generic map
(
SIZE => SIZE_TB
)
port map
(
a0 => a0_tb,
a1 => a1_tb,
a2 => a2_tb,
a3 => a3_tb,
a4 => a4_tb,
a5 => a5_tb,
a6 => a6_tb,
a7 => a7_tb,
minout => minout_tb
);
process
begin
wait for 10 ns;
a0_tb <= "00000100";
a1_tb <= "00001000";
a2_tb <= "00010000";
a3_tb <= "00100000";
a4_tb <= "01000000";
a5_tb <= "10000000";
a6_tb <= "00000010";
a7_tb <= "00000001";
wait for 10 ns;
--std.env.stop;
wait;
end process;
end architecture;
综合比较
所有三个版本都综合到相同数量的逻辑元素,但版本 3 是最快的。
版本 1 RTL - 一条长链
版本 2 RTL - 两个半长链
版本 3 RTL - 树
推荐阅读
- libgdx - 如何以速度和加速度将演员从一个点移动到另一个点
- f# - 使用折返重新创建“树包含元素”。我不明白为什么它工作
- c# - Moq 使用表达式参数模拟函数
- c# - 在 C# 中收到无法访问代码检测到问题的错误消息
- javascript - 如何使用 Chart.js 在散点图中添加文本?
- php - 如果存在另一个 meta_key,则插入 meta_key
- java - 阻塞其他线程直到一个线程完成的最佳方法
- c# - 在 Paragraph.Parent 属性不是 FlowDocument 的情况下,是否有任何有意义的用途?
- kubernetes - Kubernetes Pod 串口通信问题
- c# - 如何将 nUnit/OpenCover 结果导入 SonarQube