Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers

FSM problem

Altera_Forum
Honored Contributor II
2,875 Views

Heyy I'm trying to make a video game in vhdl on de0 board and I need help about the following FSM. No error or warning. Does anyone notice a mistake?? 

thankss. 

 

type XY_REG_TYPE is array (0 to 19,0 to 9) of std_logic; type AB_REG_TYPE is array (0 to 3,0 to 3) of std_logic; type XY_NEXT_TYPE is array (0 to 19,0 to 9) of std_logic; type AB_NEXT_TYPE is array (0 to 3,0 to 3) of std_logic; type STATE_TYPE is (count,zero,left,down,right); signal m : integer range 0 to 9; signal n : integer range 0 to 19; signal c,d : integer range 0 to 3; signal ab_reg : AB_REG_TYPE; signal xy_reg : XY_REG_TYPE; signal ab_next : AB_NEXT_TYPE; signal xy_next : XY_NEXT_TYPE; signal state_reg, state_next : STATE_TYPE; signal T_reg, T_next : integer range 0 to 10; begin FSM1: process (clk, reset, n, m, c ,d) begin if reset = '1' then xy_reg(n,m) <= '0'; T_reg <= 0; state_reg <= zero; elsif clk'event and clk = '1' then xy_reg(n,m) <= xy_next(n,m); T_reg <= T_next; state_reg <= state_next; end if; end process FSM1; FSM2: process (SW(1), BUTTON, xy_reg, ab_reg, state_reg, T_reg, T_next, m, n, c ,d) begin xy_next(n,m) <= xy_reg(n,m); T_next <= T_reg; state_next <= state_reg; case state_reg is when count => if EndOfField = '1' then T_next <= T_reg + 1; if T_reg = 10 and SW(1) = '1' then state_next <= zero; else state_next <= count; end if; end if; when zero => if BUTTON = "111" then if xy_reg(n+1,m) = '0' then xy_next(n,m) <= xy_reg(n+1,m); T_next <= 0; state_next <= count; else xy_next(n,m) <= xy_reg(n,m); T_next <= 0; state_next <= count; end if; elsif BUTTON = "101" then state_next <= down; elsif BUTTON = "110" then state_next <= right; elsif BUTTON = "011" then state_next <= left; end if; when down => if xy_reg(n+1,m) = '0' then xy_next(n,m) <= xy_reg(n+1,m); T_next <= 0; state_next <= count; else xy_next(n,m) <= xy_reg(n,m); T_next <= 0; state_next <= count; end if; when right => if xy_reg(n,m+1) = '0' then xy_next(n,m) <= xy_reg(n,m+1); T_next <= 0; state_next <= count; else xy_next(n,m) <= xy_reg(n,m); T_next <= 0; state_next <= count; end if; when left => if m >= 1 then if xy_reg(n,m-1) = '0' then xy_next(n,m) <= xy_reg(n,m-1); T_next <= 0; state_next <= count; else xy_next(n,m) <= xy_reg(n,m); T_next <= 0; state_next <= count; end if; else xy_next(n,m) <= xy_reg(n+1,m); T_next <= 0; state_next <= count; end if; end case; end process FSM2;
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
1,148 Views

It is hard to tell if there is a mistake if you do not know what this piece of code is supposed to do. 

 

Anyway, I would suggest you something about VHDL coding style. Please, take this advice as something that comes from a guy that studied VHDL some long time ago and now uses it for its job. I mean that I may be outdated at academic coding style... 

Why you make use of integers as signals for synthesis? It seems that a large bus of bits travels around your design and it is used as decoder for a multiplexer. The multiplexer is implicit in the array indexing. Someone taught to me that this can lead to sub-optimal synthesis results. This teaching, as I told, may be outdated or too much conservative (for "company" compatibility with older tools that produced sub-optimal synthesis results).
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

I don't understand what you are saying gabrigob. What is he supposed to use instead of integers? As long as you specify ranges for each one of them the synthesizer will be smart enough to just generate the required width for the signals.

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

Gabrigob - very outdated views indeed. I suppose you only use std_logic(_vector) for ports too? 

 

Synthesisors are pretty good at doing stuff now. I even messed around with it a couple of months ago and used the character type as an array indexes fior a mux: 

 

type silly_array_t is array ('A' to 'G') of integer; signal mux : silly_array_t; ... entity silly is port ( char : in character range 'A' to 'G'; ); architecture.... output <= input(char);  

 

And it built me a mux fine (just dont try and map a character to a pin). 

 

At Korch - thats a lot of code for anyone else to look at. Why not minismise the code to something specific where you're having the error.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

This reminds me of an interview question when the man in power asked me why I used integer for my counters, and that I should have used unsigned. I firmly replied that constrained integers, or signed or unsigned or std_logic eventually are translated by compiler to buses. We either trust the tools or give up. 

 

