Traffic VHDL simulation issues - vhdl

I have updated the program, it does finish but now I am trying simulate the project. I am able to get the clock clear and lights on the pins, but I am not able to get the lights to work and count and states are not even showing. I believe I have this all set correctly but I could be wrong. Thank you once again Morten Zilmer for the help with the Error code.
http://tinypic.com/r/24yog0z/8
This is the simulation of the file,
entity traffic is
port (clk: in std_logic;
clr: in std_logic;
lights: out std_logic_vector (5 downto 0));
end traffic;
architecture traffic of traffic is
type state_type is (s0, s1, s2, s3, s4, s5);
signal state: state_type;
signal count : std_logic_vector (3 downto 0);
constant sec5: std_logic_vector (3 downto 0) := "1111";
constant sec1: std_logic_vector (3 downto 0) := "0011";
begin
process(clk, clr)
begin
if clr = '1' then
state<= s0;
count <= x"0";
elsif (clk'event and clk = '1') then
case state is
when s0 =>
if count <= sec5 then
state <= s0;
count <= count +1;
else
state <= s1;
count <= x"0";
end if;
when s1 =>
if count <= sec1 then
state <= s1;
count <= count +1;
else
state <= s2;
count <= x"0";
end if;
when s2 =>
if count <= sec1 then
state <= s2;
count <= count +1;
else
state <= s3;
count <= x"0";
end if;
when s3 =>
if count <= sec5 then
state <= s3;
count <= count +1;
else
state <= s4;
count <= x"0";
end if;
when s4 =>
if count <= sec1 then
state <= s4;
count <= count +1;
else
state <= s5;
count <= x"0";
end if;
when s5 =>
if count <= sec1 then
state <= s5;
count <= count +1;
else
state <= s0;
count <= x"0";
end if;
when others =>
state <= s0;
end case;
end if;
end process;
c2 : process (state)
begin
case state is
when s0 => lights <= "100001";
when s1 => lights <= "100010";
when s2 => lights <= "100100";
when s3 => lights <= "001100";
when s4 => lights <= "010100";
when s5 => lights <= "100100";
when others => lights <= "100001";
end case;
end process;
end traffic;

Change elseif to elsif, for valid VHDL syntax.

Related

Can't find the issues and latches are generated

My code generates two latches, could please someone help me finding why?
According to Xilinx ISE latches are generated because of "try_counter" which is a counter for how many times you get a numeric sequence wrong. (which is the main point of my code).
I don't know what else to do.
entity moore is
Port ( badgeSx : in STD_LOGIC;
badgeDx : in STD_LOGIC;
col : in std_logic_vector (1 to 3);
row : in std_logic_vector (1 to 4);
clk : in std_logic;
rst : in std_logic;
unlock : out STD_LOGIC
);
end moore;
architecture Behavioral of moore is
type stato is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
signal current_state,next_state : stato;
signal badge : std_logic_vector(1 downto 0);
signal count, new_count: integer range 0 to 28;
signal temp_unlock : std_logic :='0';
signal timeover : std_logic :='0';
begin
badge <= badgeDx & badgeSx; --concatenazione dei badge
--processo sequenziale
current_state_register: process(clk)
begin
if rising_edge(clk) then
if (rst = '1') then
current_state <= s0;
count <= 0;
else
current_state <= next_state;
count <= new_count;
end if;
end if;
end process;
process (current_state,badge,col,row,timeover)
variable try_counter: integer range 0 to 3;
begin
case current_state is
when s0 =>
try_counter := 0;
temp_unlock <= '0';
unlock <='0';
if(badge ="01" and row = "0000" and col = "000" ) then
next_state <= s1;
else
next_state <= s0;
end if;
when s1 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s2 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
else
next_state <= s3;
end if;
when s3 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s4 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
else
next_state <= s5;
end if;
when s5 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s6 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
else
next_state <= s7;
end if;
when s7 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s8 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
else
next_state <= s9;
end if;
when s9 =>
temp_unlock <= '0';
unlock <= '1';
if (badge = "10") then
next_state <= s0;
else
next_state <= s5;
end if;
when others =>
next_state <= s0;
end case;
end process;
Contatore_TIMER : process(temp_unlock,count)
begin
if temp_unlock = '1' then
if count = 28 then
new_count<=0;
timeover<='1';
else
new_count<=count+1;
timeover<='0';
end if;
else
new_count<=0;
timeover <= '0';
end if;
end process;
end Behavioral;
The code nearly works as expected (I mean it compiles and I don't get any error) but the RTL schematic isn't what it is supposed to be since it synthesises latches in the process.
In the apparently combinatorial process with process (current_state,badge,col,row,timeover), the variable try_counter is used to store information (sequential behaviour), which is only updated when process evaluation is triggered. This will very likely to generate the 2 latches, which matches the value range from 0 to 3 for try_counter.
To fix this, you can define try_counter as a signal, and include it in the sensitivity list for the process.
Having try_counter as a signal will also ease debugging, since the current state can easily be inspected in waveforms.

Finite state machine VHDL reset

I am new to VHDL and I have a question about the implementation of a FSM.
I would like the behaviour shown in the picture (where I implemented the same FSM with AHDL). When I implement it in VHDL I have a different behaviour of the reset : if it detects reset=1 and at the same time there is a rising edge the FSM does not go on but it keeps on putting PS at S0.
I know the problem is that if... elsif (it detects right the 1st condition and does not enter in the 2nd I suppose).
I have tried in many different ways but still is not working and the output stays at 00 also after the 1st rising edge.
Waveforms of AHDL implementation:
Waveforms of VHDL implementation:
LIBRARY ieee; -- Bibliotheksvereinbarung
USE ieee.std_logic_1164.all;
ENTITY sumconvol IS -- Schaltungssymbol
PORT
(
x : IN STD_LOGIC; --input of 1st FF
clk : IN STD_LOGIC; --clock of all the 3 FFs
clrn : IN STD_LOGIC;
y : OUT STD_LOGIC_VECTOR (1 downto 0) --vector of output data
);
END sumconvol;
ARCHITECTURE a OF sumconvol IS -- Creation of architecture
--SIGNAL output_tmp : STD_LOGIC_VECTOR (1 downto 0); -- temporary variables (e.g. input/output between FFs)7
TYPE state_type IS (S0,S1,S2,S3);
SIGNAL NS,PS : state_type;
SIGNAL stato : STD_LOGIC;
BEGIN
sync_proc: PROCESS (clk,clrn)
BEGIN
if ((clrn='1')) THEN
PS<=S0;
y <= "00";
elsif (rising_edge(clk)) then
PS <= NS;
CASE PS IS
when S0 =>
if ((x='0'))then
NS <= S0;
y <= "00";
else
NS <= S1;
y <= "11";
end if;
when S1 =>
if (x='0') then
NS <= S2;
y<="10";
else
NS <= S3;
y <= "01";
end if;
when S2 =>
if (x='0') then
NS <= S0;
y <="11";
else
NS <= S1;
y <= "00";
end if;
when S3 =>
if (x='0') then
NS <= S2;
y <="01";
else
NS <= S3;
y <= "10";
end if;
end case;
end if;
end process sync_proc;
END a;
One thing you might not noticed, is that you put both PS (previous state) and NS (next state) in a clocked process. That means registers are inferred for both signals. Thus, NS will be set to PS one clock later that you would probably expect. This can be solved two ways:
1) remove the PS->NS part, and just use state.
sync_proc: PROCESS (clk, clr)
BEGIN
if clr = '1' THEN
state <= S0;
y <= "00";
elsif rising_edge(clk) then
CASE state IS
when S0 =>
if x = '0' then
state <= S0;
y <= "00";
else
state <= S1;
y <= "11";
end if;
when S1 =>
if x = '0' then
state <= S2;
y<="10";
else
state <= S3;
y <= "01";
end if;
when S2 =>
if x = '0' then
state <= S0;
y <="11";
else
state <= S1;
y <= "00";
end if;
when S3 =>
if (x='0') then
state <= S2;
y <="01";
else
state <= S3;
y <= "10";
end if;
end case;
end if;
end process sync_proc;
2) separate the process into a clocked and a combinatorial process.
clk_proc: PROCESS (clk, clr)
BEGIN
if clr = '1' THEN
PS <= S0;
y <= "00";
elsif rising_edge(clk) then
PS <= NS;
y <= next_y;
end if;
end process;
comb_proc : process(PS, x)
begin
CASE PS IS
when S0 =>
if x = '0' then
NS <= S0;
next_y <= "00";
else
NS <= S1;
next_y <= "11";
end if;
when S1 =>
if x = '0' then
NS <= S2;
next_y <= "10";
else
NS <= S3;
next_y <= "01";
end if;
when S2 =>
if x = '0' then
NS <= S0;
next_y <="11";
else
NS <= S1;
next_y <= "00";
end if;
when S3 =>
if x = '0' then
NS <= S2;
next_y <="01";
else
NS <= S3;
next_y <= "10";
end if;
end case;
end process;
Next, I don't understand what you want with reset. The VHDL code is doing exactly what it should do. This is the proper way to use a reset: as long as the reset is asserted, y should display "00". Then, once it is deasserted, y should change on the next clock edge. That is proper design. What the first (AHDL) picture shows is not good: activity of y during reset.
But anyhow, if you are really stubborn, you can get the behavior that is in the first image using some tricks.
sync_proc: PROCESS (clk)
BEGIN
if (rising_edge(clk)) then
if clr = '1' THEN
state <= S0;
y <= "11";
else
case state is
[...]
p.s. you are calling the process sync_proc, as in "synchronous process". But this is not true, as the reset in your code is asynchronous...
p.s.2: give your signals some proper names, instead of e.g. x...

