수색…


비고

VHDL 1993 이전의 두 가지 동시 프로세스는 신호와 만 통신 할 수있었습니다. 시뮬레이션 단계 사이에서만 신호를 업데이트하는 언어의 시뮬레이션 의미론 덕분에 시뮬레이션 결과는 결정적이었습니다. 프로세스를 실행하기 위해 시뮬레이션 스케줄러에서 선택한 순서에 의존하지 않았습니다.

[사실, 이것은 100 % 사실이 아닙니다. 프로세스는 파일 입 / 출력을 사용하여 통신 할 수도 있습니다. 그러나 디자이너가 파일을 사용하여 결정론을 손상시키는 경우 실제로 실수가 될 수는 없습니다.]

언어는 이렇게 안전했다. 목적을 제외하고는 비 결정적 VHDL 모델을 설계하는 것은 거의 불가능했습니다.

VHDL 1993은 공유 변수를 도입하고 비 결정적 VHDL 모델을 설계하는 것은 매우 쉬워졌습니다.

VHDL 2000은 보호 된 유형과 공유 변수가 보호 된 유형이어야한다는 제한 사항을 도입했습니다.

VHDL에서 보호 된 유형은 객체 지향 (OO) 언어의 객체 개념과 가장 유사한 개념입니다. 그들은 데이터 구조와 메소드의 캡슐화를 구현합니다. 또한 데이터 멤버에 대한 독점적 액세스와 원자 적 액세스를 보장합니다. 이것은 비 결정론을 완전히 방지하지는 않지만 적어도 공유 변수에 배타성과 원 자성을 추가합니다.

보호 된 유형은 시뮬레이션 전용 VHDL 모델을 설계 할 때 매우 유용합니다. 그것들은 OO 언어에 대해 몇 가지 아주 좋은 특성을 가지고 있습니다. 자주 사용하면 코드를 읽기 쉽고 유지 보수 가능하며 재사용 할 수 있습니다.

노트:

  • 일부 시뮬레이션 도구 체인은 기본적으로 공유 변수가 보호 된 유형이 아닌 경우에만 경고를 발행합니다.
  • 일부 합성 도구는 보호 된 유형을 지원하지 않습니다.
  • 일부 합성 도구에는 공유 변수가 제한적으로 지원됩니다.
  • 공유 변수는 하드웨어를 모델링하는 데 사용할 수없고 부작용없이 코드 계측을 위해 예약되어야한다고 생각할 수 있습니다. 그러나 여러 EDA 공급 업체가 다중 포트 RAM (Multi-Port Random Access Memory)의 메모리 평면을 모델링하도록 권고 한 VHDL 패턴은 공유 변수를 사용합니다. 그래서, 네, 공유 변수는 특정 환경에서 합성 될 수 있습니다.

의사 랜덤 생성기

