OpenCores
URL https://opencores.org/ocsvn/pid_controler/pid_controler/trunk

Subversion Repositories pid_controler

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/pid_controler/trunk/pid_controller.vhd
0,0 → 1,192
-------------------------------------------------------------------------------
-- Title : Digital PID Controller
-- Project :
-------------------------------------------------------------------------------
-- File : pid_controller.vhd
-- Author : Tomasz Turek <tomasz.turek@gmail.com>
-- Company : SzuWar ZOO
-- Created : 12:56:06 20-07-2010
-- Last update: 21:00:09 06-10-2010
-- Platform : Xilinx ISE 10.1.03
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description:
-- PID CONTROLLER
--
-- ___________ ___
-- | | | |
-- |-->| KP Gain |------------------------>| + |
-- | |___________| | |
-- | | |
-- | ___________ | |
-- | | -iDelayD | | |
-- | |--| Z |<--| | |
-- | | |___________| | | |
-- | | ___ | | |
-- | | | | | | | _________
-- _______ ___________ | ___________ |------->| + | | | | | |
-- | | | | | | | | |-----|-->| + |-->| correct |
-- | error |-->| KM Gain |--|-->| KD Gain |---------->| + | | | |_________|
-- |_______| |___________| | |___________| |___| | |
-- | | |
-- | ____ | |
-- | | -1| | |
-- | |--| Z |<---| | |
-- | | |____| | | |
-- | | ___ | | |
-- | | | | | | |
-- | ___________ |-->| + | | | |
-- | | | | |----|-------->| + |
-- |-->| KI Gain |----->| + | | |
-- |___________| |___| |___|
--
-------------------------------------------------------------------------------
-- Copyright (c) 2010 SzuWar ZOO
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 12:56:06 20-07-2010 1.0 aTomek Created
-- 19:29:34 04-10-2010 1.1 aTomek Created
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
entity pid_controller is
 
generic
(
-- size of input and output data --
iDataWidith : integer range 8 to 32 := 8;
-- proportionally gain --
iKP : integer range 0 to 7 := 3; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
-- integral gain --
iKI : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
-- differential gain --
iKD : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
-- master gain --
iKM : integer range 0 to 7 := 1; -- 0 - /1, 1 - /2, 2 - /4, 3 - /8 , 4 - /16, 5 - /32, 6 - /64 , 7 - /128
-- delay between samples of error --
iDelayD : integer range 1 to 16 := 10;
-- 0 - controller use derivative of PATERN_I and PATERN_ESTIMATION_I, 1 - controller use error to work --
iWork : integer range 0 to 1 := 1
);
 
port
(
CLK_I : in std_logic;
RESET_I : in std_logic;
-- error --
ERROR_I : in std_logic_vector(iDataWidith - 1 downto 0);
-- threshold --
PATERN_I : in std_logic_vector(iDataWidith - 1 downto 0);
-- current sample --
PATERN_ESTIMATION_I : in std_logic_vector(iDataWidith - 1 downto 0);
-- correction --
CORRECT_O : out std_logic_vector(iDataWidith - 1 downto 0)
);
end entity pid_controller;
 
architecture rtl of pid_controller is
-------------------------------------------------------------------------------
-- functions --
-------------------------------------------------------------------------------
-- purpose: make a std_logic_vector of size c_size and build from c_value --
function f_something ( constant c_size : integer; signal c_value : std_logic) return std_logic_vector is
 
variable var_temp : std_logic_vector(c_size - 1 downto 0);
begin -- function f_something --
 
var_temp := (others => c_value);
 
