01signal.com

Vivado에서 부분 재구성(Partial Reconfiguration) 적용 방법

소개

이 글은 Xilinx Vivado의 부분 재구성(Partial Reconfiguration), 즉 DFX(Dynamic Function eXchange)에 관한 네 편짜리 시리즈의 두 번째 글입니다. 이 글의 목적은 FPGA 설계에서 부분 재구성(Partial Reconfiguration)을 활성화하는 단계를 안내하고 설명하는 것입니다. 아직 읽지 않았다면 첫 번째 글을 먼저 읽어 보시길 권합니다. 이 단계들의 배경 개념을 설명해 두었기 때문입니다.

Xilinx는 2020년에 부분 재구성(Partial Reconfiguration)을 "DFX(Dynamic Function eXchange)"로 브랜드를 변경했습니다. DFX는 Vivado의 메뉴와 안내 문구에 사용되는 표현입니다. 하지만 이 글에서는 기술 용어인 "부분 재구성(Partial Reconfiguration)"을 계속 사용합니다.

이 글에서는 설명을 단순하게 하기 위해 프로젝트에 재구성 파티션(reconfigurable partition)이 하나만 있다고 가정합니다. 여러 개의 파티션으로 확장하는 것은 비교적 간단합니다.

이 글에서 설명하는 절차는 프로젝트가 부분 재구성(Partial Reconfiguration)을 사용하도록 설정되기 이전부터 시작합니다. 대략적으로 단계를 나누면 다음과 같습니다.

플로어플래닝 준비

플로어플래닝(floorplanning)은 다른 어떤 작업보다 머리를 써야 하는 작업입니다. FPGA 로직 영역을 낭비하지 않으면서도, 정적 파티션(static partition)과 재구성 파티션 모두 배치 및 배선(place and route) 과정에서 큰 장애물을 만나지 않도록 보장해야 하는 미묘한 균형이 필요합니다.

따라서 이 글의 상당 부분이 이 주제를 다룹니다.

오래전에는 플로어플래닝(floorplanning)이 타이밍 클로저(timing closure)를 위해 사용되던 기법이었습니다. 플로어플래닝은 도구가 로직을 합리적인 방식으로 배치하도록 도와주었습니다. FPGA 설계 도구가 시간이 지나면서 개선됨에 따라, 플로어플래닝이 타이밍 제약(timing constraints) 달성에 실제로 도움이 되는 것을 마지막으로 본 지도 수년이 지났습니다. 오늘날에는 거의 언제나 도구가 스스로 판단하도록 두는 것이 타이밍 제약을 달성하는 최선의 전략입니다.

부분 재구성(Partial Reconfiguration)에서는 플로어플래닝(floorplanning)이 필수이므로, 목표는 상황을 더 나쁘게 만들지 않는 것입니다. 이를 위한 작업은 대개 시행착오의 연속입니다. 좋은 결과를 얻는 가장 간단한 방법은 플로어플래닝 없이 설계를 한번 구현해 보고, 로직이 자연스럽게 배치된 모습을 출발점으로 삼는 것입니다. 그다음 단계로, 초기 배치를 가이드라인으로 삼아 부분 재구성에 맞는 영역 구성을 시도하는 것입니다.

플러그인 사용(plugin usage) 시나리오에서는 프로젝트가 발전함에 따라 플로어플래닝(floorplanning)을 갱신할 수 있습니다. 그러나 Remote Update(원격 업데이트) 시나리오, 즉 출시된 설계를 부분 재구성(Partial Reconfiguration)으로 버전 업데이트하는 경우에는 그렇지 않습니다. Remote Update에서는 모든 부분 비트스트림이 초기 비트스트림과 일치해야 합니다. 따라서 초기 비트스트림이 출시되는 순간 설계의 정적 로직(static logic) 부분은 동결됩니다. 그 외에도 플로어플래닝이 동일하게 유지되어야 한다는 뜻입니다.

그러므로 부분 재구성을 시작하기 전에, 가장 먼저 할 일은 FPGA 안에서 정적 로직(static logic)이 들어갈 적절한 영역을 찾는 것입니다. 여기에 너무 많은 시간을 쓸 필요는 없습니다. 프로젝트가 두 부분으로 나뉜 뒤에 진행할 수 있는 출발점만 잡으면 됩니다.

혼동하지 마세요. 이 첫 단계의 목적은 플로어플래닝(floorplanning) 자체가 아닙니다. 제약 없이 Vivado가 로직을 어떻게 배치하는지 확인하고, 그로부터 정적 로직(static logic)에 어떤 영역을 할당할지 결정하는 것입니다. 절차는 다음과 같습니다.

