Luis Daniel Bolaños
Member level 2
- Joined
- Apr 4, 2014
- Messages
- 47
- Helped
- 2
- Reputation
- 4
- Reaction score
- 2
- Trophy points
- 8
- Activity points
- 342
Warning (10631): VHDL Process Statement warning at simon_fsm.vhd(63): inferring latch(es) for signal or variable "color", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at simon_fsm.vhd(63): inferring latch(es) for signal or variable "nivel", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at simon_fsm.vhd(63): inferring latch(es) for signal or variable "global", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at simon_fsm.vhd(63): inferring latch(es) for signal or variable "aux", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at simon_fsm.vhd(63): inferring latch(es) for signal or variable "input", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at simon_fsm.vhd(63): inferring latch(es) for signal or variable "nx_state", which holds its previous value in one or more paths through the process
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity simon_fsm is
port
(
reset, clk, verde_in, rojo_in, amarillo_in, azul_in, start : in std_logic;
secuencia: in std_logic_vector(44 downto 0);
color : out std_logic_vector(2 downto 0)
);
end entity;
architecture rtl of simon_fsm is
-- Construir el tipo estado
type estado is (s0, s1, s2, s3, s4, s5, s6);
-- Registro para almacenar los estados de la FSM
signal pr_state, nx_state : estado;
-- Convecion de Colores para VGA
constant azul : std_logic_vector(2 downto 0) := "001";
constant rojo : std_logic_vector(2 downto 0) := "100";
constant amarillo : std_logic_vector(2 downto 0) := "110";
constant verde : std_logic_vector(2 downto 0) := "010";
constant negro : std_logic_vector(2 downto 0) := "000";
constant blanco : std_logic_vector(2 downto 0) := "111";
signal global, nivel, aux: integer;
signal input: std_logic_vector(2 downto 0);
function sec_to_color(s: std_logic_vector(2 downto 0))
return std_logic_vector is
begin
case s is
when "000" => return azul;
when "001" => return azul;
when "010" => return verde;
when "011" => return verde;
when "100" => return rojo;
when "101" => return rojo;
when "110" => return azul;
when others => return verde;
end case;
end sec_to_color;
begin
-- Logica Secuencial
process (clk, reset)
begin
if reset = '1' then
pr_state <= s0;
elsif (rising_edge(clk)) then
pr_state <= nx_state;
end if;
end process;
-- Logica Combinacional
process (pr_state, start, nivel, global, aux, input, secuencia, verde_in, rojo_in, amarillo_in, azul_in)
begin
case pr_state is
when s0 =>
color <= blanco;
nivel <= 1;
global <= 0;
aux <= 0;
input <= "000";
if start = '1' then
nx_state <= s1;
end if;
when s1 =>
color <= sec_to_color(secuencia(44-3*global downto 42-3*global));
if global < nivel then
global <= global + 1;
else
global <= 0;
input <= "000";
nx_state <= s2;
end if;
when s2 =>
if aux = 0 then
color <= blanco;
aux <= 1;
else
color <= negro;
aux <= 0;
nx_state <= s3;
end if;
when s3 =>
if verde_in = '1' then
input <= verde;
elsif rojo_in = '1' then
input <= rojo;
elsif azul_in = '1' then
input <= azul;
elsif amarillo_in = '1' then
input <= amarillo;
else
input <= "000";
end if;
if input /= "000" then
nx_state <= s4;
end if;
when s4 =>
if input = sec_to_color(secuencia(44-3*aux downto 42-3*aux)) then
color <= input;
if aux >= nivel then
aux <= 0;
nivel <= nivel + 1;
nx_state <= s5;
elsif aux < nivel then
aux <= aux + 1;
nx_state <= s3;
elsif aux > 14 then
nx_state <= s6;
end if;
else
nx_state <= s0;
end if;
when s5 =>
if aux = 0 then
color <= negro;
aux <= 1;
elsif aux = 1 then
color <= blanco;
aux <= 2;
else
color <= negro;
aux <= 0;
nx_state <= s1;
end if;
when s6 =>
if aux = 0 then
color <= verde;
aux <= 1;
elsif aux = 1 then
color <= azul;
aux <= 2;
elsif aux = 2 then
color <= rojo;
aux <= 3;
elsif aux = 3 then
color <= amarillo;
aux <= 4;
elsif aux = 4 then
color <= verde;
aux <= 5;
elsif aux = 5 then
color <= azul;
aux <= 6;
elsif aux = 6 then
color <= rojo;
aux <= 7;
elsif aux = 7 then
color <= amarillo;
aux <= 8;
elsif aux = 8 then
color <= verde;
aux <= 9;
else
color <= negro;
aux <= 0;
nx_state <= s0;
end if;
end case;
end process;
end rtl;
In an asynchronous process (your state machine) You need to ensure ALL signals are assigned in ALL cases. This is usually done by adding a default assignment before the state case statement, so that if they are not assigned in the state machine they are assigned to a default value.
Did you intend to have so many unregistered outputs?
Ok, I got it. But my professor ask me to do the state machine that way: a non-clocked process with only combinational logic for the output, so I can't change that. Therefore, I guess I'll just take every signal and assign it to all cases. Can you help me with that please? That's a code I took from internet and fix it a bit, but I dont know that much.
Thank you
The infamous 2 process FSM that schools and books are stuck on for no good reason (synthesis tools understand 1 process FSMs).
Because back in the black and white days, tools could only understand 2 process state machines. This was when lecturers devised their lesson plans and learned their VHDL. Many dont use their skill any more, and stick with the old notes/textbooks.
Ok, I got it. But my professor ask me to do the state machine that way: a non-clocked process with only combinational logic for the output, so I can't change that. Therefore, I guess I'll just take every signal and assign it to all cases. Can you help me with that please? That's a code I took from internet and fix it a bit, but I dont know that much.
Thank you
color <= (others => '0');
input <= "000";
case pr_state is
when s1 =>
--no assignments here, so color = 0 and input = 0
when s2 =>
input <= "011"; --overrides default assignment
color <= blue;
The easiest way is to assign the signals a value before the case statement. eg:
Code:color <= (others => '0'); input <= "000"; case pr_state is when s1 => --no assignments here, so color = 0 and input = 0 when s2 => input <= "011"; --overrides default assignment color <= blue;
This way everything assigned a default will always have a value and a latch will not be infered. Dont be tempted to do something silly like:
color <= color;
as that IS a latch.
-- Se describe el juego Simon Says usando FSM
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity simon_fsm is
port
(
reset, clk, start : in std_logic;
input : in std_logic_vector (2 downto 0);
secuencia: in std_logic_vector(44 downto 0);
color : out std_logic_vector(2 downto 0)
);
end entity;
architecture rtl of simon_fsm is
-- Construir el tipo estado
type estado is (s0, s1, s2, s3);
-- Registro para almacenar los estados de la FSM
signal pr_state, nx_state : estado;
-- Convecion de Colores para VGA
constant azul : std_logic_vector(2 downto 0) := "001";
constant rojo : std_logic_vector(2 downto 0) := "100";
constant amarillo : std_logic_vector(2 downto 0) := "110";
constant verde : std_logic_vector(2 downto 0) := "010";
constant negro : std_logic_vector(2 downto 0) := "000";
constant blanco : std_logic_vector(2 downto 0) := "111";
begin
-- Logica Secuencial
process (clk, reset)
begin
if reset = '1' then
pr_state <= s0;
elsif (rising_edge(clk)) then
pr_state <= nx_state;
end if;
end process;
-- Logica Combinacional
process (pr_state, start, input, secuencia)
variable global, nivel : integer;
variable temp : std_logic_vector (2 downto 0);
begin
color <= negro;
nivel := 0;
global := 0;
temp := "000";
nx_state <= s1;
case pr_state is
when s0 =>
if start = '1' then
color <= negro;
nivel := 0;
global := 0;
nx_state <= s1;
else
nx_state <= s0;
end if;
when s1 =>
color <= secuencia(44-3*global downto 42-3*global);
if global < nivel then
global := global + 1;
nx_state <= s1;
else
global := 0;
nx_state <= s2;
end if;
when s2 =>
if input /= "000" then
temp := input;
global := 0;
nx_state <= s3;
else
nx_state <= s2;
end if;
when s3 =>
if temp /= secuencia(44-3*global downto 42-3*global) then
color <= blanco;
nx_state <= s0;
else
color <= temp;
if global >= nivel then
global := 0;
nivel := nivel + 1;
nx_state <= s1;
elsif global < nivel then
global := global + 1;
nx_state <= s3;
elsif global > 14 then
nx_state <= s0;
global := 0;
end if;
end if;
end case;
end process;
end rtl;
nivel := 0;
global := 0;
temp := "000";
if temp /= secuencia(44-3*global downto 42-3*global) then
However, it seems like because variables nivel and temp have default values, the actual values do not increase during the process.
The two process FSM template requires to assign them in the clocked process, using auxilary signals that take the output of the combinational process. If you are required to use this design style, firstly try to minimize the number of additional memory elements (that actually represent FSM "substates"). Secondly code the necessary ones (like timers or counters) in a proper form.
This is where a testbench is required to test your functionality.
Also, is there any reason you havent registered your color output?
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity testbench is
end entity;
architecture prueba of testbench is
component simon_fsm is
port
(
reset, clk, start : in std_logic;
input : in std_logic_vector (2 downto 0);
secuencia: in std_logic_vector(44 downto 0);
color : out std_logic_vector(2 downto 0)
);
end component;
-- Declaracion de Senales
signal clk: std_logic := '0';
signal reset: std_logic := '0';
signal input: std_logic_vector (2 downto 0) := "000";
signal start: std_logic := '1';
signal secuencia : std_logic_vector (44 downto 0) := "110010110001100010100010001100110010001110100";
signal color: std_logic_vector (2 downto 0) := "000";
begin
sim: simon_fsm port map (reset, clk, start, input, secuencia, color);
start <= '0' after 20 ns;
clk <= not clk after 10 ns;
input <= "110" after 40 ns, "000" after 80 ns;
end architecture;
The style requires that all registers (not only pr_state, also global, temp and nivel) are assigned in a clocked process.I can not add anything to the clocked process, I have to keep this style.
Ok, I will convice my teacher 8-OThe style requires that all registers (not only pr_state, also global, temp and nivel) are assigned in a clocked process.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?