-- Automatically generated by WhishList - https://gitlab.cern.ch/msilvaol/wishlist
-- File name: {{ name.lower() }}_address_decoder
-- Description : {{ description }}

library ieee;
use ieee.std_logic_1164.all;
library work;
use work.{{ name.lower() }}_pkg.all;

entity {{ name.lower() }}_address_decoder is
port(
    clk_i : in std_logic;
    read_i : in std_logic;
    write_i : in std_logic;
    address_i : in std_logic_vector({{ address_width-1 }} downto 0);
    data_i : in std_logic_vector({{ address_width-1 }} downto 0);
    data_o : out std_logic_vector({{ address_width-1 }} downto 0);
    write_ack_o : out std_logic;
    read_ack_o : out std_logic;
    error_o : out std_logic;
    {{ name.lower() }}_status_i : in {{ name.lower() }}_status_record_type;
    {{ name.lower() }}_control_o : out {{ name.lower() }}_control_record_type

);
end entity {{ name.lower() }}_address_decoder;


architecture rtl of {{ name.lower() }}_address_decoder is

signal int_{{ name.lower() }}_control : {{ name.lower() }}_control_record_type;
signal int_{{ name.lower() }}_status : {{ name.lower() }}_status_record_type;
signal write_ack_int : std_logic;
signal read_ack_int : std_logic;
signal error_int : std_logic;

begin

{{ name.lower() }}_control_o <= int_{{ name.lower() }}_control;
int_{{ name.lower() }}_status <= {{ name.lower() }}_status_i;

address_decoder_p : process (clk_i) is
begin
    if rising_edge(clk_i) then
        -- default assignments
        data_o <= (others => 'X');
        write_ack_int <= '0';
        read_ack_int <= '0';
        error_int <= '0';
{#- Iterating status and control registers #}
{%- for permission_regex, direction, strobe in (('^rw?$','status','read'),('^rw$','control','write')) %}
        if ({{ strobe }}_i = '1') then
            {{ strobe }}_ack_int <= '1';
            case address_i is
    {%- set df = address_decoder[address_decoder.permission.str.match(permission_regex)] %}
    {%- for address in np.sort(df.address.unique()) %}
                when X"{{ get_address_string(address) }}" =>
        {%- for i, row in df[df.address==address].iterrows() %}
                {%- if direction == 'control' %}
                    int_{{ row.vhdl_member_name }}{{ get_vhdl_bit_string(row.register_bits_lists, side='signal', node_width=row.node_width) }} <= data_i{{ get_vhdl_bit_string(row.address_bits_lists,side='address', node_width=row.node_width) }};
            {%- else %}
                    data_o{{ get_vhdl_bit_string(row.address_bits_lists,side='address', node_width=row.node_width) }} <= int_{{ row.vhdl_member_name }}{{ get_vhdl_bit_string(row.register_bits_lists,side='signal', node_width=row.node_width) }};
            {%- endif %}
        {%- endfor %}
    {%- endfor %}
                when others =>
                    {{ strobe }}_ack_int <= '0';
                    error_int <= '1';
            end case;
        end if;
{%- endfor %}
    -- delaying output by one clock cycle
    write_ack_o <= write_ack_int;
    read_ack_o <= read_ack_int;
    error_o <= error_int;
    end if;
end process address_decoder_p;

end architecture rtl;