Intel® FPGA University Program
University Program Material, Education Boards, and Laboratory Exercises

PI controller VHDL

Altera_Forum
Honored Contributor II
2,955 Views

One of my task is to make PI controller for DC drive. I decided to make it's in vhdl. I prepare following code: 

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity pid is Port ( clock : in STD_LOGIC; reset : in STD_LOGIC; data_en : in STD_LOGIC; set_point : in STD_LOGIC_VECTOR (15 downto 0); fb : in STD_LOGIC_VECTOR (15 downto 0); pi_o : out STD_LOGIC_VECTOR (31 downto 0)); end pid; architecture Behavioral of pi is begin process(clock) is variable p,i,result: signed(pi_o'range); begin if rising_edge(clock) then if reset = '1' then i := (others => '0'); elsif data_en = '1' then p := signed((set_point - fb)* "0000000000000011"); -- data-fb is the error i := i + signed((set_point-fb) * "0000000000000010"); result := (p + i); end if; pi_o <= std_logic_vector(result); end if; end process; end Behavioral;  

I have question if it's correct? All variables are initialized correctly? I ask this stupid questions because we don't have enough access to Altera fpga boards. 

i := i + signed((set_point-fb) * "0000000000000010");  

In this line I think that I should add something more, it should be divide by something, but I don't know by what?
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
1,318 Views

could you post the error? 

Also try to avoid variables u til you know more VHDL. Try using signals instead.
0 Kudos
Altera_Forum
Honored Contributor II
1,318 Views

I don't know what you mean by "post the error" 

During compilation in Quartus I didn't get any error. 

I asked this question because I have problems test my project on fpga board and DC drive
0 Kudos
Altera_Forum
Honored Contributor II
1,318 Views

I am sorry but then I do not uderstand your question. The code compiles whitout errors, but you think it won't work or?

0 Kudos
Altera_Forum
Honored Contributor II
1,318 Views

 

--- Quote Start ---  

One of my task is to make PI controller for DC drive. I decided to make it's in vhdl. I prepare following code: 

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity pid is Port ( clock : in STD_LOGIC; reset : in STD_LOGIC; data_en : in STD_LOGIC; set_point : in STD_LOGIC_VECTOR (15 downto 0); fb : in STD_LOGIC_VECTOR (15 downto 0); pi_o : out STD_LOGIC_VECTOR (31 downto 0)); end pid; architecture Behavioral of pi is begin process(clock) is variable p,i,result: signed(pi_o'range); begin if rising_edge(clock) then if reset = '1' then i := (others => '0'); elsif data_en = '1' then p := signed((set_point - fb)* "0000000000000011"); -- data-fb is the error i := i + signed((set_point-fb) * "0000000000000010"); result := (p + i); end if; pi_o <= std_logic_vector(result); end if; end process; end Behavioral;  

I have question if it's correct? All variables are initialized correctly? I ask this stupid questions because we don't have enough access to Altera fpga boards. 

i := i + signed((set_point-fb) * "0000000000000010");  

In this line I think that I should add something more, it should be divide by something, but I don't know by what? 

--- Quote End ---  

 

 

 

This code should be giving you compilation error since your entity name is pid but while declaring architecture you have written 

architecture Behavioral of pi is 

 

It is generally a good practice to use asynchronous reset as shown below: 

process(clock,reset) 

variable p,i,result: signed(pi_o'range); 

begin 

if(reset = '1') then 

i := (others => '0'); 

elsif rising_edge(clock) then 

....... 

end if; 

end process; 

 

It is generally not a good practice to use variables unless your timing requirement is such that you cannot spare any clock cycle for the calculation. 

variable "p" needs initialization. 

I simulated your code and it does not seem to have any problem.
0 Kudos
Altera_Forum
Honored Contributor II
1,318 Views

 

--- Quote Start ---  

 

It is generally a good practice to use asynchronous reset as shown below: 

process(clock,reset) 

variable p,i,result: signed(pi_o'range); 

begin 

if(reset = '1') then 

i := (others => '0'); 

elsif rising_edge(clock) then 

....... 

end if; 

end process; 

 

--- Quote End ---  

 

 

THis is only true IF you asynchronous reset is de-asserted synchronously. There is nothing wrong with sync resets - but in altera land sync resets are emulated in the fabric and can hurt timing in high speed applications, but it is much safer overall to use sync resets. In Xilinx async, resets should be avoided as much as possible.  

 

So as a general rule, avoid async resets - sync resets are much safer. 

 

 

--- Quote Start ---  

 

It is generally not a good practice to use variables unless your timing requirement is such that you cannot spare any clock cycle for the calculation. 

 

--- Quote End ---  

 

 

What a load of rubbish. Instead of trying to separate variables/signals, you need to understand the underlying logic. There is NOTHING you can do with variables you cant do with signals with regards RTL description. But there are plenty of things variables can do that you cant do with signals, but this is really just in simulation land. 

 

As a beginner, NEVER use variables.
0 Kudos
Altera_Forum
Honored Contributor II
1,318 Views

We are doing a project on CLOSED LOOP SPEED CONTROL OF BLDC MOTOR USING PI CONTROLLER IN FPGA VHDL SPARTAN 3 PROGRAMMER, 

We are facing issue in implementing it , So pls help with Vhdl code for PI controller implementation
0 Kudos
Altera_Forum
Honored Contributor II
1,318 Views

@basilpe7, We are here to help you out when you have problems, not to do your work for you. If you have a new question please create a new thread instead of highkacking another, which you have done already. And one other thing, a Spartan is a Xilinx chip, not an Altera one.

0 Kudos
Reply