return var_temp;
end function f_something;
-- examples:
-- f_something(c_size => 3 , c_value => 'Z') == "ZZZ"
-- f_something(c_size => 3 , c_value => '1') == "111"
-- ...
-------------------------------------------------------------------------------
-- types --
-------------------------------------------------------------------------------
-- delay register --
type type_sr is array (0 to iDelayD - 1) of std_logic_vector(iDataWidith - 1 downto 0);
-------------------------------------------------------------------------------
-- signals --
-------------------------------------------------------------------------------
signal v_error : std_logic_vector(iDataWidith - 1 downto 0);
signal v_error_KM : std_logic_vector(iDataWidith - 1 downto 0);
signal v_error_KP : std_logic_vector(iDataWidith - 1 downto 0);
signal v_error_KD : std_logic_vector(iDataWidith - 1 downto 0);
signal v_error_KI : std_logic_vector(iDataWidith - 1 downto 0);
signal t_div_late : type_sr;
signal v_div : std_logic_vector(iDataWidith - 1 downto 0);
signal v_acu_earl : std_logic_vector(iDataWidith - 1 downto 0);
signal v_acu : std_logic_vector(iDataWidith - 1 downto 0);
signal v_sum : std_logic_vector(iDataWidith - 1 downto 0);
begin -- architecture rtl --
 
-- choice source of input data --
v_error <= ERROR_I when iWork = 1 else
conv_std_logic_vector(signed(PATERN_I) - signed(PATERN_ESTIMATION_I) , iDataWidith) when iWork = 0 else
(others => '0');
-- master gain execute by shift of iKM bits to the right --
v_error_KM <= v_error when iKM = 0 else
f_something(c_size => iKM , c_value => v_error(iDataWidith - 1)) & v_error(iDataWidith - 1 downto iKM) when iKM > 0 else
(others => '0');
-- proportionally gain execute by shift of (iKP - 1) bits to the right --
v_error_KP <= f_something(c_size => iKP + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKP + 1);
-- derivative gain execute by shift of (iKD - 1) bits to the right --
v_error_KD <= f_something(c_size => iKD + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKD + 1);
-- integral gain execute by shift of (iKI + 1) bits to the right --
v_error_KI <= f_something(c_size => iKI + 1 , c_value => v_error_KM(iDataWidith - 1)) & v_error_KM(iDataWidith - 1 downto iKI + 1);
 
DI00: process (CLK_I) is
begin -- process DI00
 
if rising_edge(CLK_I) then
 
-- synchronous reset --
if RESET_I = '1' then
 
t_div_late <= (others => (others => '0'));
v_div <= (others => '0');
v_acu <= (others => '0');
v_acu_earl <= (others => '0');
 
else
 
-- delay register --
t_div_late <= v_error_KD & t_div_late(0 to iDelayD - 2);
 
-- difference between samples --
v_div <= conv_std_logic_vector(signed(v_error_KD) - signed(t_div_late(iDelayD - 1)) , iDataWidith);
 
-- integration of error --
v_acu <= conv_std_logic_vector(signed(v_error_KI) + signed(v_acu_earl) , iDataWidith);
-- sum of N - 1 samples of error --
v_acu_earl <= v_acu;
end if;
end if;
end process DI00;
 
-- first stage of adder --
v_sum <= conv_std_logic_vector(signed(v_acu) + signed(v_div) , iDataWidith);
-- correction and second stage of adder --
CORRECT_O <= conv_std_logic_vector(signed(v_error_KP) + signed(v_sum) , iDataWidith) when RESET_I = '0' else
(others => '0');
end architecture rtl;
/pid_controler/trunk/tb_pid_controller_0.vhd
0,0 → 1,162
-------------------------------------------------------------------------------
-- Title : Testbench for pid_controller
-- Project :
-------------------------------------------------------------------------------
-- File : tb_pid_controller_0.vhd
-- Author : Tomasz Turek <tomasz.turek@gmail.com>
-- Company : SzuWar ZOO
-- Created : 16:43:29 21-07-2010
-- Last update: 20:54:54 04-10-2010
-- Platform : Xilinx ISE 10.1.03
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2010 SzuWar ZOO
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 16:43:29 21-07-2010 1.0 aTomek Created
-- 20:54:31 04-10-2010 1.1 aTomek Created
-------------------------------------------------------------------------------
 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
 