De-bounced button press resulting in successive state transitions

I am programming an FPGA that uses push buttons as input signals. It has a finite state machine with 11 states that transition from state to state using specific button presses.
For example, in my design, state s0 goes to state s1 using a button press. This is the same transition case from state s1 to s2 and from state s2 to s3. This state transition system is implemented in my VHDL code using case statements.
LEDs light up in each state to keep track of which state the board is currently in.
My issue is that when my_btnL = '1' is true while in state s0, the board shows that it has moved to state s3.
What I think is happening is that it is indeed going to state s1 and s2 but the same button press in state s0 is also being read in state s1 and s2. This happens so fast that the boards doesn't have enough time to show the LED indications for state s1 and s2. It stops at state s3 because state s3 moves to state s4 using a different button.
So my question is how do I make the button press signal have a rising edge and a falling edge such that a single button press is read only in one state and not the ones that follow it?
The press button signals are de-bounced but this only makes the signal a uniform square wave.
In the following code btnC, btnL, btnR,... are the push buttons:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity digital_lock is
Port (
my_btnC, clk, my_btnU, my_btnR, my_btnL, my_btnD: in std_logic;
my_sw: in std_logic_vector(3 downto 0);
hex0, hex1, hex2, hex3: out std_logic_vector (3 downto 0);
my_led: out std_logic_vector(15 downto 0)
);
end digital_lock;
architecture Behavioral of digital_lock is
type state IS (s0, s1, s2, s3, s4 ,s5 ,s6, s7, s8, s9, s10,s11);
signal my_state: state;
signal my_status: unsigned(1 downto 0);
signal num1, num2, num3, key1, key2, key3: std_logic_vector(3 downto 0);
signal number, final_key: std_logic_vector(11 downto 0);
begin
FSM: process(clk, my_btnC)
begin
if(my_btnC ='1') then
my_state <= s0;
elsif rising_edge(clk) then
case my_state is
when s0 =>
my_status <= "00";
my_led <= "1100000000000000";
hex3 <= "0000";
hex2 <= "0000";
hex1 <= "0000";
hex0 <= "0000";
if(my_btnL ='1') then
my_state <= s1;
else
my_state <= s0;
end if;
when s1 =>
key1 <= my_sw;
hex0 <= key1;
my_led <= "0000000000000001";
if(my_btnL='1') then
my_state <= s2;
else
my_state <= s1;
end if;
when s2 =>
key2 <= my_sw;
hex0 <= key2;
my_led <= "0000000000000010";
if(my_btnL ='1') then
my_state <= s3;
else
my_state <= s2;
end if;
when s3 =>
key3 <= my_sw;
hex0 <= key3;
my_led <= "0000000000000011";
if(my_btnR= '1') then
my_state <= s4;
else
my_state <= s3;
end if;
when s4 =>
final_key(11 downto 8) <= key1;
final_key(7 downto 4) <= key2;
final_key(3 downto 0) <= key3;
my_led <= "0000000000000100";
if(my_btnU ='1') then
my_state <= s5;
else
my_state <= s4;
end if;
when s5 =>
num1 <= my_sw;
hex0 <= num1;
my_led <= "0000000000000101";
if(my_btnD ='1') then
my_state <= s0;
elsif (my_btnL ='1') then
my_state <= s6;
else
my_state <= s5;
end if;
when s6 =>
num2 <= my_sw;
hex0 <= num2;
my_led <= "0000000000000110";
if(my_btnD ='1') then
my_state <= s0;
elsif(my_btnL ='1') then
my_state <= s7;
else
my_state <= s6;
end if;
when s7 =>
num3 <= my_sw;
hex0 <= num3;
my_led <= "0000000000000111";
if(my_btnD ='1') then
my_state <= s0;
elsif(my_btnR = '1') then
my_state <= s8;
else
my_state <= s7;
end if;
when s8 =>
number(11 downto 8) <= num1;
number(7 downto 4) <= num2;
number(3 downto 0) <= num3;
my_led <= "0000000000001000";
if(number = final_key) then
my_state <= s9;
else
my_state <= s10;
end if;
when s9 =>
my_led <= "1111111111111111";
if(my_btnD = '1') then
my_state <= s0;
else
my_state <= s9;
end if;
when s10 =>
my_status <= my_status + 1;
if(my_status >= 3) then
my_state <= s11;
elsif(my_status < 3) then
my_state <= s5;
end if;
when s11 =>
my_led <= "0000000000000000";
hex0 <= "1111";
hex1 <= "1111";
hex2 <= "1111";
hex3 <= "1111";
my_state <= s11;
end case;
end if;
end process;
end Behavioral;
An edge detector for a de-bounced signal in the same clock domain as the state machine can be done with a flip flop with the signal input and a gate to detect the preferred state on the input (following the input edge) while the flip flop is in the other state.
signal my_btnL_event: std_logic;
signal my_btnLd: std_logic; -- architecture declarative items
process (clk)
begin
if rising_edge(clk) then
my_btnLd <= my_btnL;
end if;
my_btnL_event <= my_btnL and not my_btnLd;
Where you'd use my_btnL_event in place of my_btnL for transitioning between states.
Note this would require my_btnL to go invaid before going valid again assuming adequate de-bounce.
The my_btnL_event assignment could be expressed in multiple ways, such as an by an if statement or a conditional signal assignment.

