MODELSIM ALTERA ERROR: NUMERIC_STD."=": metavalue detected, returning FALSE - runtime-error

I wanted to make a counter in vhdl as part of a bigger project and when i compile everything works fine. However, when i run the whole simulation it never shows the graphic pannel and instead shows this error: # ** Warning: NUMERIC_STD."=": metavalue detected, returning FALSE
Time: 0 ps Iteration: 1 Instance: /pract2/i2. -- i2 is the vhdl file that is named 'ContadorUno'
I know this has to do something with the fact that some value is U or X instead of a boolean, so when comparing it with another boolean it arises this error. However, i can´t seem to spot it in this file. ¿Perhaps it is in another one even though the simulation tells me in this one? I dont know, i need help please.
--BLOQUE CONTADOR
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY ContadorUno IS
PORT (
clk, reset_n : IN std_logic;
enable_t : IN std_logic; -- necesito dos enables para que en la maquina de estados, cuando quiero que me empiece a contar hasta uno, se resetee
cuenta_uno: out std_logic);
END ContadorUno;
ARCHITECTURE behavioral of ContadorUno is
signal contador: unsigned(11 downto 0);
constant uno: unsigned(11 downto 0):= to_unsigned(2604,12);
begin
process(clk,reset_n)
begin
if reset_n='0' then
contador <= (others => '0');
elsif clk'event and clk='1' then
if enable_t='1' then
if contador=uno then
contador <= (others => '0');
else
contador <= contador +1;
end if;
else
contador <= (others => '0');
end if;
end if;
end process;
cuenta_uno <= '1' when (contador=uno and enable_t='1') else '0';
end behavioral;

Related

How can I test all cases of vector multiplexer in VHDL?

