state machine problem in vhdl

A

anupam

Guest
Hi alls,
I am facing problem with the following process.
state machine from state "0001" goes to state "0011" instead of "0010"
when the wr signal is low.
Can u suggest something ?

Regards,

Anupam


PROCESS (rst, extclk) --PROCESS no 01

BEGIN
IF rst = '0' THEN
temp_w <= "0000";
wrpointer_tx <= (OTHERS => (OTHERS => '0'));
wren_txram <= '0';
wraddress_txram <= (OTHERS => '0');
ELSIF rising_edge(extclk) THEN
case temp_w is
when "0000" =>
wren_txram <= '0';
IF cs = '0' AND offset < "100000" THEN
temp_w <= "0001";
else temp_w <= "0000";
end if;
when "0001" =>
wren_txram <= '0';
wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
data2txram <= datain;
if wr = '0' then
temp_w <= "0010";
elsif rd = '0' then
temp_w <= "0000";
else temp_w <= "0001";
end if;
when "0010" =>
temp_w <= "0100";
wren_txram <= '1';
wrpointer_tx(conv_integer(ch_no)) <=
wrpointer_tx(conv_integer(ch_no)) + 1;
when "0100" =>
wren_txram <= '1';
IF cs = '1' OR wr = '1' THEN
temp_w <= "0000";

ELSE
temp_w <= "0100";
END IF;

when others => null;
end case;
IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
datain(bit_XRES) = '1' THEN
wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
END IF;
END IF;
END PROCESS;
 
Try to change this

----------------------------
if wr = '0' then
temp_w <= "0010"
elsif rd = '0' then
temp_w <= "0000";
else temp_w <= "0001";
end if;

---------------------------------------
****(if+ elsif + else) i hate this code....

by this:

---------------------------------
temp_w <= "0001";
if wr = '0' then
temp_w <= "0010"
elsif rd = '0' then
temp_w <= "0000";
end if;
---------------------------------


"anupam" <anupam@coraltele.com> a écrit dans le message de
news:51b73fd7a32b97ab3c4b804d2d834b7c@localhost.talkaboutprogramming.com...
Hi alls,
I am facing problem with the following process.
state machine from state "0001" goes to state "0011" instead of "0010"
when the wr signal is low.
Can u suggest something ?

Regards,

Anupam


PROCESS (rst, extclk) --PROCESS no 01

BEGIN
IF rst = '0' THEN
temp_w <= "0000";
wrpointer_tx <= (OTHERS => (OTHERS => '0'));
wren_txram <= '0';
wraddress_txram <= (OTHERS => '0');
ELSIF rising_edge(extclk) THEN
case temp_w is
when "0000" =
wren_txram <= '0';
IF cs = '0' AND offset < "100000" THEN
temp_w <= "0001";
else temp_w <= "0000";
end if;
when "0001" =
wren_txram <= '0';
wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
data2txram <= datain;
if wr = '0' then
temp_w <= "0010";
elsif rd = '0' then
temp_w <= "0000";
else temp_w <= "0001";
end if;
when "0010" =
temp_w <= "0100";
wren_txram <= '1';
wrpointer_tx(conv_integer(ch_no)) <=
wrpointer_tx(conv_integer(ch_no)) + 1;
when "0100" =
wren_txram <= '1';
IF cs = '1' OR wr = '1' THEN
temp_w <= "0000";

ELSE
temp_w <= "0100";
END IF;

when others => null;
end case;
IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
datain(bit_XRES) = '1' THEN
wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
END IF;
END IF;
END PROCESS;
 
Vince a écrit:
Try to change this
----------------------------
if wr = '0' then
temp_w <= "0010"
elsif rd = '0' then
temp_w <= "0000";
else temp_w <= "0001";
end if;
---------------------------------------
****(if+ elsif + else) i hate this code....
by this:
---------------------------------
temp_w <= "0001";
if wr = '0' then
temp_w <= "0010"
elsif rd = '0' then
temp_w <= "0000";
end if;
---------------------------------
Strictly equivalent, this won't change anything.
I think the problem comes from wr which is probably asynchronous, or
badly resynchronized.


