state machine question

This is a discussion on state machine question within the vhdl forums in Programming Languages category; 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 ...

Go Back   Application Development Forum > Programming Languages > vhdl

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-17-2008, 10:13 AM
logitech
Guest
 
Default state machine question

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/m...f?t=1218982255
I can't use sensitivity list because I must have "wait until" in my
states...
Thank you!


Reply With Quote
  #2  
Old 08-17-2008, 02:31 PM
rickman
Guest
 
Default Re: state machine question

On Aug 17, 10:13 am, "logitech" <kljunas.cudnov...@gmail.com> 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/m...achine.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
Reply With Quote
  #3  
Old 08-18-2008, 10:46 AM
logitech
Guest
 
Default Re: state machine question

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-hambu...L-Cookbook.pdf,
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.






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


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

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-hambu...L-Cookbook.pdf,
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.




> 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



Reply With Quote
  #4  
Old 08-18-2008, 01:29 PM
rickman
Guest
 
Default Re: state machine question

On Aug 18, 10:46 am, "logitech" <t...@fr.hr> 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-hambu...book/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-hambu...book/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
Reply With Quote
  #5  
Old 08-19-2008, 10:44 AM
logitech
Guest
 
Default Re: state machine question


>
> Without seeming rude, it appears that you are fairly new to HDL and
> possibly FPGA design.
> Rick


You are right, I am beginner to HDL... Your post has been helpful, I figured
out how to design my FSM. Thanks!


Reply With Quote
  #6  
Old 08-19-2008, 11:35 AM
Ralf Hildebrandt
Guest
 
Default Re: state machine question

logitech schrieb:

> 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?).


Hmm .. many states for every bit? - What about a simple counter?


> So I found one processor design on web that don't use sensitivity
> list
> (http://tams-www.informatik.uni-hambu...L-Cookbook.pdf,
> page 92.).


Although this is quite a good reference for VHDL it is definitely not a
good paper for learning synthesizable VHDL. There is a lot of not
synthesizable code included in this paper.

I used "HDL Chip Design" by Douglas J. Smith for learing VHDL / Verilog.
Now after knowing what I am doing I use the VHDL cookbook as a reference.


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


While you are learing VHDL: forget the "wait until" for a while. Stick
to the synchronous templeate:

process(async_reset_n,clk)
begin
if (async_reset_n='0') then
-- do some async reset here
elsif rising_edge(clk) then
-- do some synchronous stuff here
end if;
end process;


Build a classic state machine. And if you need to stay in one state for
a number of cycles, then use a counter to count the number of cycles.


Ralf
Reply With Quote
  #7  
Old 08-19-2008, 12:05 PM
whygee
Guest
 
Default Re: state machine question

logitech wrote:
>> Without seeming rude, it appears that you are fairly new to HDL and
>> possibly FPGA design.
>> Rick

>
> You are right, I am beginner to HDL... Your post has been helpful, I figured
> out how to design my FSM. Thanks!


On the contrary, I thought that the FSM had created us
http://www.venganza.org/
(sorry, I could not resist but every time I read "FSM",
I can't stop thinking about this "thing")

yg
Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 03:48 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.