2016-06-13 4 views
0

std_logic_vector의 특정 위치에서 비트를 설정하는 자원 효율적인 방법을 찾고 있습니다.std_logic_vector에서 규칙 패턴 생성

signal a := std_logic_vector(LEN-1 downto 0) := (others => '0'), 과 같이 std_logic_vector가 있다고 가정 해 봅시다. 여기서 LEN은 일반 사항입니다. 정기적 인 인터벌, 예를 들어 다섯 번째, 열 번째, ... 위치에서 1으로 설정하고 싶습니다. 인터벌은 사전 정의 된 숫자의 작은 세트 ( ) (예 : (5,10,20,25,30,40,50))에서 가져올 수 있습니다. 이 작업을 수행하는 데 가장 자원 절약적인 방법은 무엇입니까?

분명히 이것은 for 루프와 mod 기능을 사용하여 달성 할 수 있습니다. 그러나이 방법을 합성에 사용하고 싶습니다. 따라서 mod 함수가 값 비쌉니다. 또 다른 가능성은 루프를 푸는 것입니다. 그러나 LEN이 일반이기 때문에 단계 수를 알지 못합니다. 또한 불가능한 조합을 제외하고 싶습니다. 예 : LEN = 20 인 경우 반올림 > 20을 제외해야합니다.

+1

; 둘 다 일정합니다. 가장 비싼 부분은 입력 선택을 해독 할 가능성이 있습니다. –

+0

하나 이상의 상수 선언에 대한 값을 생성하는 함수를 작성할 수 있습니다. 값을 소비하는 데 사용하는 메커니즘 이외에 비용을 내지 않는 정교한 디자인을 합성하기 때문입니다. – user1155120

답변

1

얀의 대답은 VHDL 구문에 익숙하지 않은 사람들에게 답을 제공하기 위해 여기에 몇 가지 문제를 제시하고자합니다. 이는 Yann이 선택한 구현에 대한 비판이 아니라 구문 문제를 명확히하기위한 것입니다.

먼저 위의 예는 완료되지 않았습니다. component 문을 설명하지만 해당 없음은 entity입니다. component의 사용은 선언적 영역에만 있으며 package 또는 architecture 외부의 독립 실행 형 일 수 없습니다. 서면으로 컴파일되지 않습니다. 대신 다음과 같이 변경해야합니다.

entity columns is 
... 
end entity columns; 

둘째, 해당 유형 선언없이 배열을 선언 할 수 없습니다. 즉, Yann의 게시물 예시 :

values : array (0 to choices-1) of integer 

을 수행 할 수 없습니다. 형식을 사용하려면 먼저 선언해야합니다. 그리고 해당 유형을 구성 요소/엔티티에서 볼 수있게하려면 component 또는 entity보다 먼저 정의해야합니다. entity의 경우 패키지에 정의해야합니다. 예를 들어 :

package columns_pkg is 
    type values_array is array(natural range <>) of integer; 
end package columns_pkg; 

그런 columns_pkgentity에서 참조 할 수 있습니다. 예 :

library ieee; 
use ieee.std_logic_1164.all; 
use work.columns_pkg.all; 

entity columns is 
    generic (
    LEN  : integer;     -- bits of output 
    choices : integer;     -- number of column combinations 
     -- distances at which bits may be 1 
    values : values_array(0 to choices-1) 
); 
    ... 

이제는 여전히 적절하지 않습니다. VHDL-2008에서만 generics가 서로 의존적 일 수 있습니다. 즉, values의 범위는 VHDL-2008의 경우에만 choices에 종속 될 수 있습니다. 이전 언어 버전은 VHDL-2002 이전 버전에서 위의 values 선언이 실패한다는 의미입니다.

그러나 choices도 필요하지 않습니다. 오히려, 하나는 (모두 함께 데려와 오타의 몇 가지를 정리)이 작업을 수행 할 수 있습니다 values은 구속이다

library ieee; 
use ieee.std_logic_1164.all; 

package columns_pkg is 
    type values_array is array(natural range <>) of integer; 
end package columns_pkg; 

