Search code examples
vhdlxilinxxilinx-ise

What's wrong with this signal assignment?


When I compile with Xilinx 9.1i, It tells me:

  • "Line 91. Type of Tens is incompatible with type of tensOut."
  • "Line 92. Type of Ones is incompatible with type of onesOut."

But both are std_logic_vector (7 downto 0)

Here's the code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity BNG is
    Port ( Clk : in  STD_LOGIC;
           E : in  STD_LOGIC;
           BNRand : in  STD_LOGIC_VECTOR (6 downto 0);
           Letter : out  STD_LOGIC_VECTOR (7 downto 0);
           Tens : out  STD_LOGIC_VECTOR (7 downto 0);
           Ones : out  STD_LOGIC_VECTOR (7 downto 0));
end BNG;

architecture Behavioral of BNG is
    type states is (neutral, gen);
    signal current_state, next_state : states;
begin

    state_register: process(Clk)
    begin
        if rising_edge(Clk) then
            current_state <= next_state;
        end if;
    end process;

    next_logic: process(current_state)
    begin
        case current_state is
            when neutral => if E = '1' then next_state <= gen; else next_state <= neutral; end if;
            when gen => next_state <= neutral;
        end case;
    end process next_logic;

    logic: process(current_state)
        variable letterOut, tensOut, onesOut : std_logic_vector (7 downto 0);
        variable tens, ones : integer range 0 to 9;
        variable input : integer;
        constant B : std_logic_vector (7 downto 0) := "01000010";
        constant I : std_logic_vector (7 downto 0) := "01001001";
        constant N : std_logic_vector (7 downto 0) := "01001110";
        constant G : std_logic_vector (7 downto 0) := "01000111";
        constant O : std_logic_vector (7 downto 0) := "01001111";
        constant zero : std_logic_vector (7 downto 0) := "00110000";
    begin
        if current_state = gen then
            input := conv_integer( unsigned(BNRand) );
            tens := input / 10;
            ones := input mod 10;

            if (input > 0) and (input < 16) then
                letterOut := B;
            elsif (input > 15) and (input < 31) then
                letterOut := I;
            elsif (input > 30) and (input < 46) then
                letterOut := N;
            elsif (input > 45) and (input < 61) then
                letterOut := G;
            elsif (input > 60) and (input < 76) then
                letterOut := O;
            end if;

            tensOut := zero + std_logic_vector( conv_unsigned(tens, 8) );
            onesOut := zero + std_logic_vector( conv_unsigned(ones, 8) );
        end if;
        Letter <= letterOut;
        Tens <= tensOut;
        Ones <= onesOut;
    end process logic;

end Behavioral;

Solution

  • In VHDL the identifiers are not case sensitive. The identifiers Tens and Ones are declared as port, while identifiers tens and ones are declared as variables in the process. The assign with Tens <= tensOut; and Ones <= onesOut; inside the process thus sees the variables tens and ones, and not the ports.

    A useful coding style is to name variables with a ending _v, thus getting tens_v and ones_v, which also helps to remember the kind of assign as <= for signals and := for variables.