{"id":1544,"date":"2021-04-02T12:27:41","date_gmt":"2021-04-02T12:27:41","guid":{"rendered":"https:\/\/imperix.com\/doc\/?p=1544"},"modified":"2025-05-07T12:03:12","modified_gmt":"2025-05-07T12:03:12","slug":"hysteresis-current-control","status":"publish","type":"post","link":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control","title":{"rendered":"FPGA-based hysteresis current controller for three-phase inverter"},"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\/hysteresis-current-control\/#Software-resources\" >Software resources<\/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\/hysteresis-current-control\/#Implementation-of-the-hysteresis-current-control\" >Implementation of the hysteresis current control<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control\/#FPGA-logic-of-the-hysteresis-controller\" >FPGA logic of the hysteresis controller<\/a><\/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\/hysteresis-current-control\/#CPU-implementation-using-the-imperix-blockset-for-Simulink\" >CPU implementation (using the imperix blockset for Simulink)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control\/#Experimental-results-and-validation-of-the-hysteresis-current-control\" >Experimental results and validation of the hysteresis current control<\/a><\/li><\/ul><\/nav><\/div>\n\n<p>This technical note provides an example of how a fast hysteresis current controller can be implemented, leveraging the possibility of <a href=\"https:\/\/imperix.com\/software\/fpga-programming\/\">editing the FPGA firmware<\/a> for rapid control prototyping applications.<\/p>\n\n\n\n<p>This example implements the direct current control of a three-phase passive load. It relies on manually-generated VHDL code. The automated generation of VHDL code is presented in <a href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-based-hysteresis-controller-hdl-coder\">TN121<\/a>, which addresses the same application from Simulink and using <a href=\"https:\/\/imperix.com\/doc\/help\/matlab-hdl-coder\">Matlab HDL Coder<\/a>.<\/p>\n\n\n\n<p>Instructions on how to set up the FPGA development toolchain for <a href=\"https:\/\/imperix.com\/products\/control\/\">imperix controllers<\/a> are given in the dedicated note <a href=\"https:\/\/imperix.com\/doc\/help\/vivado-design-suite-installation\">PN168<\/a>. Quick-start recommendations regarding FPGA firmware customization can also be found in the&nbsp;<a href=\"https:\/\/imperix.com\/doc\/help\/getting-started-with-fpga-control-development\">getting started with FPGA 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-software-resources\"><span class=\"ez-toc-section\" id=\"Software-resources\"><\/span>Software resources<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/04\/dcc_simulink.slx\">hysteresis_current_control_simulink<\/a><a href=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/04\/dcc_simulink.slx\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/04\/dcc_vivado_project.zip\">hysteresis_current_control_FPGA_vivado_project<\/a><a href=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/04\/dcc_vivado_project.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p>The first file is the Simulink model used to generate the CPU code, and the second file contains a Vivado project that implements the FPGA logic described below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-implementation-of-the-hysteresis-current-control\"><span class=\"ez-toc-section\" id=\"Implementation-of-the-hysteresis-current-control\"><\/span>Implementation of the hysteresis current control<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>This implementation stems from the following choices:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The current references are generated inside the CPU at a 40 kHz interval.<\/li><li>The measured 3-phase currents are sampled at 400 kHz.<\/li><li>The hysteresis control is implemented inside the programmable logic area (FPGA) by comparing the &#8220;fast&#8221; measured currents (400 kHz) with the &#8220;slow&#8221; generated references (40 kHz).<\/li><li>The hysteresis comparators are 2-level comparators.<\/li><li>The PWM output states are directly derived from the comparator state (see logic below).<\/li><li>A counter prevents the PWM output from switching excessively rapidly between states (state change limiter). This ensures that the switching frequency of each phase is kept below a defined threshold.<\/li><\/ul>\n\n\n\n<p>Both CPU and FPGA tasks are illustrated below. The current references and the tolerance values are computed in the CPU and transferred to the FPGA with <a href=\"https:\/\/imperix.com\/doc\/software\/sbo-sandbox-output-towards-fpga\">SBO blocks<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/FPGA_SCHEMA-2.png\" alt=\"Hysteresis current control implementation diagram\" class=\"wp-image-2109\" width=\"542\" height=\"221\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/FPGA_SCHEMA-2.png 703w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/FPGA_SCHEMA-2-300x122.png 300w\" sizes=\"auto, (max-width: 542px) 100vw, 542px\" \/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-fpga-logic-of-the-hysteresis-controller\"><span class=\"ez-toc-section\" id=\"FPGA-logic-of-the-hysteresis-controller\"><\/span>FPGA logic of the hysteresis controller<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The following control logic is implemented in VHDL. Details on how to edit the firmware of the B-Box RCP are given in <a href=\"https:\/\/imperix.com\/doc\/help\/editing-the-fpga-firmware-using-the-sandbox\">PN116<\/a>.<\/p>\n\n\n<style>.kt-accordion-id_227b28-fa .kt-accordion-inner-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:1px;}.kt-accordion-id_227b28-fa .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-id_227b28-fa > .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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa > .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-id_227b28-fa .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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id_227b28-fa > .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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa: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-id_227b28-fa .kt-accordion-inner-wrap{display:block;}.kt-accordion-id_227b28-fa .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-wrap kt-accordion-id_227b28-fa kt-accordion-has-2-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-pane_5e6a79-e0\"><div class=\"kt-accordion-header-wrap\"><button class=\"kt-blocks-accordion-header kt-acccordion-button-label-show\"><span class=\"kt-blocks-accordion-title-wrap\"><span class=\"kt-blocks-accordion-title\"><strong><strong>Source code of dcc.vhd<\/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=\"VHDL\" data-shcb-language-slug=\"vhdl\"><span><code class=\"hljs language-vhdl\"><span class=\"hljs-keyword\">library<\/span> IEEE;\n<span class=\"hljs-keyword\">use<\/span> IEEE.STD_LOGIC_1164.<span class=\"hljs-keyword\">ALL<\/span>;\n<span class=\"hljs-keyword\">use<\/span> IEEE.NUMERIC_STD.<span class=\"hljs-keyword\">ALL<\/span>;\n \n<span class=\"hljs-keyword\">entity<\/span> DirectCurrentControl <span class=\"hljs-keyword\">is<\/span>\n    <span class=\"hljs-keyword\">Port<\/span> (\n        <span class=\"hljs-comment\">-- Measure<\/span>\n        meas_in : <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n        <span class=\"hljs-comment\">-- Reference<\/span>\n        ref_in : <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n        <span class=\"hljs-comment\">-- Tolerence<\/span>\n        tol_in  : <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n        <span class=\"hljs-comment\">-- Delay<\/span>\n        delay_in  : <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n        <span class=\"hljs-comment\">-- Error = Measure - Reference<\/span>\n        err_out  : <span class=\"hljs-keyword\">out<\/span> <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>);\n \n        <span class=\"hljs-comment\">-- Timing pulses<\/span>\n        adc_done_pulse_in : <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">std_logic<\/span>;\n        data_valid_pulse_in : <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">std_logic<\/span>;\n \n        <span class=\"hljs-comment\">-- PWM output<\/span>\n        pwm_out : <span class=\"hljs-keyword\">out<\/span> <span class=\"hljs-built_in\">std_logic<\/span>;\n \n        <span class=\"hljs-comment\">-- Main clock running at 250 MHz<\/span>\n        clk_in : <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-built_in\">std_logic<\/span>\n    );\n<span class=\"hljs-keyword\">end<\/span> DirectCurrentControl;\n \n<span class=\"hljs-keyword\">architecture<\/span> impl <span class=\"hljs-keyword\">of<\/span> DirectCurrentControl <span class=\"hljs-keyword\">is<\/span>\n \n    <span class=\"hljs-keyword\">ATTRIBUTE<\/span> X_INTERFACE_INFO : <span class=\"hljs-built_in\">STRING<\/span>;\n    <span class=\"hljs-keyword\">ATTRIBUTE<\/span> X_INTERFACE_INFO <span class=\"hljs-keyword\">of<\/span> clk_in: <span class=\"hljs-keyword\">SIGNAL<\/span> <span class=\"hljs-keyword\">is<\/span> <span class=\"hljs-string\">\"xilinx.com:signal:clock:1.0 clk CLK\"<\/span>;\n \n    <span class=\"hljs-keyword\">signal<\/span> meas_ff1 : <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n    <span class=\"hljs-keyword\">signal<\/span> ref_ff1 : <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n    <span class=\"hljs-keyword\">signal<\/span> ref_ff2 : <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n    <span class=\"hljs-keyword\">signal<\/span> tol_ff1 : <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n    <span class=\"hljs-keyword\">signal<\/span> tol_ff2 : <span class=\"hljs-built_in\">std_logic_vector<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n \n    <span class=\"hljs-keyword\">signal<\/span> counter_reg : <span class=\"hljs-built_in\">unsigned<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>) := (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n \n    <span class=\"hljs-keyword\">signal<\/span> err : <span class=\"hljs-built_in\">signed<\/span>(<span class=\"hljs-number\">15<\/span> <span class=\"hljs-keyword\">downto<\/span> <span class=\"hljs-number\">0<\/span>);\n \n    <span class=\"hljs-keyword\">type<\/span> type_fsm_state <span class=\"hljs-keyword\">is<\/span> (STATE_HIGH, STATE_LOW, STATE_H2L, STATE_L2H);\n    <span class=\"hljs-keyword\">signal<\/span> fsm_state : type_fsm_state := STATE_LOW;\n \n<span class=\"hljs-keyword\">begin<\/span>\n \n    INPUT : <span class=\"hljs-keyword\">process<\/span>(clk_in)\n    <span class=\"hljs-keyword\">begin<\/span>\n        <span class=\"hljs-keyword\">if<\/span> rising_edge(clk_in) <span class=\"hljs-keyword\">then<\/span>\n \n            <span class=\"hljs-comment\">-- new SBO data are available<\/span>\n            <span class=\"hljs-keyword\">if<\/span> data_valid_pulse_in = <span class=\"hljs-string\">'1'<\/span> <span class=\"hljs-keyword\">then<\/span>\n                ref_ff1 &lt;= ref_in;\n                tol_ff1 &lt;= tol_in;\n            <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n \n            <span class=\"hljs-comment\">-- new measure is available<\/span>\n            <span class=\"hljs-keyword\">if<\/span> adc_done_pulse_in = <span class=\"hljs-string\">'1'<\/span> <span class=\"hljs-keyword\">then<\/span>\n                meas_ff1 &lt;= meas_in;\n                ref_ff2 &lt;= ref_ff1;\n                tol_ff2 &lt;= tol_ff1;\n            <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n \n        <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n    <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">process<\/span> INPUT;\n \n    err &lt;= <span class=\"hljs-built_in\">signed<\/span>(meas_ff1) - <span class=\"hljs-built_in\">signed<\/span>(ref_ff2);\n    err_out &lt;= <span class=\"hljs-built_in\">std_logic_vector<\/span>(err);\n \n    HYSTERESIS : <span class=\"hljs-keyword\">process<\/span>(clk_in)\n    <span class=\"hljs-keyword\">begin<\/span>\n        <span class=\"hljs-keyword\">if<\/span> rising_edge(clk_in) <span class=\"hljs-keyword\">then<\/span>\n \n            <span class=\"hljs-keyword\">case<\/span> fsm_state <span class=\"hljs-keyword\">is<\/span>\n \n                <span class=\"hljs-keyword\">when<\/span> STATE_HIGH =&gt;\n                    pwm_out &lt;= <span class=\"hljs-string\">'0'<\/span>;\n                    counter_reg &lt;= (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n                    <span class=\"hljs-keyword\">if<\/span> err &lt; -<span class=\"hljs-built_in\">signed<\/span>(tol_ff2) <span class=\"hljs-keyword\">then<\/span>\n                        fsm_state &lt;= STATE_H2L;\n                    <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n \n                <span class=\"hljs-keyword\">when<\/span> STATE_H2L =&gt;\n                    pwm_out &lt;= <span class=\"hljs-string\">'1'<\/span>;\n                    counter_reg &lt;= counter_reg + <span class=\"hljs-number\">1<\/span>;\n                    <span class=\"hljs-keyword\">if<\/span> counter_reg &gt;= <span class=\"hljs-built_in\">unsigned<\/span>(delay_in) <span class=\"hljs-keyword\">then<\/span>\n                        fsm_state &lt;= STATE_LOW;\n                    <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n \n                <span class=\"hljs-keyword\">when<\/span> STATE_LOW =&gt;\n                    pwm_out &lt;= <span class=\"hljs-string\">'1'<\/span>;\n                    counter_reg &lt;= (<span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-string\">'0'<\/span>);\n                    <span class=\"hljs-keyword\">if<\/span> err &gt; <span class=\"hljs-built_in\">signed<\/span>(tol_ff2) <span class=\"hljs-keyword\">then<\/span>\n                        fsm_state &lt;= STATE_L2H;\n                    <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n \n                <span class=\"hljs-keyword\">when<\/span> STATE_L2H =&gt;\n                    pwm_out &lt;= <span class=\"hljs-string\">'0'<\/span>;\n                    counter_reg &lt;= counter_reg + <span class=\"hljs-number\">1<\/span>;\n                    <span class=\"hljs-keyword\">if<\/span> counter_reg &gt;= <span class=\"hljs-built_in\">unsigned<\/span>(delay_in) <span class=\"hljs-keyword\">then<\/span>\n                        fsm_state &lt;= STATE_HIGH;\n                    <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n \n                <span class=\"hljs-keyword\">when<\/span> <span class=\"hljs-keyword\">others<\/span> =&gt; <span class=\"hljs-keyword\">null<\/span>;\n        <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">case<\/span>;\n \n      <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">if<\/span>;\n    <span class=\"hljs-keyword\">end<\/span> <span class=\"hljs-keyword\">process<\/span> HYSTERESIS;\n \n<span class=\"hljs-keyword\">end<\/span> impl;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">VHDL<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">vhdl<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<p>The resulting logic is illustrated in the figure below. The current error is simply obtained by comparing the current reference with the actual measurement. Subsequently, as basic state machine controls the state transitions of the <code>pwm_out<\/code> signal, enforcing a minimum delay to limit the converter switching frequency.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-108.png\" alt=\"FPGA logic of the hysteresis controller\" class=\"wp-image-2077\" width=\"800\" title=\"Technical notes &gt; TN120: FPGA-based hysteresis current control &gt; f7f5e9b3-d279-4c6c-81ca-1f26d5c9a6b5.png\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-108.png 886w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-108-300x145.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-108-768x372.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/figure><\/div>\n\n\n\n<p>This subsystem is instantiated three times, one for each phase. Connections are made as shown in the next figure:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>meas_in<\/code> are connected to <code>ADC_reg_00<\/code>, <code>ADC_reg_01<\/code> and <code>ADC_reg_02<\/code><\/li><li><code>ref_in<\/code> are connected to <code>SBO_reg_00<\/code>, <code>SBO_reg_01<\/code>and <code>SB0_reg_02<\/code><\/li><li><code>tol_in<\/code> are connected to <code>SBO_reg_03<\/code><\/li><li><code>delay_in<\/code> are connected to <code>SBO_reg_04<\/code><\/li><li><code>err_out<\/code> are connected to a <code>SBI_reg_00<\/code>, <code>SBI_reg_01<\/code> and <code>SBI_02<\/code><\/li><li><code>pwm_out<\/code> are connected to <code>sb_pwm[0]<\/code>, <code>sb_pwm[2]<\/code> and <code>sb_pwm[4]<br><\/code><\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1001\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-107-1024x1001.png\" alt=\"Interface between the hysteresis current controllers and imperix IP\" class=\"wp-image-2076\" title=\"Technical notes &gt; TN120: FPGA-based hysteresis current control &gt; dcc_vivado_block_diagram.png\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-107-1024x1001.png 1024w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-107-300x293.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-107-768x751.png 768w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-107-1536x1502.png 1536w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-107.png 1726w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-cpu-implementation-using-the-imperix-blockset-for-simulink\"><span class=\"ez-toc-section\" id=\"CPU-implementation-using-the-imperix-blockset-for-Simulink\"><\/span>CPU implementation (using the imperix blockset for Simulink)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The following configuration is used:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>CLOCK_0 (main clock, controlling the sampling frequency): 400 kHz<\/li><li>Interrupt postscaler: 5 (i.e. control interrupt executed at 40 kHz)<\/li><li>SBO registers 00 to 02: current references (real-time registers)<\/li><li>SBO register 03: hysteresis tolerance (real-time register)<\/li><li>SBO register 04: state counter period (configuration register)<\/li><li>SBI registers (read from FPGA) 00 to 02: current errors (for monitoring purpose only)<\/li><li>SB_PWM: PWM channels 0 to 2 configured with dual outputs with a 1 us dead time<\/li><li>State change limiter: maximum switching frequency: 40 kHz (i.e. H2L and L2H states have a counter period of 3125. Counter period is 4 ns)<\/li><\/ul>\n\n\n\n<p>The CPU code is generated automatically from Simulink, using the following model:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"468\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-106-1024x468.png\" alt=\"CPU code implementation using Simulink\" class=\"wp-image-2075\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-106-1024x468.png 1024w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-106-300x137.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-106-768x351.png 768w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-106.png 1533w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The PWM output configuration is the following. Further information on sandbox PWM configuration is available on the <a href=\"https:\/\/imperix.com\/doc\/implementation\/fpga-pwm-modulator\">custom FPGA PWM<\/a> page.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"533\" height=\"679\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-99.png\" alt=\"Configuration dialog of the Sandbox PWM outputs\" class=\"wp-image-2067\" title=\"Technical notes &gt; TN120: FPGA-based hysteresis current control &gt; Block Parameters_ PWM_SB.png\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-99.png 533w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-99-235x300.png 235w\" sizes=\"auto, (max-width: 533px) 100vw, 533px\" \/><\/figure><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/06\/TN147_deadtime.png\" alt=\"\"\/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>This model generates 3-phase current references with a user-defined amplitude and a frequency of 50Hz. These references are then converted into <code>unsigned int16<\/code> format to match the format of the FPGA registers. The conversion from Amperes to bits or inversely is done with the following operations. It considers the sensitivity of the current sensors and an input voltage range of \u00b110V with 16 bits ADCs. The intermediate conversion to <code>int16<\/code> ensures that the signed float number is coded or interpreted correctly in 2&#8217;s complement.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-97-1024x192.png\" alt=\"Data type conversion for CPU to FPGA transfer\" class=\"wp-image-2065\" width=\"702\" height=\"131\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-97-1024x192.png 1024w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-97-300x56.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-97-768x144.png 768w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-97-1536x289.png 1536w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-97.png 1650w\" sizes=\"auto, (max-width: 702px) 100vw, 702px\" \/><figcaption>Data type conversion for CPU to FPGA transfer<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-98-1024x192.png\" alt=\"Data type conversion for FPGA to CPU transfer\" class=\"wp-image-2066\" width=\"702\" title=\"Technical notes &gt; TN120: FPGA-based hysteresis current control &gt; bit2float.png\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-98-1024x192.png 1024w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-98-300x56.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-98-768x144.png 768w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-98-1536x289.png 1536w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-98.png 1650w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>Data type conversion for FPGA to CPU transfer<\/figcaption><\/figure><\/div>\n\n\n\n<p>All probe variables are used for monitoring and debug purposes only.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-experimental-results-and-validation-of-the-hysteresis-current-control\"><span class=\"ez-toc-section\" id=\"Experimental-results-and-validation-of-the-hysteresis-current-control\"><\/span>Experimental results and validation of the hysteresis current control<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The subsequent results consider the following parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>V<sub>DC<\/sub> = 70 V<\/li><li>L<sub>load<\/sub> = 5 mH<\/li><li>R<sub>load<\/sub> = 8 Ohm<\/li><\/ul>\n\n\n\n<p>The resulting current waveforms are shown below, for a current reference of 4 A peak and a hysteresis tolerance of \u00b10.3 A and \u00b10.1 A :<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"519\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-95-1024x519.png\" alt=\"Experimental results of the hysteresis current controller\" class=\"wp-image-2063\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-95-1024x519.png 1024w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-95-300x152.png 300w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-95-768x389.png 768w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-95-1536x778.png 1536w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/image-95-2048x1037.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>It can be clearly seen that reducing the hysteresis tolerance reduces the current ripples but increases the switching frequency. It also appears that the current error is not kept fully within the hysteresis band. This is unavoidable in digital implementations, for the following 2 reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>A finite sampling frequency implies a maximum delay of Ts. In the present implementation, this corresponds to an additional current error of at most 1.5*V<sub>DC<\/sub>*T<sub>s<\/sub>\/L<sub>load<\/sub> = 50 mA<\/li><li>The ADCs have a non-zero conversion delay. In the present implementation, the ADC have a 2 \u00b5s delay, which leads to an additional current error of at most 1.5*V<sub>DC<\/sub>*T<sub>delay<\/sub>\/L<sub>load<\/sub> = 42 mA<\/li><\/ul>\n\n\n\n<p>All in all, this explains a current error of approx. 100 mA beyond the hysteresis bounds.<\/p>\n\n\n\n<div class=\"wp-block-simple-alerts-for-gutenberg-alert-boxes sab-alert sab-alert-dark\" role=\"alert\">Back to\u00a0<a href=\"https:\/\/imperix.com\/doc\/help\/fpga-development-on-imperix-controllers\">FPGA development homepage<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>This technical note provides an example of how a fast hysteresis current controller can be implemented, leveraging the possibility of editing the FPGA firmware for&#8230;<\/p>\n","protected":false},"author":4,"featured_media":3043,"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":[53,17],"software-environments":[106,103],"provided-results":[108],"related-products":[50,31,32,92,166,51,110],"guidedreadings":[],"tutorials":[],"user-manuals":[],"coauthors":[70,63],"class_list":["post-1544","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-implementation","tag-current-control","tag-fpga-programming","software-environments-fpga","software-environments-matlab","provided-results-experimental","related-products-acg-sdk","related-products-b-board-pro","related-products-b-box-rcp","related-products-b-box-micro","related-products-b-box-rcp-3-0","related-products-cpp-sdk","related-products-tpi"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>FPGA-based hysteresis current controller for three-phase inverter - imperix<\/title>\n<meta name=\"description\" content=\"This technical note provides an example of hysteresis current control done in FPGA on a rapid control prototyping controller.\" \/>\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\/hysteresis-current-control\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"FPGA-based hysteresis current controller for three-phase inverter - imperix\" \/>\n<meta property=\"og:description\" content=\"This technical note provides an example of hysteresis current control done in FPGA on a rapid control prototyping controller.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control\" \/>\n<meta property=\"og:site_name\" content=\"imperix\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-02T12:27:41+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-07T12:03:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/3_2_ratio_TN120.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=\"Beno\u00eet Steinmann, Julien Orsinger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Beno\u00eet Steinmann, Julien Orsinger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control\"},\"author\":{\"name\":\"Beno\u00eet Steinmann\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/person\\\/a69a3bda75b05d0923cc76d7268cc94f\"},\"headline\":\"FPGA-based hysteresis current controller for three-phase inverter\",\"datePublished\":\"2021-04-02T12:27:41+00:00\",\"dateModified\":\"2025-05-07T12:03:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control\"},\"wordCount\":831,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/3_2_ratio_TN120.png\",\"keywords\":[\"Current control\",\"FPGA programming\"],\"articleSection\":[\"Technical notes\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control\",\"name\":\"FPGA-based hysteresis current controller for three-phase inverter - imperix\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/3_2_ratio_TN120.png\",\"datePublished\":\"2021-04-02T12:27:41+00:00\",\"dateModified\":\"2025-05-07T12:03:12+00:00\",\"description\":\"This technical note provides an example of hysteresis current control done in FPGA on a rapid control prototyping controller.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#primaryimage\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/3_2_ratio_TN120.png\",\"contentUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/3_2_ratio_TN120.png\",\"width\":450,\"height\":300},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/hysteresis-current-control#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-based hysteresis current controller for three-phase inverter\"}]},{\"@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\\\/a69a3bda75b05d0923cc76d7268cc94f\",\"name\":\"Beno\u00eet Steinmann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/22a9252907f853f91d07b143dfcc84f6ec0cc31f6b72408b503a7026eed5b109?s=96&d=mm&r=g3b3f3d8e66019ebcb2848094940b98c0\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/22a9252907f853f91d07b143dfcc84f6ec0cc31f6b72408b503a7026eed5b109?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/22a9252907f853f91d07b143dfcc84f6ec0cc31f6b72408b503a7026eed5b109?s=96&d=mm&r=g\",\"caption\":\"Beno\u00eet Steinmann\"},\"description\":\"Benoit is an embedded systems expert and the leader of software and firmware developments at imperix. On the knowledge base, he is the author of numerous software reference documents.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/benoit-steinmann\\\/\"],\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/author\\\/steinmann\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"FPGA-based hysteresis current controller for three-phase inverter - imperix","description":"This technical note provides an example of hysteresis current control done in FPGA on a rapid control prototyping controller.","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\/hysteresis-current-control","og_locale":"en_US","og_type":"article","og_title":"FPGA-based hysteresis current controller for three-phase inverter - imperix","og_description":"This technical note provides an example of hysteresis current control done in FPGA on a rapid control prototyping controller.","og_url":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control","og_site_name":"imperix","article_published_time":"2021-04-02T12:27:41+00:00","article_modified_time":"2025-05-07T12:03:12+00:00","og_image":[{"width":450,"height":300,"url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/3_2_ratio_TN120.png","type":"image\/png"}],"author":"Beno\u00eet Steinmann, Julien Orsinger","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Beno\u00eet Steinmann, Julien Orsinger","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#article","isPartOf":{"@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control"},"author":{"name":"Beno\u00eet Steinmann","@id":"https:\/\/imperix.com\/doc\/#\/schema\/person\/a69a3bda75b05d0923cc76d7268cc94f"},"headline":"FPGA-based hysteresis current controller for three-phase inverter","datePublished":"2021-04-02T12:27:41+00:00","dateModified":"2025-05-07T12:03:12+00:00","mainEntityOfPage":{"@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control"},"wordCount":831,"commentCount":0,"publisher":{"@id":"https:\/\/imperix.com\/doc\/#organization"},"image":{"@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#primaryimage"},"thumbnailUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/3_2_ratio_TN120.png","keywords":["Current control","FPGA programming"],"articleSection":["Technical notes"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#respond"]}]},{"@type":"WebPage","@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control","url":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control","name":"FPGA-based hysteresis current controller for three-phase inverter - imperix","isPartOf":{"@id":"https:\/\/imperix.com\/doc\/#website"},"primaryImageOfPage":{"@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#primaryimage"},"image":{"@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#primaryimage"},"thumbnailUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/3_2_ratio_TN120.png","datePublished":"2021-04-02T12:27:41+00:00","dateModified":"2025-05-07T12:03:12+00:00","description":"This technical note provides an example of hysteresis current control done in FPGA on a rapid control prototyping controller.","breadcrumb":{"@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#primaryimage","url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/3_2_ratio_TN120.png","contentUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/04\/3_2_ratio_TN120.png","width":450,"height":300},{"@type":"BreadcrumbList","@id":"https:\/\/imperix.com\/doc\/implementation\/hysteresis-current-control#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-based hysteresis current controller for three-phase inverter"}]},{"@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\/a69a3bda75b05d0923cc76d7268cc94f","name":"Beno\u00eet Steinmann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/22a9252907f853f91d07b143dfcc84f6ec0cc31f6b72408b503a7026eed5b109?s=96&d=mm&r=g3b3f3d8e66019ebcb2848094940b98c0","url":"https:\/\/secure.gravatar.com\/avatar\/22a9252907f853f91d07b143dfcc84f6ec0cc31f6b72408b503a7026eed5b109?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/22a9252907f853f91d07b143dfcc84f6ec0cc31f6b72408b503a7026eed5b109?s=96&d=mm&r=g","caption":"Beno\u00eet Steinmann"},"description":"Benoit is an embedded systems expert and the leader of software and firmware developments at imperix. On the knowledge base, he is the author of numerous software reference documents.","sameAs":["https:\/\/www.linkedin.com\/in\/benoit-steinmann\/"],"url":"https:\/\/imperix.com\/doc\/author\/steinmann"}]}},"_links":{"self":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/1544","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\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/comments?post=1544"}],"version-history":[{"count":22,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/1544\/revisions"}],"predecessor-version":[{"id":25320,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/1544\/revisions\/25320"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/media\/3043"}],"wp:attachment":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/media?parent=1544"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/categories?post=1544"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/tags?post=1544"},{"taxonomy":"software-environments","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/software-environments?post=1544"},{"taxonomy":"provided-results","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/provided-results?post=1544"},{"taxonomy":"related-products","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/related-products?post=1544"},{"taxonomy":"guidedreadings","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/guidedreadings?post=1544"},{"taxonomy":"tutorials","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/tutorials?post=1544"},{"taxonomy":"user-manuals","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/user-manuals?post=1544"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/coauthors?post=1544"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}