library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.firebee_utils_pkg.all; entity flexbus_register is generic ( reg_width : integer := 11; match_address : std_logic_vector(31 downto 0) := (others => '0'); num_ignore : integer range 0 to 31; match_fbcs : integer := 0 ); port ( clk : in std_logic; -- FlexBus signals fb_addr : in std_logic_vector(31 downto 0); fb_ad_in : in std_logic_vector(31 downto 0); fb_ad_out : out std_logic_vector(31 downto 0); fb_cs_n : in std_logic_vector(5 downto 1); fb_wr_n : in std_logic; fb_oe_n : in std_logic; fb_size : in std_logic_vector(1 downto 0); register_ta : out std_logic ); end entity flexbus_register; architecture rtl of flexbus_register is signal fbcs_match : std_logic; signal address_match : std_logic; signal fb_b : std_logic_vector(3 downto 0); -- byte selects signal cs : std_logic; signal reg_value : std_logic_vector(reg_width - 1 downto 0); begin -- byte selects -- HWORD -- HHBYT -- LONG UND LINE fb_b(0) <= (fb_size(1) and (not fb_size(0)) and (not fb_addr(1))) or ((not fb_size(1)) and fb_size(0) and (not fb_addr(1)) and (not fb_addr(0))) or ((not fb_size(1)) and (not fb_size(0))) or (fb_size(1) and fb_size(0)); -- HWORD -- HLBYT -- LONG UND LINE fb_b(1) <= (fb_size(1) and (not fb_size(0) and (not fb_addr(1)))) or ((not fb_size(1)) and fb_size(0) and (not fb_addr(1)) and fb_addr(0)) or ((not fb_size(1)) and (not fb_size(0))) or (fb_size(1) and fb_size(0)); -- LWORD -- LHBYT -- LONG UND LINE fb_b(2) <= (fb_size(1) and (not fb_size(0)) and fb_addr(1)) or ((not fb_size(1)) and fb_size(0) and fb_addr(1) and (not fb_addr(0))) or ((not fb_size(1)) and (not fb_size(0))) or (fb_size(1) and fb_size(0)); -- LWORD -- LLBYT -- LONG UND LINE fb_b(3) <= (fb_size(1) and (not fb_size(0)) and fb_addr(1)) or ((not fb_size(1)) and fb_size(0) and fb_addr(1) and fb_addr(0)) or ((not fb_size(1)) and (not fb_size(0))) or (fb_size(1) and fb_size(0)); fbcs_match <= '1' when not(fb_cs_n(match_fbcs)) = '1' else '0'; address_match <= f_addr_cmp_mask(fb_addr, match_address, num_ignore); cs <= '1' when fbcs_match and address_match else '0'; p_copy_data_in : process (all) begin reg_value <= reg_value; if cs and not fb_wr_n then if reg_width > 24 and fb_b(0) = '1' then -- HH byte reg_value(reg_width - 1 downto 24) <= fb_ad_in(work.firebee_utils_pkg.min(31, reg_width - 1) downto 24); end if; if reg_width > 16 and fb_b(1) = '1' then -- HL byte reg_value(work.firebee_utils_pkg.min(23, reg_width - 1) downto 16) <= fb_ad_in(work.firebee_utils_pkg.min(23, reg_width - 1) downto 16); end if; if reg_width > 8 and fb_b(2) = '1' then -- LH byte reg_value(work.firebee_utils_pkg.min(15, reg_width - 1) downto 8) <= fb_ad_in(work.firebee_utils_pkg.min(15, reg_width - 1) downto 8); end if; if reg_width > 0 and fb_b(3) = '1' then -- LL byte reg_value(work.firebee_utils_pkg.min(7, reg_width - 1) downto 0) <= fb_ad_in(work.firebee_utils_pkg.min(7, reg_width - 1) downto 0); end if; end if; end process p_copy_data_in; p_copy_data_out : process (all) begin fb_ad_out <= (others => 'Z'); if cs and not fb_oe_n then if reg_width > 24 and fb_b(0) = '1' then -- HH byte fb_ad_out(work.firebee_utils_pkg.min(31, reg_width - 1) downto 24) <= reg_value(work.firebee_utils_pkg.min(31, reg_width - 1) downto 24); end if; if reg_width > 16 and fb_b(1) = '1' then -- HL byte fb_ad_out(work.firebee_utils_pkg.min(23, reg_width - 1) downto 16) <= reg_value(work.firebee_utils_pkg.min(23, reg_width - 1) downto 16); end if; if reg_width > 8 and fb_b(2) = '1' then -- LH byte fb_ad_out(work.firebee_utils_pkg.min(15, reg_width - 1) downto 8) <= reg_value(work.firebee_utils_pkg.min(15, reg_width - 1) downto 8); end if; if reg_width > 0 and fb_b(3) = '1' then -- LL byte fb_ad_out(work.firebee_utils_pkg.min(7, reg_width - 1) downto 0) <= reg_value(work.firebee_utils_pkg.min(7, reg_width - 1) downto 0); end if; end if; end process p_copy_data_out; register_ta <= cs; end architecture rtl;