Comments on my code

Discussion in 'VHDL' started by daveip, Apr 4, 2008.

  1. daveip

    daveip

    Joined:
    Apr 25, 2007
    Messages:
    6
    Likes Received:
    0
    Hi ... I'm hoping someone could comment on my code.
    It compiles fine in model sim but I just don't think it'll work

    Anywhos ... here it is:

    ------------------------------------------------------------------

    ibrary IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_unsigned.all;
    use IEEE.Numeric_STD.all;

    entity statemachine is
    port(
    clock : in std_logic;
    reset : in std_logic;
    in_pin : in std_logic;
    out_pin: in std_logic;
    empty : out std_logic;
    full : out std_logic;
    err : out std_logic;
    number : out std_logic_vector (7 downto 0)
    );
    end;

    architecture struct of statemachine is

    type state is (S_ERROR, S_FULL, S_EMPTY, S_ADD, S_SUB, S_NORMAL); -- 11 states
    signal next_state,current_state : state;


    begin

    --------------------------------
    -- RESET PROCEDURE
    --------------------------------

    zero : process(clock)
    begin
    if (reset = '1') then
    current_state <= S_EMPTY; --go to empty state
    number <= "00000000"; --reset counter to zerp
    err <= '0'; --error value = 0
    full <= '0'; --full = 0
    empty <= '1'; --empty = 1 as full reset
    elsif rising_edge(clock) then
    current_state <= next_state; --on each clock cycle, move to next state
    else null;
    end if;
    end process zero;


    ------------------------------
    -- STATE MACHINE
    ------------------------------

    states : process(current_state, in_pin, out_pin)

    variable v_state : state;
    variable v_err, v_full, v_empty : std_logic;
    variable v_number : std_logic_vector(7 downto 0);

    begin

    case v_state is

    when S_ERROR =>
    v_err := '1';
    v_state := S_ERROR;

    when S_FULL =>
    if (in_pin = '1') then
    v_state := S_ERROR;
    elsif (out_pin = '1') then
    v_number := v_number - 1;
    v_state := S_NORMAL;
    else null;
    end if;


    when S_EMPTY =>
    if (out_pin = '1') then
    v_state := S_ERROR;
    elsif (in_pin = '1') then
    v_number := v_number + 1;
    v_state := S_NORMAL;
    else null;
    end if;


    when S_ADD =>
    if (v_number = "11111110") then
    v_number := "11111111";
    v_state := S_FULL;
    else
    v_number := v_number + 1;
    v_state := S_NORMAL;
    end if;

    when S_SUB =>
    if (v_number = "00000001") then
    v_number := "00000000";
    v_state := S_EMPTY;
    else
    v_number := v_number - 1;
    v_state := S_NORMAL;
    end if;

    when S_NORMAL =>
    v_full := '0';
    v_empty := '0';
    if rising_edge(in_pin) then
    v_state := S_ADD;
    elsif rising_edge(out_pin) then
    v_state := S_SUB;
    else null;
    end if;

    when others => null;


    end case;

    next_state <= v_state;
    err <= v_err;
    full <= v_full;
    empty <= v_empty;
    number <= v_number;


    end process;

    end struct;

    -------------------------------------------------------------------

    Its been a while since I played with VHDL. I can't remember how to assign the initial state without assigning 1 to the reset pin.

    Anything constructive is welcomed =)
     
    daveip, Apr 4, 2008
    #1
    1. Advertisements

  2. daveip

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Likes Received:
    0
    Location:
    Denmark
    These lines are the bad ones from a synthesize point of view - but for simulation are the ok.
    The process surposed to produce combinatirial logic but you mix it with edge sentive stuff.

    The if rising_edge .... then .... elsif rising_edge ... will aways give you errors.

    Rething your design.

    PHP:
    v_full := '0';
    v_empty := '0';
    if rising_edge(in_pin) then
    v_state := S_ADD;
    elsif rising_edge(out_pin) then
    v_state := S_SUB;
    else null;
    end if;
    your welcome
    Jeppe
     
    Last edited: Apr 4, 2008
    jeppe, Apr 4, 2008
    #2
    1. Advertisements

  3. daveip

    daveip

    Joined:
    Apr 25, 2007
    Messages:
    6
    Likes Received:
    0
    Thanks for your reply Jeppe.

    Yeah I know that it won't synthesise.

    The task I've been set is to implement the VHDL code in Xilinx and build timing constraints from Xilinx to return back to modelsim to simulate it. If that makes sense =S

    I'm not sure how else to implement the input signals. My lecturer hasn't described to me the way the input signal is triggered and for how long. I have to make assumptions and I'm assuming that for each item that passes a sensor, the best way to count them would be the use of edge triggers.

    I'm thinking of possibly adding a "holding state" where the machine waits for either signal to fall back to zero. But my problem there would be this situation: if the item is triggering the sensor on the in_pin and the machine enters the holding state, it will miss anything passing the out_pin whilst it's still in this state.

    I'm abit stuck as to how best to implement this code =/
     
    daveip, Apr 4, 2008
    #3
  4. daveip

    daveip

    Joined:
    Apr 25, 2007
    Messages:
    6
    Likes Received:
    0
    I think i have it figured?

    I'll have to detect the edge somehow and hold that value for just 1 clock cycle. .... how i haven't figured yet =/
     
    daveip, Apr 5, 2008
    #4
  5. daveip

    daveip

    Joined:
    Apr 25, 2007
    Messages:
    6
    Likes Received:
    0
    PHP:
    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_unsigned.all;
    use IEEE.Numeric_STD.all;

    entity statemachine is
        port(
            clock : in std_logic;
            reset : in std_logic;
            in_pin : in std_logic;
            out_pin: in std_logic;
            empty : out std_logic;
            full : out std_logic;
            err : out std_logic;
            number : out std_logic_vector (7 downto 0)
            );
        end;

    architecture struct of statemachine is

    type state is (S_ERROR, S_FULL, S_EMPTY, S_ADD, S_SUB, S_NORMAL);  
    signal next_state,current_state : state;
    signal s_in, s_out : std_logic;


    begin
       
    --------------------------------
    -- RESET PROCEDURE
    --------------------------------

    zero : process(clock,reset)
    begin
        if (reset = '1') then        
            number <= "11111111";          --reset counter to zerp
            err <= '0';                    --error value = 0
            full <= '0';                   --full = 0
            empty <= '1';                  --empty = 1 as full reset
            current_state <= S_EMPTY;      --go to empty state
            elsif rising_edge(clock) then
                current_state <= next_state;
        end if;
    end process zero;

       
    in_latch : process(clock,in_pin)
    begin
        if rising_edge(in_pin) then
            s_in <= '1';
            else
            s_in <= '0';
        end if;
    end process;

    out_latch : process(clock,out_pin)
    begin
        if rising_edge(out_pin) then
            s_out <= '1';
            else
            s_out <= '0';
        end if;
    end process;
       
       
    ------------------------------
    -- STATE MACHINE
    ------------------------------

    states : process(current_state, s_in, s_out)

    variable v_state : state;
    variable v_err, v_full, v_empty : std_logic;
    variable v_number : std_logic_vector(7 downto 0);

    begin
       
        case v_state is
           
            when S_EMPTY =>
                if (s_out = '1') then
                    v_state := S_ERROR;
                    elsif (s_in = '1') then
                        v_number := v_number + 1;
                        v_state := S_NORMAL;
                        else v_state := S_EMPTY;
                    end if;
                   
            when S_NORMAL =>
                v_full := '0';
                v_empty := '0';
                if (s_in = '1') then
                    v_state := S_ADD;
                elsif (s_out = '1') then
                    v_state := S_SUB;
                    else null;
                end if;

            when S_ERROR =>
                v_err := '1';
                v_state := S_ERROR;
               
            when S_FULL =>
                if (s_in = '1') then
                    v_state := S_ERROR;
                    elsif (s_out = '1') then
                        v_number := v_number - 1;
                        v_state := S_NORMAL;
                        else null;
                    end if;
               
            when S_ADD =>
                if (v_number = "11111110") then
                    v_number := "11111111";
                    v_state := S_FULL;
                    else
                    v_number := v_number + 1;
                    v_state := S_NORMAL;
                end if;
               
            when S_SUB =>
                if (v_number = "00000001") then
                    v_number := "00000000";
                    v_state := S_EMPTY;
                    else
                    v_number := v_number - 1;
                    v_state := S_NORMAL;
                end if;
               

           
            when others => null;
               
               
           end case;
           
        next_state <= v_state;
        err <= v_err;
        full <= v_full;
        empty <= v_empty;
        number <= v_number;                    

    end process;

       
       
    end struct;
           
    there's the updated code. I've built a test bench for the machine but there's a problem i can't figure! I'm trying to assign the initial values of the outputs by resetting before doing anything.

    the simulator isn't showing the updated outputs getting zeroed ... but leaving them undefined and next state seems to be stuck on my error state =/

    i figured the latch and it works perfectly!!!

    anyone able to lend a hand please?
     
    daveip, Apr 5, 2008
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.