Forum Discussion
FSM problem
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;12 Replies
- Altera_Forum
Honored Contributor
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.
- Altera_Forum
Honored Contributor
--- 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. - Altera_Forum
Honored Contributor
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; - Altera_Forum
Honored Contributor
and it is still unsolved so your ideas will be very helpful.
- Altera_Forum
Honored Contributor
thanks anyway bro.
- Altera_Forum
Honored Contributor
Wish I could help you brother
- Altera_Forum
Honored Contributor
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; - Altera_Forum
Honored Contributor
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.
- Altera_Forum
Honored Contributor
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... - Altera_Forum
Honored Contributor
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:
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.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);