부분 재구성(Partial Reconfiguration) 프로젝트 설정

Xilinx의 UG909는 부분 재구성(Partial Reconfiguration)을 위한 두 가지 작업 절차를 제시합니다.

이 글에서는 프로젝트 방식을 사용하겠습니다. 여기에는 몇 가지 제약이 있고, 그중 일부는 재구성 모듈에 포함되는 소스의 유형과 관련됩니다(특히 블록 디자인을 사용하는 경우). 어쨌든 프로젝트 방식으로 시작하는 편이 좋습니다. 프로젝트 방식이 생성하는 구현용 스크립트(script)는 필요할 때 비프로젝트 방식의 좋은 기반이 되기 때문입니다.

기존 프로젝트에서 부분 재구성(Partial Reconfiguration) 지원을 활성화하는 단계는 다음과 같습니다.

이 시점에서 프로젝트 구현을 시도하면 대부분 다음과 같은 오류로 실패합니다. "[DRC HDPR-30] Missing PBLOCK On Reconfigurable Cell: HD.RECONFIGURABLE cell 'pr_block_ins' must have PBLOCK assigned to itself or its descendant cells". 쉽게 말하면 플로어플래닝(floorplanning)이 필요하다는 뜻입니다.

플로어플래닝(floorplanning)

이 시점에서 프로젝트는 플로어플래닝(floorplanning) 작업을 진행할 수 있을 만큼만 설정되어 있습니다.

이 작업을 작은 단계로 나누기 전에 몇 가지 유의할 점을 언급해 두겠습니다.

이제 단계별로 나누어 보겠습니다.

플로어플래닝 수정

부분 재구성(Partial Reconfiguration)에서 가장 달갑지 않은 부분이 아마 바로 이것일 것입니다. 플로어플래닝(floorplanning)을 정확하게 맞추는 일 말입니다. Remote Update(원격 업데이트) 용도로 작업하고 있다면 이 단계는 특히 중요합니다. 이 플로어플래닝이 프로젝트 수명 내내 그대로 유지되기 때문입니다.

플로어플래닝 수정이 필요한 이유는 크게 두 가지입니다. Critical Warning(치명적 경고)에 대응하기 위한 경우와, 나중 단계에서 FPGA 사용을 최적화하기 위한 경우입니다. 목표는 리소스 낭비를 줄이면서 동시에 배치 및 배선(place and route)에 장애물을 만들지 않는 것입니다.

수정 자체는 어렵지 않습니다. Pblock의 경계를 끌어서 조정하면 되니까요. 추가 사각형으로 Pblock을 확장하는 것도 쉽습니다. Pblock을 마우스 오른쪽 버튼으로 클릭하고 "Add Pblock Rectangle"을 선택하면 됩니다.

Critical Warning은 대개 어떤 수정이 필요한지 알려 줍니다. 그렇더라도 사용 중인 FPGA의 플로어플래닝 제약에 관한 Xilinx 사용자 가이드 UG909의 해당 장(6, 7 또는 8장)을 반드시 읽어 두어야 합니다.

이 절의 나머지 부분에서는 series-7 FPGA에서 발생할 수 있는 문제를 다룹니다. Ultrascale FPGA는 작업하기가 훨씬 쉽습니다.

series-7 FPGA에서 흔한 오류 중 하나는 인터커넥트 타일 컬럼(interconnect tile column)이 분할되는 것입니다. 예를 들면 다음과 같습니다.

[Constraints 18-993] The Pblock pblock_pr_block_ins has defined an area that causes the splitting of interconnect tile columns. Dynamic Function eXchange requires that the left and right paired interconnect tile columns cannot be split by a reconfigurable boundary.  This is caused by either the left or right edge of a Pblock boundary, or by the Pblock spanning over logic types not included in the Pblock ranges.  To avoid an unroutable situation, placement will be prohibited from both of these columns. To avoid placement restrictions, modify the Pblock to avoid splitting the two columns.
The column of the split contains interconnect tile INT_L_X48Y299  (SLICE_X79Y299 SLICE_X78Y299).
Please refer to the Xilinx document on Dynamic Function eXchange.
Resolution: Set the Pblock property SNAPPING_MODE to value of ON, or modify the column/X specification of the pblock to avoid this edge.

그리고

