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.

Finite state machine VS rising edge

Status
Not open for further replies.

Feco

Newbie level 6
Joined
May 13, 2013
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,371
Hello.
I have a finite state machine and I want it to change from state 'idle' to state 'start' when I press a button called 'EN' (rising_edge(EN)). My problem is, it doesn't behave like I wanted. If I press the EN button and keep it pressed, the fsm is going to change the states in every clock cycle, however is shouldn't, only if it detects a rising edge.

So it works like [if EN = '1'] instead of [if rising_edge(EN)], but I have no idea why.
Here is the code:

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity uart is
    Port ( CLK : in  STD_LOGIC;
           EN : in  STD_LOGIC;
           tx : out  STD_LOGIC);
end uart;

architecture Behavioral of uart is

type state is (idle, start, d0, d1, d2, d3, d4, d5, d6, d7, stop);

signal curr_s, next_s : state;

constant data : STD_LOGIC_VECTOR (7 downto 0) := "00111100";

begin

state_proc : process(CLK)
begin
    if (rising_edge(CLK)) then
        curr_s <= next_s;
    end if;
end process;

fsm_proc : process(curr_s, EN)
begin
    case curr_s is
        when idle  => tx      <= '1';
                        if (rising_edge(EN)) then --THAT IS THE PROBLEM
                            next_s <= start;
                        else
                            next_s <= idle;
                        end if;
        when start =>  tx      <= '0';
                            next_s <= d0;
        when d0      =>  tx      <= data(0);
                            next_s <= d1;
        when d1      =>  tx      <= data(1);
                            next_s <= d2;
        when d2      =>  tx      <= data(2);
                            next_s <= d3;
        when d3      =>  tx      <= data(3);
                            next_s <= d4;
        when d4      =>  tx      <= data(4);
                            next_s <= d5;
        when d5      =>  tx      <= data(5);
                            next_s <= d6;
        when d6      =>  tx      <= data(6);
                            next_s <= d7;
        when d7      =>  tx      <= data(7);
                            next_s <= stop;
        when others=>  tx      <= '1';
                            next_s <= idle;
    end case;
end process;
end Behavioral;

Thanks.
 

you need to make an edge detector - register en and then compare en to the registered version.

PS. you cannot detect rising edge on en the way you have it - you cannot create logic like that.
 
  • Like
Reactions: Feco

    Feco

    Points: 2
    Helpful Answer Positive Rating
@Feco
its detecting edge only just check simulation.....but its detecting only when he state machine is in ideal state......
ones it goes to start state it will not care about the " w.pngEN"
 

@TrickyDicky:
That's working fine, thx.
But I still don't know why my solution doesn't work, care to explain?

@sagar.bavane:
The simulation is good, that's how it should work, but in real life it wasn't like that.
 

the rising_edge function (or clk'event detection) can only be done on a clock. so it should be the outermost thing in your code, and should encompas everyhing within in. You cannot detect a rising edge with logic.
 

you need to make an edge detector - register en and then compare en to the registered version.

PS. you cannot detect rising edge on en the way you have it - you cannot create logic like that.

I think this is a valid solution. On every clock edge you register state of 'EN' and then compare vs currently held value in that register. If the old value is '0' and new is '1' then there was a rising edge in between and you make your FSM change state.

So something like
Code:
reg EN_reg;

process (CLK, EN)
begin
  if(rising_edge(CLK))
  begin
    EN_reg<=EN;
  if(EN='1' and EN_reg='0')then
    //do whaterver you need here to change state
   end if
  end
end process
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top