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;
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.
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;
I am using RS232 interface reference component from https://reference.digilentinc.com/reference/programmable-logic/nexys-2/start and an example code which is:
-------------------------------------------------------------------------
-- main.vhd
-------------------------------------------------------------------------
-- Author: Dan Pederson
-- Copyright 2004 Digilent, Inc.
-------------------------------------------------------------------------
-- Description: This file tests the included UART component by
-- sending data in serial form through the UART to
-- change it to parallel form, and then sending the
-- resultant data back through the UART to determine if
-- the signal is corrupted or not. When the serial
-- information is converted into parallel information,
-- the data byte is displayed on the 8 LEDs on the
-- system board.
--
-- NOTE: Not all mapped signals are used in this test.
-- The signals were mapped to ease the modification of
-- test program.
-------------------------------------------------------------------------
-- Revision History:
-- 07/30/04 (DanP) Created
-- 05/26/05 (DanP) Modified for Pegasus board/Updated commenting style
-- 06/07/05 (DanP) LED scancode display added
-------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-------------------------------------------------------------------------
--
--Title: Main entity
--
--Inputs: 3 : RXD
-- CLK
-- RST
--
--Outputs: 1 : TXD
-- LEDS
--
--Description: This describes the main entity that tests the included
-- UART component. The LEDS signals are used to
-- display the data byte on the LEDs, so it is set equal to
-- the dbOutSig. Technically, the dbOutSig is the scan code
-- backwards, which explains why the LEDs are mapped
-- backwards to the dbOutSig.
--
-------------------------------------------------------------------------
entity DataCntrl is
Port ( TXD : out std_logic := '1';
RXD : in std_logic := '1';
CLK : in std_logic;
LEDS : out std_logic_vector(7 downto 0) := "11111111";
RST : in std_logic := '0');
end DataCntrl;
architecture Behavioral of DataCntrl is
-------------------------------------------------------------------------
-- Local Component, Type, and Signal declarations.
-------------------------------------------------------------------------
-------------------------------------------------------------------------
--
--Title: Component Declarations
--
--Description: This component is the UART that is to be tested.
-- The UART code can be found in the included
-- RS232RefComp.vhd file.
--
-------------------------------------------------------------------------
component RS232RefComp
Port ( TXD : out std_logic := '1';
RXD : in std_logic;
CLK : in std_logic;
DBIN : in std_logic_vector (7 downto 0);
DBOUT : out std_logic_vector (7 downto 0);
RDA : inout std_logic;
TBE : inout std_logic := '1';
RD : in std_logic;
WR : in std_logic;
PE : out std_logic;
FE : out std_logic;
OE : out std_logic;
RST : in std_logic := '0');
end component;
-------------------------------------------------------------------------
--
--Title: Type Declarations
--
--Description: There is one state machine used in this program, called
-- the mainState state machine. This state machine controls
-- the flow of data around the UART; allowing for data to be
-- changed from serial to parallel, and then back to serial.
--
-------------------------------------------------------------------------
type mainState is (
stReceive,
stSend);
-------------------------------------------------------------------------
--
--Title: Local Signal Declarations
--
--Description: The signals used by this entity are described below:
--
-- -dbInSig : This signal is the parallel data input
-- for the UART
-- -dbOutSig : This signal is the parallel data output
-- for the UART
-- -rdaSig : This signal will get the RDA signal from
-- the UART
-- -tbeSig : This signal will get the TBE signal from
-- the UART
-- -rdSig : This signal is the RD signal for the UART
-- -wrSig : This signal is the WR signal for the UART
-- -peSig : This signal will get the PE signal from
-- the UART
-- -feSig : This signal will get the FE signal from
-- the UART
-- -oeSig : This signal will get the OE signal from
-- the UART
--
-- The following signals are used by the main state machine
-- for state control:
--
-- -stCur, stNext
--
-------------------------------------------------------------------------
signal dbInSig : std_logic_vector(7 downto 0);
signal dbOutSig : std_logic_vector(7 downto 0);
signal rdaSig : std_logic;
signal tbeSig : std_logic;
signal rdSig : std_logic;
signal wrSig : std_logic;
signal peSig : std_logic;
signal feSig : std_logic;
signal oeSig : std_logic;
signal stCur : mainState := stReceive;
signal stNext : mainState;
------------------------------------------------------------------------
-- Module Implementation
------------------------------------------------------------------------
begin
------------------------------------------------------------------------
--
--Title: LED definitions
--
--Description: This series of definitions allows the scan code to be
-- displayed on the LEDs on the FPGA system board. Because the
-- dbOutSig is the scan code backwards, the LEDs must be
-- defined backwards from the dbOutSig.
--
------------------------------------------------------------------------
LEDS(7) <= dbOutSig(0);
LEDS(6) <= dbOutSig(1);
LEDS(5) <= dbOutSig(2);
LEDS(4) <= dbOutSig(3);
LEDS(3) <= dbOutSig(4);
LEDS(2) <= dbOutSig(5);
LEDS(1) <= dbOutSig(6);
LEDS(0) <= dbOutSig(7);
-------------------------------------------------------------------------
--
--Title: RS232RefComp map
--
--Description: This maps the signals and ports in main to the
-- RS232RefComp. The TXD, RXD, CLK, and RST of main are
-- directly tied to the TXD, RXD, CLK, and RST of the
-- RS232RefComp. The remaining RS232RefComp ports are
-- mapped to internal signals in main.
--
-------------------------------------------------------------------------
UART: RS232RefComp port map ( TXD => TXD,
RXD => RXD,
CLK => CLK,
DBIN => dbInSig,
DBOUT => dbOutSig,
RDA => rdaSig,
TBE => tbeSig,
RD => rdSig,
WR => wrSig,
PE => peSig,
FE => feSig,
OE => oeSig,
RST => RST);
-------------------------------------------------------------------------
--
--Title: Main State Machine controller
--
--Description: This process takes care of the Main state machine
-- movement. It causes the next state to be evaluated on
-- each rising edge of CLK. If the RST signal is strobed,
-- the state is changed to the default starting state, which
-- is stReceive.
--
-------------------------------------------------------------------------
process (CLK, RST)
begin
if (CLK = '1' and CLK'Event) then
if RST = '1' then
stCur <= stReceive;
else
stCur <= stNext;
end if;
end if;
end process;
-------------------------------------------------------------------------
--
--Title: Main State Machine
--
--Description: This process defines the next state logic for the Main
-- state machine. The main state machine controls the data
-- flow for this testing program in order to send and
-- receive data.
--
-------------------------------------------------------------------------
process (stCur, rdaSig, dboutsig)
begin
case stCur is
-------------------------------------------------------------------------
--
--Title: stReceive state
--
--Description: This state waits for the UART to receive data. While in
-- this state, the rdSig and wrSig are held low to keep the
-- UART from transmitting any data. Once the rdaSig is set
-- high, data has been received, and is safe to transmit. At
-- this time, the stSend state is loaded, and the dbOutSig
-- is copied to the dbInSig in order to transmit the newly
-- acquired parallel information.
--
-------------------------------------------------------------------------
when stReceive =>
rdSig <= '0';
wrSig <= '0';
if rdaSig = '1' then
dbInSig <= dbOutSig;
stNext <= stSend;
else
stNext <= stReceive;
end if;
-------------------------------------------------------------------------
--
--Title: stSend state
--
--Description: This state tells the UART to send the parallel
-- information found in dbInSig. It does this by strobing
-- both the rdSig and wrSig signals high. Once these
-- signals have been strobed high, the stReceive state is
-- loaded.
--
-------------------------------------------------------------------------
when stSend =>
rdSig <= '1';
wrSig <= '1';
stNext <= stReceive;
end case;
end process;
end Behavioral;
On the basis of above code,I am trying to make my own state machine that allows me to receive few bytes from a terminal in a row to a buffer, change the state and send this bytes from a buffer to a terminal on my PC.
I've started from making counter that counts the amounts of the received bytes. I ended up not knowing what is going on, because the counter changes its value not by one but randomly. I am new to VHDL and any suggestions will be appreciated.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity DataCntrl is
Port ( TXD : out std_logic := '1';
RXD : in std_logic := '1';
CLK : in std_logic;
LED : out std_logic_vector(7 downto 0) := "00000000";
RST : in std_logic := '0');
end DataCntrl;
architecture Behavioral of DataCntrl is
component RS232RefComp
Port ( TXD : out std_logic := '1';
RXD : in std_logic;
CLK : in std_logic;
DBIN : in std_logic_vector (7 downto 0);
DBOUT : out std_logic_vector (7 downto 0);
RDA : inout std_logic;
TBE : inout std_logic := '1';
RD : in std_logic;
WR : in std_logic;
PE : out std_logic;
FE : out std_logic;
OE : out std_logic;
RST : in std_logic := '0');
end component;
type mainState is (
stReceive, stA,
stRereceive);
signal dbInSig : std_logic_vector(7 downto 0);
signal dbOutSig : std_logic_vector(7 downto 0);
signal rdaSig : std_logic;
signal tbeSig : std_logic;
signal rdSig : std_logic;
signal wrSig : std_logic;
signal peSig : std_logic;
signal feSig : std_logic;
signal oeSig : std_logic;
signal stCur : mainState := stReceive;
signal stNext : mainState;
begin
UART: RS232RefComp port map ( TXD => TXD,
RXD => RXD,
CLK => CLK,
DBIN => dbInSig,
DBOUT => dbOutSig,
RDA => rdaSig,
TBE => tbeSig,
RD => rdSig,
WR => wrSig,
PE => peSig,
FE => feSig,
OE => oeSig,
RST => RST);
process (CLK, RST)
begin
if (CLK = '1' and CLK'Event) then
if RST = '1' then
stCur <= stReceive;
else
stCur <= stNext;
end if;
end if;
end process;
process (stCur, rdaSig, dboutsig)
variable Send: std_logic :='0';
variable Count: integer :=0;
variable Jol: integer :=0;
begin
Jol:=Count;
Led<=std_logic_vector(to_unsigned(Jol,8));
case stCur is
when stReceive =>
rdSig <= '0';
wrSig <= '0';
if rdaSig = '1' then
Send:='0';
dbInSig <= dbOutSig;
if(Count=4) then
dbInSig <= "11101111";
stNext <= stA;
else
stNext <= stRereceive;
end if;
else
stNext <= stReceive;
end if;
when stRereceive =>
rdSig <= '1';
if(Send='0') then
Count:=Count+1;
Send:='1';
end if;
stNext <= stReceive;
when stA=>
wrSig <= '1';
rdSig <= '1';
end case;
end process;
end Behavioral;
So, take a look at your counter increment code:
process (stCur, rdaSig, dboutsig)
[...]
variable Count: integer := 0;
begin
[...]
case stCur is
[...]
when stRereceive =>
[...]
if(Send='0') then
Count:=Count+1;
Let's analyse what we see here.
count is a variable.
count is increased in a combinatorial process.
[let's leave out that your sensitivity list is incomplete]
When you say "the counter changes its value not by one", I assume you want it to increase by one every clock cycle (or comparable). But to be able to increase over a previous value, the counter must hold that previous value. That means registers are required. However, registers required a clock input. So in a clock-less combinatorial process no registers are inferred.
Then: don't use variables for registered values. There are only very little situations in which you should use variables, and this is not one of them.
Here's an example of a clocked counter process
architecture rtl of ent is
signal count : unsigned(3 downto 0) := (others => '0');
begin
clk_proc : process (clk)
begin
if rising_edge(clk) then
if [condition] then
count <= count + 1;
end if;
if reset = '1' then
count <= (others => '0');
end if;
end if;
end process;
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.