복잡한 디자인을 위한 영역 및 배열 사용 이해하기

  • 네이버 블로그 공유하기
  • 카카오톡 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 트위터 공유하기

프로그래밍

복잡한 설계를 위한 영역 및 배열 사용 이해하기

FPGA 디자인, 특히 복잡한 디자인의 경우 영역 및 어레이를 사용하지 않고는 관리하기 어려울 수 있는 여러 변수를 사용해야 합니다. 이러한 변수는 코드 구성을 돕고 FPGA 설계 프로세스를 단순화합니다. 그러나 초보자에게 위협이 될 수 있으며 마스터하는 데 시간이 걸릴 수 있습니다. 이 블로그 게시물에서는 복잡한 디자인에 영역 및 배열을 사용하는 방법을 자세히 살펴보겠습니다.

지역

영역은 관련 논리를 함께 그룹화하는 데 사용됩니다. 관련 논리 그룹은 특정 기능을 수행하는 상호 연결된 신호 또는 구성 요소 그룹으로 정의됩니다. 영역을 정의하면 유지하기 어려운 여러 개의 얽힌 연결 생성을 방지하는 데 도움이 됩니다. 영역은 또한 코드의 레이아웃과 구성을 개선하고 읽기 쉽게 만듭니다.

영역을 정의하는 구문은 간단합니다. “region”이라는 키워드와 논리 문 그룹 앞에 영역 이름을 추가하기만 하면 됩니다. 예를 들어:
베릴로그
지역 my_region;
adder1: 엔티티 work.adder 포트 맵(a => a_i, b => b_i, c => c1);
adder2: 엔티티 work.adder 포트 맵(a => c1, b => a_i, c => c2);
adder3: 엔티티 work.adder 포트 맵(a => c2, b => b_i, c => out_i);
끝 지역 my_region;

위의 코드는 “my_region”이라는 영역을 정의하고 여기에 3개의 가산기 엔터티를 할당합니다. 이렇게 하면 세 개의 가산기가 모두 함께 그룹화되어 쉽게 식별할 수 있습니다.

배열

배열은 관련 신호 또는 구성 요소를 함께 그룹화하는 데 사용됩니다. 배열은 유사한 요소의 모음으로 정의됩니다. 배열은 하나의 코드로 많은 수의 신호 또는 구성 요소를 관리할 수 있도록 하여 설계 프로세스를 단순화합니다. 배열을 사용하면 코드의 일관성과 가독성이 크게 향상됩니다.

배열을 정의하는 구문도 간단합니다. “배열”이라는 키워드를 추가하고 신호 또는 구성 요소 명령문 그룹 앞에 배열 이름을 추가하면 됩니다. 예를 들어:
“`베릴로그
어레이 와이어[3:0] my_signals;

할당 my_signals[0] = in1;
할당 my_signals[1] = in2;
할당 my_signals[2] = in3;
할당 my_signals[3] = in4;
“`
이 코드는 4개의 와이어로 구성된 “my_signals”라는 배열을 생성합니다. 그런 다음 어레이는 브래킷을 사용한 인덱싱을 사용하여 4개의 신호 각각을 4개의 와이어에 할당합니다. 또한 루프를 사용하여 배열에서 작동할 수 있으므로 코드가 더욱 단순해집니다.

영역 및 배열 구현

이제 영역 및 배열의 기본 사항을 살펴보았으므로 다양한 상황에서 이를 구현하는 방법에 대한 몇 가지 예를 살펴보겠습니다.

예 1: 영역을 사용하여 복잡한 데이터 경로 정의

다양한 신호와 상호 연결된 여러 기능 블록으로 구성된 데이터 경로가 있다고 가정합니다. 설계 프로세스를 단순화하기 위해 데이터 경로의 각 블록을 영역으로 그룹화할 수 있습니다. 또한 각 지역에 자체 대기 시간 및 파이프라인 단계를 할당하여 데이터 경로를 최적화할 수 있습니다. 다음은 몇 가지 예제 코드입니다.
“`베릴로그
지역 레지스터_뱅크;
reg [15:0] data_in_i, data_out_i;
끝 영역 register_bank;

지역 adder_pipeline;
reg [15:0] adder_in_i, adder_out_i;
항상 @(posedge clk 또는 posedge 먼저)
시작하다
if (처음 == 1’b1)
adder_out_i <= 0;
그렇지 않으면 (활성화 == 1’b1)
adder_out_i <= adder_in_i + register_out_i;

끝 영역 adder_pipeline;

지역 승수_파이프라인;
reg [31:0] mult_in_i;
reg [31:0] mult_out_i;
항상 @(posedge clk 또는 posedge 먼저)
시작하다
if (처음 == 1’b1)
mult_out_i <= 0;
그렇지 않으면 (활성화 == 1’b1)
mult_out_i <= mult_in_i * register_out_i;

끝 영역 multiplier_pipeline;

할당 data_out_i = mult_out_i + adder_out_i;
“`
다음은 register_bank, adder_pipeline 및 multiplier_pipeline의 세 영역으로 구성된 데이터 경로에 대한 코드의 예입니다. 각 지역에는 자체 신호 세트가 있으며 최적의 데이터 경로를 위해 각 지역에 자체 파이프라인 단계를 할당할 수 있습니다. data_out_i 신호는 코드의 마지막 줄에 표시된 것처럼 mult_out_i와 adder_out_i의 합에 할당됩니다.

예제 2: 배열을 사용하여 메모리 인터페이스용 코드 단순화

너비가 다른 여러 메모리 인터페이스가 있는 FPGA를 설계하고 코드를 최대한 단순화하려고 한다고 가정합니다. 배열을 사용하여 각 인터페이스에 해당하는 와이어를 그룹화할 수 있습니다. 다음은 몇 가지 예제 코드입니다.
“`베릴로그
어레이[255:0] mem1_data_in, mem2_data_in, mem3_data_in;
배열 [4095:0] mem1_addr, mem2_addr, mem3_addr;

할당 mem1_data_in[0] = in_data_0_i;
할당 mem1_data_in[1] = in_data_1_i;
할당 mem1_data_in[2] = in_data_2_i;
// 등등…

할당 mem2_data_in[0] = in_data_8_i;
할당 mem2_data_in[1] = in_data_9_i;
할당 mem2_data_in[2] = in_data_10_i;
// 등등…

할당 mem3_data_in[0] = in_data_16_i;
할당 mem3_data_in[1] = in_data_17_i;
할당 mem3_data_in[2] = in_data_18_i;
// 등등…

할당 mem1_addr = in_addr_0_i;
할당 mem2_addr = in_addr_1_i;
할당 mem3_addr = in_addr_2_i;
“`
여기서는 배열을 사용하여 데이터 및 주소 버스의 폭으로 메모리 인터페이스를 그룹화합니다. 이 예제에는 mem1, mem2 및 mem3의 세 가지 메모리 인터페이스가 있습니다. 각 인터페이스에는 데이터 입력용 배열과 주소 입력용 별도 배열이 있습니다. 코드에 표시된 대로 대괄호를 사용한 인덱싱을 사용하여 각 배열에 값을 할당합니다.

결론

결론적으로 복잡한 FPGA 설계를 설계할 때 영역과 배열을 사용하는 것이 필수적입니다. 이러한 도구는 코드를 구성하고 읽기 및 유지 관리를 쉽게 하며 전체 설계 프로세스를 단순화하는 데 도움이 됩니다. 처음에는 위협적일 수 있지만 마스터링 영역 및 배열 구문은 FPGA 설계 전문 지식을 다음 단계로 끌어올릴 것입니다.