Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

pid controller vhdl code

Status
Not open for further replies.

mansi0905

Junior Member level 1
Joined
Jan 21, 2010
Messages
16
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,283
Location
jaipur
Activity points
1,406
i have to design a pid controller for controlling the duty cycle. the problem is wrote a vhdl code but they simulation results show undefind output of pid evry alternate clock cycle. i am not able to underdstand the problem.
pls help.
 

check for multiple drivers, or check the inputs to the assignment of the affected signal.
 

    V

    Points: 2
    Helpful Answer Positive Rating
i have already checked the code . i don't think dat there is prblm of multiple drivers. here is d code.

pls lemme know the error in dis vhdl code .

entity pid is
port(
u_out:eek:ut std_logic_vector( 15 downto 0);
e_in:in std_logic_vector(15 downto 0);
clk:in std_logic;
reset:in std_logic);
end pid;

architecture Behavioral of pid is
signal u1: std_logic_vector(15 downto 0);
signal u_prev : std_logic_vector( 15 downto 0);
signal e_prev1: std_logic_vector( 15 downto 0);
signal e_prev2: std_logic_vector( 15 downto 0);
constant k1: std_logic_vector( 6 downto 0 ):="1101011";
constant k2:std_logic_vector( 6 downto 0):="1101000";
constant k3: std_logic_vector( 6 downto 0) :="0000010";
begin
process( clk)
begin
if( clk'event and clk='1') then
if reset ='1' then
u_prev <="0000000000000000";
e_prev1<="0000000000000000";
e_prev2<="0000000000000000";
else
e_prev2<=e_prev1;
e_prev1<=e_in;
u_prev<=u1;
u1<= u_prev + (k1*e_in)+(k2*e_prev2)+(k3*e_prev2);

end if;

end if;
u_out<=u1;
end process;
end Behavioral;
 
  • Like
Reactions: EngHussein

    V

    Points: 2
    Helpful Answer Positive Rating

    EngHussein

    Points: 2
    Helpful Answer Positive Rating
there are several things that can be done better. Here are my suggestions:
1.) u1 needs some action on the reset. this is your issue.
2.) really, it doens't need a reset at all. it could be moved out of the if-reset block.
3.) e_prev2 appears for k2 and k3. this is probably a mistake.

this does have a long longest path, so if a high clock rate is needed, you might need to do something to improve performance.

Added after 45 seconds:

also, none of the multiplies will be correct. the output of a*b is a vector of length len(a)+len(b).
 

In the above code the following statements are blocking statements:

--first three statements happens in the first clock cycle.
e_prev2<=e_prev1;
e_prev1<=e_in;
u_prev<=u1;
--this statment happens in the 2nd clock cycle.So output comes every 2 clock cycle.
u1<= u_prev + (k1*e_in)+(k2*e_prev2)+(k3*e_prev2);


Use variables inside the process.Then it will work.

--vipin
https://vhdlguru.blogspot.com/
 

@Tricky : Why it will not work?
The statement is similar to this right.
u1<= u1 + (k1*e_in)+(k2*e_prev2)+(k3*e_prev2);

What do you mean by it is never given a value.Can you explain more?
 

thanks a lot for d suggestion .
i have replaced e_prev2 e_prev1 . yes it was an error but then also it was still giving same result .
then i tried using variable inside process then the output of pid was undefined for all the clock cycles.
pls help
 

here is the new code for pid
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.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 primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity pid is
port(
u_out:eek:ut std_logic_vector( 15 downto 0);
e_in:in std_logic_vector(15 downto 0);
clk:in std_logic;
reset:in std_logic);
end pid;

architecture Behavioral of pid is
signal u1: std_logic_vector(15 downto 0);
signal u_prev : std_logic_vector( 15 downto 0);
signal e_prev1: std_logic_vector( 15 downto 0);
signal e_prev2: std_logic_vector( 15 downto 0);
constant k1: std_logic_vector( 6 downto 0 ):="1101011";
constant k2:std_logic_vector( 6 downto 0):="1101000";
constant k3: std_logic_vector( 6 downto 0) :="0000010";
begin
process( clk)
--variable u1: std_logic_vector(15 downto 0);
--variable u_prev : std_logic_vector( 15 downto 0);
--variable e_prev1: std_logic_vector( 15 downto 0);
--variable e_prev2: std_logic_vector( 15 downto 0);
--constant k1: std_logic_vector( 6 downto 0 ):="1101011";
--constant k2:std_logic_vector( 6 downto 0):="1101000";
--constant k3: std_logic_vector( 6 downto 0) :="0000010";
begin
if( clk'event and clk='1') then
if reset ='1' then
u_prev <="0000000000000000";
e_prev1<="0000000000000000";
e_prev2<="0000000000000000";
else
e_prev2<=e_prev1;
e_prev1<=e_in;
u_prev<=u1;
u1<= u_prev + (k1*e_in)+(k2*e_prev1)+(k3*e_prev2);

end if;

end if;
u_out<=u1;
end process;
end Behavioral;
 
Can you try out this code and tell me what is the output?

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity pid is
port(
u_out:out std_logic_vector( 15 downto 0);
e_in:in std_logic_vector(15 downto 0);
clk:in std_logic;
reset:in std_logic);
end pid;

architecture Behavioral of pid is

begin
process( clk)
variable u1: std_logic_vector(15 downto 0);
variable u_prev : std_logic_vector( 15 downto 0);
variable e_prev1: std_logic_vector( 15 downto 0);
variable e_prev2: std_logic_vector( 15 downto 0);
constant k1: std_logic_vector( 6 downto 0 ):="1101011";
constant k2:std_logic_vector( 6 downto 0):="1101000";
constant k3: std_logic_vector( 6 downto 0) :="0000010";
begin
if( clk'event and clk='1') then
if reset ='1' then
u_prev :="0000000000000000";
e_prev1:="0000000000000000";
e_prev2:="0000000000000000";
else
e_prev2:=e_prev1;
e_prev1:=e_in;
u1:= u1 + (k1*e_in)+(k2*e_prev1)+(k3*e_prev2);

end if;

end if;
u_out<=u1;
end process;
end Behavioral;

--vipin
https://vhdlguru.blogspot.com/
 
i tried this code but simulation results show u_out as undefined for all the clock cycles. thanks a lot for help
 

"1.) u1 needs some action on the reset. this is your issue."

"No It wont.

U1 is never given a value."

u1 starts at xxxx. thus, on the first cycle, you will have: xxxx + 0000 + 0000 + 0000 = xxxx. the next cycle, xxxx + ...

I suggest that variables never be used to infer registers. its not that they can't, it's that it is more difficult to read/modify/write the code correctly.
 

So does this solve the problem while initializing u1?
variable u1: std_logic_vector(15 downto 0):=(others => '0');
 

sorry i am not getting what should be done . could you please explain a bit more about the suggestion
 

i has simulated this code but i am not getting how to check the output
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top