Re: state machine question

Discussion in 'VHDL' started by rickman, Aug 17, 2008.

  1. rickman

    rickman Guest

    On Aug 17, 10:13 am, "logitech" <> wrote:
    > Hi!
    > I have one question about this code I wrote:
    >
    > library IEEE;
    > use IEEE.std_logic_1164.all;
    > use IEEE.std_logic_arith.all;
    > use IEEE.std_logic_unsigned.all;
    >
    > entity sm is
    > port (mclk : in std_logic;
    > load_en : in bit;
    > output : out std_logic_vector(3 downto 0));
    > end sm;
    >
    > architecture RTL of sm is
    >
    > type state is (a,
    > b,
    > c);
    > signal current_state, next_state: state;
    >
    > begin
    >
    > state_machine: process
    > begin
    >
    > wait until mclk = '1';
    > if load_en = '0' then
    > wait until load_en = '1';
    > current_state <= b;
    > else
    > current_state <= next_state;
    > end if;
    >
    > case current_state is
    > when a =>
    > output <= "1000";
    > next_state <= b;
    > when b =>
    > output <= "0100";
    > next_state <= c;
    > when c =>
    > output <= "0010";
    > next_state <= a;
    > end case;
    >
    > end process;
    >
    > end architecture RTL;
    >
    > -----------------------------
    >
    > Question is: why ins't state changed on every rising clock? And how can
    > "current_state" and "next_state" be the same (like state "c" on 5th clock
    > period)... Here is picture:http://i107.photobucket.com/albums/m308/tante_01/statemachine.gif?t=1...
    > I can't use sensitivity list because I must have "wait until" in my
    > states...
    > Thank you!


    I can honestly say I don't understand what you are trying to do. You
    have two waits in this process. My understanding is that this is not
    synthesizable. If it does not need to be synthesizable, then it may
    still have an issue with the load_en signal. When load_en = '0', you
    seem to hang the process until it becomes a '1'. Meanwhile the state
    does not change until load_en is '1' and the clock is ignored.

    This is not how a typical register works.

    When you say you "must" have a "wait until" in your code, that makes
    me think this is a school assignment. Even so, this is a bit odd
    because this sort of construct is nearly never used other than in a
    simulation test bench perhaps.

    Rick
    rickman, Aug 17, 2008
    #1
    1. Advertising

  2. rickman

    rickman Guest

    On Aug 18, 10:46 am, "logitech" <> wrote:
    > This is what I need to do: I have external 2048 B EEPROM memory, and I need
    > to make module which will read 16 bit words form EEPROM via SPI serial bus
    > and store them to internal SRAM memory. All this starts when load_en is '1'.
    > What I wanted to do is make this without sensitivity list because if I use
    > sensitivity list, I would need many states (one state for every bit I want
    > to read?). So I found one processor design on web that don't use sensitivity
    > list
    > (http://tams-www.informatik.uni-hamburg.de/vhdl/doc/cookbook/VHDL-Cook...,
    > page 92.). I don't know if this is trivial to you, can you tell me how would
    > you writ this: to read from memory, you must set chip select, then send a
    > start bit, then 2 op-code bits, then address bits. I thought "wait until
    > mclk" after every instruction would work.
    >
    > Sorry for my bad English, I hope you understand what I want to say.


    Your English is not a problem. It is quite good enough to explain
    technical details.

    Without seeming rude, it appears that you are fairly new to HDL and
    possibly FPGA design. Your explanation of needing separate states for
    each bit because of the use of a sensitivity list is wrong. The two
    are not related. In any event, unless the EEPROM gives you some
    feedback that you have read a word from it (which I doubt), you will
    need a FSM that can count the bits. However, you don't need to
    consider this counter to be a part of your FSM. It can be a counter
    with an output on reaching 16 bits (or whatever qty you need). You
    will also need a separate counter that can count the 2048 bytes.

    The FSM and each counter will need to be written in a clocked process
    like this...

    ENTITY CntrComp is
    GENERIC (
    Width : natural := 2
    );
    PORT (
    SysClk : in std_logic ;
    SysRst : in std_logic ;
    ClkEn : in std_logic;
    Load : in std_logic;
    Input : in unsigned (Width downto 0);
    TermCnt : out std_logic
    );
    END CntrComp;

    architecture RTL of CntrComp is
    signal Cntr : unsigned (Width downto 0); -- Register

    begin
    LFSReg : process (SysClk, SysRst) begin
    if (SysRst = '1') then
    Cntr <= to_unsigned(1, Cntr'length);
    elsif (rising_edge(SysClk)) then
    if (Load = '1') then
    Cntr <= Input; -- Reload and restart counter
    elsif (ClkEn = '1') then
    if (Cntr /= 0) then
    Cntr <= Cntr - 1;
    end if;
    end if;
    end if;
    end process LFSReg;

    TermCnt <= '1' when (Cntr = 0) else '0'; -- Flag terminal count

    end RTL;

    I think this is error free, but I didn't test it. Using SysClk and
    SysRst in the sensitivity list and the IF constructs this way creates
    a register. Using a wait may not do that and if you use two waits on
    different signals, I can assure you that it will not synthesize what
    you want. VHDL can be used as a programming language, but all VHDL
    programs are not synthesizable. You have to stick with certain
    constructs.


    > I want to do nothing until load_en is '1' and than, when it becomes '1' i
    > want to change states on every rising mclk...


    The example above will do that.


    > This is what I need to do: I have external 2048 B EEPROM memory, and I need
    > to make module which will read 16 bit words form EEPROM via SPI serial bus
    > and store them to internal SRAM memory. All this starts when load_en is '1'.
    > What I wanted to do is make this without sensitivity list because if I use
    > sensitivity list, I would need many states (one state for every bit I want
    > to read?). So I found one processor design on web that don't use sensitivity
    > list
    > (http://tams-www.informatik.uni-hamburg.de/vhdl/doc/cookbook/VHDL-Cook...,
    > page 92.). I don't know if this is trivial to you, can you tell me how would
    > you writ this: to read from memory, you must set chip select, then send a
    > start bit, then 2 op-code bits, then address bits. I thought "wait until
    > mclk" after every instruction would work.


    There are still a lot of questions that need to be answered to solve
    your problem. Mostly you have not defined the application well
    enough.

    How many address bits, 11?

    Do you always want to transfer 2048 bytes?

    Is load_en pulsed for one clock or does it stay asserted until an
    acknowledge flag is set?

    You should use a pair of shift registers, two counters and a simple
    FSM to implement this task. Think of how you would design this job in
    hardware and then write the HDL to describe the hardware. Works every
    time!

    Rick
    rickman, Aug 18, 2008
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Lamb
    Replies:
    1
    Views:
    659
  2. Weng Tianxiang
    Replies:
    7
    Views:
    1,086
    Mike Treseler
    Nov 25, 2003
  3. Weng Tianxiang
    Replies:
    3
    Views:
    1,374
    Weng Tianxiang
    Jul 25, 2006
  4. Grumps
    Replies:
    2
    Views:
    670
    Grumps
    Feb 13, 2008
  5. fenster
    Replies:
    3
    Views:
    1,152
    jeppe
    Dec 23, 2011
Loading...

Share This Page