Unsigned VHDL conversion not working - vhdl

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--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 fourToSixteenDecoder is
port ( a : in std_logic_vector(0 to 3);
EN : in STD_LOGIC;
Y : out std_logic_vector(0 to 15));
end fourToSixteenDecoder;
architecture Behavioral of fourToSixteenDecoder is
begin
process(a, EN)
variable inputs : integer := conv_integer(unsigned(a));
variable Y_c : std_logic_vector(0 to 15);
begin
Y_c := X"0000";
if (EN = '1') then
Y_c(inputs) := '1';
elsif (EN = '0') then
Y_c := X"0000";
end if;
Y <= Y_c;
end process;
end Behavioral;
Trying to make a 4-16 Decoder, however, I am trying to use conversion between integer and SLV to do bit indexing assignment, but the conversion does not work.
ERROR:HDLCompiler:806 - "..." Line 40: Syntax error near "b".
Also tried
to_integer(unsigned())
integer(unsigned())
integer(to_unsigned())
to_integer(to_unsigned())
use IEEE.ARITH and IEEE.STD_LOGIC.UNSIGNED
No solution.

The conversion routine is call to_integer in package numeric_std, and for an unsigned produces a natural range integer.
With variable inputs : integer := to_integer(unsigned(a)); inputs would be initialized to the initial value of a converted to an integer (likely 0 if a is uninitialized (all 'U's).
There is no other assignment to inputs and inputs wouldn't change with a value changes.
Replace the variable inputs declaration with
variable inputs: integer range 0 to 15;
which restricts the range of inputs to the index range of Y_c.
Add
inputs := to_integer(unsigned(a));
as a first sequential statement to the process.
The two assignments:
Y_c := X"0000";
are redundant. The elsif can be eliminated:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fourToSixteenDecoder is
port (
a: in std_logic_vector(0 to 3);
EN: in std_logic;
Y: out std_logic_vector(0 to 15)
);
end entity fourToSixteenDecoder;
architecture Behavioral of fourToSixteenDecoder is
begin
process(a, EN)
-- variable inputs : integer := conv_integer(unsigned(a));
variable inputs: integer range 0 to 15;
variable Y_c: std_logic_vector(0 to 15);
begin
inputs := to_integer(unsigned(a)); -- ADDED
Y_c := X"0000";
if EN = '1' then
Y_c(inputs) := '1';
-- elsif (EN = '0') then
-- Y_c := X"0000";
end if;
Y <= Y_c;
end process;
end architecture Behavioral;
This analyzes, elaborates and simulates. Notice the parentheses around the if statement conditions aren't needed.
A testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb_4to16 is
end entity;
architecture fum of tb_4to16 is
signal a: std_logic_vector (0 to 3) := (others => '0');
signal EN: std_logic;
signal Y: std_logic_vector(0 to 15);
begin
DUT:
entity work.fourtosixteendecoder
port map (
a => a,
EN => EN,
Y => Y
);
STIMULI:
process
begin
for i in 0 to 15 loop
EN <= '0';
a <= std_logic_vector(to_unsigned(i,4));
wait for 10 ns;
EN <='1';
wait for 10 ns;
end loop;
EN <= '0';
wait for 10 ns;
wait;
end process;
end architecture;
The results:

Related

Can VHDL synthesize clk'event?

I'm trying to write a 4-bit multiplier with VHDL. This is the code I wrote:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--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 multiplier_8bit_2 is
Port ( clk : in STD_LOGIC;
A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
Y : out STD_LOGIC_VECTOR (7 downto 0));
end multiplier_8bit_2;
architecture Behavioral of multiplier_8bit_2 is
begin
process(clk, A, B)
variable sum_result : unsigned(8 downto 0) := (others => '0');
begin
if A'event or B'event then
sum_result:=(others => '0');
for i in 0 to 3 loop
if B(i)='1' then
sum_result:=sum_result+shift_left(b"00000"&unsigned(A),i);
end if;
end loop;
end if;
Y<=STD_LOGIC_VECTOR(sum_result(7 downto 0));
end process;
end Behavioral;
It can be executed in simulation and it works, but when I try to synthesize it, I get:
unsupported Clock statement.
If you just want a multiplier with 4 bit arguments, then code it without clk as follows. You do not need a'event or b'event.
process(A, B)
variable sum_result : unsigned(8 downto 0) := (others => '0');
begin
sum_result:=(others => '0');
for i in 0 to 3 loop
if B(i)='1' then
sum_result:=sum_result+shift_left(b"00000"&unsigned(A),i);
end if;
end loop;
Y<=STD_LOGIC_VECTOR(sum_result(7 downto 0));
end process;
OTOH, if you wanted a multiplier and a flip-flop, then code the following. You have no need for A or B on the sensitivity list.
process(clk)
variable sum_result : unsigned(8 downto 0) := (others => '0');
begin
if clk = '1' and clk'event then
sum_result:=(others => '0');
for i in 0 to 3 loop
if B(i)='1' then
sum_result:=sum_result+shift_left(b"00000"&unsigned(A),i);
end if;
end loop;
Y<=STD_LOGIC_VECTOR(sum_result(7 downto 0));
end if;
end process;

How to declare an array of arrays in the test bench of a VHDL code?

I have an array of arrays defined as the input to my entity. I used a package to define the array of arrays. In the test bench, I included that package and declared the component in the architecture but there is an error saying "formal port x does not exist in entity average. Please compare the definition of block average to its component declaration and its instantion to detect the mismatch."
Attaching the declarations below. Please help.
-- the code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
package vpkg is
type m_array is array(1 downto 0, 1 downto 0) of std_logic_vector(7 downto 0);
end package;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vpkg.all;
entity average is
Port (x : in m_array;
clk : in std_logic;
y : out std_logic_vector(7 downto 0)
);
end average;
architecture avg_arch of average is
signal sum : std_logic_vector(8 downto 0) := (others => '0');
begin
process(x):
for I in 0 to 1 loop
for J in 0 to 1 loop
sum <= sum + ('0' + x(I,J));
end loop;
end loop;
end process;
y <= std_logic_vector(to_signed(to_integer(signed(sum) / 4),8));
end avg_arch;
--the test bench
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.vpkg.all;
entity tb_average is
-- Port ( );
end tb_average;
architecture tb_average_arch of tb_average is
component average
Port (x : in m_array;
clk : in std_logic;
y : out std_logic_vector(7 downto 0)
);
end component;
signal x : m_array;
signal clk : std_logic := '0';
signal y : std_logic_vector(7 downto 0);
begin
average_1 : average Port Map (x => x,clk => clk,y=>y);
input_proc : process
begin
wait for 100ns;
x(0,0) <= "00001001";
x(0,1) <= "00000110";
x(1,0) <= "00000011";
x(1,1) <= "00000001";
wait;
end process;
clk_proc : process
begin
wait for 100ns;
loop
clk <= '1';
wait for 10ns;
clk <= '0';
wait for 10ns;
end loop;
end process;
end tb_average_arch;

Adding two bit_vector in VHDL return error "(vcom-1581) No feasible entries for infix operator '+'."

This is my code for converting binary to BCD in VHDL
library ieee;
use ieee.numeric_bit.all;
entity bin2bcd is
port (bin : in bit_vector(3 downto 0) := "0000";
clk : in bit;
bcdout : out bit_vector(4 downto 0) := "00000");
end bin2bcd;
architecture bin2bcdarch of bin2bcd is
begin
process(clk)
variable gt9 : bit;
variable temp : bit_vector(3 downto 0) := "0110";
variable bcdout_temp : bit_vector(4 downto 0);
begin
if clk'event and clk = '1' then
gt9 := bin(3) and(bin(2) or bin(1));
if gt9 = '1' then
bcdout_temp := ('0' & bin) + ('0' & temp);
else
bcdout_temp := ('0' & bin);
end if;
end if;
bcdout <= bcdout_temp;
end process;
end bin2bcdarch;
The problem is when i am trying to add the two bit_vector in the line
bcdout_temp := ('0' & bin) + ('0' & temp);
using "+" operator, that I get the error
(vcom-1581) No feasible entries for infix operator '+'.
Now, I looked in the web and most of the solutions are for when I use std_logic_vector.
The code works fine if I use std_logic_vector but not when I use bit_vector.
Is there any solution to the problem as to why I am getting the error?
You can add bit vectors if you use ieee.numeric_bit_unsigned.all which is part of VHDL-2008. The numeric_std package you're using does not define addition for bit vector.
If you find your old CAD lab software doesn't support numeric_bit_unsigned you can use type conversions, numeric_bit contains declarations for types signed and unsigned:
library ieee;
use ieee.numeric_bit.all;
entity bin2bcd is
port (bin : in bit_vector(3 downto 0) := "0000";
clk : in bit;
bcdout : out bit_vector(4 downto 0) := "00000");
end bin2bcd;
architecture bin2bcdarch of bin2bcd is
begin
process(clk)
variable gt9 : bit;
variable temp : unsigned(3 downto 0) := "0110"; -- was bit_vector
variable bcdout_temp : unsigned(4 downto 0); -- was bit vector
begin
if clk'event and clk = '1' then
gt9 := bin(3) and(bin(2) or bin(1));
if gt9 = '1' then
bcdout_temp := '0' & unsigned(bin) + ('0' & temp); -- type conversion
else
bcdout_temp := '0' & unsigned(bin); -- type conversion
end if;
end if;
bcdout <= bit_vector(bcdout_temp); -- type conversion
end process;
end bin2bcdarch;
Note temp can also be class constant instead of variable, it's not assigned other than an initial value.
From your comments using WARP2 to synthesis (presumably CPLDs) I recall that it was originally developed to use AHDL as input description and that support for VHDL and Verilog were an afterthought.
You're likely seeing limitations based on what VHDL constructs map to AHDL constructs that are supported for synthesis.
The way to deal with such limitations may be to describe troublesome parts of designs as a dataflow description:
entity bin2bcd is
port (
bin: in bit_vector(3 downto 0);
clk: in bit;
bcdout: out bit_vector(4 downto 0)
);
end entity bin2bcd;
architecture dataflow of bin2bcd is
signal bcdout_temp: bit_vector(4 downto 0);
begin
bcdout_temp(4) <= bin(3) and ( bin(2) or bin(1) ); -- gt9
bcdout_temp(3) <= not bcdout_temp(4) and bin(3); -- zero if gt9
bcdout_temp(2) <= ( bin(3) and bin(2) and bin(1)) or
(not bin(3) and bin(2));
bcdout_temp(1) <= ( bcdout_temp(4) and not bin(1)) or -- gt9 XOR bin(1)
(not bcdout_temp(4) and bin(1));
bcdout_temp(0) <= bin(0); -- doesn't change
REG5:
process (clk)
begin
if clk'event and clk = '1' then
bcdout <= bcdout_temp;
end if;
end process;
end architecture;
While there's no guarantee of this would work better (although likely) it also simulates as VHDL with a testbench:
library ieee;
use ieee.numeric_bit.all;
entity bin2bcd_tb is
end entity;
architecture foo of bin2bcd_tb is
signal bin: bit_vector(3 downto 0);
signal clk: bit;
signal bcdout: bit_vector(4 downto 0);
begin
DUT:
entity work. bin2bcd (dataflow)
port map (
bin => bin,
clk => clk,
bcdout => bcdout
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if now > 160 ns then
wait;
end if;
end process;
STIMULI:
process
begin
for i in 0 to 2 ** bin'length - 1 loop
bin <= bit_vector(to_unsigned(i, bin'length));
wait for 10 ns;
end loop;
wait;
end process;
end architecture;
And shows it gives the right results:
bin is displayed in decimal while bcdout is displayed in hex.

VHDL Warning: (vcom-1263) Configuration specification "all : bcd" applies to no component instantiation statements

I have been stuck with this problem for a while. I would be really grateful if someone is able help. Have gone through most of the code repeatedly without any solution. There are sets of codes in use; this bcd counter is used further in the rest of my project. I have added the necessary codes below:
BCD counter for 1 digit:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE WORK.mypackage_p.ALL;
ENTITY bcd_e IS
PORT(
res_i, clk_i, enable_i, counter_res_i : IN STD_LOGIC;
bcd_o : OUT STD_LOGIC_VECTOR(bcd_width_c-1 DOWNTO 0);
carry_o : OUT STD_LOGIC
);
END bcd_e;
ARCHITECTURE bcd_a OF bcd_e IS
SIGNAL count_s : INTEGER RANGE bcd_cnt_c DOWNTO 0;
BEGIN
PROCESS(res_i, clk_i)
BEGIN
IF (res_i = '1') THEN
count_s <= 0;
ELSIF (clk_i = '1' AND clk_i'EVENT) THEN
IF (enable_i = '1') THEN
IF(count_s >= bcd_cnt_c) THEN
count_s <= 0;
ELSE
count_s <= count_s + 1;
END IF;
END IF;
IF (counter_res_i = '1') THEN
count_s <= 0;
END IF;
END IF;
END PROCESS;
bcd_o <= STD_LOGIC_VECTOR(to_unsigned(count_s, bcd_width_c));
carry_o <= '1' WHEN (count_s = bcd_cnt_c) ELSE '0';
END bcd_a;
8 digit BCD using the above bcd counter to create 8 digits
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE WORK.mypackage_p.ALL;
ENTITY bcd_8counter_e IS
PORT(
res_i, clk_i, enable_i, counter_res_i : IN STD_LOGIC;
bcd_array_o : OUT bcd_array_t
);
END bcd_8counter_e;
ARCHITECTURE bcd_8counter_a OF bcd_8counter_e IS
COMPONENT bcd
PORT(
res_i, clk_i, enable_i, counter_res_i : IN STD_LOGIC;
bcd_o : OUT STD_LOGIC_VECTOR(bcd_width_c-1 DOWNTO 0);
carry_o : OUT STD_LOGIC
);
END COMPONENT;
SIGNAL bcd_array_s : bcd_array_t;
SIGNAL enable_s : STD_LOGIC_VECTOR(no_of_digits_c-1 DOWNTO 0);
SIGNAL carry_s : STD_LOGIC_VECTOR(no_of_digits_c-1 DOWNTO 0);
FOR ALL : bcd USE ENTITY WORK.bcd_e (bcd_a);
BEGIN
carry_s(0) <= enable_i;
gen_carry : FOR i IN 1 TO (no_of_digits_c-1) GENERATE
carry_s(i) <= carry_s((i-1)) AND enable_s((i-1));
END GENERATE gen_carry;
gen_bcd : FOR i IN 0 TO (no_of_digits_c-1) GENERATE
digitx : bcd PORT MAP(res_i, clk_i, carry_s(i), counter_res_i, bcd_array_s(i), enable_s(i));
END GENERATE gen_bcd;
bcd_array_o <= bcd_array_s
END bcd_8counter_a;
My package file for the constants:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
PACKAGE mypackage_p IS
CONSTANT freq_20k_c : INTEGER := 2500;
CONSTANT bcd_cnt_c : INTEGER := 9;
CONSTANT bcd_width_c : INTEGER := 4;
CONSTANT no_of_digits_c : INTEGER := 8;
TYPE bcd_array_t IS ARRAY(7 DOWNTO 0) OF STD_LOGIC_VECTOR(3 DOWNTO 0);
END PACKAGE;
I keep getting the following warning:
Warning: /home/stud/mr-131416/Desktop/VHDL_Project_Latest/src/bcd_counter8_a.vhd(15): (vcom-1263) Configuration specification "all : bcd" applies to no component instantiation statements.
The code does not pass test/simulation of a test-bench because of this warning. Help would be really appreciated.
It's a matter of scope. A component configuration configures a component instantiation. The generate statement produces a block statement (or nested block statements when a port map is supplied).
A block statement (for an internal or external block) use a block configuration which is only found in a configuration declaration.
Binding indications are not hierarchical, without the ability to reach down into a block to specify a component instantiation you can either use a configuration declaration or move the configuration specification:
-- for all : bcd use entity work.bcd_e (bcd_a);
begin
carry_s(0) <= enable_i;
gen_carry :
for i in 1 to (no_of_digits_c-1) generate
carry_s(i) <= carry_s((i-1)) and enable_s((i-1));
end generate gen_carry;
gen_bcd :
for i in 0 to (no_of_digits_c-1) generate
for all: bcd use entity work.bcd_e (bcd_a);
begin
digitx : bcd port map (res_i, clk_i, carry_s(i),
counter_res_i, bcd_array_s(i), enable_s(i));
end generate gen_bcd;
bcd_array_o <= bcd_array_s; -- CHANGED WAS MISSING SEMICOLON
end bcd_8counter_a;
Note the missing semicolon on the assignment statement for bcd_array_o has been added.
With these changes your design analyzes and elaborates without warnings.
You could note not all synthesis tools support configuration declarations while most support configuration specifications.
See IEEE Std 1076-2008 7.3 Configuration specification, 3.4 Configuration declarations, 3.4.2 Block configurations
The failure to simulate or synthesize would be because the distx component instantiations are unbound because there isn't a bcd entity found in the working directory.
Writing a simple testbench that does not invoke the synchronous reset, uses a clock with a 10 ns period and runs for 10 ms:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.mypackage_p.all;
entity tb is
end entity;
architecture foo of tb is
signal reset: std_logic; -- '1' for RESET
signal clk: std_logic := '0';
signal en: std_logic; -- '1' for ENABLE
signal syn_reset: std_logic; -- '1' for SYNCHRONOUS RESET
signal bcd_array: bcd_array_t;
begin
DUT:
entity work.bcd_8counter_e
port map (
res_i => reset,
clk_i => clk,
enable_i => en,
counter_res_i => syn_reset,
bcd_array_o => bcd_array
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if now > 10 ms then
wait;
end if;
end process;
STIMULI:
process
begin
wait for 10 ns;
reset <= '0';
en <= '0';
syn_reset <= '0';
wait for 10 ns;
reset <= '1';
wait for 20 ns;
reset <= '0';
wait for 20 ns;
en <= '1';
wait;
end process;
end architecture;
Shows that the counter depends on enable and shows that the first 6 digits work:

VHDL Counter ones errors

I already done the code, and it can work, However, when I try to write the test bench, I got some troubles on that. The input x sets up as 8 bits, and x: IN BIT_VECTOR (N -1 DOWNTO 0).
When I write the test bench I connot enter the bits number.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones IS
GENERIC (N: INTEGER := 8); -- number of bits
PORT ( x: IN BIT_VECTOR (N -1 DOWNTO 0); y: OUT NATURAL RANGE 0 TO N);
END ENTITY ;
architecture Behavioral of Count_ones is
TYPE count is Array (N DOWNTO 1) OF Natural;
signal a : count;
begin
a(0) <= 1 when (x(0) = '1')
else
0;
gen: FOR i IN N-1 DOWNTO 0
GENERATE
a(i+1) <= (a(i)+1) when (x(i)='0')
else
a(i);
END GENERATE;
y <= a(N-1);
end Behavioral;
The Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones_TB IS
END Count_ones_TB;
ARCHITECTURE behavior OF Count_ones_TB IS
COMPONENT Count_ones
PORT(
x : IN std_logic_vector(7 downto 0);
y : OUT std_logic_vector(0 to 3)
);
END COMPONENT;
--Inputs
signal x : std_logic_vector(7 downto 0) := (others => '0');
--Outputs
signal y : std_logic_vector(0 to 3);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Count_ones PORT MAP (
x => x,
y => y
);
stim_proc: process
begin
x <= "00010101";
wait for 100 ns;
x <= "00001001";
wait for 100 ns;
x <= "11111111101"
wait for 100ns;
-- insert stimulus here
wait;
end process;
END;
The error is
Entity port x does not match with type std_logic_vector of component port
Entity port y does not match with type std_logic_vector of component port
Please help me, I real cannot figure out the way to solve that.
The answer to your specific question is that the types of the ports in the entity, the ports in the component and the types of the signals must match. Here is a link to your code with those errors and many more corrected.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones IS
GENERIC (N: INTEGER := 8); -- number of bits
PORT ( x: IN BIT_VECTOR (N -1 DOWNTO 0); y: OUT NATURAL RANGE 0 TO N);
END ENTITY ;
architecture Behavioral of Count_ones is
TYPE count is Array (N DOWNTO 0) OF Natural;
signal a : count;
begin
a(0) <= 1 when (x(0) = '1')
else
0;
gen: FOR i IN N-1 DOWNTO 0
GENERATE
a(i+1) <= (a(i)+1) when (x(i)='0')
else
a(i);
END GENERATE;
y <= a(N-1);
end Behavioral;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
ENTITY Count_ones_TB IS
END Count_ones_TB;
ARCHITECTURE behavior OF Count_ones_TB IS
COMPONENT Count_ones
GENERIC (N: INTEGER := 8); -- number of bits
PORT ( x: IN BIT_VECTOR (N -1 DOWNTO 0);
y: OUT NATURAL RANGE 0 TO N);
END COMPONENT;
--Inputs
signal x : BIT_VECTOR(7 downto 0) := (others => '0');
--Outputs
signal y : natural;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Count_ones PORT MAP (
x => x,
y => y
);
stim_proc: process
begin
x <= "00010101";
wait for 100 ns;
x <= "00001001";
wait for 100 ns;
x <= "11111101";
wait for 100ns;
-- insert stimulus here
wait;
end process;
END;
However I must point out that you are a long way from achieving your goal of trying to count the number of ones.
Because of that:
My corrections to your code are not the only correct answer. In
fact, my corrections are not even a good answer. I have simply made
the minimum corrections to make your code compile and run. You need
to think very carefully what type all the ports and signals in your
design should be.
My corrections will not make your code work, i.e. count the number of
ones.

Resources