Bitsequence detector counter doesn't work (VHDL)

I build a 4 bit sequence detector with a 16-bit input.
I wanna now how often the sequence appears in the 16 bits.
For that I use this code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY seqdec IS
PORT ( X: IN std_logic_vector(15 DOWNTO 0);
CLK: IN std_logic;
RESET:IN std_logic;
LOAD: IN std_logic;
Y: OUT std_logic);
END seqdec;
ARCHITECTURE SEQ OF seqdec IS
TYPE statetype IS (s0, s1, s2, s3, s4);
SIGNAL state, next_state: statetype;
SIGNAL counter: std_logic_vector(3 DOWNTO 0) :="0000" ;
SIGNAL temp: std_logic_vector(15 DOWNTO 0);
SIGNAL so: std_logic;
BEGIN
STATE_AKT: PROCESS (CLK, RESET)
BEGIN
IF RESET = '1' THEN
state <= s0 ;
counter <= (OTHERS => '0') ;
ELSIF CLK = '1' AND CLK'event THEN
state <= next_state ;
END IF;
END PROCESS STATE_AKT;
PISO: PROCESS (CLK, LOAD, X)
BEGIN
IF (LOAD = '1') THEN
temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
ELSIF (CLK'event and CLK='1') THEN
so <= temp(15) ;
temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
temp(0) <= '0';
END IF;
END PROCESS PISO;
STATE_CAL: PROCESS (so,state)
BEGIN
CASE state IS
WHEN s0 => IF so = '0' THEN next_state <= s0 ;
ELSE next_state <= s1 ;
END IF;
WHEN s1 => IF so = '0' THEN next_state <= s1;
ELSE next_state <= s2 ;
END IF;
WHEN s2 => IF so = '0' THEN next_state <= s3 ;
ELSE next_state <= s2 ;
END IF;
WHEN s3 => IF so = '0' THEN next_state <= s0 ;
ELSE next_state <= s4 ;
END IF;
WHEN s4 => IF so = '0' THEN next_state <= s0;
ELSE next_state <= s2 ;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS STATE_CAL;
STATE_Y: PROCESS (state)
BEGIN
CASE state IS
WHEN s4 =>
Y <= '1';
counter <= counter + '1';
WHEN OTHERS => Y <= '0' ;
END CASE;
END PROCESS STATE_Y;
END SEQ;
But neither my counter reset nor my incrementation of counter is working.
The rest is working perfect and fine.
Has somebody a hint or an idea for me?
The programm is now working fine in ModelSim, but I struggle with getting it on the board.
I simulated it several times in ModelSim, with different parameters and it works fine, so the functional part is fine.
My code looks now this way:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY seqdec IS
PORT ( X: IN std_logic_vector(15 DOWNTO 0);
CLK: IN std_logic;
RESET: IN std_logic;
LOAD: IN std_logic;
DIGIT: OUT std_logic_vector(6 DOWNTO 0) := "1111110";
COUT: OUT std_logic_vector(2 DOWNTO 0);
Y: OUT std_logic);
END seqdec;
ARCHITECTURE SEQ OF seqdec IS
TYPE statetype IS (s0, s1, s2, s3, s4);
SIGNAL state: statetype;
SIGNAL next_state: statetype:=s0;
SIGNAL counter: std_logic_vector(2 DOWNTO 0) :="000" ;
SIGNAL temp: std_logic_vector(15 DOWNTO 0);
SIGNAL so: std_logic := 'U';
-------------------Aktualisierung des Zustandes--------------------------------
BEGIN
STATE_AKT: PROCESS (CLK, RESET)
BEGIN
IF RESET = '1' THEN
state <= s0;
ELSIF CLK = '1' AND CLK'event THEN
state <= next_state ;
END IF;
END PROCESS STATE_AKT;
---------------------Counter---------------------------------------------------
COUNT: PROCESS (state, RESET)
BEGIN
IF (RESET = '1') THEN
counter <= (OTHERS => '0');
ELSIF (state = s4) THEN
counter <= counter + '1';
COUT <= counter;
END IF;
END PROCESS COUNT;
-------------------PiSo für die Eingabe des zu Prüfenden Vektors---------------
PISO: PROCESS (CLK, LOAD, X)
BEGIN
IF (LOAD = '1') THEN
temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
ELSIF (CLK'event and CLK='1') THEN
so <= temp(15);
temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
temp(0) <= '0';
END IF;
END PROCESS PISO;
-------------------Zustandsabfrage und Berechnung------------------------------
STATE_CAL: PROCESS (so,state)
BEGIN
CASE state IS
WHEN s0 => IF so = '0' THEN next_state <= s0 ;
ELSIF (so = '1') THEN next_state <= s1 ;
END IF;
WHEN s1 => IF so = '0' THEN next_state <= s1;
ELSIF (so = '1') THEN next_state <= s2 ;
END IF;
WHEN s2 => IF so = '0' THEN next_state <= s3 ;
ELSIF (so = '1') THEN next_state <= s2 ;
END IF;
WHEN s3 => IF so = '0' THEN next_state <= s0 ;
ELSIF (so = '1') THEN next_state <= s4 ;
END IF;
WHEN s4 => IF so = '0' THEN next_state <= s0;
ELSIF (so = '1') THEN next_state <= s2 ;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS STATE_CAL;
-------------------Ausgang-----------------------------------------------------
STATE_Y: PROCESS (state)
BEGIN
CASE state IS
WHEN s4 =>
Y <= '1';
WHEN OTHERS => Y <= '0' ;
END CASE;
END PROCESS STATE_Y;
-------------------7 Segment---------------------------------------------------
SEVEN_SEG: PROCESS (counter, CLK)
BEGIN
IF (RESET = '1') THEN
DIGIT <= "1111110";
END IF;
CASE counter IS
WHEN "000" => DIGIT <= "1111110";
WHEN "001" => DIGIT <= "0110000";
WHEN "010" => DIGIT <= "1101101";
WHEN "011" => DIGIT <= "1111001";
WHEN "100" => DIGIT <= "0110011";
WHEN "101" => DIGIT <= "1011011";
WHEN OTHERS => NULL;
END CASE;
END PROCESS SEVEN_SEG;
END SEQ;
When i put it on the board the 7-segment will show a "3".
I would assume, as the functional part seems to be good,that it has to do somethink with the timings, but i can't find any solution to it. If some experience VHDL-programmer could give me a new hint that would be great.
Best regards
Adrian

why the elevator stuckes in a state?

this is vhdl code for an elevator for 7 floors
the coding is encapsulated into 3 states s0=no move ,s1=move up , s2 =move down
if it is in s0 it should wait for 2 cycles after that move up/down according to the desired floor or called floor on the next positive edge .
The problem is that the elevator is stuck in s1 state
could anyone help me please ?
-- Cad Project
-- Project Name : Elevator
-- Date : 18\12\2013
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--Entity Decleration
entity Elevator is
port (call, clk, press : in std_logic;
-- Call To Call The Elevator ,press if a key is pressrd from the pannel inside the elevator .
Desire_floor, Call_Floor : in std_logic_vector (2 downto 0);
-- Desired_floor is the floor number choosed from inside the elevator .
-- called_floor is the floor number that the "Call" Key has been pressed from .
weight : in std_logic;
Door_open_close, Move_up, move_down, OverWeight : out std_logic;
-- Door_open_close is 1 when opened ,0 when closed .
-- OverWeight is 1 when the weight is over 500 KG.
Current_Floor : buffer std_logic_vector (2 downto 0) := "000";
temp1_state, temp2_state : buffer std_logic_vector (1 downto 0);
o1, o2, o3, o4, o5, o6, o7 : out std_logic_vector (2 downto 0));
end;
--architecture Decleration
architecture Elevator of Elevator is
type state is (s0, s1, s2);
--s0 state represents no move ,s1 state represents move up ,s2 state represents move down .
signal current_state : state := s0;
signal next_state : state;
signal Desired_floor, Called_Floor : std_logic_vector (2 downto 0);
signal X : std_logic := '0'; -- X is a signal used to restart the timer or to resume it's count.
signal counter : std_logic_vector (2 downto 0); -- Timer befor closing/opening the doors "timer".
signal counter2 : std_logic_vector (2 downto 0) := "000"; -- Timer for the elevator to move up or down.
signal temp1, temp2, temp3, temp4, temp5 : std_logic_vector (2 downto 0);
begin
P1 : process (clk , weight, x)
variable s11 : std_logic_vector (2 downto 0) := "000";
-- Variable insted of the counter signal -->to have the direct assigment
begin
if (weight = '1') then
OverWeight <= '1';
current_state <= s0;
elsif (clk'event and clk = '1') then
if (x = '1') then -- if X equals to 1 that means restart the timer.
s11 := "000";
elsif (x = '0') then -- if X equals 0 then count up "keep counting ".
s11 := s11+1;
end if;
current_state <= next_state;
counter <= s11;
OverWeight <= '0';
end if;
counter <= s11;
o5 <= counter;
end process P1;
P2 : process (clk) -- this process if for the 2nd timer.
variable s4 : std_logic_vector (2 downto 0) := "000";
-- Variable insted of the counter2 signal -->to have the direct assigment
begin
if (rising_edge(clk)) then
if (press = '1') then
Desired_floor <= Desire_floor;
if (Current_Floor < Desired_floor) then
s4 := s4 +1;
elsif (Current_Floor > Desired_floor) then
s4 := s4 -1;
end if;
counter2 <= s4;
elsif (call = '1') then
Called_Floor <= Call_Floor;
if (Current_Floor < Called_Floor) then
s4 := s4 +1;
elsif (Current_Floor > Called_Floor) then
s4 := s4 -1;
end if;
end if;
end if;
counter2 <= s4;
o1 <= counter2;
o2 <= Desired_floor;
o3 <= Called_Floor;
counter2 <= s4;
--Desired_floor<=Desire_floor;
end process P2;
P3 : process (counter, current_state)
begin
case current_state is
when s0 =>
if(counter < "001") then
x <= '0';
Current_Floor <= Current_Floor;
next_state <= s0;
temp1_state <= "00";
else
if (press = '1') then
if(Desired_floor > Current_Floor) then
next_state <= s1;
temp2_state <= "01";
elsif (Desired_floor < Current_Floor) then
next_state <= s2;
temp2_state <= "10";
end if;
else
if (call = '1') then
if (Called_Floor > Current_Floor) then
next_state <= s1;
temp2_state <= "01";
elsif (Called_Floor < Current_Floor) then
next_state <= s2;
temp2_state <= "10";
end if;
end if;
end if;
x <= '1';
end if;
Door_open_close <= '1';
Move_up <= '0';
move_down <= '0';
Current_Floor <= counter2;
temp1_state <= "00";
when s1 =>
temp1 <= (Desired_floor - Current_Floor);
temp2 <= (Called_Floor-Current_Floor);
o4 <= temp1;
if ((temp1 /= "000") or (temp2 /= "000")) then
next_state <= s1;
temp2_state <= "01";
Current_Floor <= counter2;
elsif (((Desired_floor-Current_Floor) = "000")or ((Called_Floor-Current_Floor) = "000")) then
next_state <= s0;
temp2_state <= "00";
end if;
Door_open_close <= '0';
Move_up <= '1';
move_down <= '0';
Current_Floor <= counter2;
x <= '1';
temp1_state <= "01";
when s2 =>
temp3 <= (Current_Floor-Desired_floor);
temp4 <= (Current_Floor-Called_Floor);
if ((temp3 /= "000") or (temp4 /= "000")) then
next_state <= s2;
temp2_state <= "10";
Current_Floor <= counter2;
elsif (((Current_Floor-Desired_floor) = "000") or ((Called_Floor-Current_Floor) = "000")) then
next_state <= s0;
temp2_state <= "00";
end if;
Door_open_close <= '0';
Move_up <= '0';
move_down <= '1';
Current_Floor <= counter2;
x <= '1';
temp1_state <= "10";
end case;
end process P3;
end;
**********************************
I mad a lot of changes on the code and still have a problem .How can i save the value of an input at a certain state and ignore it's value until the next entering of the same state
-- Cad Project .
-- Project Name : Elevator .
-- Date : 18\12\2013.
-- Group Number : 13.
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--Entity Decleration
entity Elevator is
port (clk, press : in std_logic;
-- Call To Call The Elevator ,press if a key is pressrd from the pannel inside the elevator .
Desire_floor : in std_logic_vector (2 downto 0);
-- Desired_floor is the floor number choosed from inside the elevator .
-- called_floor is the floor number that the "Call" Key has been pressed from .
weight : in std_logic;
Door_open_close, Move_up, move_down, OverWeight : out std_logic;
-- Door_open_close is 1 when opened ,0 when closed .
-- OverWeight is 1 when the weight is over 500 KG.
Current_Floor : buffer std_logic_vector (2 downto 0) := "000";
temp1_state, temp2_state : buffer std_logic_vector (1 downto 0);
o1, o2, o3, o4, o5, o6, o7 : out std_logic_vector (2 downto 0));
end;
--architecture Decleration
architecture Elevator of Elevator is
type state is (s0, s1, s2);
--s0 state represents no move ,s1 state represents move up ,s2 state represents move down .
signal current_state : state := s0;
signal next_state : state;
signal Desired_floor : std_logic_vector (2 downto 0);
signal X : std_logic := '0'; -- X is a signal used to restart the timer or to resume it's count.
signal counter : std_logic_vector (2 downto 0); -- Timer befor closing/opening the doors "timer".
signal counter2 : std_logic_vector (2 downto 0) := "000"; -- Timer for the elevator to move up or down.
signal temp1, temp2, temp3, temp4, temp5 : std_logic_vector (2 downto 0);
signal temp6 : std_logic;
begin
P1 : process (clk , weight, x)
variable s11 : std_logic_vector (2 downto 0) := "000";
-- Variable insted of the counter signal -->to have the direct assigment
begin
if (weight = '1') then
OverWeight <= '1';
current_state <= s0;
elsif (clk'event and clk = '1') then
if (x = '1') then -- if X equals to 1 that means restart the timer.
s11 := "000";
elsif (x = '0') then -- if X equals 0 then count up "keep counting ".
s11 := s11+1;
end if;
current_state <= next_state;
counter <= s11;
OverWeight <= '0';
end if;
counter <= s11;
o5 <= counter;
end process P1;
P2 : process (clk) -- this process if for the 2nd timer.
variable s4 : std_logic_vector (2 downto 0) := "000";
-- Variable insted of the counter2 signal -->to have the direct assigment
begin
if (rising_edge(clk)) then
if (press = '1') then
if (Current_Floor < Desired_floor) then
s4 := s4 +1;
elsif (Current_Floor > Desired_floor) then
s4 := s4 -1;
end if;
counter2 <= s4;
end if;
end if;
counter2 <= s4;
o1 <= counter2;
o2 <= Desired_floor;
counter2 <= s4;
end process P2;
P3 : process (counter, current_state)
begin
case current_state is
when s0 =>
if(counter < "010") then
x <= '0';
Current_Floor <= Current_Floor;
next_state <= s0;
temp1_state <= "00";
else
if (press = '1') then
if(Desired_floor > Current_Floor) then
next_state <= s1;
temp2_state <= "01";
elsif (Desired_floor < Current_Floor) then
next_state <= s2;
temp2_state <= "10";
end if;
end if;
x <= '1';
end if;
Door_open_close <= '1';
Move_up <= '0';
move_down <= '0';
Current_Floor <= counter2;
temp1_state <= "00";
temp6 <= '1';
when s1 =>
temp1 <= (Desired_floor - Current_Floor);
o4 <= temp1;
if ((temp1 /= "000")) then
next_state <= s1;
temp2_state <= "01";
Current_Floor <= counter2;
elsif ((Desired_floor-Current_Floor) = "000") then
next_state <= s0;
temp2_state <= "00";
end if;
Door_open_close <= '0';
Move_up <= '1';
move_down <= '0';
Current_Floor <= counter2;
x <= '1';
temp1_state <= "01";
temp6 <= '0';
when s2 =>
temp3 <= (Current_Floor-Desired_floor);
if ((temp3 /= "000")) then
next_state <= s2;
temp2_state <= "10";
Current_Floor <= counter2;
elsif ((Current_Floor-Desired_floor) = "000") then
next_state <= s0;
temp2_state <= "00";
end if;
Door_open_close <= '0';
Move_up <= '0';
move_down <= '1';
Current_Floor <= counter2;
x <= '1';
temp1_state <= "10";
temp6 <= '0';
end case;
end process P3;
P4 : process (temp6, clk)
begin
if (clk 'event and clk = '1') then
if (temp6'event and temp6 = '1')then
--if ( current_state =s0 ) then
Desired_floor <= Desire_floor;
else
Desired_floor <= Desired_floor;
end if;
Desired_floor <= Desired_floor;
end if;
end process P4;
end;
It looks like the floor counter is only being incremented when the user presses 'press'.
Explanation
If we're not on the desired floor yet, then Current_Floor is driven by counter2
temp1 <= (Desired_floor - Current_Floor);
o4 <= temp1;
if ((temp1 /= "000")) then
next_state <= s1;
temp2_state <= "01";
Current_Floor <= counter2;
counter2 is driven by s4:
if (rising_edge(clk)) then
if (press = '1') then
if (Current_Floor < Desired_floor) then
s4 := s4 +1;
elsif (Current_Floor > Desired_floor) then
s4 := s4 -1;
end if;
counter2 <= s4; <-
end if;
end if;
counter2 <= s4; <-
o1 <= counter2;
o2 <= Desired_floor;
counter2 <= s4; <-
(Aside, why do you assign s4 to counter2 three times?)
s4 is only changed when press is asserted. So your lift is only going to be moving up or down a floor when someone pushes the button.
General comments
Your process sensitivity lists are all over the place! Your sensitivity lists should either be clock or clock,reset. Asynchronous processes (those without a clock in the sensitivity list) do have their place, but I generally avoid them unless absolutely necessary. I find it a lot easier to visualise the timing behaviour in my head when everything is strictly synchronous.
P1 : process (clk , weight, x) <- BAD
P2 : process (clk) <- GOOD
P3 : process (counter, current_state) <- OKAY
P4 : process (temp6, clk) <- BAD
Indenting has a huge impact on how you read the code. Learn to indent properly. I use the emacs VHDL mode, it has a great beautify function which really helps. I ran your code through it when I edited the comment and wrote this answer.
Your signal names need work. things like temp are a bad idea. you are doing pretty well with commenting though, so that's a plus. keep that up!
I'm going to briefly mention the code redundancy, example:
if (temp6'event and temp6 = '1')then
--if ( current_state =s0 ) then
Desired_floor <= Desire_floor;
else
Desired_floor <= Desired_floor;
end if;
Desired_floor <= Desired_floor;
If it was different before, totally understandable, but clean that stuff up, unnecessary reading for whoever is on the receiving end of your code.

Resources