I am designing a parking-lot gate in VHDL. When I simulate it using Quartus VWF files, I am getting unknown values (X), but I don't know why.
Basically you just have to validate your card (Sin
) and the gate opens for 10 seconds.
And when a car exits the parking lot (Sout
), it counts the total cars at the moment inside of the parking lot.
I have created the signal Ncarros
(to count number of cars) and s_count
for the timer.
It all compiles correctly. But when I'm testing it using a VWF file, this is what I get:
Original simulation output
I'm using Altera Quartus Prime Lite Edition.
Can someone check my code and tell me what I'm doing wrong?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity MicroProj is
port (clk : in std_logic;
Sin : in std_logic;
Sout : in std_logic;
cancela : out std_logic;
timerOut : out std_logic);
end MicroProj;
architecture Behavioral of MicroProj is
signal Ncarros : integer := 0;
signal s_count : integer := 0;
begin
process (Sin,Sout,clk)
begin
if (Sin = '0') then
cancela <= '0';
else
if (Ncarros < 99) then
Ncarros <= Ncarros + 1;
cancela <= '1';
if(rising_edge(clk)) then
if(s_count /= 0) then
if(s_count = 499999999) then
timerOut <= '1';
s_count <= 0;
else
timerOut <= '0';
s_count <= s_count + 1;
end if;
else
timerOut <= '0';
s_count <= s_count + 1;
end if;
end if;
end if;
end if;
if (Sout ='1') then
Ncarros <= Ncarros - 1;
end if;
end process;
end Behavioral;
When you simulate with a Vector Waveform File (VWF), Quartus-II actually simulates the behaviour of the synthesized netlist (checked here with Quartus-II 13.1). If you haven't run the step "Analysis & Synthesis", Quartus asks to do so. You have to always run this step manually, when you change your VHDL files before simulating the VWF again. The synthesized netlist is written out as Verilog code which will be the input of the ModelSim simulator. You can find it in the file simulation/qsim/microproj.vo
.
As long as Quartus reports warnings (or errors), the behavior of the synthesized design can differ from the VHDL description. And this is the case here as pointed out below. To directly simulate the behavior of your VHDL description, you have to write a testbench.
The following testbench will be a good starter. It assign the same input values as in your VWF file for the first 200 ns. You will have to extend the code at the indicated location to add more signal transitions.
library ieee;
use ieee.std_logic_1164.all;
entity microproj_tb is
end entity microproj_tb;
architecture sim of microproj_tb is
-- component ports
signal clk : std_logic := '0';
signal Sin : std_logic;
signal Sout : std_logic;
signal cancela : std_logic;
signal timerOut : std_logic;
begin -- architecture sim
-- component instantiation
DUT: entity work.microproj
port map (
clk => clk,
Sin => Sin,
Sout => Sout,
cancela => cancela,
timerOut => timerOut);
-- clock generation
clk <= not clk after 10 ns;
-- waveform generation
WaveGen : process
begin
Sin <= '0';
Sout <= '0';
wait for 40 ns; -- simulation time = 40 ns
Sin <= '1';
wait for 70 ns; -- simulation time = 110 ns
Sin <= '0';
wait for 50 ns; -- simulation time = 160 ns
Sin <= '1';
-- Extend here to add more signal transistions
wait;
end process WaveGen;
end architecture sim;
The Quartus Prime Lite Edition includes an installation of the ModelSim Altera Edition. You can setup and start the simulation using ModelSim directly within the Quartus project settings. The simulation output for the first 200 ns using my testbench is as follows:
As you see, the output differs from your simulation of the VWF file because the VHDL design itself is simulated now.
In your VHDL code you described latches for the signals cancela
and Ncarros
as also reported by the "Analysis & Synthesis" step:
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(26): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(27): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(48): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10631): VHDL Process Statement warning at MicroProj.vhdl(21): inferring latch(es) for signal or variable "cancela", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at MicroProj.vhdl(21): inferring latch(es) for signal or variable "Ncarros", which holds its previous value in one or more paths through the process
Info (10041): Inferred latch for "Ncarros[0]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "Ncarros[1]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "Ncarros[2]" at MicroProj.vhdl(20)
...
Info (10041): Inferred latch for "Ncarros[31]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "cancela" at MicroProj.vhdl(20)
On Altera FPGAs, latches are implemented using the look-up table (LUT) and a combinational feedback path within the logic element (LE). The state of such a latch is undefined after programming the FPGA. The simulation of the synthesized netlist shows this as 'X'es.
I recommend to fix the latches anyway and transform your code into a fullly synchronous, clock-edge driven design. That is, assign new values to cancela
and Ncarros
only at the rising edge of the clock. The VHDL code pattern is:
process(clk)
begin
if rising_edge(clk) then
-- put all your assignments to cancela and Ncarros here
end if;
end process;