----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 16.03.2022 20:07:22
-- Design Name: 
-- Module Name: pwm_test_db - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;



--use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity pwm_test_db is
--  Port ( );
end pwm_test_db;

architecture Behavioral of pwm_test_db is

component regler is
    Port ( clk : in STD_LOGIC;      --Clk -> Gibt abtastzeit vor
           prescaler : in signed(63 downto 0) := to_signed(1000000, 64);   -- prescaler für Zeit 1000000
           w : in signed(63 downto 0) := (others => '0');     --Sollwert
           y : in signed(63 downto 0) := (others => '0');     --Istwert
           u : inout signed(63 downto 0) := (others => '0'); --Stellgöße
           KR : in signed(9 downto 0) := to_signed(1,10);    -- Verstärkung
           T : in signed(9 downto 0) := to_signed(1000, 10);   -- Abtastzeit in us 1000us
           TV : signed(9 downto 0) := (others => '0');     -- Vorhaltezeit   für Differenzierer interesannt
           TN : in signed(9 downto 0) := to_signed(1,10);   -- Nachstellzeit
           regler_bruecken : in STD_LOGIC := '0');   
end component;

component pt1 is
  Port ( 
        clk : in STD_LOGIC;
        prescaler : in signed(63 downto 0) := to_signed(1000000, 64);   -- prescaler für Zeit 1000000
        u : in signed(63 downto 0) := to_signed(1,64);
        y : inout signed(63 downto 0) := to_signed(1,64); -- muss vielleicht initalisiert werden vorher!?
        a : in signed(9 downto 0) := to_signed(1,10);
        k : in signed(9 downto 0) := to_signed(1,10);
        stepWidth : signed(9 downto 0) := to_signed(10,10)); --in us -> 10us
end component;


component autoTuning is
    Port ( clk : in STD_LOGIC;
           prescaler : in signed(63 downto 0) := to_signed(1000000, 64);   -- prescaler für Zeit 1000000
           duration : in signed(63 downto 0) := to_signed(5000000, 64);  -- Zeit in Microsekunden/ oder Clk-Ticks?
           start_Tuning : inout std_logic := '1';
           regler_bruecken : out STD_LOGIC := '0';
           w : in signed(63 downto 0) := (others => '0');       --Sollwert für Regler -> während Outotuing konst!
           y : in signed(63 downto 0) := (others => '0');       --Istwert
           --u : inout signed(63 downto 0) := (others => '0');    --Stellgöße
           KR : out signed(9 downto 0) := to_signed(1, 10);      -- Verstärkung
           T : in signed(9 downto 0) := to_signed(1000, 10);    -- Abtastzeit in us 1000us
           TV : out signed(9 downto 0) := (others => '0');          -- Vorhaltezeit   für Differenzierer interesannt
           TN : out signed(9 downto 0) := to_signed(1, 10));     -- Nachstellzeit);   -- u <= w);
end component;


signal clk : std_logic := '0';
signal clk_100 : std_logic := '0';

signal prescaler : signed(63 downto 0) := to_signed(1000000, 64);   -- prescaler für Zeit

signal w : signed(63 downto 0) := to_signed(1000000, 64);
signal u  : signed(63 downto 0) := to_signed(0, 64);
signal y  : signed(63 downto 0) := to_signed(0, 64);
signal cnt : integer := 0;
signal risingEdge : std_logic := '0';

--Streckenparameter
signal a : signed(9 downto 0) := to_signed(1, 10);
signal k : signed(9 downto 0) := to_signed(1, 10);
signal stepWidth : signed(9 downto 0) := to_signed(10, 10);

--Reglerparameter
signal KR : signed(9 downto 0) := to_signed(1, 10);     -- Verstärkung
signal T : signed(9 downto 0) := to_signed(1000, 10);   -- Abtastzeit in ns = 1ms = 1000000ns
signal TV : signed(9 downto 0) := to_signed(0, 10);     -- Vorhaltezeit   für Differenzierer interesannt
signal TN : signed(9 downto 0) := to_signed(100000, 10);    -- Nachstellzeit in us

--Autotuning
signal duration : signed(63 downto 0) := to_signed(2000000, 64);
signal start_Tuning : std_logic := '1';
signal regler_bruecken : std_logic := '0';

begin

uut_regler: regler PORT MAP (
    clk => clk_100,
    prescaler => prescaler,
    w => w,
    y => y,
    u => u,
    KR => KR,
    T => T,
    TV => TV,
    TN => TN,
    regler_bruecken => regler_bruecken
);

uut_pt1: pt1 PORT MAP (
    clk => clk,
    prescaler => prescaler,
    u => u,
    y => y,
    a => a,
    k => k,
    stepWidth => stepWidth
);

uut_autoTuning: autoTuning PORT MAP (
    clk => clk_100,
    prescaler => prescaler,
    duration => duration,
    start_Tuning => start_Tuning,
    regler_bruecken => regler_bruecken,
    w => w,
    y => y,
    KR => KR,
    T => T,
    TV => TV,
    TN => TN
);

--generate clock
clk <= not clk after 5 us;


process 
begin
    --w <= 100000000;
    --w <= to_signed(100000000, 64); --muss >= 1000000 sein!
    w <= to_signed(10000000, 64);   --INTwert darf nicht über Maximalen wert von 32-Bit sein
    start_Tuning <= '1';
   -- w <= w * prescaler;
--    if rising_edge(clk) and ( cnt >= 100) then
--        clk_100 <= not clk_100;
--        cnt <= 0;
--    end if;
    
    if clk = '1' and risingEdge = '0' then
        cnt <= cnt+1;
        risingEdge <= '1';
        clk_100 <= '0';
        
    end if;
    
    if clk = '0' then
        risingEdge <= '0';
    end if;
        
    if cnt >= 99 then
        clk_100 <= '1';
        cnt <= 0;
    end if;
    
    wait for 1 us;
--    cnt <= cnt+1;

end process;


end Behavioral;
