state machine question

L

logitech

Guest
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=1218982255
I can't use sensitivity list because I must have "wait until" in my
states...
Thank you!
 
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-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-hamburg.de/vhdl/doc/cookbook/VHDL-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
 
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 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/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
 
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-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
 
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-hamburg.de/vhdl/doc/cookbook/VHDL-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
 
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
 

Welcome to EDABoard.com

Sponsor

Back
Top