library ieee; use work.ucore_package.all; use work.bus_package.all; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity bus_arbiter_uctrl is port ( -- global clk : in std_logic; reset : in std_logic; -- uctrl -- send uctrl_send_address : in std_logic_vector(31 downto 0); uctrl_send_busy : out std_logic; uctrl_send_wrreq : in std_logic; -- recive uctrl_recive_data : out std_logic_vector(31 downto 0); uctrl_recive_busy : out std_logic; uctrl_recive_ack : in std_logic; -- memory clks sram_clk : in std_logic; sdram_clk : in std_logic; -- to memory to_sram_data : out std_logic_vector(71 downto 0); to_sram_busy : out std_logic; to_sram_ack : in std_logic; to_sdram_data : out std_logic_vector(71 downto 0); to_sdram_busy : out std_logic; to_sdram_ack : in std_logic; -- from memory fifos from_sram_data : in std_logic_vector(71 downto 0); from_sram_busy : in std_logic; from_sram_ack : out std_logic; from_sdram_data : in std_logic_vector(71 downto 0); from_sdram_busy : in std_logic; from_sdram_ack : out std_logic ); end entity; architecture rtl of bus_arbiter_uctrl is -- external memory fifo --component dcfifo_min IS -- PORT -- ( -- aclr : IN STD_LOGIC := '0'; -- data : IN STD_LOGIC_VECTOR (71 DOWNTO 0); -- rdclk : IN STD_LOGIC ; -- rdreq : IN STD_LOGIC ; -- wrclk : IN STD_LOGIC ; -- wrreq : IN STD_LOGIC ; -- q : OUT STD_LOGIC_VECTOR (71 DOWNTO 0); -- rdempty : OUT STD_LOGIC ; -- wrusedw : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) -- ); --END component; component dc_fifo IS GENERIC ( FIFO_DEPTH : natural; FIFO_WIDTH : natural; FIFO_SHOWAHEAD : string; FIFO_USEDWWIDTH : natural; FIFO_SYNCSTAGES : natural ); PORT ( aclr : IN STD_LOGIC := '0'; data : IN STD_LOGIC_VECTOR (FIFO_WIDTH-1 DOWNTO 0); rdclk : IN STD_LOGIC ; rdreq : IN STD_LOGIC ; wrclk : IN STD_LOGIC ; wrreq : IN STD_LOGIC ; q : OUT STD_LOGIC_VECTOR (FIFO_WIDTH-1 DOWNTO 0); rdempty : OUT STD_LOGIC ; wrusedw : OUT STD_LOGIC_VECTOR (FIFO_USEDWWIDTH-1 DOWNTO 0) ); END component; -- type send_xn_data_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC_VECTOR (71 DOWNTO 0); type send_xn_rdreq_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC; type send_xn_rclk_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC; type send_xn_wrreq_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC; type send_xn_q_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC_VECTOR (71 DOWNTO 0); type send_xn_rdempty_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC; type send_xn_wrfull_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC; type send_xn_wrusedw_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC_VECTOR (7 DOWNTO 0); signal send_xn_data : send_xn_data_t := (others => (others => '0')); signal send_xn_rdreq : send_xn_rdreq_t := (others => '0'); signal send_xn_rclk : send_xn_rclk_t := (others => '0'); signal send_xn_wrreq : send_xn_wrreq_t := (others => '0'); signal send_xn_q : send_xn_q_t := (others => (others => '0')); signal send_xn_rdempty : send_xn_rdempty_t := (others => '0'); signal send_xn_wrfull : send_xn_wrfull_t := (others => '0'); signal send_xn_wrusedw : send_xn_wrusedw_t := (others => (others => '0')); -- type recive_xn_data_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC_VECTOR (71 DOWNTO 0); type recive_xn_busy_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC; type recive_xn_ack_t is array(0 to uctrl_reciver_count-1) of STD_LOGIC; signal recive_xn_data : recive_xn_data_t := (others => (others => '0')); signal recive_xn_busy : recive_xn_busy_t := (others => '0'); signal recive_xn_ack : recive_xn_ack_t := (others => '0'); -- constant SRAM : integer := 0; constant SDRAM : integer := 1; constant UKNOWN : integer := 2; -- begin ----------------------------------------------------------------------------------------------------------- ---- SEND DATA (1 cycle delay) ----------------------------------------------------------------------------------------------------------- process(clk) variable destination : integer := UKNOWN; variable tport : port_struct := fill_port('0'); begin if rising_edge(clk) then -- default for i in 0 to uctrl_reciver_count-1 loop send_xn_wrreq(i) <= '0'; end loop; if reset = '1' then else -- which destination case uctrl_send_address(31 downto 28) is when x"f" => destination := SRAM; when x"d" => destination := SDRAM; when others => destination := UKNOWN; end case; -- setup port tport.data := x"00000000"; -- no data tport.address := uctrl_send_address; -- address tport.we := '0'; -- ever read tport.dmode := '0'; -- 32 bit mode -- to which port if uctrl_send_wrreq = '1' then -- write request ? for i in 0 to uctrl_reciver_count-1 loop if i = destination then send_xn_wrreq(i) <= '1'; end if; end loop; end if; end if; -- set data to all outgoing fifos for i in 0 to uctrl_reciver_count-1 loop send_xn_data(i) <= port_to_raw(tport); end loop; -- full generate for i in 0 to uctrl_reciver_count-1 loop if send_xn_wrusedw(i) >= x"fb" then send_xn_wrfull(i) <= '1'; else send_xn_wrfull(i) <= '0'; end if; end loop; end if; end process; -- generate fifos send_xf_loop : for i in 0 to uctrl_reciver_count-1 generate send_xf : dc_fifo generic map ( FIFO_DEPTH => 256, FIFO_WIDTH => 72, FIFO_SHOWAHEAD => "ON", FIFO_USEDWWIDTH => 8, FIFO_SYNCSTAGES => 3 ) port map ( '0', send_xn_data(i), send_xn_rclk(i), -- read with component clk send_xn_rdreq(i), clk, -- write with ucore clk send_xn_wrreq(i), send_xn_q(i), send_xn_rdempty(i), send_xn_wrusedw(i) ); end generate; -- full process(all) variable isBusy : std_logic := '0'; begin isBusy := '0'; for i in 0 to uctrl_reciver_count-1 loop isBusy := isBusy or send_xn_wrfull(i); end loop; uctrl_send_busy <= isBusy; -- default end process; -- to slaves to_sram_data <= send_xn_q(0); to_sram_busy <= send_xn_rdempty(0); send_xn_rdreq(0) <= to_sram_ack; send_xn_rclk(0) <= sram_clk; to_sdram_data <= send_xn_q(1); to_sdram_busy <= send_xn_rdempty(1); send_xn_rdreq(1) <= to_sdram_ack; send_xn_rclk(1) <= sdram_clk; ----------------------------------------------------------------------------------------------------------- ---- RECIVE DATA ----------------------------------------------------------------------------------------------------------- process(all) begin for I in 0 to uctrl_reciver_count-1 loop recive_xn_ack(i) <= '0'; end loop; uctrl_recive_busy <= '1'; uctrl_recive_data <= (others => '0'); for I in 0 to uctrl_reciver_count-1 loop if recive_xn_busy(i) = '0' then uctrl_recive_data <= raw_to_port(recive_xn_data(i)).data; uctrl_recive_busy <= '0'; recive_xn_ack(i) <= uctrl_recive_ack; exit; -- stop loop end if; end loop; end process; recive_xn_data(0) <= from_sram_data; recive_xn_busy(0) <= from_sram_busy; from_sram_ack <= recive_xn_ack(0); recive_xn_data(1) <= from_sdram_data; recive_xn_busy(1) <= from_sdram_busy; from_sdram_ack <= recive_xn_ack(1); end rtl;