08-08-2016 10:29 AM
Good evening, I have a problem with the following:
process(present_state) is
begin
if (present_state=a) then
i<=i+1;
end if;
end process
The problem is that with simulation implementation there's no problem because i<=i+1 is evalueted only one time: when present_state change and then, while it is a the evaluation is not done.
When I implement on a fpga, the sensitivity list is not only for the present_state but for all the signals/in etc.. and then I have that when present_state=a the evaluation i<=i+1 is done more than one time (until present_state/=a)...so that's a big problem for me and I can't really find any solution...do you have any idea?
Thanks.
08-08-2016 01:32 PM
Thanks for the answer, it was what i needed...
At the moment on the board everything work fine but there's a problem with the counter that count from 0 to 9: sometimes it counts 2 times in a row (when I click the confirm button) but it's weird because I stay in the state "c" (where i=i+1) only for 1 clock...I got this problem even before with another type of implementation.
I'll post the code of the state machine:
process (reset,clock) is
begin
if reset='0' then
present_state<=a;
elsif rising_edge(clock) then
case present_state is
when a=>
present_state<=b;
when b=>
if confirm='1' then
present_state<=c;
else
present_state<=b;
end if;
when c=>
present_state<=d;
when d=>
if k1="0100" or i=10 then
present_state<=a;
else
present_state<=e;
end if;
when e=>
if confirm='1' then
present_state<=e;
else
present_state<=f;
end if;
when f=>
if confirm='0' then
present_state<=f;
else
present_state<= c;
end if;
end case;
end if;
end process;
and the process that assign the output is:
process (clock) is
begin
led<="0000000000000000";
if rising_edge(clock) then
if present_state=a then
i<=0;
led<="1111111111111111";
X0<=(((X2 and "001") or (X3 and X1))or("010"))xnor(X1);
X1<=(((X2 or "011") or (X0 and X3))and("101"))xnor(X3);
X2<=(((X1 and X1) or (X3 or "011"))or("001"))xnor(X0);
X3<=(((X2 and X0) or (X1 and "110"))and("110"))xnor(X2);
elsif present_state=c then
i<=i+1;
elsif present_state=d then
k2<=K0;
k3<=K1;
k<=std_logic_vector(to_unsigned(i,4));
end if;
end if;
end process;
k1 and k0 are given from another process and k2,k3,k are showed on a 7 segm-display.
And when I press confirm, sometimes it increase the counter of 2 instead of 1 (sometimes is like 1 time versus 10) and it's weird because the state "c" lasts only 1 clock so that the rising_edge(clock) can only see 1 state "c" and so increase of 1 the signal "i"....do you have any idea about that?
Thanks :)
08-08-2016 11:12 AM
My first advice is "think hardware"
Exactly what hardware cell or combination of cells can accomplish what you want? Hardware in an FPGA consists of combinatorial cells (that can perform Boolean functions) and flip-flops (and latches, but you probably don't want to use latches).
So, with these cells, how can you implement what you want - you want the count to increment any time a set of bits has a particular pattern. In combinatorial logic (and you have no clock here, so this is all combinatorial logic), there is no mechanism that can deal with history; "entering" the selected state means the moment in time where the selected state exists where it did not before...
So, while this may work in a simulator, this code is inherently not synthesizable since it is inherently impossible to implement in "normal" synchronous design methodologies.
The heart of this is that you are trying to do something in combinatorial logic that has some concept of "state". To deal with "state", you need a synchronous process - you need a clock. Now, if present_state is a state from a state machine, then you have a clock - the clock that is clocking the state machine.
So, assuming present_state is coming from a state machine, what do you want (and I can see two possibilities)
a) increment the count on any clock cycle that the state machine is in state a or
b) increment the count on any clock cycle when the state machine enters state a
The first is easy (forgive any syntax errors, I am not a VHDL guy)
process (clk) is begin if rising_edge(clk) then if (present_state = a) then i<= i + 1; endif; endif; end;
(you would need to add a reset for the counter)
The second is only slightly harder
process (clk) is begin if rising_edge(clk) then old_state <= present_state if ((present_state = a) and (old_state != a)) then i<= i + 1; endif; endif; end;
Avrum
08-08-2016 01:32 PM
Thanks for the answer, it was what i needed...
At the moment on the board everything work fine but there's a problem with the counter that count from 0 to 9: sometimes it counts 2 times in a row (when I click the confirm button) but it's weird because I stay in the state "c" (where i=i+1) only for 1 clock...I got this problem even before with another type of implementation.
I'll post the code of the state machine:
process (reset,clock) is
begin
if reset='0' then
present_state<=a;
elsif rising_edge(clock) then
case present_state is
when a=>
present_state<=b;
when b=>
if confirm='1' then
present_state<=c;
else
present_state<=b;
end if;
when c=>
present_state<=d;
when d=>
if k1="0100" or i=10 then
present_state<=a;
else
present_state<=e;
end if;
when e=>
if confirm='1' then
present_state<=e;
else
present_state<=f;
end if;
when f=>
if confirm='0' then
present_state<=f;
else
present_state<= c;
end if;
end case;
end if;
end process;
and the process that assign the output is:
process (clock) is
begin
led<="0000000000000000";
if rising_edge(clock) then
if present_state=a then
i<=0;
led<="1111111111111111";
X0<=(((X2 and "001") or (X3 and X1))or("010"))xnor(X1);
X1<=(((X2 or "011") or (X0 and X3))and("101"))xnor(X3);
X2<=(((X1 and X1) or (X3 or "011"))or("001"))xnor(X0);
X3<=(((X2 and X0) or (X1 and "110"))and("110"))xnor(X2);
elsif present_state=c then
i<=i+1;
elsif present_state=d then
k2<=K0;
k3<=K1;
k<=std_logic_vector(to_unsigned(i,4));
end if;
end if;
end process;
k1 and k0 are given from another process and k2,k3,k are showed on a 7 segm-display.
And when I press confirm, sometimes it increase the counter of 2 instead of 1 (sometimes is like 1 time versus 10) and it's weird because the state "c" lasts only 1 clock so that the rising_edge(clock) can only see 1 state "c" and so increase of 1 the signal "i"....do you have any idea about that?
Thanks :)
08-08-2016 01:48 PM
(This sounds/looks like it might be homework...)
Do a google search on switch debouncing...
Avrum
08-08-2016 02:50 PM
oh, thanks a lot, that's also what i needed and i couldn't understand what it was.
Here it's all solved and thanks again to avrumw :)