Search code examples
vhdlhdl

Initialize array of integer


I have problem about inialize of integer.

package mytypes is
    type gamma_cor_array is array (NATURAL RANGE <>) of integer range 15 downto 0;
end mytypes;

library UNISIM;
use UNISIM.VComponents.all;
use work.mytypes.all;

entity gamma_correction is
    GENERIC (DEPH : natural:=4; GAMMA_COR : real:=1.0);
    Port ( clk : in  STD_LOGIC;
        gamma_cor_array_s : out gamma_cor_array(2**DEPH-1 downto 0):= (others => 0));

end gamma_correction;

architecture Behavioral of gamma_correction is

begin
    PROCESS (clk) BEGIN
        IF rising_edge(clk) THEN
            for i in 0 to (2**DEPH - 1) loop
                gamma_cor_array_s(i) <= integer(((real(i)/real(2**DEPH - 1))**GAMMA_COR)*real(2**DEPH - 1));
            end loop;
        end if;
    end process;
end Behavioral;

I get these warnings:

WARNING:Xst:2404 - FFs/Latches <1:1>> (without init value) have a constant value of 0 in block .

WARNING:Xst:2404 - FFs/Latches <1:2>> (without init value) have a constant value of 0 in block .

WARNING:Xst:2404 - FFs/Latches <1:2>> (without init value) have a constant value of 0 in block .

WARNING:Xst:2404 - FFs/Latches <1:2>> (without init value) have a constant value of 0 in block .

WARNING:Xst:2404 - FFs/Latches <3:3>> (without init value) have a constant value of 0 in block .

WARNING:Xst:2404 - FFs/Latches <1:3>> (without init value) have a constant value of 0 in block .

WARNING:Xst:2404 - FFs/Latches <1:4>> (without init value) have a constant value of 0 in block .

In testbench my code is working ok. Init values are 0, but the warnings still remain. How can I get rid of them?


Solution

  • Why isn't gamma_cor_array_s class constant? GAMMA_COR is class constant as is DEPH, you do not need flip flops, write a function to initialize gamma_cor_s where it is used and don't use an entity/architecture pair.

    As is the values of gamma_cor_s are (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) after rising_edge (clk):

    library ieee;
    use ieee.std_logic_1164.all;
    use work.mytypes.all;  -- type gamma_cor_array
    
    entity gam_cor_tb is
    end entity;
    architecture foo of gam_cor_tb is
        signal clk: std_logic := '0';
        constant DEPH:  natural := 4;
        constant GAMMA_COR: real := 1.0;
        signal gamma_cor_array_s:  
                    gamma_cor_array (2 ** DEPH - 1 downto 0) ;
    begin
    CLOCK:
        process
        begin
            wait for 10 ns;
            clk <= not clk;
            wait for 10 ns;
            wait;   -- one ping only
        end process;
    DUT:
        entity work.gamma_correction
            generic map (
                DEPH => DEPH,
                GAMMA_COR => GAMMA_COR
            )
            port map (
                clk => clk,
                gamma_cor_array_s => gamma_cor_array_s
            );
    MONITOR:
        process (gamma_cor_array_s)
        begin
            for i in 0 to (2 ** DEPH - 1) loop
                report "gamma_cor_array_s(" & integer'image(i) & ") = " &
                        integer'image(gamma_cor_array_s(i));
            end loop;
        end process;
    end architecture;
    

    The results:

    gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(0) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(1) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(2) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(3) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(4) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(5) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(6) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(7) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(8) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(9) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(10) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(11) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(12) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(13) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(14) = 0 gamma_corrections.vhdl:75:13:@0ms:(report note): gamma_cor_array_s(15) = 0 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(0) = 0 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(1) = 1 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(2) = 2 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(3) = 3 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(4) = 4 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(5) = 5 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(6) = 6 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(7) = 7 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(8) = 8 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(9) = 9 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(10) = 10 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(11) = 11 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(12) = 12 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(13) = 13 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(14) = 14 gamma_corrections.vhdl:75:13:@10ns:(report note): gamma_cor_array_s(15) = 15

    You declare 64 flip flops, initialize them to all '0' and only 30 of them are changed to '1' - you didn't show all the warnings (which can be ignored here). Use of type real is non-portable (real values are approximate).

    The context clause for entity gamma_correction should be:

        library ieee; 
        ieee.std_logic_1164.all; -- for type std_logic, function rising_edge
        use ieee.math_real.all;  -- for function "**" [integer, real return real]
        use work.mytypes.all;    -- for type gamma_cor_array
    

    The references to unisim are not needed.

    For initializing a constant instead of using a signal generated in a separate entity and architecture:

    architecture fum of gam_cor_tb is
        signal clk: std_logic := '0';
        constant DEPH:  natural := 4;
        constant GAMMA_COR: real := 1.0;
        -- signal gamma_cor_array_s:
        --             gamma_cor_array (2 ** DEPH - 1 downto 0) ;
    
        function gamma_correct return gamma_cor_array is  -- added pure function
            use ieee.math_real.all;
            variable gamma_cor_array_s: gamma_cor_array(2 ** DEPH - 1 downto 0);
        begin
            for i in 0 to (2 ** DEPH - 1) loop
                gamma_cor_array_s(i) := integer (
                    ( (real(i) / real (2 ** DEPH - 1) ) ** GAMMA_COR ) * 
                      real(2 ** DEPH - 1)
                );
            end loop;
            return gamma_cor_array_s;
        end function;
    
        constant gamma_cor_array_s:  -- previously a signal
                    gamma_cor_array (2 ** DEPH - 1 downto 0) := gamma_correct;
    begin
    -- CLOCK:
    --     process
    --     begin
    --         wait for 10 ns;
    --         clk <= not clk;
    --         wait for 10 ns;
    --         wait;   -- one ping only
    --     end process;
    -- DUT:
    --     entity work.gamma_correction
    --         generic map (
    --             DEPH => DEPH,
    --             GAMMA_COR => GAMMA_COR
    --         )
    --         port map (
    --             clk => clk,
    --             gamma_cor_array_s => gamma_cor_array_s
    --         );
    MONITOR:
        process -- (gamma_cor_array_s)
        begin
            for i in 0 to (2 ** DEPH - 1) loop
                report "gamma_cor_array_s(" & integer'image(i) & ") = " &
                        integer'image(gamma_cor_array_s(i));
            end loop;
            wait;
        end process;
    end architecture;
    

    The function specification needs to be within the scope of the the constants previously passed as generic constants to entity gamma_correction.

    The function is used to initialize a constant which is a look up table to determine gamma correction.

    Notice there is no signal which communicates values between processes based on events. One you assigned gamma_cor_array_s the values were never changed (the driver in the process in entity gamma_correction's architecture).

    The output value is:

    gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(0) = 0 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(1) = 1 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(2) = 2 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(3) = 3 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(4) = 4 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(5) = 5 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(6) = 6 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(7) = 7 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(8) = 8 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(9) = 9 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(10) = 10 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(11) = 11 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(12) = 12 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(13) = 13 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(14) = 14 gamma_corrections.vhdl:126:13:@0ms:(report note): gamma_cor_array_s(15) = 15

    which matches the value of the previous signal after the rising edge of clock.

    It's possible to make gamma_cor_array_s a signal, subject to dynamic assignment, this requires all assignments are done in one process (a concurrent statement will elaborate a process for an assignment)