library ieee; 
use ieee.std_logic_1164.all; 
use work.columns_pkg.all; 

entity columns is 
    generic 
    (
    LEN  : integer;     -- bits of output 
    values : values_array 
); 
    port 
    (
    -- one hot encoded distance choice 
    distance : in std_logic_vector(values'length-1 downto 0); 
    -- data which is 1 at selected distance 
    bits  : out std_logic_vector(LEN-1 downto 0) 
); 
end entity columns; 

architecture behavioural of columns is  
begin -- architecture behavioural 

    bitgen: for i in bits'range generate 
    begin 
    -- purpose: calculate one individual bit 
    -- type : combinational 
    -- inputs : distance 
    -- outputs: bits(i) 
    bitcalc: process (distance) is 
     variable j : integer; 
    begin -- process bitcalc 
     bits(i) <= '0'; 
     for j in values'range loop 
     if i mod values(j) = 0 and distance(j) = '1' then 
      bits(i) <= '1'; 
     end if; 
     end loop; -- j 
    end process bitcalc; 
    end generate; 

end architecture behavioural; 

하는 것으로. 길이는 정교 시간에 결정됩니다. 그리고 속성을 사용하여 길이와 범위를 결정할 수 있습니다.

또한 LENvalues 사이의 관계가있는 경우 LEN 제네릭을 제거 할 수도 있습니다.

그리고 마지막으로, columns의 사용을 만들기 위해, 하나는 않습니다 : 당신은 미리 정의 된 번호의 제한된 세트와 비트 위치 사이의 모드를하고있는

entity top is 
end entity top; 

use work.columns_pkg.all; 

architecture behavioural of top is 
    constant columns_values : values_array(0 to 5) := (0, 5, 10, 15); 

    -- one hot encoded distance choice 
    signal distance : std_logic_vector(columns_values'length-1 downto 0); 

    -- data which is 1 at selected distance 
    signal bits  : out std_logic_vector(31 downto 0); 
begin 
    columns_inst : entity work.columns 
    generic map 
    (
    LEN => bits'length, 
    values => columns_values 
) 
    port map 
    (
    distance => distance, 
    bits => bits 
); 

end architecture behavioural; 
+0

고마워, 내가 제안한 솔루션을 사용합니다! – Apoptose

0

숫자가 미리 정의되어 있으면 상수 비트 위치와 소수 숫자 중 하나만 모듈로 계산됩니다. 이 작업은 비트 당 간단하고/또는 트리를 생성하는 두 개의 루프 세트로 수행 할 수 있습니다. 신디사이저는 일반적인 로직을 제거 할 가능성이 상당히 높습니다. 나는 아마도 5 단계가 n * 5를 의미하는 것과 같이 아마도 하나의 뜨겁거나 나무 형태로 스텝 거리를 인코딩 할 것입니다. 코드가 비슷할 것 같아요 :

component columns is 
    generic (
    LEN  : integer;     -- bits of output 
    choices : integer;     -- number of column combinations 
     -- distances at which bits may be 1 
    values : array (0 to choices-1) of integer); 
    port (
     -- one hot encoded distance choice 
    distance : in std_logic_vector(choices-1 downto 0); 
     -- data which is 1 at selected distance 
    bits  : out std_logic_vector(LEN-1 downto 0)); 
end component columns; 

architecture behavioural of columns is 

begin -- architecture behavioural 

    bitgen: for i in 0 to choices-1 generate 
    begin 
    -- purpose: calculate one individual bit 
    -- type : combinational 
    -- inputs : distance 
    -- outputs: bits(i) 
    bitcalc: process (distance) is 
     variable j : integer; 
    begin -- process bitcalc 
     bits(i) <= '0'; 
     for j in 0 to chocies-1 loop 
     if i mod values(j) = 0 and distance(j) then 
      bits(i) <= '1'; 
     end if; 
     end loop; -- j 
    end process bitcalc; 
    end generate; 

end architecture behavioural; 

이것은 다양한 너비 또는 소수의 게이트 만 생성해야합니다.

+0

고마워, 내가 이것을 시도합니다! – Apoptose