--- 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.