수색…
비고
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
, bit
및 bit_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