Peudo-random 생성기는 시뮬레이션 환경을 설계 할 때 종종 유용합니다. 다음 VHDL 패키지의 의사 난수 생성기 설계하는 보호 유형을 사용하는 방법을 보여줍니다 boolean , bitbit_vector . 무작위의 std_ulogic_vector ( signed , unsigned 생성하기 위해 쉽게 확장 할 수 있습니다. 임의의 경계와 균일 한 분포를 갖는 임의의 정수를 생성하도록 확장하는 것은 좀 더 까다 롭지 만 실행 가능합니다.

패키지 선언

보호 된 유형에는 모든 공용 서브 프로그램 액세서가 선언 된 선언이 있습니다. 우리의 무작위 생성기에 대해 우리는 하나의 시드 초기화 프로 시저와 임의의 boolean , bit 또는 bit bit_vector 반환하는 3 개의 불순한 함수를 공개 할 것입니다. 동일한 매개 변수를 사용하는 서로 다른 호출이 서로 다른 값을 반환 할 수 있기 때문에 함수가 순수하지 않을 수 있습니다.

-- file rnd_pkg.vhd
package rnd_pkg is
    type rnd_generator is protected
        procedure init(seed: bit_vector);
        impure function get_boolean return boolean;
        impure function get_bit return bit;
        impure function get_bit_vector(size: positive) return bit_vector;
    end protected rnd_generator;
end package rnd_pkg;

패키지 몸체

보호 된 본문 본문은 내부 데이터 구조 (멤버)와 서브 프로그램 본문을 정의합니다. 랜덤 제너레이터는 4 비트의 탭이있는 128 비트 선형 피드백 쉬프트 레지스터 (LFSR)를 기반으로합니다. state 변수는 LFSR의 현재 상태를 저장합니다. 민간 throw 절차는 발전기가 사용될 때마다 LFSR을 이동시킨다.

-- file rnd_pkg.vhd
package body rnd_pkg is
    type rnd_generator is protected body
        constant len: positive := 128;
        constant default_seed: bit_vector(1 to len) := X"8bf052e898d987c7c31fc71c1fc063bc";
        type tap_array is array(natural range <>) of positive range 1 to len;
        constant taps: tap_array(0 to 3) := (128, 126, 101, 99);

        variable state: bit_vector(1 to len) := default_seed;

        procedure throw(n: positive := 1) is
            variable tmp: bit;
        begin
            for i in 1 to n loop
                tmp := '1';
                for j in taps'range loop
                    tmp := tmp xnor state(taps(j));
                end loop;
                state := tmp & state(1 to len - 1);
            end loop;
        end procedure throw;

        procedure init(seed: bit_vector) is
            constant n:   natural            := seed'length;
            constant tmp: bit_vector(1 to n) := seed;
            constant m:   natural            := minimum(n, len);
        begin
            state         := (others => '0');
            state(1 to m) := tmp(1 to m);
        end procedure init;

        impure function get_boolean return boolean is
            constant res: boolean := state(len) = '1';
        begin
            throw;
            return res;
        end function get_boolean;

        impure function get_bit return bit is
            constant res: bit := state(len);
        begin
            throw;
            return res;
        end function get_bit;

        impure function get_bit_vector(size: positive) return bit_vector is
            variable res: bit_vector(1 to size);
        begin
            if size <= len then
                res := state(len + 1 - size to len);
                throw(size);
            else
                res(1 to len) := state;
                throw(len);
                res(len + 1 to size) := get_bit_vector(size - len);
            end if;
            return res;
        end function get_bit_vector;
    end protected body rnd_generator;
end package body rnd_pkg;

랜덤 생성기는 다음과 같이 OO 스타일로 사용할 수 있습니다.

-- file rnd_sim.vhd
use std.env.all;
use std.textio.all;
use work.rnd_pkg.all;

entity rnd_sim is
end entity rnd_sim;

architecture sim of rnd_sim is
    shared variable rnd: rnd_generator;
begin
    process
        variable l: line;
    begin
        rnd.init(X"fe39_3d9f_24bb_5bdc_a7d0_2572_cbff_0117");
        for i in 1 to 10 loop
            write(l, rnd.get_boolean);
            write(l, HT);
            write(l, rnd.get_bit);
            write(l, HT);
            write(l, rnd.get_bit_vector(10));
            writeline(output, l);
        end loop;
        finish;
    end process;
end architecture sim;
$ mkdir gh_work
$ ghdl -a --std=08 --workdir=gh_work rnd_pkg.vhd rnd_sim.vhd
$ ghdl -r --std=08 --workdir=gh_work rnd_sim
TRUE    1    0001000101
FALSE   0    1111111100
TRUE    1    0010110010
TRUE    1    0010010101
FALSE   0    0111110100
FALSE   1    1101110010
TRUE    1    1011010110
TRUE    1    0010010010
TRUE    1    1101100111
TRUE    1    0011100100
simulation finished @0ms


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow