2

我已经用 VHDL 编写了一个算法,但是我收到了我不理解的消息“sra/sla 在这种情况下不能有这样的操作数。”。请问有什么帮助吗?

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_arith.conv_std_logic_vector;

entity hsl2rgb is
    generic(
        constant hue : integer := 85;
        constant sat : integer := 127
    );
    port(
        lum    : in  std_logic_vector(7 downto 0);
        ored   : out std_logic_vector(5 downto 0);
        ogreen : out std_logic_vector(5 downto 0);
        oblue  : out std_logic_vector(5 downto 0)
    );
end entity;

architecture behavioral of hsl2rgb is
begin

    process(lum)
        variable v : integer;
        variable m : integer;
        variable sextant : integer;
        variable fract : integer;
        variable vsf : integer;
        variable mid1 : integer;
        variable mid2 : integer;
        variable lumx : integer;
    begin
        lumx := to_integer(unsigned(lum));
        if (lumx < 127) then
            v := (lumx * (256 + sat)) sra 8;
        else
            v := (((lumx + sat) sla 8) - lumx * sat) sla 8;
        end if;

        if (v <= 0) then
            ored <= (others => '0');
            ogreen <= (others => '0');
            oblue <= (others => '0');
        else
            m := (2 * lumx) - v;
            sextant := (hue * 6) sra 8;
            fract := (hue * 6) - (sextant sla 8);
            vsf := (fract * (v - m)) sra 8;
            mid1 := m + vsf;
            mid2 := v - vsf;

            case sextant is
                when 0 =>
                    ored <= conv_std_logic_vector(v, 6);
                    ogreen <= conv_std_logic_vector(mid1, 6);
                    oblue <= conv_std_logic_vector(m, 6);
                when 1 =>
                    ored <= conv_std_logic_vector(mid2, 6);
                    ogreen <= conv_std_logic_vector(v, 6);
                    oblue <= conv_std_logic_vector(m, 6);
                when 2 =>
                    ored <= conv_std_logic_vector(m, 6);
                    ogreen <= conv_std_logic_vector(v, 6);
                    oblue <= conv_std_logic_vector(mid1, 6);
                when 3 =>
                    ored <= conv_std_logic_vector(m, 6);
                    ogreen <= conv_std_logic_vector(mid2, 6);
                    oblue <= conv_std_logic_vector(v, 6);
                when 4 =>
                    ored <= conv_std_logic_vector(mid1, 6);
                    ogreen <= conv_std_logic_vector(m, 6);
                    oblue <= conv_std_logic_vector(v, 6);
                when 5 =>
                    ored <= conv_std_logic_vector(v, 6);
                    ogreen <= conv_std_logic_vector(m, 6);
                    oblue <= conv_std_logic_vector(mid2, 6);
                when others =>
                    ored <= (others => '0');
                    ogreen <= (others => '0');
                    oblue <= (others => '0');
            end case;
        end if;
    end process;
end architecture;
4

2 回答 2

2

对于整数,您必须使用*/运算符。如果它们在正确的位置(即在除法的右侧,乘法的任一侧)具有恒定的 2 次幂,则合成器将“做正确的事”。

或者(正如查尔斯所指出的)使用signedunsigned类型来自ieee.numeric_std library.

顺便说一句,conv_std_logic_vector你用过为什么还要用ieee.numeric_std

ored <= std_logic_vector(to_unsigned(mid1, 6));

应该是你所需要的,那么你可以摆脱讨厌的ieee.std_logic_arith图书馆

(旁白:如果您(或未来的读者)针对的是 FPGA(我接受您可能不是,但现在很多人是这样的:)您可能会发现,如果目标频率为完全具有挑战性。在一个简短的眼球综合中,有六个以上的加法器,几个实数乘法器和几个多路复用器 - 所有这些都在一个时钟周期内。特别是这将排除使用硬我知道的所有 FPGA 中的乘法器)

于 2011-01-10T15:37:48.267 回答
1

问题是您已将 std_logic_vector I/O 转换为整数以执行数学运算,但 sra/srl 操作数仅适用于位或布尔类型的一维数组。尝试使用有符号或无符号类型(数字的位向量表示)而不是混合 std_logic_vectors(没有固有数值)和整数(没有位向量表示),您可能会有更好的运气。

于 2011-01-10T00:55:40.310 回答