This is my first VHDL code, I have this multiplexer (two inputs, one selection bit) which has 8bit-vector inputs. How can I write a testing function that generates all possible vectors?
library IEEE;
use IEEE.std_logic_1164.all;
entity mux is
port(
in0, in1: in std_logic_vector(7 downto 0);
sel: in std_logic;
out0: out std_logic_vector(7 downto 0);
end mux;
architecture dataflow of mux is
begin
out0<=in1 when sel='1'
else in0;
end dataflow;
This is the testbench at the moment:
library IEEE;
use IEEE.std_logic_1164.all;
entity testbench is --empty
end testbench;
architecture tb of testbench is
-- DuT component
component mux is
port(
in0, in1: in std_logic_vector(7 downto 0);
sel: in std_logic;
out0: out std_logic);
end component;
signal tb_sel: std_logic;
signal tb_in0, tb_in1, tb_out0: std_logic_vector(7 downto 0);
begin
-- Connect DuT
DuT: mux port map(tb_in0, tb_in1, tb_sel, tb_out0);
process
begin
tb_sel <= 0;
tb_in0 <= "00000000";
tb_in1 <= "00000000";
-- TODO: test all possibilities
end process;
end tb;
Something like this can be used:
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity testbench is --empty
end testbench;
architecture tb of testbench is
signal tb_sel: std_logic;
signal tb_in0, tb_in1, tb_out0: std_logic_vector(7 downto 0);
begin
-- Connect DuT
DuT: entity work.mux port map(tb_in0, tb_in1, tb_sel, tb_out0);
process
begin
-- Done: Test all possibilities
for sel in 0 to 1 loop
for in0 in 0 to 2 ** tb_in0'length - 1 loop
for in1 in 0 to 2 ** tb_in1'length - 1 loop
-- Make stimuli
if sel = 0 then
tb_sel <= '0';
else
tb_sel <= '1';
end if;
tb_in0 <= std_logic_vector(to_unsigned(in0, tb_in0'length));
tb_in1 <= std_logic_vector(to_unsigned(in1, tb_in1'length));
-- Wait for output, also to ease viewing in waveforms
wait for 10 ns;
-- Test output
if sel = 0 then
assert tb_out0 = tb_in0 report "Wrong out0 output value for selected in0 input" severity error;
else
assert tb_out0 = tb_in1 report "Wrong out0 output value for selected in1 input" severity error;
end if;
end loop;
end loop;
end loop;
report "OK (not actual failure)" severity FAILURE;
wait;
end process;
end tb;
Note that I have used instantiation by entity for mux, to avoid the component declaration, where there actually was an error in the port list; clearly showing why it is a bad idea to write the same twice ;-)
Also not that I have included the IEEE numeric_std package.
It can surely be improved with respect to testing of X values also, but for a simple module like a mux the testing above will give the required coverage.
For more advanced testing, take a look at OSVVM.

VHDL Unable to initialize array of unsigned vectors

The lines:
type some_array_type is array (0 to 4, 0 to 4) of unsigned(7 downto 0);
signal some_array : some_array_type := (others=>(others=>'0'));
cause vivado 2018.2 to throw the error:
[Synth 8-1807] character '0' is not in type unresolved_unsigned
for some reason in a VHDL 2008 file. What it the magical syntax to get Vivado to realize that I'm just trying to initialize the array to zeros? I shouldn't have to write a function to do this. I also tried unsigned((others=>(others=>'0')));
The code below can of course be ignored and isn't needed for anything at all. It is just there for the OCD people. "You have to always include a minimal working example!"
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity some_entity is
port (
clk, rst: in std_logic ;
);
end some_entity ;
architecture arch of some_entity is
type some_array_type is array (0 to 4, 0 to 4) of unsigned(7 downto 0);
-- throws error
signal some_array : some_array_type := (others=>(others=>'0'));
type some_other_array_type is array (natural range <>) of std_logic_vector(7 downto 0);
-- doesn't throw error
signal some_other_array : some_other_array_type(0 to 4) := (others=>(others=>'0'));
begin
-- some made up process
process(clk, rst)
begin
if(rising_edge(clk)) then
if rst = '1' then
some_array <= (others=>(others=>'0'));
else
some_array <= (others=>(others=>'1'));
end if;
end if;
end process;
end arch;

VHDL asynch ripple counter glitch

Here is a design for 4-bit asynchronous ripple counter (using T flip flop however I didn't define a component for Tff and just coded the behavior of circuit regarding T signals).
Following are the questions:
1.) inout ports, I first defined Q as inout (since it's obviously my output and the bits are also used as clk inputs to their following flip flops). Still, when I wanted to simulate my code, the Q output was UUUU which makes sense cause I had to initialize it with the number I wanted my count to begin with. Though I didn't know how to set an inout initial value (I tried Process ... Q <= "0000"; wait; end process but it didn't work)!
2.) In order to solve the above-mentioned problem I changed my inout port to out (Q_out) and defined Q as a signal, this worked BUT...my counter only changed the Q(0) bit and not the others...thus it counts like: 0,1,0,1,0,1,...
3.) I want to debug this code. I tried another style, instead of a 4-bit output I defined 4 1-bit output signals (Q_out1 to Q_out2) in addition to 4 internal signals Q0 to Q1 and this perfectly works
I just want to know why the first style (Q as a 4_bit vector) didn't work out.
thanks in advance for your help.
Here is my code and its test bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity four_bit_Asynch_Counter is
Port ( T0,T1,T2,T3 : in STD_LOGIC;
clk : in STD_LOGIC;
Q_out: out STD_LOGIC_VECTOR (3 downto 0));
end four_bit_Asynch_Counter;
architecture Behavioral of four_bit_Asynch_Counter is
signal Q : STD_LOGIC_VECTOR (3 downto 0) := "0000";
begin
Process (clk,Q(0),Q(1),Q(2))
begin
if (falling_edge(clk)) then
if (T0 = '1') then
Q(0) <= not Q(0);
else
Q(0) <= Q(0);
end if;
end if;
if (falling_edge(Q(0))) then
if (T1 = '1') then
Q(1) <= not Q(1);
else
Q(1) <= Q(1);
end if;
end if;
if (falling_edge(Q(1))) then
if (T2 = '1') then
Q(2) <= not Q(2);
else
Q(2) <= Q(2);
end if;
end if;
if (falling_edge(Q(2))) then
if (T3 = '1') then
Q(3) <= not Q(3);
else
Q(3) <= Q(3);
end if;
end if;
Q_out <= Q;
end Process;
end Behavioral;
--------------- Test Bench------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb_counter IS
END tb_counter;
ARCHITECTURE behavior OF tb_counter IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT four_bit_Asynch_Counter
PORT(
T0 : IN std_logic;
T1 : IN std_logic;
T2 : IN std_logic;
T3 : IN std_logic;
clk : IN std_logic;
Q_out : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal T0 : std_logic := '1';
signal T1 : std_logic := '1';
signal T2 : std_logic := '1';
signal T3 : std_logic := '1';
signal clk : std_logic := '0';
--Outputs
signal Q_out : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: four_bit_Asynch_Counter PORT MAP (
T0 => T0,
T1 => T1,
T2 => T2,
T3 => T3,
clk => clk,
Q_out => Q_out
);
-- 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.
wait for 100 ns;
wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;
The TL;DR answer is that q(3) doesn't show up in your process sensitivity list.
architecture behavioral of four_bit_asynch_counter is
signal q: std_logic_vector (3 downto 0) := "0000";
begin
process (clk, q(0), q(1), q(2))
begin
if falling_edge(clk) then
if t0 = '1' then
q(0) <= not q(0);
-- else
-- q(0) <= q(0);
end if;
end if;
if falling_edge(q(0)) then
if t1 = '1' then
q(1) <= not q(1);
-- else
-- q(1) <= q(1);
end if;
end if;
if falling_edge(q(1)) then
if t2 = '1' then
q(2) <= not q(2);
-- else
-- q(2) <= q(2);
end if;
end if;
if falling_edge(q(2)) then
if t3 = '1' then
q(3) <= not q(3);
-- else
-- q(3) <= q(3);
end if;
end if;
q_out <= q;
end process;
end architecture behavioral;
For your process sensitivity list you've discovered a feature in how the sensitivity list is constructed from the expression consisting of primaries - clk, q(0), q(1), q(2).
From IEEE Std 1076 -1993, 8.1 Wait statement:
...
The sensitivity set is initially empty. For each primary in the condition of the condition clause, if the primary is
-- A simple name that denotes a signal, add the longest static prefix of the name to the sensitivity set
-- A selected name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set
-- An expanded name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set
-- An indexed name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set and apply this rule to all expressions in the indexed name
...
...
This rule is also used to construct the sensitivity sets of the wait statements in the equivalent process statements for concurrent procedure call statements( 9.3 ), concurrent assertion statements ( 9.4 ), and concurrent signal assignment statements ( 9.5 ).
If a signal name that denotes a signal of a composite type appears in a sensitivity list, the effect is as if the name of each scalar subelement of that signal appears in the list.
...
I only included elements of the rule that are of interest here, the first covers the clock the last element shown covers the std_logic_vector elements specified by selected names.
It helps to understand what is meant by the longest static prefix. This explained in -1993 6.1 Names.
The primaries (indexed names) are static names (q(0), q(1), q(2)), every expression that's part of each indexed name is static.
This means the longest static prefix is the indexed name comprising each primary.
And this leaves q(3) dangling in the breeze for the process signal assignment statement:
q_out <= q;
Without sensitivity to q(3) the value of q_out is not updated until the next event in the sensitivity list, which happens to be on clk:
There are two ways to cure this, you could move the q_out assignment outside the process statement, where it becomes a concurrent signal assignment (with an elaborated equivalent process with a sensitivity list set to q), or you can change the sensitivity list in the present process:
process (clk, q)
So that q_out is updated for an event on q(3) (noting the last quoted paragraph in 8.1 above).
This behavior hold true for later revisions of the standard as well.
With the process sensitivity list is fixed:
Your counter behaves properly.
Also note I commented out the redundant else assignments to the q(0), q(1), q(2) and q(3) a signal will hold it's value until assigned and these are sequential (clocked) statements. Also eliminated the redundant parentheses pairs.
When implementing counters in realisable hardware (either ASIC or FPGA) you should never use a ripple counter. By using the flip-flop output as a clock to the next you will have sub-optimal timing, the tools will not be able to accurately validate the setup and hold times and you are not able to take advantage of dedicated clock routing. In general asynchronous design is a bad idea for real implementations.
A true synchronous design will be much better for synthesis and is much easier to infer in the VHDL code.
Examples of Counter implementations
See the above link for both verilog and vhdl examples of counter implementation.

How to initialize std_logic_vector?

I have this code
--RAM module
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
entity RAM is
generic(
address_length, data_length : integer);
port(
addr : in std_logic_vector(address_length-1 downto 0);
dat : inout std_logic_vector(data_length-1 downto 0);
rd, wr, en : in bit);
end entity RAM;
architecture RAM_impl of RAM is
type mem is array(2**address_length-1 downto 0) of std_logic_vector(data_length-1 downto 0);
begin
process(rd, wr, en)is
variable cont : mem;
begin
if(en = '1')then
if(wr = '1' and rd = '0')then
cont(to_integer(unsigned(addr))) := dat;
end if;
if(rd = '1' and wr = '0')then
dat <= cont(to_integer(unsigned(addr)));
end if;
end if;
end process;
end architecture RAM_impl;
--Test module
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
entity Example4RAM is
end entity Example4RAM;
architecture Tester of Example4RAM is
signal rd, wr, en : bit;
signal str : std_logic_vector(15 downto 0);
signal ext : std_logic_vector(7 downto 0);
begin
module : entity work.RAM(RAM_impl)
generic map(
address_length => 16,
data_length => 8)
port map(str, ext, rd, wr, en);
tt : process is
begin
str <= X"0001";
ext <= "00000000";
rd <= '0'; wr <= '1';
wait for 5 ns;
en <= '1';
wait for 5 ns;
rd <= '0'; wr <= '0';
wait for 10 ns;
rd <= '1'; wr <= '0';
end process;
end architecture Tester;
When i run simulation on this RAM module str vector initializes fine but ext vector stays uninitialized. In RAM module str is in vector and ext is inout vector. Is this somehow making problem and does anyone know the solution? (I did change source since yesterday but it doesn't work still)
I added a RAM module and tinkered with the test stimulus slightly (ext is driven to all 'Z's when wr goes invalid (the behavioral model requires no hold over).
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity RAM is
generic (
constant address_length: natural := 16;
constant data_length: natural := 8
);
port (
signal str: in std_logic_vector (address_length-1 downto 0);
signal ext: inout std_logic_vector (data_length-1 downto 0);
signal rd: in BIT;
signal wr: in BIT
);
end entity;
architecture RAM_impl of RAM is
type ram_array is array (natural range address_length-1 downto 0)
of std_logic_vector (data_length-1 downto 0);
signal mem_array: ram_array;
begin
MEMORY:
process (str, ext, rd, wr)
variable addr: natural range 0 to 2**address_length -1 ;
begin
addr := TO_INTEGER(UNSIGNED(str)); -- heed the warnings
if wr = '1' then
mem_array(addr) <= ext;
end if;
if rd = '0' then
ext <= (others => 'Z');
else
ext <= mem_array(addr);
end if;
end process;
end architecture;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.numeric_std.ALL;
entity Example4RAM is
end entity Example4RAM;
architecture Tester of Example4RAM is
signal rd,wr,clk: bit;
signal str: std_logic_vector(15 downto 0);
signal ext: std_logic_vector(7 downto 0);
begin
module:
entity work.RAM(RAM_impl)
generic map (
address_length=>16,
data_length=>8
)
port map (
str,
ext,
rd,
wr
)
;
tt:
process
begin
str<=X"0001";
ext<="00000000";
wait for 5 ns;
rd<='0';wr<='1';
wait for 5 ns;
rd<='0';wr<='0';
ext <= (others => 'Z'); -- ADDED
wait for 10 ns;
rd<='1';wr<='0';
wait for 20 ns; -- ADDED
str <=X"0002"; -- ADDED
wait for 20 ns; -- ADDED
wait;
end process;
end architecture Tester;
The change to the stimulus includes a change to the RAM address showing that reading an uninitialized location returns 'U's (uu on the waveform):
ghdl -a exampleram.vhdl
ghdl -r Example4RAM --wave=Example4RAM.ghw
../../../../libraries/ieee/numeric_std-body.v93:2098:7:#0ms:(assertion warning):
NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
open *.ghw
Essentially, the process and the RAM drive ext with all 'Z's whenever either one shouldn't be driving a value out. Writing before reading hides the 'U' values from str address X"0001". As you see, if the address is changed to a location that is not initialized, the 'U's show up. Resolution delivers the RAM read data or provides write data to the RAM array on the bidirectional data bus (ext).
(This was done on a Mac with a ghdl mcode version (direct compile, like for Windows, requiring no explicit elaboration), and displayed using GTKWave).
The assertion warning (metavalue detected) comes from the default value assigned to str (all 'U's) at time zero (#0ms).

VHDL Value in case statement randomly gets stuck at a certain value

I've recently been working on some code trying to make a vending machine in vhdl. Started getting some strange errors and managed to narrow it down to my display value being updated.
The code is basically suppose to be able to toggle between display formats for a 7-segment display. I'd say it works as it should mostly but seemed to freeze randomly
I altered to code,found below, a little for debugging and noticed that the values within the case statement get stuck at a certain value. The rest of the code continuous to run perfectly so I can reset and it will work again. Below is the code with the problem
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity display_switch is
Port ( clk : in STD_LOGIC;
reset: in STD_LOGIC;
number : in STD_LOGIC_VECTOR (13 downto 0);-- unsigned binary number
hexid : in std_logic_vector(15 downto 0); -- hex representation
sel : in std_logic;
an : out std_logic_vector(3 downto 0);
seg : out STD_LOGIC_VECTOR (6 downto 0); -- 7 segment display
dp,Led,Led1,Led2 : out std_logic);
end display_switch;
architecture bhv of display_switch is
type button_state is(dec,hex,deb); -- states for display formats
signal current_display,next_display : button_state;
process(clk, reset)
begin
if reset = '1' then -- asynchronous reset
current_display <= dec;
next_display <= hex;
decp <= '1'; -- decimal point
elsif rising_edge(clk) then
segm_display <= hexid;
case current_display is
when dec => Led2 <= '1';
Led1 <= '0';
Led <= '0';
decp <= '0';
next_display <= hex;
if sel = '1' then
current_display <= deb;
end if;
when hex => Led2 <= '0';
Led1 <= '1';
Led <= '0';
decp <= '1';
next_display <= dec;
if sel = '1' then
current_display <= deb;
end if;
when deb => Led2 <= '0';
Led1 <= '0';
Led <= '1';
if sel /= '1' then
current_display <= next_display;
end if;
when others => current_display <= dec;
end case;
end if;
end process;
end bhv;
Basically what happens is that the output values in the case statements either all get stuck at '1' or all get stuck at '0'.
Thanks
Your computation for the next states is dubious. If you are using a synchronous process (as you are indeed doing), you do not need a next_display signal. Just assign the next state value to current_display instead.
I found the problem. It was a timing issue with the "sel" input variabel.
added a signal to store the value on rising clock edge.
temp <= sel;
then used that temp variable instead.

Resources