entity tb_pid_controller_0 is
 
end entity tb_pid_controller_0;
 
architecture testbench of tb_pid_controller_0 is
-------------------------------------------------------------------------------
-- components --
-------------------------------------------------------------------------------
component pid_controller is
 
generic
(
iDataWidith : integer range 8 to 32 := 12;
iKP : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
iKI : integer range 0 to 7 := 3; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
iKD : integer range 0 to 7 := 4; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
iKM : integer range 0 to 7 := 0; -- 0 - /1, 1 - /2, 2 - /4, 3 - /8 , 4 - /16, 5 - /32, 6 - /64 , 7 - /128
iDelayD : integer range 1 to 16 := 1;
 
);
 
port
(
CLK_I : in std_logic;
RESET_I : in std_logic;
ERROR_I : in std_logic_vector(iDataWidith - 1 downto 0);
PATERN_I : in std_logic_vector(iDataWidith - 1 downto 0);
PATERN_ESTIMATION_I : in std_logic_vector(iDataWidith - 1 downto 0);
CORRECT_O : out std_logic_vector(iDataWidith - 1 downto 0)
);
end component pid_controller;
-------------------------------------------------------------------------------
-- constants --
-------------------------------------------------------------------------------
constant TS : time := 5 ns;
constant iDataWidith : integer range 8 to 32 := 12;
constant iKP : integer range 0 to 7 := 2; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
constant iKI : integer range 0 to 7 := 1; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
constant iKD : integer range 0 to 7 := 1; -- 0 - /2, 1 - /4, 2 - /8, 3 - /16, 4 - /32, 5 - /64, 6 - /128, 7 - /256
constant iKM : integer range 0 to 7 := 0; -- 0 - /1, 1 - /2, 2 - /4, 3 - /8 , 4 - /16, 5 - /32, 6 - /64 , 7 - /128
constant iDelayD : integer range 1 to 16 := 16;
constant iWork : integer range 0 to 1 := 0;
-------------------------------------------------------------------------------
-- signals --
-------------------------------------------------------------------------------
-- Inputs --
signal CLK_I : std_logic := '0';
signal RESET_I : std_logic := '0';
signal ERROR_I : std_logic_vector(iDataWidith - 1 downto 0) := x"00f";
signal PATERN_I : std_logic_vector(iDataWidith - 1 downto 0) := x"6ff";
signal PATERN_ESTIMATION_I : std_logic_vector(iDataWidith - 1 downto 0) := x"007";
-- Outputs --
signal CORRECT_O : std_logic_vector(iDataWidith - 1 downto 0);
-- Others --
signal v_count : std_logic_vector(15 downto 0) := x"0000";
begin -- architecture testbench
 
-- Unit Under Test --
uut :
pid_controler
 
generic map
(
iDataWidith => iDataWidith,
iKP => iKP,
iKI => iKI,
iKD => iKD,
iKM => iKM,
iDelayD => iDelayD,
iWork => iWork
)
 
port map
(
CLK_I => CLK_I,
RESET_I => RESET_I,
ERROR_I => ERROR_I,
PATERN_I => PATERN_I,
PATERN_ESTIMATION_I => PATERN_ESTIMATION_I,
CORRECT_O => CORRECT_O
);
 
-- stimulate proces --
stim_proc: process
begin
 
for i in 0 to 1000000 loop
 
CLK_I <= '0';
 
wait for TS;
 
CLK_I <= '1';
 
wait for TS;
end loop; -- i
end process;
 
T0: process (CLK_I) is
begin -- process T0
 
if rising_edge(CLK_I) then
case v_count is
when x"0010" =>
 
v_count <= v_count + 1;
RESET_I <= '1';
when x"0020" =>
 
v_count <= v_count + 1;
RESET_I <= '0';
 
 
when others =>
 
PATERN_ESTIMATION_I <= PATERN_I - 336 + CORRECT_O;
v_count <= v_count + 1;
end case;
end if;
end process T0;
 
end architecture testbench;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.