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.
 

permute

Advanced Member level 3
Joined
Jul 16, 2010
Messages
923
Helped
295
Reputation
590
Reaction score
268
Trophy points
1,343
Activity points
8,543
check for multiple drivers, or check the inputs to the assignment of the affected signal.
 

    V

    Points: 2
    Helpful Answer Positive Rating

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

permute

Advanced Member level 3
Joined
Jul 16, 2010
Messages
923
Helped
295
Reputation
590
Reaction score
268
Trophy points
1,343
Activity points
8,543
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).
 

vipinlal

Full Member level 6
Joined
Mar 8, 2010
Messages
358
Helped
76
Reputation
152
Reaction score
60
Trophy points
1,308
Location
India
Activity points
3,187
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/
 

vipinlal

Full Member level 6
Joined
Mar 8, 2010
Messages
358
Helped
76
Reputation
152
Reaction score
60
Trophy points
1,308
Location
India
Activity points
3,187
@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?
 

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

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

vipinlal

Full Member level 6
Joined
Mar 8, 2010
Messages
358
Helped
76
Reputation
152
Reaction score
60
Trophy points
1,308
Location
India
Activity points
3,187
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/
 

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 tried this code but simulation results show u_out as undefined for all the clock cycles. thanks a lot for help
 

permute

Advanced Member level 3
Joined
Jul 16, 2010
Messages
923
Helped
295
Reputation
590
Reaction score
268
Trophy points
1,343
Activity points
8,543
"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.
 

vipinlal

Full Member level 6
Joined
Mar 8, 2010
Messages
358
Helped
76
Reputation
152
Reaction score
60
Trophy points
1,308
Location
India
Activity points
3,187
So does this solve the problem while initializing u1?
variable u1: std_logic_vector(15 downto 0):=(others => '0');
 

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
sorry i am not getting what should be done . could you please explain a bit more about the suggestion
 

kesava

Newbie level 1
Joined
Nov 5, 2012
Messages
1
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,284
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

Top