[Constraints 18-996] The split between the left and right columns occurs between a reconfigurable Pblock and Static logic. The static sites are not reconfigurable. The Pblock should be adjusted to remove the column from the Pblock, unless the excluded reconfigurable and static sites are not needed for the design. Note that adjusting the Pblock will prevent prohibits and improve placement of the design, but may reduce the routability if the removed sites were needed to span across the static logic. Failure to modify the Pblock may lead to an unplaceable design if these prohibited sites are required by the design. Resolution: Set the Pblock property SNAPPING_MODE to value of ON, or modify the column/X specification of the pblock to avoid this edge. and

이 문제를 해결하려면 첫 번째 경고에서 제안한 대로 Pblock의 SNAPPING_MODE 속성을 ROUTING 또는 ON으로 설정하세요. 아마 ROUTING만으로는 충분하지 않을 가능성이 높으므로 ON을 선택하세요. 이렇게 하면 XDC 파일에 다음과 같은 종류의 제약 조건이 많이 추가될 것입니다.

set_property PROHIBIT true [get_sites SLICE_X79Y349]
set_property PROHIBIT true [get_sites SLICE_X78Y349]
[ ... ]
set_property PROHIBIT true [get_sites SLICE_X79Y191]
set_property PROHIBIT true [get_sites SLICE_X78Y191]
set_property PROHIBIT true [get_sites PMV_X0Y2]
set_property PROHIBIT true [get_sites SLICE_X36Y190]
set_property PROHIBIT true [get_sites SLICE_X37Y190]
[ ... ]
set_property PROHIBIT true [get_sites SLICE_X79Y176]
set_property PROHIBIT true [get_sites SLICE_X78Y176]
set_property PROHIBIT true [get_sites T14]
set_property PROHIBIT true [get_sites R15]
set_property PROHIBIT true [get_sites XADC_X0Y0]
set_property PROHIBIT true [get_sites SLICE_X36Y175]
set_property PROHIBIT true [get_sites SLICE_X37Y175]
[ ... ]

그리고 이런 줄이 계속 이어집니다.

슬라이스(slice) 사이트에 대한 PROHIBIT 설정은 앞서 언급한 Critical Warning을 잠재우는 역할을 합니다. 나머지 PROHIBIT 지정은 기하학적 영역에는 포함되지만, 사용 중인 FPGA에서 부분 재구성(Partial Reconfiguration)이 허용되지 않는 로직 사이트에 대해 추가됩니다. Ultrascale FPGA 이상에서는 PROHIBIT 줄이 아예 없거나 훨씬 적게 생성됩니다.

단순히 Critical Warning을 잠재우는 것이 목적이라면, PROHIBIT가 있는 줄을 모두 제거하고 슬라이스(slice)에 대한 줄 하나만 남겨도 괜찮습니다. Vivado가 SNAPPING_MODE 변경에 대응하여 추가한 슬라이스 범위를 하나로 합치면 됩니다. 그 범위를 다음과 같은 형태로 바꾸는 것입니다.

set_property PROHIBIT true [get_sites -range {SLICE_X79Y0 SLICE_X79Y349}]

이런 형태의 줄은 XDC 파일을 방대하게 만들지 않으면서 인터커넥트 분할 문제를 해결할 수 있는 방법입니다.

어쨌든 다음과 같은 줄도 XDC 파일에 나타날 수 있습니다. 이 줄을 제거해도 문제없는 것으로 보입니다.

set_property HD.PLATFORM_WRAPPER true [get_cells pr_block_ins]

XDC 파일을 Critical Warning이 발생하지 않는 최소한의 내용으로 줄이는 것이 다소 피상적으로 보일 수 있습니다. 그러나 그 대안은 나중에 혼란을 부르는 거대한 제약 파일입니다. 제 경험상 이러한 종류의 경고가 없다는 것은 설계의 플로어플랜이 괜찮다는 승인으로 받아들여도 됩니다.

SNAPPING_MODE 속성을 다시 OFF로 되돌리면 XDC를 어떻게 바꿨든 문제가 다시 생길 가능성이 높습니다.

재구성 모듈 추가

지금까지의 구현은 사실상 몇 가지 제약이 추가된 계층적 설계(Hierarchical Design)와 같은 결과를 만듭니다. 부분 비트스트림(partial bitstream)이 생성되기는 하지만, 그것은 거의 쓸모가 없습니다. 로드해도 같은 설계가 유지될 뿐이기 때문입니다.

따라서 목표는 다른 재구성 모듈을 기반으로 하는 또 다른 부분 비트스트림을 만드는 것입니다. 그러려면 자식 구현(Child Implementation)을 추가해야 합니다.

