Search code examples
vhdlsimulationquartus

Unknown values (X) in simulation of parking lot gate


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:

Cropped simulation output

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;

Solution

  • 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:

    simulation output

    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;