Bao Thai
Bao Thai

Reputation: 553

Unsigned VHDL conversion not working

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.

Upvotes: 0

Views: 1719

Answers (1)

user1155120
user1155120

Reputation:

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: tb_4to6.png

Upvotes: 2

Related Questions