이것은 Xilinx의 Vivado와 함께 Partial Reconfiguration또는 Dynamic Function eXchange (DFX)에 대한 4개의 시리즈 중 마지막 게시물입니다. 주로 Remote Update 시나리오에서 Partial Reconfiguration을 사용하려는 사람들을 위한 것입니다. 이 게시물은 이전 3편을 이미 읽었다는 가정 하에 작성되었습니다.
소개
일반적으로 Partial Reconfiguration 에 대해 논의한 다음 이 목적을 위한 Vivado의 일반적인 절차에 대해 논의한 후 이 게시물은 FPGA의 logic의 Remote Update 에 이 기술을 사용하기 위한 기초를 설정합니다.
이 사용 시나리오의 주요 문제는 partial bitstream이 아마도 몇 년 전에 생성된 initial bitstream 와 호환되어야 한다는 것입니다. 따라서 원래 Parent Implementation은 reconfigurable logic의 implementation 동안 사용 가능해야 하며, 그렇지 않으면 정확히 동일한 결과, 즉 정확히 동일한 place and route를 생성하기 위해 재생성되어야 합니다.
Parent Implementation을 다시 실행하지 않도록 전체 Vivado 프로젝트를 그대로 유지하는 것이 가능할 수 있습니다. 이 implementation을 반복하면 정확히 같은 결과를 얻을 수도 있습니다. 그러나 이 두 가지 방법 중 하나를 기반으로 향후 partial bitstreams 출시 가능성을 보장하기는 어렵습니다.
이 문제에 대한 신뢰할 수 있는 솔루션이 있지만 작동 방식을 이해하려면 먼저 DCPs 및 OOCs에 익숙해져야 합니다. 두 주제에 대한 간략한 소개는 다음과 같습니다.
Design Checkpoint (DCP)
Vivado는 일반적으로 synth_1, impl_1 및 Out-of-Context module runs (OOCs)로 분류되는 추가 runs 로 명명되는 여러 Design runs덕분에 FPGA design의 implementation을 수행합니다.
이러한 각각의 run은 임시 "in-memory project"를 생성하고, design 파일을 로드하고, 속성과 속성을 설정하고, synthesis, placing, routing, bitstreams생성 및 기타 작업을 수행하는 Tcl 기능을 호출하는 Tcl script실행으로 구성됩니다.
이 in-memory project는 디스크에 파일을 생성하지 않으며 GUI에서 볼 수 있는 Vivado 프로젝트와 아무 관련이 없습니다. Tcl 명령으로 많은 순차 작업을 수행할 수 있는 메모리의 object 입니다.
implementation이 진행됨에 따라 Design CheckPoints (DCP) 파일이 디스크에 기록됩니다( Tcl의 write_checkpoint 명령 덕분에). DCP 파일의 내용은 in-memory project의 snapshot 입니다. 즉, 로드된 design 파일과 로드된 이후 프로젝트에서 수행된 작업을 반영하는 database 입니다.
예를 들어, synthesis run (보통 synth_1라고 함)는 모든 HDL 파일, constraint 파일 및 IP 파일을 로드한 다음 HDL 파일의 synthesis를 수행하기 위해 synth_design 라는 Tcl 명령을 사용할 수 있습니다. 결과는 이러한 모든 sources ( IPs포함)에서 하나의 큰 netlist 입니다. 그러나 netlist는 in-memory project의 일부로 메모리에 저장됩니다. 따라서 synthesis run의 Tcl script는 synthesis의 제품인 DCP 파일을 생성하기 위해 write_checkpoint 에 함수 호출을 합니다. 이것으로 synth_1 run을 마칩니다.
실제로 synth_1 에 의해 생성된 DCP는 일반적으로 XDC 파일의 constraints 도 포함하지만 netlist DCP 라고 합니다.
일반적으로 impl_1라고 하는 이후에 나오는 implementation run은 새 in-memory project를 만들고 이 netlist DCP를 다음 작업의 시작점으로 읽습니다. 이 run은 처리 단계(예: optimize design, place, physically optimize, route 등) 이후 프로젝트의 snapshot 인 여러 DCP 파일을 작성합니다.
synth_1을 포함한 모든 runs는 DCPs를 in-memory project에 로드할 수 있습니다. 이것은 그들이 일반적으로 하는 일입니다.
Out Of Context (OOC) Module Runs
Vivado에서 IPs는 일반적으로 GUI 도구를 통해 구성됩니다. 이 작업이 완료되면 script는 source files (주로 HDL 및 constraint 파일)를 생성하고 이에 대해 synthesis를 수행합니다. 그 결과 netlist DCP가 생성되고 메인 프로젝트의 synthesis run 및 implementation runs에 로드됩니다. 이렇게 하면 IPs 의 sources를 재생성하고 synthesis를 계속해서 수행할 필요가 없으므로 전체 프로젝트의 implementation이 완료되는 데 걸리는 시간이 줄어듭니다.
원시 제품( IP의 구성 정보, 일부 HDL 파일 또는 존재하는 모든 것)을 가져와서 netlist DCP로 변환하는 Vivado run을 Vivado용어로 Out-Of-Context run 라고 합니다. 이 용어는 Vivado와 관련해서만 사용되며 내가 아는 다른 용도는 없습니다. 사실 이름 선택이 좀 애매합니다.
이 netlist DCP는 일반적으로 Tcl 명령 read_ip덕분에 synthesis run 및 implementation runs에 의해 로드되며, 일반적으로 OOC run에 의해 생성된 DCP를 로드하는 것으로 요약됩니다.
Vivado는 또한 메인 프로젝트에서 HDL module을 선택할 수 있게 하고 synthesis가 OOC 로 수행되도록 요청합니다( Project Manager의 source tree 에서 source를 마우스 오른쪽 버튼으로 클릭하고 "Set as Out-of-Context for Synthesis…" 선택).
OOCs 의 단점은 synthesizer가 전체 design을 단일 프로젝트로 가져올 때 modules 의 경계를 넘어 특정 최적화를 수행할 수 있다는 것입니다. 따라서 OOCs 덕분에 개별 synthesis는 성능이 저하되고 리소스가 낭비될 수 있습니다.
Partial Reconfiguration이 있는OOCs 및 DCPs
source 파일이 reconfigurable module용 top-level 로 선택되면 Vivado는 이 module 및 해당 submodules의 synthesis 용 OOC run을 생성합니다. 이 run은 관련 implementation에서 사용하기 위해 netlist DCP를 생성합니다. 이것은 Parent Implementation 와 Child Implementations에 해당됩니다. reconfigurable module은 항상 별도의 DCP로 표시됩니다.
그러나 이 netlist DCP는 Parent Implementation 와 Child Implementations에서 다르게 사용됩니다. Parent Implementation 에 할당된 netlist DCP는 일반 implementation의 IP 와 마찬가지로 synth_1 와 impl_1에 의해 로드됩니다. Partial Reconfiguration이 관련되어 있다는 사실은 대부분 floorplanning에 의해 부과되는 placement constraints를 통해 이 프로세스에 영향을 미칩니다.
반면 Child Implementation에는 전용 synthesis 위상이 없습니다. 오히려 reconfigurable module의 netlist DCP 와 Parent Implementation 의 최종 DCP를 혼합합니다(즉, place and route이후의 DCP ). 보다 정확하게는 Child Implementation은 Parent Implementation의 최종 DCP를 가져와 reconfigurable logic의 일부를 제거하고 대신 자체 reconfigurable module의 netlist DCP를 삽입합니다. 속을 채운 호박이나 그런 종류의 것을 만들기 위해 야채의 중간 부분을 제거하는 것과 약간 비슷합니다.
이제 이것을 Tcl 명령으로 나눌 때입니다.
Parent-Child implementations의 너트와 볼트
implementation이 내부에서 어떻게 작동하는지 찾는 곳은 프로젝트 이름( .tcl 접미사 포함)이 있는 Tcl 파일에 있습니다. 이 파일은 implementation의 파일이 생성된 디렉토리와 동일합니다.
특히 child implementation 용 implementation script가 흥미롭다. 관련 사용자 가이드 UG909의 3장("Vivado Software Flow")에서 직접적으로 언급하지 않더라도 script를 보여주고 설명하는 것은 우연이 아닙니다.
방금 언급했듯이 reconfigurable module의 netlist 에 대해 DPC 에 의존하고 floorplanning constraints가 적용된다는 점을 제외하고는 Parent의 implementation에 대해 그다지 특별한 것은 없습니다. hierarchical design와 거의 비슷합니다.
그러나 Parent Implementation은 다음과 같은 Tcl 명령 덕분에 하나가 아닌 두 개의 bitstreams를 씁니다.
write_bitstream -force -no_partial_bitfile theproject.bit write_bitstream -force -cell pr_block_ins pr_block_ins_lpf_partial.bit
그런 다음 나중에 Child Implementation에서 사용되는 DCP를 만듭니다.
update_design -cell pr_block_ins -black_box lock_design -level routing write_checkpoint -force theproject_postroute_physopt_bb.dcp
이 부분이 실행되는 동안 netlist DCPs를 로드하는 것으로 시작하여 place and route 및 기타 모든 최적화를 거친 in-memory project가 있음을 기억하십시오. 이 세 개의 Tcl 라인은 bitstream을 작성한 후 실행되므로 in-memory project는 정말 마지막 단계입니다.
지금이 구멍을 뚫고 호박 속을 채울 적기입니다. update_design 명령은 reconfigurable module을 black box로 바꿉니다. 즉, 모든 logic이 제거되어 다른 logic이 들어올 공간이 생깁니다.
그런 다음 design 의 place and route는 lock_design 명령에 의해 잠깁니다. 그 후 프로젝트의 snapshot이 theproject_postroute_physopt_bb.dcp에 기록됩니다. "bb"는 물론 "Black Box"를 나타냅니다.
Child Implementation의 script 에서 해당 부분은 다음과 같습니다.
create_project -in_memory -part xc7k325tffg900-2 set_property design_mode GateLvl [current_fileset] add_files -quiet .../impl_1/theproject_postroute_physopt_bb.dcp add_files -quiet .../two_synth_1/pr_block.dcp set_property SCOPED_TO_CELLS pr_block_ins [get_files .../bpf_synth_1/pr_block.dcp] link_design -top theproject -part xc7k325tffg900-2 -reconfig_partitions pr_block_ins opt_design write_checkpoint -force theproject_opt.dcp [ ... ]
그리고 이 시점부터 place and route 등으로 넘어갑니다.
위의 implementation script는 두 개의 소스만 사용하며 둘 다 DCPs입니다.
- place, route 및 잠금 후 static logic인theproject_postroute_physopt_bb.dcp.
- pr_block.dcp는 reconfigurable module의 netlist 입니다(즉, synthesis이후).
implementation이 계속되면 첫 번째 DCP가 잠겨 있다는 사실로 인해 static logic이 움직이지 않습니다. 그럼에도 불구하고 reconfigurable module의 place and route는 netlist DCP를 기반으로 평소와 같이 수행됩니다.
참고로 reconfigurable module에 속하는 XCI IPs가 있는 경우 위의 두 add_files 명령 사이에 각 IP에 대해 다음과 같은 행이 추가됩니다.
read_ip -quiet .../theproject.srcs/sources_1/ip/blkmem/blkmem.xci
이것은 Partial Reconfiguration에만 해당되는 것은 아니지만 모든 implementation에서 이런 방식으로 수행됩니다.
두 개의 bitstreams를 쓰기 직전에 Child Implementation은 얻은 routed design이 Parent Implementation의 static logic , 특히 place and route와 호환되는지 확인합니다.
이에 대한 Tcl 명령은 다음과 같습니다.
pr_verify -full_check -initial /path/to/impl_1/theproject_postroute_physopt.dcp -additional /path/to/child_1_impl_1/theproject_routed.dcp -file child_1_impl_1_pr_verify.log
이것은 in-memory project에 관계없이 두 개의 DCP 파일을 비교한다는 점에 유의하십시오. Parent Implementation의 routed DCP는 Child Implementation의 최종 DCP 와 비교됩니다. 이 비교의 출력은 *_pr_verify.log라는 파일로 이동합니다.
이 비교는 parent의 bitstream이 이미 FPGA에 로드되어 있을 때 로드될 수 있다는 점에서 partial bitstream이 호환됨을 보장합니다. static partition의 logic elements 와 routing을 거치게 됩니다.
pr_verify은 비호환성이 있는 경우 실패 상태로 반환됩니다. 이 경우 Vivado의 script 에 bitstreams가 생성되지 않습니다. 사용자 정의 implementation scripts를 작성할 때 이 단계를 염두에 두는 것이 중요합니다.
이 검증이 실패할 이유는 없지만, 실패할 경우 "ERROR: [Constraints 18-891] HDPRVerify-08: design check point .../impl_1/theproject_postroute_physopt.dcp places instance ... at site SLICE_X118Y125, yet design check point .../impl_2/theproject_routed.dcp does not. Both check point must have the same static placement result"와 같은 많은 오류와 함께 bitstream generation이 실패합니다.
이러한 오류 메시지는 아마도 100의 한계에 도달한 다음 침묵하게 될 것입니다.
Remote Update 시나리오를 위한 솔루션
위에서 언급한 문제는 reconfigurable logic 의 implementation이 Child Implementation로 수행될 때 원래 Parent Implementation 의 결과를 사용할 수 있어야 한다는 것입니다.
brute-force 솔루션은 전체 Vivado 프로젝트 디렉토리의 사본을 그것이 의존할 수 있는 모든 파일과 함께 만드는 것입니다. 새 partial bitstream을 생성해야 하는 경우 모든 파일을 복원하고 Parent Implementation을 최신 상태로 유지하고 Child Implementation 전용 bitstream을 생성합니다. 이 방법은 기술적으로 괜찮지만 장기적으로 보면 성가실 수 있습니다. 이 방법을 선택하면 원본 Parent Implementation의 DCP 파일에 대해 pr_verify을 수동으로 실행해야 합니다. 이 방법은 Parent Implementation에서 의도하지 않은 변경을 감지하지 못하기 때문입니다.
위에서 설명한 것처럼 두 개의 DCP 파일을 통해 Parent Implementation 와 Child Implementations가 상호 작용하는 방식에 대한 지식을 기반으로 하는 두 가지 다른 대안이 있습니다. 이 두 가지 대안의 명백한 이점은 무엇을 하고 있는지 알 수 있다는 것입니다.
두 대안의 원리는 partial bitstream이 initial bitstream와 함께 생성된 두 개의 DCP 파일에 의존하도록 하는 것입니다. 이 파일을 Golden DCPs라고 합니다.
첫 번째 대안은 partial bitstream 의 implementation을 non-project flow와 함께 Tcl script 로 실행하는 것입니다. 본질적으로 이것은 Vivado가 Child Implementation을 위해 생성한 script를 실행하지만 Golden DCPs를 사용하도록 수정하는 것을 의미합니다. 보다 정확하게는 link_design 명령과 pr_verify 명령의 인수를 수정하여 Golden DCPs에 의존하도록 합니다.
이 대안의 주요 단점은 non-project flow 와 함께 Tcl script를 실행하는 것이 Vivado의 GUI와 잘 통합되지 않아 메시지를 처리하고 검토를 위해 implemented design을 여는 등의 작업이 훨씬 더 어려워진다는 것입니다.
Golden DCPs hack
이상적으로는 Child Implementation run에 대해 Vivado 에 의해 생성된 script를 자동으로 수정할 수 있으므로 Golden DCPs와 관련될 것입니다. 불행히도 그렇게 할 수있는 신뢰할 수있는 방법이없는 것 같습니다.
그러나 Vivado는 implementation의 특정 단계 전후에 실행을 위해 Tcl scripts를 정의할 수 있습니다. 이러한 scripts는 implementation run의 script에서 실행되므로 run의 script 자체를 변경하는 데 사용할 수 없습니다.
그럼에도 불구하고 이것은 두 번째 대안인 다소 추한 방법을 위해 열립니다. 아이디어는 Parent Implementation 의 DCPs를 Golden DCPs로 덮어쓰는 것입니다. 이렇게 하면 Child Implementation이 정상적으로 실행되지만 Parent Implementation이 생성한 내용에 관계없이 Golden DCPs에 의존합니다.
이 방법의 장점은 Vivado 의 일반적인 작업 습관이 변경되지 않은 상태로 유지된다는 것입니다. reconfigurable logic이 변경되고 Vivado가 reconfigurable module의 synthesis 에 대해 OOC를 다시 실행한 다음 partial bitstream을 생성하기 위해 Child Implementation을 다시 실행합니다. static logic에서 변경 사항이 없으므로 Vivado는 관련 runs를 시작할 이유가 없습니다.
이 Golden DPC 복사 방법을 구현하는 Tcl script는
if { [catch {
set parentimpldir "[ file normalize "../impl_1"]"
set goldendir "[ file normalize "/path/to/golden"]"
file copy -force "[file normalize "$goldendir/theproject_postroute_physopt_bb.dcp"]" "$parentimpldir/"
file copy -force "[file normalize "$goldendir/theproject_postroute_physopt.dcp"]" "$parentimpldir/"
} errmsg ] } {
send_msg_id golden-reconfig-1 error "Failed to copy golden parent reconfiguration file(s): $errmsg"
return -code error
}
이 script는 Parent Implementation이 Child Implementation 디렉토리에 인접한 "impl_1" 디렉토리에 보관되어 있고(대부분 그럴 가능성이 높음) 두 Golden DCPs가 이 script의 3행에 정의된 디렉토리에 저장되어 있다고 가정합니다.
Design Runs 탭에서 child run (예: child_0_impl_1)를 마우스 오른쪽 버튼으로 클릭하고 "Change Run Settings…"를 선택한 다음 열리는 dialog 에서 Design Initialization 용 tcl.pre (init_design)를 script로 설정합니다. 또는 Tcl에서 script가 golden_pr.tcl로 저장된 경우:
add_files -fileset utils_1 -norecurse /path/to/golden_pr.tcl set_property STEPS.INIT_DESIGN.TCL.PRE [ get_files /path/to/golden_pr.tcl -of [get_fileset utils_1] ] [get_runs child_0_impl_1]
이 script를 사용할 때 명심해야 할 중요한 점은 Parent Implementation와 관련하여 Vivado가 제공하는 모든 정보와 이를 대신하여 생성된 모든 파일을 무시하는 것입니다. Vivado는 Implemented Design GUI를 열고 보고서를 표시할 수 있지만 이 모든 것이 완전히 관련이 없을 수 있습니다. 그래서 이것은 약간의 혼란을 야기합니다.
두 번째 가능한 성가심은 Vivado가 프로젝트 설정 또는 constraints 파일의 변경에 대한 응답으로 때때로 Parent Implementation을 실행할 수 있다는 것입니다. Design Runs 탭에서 관련 행을 마우스 오른쪽 버튼으로 클릭하고 "Force Up-to-Date"를 선택하면 이 문제를 해결할 수 있습니다. 이 메뉴는 run이 Out-of-Date 상태에 있을 때만 나타납니다. 즉, 완료되었지만 Vivado가 새로 고침이 필요하다고 판단합니다. 관련 Tcl 명령은 예를 들어
set_property needs_refresh false [get_runs synth_1]
Golden DCPs와 함께 저장할 파일
분명히 Golden DCPs는 미래에 호환 가능한 bitstream 파일을 생성할 수 있는 기능을 유지하기 위해 안전한 장소에 보관해야 합니다. 이와 함께 빠른 재개를 위해 전체 Vivado 프로젝트를 .tar.gz / .zip 파일로 압축하는 것이 좋습니다. 또는 project archive는 File > Project > Archive… 또는 이와 유사한 것으로 생성할 수 있습니다.
archive_project /path/to/theproject.xpr.zip -force -include_local_ip_cache -include_config_settings
그러나 프로젝트 파일과 Vivado 프로젝트의 다른 파일 모두에 absolute paths가 포함될 수 있으므로 다른 디렉터리나 다른 컴퓨터에 프로젝트를 배포하면 예상대로 작동하지 않을 수 있습니다. 이는 아카이브에서도 마찬가지입니다.
어떤 Vivado 버전이 사용되는지는 가능한 모든 보고서 파일과 .xpr 프로젝트 파일에 작성되지만 메모해 두어도 문제가 없습니다. 소프트웨어 업그레이드가 중요한 이유가 명확하지 않더라도 해당 버전의 Vivado에 대한 실행 가능한 복사본을 보유할 수 있습니다. 한 Vivado 버전의 Golden DCPs를 다른 버전의 reconfigurable logic의 netlist DCP 와 혼합하면 아마 정상적으로 작동할 것입니다. 그러나 이것은 Vivado가 계획한 것이 아닙니다.
요약하자면 최소 파일 세트는 다음과 같습니다.
- Golden DCPs: theproject_postroute_physopt_bb.dcp 및 theproject_postroute_physopt.dcp
- initial bitstream 파일, 예: theproject.bit (이것은 FPGA를 로드하는 데 사용되므로 이 파일을 저장하는 것이 분명합니다)
- Parent Implementation구축을 위한 소스.
- Ultrascale FPGAs 전용( Ultrascale+제외): initial bitstream와 관련된 clearing bitstream .
Ultrascale FPGAs 에서 clearing bitstream을 사용하는 것은 이미 FPGA에 있는 logic 와 관련이 있습니다. 그렇기 때문에 initial bitstream 와 관련된 clearing bitstream을 저장해야 합니다. 또한 initial bitstream이 일부 Child Implementation의 결과인 경우 해당 implementation 의 clearing bitstream을 저장해야 합니다.
Parent Implementation의 sources를 저장하는 것은 static logic 와 reconfigurable logic간의 연결을 결정하기 때문에 중요합니다. 예를 들어, sources가 편집되고 port가 reconfigurable logic 에 추가되고 이 port가 instantiation로 나타나면 partition pins 의 집합이 변경됩니다. 따라서 reconfigurable logic 의 netlist 에는 원래 static design에 나타나지 않는 외부 pins가 있습니다.
이러한 불일치가 발생하면 "ERROR: [Netlist 29-77] Could not replace (cell 'pr_block_bb', library 'work_pr_block_ins_pr_block_ins_4', file 'NOFILE') with (cell 'pr_block', library 'work', file 'pr_block.edf') because of a port interface mismatch; in strict mode, no extra ports are allowed. 8 ports are missing on the original cell. 5 of the missing ports are: 'thingy[7]' 'thingy[6]' 'thingy[5]' 'thingy[1]' 'thingy[0]'"와 같은 오류 메시지와 함께 child implementation이 실패합니다.
이 경우 실제로 실패하는 것은 static logic 와 combinatorial logic을 함께 붙이는 link_design 명령(위 참조)입니다.
이 문제를 피하는 간단하고 분명한 방법은 design의 static 부분을 변경하지 않고 reconfigurable logic의 port list 도 변경하지 않는 것입니다.
그러나 실제로 프로젝트의 static 부분을 변경하는 것은 괜찮습니다. 동일하게 유지되어야 하는 것은 reconfigurable module 의 instantiation 뿐입니다. implementation이 마지막에 검증을 포함하여 원활하게 진행되는 한 문제는 없습니다.
요약
Partial Reconfiguration의 Remote Update 사용에 대한 완전히 매끄러운 솔루션은 없지만 그럼에도 불구하고 이 목표를 달성하기 위한 몇 가지 사용 가능한 전략이 있습니다.
중요한 점은 원칙적으로 2개의 Golden DCPs 만 있으면 기존 프로젝트에 대한 partial bitstream을 구축하고 검증할 수 있다는 것입니다.
그리고 여기에 제시된 전략이 얼마나 파격적으로 보일지 모르지만 pr_verify 에서 수행한 검증은 이미 시행 중인 partial bitstream 와 static logic 간의 호환성에 대한 포괄적인 검사라는 점을 명심하십시오. 이 검증에 올바른 Golden DCP를 사용하고 테스트를 통과하는 한 걱정할 것이 없습니다. 또한 Child Implementation이 timing constraints를 달성한다는 점은 물론이지만 design의 모든 implementation 에 해당합니다.