【问题标题】:If statement in a for loop VHDLfor循环VHDL中的if语句
【发布时间】:2020-04-09 16:49:13
【问题描述】:

我想为 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 运算符错误:无法评估对运算符 ""enter code here0:00:17 错误:总 CPU 时间(在所有处理器上):00:00:43

【问题讨论】:

  • IEEE Std 1076-2008 8.4 索引名称“索引名称表示数组的元素。...索引名称的前缀应适用于数组类型。表达式指定索引值对于元素;对于数组的每个索引位置应该有一个这样的表达式,并且每个表达式都应该是相应索引的类型。对于索引名称的评估,前缀和表达式被评估。它是如果索引值不属于数组对应索引范围的范围,则会出错。"

标签: for-loop if-statement vhdl min quartus


【解决方案1】:

正如其他人所指出的,for 循环索引超出了数组长度的范围。您还需要生成一系列最小值。并且 Compare 架构中的位宽应该取决于通用 SIZE。

在下面的版本 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 - 树

【讨论】:

    【解决方案2】:
    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
    

    a_unss(i+1) 的索引导致问题,因为您从 0 迭代到 7。当 i 达到 7 时,i+1 等于 8,大于 a_unss 的边界。这就是消息:Error (10385): VHDL error at bitmin.vhd(48): index value 8 is outside the range (0 to 7) of object "a_unss" 的意思。

    编辑

    代码更新建议:

    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;
    signal MinOut_tmp : UNSIGNED (size-1 downto 0) := 0;
    signal done_flag: STD_LOGIC := '0';
    
    
    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
        done_flag <= '0';
    
        for i in 0 to 7 loop
            if (a_unss(i) < MinOut_tmp) then
                MinOut_tmp<=a_unss(i);
            end if;
        end loop;
    
        done_flag <= '1';
    end process;
    END compare;
    
    
    process(done_flag) begin
        if (done_flag == '1') then
            MinOut <= MinOut_tmp;
        end if;
    end process;
    

    【讨论】:

    • 我知道。我想在 i=7 (a_unss(i)
    • 您可以将循环条件更改为:vhdl for i in 0 to 6 loop
    • 还要注意条件逻辑不正确。它同时检查不同的(a_unss(i)&lt;a_unss(i+1)) ,这是没有意义的。我知道您正在尝试检查:(a_unss(0)&lt;a_unss(1)) and (a_unss(1)&lt;a_unss(2)) and (a_unss(2)&lt;a_unss(3)) ... 等等,但您所写的并没有实现这一点。
    • 我怎样才能归档这个?
    • 我在 0 到 6 循环中尝试了 i,但它在非端口 A(7) 上工作
    猜你喜欢
    • 2016-06-16
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    相关资源
    最近更新 更多