The above state machine looks to me well coded and too professional for a beginner. The problem itself is not stated. Is it used as it should be integrated correctly in the project...
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

Thanks a lot for the information; as I stated in my post, the information I reported might be constrained to "old style" by job practice.

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

Sorry for late reply and thank you for your replies. After some tests I found problem and rewrite the code but this time I got some errors. 

 

Error (10028): Can't resolve multiple constant drivers for net "xy_reg[1][1]" at VGA.vhd(255) 

Error (10029): Constant driver at VGA.vhd(241) 

 

The problem is not in state machine's cases at this time but I dont minimise the code anyway. When I erase the line underlined below, It kinda works but not enough. I know your ideas will be very helpful. 

 

 

type XY_REG_TYPE is array (0 to 19,0 to 9) of std_logic; type AB_REG_TYPE is array (0 to 3,0 to 3) of std_logic; type XY_NEXT_TYPE is array (0 to 19,0 to 9) of std_logic; type AB_NEXT_TYPE is array (0 to 3,0 to 3) of std_logic; type STATE_TYPE is (count,zero,left,down,right); signal m : integer range 0 to 9; signal n : integer range 0 to 19; signal c,d : integer range 0 to 3; signal ab_reg : AB_REG_TYPE; signal xy_reg : XY_REG_TYPE; signal ab_next : AB_NEXT_TYPE; signal xy_next : XY_NEXT_TYPE; signal state_reg, state_next : STATE_TYPE; signal T_reg, T_next : integer range 0 to 10; begin TimeDelay : process (clk) variable cnt : integer range 0 to 10 := 0; begin if clk'event and clk = '1' then if EndOfField = '1' then if cnt = 10 then Delay <= '1'; cnt := 0; else Delay <= '0'; cnt := cnt + 1; end if; end if; end if; end process TimeDelay; FSM1 : process (clk, reset) begin if reset = '1' then state_reg <= count; elsif clk'event and clk = '1' then for n in 0 to 19 loop for m in 0 to 9 loop if xy_reg(n,m) = '1' then state_reg <= state_next; xy_reg(n,m) <= xy_next(n,m); end if; end loop; end loop; end if; end process FSM1; FSM2 : process (SW(1), BUTTON, Delay, xy_reg(n,m), state_reg) begin for n in 0 to 19 loop for m in 0 to 9 loop if xy_reg(n,m) = '1' then state_next <= state_reg; xy_next(n,m) <= xy_reg(n,m); case state_reg is when count => if Delay = '1' and SW(1) = '1' then state_next <= zero; else state_next <= count; end if; when zero => if BUTTON = "111" then if n <= 18 then if xy_reg(n+1,m) = '0' then xy_next(n+1,m) <= xy_reg(n,m); state_next <= count; else xy_next(n,m) <= xy_reg(n,m); state_next <= count; end if; end if; elsif BUTTON = "101" then state_next <= down; elsif BUTTON = "110" then state_next <= right; elsif BUTTON = "011" then state_next <= left; end if; when down => if n <= 18 then if xy_reg(n+1,m) = '0' then xy_next(n+1,m) <= xy_reg(n,m); state_next <= count; else xy_next(n,m) <= xy_reg(n,m); state_next <= count; end if; end if; when right => if m <= 8 then if xy_reg(n,m+1) = '0' then xy_next(n,m+1) <= xy_reg(n,m); state_next <= count; else xy_next(n,m) <= xy_reg(n,m); state_next <= count; end if; end if; when left => if m >= 1 and n <= 18 then if xy_reg(n,m-1) = '0' then xy_next(n,m-1) <= xy_reg(n,m); state_next <= count; else xy_next(n,m) <= xy_reg(n,m); state_next <= count; end if; end if; end case; end if; end loop; end loop; end process FSM2; Game: process (clk) begin if clk'event and clk = '1' then xy_reg(1,1) <= '1'; end if; end process Game;
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

Wish I could help you brother

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

thanks anyway bro.

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

and it is still unsolved so your ideas will be very helpful.

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

The purspose of this process with a single constant assignment isn't well understandable, but because xy_reg is also assigned in the process FSM1, it's causing a "multiple driver" error. If you feel a need for multiple concurrent assignments to xy_reg, they have to be placed inside FSM1. For the general rules for signal assignments, consult a VHDL text book or tutorial.  

Game: process (clk) begin if clk'event and clk = '1' then xy_reg(1,1) <= '1';^ end if; end process Game;
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

 

--- Quote Start ---  

and it is still unsolved so your ideas will be very helpful. 

--- Quote End ---  

 

 

It would help a lot if you tried to pin point your problem and post a lot less code.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

It seems that the state machine is only half recognised by the FSM viewer. It can list the states but not the transitions. I'm not sure, but you may have to stick to the two-process model that Altera describes in the guidelines for the state machine to be properly recognized by the viewer.

0 Kudos
Reply