2011-01-09 4 views
2

VHDL에서 알고리즘을 코딩했는데 "sra/sla가이 컨텍스트에서 피연산자를 가질 수 없다는 것을 이해하지 못한다는 메시지가 있습니다." 어떤 도움을 주시겠습니까?SRA에는 이러한 피연산자를 사용할 수 없습니까?

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; 

답변

2

정수를 사용하는 경우 */ 연산자를 사용해야합니다. 만약 그들이 올바른 위치에서 (즉, 나누기의 오른쪽, 즉 곱셈의 양쪽에) 일정한 2의 제곱을 가지면, 신디사이저는 "올바른 일을 할 것"입니다.

(찰스 언급) ieee.numeric_std library에서 signed 또는 unsigned 유형을 사용하십시오.

ieee.numeric_std을 사용했을 때 conv_std_logic_vector을 사용하고 계십니까? (또는이의 미래 리더)는 FPGA를 대상으로하는 경우 (그리고 난 당신이 할 수있다 동의 :

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

는 다음

(제외 불쾌한 ieee.std_logic_arith 라이브러리 제거 할 수, 무엇을 필요로해야한다 많지는 않지만 요즘 사람들이 많습니다 :) 대상 주파수가 까다로운 경우에는 아키텍처를 파이프 라인 화해야 할 필요가 있음을 알 수 있습니다. 간단한 안구 합성에서는 6 개 이상의 덧셈기가 있습니다. 몇 가지 실제 곱셈기와 몇 개의 멀티플렉서를 모두 단일 클록 주기로 구현할 수 있습니다. 특히, 알고있는 모든 FPGA에서 하드 곱셈기를 사용할 수 없게됩니다.

+0

보다 구체적으로, (x sll 3) 대신 (x * 8)을 사용할 수 있습니다. – Philippe

1

문제는 당신이 수학을 수행하기 위해 I/O 정수로 std_logic_vector를 변환 한하지만 SRA/SRL 피연산자는 비트 또는 부울 유형의 1 차원 배열에서 작동합니다. std_logic_vectors (고유 한 숫자 값이없는)와 정수 (비트 벡터 표현이없는)를 혼합하는 대신 부호가 있거나 부호없는 유형 (숫자의 비트 벡터 표현)을 사용하여 작업하는 것이 훨씬 나을 것입니다.

관련 문제