이 글을 계속 읽기 전에 이전 글을 잘 기억해 두세요. 특히 부모 구현(Parent Implementation)과 자식 구현(Child Implementation), 그리고 Dynamic Function eXchange Wizard에 관한 부분이 중요합니다. 또한 이 글의 앞부분에서 설명했듯이, "Partition Definitions" 탭에는 현재 정의된 재구성 모듈과 해당 소스가 들어 있다는 점도 기억하세요.

Tools 메뉴에서 Dynamic Function eXchange Wizard를 열고 시작 창에서 Next를 클릭합니다.

"Edit Reconfigurable Modules" 창에서 "+"를 클릭합니다. 그러면 재구성 모듈을 추가하는 대화상자가 열립니다. 이 대화상자에서 신경 쓸 것은 Reconfigurable Module Name뿐입니다. 앞서 설명한 대로, 이 이름은 재구성 로직을 식별하는 데 사용됩니다.

대화상자에서는 이 모듈을 파티션 정의(partition definition) 이름과 연결하도록 요구합니다. 하지만 어차피 파티션 정의는 하나뿐입니다. 이 글은 파티션이 하나만 정의되어 있다고 가정하기 때문입니다.

계속하려면 Verilog/VHDL 소스 파일을 최소한 하나는 추가해야 합니다. 더 많은 파일은 나중에 "Partition Definitions" 탭에서 추가할 수 있습니다. 이 재구성 모듈의 최상위 모듈 이름을 명시해 두는 것도 나쁘지 않습니다. 특히 소스 파일만으로는 어떤 로직인지 분명하지 않은 경우에 유용합니다.

마법사로 돌아와 다시 Next를 클릭하여 "Edit Configurations" 창으로 갑니다. "+"를 클릭하고 구성(configuration) 이름을 입력합니다. 이 이름이 중요한 이유는 Design Runs 창에 표시되기 때문뿐입니다. config_2 같은 이름이면 충분합니다.

구성 목록에 새 행이 나타납니다. 파티션에 해당하는 열의 재구성 모듈을 변경하여, 각 구성이 서로 다른 재구성 모듈을 갖도록 하세요.

마지막 창은 Edit Configuration Runs로, 런(run)을 구성(configuration)에 할당하는 곳입니다. 쉬운 방법은 이 창에 나열된 모든 런(있다면)을 삭제하고 "automatically create configuration runs"를 클릭하는 것입니다. 그러면 수동으로 했을 작업을 자동으로 해 줍니다. 부모 런을 만들고 "impl_1"이라고 이름을 붙인 다음, 자식 런들을 만들고 원하는 이름을 붙이고, 그 자식 런들이 "impl_1"의 자식이 되도록 하는 것입니다.

마법사는 각 런에 대해 구성을 자동으로 선택하지만, 그것은 쉽게 바꿀 수 있습니다. 중요한 것은 부모 런에 어떤 구성이 연결되는지뿐입니다.

그리고 참고로, 마법사에서 모든 런을 삭제하면 모든 자식 런이 사라지지만 impl_1은 남아 있습니다.

마지막으로: 설계 구현

비트스트림을 생성하려면 평소처럼 Vivado에서 "Generate Bitstreams"를 클릭하면 됩니다. 이전 글에서 이미 언급했듯이, 부분 재구성(Partial Reconfiguration) 프로젝트에서는 구성(configuration)마다 비트스트림이 두 개 또는 세 개 생성됩니다.

예를 들어 Ultrascale FPGA에서는 비트 파일(bit file)이 다음과 같이 생성될 수 있습니다.

모든 구현에 대해 동일한 수의 비트스트림 파일이 생성된다는 점에 유의하세요. 다시 말해 자식 구현(Child Implementation)에 대해서도 초기 비트스트림 파일이 생성됩니다. 따라서 자식 구현 중 하나의 초기 비트스트림으로 FPGA를 로드한 다음, 그 상태에서 계속 진행하는 것도 충분히 가능합니다.

PCIe 또는 USB 3.x를 통해 부분 비트스트림을 간단히 로드하는 방법은 이 페이지를 참조하세요.

어떤 구현에서도 Pblock이나 플로어플래닝(floorplanning)과 관련된 Critical Warning이 발생하거나 실패해서는 안 됩니다. 그러한 문제는 이미 해결되었기 때문입니다. 만약 이런 문제가 여전히 발생한다면, 앞서 설명한 대로 플로어플래닝을 수정해야 합니다.

때때로 "Generate Bitstream"을 클릭했는데 변경 사항이 자식 구현(child implementation)에만 있을 경우, Vivado가 "Bitstream generation has already completed and is up-to-date. Re-run anyway?"라고 응답할 수 있습니다. 다소 혼동스럽지만 "Yes"를 클릭하면 자식 구현이 제대로 실행됩니다. 자식 구현(Child Implementation)과 관련된 이 모든 것은 Vivado에 다소 부가적으로 붙은 기능에 가깝습니다. 그래서 구현 중 상태 표시줄에 "write_bitstream complete. Child running" 같은 문구가 표시되는 것입니다.

