-- Provides information about the firmware.
-- This block is written as a generic memory that sends data based on the requested address.
--
-- Generally this block is connected to the 'control' interface in the userlogiccmp_forxilly block and the user interacts with it using the 'control' files.
-- The information_data package should contain several mandatory constants as well as the contents of the memory. Generally, the first four 32-bit-tuples are occupied by a unique GUID that identifies the firmware.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library utilities;
use utilities.utilities.all;
library information;
use information.information_data.all;
----------------------------------------------------------------
-- NOTE: No range check on the i_data requested address.
entity information_block is
port (
clk : in std_logic;
rst : in std_logic;
-- Input side:
i_data : in std_logic_vector( 31 downto 0 );
i_valid : in std_logic;
o_enable : out std_logic;
-- Output side:
o_data : out std_logic_vector( 31 downto 0 );
o_valid : out std_logic;
i_enable : in std_logic
);
end entity;
architecture rtl of information_block is
-- data in buffer
signal buffer_valid : std_logic;
signal buffer_data : std_logic_vector( o_data'range );
-- data from the memory
signal mem_valid : std_logic;
signal mem_data : std_logic_vector( o_data'range );
signal oo_valid : std_logic;
signal addr : unsigned( log2( C_INFO_NUMDATA ) - 1 downto 0 );
--signal i_valid_d : std_logic;
constant C_RESVAL : std_logic_vector( C_INFO_BITWIDTH -1 downto 0 ) := ( others => '0' );
-- Memory content:
subtype t_memdata is t_twodim_stdlogic( C_INFO_NUMDATA - 1 downto 0, C_INFO_BITWIDTH - 1 downto 0 );
constant C_MEMDATA : t_memdata := stdlogicvector_to_twodim( C_INFO_DATA, C_INFO_NUMDATA, C_INFO_BITWIDTH );
begin
o_enable <= i_enable;
o_valid <= oo_valid and i_enable;
o_data <= buffer_data when buffer_valid = '1' else
mem_data;
oo_valid <= buffer_valid when buffer_valid = '1' else
mem_valid;
valid_handling: process( clk )
begin
if( rising_edge(clk) ) then
mem_valid <= i_valid;
end if;
end process;
addr <= unsigned( i_data( addr'range ) );
-- inferred bram:
inferred_bram_inst : entity utilities.inferred_bram
generic map(
G_RAM_CONTENT => C_MEMDATA,
G_WIDTH => C_INFO_BITWIDTH,
G_SIZE => C_INFO_NUMDATA,
G_RESVAL_A => C_RESVAL
)
port map(
i_clka => clk,
i_ena => '1',
i_wea => '0',
i_resa => '0',
i_addra => addr,
i_dataa => ( C_INFO_BITWIDTH - 1 downto 0 => '0' ),
o_dataa => mem_data
);
outp_data : process( clk )
begin
if( rising_edge(clk) ) then
if( rst = '1' ) then
buffer_valid <= '0';
else
if( i_enable = '1' ) then
buffer_valid <= '0';
elsif( buffer_valid = '0' ) then
buffer_valid <= mem_valid;
buffer_data <= mem_data;
end if;
end if;
end if;
end process;
end architecture;