Uart Vhdl, simulation is ok but in fpga not work - vhdl

I write simple vhdl code for Uart receiver.
Simulation (iSIM) is fine but when implemented I have wrong reading behavior.
When synthetized ISE tell me there are latches on state machine end on data_fill(x).
have you any suggestion.
thanks in advance
gian
here the code
library ieee;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity rx_uart is
port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
rx_data : in STD_LOGIC;
data_out: out STD_LOGIC_VECTOR(7 downto 0)
);
end rx_uart;
architecture fizzim of rx_uart is
-- state bits
subtype state_type is STD_LOGIC_VECTOR(2 downto 0);
constant idle: state_type:="000"; -- receive_en=0 load_en=0 cnt_en=0
constant receive: state_type:="101"; -- receive_en=1 load_en=0 cnt_en=1
constant stop_load: state_type:="010"; -- receive_en=0 load_en=1 cnt_en=0
signal state,nextstate: state_type;
signal cnt_en_internal: STD_LOGIC;
signal load_en_internal: STD_LOGIC;
signal receive_en_internal: STD_LOGIC;
signal count : integer range 0 to 54686:=0;
signal cnt_en : STD_LOGIC;
signal load_en : STD_LOGIC;
signal receive_en : STD_LOGIC;
signal data_fill : STD_LOGIC_VECTOR(9 downto 0);
-- comb always block
begin
COUNTER_EN : process(clk,rst,cnt_en) begin
if (rst ='1') then
count <= 0;
elsif rising_edge(clk) then
if (cnt_en ='1') then
count <= count+1;
else
count <= 0;
end if;
end if;
end process;
LOADER: process(clk,rst,load_en) begin
if (rst='1') then
data_out <= (others =>'0');
elsif (rising_edge(clk) and load_en='1')then
data_out <= data_fill(8 downto 1);
end if;
end process;
ASSIGNATION : process(clk,rst,receive_en) begin
if (rst ='1') then
data_fill <= (others =>'0');
elsif (receive_en='1') then
case count is
when 7812 =>
data_fill(1) <= rx_data;
when 13020 =>
data_fill(2) <= rx_data;
when 18228 =>
data_fill(3) <= rx_data;
when 23436 =>
data_fill(4) <= rx_data;
when 28664 =>
data_fill(5) <= rx_data;
when 33852 =>
data_fill(6) <= rx_data;
when 39060 =>
data_fill(7) <= rx_data;
when 44268 =>
data_fill(8) <= rx_data;
when 49476 =>
data_fill(9) <= rx_data;
when others =>
data_fill(0) <= '0';
end case;
end if;
end process;
COMB: process(state,clk,count,rst,rx_data) begin
case state is
when idle =>
if (rx_data='0') then
nextstate <= receive;
elsif (rx_data='1') then
nextstate <= idle;
end if;
when receive =>
if (count<=54685) then
nextstate <= receive;
elsif (count>54685) then
nextstate <= stop_load;
end if;
when stop_load =>
nextstate <= idle;
when others =>
end case;
end process;
-- Assign reg'd outputs to state bits
cnt_en_internal <= state(0);
load_en_internal <= state(1);
receive_en_internal <= state(2);
-- Port renames for vhdl
cnt_en <= cnt_en_internal;
load_en <= load_en_internal;
receive_en <= receive_en_internal;
-- sequential always block
FF: process(clk,rst,nextstate) begin
if (rst='1') then
state <= idle;
elsif (rising_edge(clk)) then
state <= nextstate;
end if;
end process;
end fizzim;

You need to understand when latches are generated. Latches are generated when you have an incomplete assignment in combinational logic. Your case statements are combinational. You do not completely assign all possibilities of your data signal and your state machine. When you have an incomplete assignment in a combinational process you will always generate a latch. Latches are bad!
Use your when others properly to assign all of your signals under all conditions. Your data_fill signal will always generate a latch because you don't handle all conditions for data 0:9 on all cases.
Read more about how to avoid latches in VHDL
Edit: It seems too that you don't consistently create sequential logic in VHDL. You need to be creating a clocked process or remove clk from your sensitivity list in a combinational process.

your design has several bad code sites besides your latch problem. I'll number them for better reference.
(1)
Xilinx XST won't recognize the implemented state machine as a FSM. See your XST report or the *.syr file. There won't be a FSM section. If XST finds no FSM it's not able to choose "the best" state encoding and optimize your FSM.
You should use an enum as a state-type and also initialize your state signal:
type t_state is (st_idle, st_receive, st_stop);
signal state : t_state := st_idle;
signal nextstate : t_state;
Your FSM process also needs default assignments (see Russell's explanation) like
nextstate <= state;
(2)
asynchronous resets are no good design practice and complicate timing closure calculations.
(3)
you are handling raw input signals from outside you FPGA without any timing information. to prevent meta stability problems place two D-flip-flops on the rx_data path. you should also add the async-reg and no-srl-extract attribute to these 2 registers to prevent XST optimizations
SIGNAL I_async : STD_LOGIC := '0';
SIGNAL I_sync : STD_LOGIC := '0';
-- Mark register "I_async" as asynchronous
ATTRIBUTE ASYNC_REG OF I_async : SIGNAL IS "TRUE";
-- Prevent XST from translating two FFs into SRL plus FF
ATTRIBUTE SHREG_EXTRACT OF I_async : SIGNAL IS "NO";
ATTRIBUTE SHREG_EXTRACT OF I_sync : SIGNAL IS "NO";
[...]
BEGIN
[...]
I_async <= In WHEN rising_edge(Clock);
I_sync <= I_async WHEN rising_edge(Clock);
Let 'In' be your asynchronous input. Now you can use I_sync in your clock domain. I choose to describe these 2 registers in a one-liner, you can also use a classic process :) The suffix '_async' allows you to define a matching timing rule in your *.xcf and *.ucf files.

