VHDL
파일에서 신호 값을 읽는 것은 테스트 중인 기기(DUT)에 대한 자극을 생성하는 또 다른 방법입니다. 테스트벤치 시퀀스와 타이밍은 VHDL 테스트벤치에서 한 줄씩 읽는 자극 파일에 하드 코딩되어 있습니다. 이를 통해 테스트 개체에 공급하려는 파형의 패턴을 쉽게 변경할 수 있습니다.
때때로 DUT를 통과시키려는 매우 구체적인 테스트 패턴이나 이벤트 시퀀스가 있습니다. ASCII 파일에서 각 신호가 가져야 하는 신호 값과 변경해야 하는 상대 시뮬레이션 시간을 지정하여 이를 달성할 수 있습니다. 이러한 전략에서 VHDL 테스트벤치의 역할은 자극 파일에서 데이터를 읽고 정확한 시간에 DUT 입력에 값을 적용하는 것입니다.
이 기사는 VHDL의 파일 액세스에 대한 시리즈의 두 번째 기사입니다. 이전 블로그 게시물에서 파일에서 16진수, 8진수 및 2진수 값을 읽는 방법을 살펴보았고 TEXTIO
을 사용하여 파일에서 읽는 방법에 대해 더 알고 싶다면 다시 읽어보세요. VHDL의 라이브러리.
이 블로그 게시물은 VHDL에서 TEXTIO 라이브러리를 사용하는 방법에 대한 시리즈의 일부입니다. 여기에서 다른 기사를 읽으십시오:
TEXTIO를 사용하여 파일에서 RAM을 초기화하는 방법
TEXTIO를 사용하여 읽은 BMP 파일 비트맵 이미지
예제 DUT는 이전 블로그 게시물 중 하나에서 가져온 4입력 멀티플렉서(MUX)입니다. 데이터 너비가 1바이트인 표준 비동기식 4-to-1 MUX입니다. 이 기사에서는 작동 방식이 중요하지 않습니다. 우리는 출력을 확인하지 않고 단지 시연용이기 때문입니다.
MUX의 엔터티는 아래와 같습니다.
entity mux_4 is port( -- Data in din_0 : in unsigned(7 downto 0); din_1 : in unsigned(7 downto 0); din_2 : in unsigned(7 downto 0); din_3 : in unsigned(7 downto 0); -- Selector sel : in unsigned(1 downto 0); -- Data out dout : out unsigned(7 downto 0)); end entity;
VHDL 파일 상단에 필요한 패키지를 가져온 후 DUT에 연결할 입력 신호를 선언합니다. 아래 목록에서 볼 수 있듯이 MUX 엔터티 선언의 청사진입니다.
signal din_0 : unsigned(7 downto 0); signal din_1 : unsigned(7 downto 0); signal din_2 : unsigned(7 downto 0); signal din_3 : unsigned(7 downto 0); signal sel : unsigned(1 downto 0); signal dout : unsigned(7 downto 0);
엔티티 인스턴스화 방법을 사용하여 테스트벤치의 아키텍처 영역 상단에 "DUT"라는 레이블이 있는 MUX의 인스턴스를 생성합니다. 엔티티 신호는 아래 코드와 같이 동일한 이름의 로컬 테스트벤치 신호에 연결됩니다.
DUT: entity work.mux_4(rtl) port map ( din_0 => din_0, din_1 => din_1, din_2 => din_2, din_3 => din_3, sel => sel, dout => dout );
자극 파일은 다양한 형식을 가질 수 있습니다. 여기에 제시된 형식은 이 기사를 작성하는 동안 머리 위에서 생각해낸 예일 뿐입니다. 그럼에도 불구하고 내가 만든 방법을 이해하면 필요에 맞게 수정할 수 있습니다.
아래 목록은 이 예에서 사용된 전체 자극 파일을 보여줍니다.
# Column description: # wait_time | sel | din_0 | din_1 | din_2 | din3 # Optional console printout 0 ns 0 AA BB CC DD # Setting initial values 10 ns 1 AA BB CC DD # Testing by changing the selector signal 10 ns 2 AA BB CC DD 10 ns 3 AA BB CC DD 10 ns 3 A1 B1 C1 D1 # Testing by changing all data inputs 10 ns 3 A2 B2 C2 D2 10 ns 3 A3 B3 C3 D3 10 ns 3 00 00 00 D2 # Changing all unselected inputs 10 ns 3 01 02 03 D2 10 ns 3 11 22 33 D2 1 ns 0 CC DD EE FF # Changing all inputs fast 1 ns 1 DD EE FF CC 1 ns 2 EE FF CC DD 1 ns 3 FF CC DD EE 10 ns 0 00 00 00 00 # Simulation stop
지금은 주석을 무시합시다. 녹색으로 표시된 주석은 항상 '#' 문자로 시작합니다. 각 선은 시뮬레이션에서 하나의 시간 단계를 나타냅니다. 각 줄에는 6개의 명령 열이 있으며 실제로는 7개의 텍스트 열이 있지만 처음 두 열은 동일한 데이터 항목에 속합니다.
텍스트 열 1과 2는 다른 열에 나열된 값을 적용하기 전에 시뮬레이터가 해당 행에서 일시 중지해야 하는 시간 값을 설명합니다. 따라서 명령이 실행되는 절대 시뮬레이션 시간은 이전 행에서 설명한 이벤트에 상대적입니다. 0, 1 또는 10나노초만 사용하고 있지만 1000나노초 또는 1000시간(1000 hr
) 그 문제에 대해.
나머지 5개의 텍스트 열은 DUT 입력에 적용할 신호 값을 설명합니다. 16진수 리터럴로 제공되며 신호 순서는 sel
입니다. , din_0
, din_1
, din_2
, 그리고 마지막으로 din_3
.
이제 댓글로 넘어갑니다. 주석에는 두 가지 유형이 있습니다. 한 줄 주석 및 후행 주석. 그것들은 우리의 테스트벤치에 의해 다르게 취급될 것입니다. 파일 맨 위에 있는 것과 같은 한 줄 주석은 무시됩니다. 반면에 후행 주석은 시뮬레이터 콘솔에 인쇄됩니다. 시뮬레이션이 실행되는 동안 무슨 일이 일어나고 있는지에 대한 단서를 제공하는 데 사용할 수 있습니다.
VHDL은 텍스트 처리를 위한 최고의 언어는 아니지만 그 역할을 합니다. 동적 문자열에 대한 지원은 제한적이며 공백 제거 또는 건너뛰기와 같은 편리한 루틴이 부족합니다. 쉽게 하기 위해 자극 파일이 잘 작성되었다고 가정하겠습니다. 텍스트 요소 사이에는 항상 한 칸의 공백이 있고 '#' 문자와 주석 텍스트 사이에는 한 칸의 공백이 있어야 합니다. 또한 자극 파일의 어디에도 추가 선행 또는 후행 공백이 없습니다.
PROC_SEQUENCER : process file text_file : text open read_mode is "stimulus.txt"; variable text_line : line; variable ok : boolean; variable char : character; variable wait_time : time; variable selector : sel'subtype; variable data : dout'subtype; begin
PROC_SEQUENCER
의 선언적 영역 절차는 위에 나와 있습니다. 먼저 특수 file
를 선언합니다. 객체, VHDL 파일 핸들러 유형. 그런 다음 line
유형의 변수를 선언합니다. . 이것은 단순히 문자열에 대한 액세스 유형이며 동적으로 할당된 문자열 개체에 대한 포인터입니다. ok
Boolean 유형의 변수는 읽기 작업이 성공했는지 확인하기 위한 것입니다. 마지막으로 4개의 변수 char
을 선언합니다. , wait_time
, selector
및 data
. 이 변수는 텍스트의 모든 줄에서 각 열의 데이터를 추출하기 위한 것입니다.
while not endfile(text_file) loop readline(text_file, text_line); -- Skip empty lines and single-line comments if text_line.all'length = 0 or text_line.all(1) = '#' then next; end if;
프로세스 본문에서 자극 파일의 모든 텍스트 줄을 반복하는 while 루프로 바로 이동합니다. readline
프로시저는 text_line
에 새 텍스트 줄을 할당합니다. 이 루프의 모든 반복에서 변수. 행을 읽은 후 행이 비어 있는지 또는 첫 번째 문자가 '#'인 경우 next
을 사용하여 즉시 다음 행으로 이동하는지 확인합니다. 루프의 반복을 건너뛰는 키워드입니다. text_line.all
를 사용하고 있습니다. line
내부의 문자열에 액세스하려면 개체.
read(text_line, wait_time, ok); assert ok report "Read 'wait_time' failed for line: " & text_line.all severity failure; hread(text_line, selector, ok); assert ok report "Read 'sel' failed for line: " & text_line.all severity failure; sel <= selector; hread(text_line, data, ok); assert ok report "Read 'din_0' failed for line: " & text_line.all severity failure; din_0 <= data; hread(text_line, data, ok); assert ok report "Read 'din_1' failed for line: " & text_line.all severity failure; din_1 <= data; hread(text_line, data, ok); assert ok report "Read 'din_2' failed for line: " & text_line.all severity failure; din_2 <= data; hread(text_line, data, ok); assert ok report "Read 'din_3' failed for line: " & text_line.all severity failure; din_3 <= data;
다음은 text_line
에서 여러 번 읽습니다. 물체. read
및 hread
프로시저 호출은 선행 공백을 건너뛰므로 text_line
내부 읽기 시작 위치를 이동하기 위해 더미 읽기를 수행할 필요가 없습니다. 물체. assert 문을 생략할 수도 있지만 읽기가 실패하면 시뮬레이션이 중지되기를 원합니다. 적어도 ModelSim에서는 이러한 일이 발생해도 시뮬레이션이 자동으로 중지되지 않습니다. wait_time
을 제외하고 성공적으로 읽은 각 변수를 관련 DUT 신호에 할당합니다. 해당 DUT 입력이 없는 변수입니다.
wait for wait_time;
신호 값을 할당한 후 지정된 시간 동안 기다립니다. wait-statement를 입력하면 예약된 신호 값이 동일한 델타 주기로 적용됩니다.
-- Print trailing comment to console, if any read(text_line, char, ok); -- Skip expected newline read(text_line, char, ok); if char = '#' then read(text_line, char, ok); -- Skip expected newline report text_line.all; end if; end loop; finish; end process;
마지막으로 프로그램이 wait-statement에서 깨어나면 text_line
에 대한 추가 후행 주석을 찾습니다. 물체. 모든 주석은 더미 읽기를 사용하여 '#' 문자와 다음 공백을 제거한 후 보고서 문을 사용하여 콘솔에 인쇄됩니다.
자극 파일의 마지막 텍스트 줄이 처리된 후 while 루프가 종료됩니다. VHDL-2008 finish
가 있습니다. 테스트벤치 중지를 담당하는 프로세스 끝에 키워드.
예제 테스트벤치는 ModelSim에서 실행될 때 시뮬레이터 콘솔에 아래 표시된 텍스트를 출력합니다. 주석이 자극 파일의 주석임을 알 수 있습니다. 인쇄된 시간 값은 자극 파일에 지정된 나노초 지연을 기반으로 하는 누적 시뮬레이션 시간입니다.
# ** Note: Setting initial values # Time: 0 ns Iteration: 1 Instance: /file_stim_tb # ** Note: Testing by changing the selector signal # Time: 10 ns Iteration: 0 Instance: /file_stim_tb # ** Note: Testing by changing all data inputs # Time: 40 ns Iteration: 0 Instance: /file_stim_tb # ** Note: Changing all unselected inputs # Time: 70 ns Iteration: 0 Instance: /file_stim_tb # ** Note: Changing all inputs fast # Time: 91 ns Iteration: 0 Instance: /file_stim_tbf # ** Note: Simulation stop # Time: 104 ns Iteration: 0 Instance: /file_stim_tb # Break in Process PROC_SEQUENCER at file_stim_tb.vhd line 98
시뮬레이션의 파형은 아래와 같습니다. 자극 파일의 값이 지정된 시뮬레이션 시간에 신호에 적용되는 방식을 시각적으로 보여줍니다.
적용해야 하는 매우 구체적인 테스트 패턴이 있는 경우 파일에서 테스트벤치 자극을 읽는 것이 유리할 수 있습니다. 전체 테스트 벤치는 텍스트 파일로 제어할 필요가 없습니다. 이 예제는 VHDL에서 파일 액세스 가능성을 보여주기 위한 것입니다.
그러나 우리가 논의하지 않은 한 가지는 DUT 출력을 확인하는 것입니다. 예제 테스트벤치는 출력을 전혀 확인하지 않습니다. 예를 들어 비교할 동작 모델을 사용하여 전체 VHDL 테스트벤치에서와 같이 DUT 동작을 확인할 수 있습니다. 또는 예상되는 출력 값을 포함하도록 코드와 자극 파일을 수정할 수 있습니다. 어떤 전략을 선택하든 자체 검사 테스트벤치를 만들고 파형을 수동으로 검사하는 데 의존하지 않도록 하십시오.
VHDL
지금까지 우리는 MATLAB 환경을 계산기로 사용했습니다. 그러나 MATLAB은 강력한 프로그래밍 언어일 뿐만 아니라 대화형 계산 환경이기도 합니다. 이전 장에서는 MATLAB 명령 프롬프트에서 명령을 입력하는 방법을 배웠습니다. MATLAB을 사용하면 파일에 일련의 명령을 작성하고 함수를 작성하고 호출하는 것과 같이 파일을 완전한 단위로 실행할 수도 있습니다. M 파일 MATLAB은 두 가지 종류의 프로그램 파일 작성을 허용합니다 - 스크립트 - 스크립트 파일은 .m 확장자를 가진 프로그램 파일입니다. . 이 파일에서 함
IoT 하드웨어, 소프트웨어 및 통신 프로토콜을 포함한 IIoT 구성 요소의 원활한 통합은 제조업체를 위한 점진적 단계에서 이루어졌습니다. 초기 산업 자동화 시스템은 기본 센서, 리미트 스위치 및 분석이 거의 또는 전혀 제공되지 않는 인쇄물이나 HMI에 직접 데이터를 공급하는 기타 장치였습니다. 데이터는 여전히 관리 수준에서 독립 실행형 소프트웨어 플랫폼에 입력해야 했습니다. 단순 소프트웨어와 엔터프라이즈급 시스템 간의 상호 운용성에 문제가 있었고 시스템이 소비를 위해 데이터를 처리할 수 있는 속도와 깊이의 한계가 있었습니다. 사