{"id":3925,"date":"2021-06-23T13:25:51","date_gmt":"2021-06-23T13:25:51","guid":{"rendered":"https:\/\/imperix.com\/doc\/?p=3925"},"modified":"2025-12-23T08:48:30","modified_gmt":"2025-12-23T08:48:30","slug":"fpga-implementation-pll","status":"publish","type":"post","link":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll","title":{"rendered":"FPGA implementation of a PLL for grid synchronization"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 ez-toc-wrap-right-text counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\/#Overview-of-the-grid-synchronization-module\" >Overview of the grid synchronization module<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\/#FPGA-implementation-of-the-PLL-with-Model-Composer-Simulink\" >FPGA implementation of the PLL with Model Composer (Simulink)<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\/#Testbench-of-the-Model-Composer-implementation\" >Testbench of the Model Composer implementation<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\/#FPGA-implementation-of-the-PLL-with-Vitis-HLS-C\" >FPGA implementation of the PLL with Vitis HLS (C++)<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\/#Testbench-of-the-Vitis-HLS-implementation\" >Testbench of the Vitis HLS implementation<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\/#Precision-of-the-fixed-point-approach\" >Precision of the fixed-point approach<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\/#Usecase-example\" >Usecase example<\/a><\/li><\/ul><\/nav><\/div>\n\n<p>The operation of a<strong> grid-tied power converter<\/strong> (such as the <a href=\"https:\/\/imperix.com\/doc\/example\/three-phase-pv-inverter\">3-phases PV inverter<\/a>) requires that the control software implements a grid synchronization technique. One well-known approach consists in using a <strong>three-phase PLL<\/strong> to project the AC grid quantities into a synchronous rotating reference frame. The PLL algorithm is usually executed on the CPU of the controller, but it can be alternatively offloaded to the FPGA.<\/p>\n\n\n\n<p>Besides the obvious benefit of offloading the CPU, the execution of the synchronization algorithm on an FPGA also allows for a much shorter control latency, ultimately enabling full-FPGA ultra-fast control loops, as presented in <a href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-based-inverter-control\">FPGA-based inverter control<\/a>.<\/p>\n\n\n\n<p>This note will cover the implementation of a simple PLL-based grid synchronization algorithm that is suitable for being executed on the FPGA of the <a href=\"https:\/\/imperix.com\/products\/control\/rapid-prototyping-controller\/\">B-Box<\/a> and <a href=\"https:\/\/imperix.com\/products\/control\/inverter-control-board\/\">B-Board<\/a> controllers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-overview-of-the-grid-synchronization-module\"><span class=\"ez-toc-section\" id=\"Overview-of-the-grid-synchronization-module\"><\/span>Overview of the grid synchronization module<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The grid synchronization algorithm implemented in FPGA is based on a conventional <strong>DQ-PLL<\/strong>, similar to the CPU implementation presented in the <a href=\"https:\/\/imperix.com\/doc\/implementation\/synchronous-reference-frame-pll\">TN103<\/a>. The PLL consists of an <a href=\"https:\/\/imperix.com\/doc\/software\/abc-to-dq0\">abc-to-dq<\/a> transformation (used as a phase detector), a <a href=\"https:\/\/imperix.com\/doc\/implementation\/basic-pi-control\">PI regulator<\/a> (used as a low-pass filter), and a wrapping integrator (used as a voltage-controlled oscillator). The grid synchronization module also projects the measured grid current into the synchronously rotating reference frame, so the projected dq components can be used by the <a href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-based-dq-current-control\">FPGA-based dq current control<\/a> module.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"371\" height=\"181\" src=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/06\/grid_synchro_module_v3_100pc.png\" alt=\"Schematic of the FPGA-based grid synchronization module with DQ-PLL\" class=\"wp-image-10292\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/grid_synchro_module_v3_100pc.png 371w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/grid_synchro_module_v3_100pc-300x146.png 300w\" sizes=\"auto, (max-width: 371px) 100vw, 371px\" \/><figcaption class=\"wp-element-caption\">Schematic of the FPGA-based grid synchronization module with DQ-PLL<\/figcaption><\/figure>\n<\/div>\n\n\n<p>The following sections detail how to pack that algorithm into the FPGA IP shown below, using both High-Level Synthesis tools&nbsp;<a href=\"https:\/\/imperix.com\/doc\/help\/xilinx-vitis-hls\">Vitis HLS<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/imperix.com\/doc\/help\/xilinx-model-composer\">Model Composer<\/a>. That IP uses&nbsp;<em>AXI4-Stream<\/em>&nbsp;inputs and outputs to be compatible with other IPs developed on other pages, as well as with&nbsp;<a href=\"https:\/\/imperix.com\/doc\/implementation\/axi4-stream-ip-from-xilinx\">Xilinx IP cores for Vivado<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"308\" height=\"293\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2022\/01\/grid_sync-1.png\" alt=\"Generated IP of the grid synchronization module\" class=\"wp-image-10288\" style=\"width:264px;height:245px\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2022\/01\/grid_sync-1.png 308w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2022\/01\/grid_sync-1-300x285.png 300w\" sizes=\"auto, (max-width: 308px) 100vw, 308px\" \/><figcaption class=\"wp-element-caption\">Generated IP of the grid synchronization module<br><\/figcaption><\/figure>\n<\/div>\n\n\n<p>Further details on integrating that IP into the FPGA are presented on the&nbsp;<a href=\"https:\/\/imperix.com\/doc\/implementation\/high-level-synthesis-for-fpga\">High-Level Synthesis<\/a> page. A complete converter control algorithm that uses that IP is presented in <a href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-based-inverter-control\">FPGA-based converter control<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-simple-alerts-for-gutenberg-alert-boxes sab-alert sab-alert-dark\" role=\"alert\">To find all FPGA-related notes, you can visit\u00a0<a href=\"https:\/\/imperix.com\/doc\/help\/fpga-development-on-imperix-controllers\">FPGA development homepage<\/a>.<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-fpga-implementation-of-the-pll-with-model-composer-simulink\"><span class=\"ez-toc-section\" id=\"FPGA-implementation-of-the-PLL-with-Model-Composer-Simulink\"><\/span>FPGA implementation of the PLL with Model Composer (Simulink)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The sources of the grid synchronization module developed with Xilinx Model Composer can be downloaded below. To generate a Vivado IP from this model using Model Composer&#8217;s automatic code generation please refer to the <a href=\"https:\/\/imperix.com\/doc\/help\/xilinx-model-composer\">introduction to Model Composer<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-file aligncenter\"><a href=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/06\/TN143_FPGA_Grid_Sync_Model_Composer.zip\" class=\"wp-block-file__button wp-element-button\" download>Download <strong>TN143_FPGA_Grid_Sync_Model_Composer.zip<\/strong><\/a><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"559\" height=\"973\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-267.png\" alt=\"Grid synchronization module implemented with Model Composer\" class=\"wp-image-4094\" style=\"width:350px;height:610px\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-267.png 559w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-267-172x300.png 172w\" sizes=\"auto, (max-width: 559px) 100vw, 559px\" \/><figcaption class=\"wp-element-caption\">Top-level of the grid synchronization module<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Basically, this module includes two <strong>abc-to-dq0<\/strong> transformations and one <strong>PLL<\/strong>. The PI controller used within the PLL block is based on the implementation presented in the <a href=\"https:\/\/imperix.com\/doc\/help\/xilinx-model-composer\">Model Composer introduction<\/a>.<\/p>\n\n\n\n<p>The abc-to-dq0 transformation simply implements the mathematical formulae introduced in <a href=\"https:\/\/imperix.com\/doc\/software\/abc-to-dq0\">abc to dq0<\/a>. In both Vitis HLS and Model Composer, fixed-point types are used to represent the intermediary results. Specifically, all the angles (radians) are represented with <code>fix16_12<\/code> and the other quantities are represented with <code>fix32_16<\/code>. The main reason is that floating-point trigonometric functions are computationally heavy and cannot meet the timing requirement. As a side benefit, using fixed-point operations also improves the resource usage and latency of the other operations (multiplications and additions). Nevertheless, to ensure compatibility with other modules, the inputs and outputs of the coordinate transformations are converted into floating-point types.<\/p>\n\n\n\n<p>As seen later in the section &#8220;Precision of the fixed-point approach&#8221;, the loss of precision caused by the use of <code>fix16_12<\/code> numbers for representing angles is negligible in practice (lost in the noise), although small differences can be seen in simulation.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"742\" height=\"419\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2022\/05\/tn143_abc2dq0.png\" alt=\"abc-to-dq0 transformation implementation with Xilinx Model Composer\" class=\"wp-image-12196\" style=\"width:682px;height:385px\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2022\/05\/tn143_abc2dq0.png 742w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2022\/05\/tn143_abc2dq0-300x169.png 300w\" sizes=\"auto, (max-width: 742px) 100vw, 742px\" \/><figcaption class=\"wp-element-caption\">abc-to-dq0 transformation implementation with Model Composer<\/figcaption><\/figure>\n<\/div>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"894\" height=\"341\" src=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/06\/tn143_PLL.png\" alt=\"DQ-PLL implementation with Xilinx Model Composer\" class=\"wp-image-10338\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/tn143_PLL.png 894w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/tn143_PLL-300x114.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/tn143_PLL-768x293.png 768w\" sizes=\"auto, (max-width: 894px) 100vw, 894px\" \/><figcaption class=\"wp-element-caption\">PLL implementation with Model Composer<\/figcaption><\/figure>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"506\" height=\"232\" src=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/06\/tn143_PI.png\" alt=\"PI controller implementation with Xilinx Model Composer\" class=\"wp-image-10340\" style=\"width:486px;height:223px\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/tn143_PI.png 506w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/tn143_PI-300x138.png 300w\" sizes=\"auto, (max-width: 506px) 100vw, 506px\" \/><figcaption class=\"wp-element-caption\">PI controller implementation with Model Composer<\/figcaption><\/figure>\n<\/div>\n\n\n<div class=\"wp-block-simple-alerts-for-gutenberg-alert-boxes sab-alert sab-alert-info\" role=\"alert\">The fixed-point trigonometric functions in Vitis HLS (math library) are calculated using the CORDIC algorithm. For those interested, open <strong>&#8220;hls_math.h&#8221;<\/strong> to see how math functions are implemented in HLS, or look at <a href=\"https:\/\/www.xilinx.com\/html_docs\/xilinx2020_2\/vitis_doc\/vitis_hls_math_library.html\">Vitis HLS math library<\/a> for reference.<br>In Model Composer, there is no need to specify the data types or implementation methods, and the software will automatically call the HLS math library during code generation.<\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-testbench-of-the-model-composer-implementation\"><span class=\"ez-toc-section\" id=\"Testbench-of-the-Model-Composer-implementation\"><\/span>Testbench of the Model Composer implementation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>One main advantage of Model Composer over Vitis HLS is that test benches can be easily run directly from within Simulink. The testbench generates 50 Hz three-phase voltages and currents and passes them as inputs to the developed PLL. To test the frequency tracking of the PLL, the input frequency is stepped to 52 Hz at t=0.02s.<\/p>\n\n\n\n<p>Mathematically, the inputs of the testbench are:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Voltages<\/strong><\/td><td><strong>Currents<\/strong><\/td><td><strong>Time<\/strong><\/td><\/tr><tr><td>$$\\begin{aligned} &amp;U_{a}=311\\cdot\\sin(2\\pi f nT_{s}) \\\\ &amp;U_{b}=311\\cdot\\sin(2\\pi f nT_{s} &#8211; 2\\pi\/3) \\\\ &amp;U_{c}=311\\cdot\\sin(2\\pi f nT_{s} + 2\\pi\/3)\\end{aligned}$$<\/td><td>$$\\begin{aligned}&amp;I_{a}=5\\cdot\\sin(2\\pi f nT_{s}) \\\\ &amp;I_{b}=5\\cdot\\sin(2\\pi f nT_{s} &#8211; 2\\pi\/3) \\\\ &amp;I_{c}=5\\cdot\\sin(2\\pi f nT_{s} + 2\\pi\/3) \\end{aligned}$$<\/td><td>$$\\begin{aligned}&amp;n=0,1,2,\u2026,1999 \\\\ &amp;T_s=50\\,\\text{\u00b5s} \\\\ &amp;f=\\begin{cases}50 &amp; n\\leqslant 400 \\\\ 55 &amp; n&gt;400 \\end{cases} \\end{aligned} $$<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"338\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-281-1024x338.png\" alt=\"Testbench of the grid synchronization module developed with Xilinx Model Composer\" class=\"wp-image-4142\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-281-1024x338.png 1024w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-281-300x99.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-281-768x253.png 768w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-281-1536x507.png 1536w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/image-281.png 1710w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Testbench of the PLL developed with Xilinx Model Composer<\/figcaption><\/figure>\n<\/div>\n\n\n<p>After running the Simulink-based simulation, the inputs and outputs can be exported to the MATLAB workspace and plotted, as shown below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"300\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/xmc_theta_freq.png\" alt=\"Testbench results of the Model Composer implementation\" class=\"wp-image-4145\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/xmc_theta_freq.png 800w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/xmc_theta_freq-300x113.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/xmc_theta_freq-768x288.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Testbench results of the Model Composer implementation<\/figcaption><\/figure>\n<\/div>\n\n\n<p>The simulation results are identical to the Vitis HLS approach shown below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-fpga-implementation-of-the-pll-with-vitis-hls-c\"><span class=\"ez-toc-section\" id=\"FPGA-implementation-of-the-PLL-with-Vitis-HLS-C\"><\/span>FPGA implementation of the PLL with Vitis HLS (C++)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The full Vitis HLS implementation of the PLL can be downloaded below and the main lines of code are given for reference.<\/p>\n\n\n\n<div class=\"wp-block-file aligncenter\"><a href=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/06\/TN143_FPGA_Grid_Sync_Vitis_HLS.zip\" class=\"wp-block-file__button wp-element-button\" download>Download <strong>TN143_FPGA_Grid_Sync_Vitis_HLS.zip<\/strong><\/a><\/div>\n\n\n<style>.kt-accordion-id3925_53ccef-a4 .kt-accordion-inner-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:1px;}.kt-accordion-id3925_53ccef-a4 .kt-accordion-panel-inner{border-top-width:2px;border-right-width:2px;border-bottom-width:2px;border-left-width:2px;border-top-left-radius:2px;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:2px;background:#ffffff;padding-top:20px;padding-right:20px;padding-bottom:20px;padding-left:20px;}.kt-accordion-id3925_53ccef-a4 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top-color:#f2f2f2;border-right-color:#f2f2f2;border-bottom-color:#f2f2f2;border-left-color:#f2f2f2;border-top-width:2px;border-right-width:2px;border-bottom-width:2px;border-left-width:2px;border-top-left-radius:2px;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:2px;background:#ffffff;font-size:16px;line-height:24px;letter-spacing:0px;font-weight:bold;text-transform:none;color:var(--global-palette3, #1A202C);padding-top:12px;padding-right:10px;padding-bottom:8px;padding-left:16px;}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:before{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id3925_53ccef-a4 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id3925_53ccef-a4 .kt-blocks-accordion-header:focus-visible{color:#444444;background:#ffffff;border-top-color:#eeeeee;border-right-color:#eeeeee;border-bottom-color:#eeeeee;border-left-color:#eeeeee;}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion--visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger, body:not(.hide-focus-outline) .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id3925_53ccef-a4 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id3925_53ccef-a4 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{color:var(--global-palette3, #1A202C);background:var(--global-palette9, #ffffff);border-top-color:var(--global-palette6, #718096);border-right-color:var(--global-palette6, #718096);border-bottom-color:var(--global-palette6, #718096);border-left-color:var(--global-palette6, #718096);}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_53ccef-a4:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:var(--global-palette9, #ffffff);}@media all and (max-width: 767px){.kt-accordion-id3925_53ccef-a4 .kt-accordion-inner-wrap{display:block;}.kt-accordion-id3925_53ccef-a4 .kt-accordion-inner-wrap .kt-accordion-pane:not(:first-child){margin-top:1px;}}<\/style>\n<div class=\"wp-block-kadence-accordion alignnone\"><div class=\"kt-accordion-wrap kt-accordion-id3925_53ccef-a4 kt-accordion-has-3-panes kt-active-pane-0 kt-accordion-block kt-pane-header-alignment-left kt-accodion-icon-style-arrow kt-accodion-icon-side-left\" style=\"max-width:none\"><div class=\"kt-accordion-inner-wrap\" data-allow-multiple-open=\"false\" data-start-open=\"none\">\n<div class=\"wp-block-kadence-pane kt-accordion-pane kt-accordion-pane-1 kt-pane3925_6c82f3-78\"><div class=\"kt-accordion-header-wrap\"><button class=\"kt-blocks-accordion-header kt-acccordion-button-label-show\" type=\"button\"><span class=\"kt-blocks-accordion-title-wrap\"><span class=\"kt-blocks-accordion-title\">Grid synchronization C++ implementation with <strong><strong>Vitis HLS<\/strong><\/strong><\/span><\/span><span class=\"kt-blocks-accordion-icon-trigger\"><\/span><\/button><\/div><div class=\"kt-accordion-panel kt-accordion-panel-hidden\"><div class=\"kt-accordion-panel-inner\"><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"grid_sync.h\"<\/span><\/span>\n\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;hls_stream.h&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;stdint.h&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"ap_fixed.h\"<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"hls_math.h\"<\/span><\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">abc2dq0<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">float<\/span> A, <span class=\"hljs-keyword\">float<\/span> B, <span class=\"hljs-keyword\">float<\/span> C, <span class=\"hljs-keyword\">float<\/span> wt, <span class=\"hljs-keyword\">float<\/span>&amp; d, <span class=\"hljs-keyword\">float<\/span>&amp; q, <span class=\"hljs-keyword\">float<\/span>&amp; zero)<\/span>\n<\/span>{\n  <span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">pragma<\/span> HLS inline<\/span>\n\n  <span class=\"hljs-keyword\">const<\/span> ap_fixed&lt;<span class=\"hljs-number\">16<\/span>,<span class=\"hljs-number\">2<\/span>&gt; sqrt3_3 = <span class=\"hljs-number\">0.57733154296875<\/span>;\n\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; A_fix = (ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt;)A;\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; B_fix = (ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt;)B;\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; C_fix = (ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt;)C;\n  ap_fixed&lt;<span class=\"hljs-number\">16<\/span>,<span class=\"hljs-number\">4<\/span>&gt; wt_fix = (ap_fixed&lt;<span class=\"hljs-number\">16<\/span>,<span class=\"hljs-number\">4<\/span>&gt;)wt;\n\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; beta_fix = (B_fix-C_fix)*sqrt3_3;\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; zero_fix = (A_fix+B_fix+C_fix)\/<span class=\"hljs-number\">3<\/span>;\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; alpha_fix = A_fix-zero_fix;\n\n  ap_fixed&lt;<span class=\"hljs-number\">16<\/span>, <span class=\"hljs-number\">2<\/span>&gt; cos_wt = hls::<span class=\"hljs-built_in\">cos<\/span>(wt_fix);\n  ap_fixed&lt;<span class=\"hljs-number\">16<\/span>, <span class=\"hljs-number\">2<\/span>&gt; sin_wt = hls::<span class=\"hljs-built_in\">sin<\/span>(wt_fix);\n\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; d_fix = alpha_fix*cos_wt + beta_fix*sin_wt;\n  ap_fixed&lt;<span class=\"hljs-number\">32<\/span>,<span class=\"hljs-number\">16<\/span>&gt; q_fix = -alpha_fix*sin_wt + beta_fix*cos_wt;\n\n  d = (<span class=\"hljs-keyword\">float<\/span>)d_fix;\n  q = (<span class=\"hljs-keyword\">float<\/span>)q_fix;\n  zero = (<span class=\"hljs-keyword\">float<\/span>)zero_fix;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">pll<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">float<\/span> Ugq, <span class=\"hljs-keyword\">float<\/span> Ts, <span class=\"hljs-keyword\">float<\/span>&amp; theta, <span class=\"hljs-keyword\">float<\/span>&amp; freq)<\/span>\n<\/span>{\n  <span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">pragma<\/span> HLS inline<\/span>\n\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">float<\/span> theta_max = <span class=\"hljs-number\">6.283185307179586<\/span>;\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">float<\/span> theta_min = <span class=\"hljs-number\">0<\/span>;\n\n  <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">float<\/span> pll_accum = <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">pragma<\/span> HLS RESET variable=pll_accum<\/span>\n\n  <span class=\"hljs-keyword\">float<\/span> pll_kiTs = pll_ki*Ts;\n  pll_accum += pll_kiTs* Ugq;\n  <span class=\"hljs-keyword\">float<\/span> pi_out = pll_kp * Ugq + pll_accum;\n  <span class=\"hljs-keyword\">float<\/span> w = pi_out + w0;\n\n  <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">float<\/span> wrapping_accum = <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">pragma<\/span> HLS RESET variable=wrapping_accum<\/span>\n\n  wrapping_accum += Ts * w;\n\n  <span class=\"hljs-keyword\">if<\/span>(wrapping_accum &gt; theta_max) {\n    wrapping_accum -= theta_max;\n  } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span>(wrapping_accum &lt; theta_min) {\n    wrapping_accum += theta_max;\n  }\n\n  theta = wrapping_accum;\n  freq = w;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">vitis_grid_sync<\/span><span class=\"hljs-params\">(\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Iga,\nhls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Igb,\nhvoid vitis_grid_sync(\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Iga,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Igb,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Igc,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Uga,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Ugb,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Ugc,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; in_Ts,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_Igd,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_Igq,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_Ig0,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_Ugd,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_Ugq,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_Ug0,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_theta,\n  hls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt;&amp; out_freq)\n{\n  #pragma HLS INTERFACE axis port=in_Iga\n  #pragma HLS INTERFACE axis port=in_Igb\n  #pragma HLS INTERFACE axis port=in_Igc\n  #pragma HLS INTERFACE axis port=in_Uga\n  #pragma HLS INTERFACE axis port=in_Ugb\n  #pragma HLS INTERFACE axis port=in_Ugc\n  #pragma HLS INTERFACE axis port=in_Ts\n  #pragma HLS INTERFACE axis port=out_Igd\n  #pragma HLS INTERFACE axis port=out_Igq\n  #pragma HLS INTERFACE axis port=out_Ig0\n  #pragma HLS INTERFACE axis port=out_Ugd\n  #pragma HLS INTERFACE axis port=out_Ugq\n  #pragma HLS INTERFACE axis port=out_Ug0\n  #pragma HLS INTERFACE axis port=out_theta\n  #pragma HLS INTERFACE axis port=out_freq\n  #pragma HLS INTERFACE ap_ctrl_none port=<span class=\"hljs-keyword\">return<\/span>\n\n  <span class=\"hljs-keyword\">float<\/span> Iga = in_Iga.read();\n  <span class=\"hljs-keyword\">float<\/span> Igb = in_Igb.read();\n  <span class=\"hljs-keyword\">float<\/span> Igc = in_Igc.read();\n  <span class=\"hljs-keyword\">float<\/span> Uga = in_Uga.read();\n  <span class=\"hljs-keyword\">float<\/span> Ugb = in_Ugb.read();\n  <span class=\"hljs-keyword\">float<\/span> Ugc = in_Ugc.read();\n  <span class=\"hljs-keyword\">float<\/span> Ts = in_Ts.read();\n\n  <span class=\"hljs-keyword\">float<\/span> Igd,Igq,Ig0,Ugd,Ugq,Ug0,w;\n  <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">float<\/span> wt;\n  #pragma HLS RESET variable=wt\n\n  abc2dq0(Uga, Ugb, Ugc, wt, Ugd, Ugq, Ug0);\n  abc2dq0(Iga, Igb, Igc, wt, Igd, Igq, Ig0);\n  pll(Ugq, Ts, wt, w);\n\n  out_Igd.write(Igd);\n  out_Igq.write(Igq);\n  out_Ig0.write(Ig0);\n  out_Ugd.write(Ugd);\n  out_Ugq.write(Ugq);\n  out_Ug0.write(Ug0);\n  out_theta.write(wt);\n  out_freq.write(w);\n}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<p>The code is divided into the following functions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>void abc2dq0(float A, float B, float C, float wt, float&amp; d, float&amp; q, float&amp; zero)<\/code><br>Transforms the three-phase AC quantities <code>A<\/code>, <code>B<\/code>, <code>C<\/code> into <code>d<\/code>, <code>q<\/code>, <code>zero <\/code>components, using the reference frame angle <code>wt<\/code>.<\/li>\n\n\n\n<li><code>void pll(float Ugq, float Ts, float&amp; theta, float&amp; freq)<\/code><br>Runs a discrete PI controller (with discretization period <code>Ts<\/code>) using the alignment error <code>Ugq<\/code> and updates the output angle (<code>theta<\/code>, in rad) and frequency (<code>freq<\/code>, in rad\/s). The controller parameters <code>pll_kp<\/code> and <code>pll_ki<\/code>, as well as the central frequency <code>w0<\/code>, are defined in the <code>grid_sync.h<\/code> file.<\/li>\n\n\n\n<li><code>void vitis_grid_sync( ... )<\/code><br>Runs the PLL algorithm on the grid quantities <code>in_Igabc<\/code> and <code>in_Ugabc <\/code>to compute the grid angle (<code>out_theta<\/code>) and frequency (<code>out_freq<\/code>), as well as the components of the grid quantities in the dq synchronous reference frame.<\/li>\n<\/ul>\n\n\n\n<p>The <strong>wrapping integrator<\/strong> is implemented using the code below, to avoid the modulo-based wrapping used in the CPU version. Since this approach only uses switches and comparators, it is much better suited to an FPGA implementation than the resource-consuming modulo function.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">float<\/span> theta_max = <span class=\"hljs-number\">6.283185307179586<\/span>;\n<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">float<\/span> theta_min = <span class=\"hljs-number\">0<\/span>;\n\n<span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">float<\/span> wrapping_accum = <span class=\"hljs-number\">0<\/span>;\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">pragma<\/span> HLS RESET variable=wrapping_accum<\/span>\n\nwrapping_accum += Ts * w;\n\n<span class=\"hljs-keyword\">if<\/span>(wrapping_accum &gt; theta_max)\n{\n  wrapping_accum -= theta_max;\n}\n<span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span>(wrapping_accum &lt; theta_min)\n{\n  wrapping_accum += theta_max;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Note that the <code>vitis_grid_sync<\/code> method uses <em>AXI4-Stream<\/em> interfaces to be compatible with the other functions developed for the <a href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-based-inverter-control\">TN147<\/a>. More information about Vitis HLS can be found in the <a href=\"https:\/\/imperix.com\/doc\/help\/xilinx-vitis-hls\">introduction to Vitis HLS<\/a>, notably on how to create an IP out of the provided code to run the algorithm on the FPGA of a B-Box or B-Board controller.<\/p>\n\n\n\n<div class=\"wp-block-simple-alerts-for-gutenberg-alert-boxes sab-alert sab-alert-info\" role=\"alert\"><code>#pragma HLS inline<\/code> is a directive that removes a function as a separate entity in the hierarchy and enables optimization with surrounding operations. It&#8217;s recommended to use this directive when defining a child function in Vitis HLS. Look at <a href=\"https:\/\/www.xilinx.com\/html_docs\/xilinx2017_4\/sdaccel_doc\/jka1504034359550.html\">pragma HLS inline (xilinx.com)<\/a> to see more details.<\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-testbench-of-the-vitis-hls-implementation\"><span class=\"ez-toc-section\" id=\"Testbench-of-the-Vitis-HLS-implementation\"><\/span>Testbench of the Vitis HLS implementation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>To validate the Vitis HLS implementation, a testbench can be built using the code provided below.<\/p>\n\n\n<style>.kt-accordion-id3925_56c049-e2 .kt-accordion-inner-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:1px;}.kt-accordion-id3925_56c049-e2 .kt-accordion-panel-inner{border-top-width:2px;border-right-width:2px;border-bottom-width:2px;border-left-width:2px;border-top-left-radius:2px;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:2px;background:#ffffff;padding-top:20px;padding-right:20px;padding-bottom:20px;padding-left:20px;}.kt-accordion-id3925_56c049-e2 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top-color:#f2f2f2;border-right-color:#f2f2f2;border-bottom-color:#f2f2f2;border-left-color:#f2f2f2;border-top-width:2px;border-right-width:2px;border-bottom-width:2px;border-left-width:2px;border-top-left-radius:2px;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:2px;background:#ffffff;font-size:16px;line-height:24px;letter-spacing:0px;font-weight:bold;text-transform:none;color:var(--global-palette3, #1A202C);padding-top:12px;padding-right:10px;padding-bottom:8px;padding-left:16px;}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:before{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id3925_56c049-e2 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id3925_56c049-e2 .kt-blocks-accordion-header:focus-visible{color:#444444;background:#ffffff;border-top-color:#eeeeee;border-right-color:#eeeeee;border-bottom-color:#eeeeee;border-left-color:#eeeeee;}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion--visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger, body:not(.hide-focus-outline) .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id3925_56c049-e2 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id3925_56c049-e2 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{color:var(--global-palette3, #1A202C);background:var(--global-palette9, #ffffff);border-top-color:var(--global-palette6, #718096);border-right-color:var(--global-palette6, #718096);border-bottom-color:var(--global-palette6, #718096);border-left-color:var(--global-palette6, #718096);}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger{background:var(--global-palette3, #1A202C);}.kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id3925_56c049-e2:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:var(--global-palette9, #ffffff);}@media all and (max-width: 767px){.kt-accordion-id3925_56c049-e2 .kt-accordion-inner-wrap{display:block;}.kt-accordion-id3925_56c049-e2 .kt-accordion-inner-wrap .kt-accordion-pane:not(:first-child){margin-top:1px;}}<\/style>\n<div class=\"wp-block-kadence-accordion alignnone\"><div class=\"kt-accordion-wrap kt-accordion-id3925_56c049-e2 kt-accordion-has-3-panes kt-active-pane-0 kt-accordion-block kt-pane-header-alignment-left kt-accodion-icon-style-arrow kt-accodion-icon-side-left\" style=\"max-width:none\"><div class=\"kt-accordion-inner-wrap\" data-allow-multiple-open=\"false\" data-start-open=\"none\">\n<div class=\"wp-block-kadence-pane kt-accordion-pane kt-accordion-pane-1 kt-pane3925_4b1156-2e\"><div class=\"kt-accordion-header-wrap\"><button class=\"kt-blocks-accordion-header kt-acccordion-button-label-show\" type=\"button\"><span class=\"kt-blocks-accordion-title-wrap\"><span class=\"kt-blocks-accordion-title\"><strong>PLL<\/strong> testbench with <strong>Vitis HLS<\/strong><\/span><\/span><span class=\"kt-blocks-accordion-icon-trigger\"><\/span><\/button><\/div><div class=\"kt-accordion-panel kt-accordion-panel-hidden\"><div class=\"kt-accordion-panel-inner\"><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"grid_sync.h\"<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">\"math.h\"<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;hls_stream.h&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;stdint.h&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;stdio.h&gt;<\/span><\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">include<\/span> <span class=\"hljs-meta-string\">&lt;stdlib.h&gt;<\/span><\/span>\n\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">define<\/span> ITERATIONS 2000<\/span>\n<span class=\"hljs-meta\">#<span class=\"hljs-meta-keyword\">define<\/span> two_pi 6.283185307f<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\n<\/span>{\n\t<span class=\"hljs-comment\">\/* Test signals *\/<\/span>\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_in_Iga;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_in_Igb;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_in_Igc;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_in_Uga;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_in_Ugb;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_in_Ugc;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_in_Ts;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_Igd;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_Igq;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_Ig0;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_Ugd;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_Ugq;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_Ug0;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_theta;\n\thls::stream&lt;<span class=\"hljs-keyword\">float<\/span>&gt; tb_out_freq;\n\n\t<span class=\"hljs-comment\">\/* Test inputs*\/<\/span>\n\t<span class=\"hljs-keyword\">float<\/span> in_Iga;\n\t<span class=\"hljs-keyword\">float<\/span> in_Igb;\n\t<span class=\"hljs-keyword\">float<\/span> in_Igc;\n\t<span class=\"hljs-keyword\">float<\/span> in_Uga;\n\t<span class=\"hljs-keyword\">float<\/span> in_Ugb;\n\t<span class=\"hljs-keyword\">float<\/span> in_Ugc;\n\t<span class=\"hljs-keyword\">float<\/span> in_Ts = <span class=\"hljs-number\">0.00005<\/span>;\t\t<span class=\"hljs-comment\">\/\/ fs = 20kHz<\/span>\n\t<span class=\"hljs-keyword\">float<\/span> Ug_angle = <span class=\"hljs-number\">0<\/span>;\t\t<span class=\"hljs-comment\">\/\/ change to non-zero to see how pll converges<\/span>\n\t<span class=\"hljs-keyword\">float<\/span> Ig_angle = <span class=\"hljs-number\">0<\/span>;\n\t<span class=\"hljs-keyword\">float<\/span> freq_in = two_pi*<span class=\"hljs-number\">50<\/span>;\t<span class=\"hljs-comment\">\/\/ fgrid = 50Hz<\/span>\n\t<span class=\"hljs-keyword\">float<\/span> wt = freq_in*in_Ts;\n\n\t<span class=\"hljs-comment\">\/* Test outputs *\/<\/span>\n\t<span class=\"hljs-keyword\">float<\/span> out_Igd;\n\t<span class=\"hljs-keyword\">float<\/span> out_Igq;\n\t<span class=\"hljs-keyword\">float<\/span> out_Ugd;\n\t<span class=\"hljs-keyword\">float<\/span> out_Ugq;\n\t<span class=\"hljs-keyword\">float<\/span> out_theta;\n\t<span class=\"hljs-keyword\">float<\/span> out_freq;\n\n\t<span class=\"hljs-comment\">\/* Create csv file to store simulation data*\/<\/span>\n\tFILE *inputs, *outputs;\n\tinputs = fopen (<span class=\"hljs-string\">\"inputs.csv\"<\/span>, <span class=\"hljs-string\">\"w+\"<\/span>);\n\toutputs = fopen (<span class=\"hljs-string\">\"outputs.csv\"<\/span>, <span class=\"hljs-string\">\"w+\"<\/span>);\n\t<span class=\"hljs-built_in\">fprintf<\/span>(inputs, <span class=\"hljs-string\">\"%s\"<\/span>, <span class=\"hljs-string\">\"Uga,Ugb,Ugc,Iga,Igb,Igc\\n\"<\/span>);\n\t<span class=\"hljs-built_in\">fprintf<\/span>(outputs, <span class=\"hljs-string\">\"%s\"<\/span>, <span class=\"hljs-string\">\"Ugd,Ugq,Igd,Igq,theta,theta_in,freq,freq_in\\n\"<\/span>);\n\n\t<span class=\"hljs-comment\">\/* Run model *\/<\/span>\n\t<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; ITERATIONS; i++)\n\t{\n\t\tin_Uga = <span class=\"hljs-number\">311<\/span>*<span class=\"hljs-built_in\">cos<\/span>(Ug_angle);\n\t\tin_Ugb = <span class=\"hljs-number\">311<\/span>*<span class=\"hljs-built_in\">cos<\/span>(Ug_angle-two_pi\/<span class=\"hljs-number\">3<\/span>);\n\t\tin_Ugc = <span class=\"hljs-number\">311<\/span>*<span class=\"hljs-built_in\">cos<\/span>(Ug_angle+two_pi\/<span class=\"hljs-number\">3<\/span>);\n\t\tin_Iga = <span class=\"hljs-number\">5<\/span>*<span class=\"hljs-built_in\">cos<\/span>(Ig_angle);\n\t\tin_Igb = <span class=\"hljs-number\">5<\/span>*<span class=\"hljs-built_in\">cos<\/span>(Ig_angle-two_pi\/<span class=\"hljs-number\">3<\/span>);\n\t\tin_Igc = <span class=\"hljs-number\">5<\/span>*<span class=\"hljs-built_in\">cos<\/span>(Ig_angle+two_pi\/<span class=\"hljs-number\">3<\/span>);\n\n\t\ttb_in_Uga.write(in_Uga);\n\t\ttb_in_Ugb.write(in_Ugb);\n\t\ttb_in_Ugc.write(in_Ugc);\n\t\ttb_in_Iga.write(in_Iga);\n\t\ttb_in_Igb.write(in_Igb);\n\t\ttb_in_Igc.write(in_Igc);\n\t\ttb_in_Ts.write(in_Ts);\n\n\t\tvitis_grid_sync(tb_in_Iga,tb_in_Igb,tb_in_Igc,tb_in_Uga,tb_in_Ugb,tb_in_Ugc,tb_in_Ts,tb_out_Igd,tb_out_Igq,tb_out_Ig0,tb_out_Ugd,tb_out_Ugq,tb_out_Ug0,tb_out_theta,tb_out_freq);\n\n\t\tout_Igd = tb_out_Igd.read();\n\t\tout_Igq = tb_out_Igq.read();\n\t\tout_Ugd = tb_out_Ugd.read();\n\t\tout_Ugq = tb_out_Ugq.read();\n\t\tout_theta = tb_out_theta.read();\n\t\tout_freq = tb_out_freq.read();\n\n\t\t<span class=\"hljs-built_in\">fprintf<\/span>(inputs,<span class=\"hljs-string\">\"%f,%f,%f,%f,%f,%f %s\"<\/span>,in_Uga,in_Ugb,in_Ugc,in_Iga,in_Igb,in_Igc,<span class=\"hljs-string\">\"\\n\"<\/span>);\n\t\t<span class=\"hljs-built_in\">fprintf<\/span>(outputs,<span class=\"hljs-string\">\"%f,%f,%f,%f,%f,%f,%f,%f %s\"<\/span>,out_Ugd,out_Ugq,out_Igd,out_Igq,out_theta,Ug_angle,out_freq,freq_in,<span class=\"hljs-string\">\"\\n\"<\/span>);\n\n\t\t<span class=\"hljs-keyword\">if<\/span>(i&gt;<span class=\"hljs-number\">400<\/span>)freq_in = two_pi*<span class=\"hljs-number\">55<\/span>;\t<span class=\"hljs-comment\">\/\/ freq step at 0.02s<\/span>\n\t\twt = freq_in*in_Ts;\n\t\tUg_angle = remainder((Ug_angle+wt),two_pi);\n\t\tIg_angle = remainder((Ig_angle+wt),two_pi);\n\t}\n\n\tfclose(inputs);\n\tfclose(outputs);\n\n\t<span class=\"hljs-built_in\">printf<\/span>(<span class=\"hljs-string\">\"------ Test Passed ------\\n\"<\/span>);\n\n\t<span class=\"hljs-comment\">\/* End *\/<\/span>\n\t<span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0<\/span>;\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<p>Here, the exact same testbench as with Model Composer (same inputs) is implemented. The <em>C Simulation<\/em> tool of Vitis HLS is used to run the testbench. The input and output data are stored in &#8220;Vitis_grid_sync\\solution1\\csim\\build&#8221; and can be plotted for comparison (e.g. with MATLAB). The results are shown below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"300\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/vitis_theta_freq-4.png\" alt=\"Simulation results of the grid synchronization module\" class=\"wp-image-4144\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/vitis_theta_freq-4.png 800w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/vitis_theta_freq-4-300x113.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/vitis_theta_freq-4-768x288.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Testbench results from C simulation of Vitis HLS model<\/figcaption><\/figure>\n\n\n\n<p>The simulation results show that the angle and frequency estimated by the PLL follow the input accurately, although some noise with relatively low amplitude can be observed on the PLL frequency. This matter will be addressed in a dedicated section, and the performance will also be compared to the already validated CPU-based model provided with the imperix blockset.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-precision-of-the-fixed-point-approach\"><span class=\"ez-toc-section\" id=\"Precision-of-the-fixed-point-approach\"><\/span>Precision of the fixed-point approach<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>As introduced before, <code>fix16_12<\/code> fixed-point angles are used inside the coordinate transformation blocks since floating-point trigonometric functions cannot meet the timing requirements. This conversion to fixed-point inevitably results in a loss of precision, which can be seen as &#8220;noise&#8221; in the testbench results.<\/p>\n\n\n\n<p>For sake of validation, if the angle is represented with <code>fix32_28<\/code> instead of <code>fix16_12<\/code>,  all the visible estimation &#8220;noise&#8221; disappears completely, as illustrated below. Unfortunately, the implementation cannot meet the timing requirements if <code>fix32_28<\/code> is used.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"300\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/compare_noise_freq-2.png\" alt=\"Comparison of resolution with fixed point FPGA implementation\" class=\"wp-image-4146\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/compare_noise_freq-2.png 800w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/compare_noise_freq-2-300x113.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/compare_noise_freq-2-768x288.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Comparison of fixed-point representations with different resolutions used in Xilinx Model Composer (xmc).<br>A floating-point implementation (cpu) is also shown for reference.<\/figcaption><\/figure>\n\n\n\n<p>Representing angles with <code>fix16_12<\/code> numbers allows for an absolute angular resolution of \\(1\/2^{12}\\approx 0.00024 \\,\\text{rad}\\), which corresponds to a precision of 0.004%. As for the other variables, using <code>fix32_16<\/code> numbers gives an absolute resolution of \\(1\/2^{12}\\approx 15 \\,\\text{\u00b5V}\\) or \\(\\text{\u00b5A}\\).<\/p>\n\n\n\n<p>The simulation testbench results showed that the resulting error on the estimated frequency is at most 0.2%, which is considered acceptable in real systems, where the measurement accuracy is rather in the 1% range.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-usecase-example\"><span class=\"ez-toc-section\" id=\"Usecase-example\"><\/span>Usecase example<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The developed FPGA PLL is used for grid synchronization in the <a href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-based-inverter-control\">FPGA ctrl of a grid-tied 3-phase inverter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The operation of a grid-tied power converter (such as the 3-phases PV inverter) requires that the control software implements a grid synchronization technique. One well-known&#8230;<\/p>\n","protected":false},"author":10,"featured_media":10468,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[4],"tags":[17],"software-environments":[106],"provided-results":[107],"related-products":[31,32,92,166,110],"guidedreadings":[],"tutorials":[129],"user-manuals":[],"coauthors":[72],"class_list":["post-3925","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-implementation","tag-fpga-programming","software-environments-fpga","provided-results-simulation","related-products-b-board-pro","related-products-b-box-rcp","related-products-b-box-micro","related-products-b-box-rcp-3-0","related-products-tpi","tutorials-fpga-based-control-of-a-grid-tied-inverter"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>FPGA implementation of a PLL for grid synchronization - imperix<\/title>\n<meta name=\"description\" content=\"This page presents an implementation of an FPGA-based PLL for grid synchronization using Xilinx Model Composer or Vitis HLS.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"FPGA implementation of a PLL for grid synchronization - imperix\" \/>\n<meta property=\"og:description\" content=\"This page presents an implementation of an FPGA-based PLL for grid synchronization using Xilinx Model Composer or Vitis HLS.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll\" \/>\n<meta property=\"og:site_name\" content=\"imperix\" \/>\n<meta property=\"article:published_time\" content=\"2021-06-23T13:25:51+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-23T08:48:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/3_2_ratio_TN143.png\" \/>\n\t<meta property=\"og:image:width\" content=\"450\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Shu Wang\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Shu Wang\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll\"},\"author\":{\"name\":\"Shu Wang\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/person\\\/e57025902e777170f33a7afa4a74afb7\"},\"headline\":\"FPGA implementation of a PLL for grid synchronization\",\"datePublished\":\"2021-06-23T13:25:51+00:00\",\"dateModified\":\"2025-12-23T08:48:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll\"},\"wordCount\":1498,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/3_2_ratio_TN143.png\",\"keywords\":[\"FPGA programming\"],\"articleSection\":[\"Technical notes\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll\",\"name\":\"FPGA implementation of a PLL for grid synchronization - imperix\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/3_2_ratio_TN143.png\",\"datePublished\":\"2021-06-23T13:25:51+00:00\",\"dateModified\":\"2025-12-23T08:48:30+00:00\",\"description\":\"This page presents an implementation of an FPGA-based PLL for grid synchronization using Xilinx Model Composer or Vitis HLS.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#primaryimage\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/3_2_ratio_TN143.png\",\"contentUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/3_2_ratio_TN143.png\",\"width\":450,\"height\":300,\"caption\":\"FPGA-based PLL\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/fpga-implementation-pll#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Knowledge base\",\"item\":\"https:\\\/\\\/imperix.com\\\/doc\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Technical notes\",\"item\":\"https:\\\/\\\/imperix.com\\\/doc\\\/category\\\/implementation\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"FPGA implementation of a PLL for grid synchronization\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#website\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/\",\"name\":\"imperix\",\"description\":\"power electronics\",\"publisher\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/imperix.com\\\/doc\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#organization\",\"name\":\"imperix\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/imperix_logo.png\",\"contentUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/imperix_logo.png\",\"width\":350,\"height\":120,\"caption\":\"imperix\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/person\\\/e57025902e777170f33a7afa4a74afb7\",\"name\":\"Shu Wang\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8c5195ad4fcc5844061b0229a4e67ac2916756927bc646fb6f6ff3dfb1bba140?s=96&d=mm&r=g4b86f01b045719d1dd14babc666c16ba\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8c5195ad4fcc5844061b0229a4e67ac2916756927bc646fb6f6ff3dfb1bba140?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8c5195ad4fcc5844061b0229a4e67ac2916756927bc646fb6f6ff3dfb1bba140?s=96&d=mm&r=g\",\"caption\":\"Shu Wang\"},\"description\":\"Shu is an experienced development engineer at imperix. He authored or co-authored numerous articles on the knowledge base, notably on FPGA-based control implementation and high-level synthesis tools and techniques.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/shu-wang-6581221b9\\\/\"],\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/author\\\/wang\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"FPGA implementation of a PLL for grid synchronization - imperix","description":"This page presents an implementation of an FPGA-based PLL for grid synchronization using Xilinx Model Composer or Vitis HLS.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll","og_locale":"en_US","og_type":"article","og_title":"FPGA implementation of a PLL for grid synchronization - imperix","og_description":"This page presents an implementation of an FPGA-based PLL for grid synchronization using Xilinx Model Composer or Vitis HLS.","og_url":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll","og_site_name":"imperix","article_published_time":"2021-06-23T13:25:51+00:00","article_modified_time":"2025-12-23T08:48:30+00:00","og_image":[{"width":450,"height":300,"url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/3_2_ratio_TN143.png","type":"image\/png"}],"author":"Shu Wang","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Shu Wang","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#article","isPartOf":{"@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll"},"author":{"name":"Shu Wang","@id":"https:\/\/imperix.com\/doc\/#\/schema\/person\/e57025902e777170f33a7afa4a74afb7"},"headline":"FPGA implementation of a PLL for grid synchronization","datePublished":"2021-06-23T13:25:51+00:00","dateModified":"2025-12-23T08:48:30+00:00","mainEntityOfPage":{"@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll"},"wordCount":1498,"commentCount":0,"publisher":{"@id":"https:\/\/imperix.com\/doc\/#organization"},"image":{"@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#primaryimage"},"thumbnailUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/3_2_ratio_TN143.png","keywords":["FPGA programming"],"articleSection":["Technical notes"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#respond"]}]},{"@type":"WebPage","@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll","url":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll","name":"FPGA implementation of a PLL for grid synchronization - imperix","isPartOf":{"@id":"https:\/\/imperix.com\/doc\/#website"},"primaryImageOfPage":{"@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#primaryimage"},"image":{"@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#primaryimage"},"thumbnailUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/3_2_ratio_TN143.png","datePublished":"2021-06-23T13:25:51+00:00","dateModified":"2025-12-23T08:48:30+00:00","description":"This page presents an implementation of an FPGA-based PLL for grid synchronization using Xilinx Model Composer or Vitis HLS.","breadcrumb":{"@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#primaryimage","url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/3_2_ratio_TN143.png","contentUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/3_2_ratio_TN143.png","width":450,"height":300,"caption":"FPGA-based PLL"},{"@type":"BreadcrumbList","@id":"https:\/\/imperix.com\/doc\/implementation\/fpga-implementation-pll#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Knowledge base","item":"https:\/\/imperix.com\/doc\/"},{"@type":"ListItem","position":2,"name":"Technical notes","item":"https:\/\/imperix.com\/doc\/category\/implementation"},{"@type":"ListItem","position":3,"name":"FPGA implementation of a PLL for grid synchronization"}]},{"@type":"WebSite","@id":"https:\/\/imperix.com\/doc\/#website","url":"https:\/\/imperix.com\/doc\/","name":"imperix","description":"power electronics","publisher":{"@id":"https:\/\/imperix.com\/doc\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/imperix.com\/doc\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/imperix.com\/doc\/#organization","name":"imperix","url":"https:\/\/imperix.com\/doc\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/imperix.com\/doc\/#\/schema\/logo\/image\/","url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/imperix_logo.png","contentUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/imperix_logo.png","width":350,"height":120,"caption":"imperix"},"image":{"@id":"https:\/\/imperix.com\/doc\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/imperix.com\/doc\/#\/schema\/person\/e57025902e777170f33a7afa4a74afb7","name":"Shu Wang","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/8c5195ad4fcc5844061b0229a4e67ac2916756927bc646fb6f6ff3dfb1bba140?s=96&d=mm&r=g4b86f01b045719d1dd14babc666c16ba","url":"https:\/\/secure.gravatar.com\/avatar\/8c5195ad4fcc5844061b0229a4e67ac2916756927bc646fb6f6ff3dfb1bba140?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8c5195ad4fcc5844061b0229a4e67ac2916756927bc646fb6f6ff3dfb1bba140?s=96&d=mm&r=g","caption":"Shu Wang"},"description":"Shu is an experienced development engineer at imperix. He authored or co-authored numerous articles on the knowledge base, notably on FPGA-based control implementation and high-level synthesis tools and techniques.","sameAs":["https:\/\/www.linkedin.com\/in\/shu-wang-6581221b9\/"],"url":"https:\/\/imperix.com\/doc\/author\/wang"}]}},"_links":{"self":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/3925","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/comments?post=3925"}],"version-history":[{"count":131,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/3925\/revisions"}],"predecessor-version":[{"id":39390,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/3925\/revisions\/39390"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/media\/10468"}],"wp:attachment":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/media?parent=3925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/categories?post=3925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/tags?post=3925"},{"taxonomy":"software-environments","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/software-environments?post=3925"},{"taxonomy":"provided-results","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/provided-results?post=3925"},{"taxonomy":"related-products","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/related-products?post=3925"},{"taxonomy":"guidedreadings","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/guidedreadings?post=3925"},{"taxonomy":"tutorials","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/tutorials?post=3925"},{"taxonomy":"user-manuals","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/user-manuals?post=3925"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/coauthors?post=3925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}