--
____ _ __ ___
| _ \_)/ _|/ _ \ Adresse de retour invalide: retirez le -
| | | | | (_| |_| | Invalid return address: remove the -
|_| |_|_|\__|\___/
 
Nicolas Matringe wrote:

I think the problem comes from wr which is probably asynchronous, or
badly resynchronized.
I agree. Find all the inputs not synchronous with extclk,
and fix them something like this:

http://groups.google.com/groups?q=test_dqdq

Your code looks good otherwise.

-- Mike Treseler
 
Mike Treseler wrote:
Nicolas Matringe wrote:

I think the problem comes from wr which is probably asynchronous, or
badly resynchronized.

I agree. Find all the inputs not synchronous with extclk,
and fix them something like this:

http://groups.google.com/groups?q=test_dqdq

Your code looks good otherwise.
I think the code will work, but it looks like he is trying to use
one-hot encoding, but I don't think this is going to work. Plus I see
one possible error. He is using four states, 0000, 0001, 0010 and
0100. The msb never changes. I think the states should be 0001, 0010,
0100 and 1000. Plus the way he has coded this, unless the compiler is
very smart about recognizing one-hit encoding, it will still generate
logic to decode all four bits on each transition.

To use one-hot encoding, typically an enumerated type is used and an
attribute is added to indicate one-hot encoding. I don't like this
myself since I am not sure it is fully portable. So I construct my
one-hot FSM by describing the various bits separately. temp_w(0) <=
f(...). Then the optimal logic is easily obtained.

--

Rick "rickman" Collins

rick.collins@XYarius.com
Ignore the reply address. To email me use the above address with the XY
removed.

Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design URL http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX
 
So I construct my
one-hot FSM by describing the various bits separately. temp_w(0) <=
f(...). Then the optimal logic is easily obtained.
I did'nt understand the way you said in the last line. Can I get an
example it clarify myself.

Thanks.

Mohammed A.khader.
 
Hi alls,
I am facing problem with the following process.
state machine from state "0001" goes to state "0011" instead of "0010"
when the wr signal is low.
Can u suggest something ?

Regards,

Anupam


PROCESS (rst, extclk) --PROCESS no 01

BEGIN
IF rst = '0' THEN
temp_w <= "0000";
wrpointer_tx <= (OTHERS => (OTHERS => '0'));
wren_txram <= '0';
wraddress_txram <= (OTHERS => '0');
ELSIF rising_edge(extclk) THEN
case temp_w is
when "0000" =
wren_txram <= '0';
IF cs = '0' AND offset < "100000" THEN
temp_w <= "0001";
else temp_w <= "0000";
end if;
when "0001" =
wren_txram <= '0';
wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
data2txram <= datain;
if wr = '0' then
temp_w <= "0010";
elsif rd = '0' then
temp_w <= "0000";
else temp_w <= "0001";
end if;
when "0010" =
temp_w <= "0100";
wren_txram <= '1';
wrpointer_tx(conv_integer(ch_no)) <=
wrpointer_tx(conv_integer(ch_no)) + 1;
when "0100" =
wren_txram <= '1';
IF cs = '1' OR wr = '1' THEN
temp_w <= "0000";

ELSE
temp_w <= "0100";
END IF;

when others => null;
end case;
IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
datain(bit_XRES) = '1' THEN
wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
END IF;
END IF;
END PROCESS;
Euhm... first of all: using a seperate process for the statemachine
(which calculates nextstate) and a register to store state itself is a
very good idea...

Is it possible thet wr is a 'weak low' signal? This means that wr is 'L'
and nog '0'. So in simulation this check will be false...
If this is true change
if wr = '0' then
to
if wr /= '1' then
or
if to_X01(wr) = '0' then
 
HI,
I saw your code.there is something fishy.No where in the code you are
state to 0011 & how can this problem arise.

Regards,
Raghavendra.

"anupam" <anupam@coraltele.com> wrote in message news:<51b73fd7a32b97ab3c4b804d2d834b7c@localhost.talkaboutprogramming.com>...
Hi alls,
I am facing problem with the following process.
state machine from state "0001" goes to state "0011" instead of "0010"
when the wr signal is low.
Can u suggest something ?

Regards,

Anupam


PROCESS (rst, extclk) --PROCESS no 01

BEGIN
IF rst = '0' THEN
temp_w <= "0000";
wrpointer_tx <= (OTHERS => (OTHERS => '0'));
wren_txram <= '0';
wraddress_txram <= (OTHERS => '0');
ELSIF rising_edge(extclk) THEN
case temp_w is
when "0000" =
wren_txram <= '0';
IF cs = '0' AND offset < "100000" THEN
temp_w <= "0001";
else temp_w <= "0000";
end if;
when "0001" =
wren_txram <= '0';
wraddress_txram <= ch_no & wrpointer_tx(conv_integer(ch_no));
data2txram <= datain;
if wr = '0' then
temp_w <= "0010";
elsif rd = '0' then
temp_w <= "0000";
else temp_w <= "0001";
end if;
when "0010" =
temp_w <= "0100";
wren_txram <= '1';
wrpointer_tx(conv_integer(ch_no)) <=
wrpointer_tx(conv_integer(ch_no)) + 1;
when "0100" =
wren_txram <= '1';
IF cs = '1' OR wr = '1' THEN
temp_w <= "0000";

ELSE
temp_w <= "0100";
END IF;

when others => null;
end case;
IF cs = '0' AND wr = '0' AND offset = OFFSET_XRES AND
datain(bit_XRES) = '1' THEN
wrpointer_tx(conv_integer(ch_no)) <= (OTHERS => '0');
END IF;
END IF;
END PROCESS;
 
"Mohammed A.khader" wrote:
So I construct my
one-hot FSM by describing the various bits separately. temp_w(0) <=
f(...). Then the optimal logic is easily obtained.


I did'nt understand the way you said in the last line. Can I get an
example it clarify myself.

Thanks.

Mohammed A.khader.
BTW, it is a good idea to include a line showing who you are quoting. I
sort my newsgroup listings by date, so I don't see the threads unless I
change that. I almost missed replying to this message because I did not
see my name as the person you were quoting.

One hot encoding, in theory, reduces the width (depth) of logic by
allowing the encoding for a given state to be represented by a single
bit rather than by a large number of bits as is the case with binary.
If you had an FSM with 17 states, you would need 5 bits for binary
encoding and all five bits would be examined to decode a single state.

With one-hot encoding, it will require 17 bits to encode all the states,
but only one needs to be considered to determin if the machine is in a
single state. Assume part of your machine looks like this...

start speedup halt -resume
-----> IDLE -----> RUNSLOW -----> RUNFAST -----> WAIT ----->
^ |
| resume |
+----------------------------+

If we use one hot encoding, each state will have its own bit. The
inputs to the logic for a given state function "f(...)" will only
include those states that have the given state as one of its next
states. The input function for RUNFAST will be f(RUNSLOW, RUNFAST,
speedup, halt). No other states need be considered. The state RUNSLOW
will be a bit more complex with f(IDLE, RUNSLOW, WAIT, start, speedup,
resume). The input function for WAIT will be very simple with
f(RUNFAST, halt).

Some of these state functions can be encoded in a single LUT and many
can be done in just two. But when the FSM has many transitions so that
most states have transitions from more than 4 functions, the equations
can depend on so many states, that a binary encoding might be more
efficient. But once the number of states gets much above 8 it seems
that one-hot encoding is most often the most efficent.

--

Rick "rickman" Collins

rick.collins@XYarius.com
Ignore the reply address. To email me use the above address with the XY
removed.

Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design URL http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX
 

Welcome to EDABoard.com

Sponsor

Back
Top