forked from Firebee/FPGA_Config
115 lines
4.9 KiB
VHDL
115 lines
4.9 KiB
VHDL
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; |