결과 검토

부분 재구성(Partial Reconfiguration)은 배치와 관련이 깊으므로, 구현된 설계를 검토해 보는 것이 좋습니다. 특정 구현을 열려면 "Open Implemented Design"을 마우스 오른쪽 버튼으로 클릭하고, 다시 표시되는 "Open Implemented Design" 메뉴 위에 커서를 올린 다음, 목록에서 열 구현을 선택하면 됩니다. 목록에 어떤 구현이 없다면 아마 이미 열려 있는 것입니다.

구현된 설계 뷰의 Netlist 창에서 재구성 로직의 최상위 행을 마우스 오른쪽 버튼으로 클릭하고 "Highlight Leaf cells"를 선택해 보세요. 그런 다음 정적 로직(static logic)에 대해서도 다른 색으로 같은 작업을 해 보세요.

같은 오른쪽 클릭 메뉴에는 "Show Connectivity"도 있습니다. 이 기능은 서로 연결된 로직 요소 사이에 직선의 흰색 선을 그립니다. FPGA의 실제 라우팅 경로는 당연히 다르므로, 이 선들이 플로어플래닝(floorplanning)의 어떤 영역을 가로지르는지는 의미가 없습니다. 그럼에도 연결 상태를 살펴보면 플로어플랜의 전체적인 구성이 도구를 얼마나 어렵게 만드는지 알아차리는 데 도움이 될 수 있습니다.

분명히 정적 로직(static logic)에 속하는 것처럼 보이는 일부 셀이 재구성 영역 안에 배치되거나, 그 반대의 경우도 상당히 정상적이고 문제없습니다. 주의해야 할 점은 어딘가에 혼잡이 있어 보이는 경우입니다. 로직이 전체적으로 또는 특정 영역에서 너무 빽빽하게 들어차 보인다면, 가능하다면 플로어플래닝(floorplanning)을 변경하여 완화할 수 있습니다.

또 하나 살펴볼 것은 파티션 핀(partition pin)의 위치입니다. 파티션 핀은 디바이스 뷰(Device view)에서 흰색 가로 막대로 표시됩니다. 다음과 같이 나타납니다(이미지를 클릭하면 확대됩니다).

Partition pins in Vivado's device view

이전 글에서 언급했듯이 파티션 핀(partition pin)은 재구성 파티션 안 어디에나 있을 수 있습니다. 그런데 파티션 핀이 파티션의 가장자리에서 멀리 떨어져 있다면, 부모 구현(Parent Implementation) 중에 라우터가 타이밍 문제로 어려움을 겪었다는 신호일 수 있습니다.

다음 Tcl 명령을 사용하면 파티션 핀의 좌표를 텍스트 목록으로 얻을 수도 있습니다. pr_block_ins를 실제 재구성 로직 셀의 이름으로 바꾸세요.

foreach s [get_pins -of [get_cells pr_block_ins]] { set partpin [get_pplocs -quiet -pins [get_pins $s]] ; puts "$s => $partpin"; }

파티션 핀(partition pin)의 좌표는 슬라이스(slice)가 아니라 CLB 그리드에 해당합니다. 표시된 그림에서 이 핀들은 "Cell pins"라고 불립니다.

셀의 핀 중 일부에 파티션 핀(partition pin)이 할당되지 않을 수도 있습니다. 이는 재구성 모듈의 포트 목록(및/또는 벡터의 폭)과 정적 로직 모듈이 그 모듈을 인스턴스화한 방식 사이에 불일치가 있을 때 발생합니다. 이러한 불일치는 Verilog에서 완전히 허용되지만, 결과가 바람직하지 않을 수 있습니다. 앞의 Tcl 명령을 실행하면 연결되지 않는 포트를 발견할 수 있습니다. 특히 이런 불일치가 의도된 것이 아닐 때 유용합니다.


이것으로 Vivado 프로젝트 설정에 대한 기술적 설명을 마칩니다. 다만 다음 글에서는 FPGA 설계의 중요한 한 측면을 다룹니다: 로직 교체가 안정적이고 원활하게 이루어지도록 보장하는 방법입니다.

이 페이지는 영어 원문을 기계 번역한 것입니다. 의문이 드는 부분이 있으면 원문을 참조하시기 바랍니다.
Copyright © 2021-2026. All rights reserved. (dcc38493)