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_controler.vhd
File deleted
/pid_controler/trunk/tb_pid_controler_0.vhd
File deleted
/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; |