170 lines
6.5 KiB
VHDL
170 lines
6.5 KiB
VHDL
-- -----------------------------------------------------------------------------
|
|
-- Copyright (c) 2013 Benjamin Krill <benjamin@krll.de>
|
|
--
|
|
-- 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;
|