-- ----------------------------------------------------------------------------- -- Copyright (c) 2013 Benjamin Krill -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in -- all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -- THE SOFTWARE. -- ----------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.strm_package.all; entity f2p_strm_top is generic ( STRM_OUT_SLV_CNT : integer := 1 ); port ( clk : in std_logic; rst_n : in std_logic; debug : out std_logic_vector(7 downto 0); -- cypress interface usb_clk : in std_logic; usb_flag_a_i : in std_logic; -- programmable flag usb_flag_b_i : in std_logic; -- full flag usb_flag_c_i : in std_logic; -- empty flag usb_cs_o : out std_logic; -- put to GND, not need for this application usb_oe_o : out std_logic; -- active_low usb_rd_o : out std_logic; -- active_low usb_wr_o : out std_logic; -- active_low usb_pktend_o : out std_logic; -- active_low usb_adr_o : out std_logic_vector(1 downto 0); -- 00 ep2, 01 ep4, 10 ep6, 11 ep8 usb_dat_io : inout std_logic_vector(7 downto 0); -- streaming bus strm_in_data_o : out std_logic_vector(31 downto 0); strm_in_eop_o : out std_logic; strm_in_en_o : out std_logic; strm_in_busy_i : in std_logic; strm_out_slv_reqs_i : in std_logic_vector(STRM_OUT_SLV_CNT-1 downto 0); strm_out_slv_busy_o : out std_logic_vector(STRM_OUT_SLV_CNT-1 downto 0); strm_out_data_i : in strm_dat_bus_t(STRM_OUT_SLV_CNT-1 downto 0); strm_out_eop_i : in std_logic_vector(STRM_OUT_SLV_CNT-1 downto 0); strm_out_en_i : in std_logic_vector(STRM_OUT_SLV_CNT-1 downto 0) ); end f2p_strm_top; architecture f2p_strm_top of f2p_strm_top is signal rp_read_cnt : unsigned(23 downto 0); signal strm_data : std_logic_vector(31 downto 0); signal strm_eop : std_logic; signal strm_en : std_logic; signal wp_wr : std_logic; signal wp_full : std_logic; signal wp_eop : std_logic; signal wp_dat : std_logic_vector(31 downto 0); signal rp_rd : std_logic; signal rp_empty : std_logic; signal rp_dat : std_logic_vector(31 downto 0); signal rrarb_req : std_logic_vector(STRM_OUT_SLV_CNT-1 downto 0); signal rrarb_ack : std_logic; signal rrarb_grant : std_logic_vector(STRM_OUT_SLV_CNT-1 downto 0); signal strm_out_data_mux : strm_dat_bus_t(STRM_OUT_SLV_CNT-1 downto 0); begin strm_in_data_o <= strm_data; strm_in_eop_o <= strm_eop; strm_in_en_o <= strm_en; f2p_master_0: entity work.f2p_master port map ( clk => clk, rst_n => rst_n, debug => debug, -- cypress interface usb_clk => usb_clk, usb_flag_a_i => usb_flag_a_i, usb_flag_b_i => usb_flag_b_i, usb_flag_c_i => usb_flag_c_i, usb_cs_o => usb_cs_o, usb_oe_o => usb_oe_o, usb_rd_o => usb_rd_o, usb_wr_o => usb_wr_o, usb_pktend_o => usb_pktend_o, usb_adr_o => usb_adr_o, usb_dat_io => usb_dat_io, -- write/read pipe wp_wr_i => wp_wr, wp_full_o => wp_full, wp_dat_i => wp_dat, wp_eop_i => wp_eop, rp_rd_i => rp_rd, rp_empty_o => rp_empty, rp_dat_o => rp_dat ); -- ------------------------------------------------------------------ -- USB FIFO SLAVES -- ------------------------------------------------------------------ -- FROM USB rp_rd <= not rp_empty and not strm_in_busy_i; process (clk, rst_n) begin if rst_n = '0' then rp_read_cnt <= (others => '0'); strm_data <= (others => '0'); strm_en <= '0'; strm_eop <= '0'; elsif rising_edge(clk) then -- get next packet and stream to slaves if rp_rd = '1' then if rp_read_cnt /= x"000000" then rp_read_cnt <= rp_read_cnt - "1"; else rp_read_cnt <= unsigned(rp_dat(STRM_LENGTH_HIGH downto STRM_LENGTH_LOW)); end if; end if; -- stream data strm_en <= '0'; strm_eop <= '0'; if rp_rd = '1' then strm_en <= '1'; strm_data <= rp_dat; if rp_read_cnt = x"000001" then strm_eop <= '1'; end if; end if; end if; end process; -- TO USB - strm arbiter rrarb_req <= strm_out_slv_reqs_i and not rrarb_grant; rrarb_ack <= '1' when (strm_out_eop_i and rrarb_grant) /= (STRM_OUT_SLV_CNT-1 downto 0 => '0') else '0'; rrarb_strm_out_0: entity work.rrarbiter generic map ( CNT => STRM_OUT_SLV_CNT ) port map ( clk => clk, rst_n => rst_n, req => rrarb_req, ack => rrarb_ack, grant => rrarb_grant ); strm_out_slv_busy_o <= not rrarb_grant or (STRM_OUT_SLV_CNT-1 downto 0 => wp_full); strm_out_data_mux(0) <= strm_out_data_i(0) and (31 downto 0 => rrarb_grant(0)); dc: for I in 1 to STRM_OUT_SLV_CNT-1 generate strm_out_data_mux(I) <= strm_out_data_mux(I-1) or (strm_out_data_i(I) and (31 downto 0 => rrarb_grant(I))); end generate dc; wp_dat <= strm_out_data_mux(STRM_OUT_SLV_CNT-1); wp_wr <= '1' when (strm_out_en_i and rrarb_grant) /= (STRM_OUT_SLV_CNT-1 downto 0 => '0') else '0'; wp_eop <= '1' when (strm_out_eop_i and rrarb_grant) /= (STRM_OUT_SLV_CNT-1 downto 0 => '0') else '0'; end f2p_strm_top;