Related

VHDL state machine testbench - works when on board but not on simulation

I have the VHDL implementation that works on board, it detects the sequence 01110 and will raise a flag for 2 clock counts. It detects overlapping sequences as well where 011101110 would raise the flag twice.
I've checked my implementation with a logic analyzer on the board and am fairly confident that it works. I am feeding in a repetition sequence of 0111 at 10 kHz, on the board, it has a clock at 100 MHz where I scale it to 10 kHz with a prescaler.
My problem is, when trying to recreate a similar scenario using a simulation, I do not get any outputs as expected
Image from logic analyzer from board
Image from Test Bench
Test Bench Code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity test_FSM_prac4 is
-- Port ( );
end test_FSM_prac4;
architecture Behavioral of test_FSM_prac4 is
component FSM_prac4 is
port (
inputSignal : in STD_LOGIC;
pushButton : in STD_LOGIC;
clk100mhz : in STD_LOGIC;
logic_analyzer : out STD_LOGIC_VECTOR (7 downto 0);
LEDs: out STD_LOGIC
); end component;
signal inputSignal : std_logic := '0';
signal pushButton: std_logic := '0';
signal clk100mhz: std_logic := '0';
signal logic_analyzer: std_logic_vector(7 downto 0);
signal LEDs : std_logic;
begin
uut : FSM_prac4 port map(
inputSignal => inputSignal,
pushButton => pushButton,
clk100mhz => clk100mhz,
logic_analyzer => logic_analyzer,
LEDs => LEDs
);
--generate clock 100mhz
clock_tic: process begin
loop
clk100mhz <= '0';
wait for 5ns;
clk100mhz <= '1';
wait for 5ns;
end loop;
end process;
input_changes: process begin
loop
inputSignal <= '0';
wait for 100us;
inputSignal <= '1';
wait for 100us;
inputSignal <= '1';
wait for 100us;
inputSignal <= '1';
wait for 100us;
end loop;
end process;
end Behavioral;
To show the mapping for logic Analyzer
logic_analyzer(0) <= masterReset;
logic_analyzer(1) <= newClock -- 10Khz Clock;
logic_analyzer(2) <= outputZ;
--FSM States
logic_analyzer(3) <= '1' when y = A ELSE '0';
logic_analyzer(4) <= '1' when y = B ELSE '0';
logic_analyzer(5) <= '1' when y = C ELSE '0';
logic_analyzer(6) <= '1' when y = D ELSE '0';
logic_analyzer(7) <= '1' when y = E ELSE '0';
If anyone could direct to what I am doing wrong on the test bench and how to replicate to get similar results as the first image as it shows that in simulation, it always stays at state A and the new clock is not toggling meaning that clk100mhz is somehow not connected but I can't figure out why.
Any help is greatly appreciated, thanks guys
edit:
I wrote a simple program to test my scalar clock
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity scaler_clk is
Port (
pushButton : in std_logic;
indicator : out std_logic;
clk100mhz : in STD_LOGIC;
clk10khz: out STD_LOGIC
);
end scaler_clk;
architecture Behavioral of scaler_clk is
signal clockScalers : std_logic_vector (12 downto 0):= (others => '0') ;
signal prescaler: std_logic_vector(12 downto 0) := "1001110001000";
signal newClock: std_logic := '0';
signal masterReset : std_logic;
begin
clk10khz <= newClock;
masterReset <= pushButton;
process (clk100mhz,masterReset) begin
if(masterReset <= '1') then <--- error occurs here
clockScalers <= "0000000000000";
newClock <= '0';
indicator <= '1';
elsif (clk100mhz'event and clk100mhz = '1')then
indicator <= '0';
clockScalers <= clockScalers + 1;
if(clockScalers > prescaler) then
newClock <= not newClock;
clockScalers <= (others => '0');
end if;
end if;
end process;
end Behavioral;
test bench code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity test_scaler_clk is
-- Port ( );
end test_scaler_clk;
architecture Behavioral of test_scaler_clk is
component scaler_clk Port (
pushButton : in std_logic;
indicator : out std_logic;
--input clock
clk100mhz : in STD_LOGIC;
clk10khz: out STD_LOGIC
);end component;
signal clk100mhz: std_logic := '0';
signal clk10khz : std_logic;
signal pushButton: std_logic;
signal indicator : std_logic;
begin
uut: scaler_clk port map(
pushButton => pushButton,
indicator => indicator,
clk100mhz => clk100mhz,
clk10khz => clk10khz
);
pushButton <= '0';
clock_tic: process begin
loop
clk100mhz <= '0';
wait for 5ns;
clk100mhz <= '1';
wait for 5ns;
end loop;
end process;
end Behavioral;
Even though I set pushButton to '0', it is still triggering masterReset, anyone knows why, that's why the 10 kHz clock isn't working
There are several things that you could (should) improve in your code. As Brian already explained, in your Behavioral architecture of scaler_clk, you should have:
if(masterReset = '1') then
instead of:
if(masterReset <= '1') then
Now, let's start with the most likely cause of your initial problem: unbound components. Your test benches instantiate the design to validate as components. VHDL components are kind of prototypes of actual entities. Prototypes are enough to compile because the compiler can perform all necessary syntax and type checking. But they are not enough to simulate because the simulator also needs the implementation behind the prototype. Some tools have a default binding strategy for unbound components: if they find an entity with the same name and if it has only one architecture, they use that. Your simulator apparently does not use such strategy (at least not by default, there is maybe an option for that but it is disabled). Note that most simulators I know issue warnings when they find unbound components. You probably missed these warnings.
Anyway, your component instances are unbound (they have no associated entity/architecture) and the simulator considers them as black boxes. Their outputs are not driven, except by the initial values you declared (1).
How to fix this? Two options:
Use a configuration to specify which entity/architecture pair shall be used for each component instance:
for all: scaler_clk use entity work.scaler_clk(Behavioral);
Use entity instantiations instead of components:
uut: entity work.scaler_clk(Behavioral) port map...
Now, let's go through some other aspects of your code that could be improved:
You are using non-standard packages, that are frequently not even compatible: IEEE.STD_LOGIC_ARITH and IEEE.STD_LOGIC_UNSIGNED. As they are not standard they should not even be in the standard IEEE library. You should use IEEE.NUMERIC_STD instead, and only that one. It declares the SIGNED and UNSIGNED types (with the same declaration as STD_LOGIC_VECTOR) and overloads the arithmetic operators on them.
Your test benches generate the 100MHz clock with:
clock_tic: process begin
loop
clk100mhz <= '0';
wait for 5ns;
clk100mhz <= '1';
wait for 5ns;
end loop;
end process;
The infinite loop is useless: a process is already an infinite loop:
clock_tic: process
begin
clk100mhz <= '0';
wait for 5ns;
clk100mhz <= '1';
wait for 5ns;
end process clock_tic;
would do the same. Same remark for your input_changes process.
Your input_changes process uses wait for <duration> statements. This is not a good idea because you do not know when the inputSignal signal toggles, compared to the clock. Is it just before, just after or exactly at the same time as the rising edge of clk100mhz? And if it is exactly at the same time, what will happen? Of course, you can carefully chose the <durations> to avoid such ambiguities but it is error prone. You should use the wait for <duration> only in the clock generating process. Everywhere else, it is better to synchronize with the clock:
input_changes: process
begin
inputSignal <= '0';
for i in 1 to 10000 loop
wait until rising_edge(clk100mhz);
end loop;
inputSignal <= '1';
for i in 1 to 10000 loop
wait until rising_edge(clk100mhz);
end loop;
inputSignal <= '1';
for i in 1 to 10000 loop
wait until rising_edge(clk100mhz);
end loop;
inputSignal <= '1';
for i in 1 to 10000 loop
wait until rising_edge(clk100mhz);
end loop;
end process input_changes;
This guarantees that inputSignal changes just after the rising edge of the clock. And you could rewrite it in a bit more elegant way (and probably a bit easier to maintain):
input_changes: process
constant values: std_logic_vector(0 to 3) := "0111";
begin
for i in values'range loop
inputSignal <= values(i);
for i in 1 to 10000 loop
wait until rising_edge(clk100mhz);
end loop;
end loop;
end process input_changes;
You are using resolved types (STD_LOGIC and STD_LOGIC_VECTOR). These types allow multiple drive, that is, having a hardware wire (VHDL signal) that is driven by several devices (VHDL processes). Usually you do not want this. Usually you even want to avoid this like the plague because it can cause short-circuits. In most cases it is wiser to use non-resolved types (STD_ULOGIC and STD_ULOGIC_VECTOR) because the compiler and/or the simulator will raise errors if you accidentally create a short circuit in your design.
One last thing: if, as its name suggests, you intend to use the clk10khz signal as a real clock, you should reconsider this decision. It is a signal that you generate with your custom logic. Clocks have very specific electrical and timing constraints that cannot really be fulfilled by regular signals. Before using clk10khz as a clock you must deal with clock skew, clock buffering... Not impossible but tricky. If you did use it as a clock your synthesizer probably issued critical warnings that you also missed (have a look maybe at the timing report). Moreover, this is probably useless in your case: an enable signal generated from clk100mhz could probably be used instead, avoiding all these problems. Instead of:
process (clk100mhz,masterReset) begin
if(masterReset = '1') then
clockScalers <= "0000000000000";
newClock <= '0';
indicator <= '1';
elsif (clk100mhz'event and clk100mhz = '1')then
indicator <= '0';
clockScalers <= clockScalers + 1;
if(clockScalers > prescaler) then
newClock <= not newClock;
clockScalers <= (others => '0');
end if;
end if;
end process;
use:
signal tick10khz: std_ulogic;
...
process(clk100mhz, masterReset) begin
if masterReset = '1') then
clockScalers <= "0000000000000";
tick10khz <= '0';
elsif rising_edge(clk100mhz) then
clockScalers <= clockScalers + 1;
tick10khz <= '0'
if(clockScalers > prescaler) then
tick10khz <= '1';
clockScalers <= (others => '0');
end if;
end if;
end process;
And then, instead of:
process(clk10khz)
begin
if rising_edge(clk10khz) then
register <= register_input;
end if;
end process;
use:
process(clk100mhz)
begin
if rising_edge(clk100mhz) then
if tick10khz = '1' then
register <= register_input;
end if;
end if;
end process;
The result will be the same but with only one single 100MHz clock, which avoids clock skew, clock buffering and clock domain crossing problems.
(1) This illustrates why declaring variables and signals with initial values is usually not a good idea: it hides potential problems. Without this your signals would have been stuck at 'U' (uninitialized) and it would maybe have helped understanding where the problem comes from.

Xilinx / ISim seem claims value to be X but it has been declared

Have JUST started learning how to use this tool so if my question seems silly i apologize in advance. I have searched the error in numerous forums (already answered posts , not mine) and couldn't understand what i was doing wrong so here is my question:
My Behavioral Code:
----------------------------------------------------------------------------- -----
-- Company:
-- Engineer:
--
-- Create Date: 01:47:22 07/07/2015
-- Design Name:
-- Module Name: Module_1 - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------- -----
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned valuessss
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Module_1 is
port (A,B,WE,reset : in std_logic;
clk : in std_logic;
DIN : in signed(3 downto 0);
FULL,EMPTY,ERROR : out std_logic:= '0';
PARKFREE : out signed(3 downto 0)
);
end Module_1;
architecture Behavioral of Module_1 is
signal current_state,next_state:std_ulogic_vector(1 downto 0);
signal empty_bf, full_bf :std_ulogic;
signal enter, reset_b : std_ulogic := '0' ;
constant s0: std_ulogic_vector (1 downto 0):="00";
constant s1: std_ulogic_vector (1 downto 0):="10";
constant s2: std_ulogic_vector (1 downto 0):="11";
constant s3: std_ulogic_vector (1 downto 0):="01";
signal park_counter,buffr: signed(3 downto 0):="0000";
signal PARKTOTAL,free_park_counter: signed(3 downto 0):= "1111";
begin
p1: process (clk,reset,reset_b)
begin
if (reset = '1') then
current_state <= s0;
elsif clk'event and clk = '1' then
current_state <= next_state;
end if;
end process p1;
p2: process (current_state,A,B)
begin
next_state <= current_state;
case current_state is
when s0 =>
if A = '1' then
enter <= '1';
next_state <= s1;
elsif B = '1' then
next_state <= s3;
end if;
when s1 =>
if A = '0' then
enter <= '0';
next_state <= s0;
elsif B = '1' then
next_state <= s2;
end if;
when s2 =>
if A = '0' then
next_state <= s3;
elsif B = '0' then
next_state <= s1;
end if;
when s3 =>
if B = '0' then
enter <= '0';
next_state <= s0;
elsif A = '1' then
next_state <= s2;
end if;
when others =>
end case;
end process p2;
p3: process(current_state,A,B)
begin
case current_state is
when s1 =>
if enter = '0' and A = '0' and empty_bf = '0' then
park_counter <= park_counter - 1;
free_park_counter <= free_park_counter + 1;
ERROR <= '0';
end if;
when s3 =>
if enter = '1' and B = '0' and full_bf = '0' then
park_counter <= park_counter + 1;
free_park_counter <= free_park_counter - 1;
ERROR <= '0';
end if;
when others =>
end case;
end process p3;
max: process(WE)
begin
if clk'event and clk = '1' and WE = '1' then
PARKTOTAL <= DIN ;
buffr <= DIN ;
if (free_park_counter < buffr - park_counter) then
ERROR <= '1';
reset_b <= '1';
else free_park_counter <= buffr - park_counter;
end if;
end if;
end process max;
incr: process(free_park_counter,DIN)
begin
PARKFREE <= free_park_counter;
if (free_park_counter = 15) then
EMPTY <= '1';
empty_bf <= '1';
else EMPTY <= '0';
empty_bf <= '0';
end if;
if (free_park_counter = 0) then
FULL <= '1';
full_bf <= '1';
else FULL <= '0';
full_bf <= '0';
end if;
end process incr;
end Behavioral;
My Testbench
----------------------------------------------------------------------------- ---
-- Company:
-- Engineer:
--
-- Create Date: 02:17:07 07/11/2015
-- Design Name:
-- Module Name: D:/Users/ErgasiaFPGA/Testbench.vhd
-- Project Name: ErgasiaFPGA
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: Module_1
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY Testbench IS
END Testbench;
ARCHITECTURE behavior OF Testbench IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT Module_1
PORT(
A : IN std_logic;
B : IN std_logic;
WE : IN std_logic;
reset : IN std_logic;
clk : IN std_logic;
DIN : IN signed(3 downto 0);
FULL : OUT std_logic;
EMPTY : OUT std_logic;
ERROR : OUT std_logic;
PARKFREE : OUT signed(3 downto 0)
);
END COMPONENT;
--Inputs
signal A : std_logic := '0';
signal B : std_logic := '0';
signal WE : std_logic := '0';
signal reset : std_logic := '0';
signal clk : std_logic := '0';
signal DIN : signed(3 downto 0) := (others => '0');
--Outputs
signal FULL : std_logic;
signal EMPTY : std_logic;
signal ERROR : std_logic;
signal PARKFREE : signed(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Module_1 PORT MAP (
A => A,
B => B,
WE => WE,
reset => reset,
clk => clk,
DIN => DIN,
FULL => FULL,
EMPTY => EMPTY,
ERROR => ERROR,
PARKFREE => PARKFREE
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
reset <= '1' ;
wait for 100 ns;
reset <= '0' ;
wait for clk_period*10;
-- insert stimulus here
A <= '1' ;
wait for clk_period*5;
B <= '1' ;
wait for clk_period*5;
A <= '0' ;
wait for clk_period*5;
B <= '0' ;
wait for clk_period*5;
B <= '1' ;
wait for clk_period*5;
A <= '1' ;
wait for clk_period*5;
B <= '0' ;
wait for clk_period*5;
A <= '0' ;
wait;
end process;
END;
I posted the whole code just in case i'm missing something in some part of it that i wouldn't think about. So , when i ISim it , with any "succesful" trigger of p3...
Referencing it again here:
p3: process(current_state,A,B)
begin
case current_state is
when s1 =>
if enter = '0' and A = '0' and empty_bf = '0' then
park_counter <= park_counter - 1;
free_park_counter <= free_park_counter + 1;
ERROR <= '0';
end if;
when s3 =>
if enter = '1' and B = '0' and full_bf = '0' then
park_counter <= park_counter + 1;
free_park_counter <= free_park_counter - 1;
ERROR <= '0';
end if;
when others =>
end case;
end process p3;
...the ISim says that in this part
"There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
and proceeds to make Xs of some of the values after that part , although all of the signals have been initialized (at least the ones in this part)
The "park_counter <= park_counter + 1;" part works correctly in the simulation but the "free_park_counter <= free_park_counter -1;" doesn't. This completely baffles me as they are declared as the same type and are both initialized the same way , even with different values.
So what am i missing or even doing blatantly wrong? Any help will be incredibly appreciated. Only looking for the error , if you could please contain optimizations since i'm looking to learn through trial and error and thought and would like to struggle to make it better myself
In addition , please be patient with my responses since i log on 2 to 3 times per day. Thanks in advance
Your design is non-workable per Brian's answer. Your testbench causes the messages when going from s3 or s1 to s0 before the clock edge. free_park_counter goes to 'U's. (Once it gets U's it won't loop further, no events occur without a signal value change).
Your counters should be clocked to prevent combinatorial looping, plus they likely won't synthesize a clock usefully due to uneven combinatorial delays. Sensitivity lists should likewise be complete, if for no other reason than the intent is to make simulation match the synthesized result.
Looking at the result of your testbench:
(clickable)
We can compare that with the messages from the arithmetic operators found in the Synopsys package std_logic_arith:
../../../src/synopsys/std_logic_arith.vhdl:315:20:#350ns:(assertion warning): There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
../../../src/synopsys/std_logic_arith.vhdl:315:20:#350ns:(assertion warning): There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
../../../src/synopsys/std_logic_arith.vhdl:315:20:#550ns:(assertion warning): There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
The signals displayed in the waveform are selected in order of importance and appearance a first pass selection and we immediately see we also get 'U's on free_park_counter as well as ERROR.
ERROR catches attention because you hadn't mentioned it previously. When asking 'where to the 'U' come from ?' it becomes apparent the issue is there are drivers on ERROR and free_park_counter in both processes p3 and max. The messages are a side effect.
Each process assigning a signal provides a driver. Signals with multiple drivers are either resolved or result in an error for non-resolved types.
The resolved value of free_park_counter with one or more elements having a metavalue will cause the diagnostic messages produced by package std_logic_arith. The 'U's in the waveform are caused by the resolution of the two drivers.
The difficulty your audience had in noticing the two drivers may be in part due to your strong insistence on focusing on process p3, which is not well specified. The title and focus of your question also seems a bit unclear. Without a Minimal Complete and Verifiable example there was also bound to be less scrutiny.
You might expect as a minimum to consolidate all the assignments to ERROR and free_park_counter into a single process. ERROR should likely be registered, and I'd expect something named park_counter would likely want to be registered, too.
There is some confusion in the question title : declaring a signal and setting its value are entirely separate.
Initialising a signal (in the declaration) will influence its value, but not fully determine it. If the initialisation and another driving value are different, the result probably will be 'X'. Likewise if the signal is driven from different processes which disagree on its value.
Now, you are using a multiple-process form of state machine, where the operations are split between clocked and combinational processes. These are recommended by more than one textbook. This is unfortunate because they are notoriously difficult to get right, and for example, a moment's inspection will show that the sensitivity list on process P3 is wrong.
Fixing P3's sensitivity list may not affect the problem, because P3 also drives its own inputs in what is known as a combinational loop. Consider that, if the process wakes up several times because of glitches on the combinational inputs in its sensitivity list, the additions will take place several times...
Rewriting these three processes in the form of a single clocked process P1, (which is, unfortunately, not well taught in several textbooks) will avoid all of these difficulties.
In ISim, if you browse the tree menu on the left you are able to add to then signals window any internal signal you want. Add all of them, rerun the simulation and look for the signals that have 'U'|'X'|'W'|'Z'|'-' values. This should give us a lead to track down the problem.
If you are really new to VHDL, this answer of mine should help you undersand some of the basic concepts of this description language :)
VHDL - iSIM output uninitialised, doesn't change states
Another advice that I learned the hard way, but you can think about it after we solved this problem: textbooks and even Xilinx describe how to implement finite state machines with two or even three distinct processes. This comes from an educational approach where FSM are splitted in synchronous logic and asynchronous logic. In practice, this is doing more harm than good: most of the FSM can be described with a single synchronous process. Google it (or if you are interested we can talk about it) and try it, you will get the hang of it really quickly and it will really simplify the code (you won't even need two separate signals for the states anymore!).

Why is my VHDL detector not recognizing the state change?

I am having problem with my VHDL code, I hope someone could help. See, the 'q' signal is supposed to detect whether the state has changed or not, but it never does. It is as if the state never gets from 'detecting' to 'idle'. The q signal remains on the '0' value, even though the state changes, while the reset is off and clk signal is on the upper edge. I hope you get to see where the problem is.
P.S. state_reg signal is for state at the moment and the next one is for the next state. qlevel_detected is the signal I used for debugging.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity detector is
port
(
clk, reset : in std_logic;
level : in std_logic;
q : out std_logic;
qlevel_detected : out std_logic
);
end detector;
architecture behavioral of detector is
type state is (idle, detecting);
signal state_reg, state_next : state;
signal level_detected_reg, level_detected_next : std_logic;
begin
process(clk, reset)
begin
if (reset = '1') then
state_reg <= idle;
elsif (clk'event and clk = '1') then
state_reg <= state_next;
level_detected_reg <= level_detected_next;
end if;
end process;
process(state_reg)
begin
state_next <= state_reg;
level_detected_next <= level_detected_reg;
case state_reg is
when idle =>
level_detected_next <= level;
state_next <= detecting;
when detecting =>
if (level /= level_detected_reg) then
state_next <= idle;
end if;
end case;
end process;
-- Output logic
q <= '0' when state_reg = idle else
'1' when state_reg = detecting;
qlevel_detected <= level_detected_reg;
end behavioral;
Your next state process is only sensitive to state_reg. As a combinational process it needs all of its inputs listed in the sensitivity list (or all with VHDL-2008).
process(state_reg, level, level_detected_reg)
begin
...
You are also missing an unconditional else on the assignment to q which will create a latch in synthesis.

Vhdl How Can I reset this signal

I'm trying to send two data to PC according to a counter. I need to send this two data just once, so I'm using a signal called "New_data_s". But my problem is this signal stays "High" too much and the data is being sent more than once. I'm sending "Datafll_s" by the way.
This is a picture of the first simulation: Sim1
Then I added another signal called "Stop_s" to reset this "New_data_s". Okay it sends the data just once, but this time, I can't reset "Stop_s". Once it goes "High" it stays "High" until I press the button. So I can't send the second data.
This is a picture of the second simulation: Sim2
I know if I don't press the button this "ELSIF(Go_s='1' and Go_s_ff='0')Then" condition is not TRUE, so that's why "Stop_s" stays "High" until I press the button. But, I couldn't find a way to do this.
Counter part:
IF(Cnt_Spc_P1>15 and Cnt_Spc_P1<=30)Then
Three_spc_s<='1';
Seven_spc_s<='0';
ELSIF(Cnt_Spc_P1>30 and Cnt_Spc_P1<50)Then
Three_spc_s<='0';
Seven_spc_s<='1';
ELSIF(Cnt_Spc_P1=50)Then
Three_spc_s<='0';
Seven_spc_s<='1';
Enable_1_s<='0';
Cnt_Spc_P1<=0;
ELSE
Three_spc_s<='0';
Seven_spc_s<='0';
END IF;
Main part:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
-------------------------------------------------------------------------------
Entity Letters is
Port(
Clk: in std_logic;
Reset: in std_logic;
Dot: in std_logic;
Dash: in std_logic;
Error : out std_logic;
New_data: out std_logic;
three_spc: in std_logic;
seven_spc: in std_logic;
d_out_d: out std_logic_vector(6 downto 0);
d_out_a: out std_logic_vector(7 downto 0)
);
END Letters;
-------------------------------------------------------------------------------
Architecture Letters_a of Letters is
-------------------------------------------------------------------------------
Type state is (Start, Space, T, E);
Signal current_s: state;
Signal Go_s, Go_s_ff: std_logic:='0';
signal data_d : std_logic_vector(6 downto 0):="1100100";
signal data_a : std_logic_vector(7 downto 0):="00000000";
Signal Error_s, New_data_s : std_logic:='0';
Signal Stop_s : std_logic:='0';
-------------------------------------------------------------------------------
BEGIN
-------------------------------------------------------------------------------
PROCESS(Clk, three_spc, seven_spc, current_s, Reset)
BEGIN
IF(Reset='1')Then
current_s<=Start;
data_d<="0000000";
data_a<="00000000";
d_out_d<="1100100";
Error_s<='0';
New_data_s<='0';
Stop_s<='0';
ELSIF(Rising_Edge(Clk))Then
IF(three_spc='1')Then
d_out_d<=data_d;
d_out_a<=data_a;
New_data_s<='1';
Stop_s<='1';
current_s<=Start;
ELSIF(seven_spc='1')Then
current_s<=Space;
d_out_d<=data_d;
d_out_a<="00100000";
New_data_s<='1';
Stop_s<='1';
current_s<=Start;
ELSIF(Go_s='1' and Go_s_ff='0')Then
Case current_s is
When Start =>
New_data_s<='0';
Stop_s<='0';
IF(Dash='1')Then
current_s<=T;
data_d<="1100100";
data_a<="01010100";
Error_s<='0';
ELSIF(Dot='1')Then
current_s<=E;
Error_s<='0';
data_d<="0000110";
data_a<="01000101";
END IF;
-------------------------------------------------------------------------------
When T =>
IF(Dash='1')Then
current_s<=M;
data_d<="1100100";
data_a<="01001101";
ELSIF(Dot='1')Then
current_s<=N;
data_d<="0101011";
data_a<="01001110";
END IF;
-------------------------------------------------------------------------------
When E =>
IF(Dash='1')Then
current_s<=A;
data_d<="0001000";
data_a<="01000001";
ELSIF(Dot='1')Then
current_s<=I;
data_d<="1111001";
data_a<="01001001";
END IF;
When OTHERS =>
current_s <= Start;
Error_s<='1'; -- Unidentified letter.
data_d<="1100100";
New_data_s<='0';
Stop_s<='0';
END Case;
END IF;
IF(Stop_s='1')Then
New_data_s<='0';
END IF;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
PROCESS(Clk, Dot, Dash, Reset)
BEGIN
Go_s<=Dash or Dot;
IF(Reset='1')Then
Go_s<='0';
Go_s_ff<='0';
ELSIF(Rising_Edge(Clk))Then
Go_s_ff<=Go_s;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
Error<=Error_s;
New_data<=New_data_s;
-------------------------------------------------------------------------------
END Letters_a;
Thank you.
I see that you've declared an enumerated type state and instantiated a signal current_s of type state. The enumerated type includes the literals, (Start, Space, T, E), but you assign literals M, N and A to signal current_s which are not members of the state type. Your compiler should complain about that. Does it?
The fsm included in your code is a bit difficult to follow because state transition code is mixed with output signal logic. So, I've rewritten it and posted it below. My fsm may not exactly represent the functionality you're looking for, however, you can use it as a template. It illustrates how to generate a one clock wide edge detector for the dot and dash signals. It also illustrates how to control the data strobe signal that you were having difficulty switching on and off.
The output logic does not take full advantage of the default signal values that proceed the output logic case statement so that it will be easier for you to see what's happening. However, many of the statements within the case could be eliminated for compactness.
Also, I haven't compiled the code, so you may find a few syntax errors, but the template should be of use to you.
-- Note, not all signals are declared here, refer to the posted code for them
Type state_t is (Idle, start_dot, start_dash, E_dot, strobe_3spc_data,
wait_1, strobe_7spc_data, wait_2, E_dash);
signal state_snoop : state_t; -- use to monitor state in simulator
signal dash_ff : std_logic;
signal dash_pulse : std_logic;
signal dot_ff : std_logic;
signal dot_pulse : std_logic;
fsm: process (clk)
variable current_s : state_t;
begin
if rising_edge(clk) then
if Reset = '1' then
current_s := Idle;
else
case Idle is
when Idle =>
if dot_pulse = '1' then
current_s := start_dot;
elsif dash_pulse = '1' then
current_s := start_dash;
end if;
-- dot related states ----------------------
when start_dot =>
current_s := E_dot;
when E_dot =>
if three_spc = '1' then
current_s := strobe_3spc_data;
end if;
when strobe_3spc_data =>
if seven_spc = '1' then -- counter strobe from external source
current_s := wait_1;
end if;
when wait_1 =>
if seven_spc = '1' then -- counter strobe from external source
current_s := strobe_7spc_data;
end if;
when strobe_7spc_data =>
current_s := wait_2;
when wait_2 =>
current_s := idle;
-- dash related states ----------------------
when start_dash =>
current_s := E_dash;
when E_dash =>
if three_spc = '1' then
current_s := strobe_3spc_data;
end if;
end case;
end if;
end if;
state_snoop <= current_s; -- monitor state in simulator. variables are hard to monitor
-------------- outputs decoded from state variable -------------------
-- default signal values
New_data_s <= '0';
data_d <= "0000000"; data_a <= "00000000"; d_out_d <= "0000000";
Stop_s <= '0'; Error_s <= '0';
case current_s is
when Idle =>
data_d <= "0000000";
data_a <= "00000000";
d_out_d <= "1100100";
Error_s <= '0';
New_data_s <= '0';
when start_dot =>
data_d <= "0000110"; --'ACK'
data_a <= "01000101"; -- ascii dash -> 'E'
Error_s <= '0';
New_data_s <= '0';
when E_dot =>
data_d <= "1111001";
data_a <= "01001001";
when strobe_3spc_data =>
d_out_d <= data_d;
d_out_a <= data_a;
New_data_s <= '1';
when wait_1 => -- switch data strobe off for first data transmission
New_data_s <= '0';
when strobe_7spc_data =>
d_out_d <= data_d;
d_out_a <= "00100000";
New_data_s <= '1';
when wait_2 => -- switch data strobe off for second data transmission
New_data_s <= '0';
-- dash related outputs
when start_dash =>
data_d <= "1100100"; --'t'
data_a <= "01010100"; --'T'
Error_s <= '0';
New_data_s <= '0';
when E_dash =>
data_d <= "0001000";
data_a <= "01000001";
when others => null;
end case;
-- rising edge detector for dash and dot input.
if Reset = '1' then
dash_pulse <= '0'
else
dash_ff << not(Dash);
dash_pulse << dash_ff and dash;
end if;
if Reset = '1' then
dot_pulse <= '0'
else
dot_ff << not(dot);
dot_pulse << dot_ff and dot;
end if;
end process fsm

How to Rewrite FSM not to use Latches

I have an FSM and it works. The synthesizer, however, complains that there are latches for "acc_x", "acc_y", and "data_out" and I understand why and why it is bad. I have no idea, however, how to rewrite the FSM so the state-part goes to the clocked process. Any ideas where to start from? Here is the code of the FSM:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity storage is
port
(
clk_in : in std_logic;
reset : in std_logic;
element_in : in std_logic;
data_in : in signed(11 downto 0);
addr : in unsigned(9 downto 0);
add : in std_logic; -- add = '1' means add to RAM
-- add = '0' means write to RAM
dump : in std_logic;
element_out : out std_logic;
data_out : out signed(31 downto 0)
);
end storage;
architecture rtl of storage is
component bram is
port
(
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in unsigned(9 downto 0);
di : in signed(31 downto 0);
do : out signed(31 downto 0)
);
end component bram;
type state is (st_startwait, st_add, st_write);
signal current_state : state := st_startwait;
signal next_state : state := st_startwait;
signal we : std_logic;
signal en : std_logic;
signal di : signed(31 downto 0);
signal do : signed(31 downto 0);
signal acc_x : signed(31 downto 0);
signal acc_y : signed(31 downto 0);
begin
ram : bram port map
(
clk => clk_in,
we => we,
en => en,
addr => addr,
di => di,
do => do
);
process(clk_in)
begin
if rising_edge(clk_in) then
if (reset = '1') then
current_state <= st_startwait;
else
current_state <= next_state;
end if;
end if;
end process;
process(current_state, element_in, add, dump, data_in, do, acc_x, acc_y)
begin
element_out <= '0';
en <= '1';
we <= '0';
di <= (others => '0');
case current_state is
when st_startwait =>
if (element_in = '1') then
acc_x <= resize(data_in, acc_x'length);
next_state <= st_add;
else
next_state <= st_startwait;
end if;
when st_add =>
if (add = '1') then
acc_y <= acc_x + do;
else
acc_y <= acc_x;
end if;
next_state <= st_write;
when st_write =>
if (dump = '1') then
data_out <= acc_y;
element_out <= '1';
else
di <= acc_y;
we <= '1';
end if;
next_state <= st_startwait;
end case;
end process;
end rtl;
This is personal preference, but I think most people on here will agree with me on this one... do not use two processes to control your state machine. The whole previous_state next_state thing is total garbage in my opinion. It's really confusing and it tends to make latches - SURPRISE - You found that out. Try rewriting your state machine with a single clocked process and only one state machine signal.
Here's my attempt at rewriting your state machine. Note that I'm not sure the functionality that I have below will work for you. Simulate it to make sure it behaves the way you expect. For example the signal en is always tied to '1', not sure if you want that...
process (clk_in)
begin
if rising_edge(clk_in) then
element_out <= '0';
en <= '1'; -- this is set to 1 always?
we <= '0';
di <= (others => '0');
case state is
when st_startwait =>
if (element_in = '1') then
acc_x <= resize(data_in, acc_x'length);
state <= st_add;
end if;
when st_add =>
if (add = '1') then
acc_y <= acc_x + do;
else
acc_y <= acc_x;
end if;
state <= st_write;
when st_write =>
if (dump = '1') then
data_out <= acc_y;
element_out <= '1';
else
di <= acc_y;
we <= '1';
end if;
state <= st_startwait;
end case;
end if;
end process;
The reason for the inferred latches is that the case in the last process does
not drive all signals in all possible combinations of the sensitive signals.
So the process can finish without altering some of the output data for some of
the signal values to the process. To hold output in this way is the operation
of a latch, so latches are therefore inferred by the synthesis tool.
The latches applies only to acc_x, acc_y, and data_out, since all other
signals are assigned a default value in the beginning of the process.
You can fix this by either driving a default value for the last 3 signals in
the beginning of the process, for example 'X' for all bit to allow synthesis
freedom:
data_out <= (others => 'X');
acc_x <= (others => 'X');
acc_y <= (others => 'X');
Alternatively can you can ensure that all outputs are driven in all branches of
the case, and you should then also add a when others => branch to the case.
I suggest that you use the assign of default value to all signals, since this
is easier to write and maintain, instead of having to keep track of assign to
all driven signals in all branches of the case.
Clearly you need supplemental (clocked) registers (D flip flops).
Your need to ask yourself "what occurs to acc_x if the FSM is in (let say) state st_add ?". Your answer is "I dont want to modify acc_x in this state". So : write it explicitely, using clocked registers (such as the one used for state ; you can augment the clocked process with these supplemental registers). Do that Everywhere. That is the rule. Otherwise, synthesizers will infer transparent latches to memorize the previous value of acc_x : but these transparent latches violate the synchronous design principles. They structurally imply combinatorial loops in your designs, which are bad.
Put another way : ask yourself what is combinatorial and where are the registers ? If you have registers in mind, code them explicitly. Do not make combinatorial signals assigned and read in the same process.

Resources