--- /dev/null
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+library work;\r
+\r
+entity gather_ports is\r
+ port(\r
+ CLK : in std_logic;\r
+ CLEAR : in std_logic;\r
+ RESET : in std_logic;\r
+ --\r
+ FRAME_AVAIL_IN : in std_logic_vector(15 downto 0) := (others => '0');\r
+ FRAME_REQ_OUT : out std_logic_vector(15 downto 0);\r
+ FRAME_ACK_IN : in std_logic_vector(15 downto 0) := (others => '0');\r
+ PORT_SELECT_OUT : out std_logic_vector(15 downto 0);\r
+ CYCLE_DONE_OUT : out std_logic;\r
+ --\r
+ DEBUG : out std_logic_vector(15 downto 0)\r
+ );\r
+end entity gather_ports;\r
+\r
+architecture gather_ports_arch of gather_ports is\r
+\r
+-- Components\r
+\r
+-- state machine signals\r
+ type state_t is (IDLE, STORE, DO_PORTS, DELAY, CLEANUP);\r
+ signal STATE, NEXT_STATE : state_t;\r
+\r
+-- Signals\r
+ signal gather_needed_x : std_logic;\r
+ signal store_ports_x : std_logic;\r
+ signal all_ports_done_x : std_logic;\r
+ signal stored_ports : std_logic_vector(15 downto 0);
+ signal next_port_x : std_logic_vector(15 downto 0);\r
+ signal select_ports : std_logic_vector(15 downto 0);\r
+ signal req_ports : std_logic_vector(15 downto 0);\r
+\r
+begin\r
+\r
+ -- we need to start a gather cycle if any src port has frames available\r
+ gather_needed_x <= '1' when FRAME_AVAIL_IN /= x"0000" else '0';\r
+\r
+ -- store the src port status\r
+ GEN_REGS: for I in 0 to 15 generate\r
+ THE_SRC_STORE_PROC: process( CLK, CLEAR )\r
+ begin\r
+ if( CLEAR = '1' ) then\r
+ stored_ports(I) <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ if( store_ports_x = '1' ) then\r
+ stored_ports(I) <= FRAME_AVAIL_IN(I);\r
+ elsif( FRAME_ACK_IN(I) = '1' ) then\r
+ stored_ports(I) <= '0';\r
+ end if;\r
+ end if;\r
+ end process THE_SRC_STORE_PROC;\r
+ end generate;\r
+\r
+ all_ports_done_x <= '1' when stored_ports = x"0000" else '0';\r
+\r
+ -- select the port data\r
+ THE_SELECT_PORT_PROC: process( CLK, CLEAR )\r
+ begin\r
+ if( CLEAR = '1' ) then\r
+ select_ports <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ select_ports <= next_port_x;\r
+ end if;\r
+ end process THE_SELECT_PORT_PROC;\r
+\r
+ PORT_SELECT_OUT <= select_ports;\r
+\r
+ -- port frame request, one clock cycle pulse\r
+ req_ports <= not select_ports and next_port_x when rising_edge(CLK);\r
+\r
+ FRAME_REQ_OUT <= req_ports;\r
+\r
+ CYCLE_DONE_OUT <= '1' when STATE = CLEANUP else '0';\r
+\r
+ -- priority decoced "next port to serve" signals\r
+ THE_NEXT_PORT_PROC: process( stored_ports )\r
+ begin\r
+ if ( stored_ports(0) = '1' ) then\r
+ next_port_x <= x"0001";\r
+ elsif( stored_ports(1) = '1' ) then
+ next_port_x <= x"0002";
+ elsif( stored_ports(2) = '1' ) then
+ next_port_x <= x"0004";
+ elsif( stored_ports(3) = '1' ) then
+ next_port_x <= x"0008";
+ elsif( stored_ports(4) = '1' ) then
+ next_port_x <= x"0010";
+ elsif( stored_ports(5) = '1' ) then
+ next_port_x <= x"0020";
+ elsif( stored_ports(6) = '1' ) then
+ next_port_x <= x"0040";
+ elsif( stored_ports(7) = '1' ) then
+ next_port_x <= x"0080";
+ elsif( stored_ports(8) = '1' ) then
+ next_port_x <= x"0100";
+ elsif( stored_ports(9) = '1' ) then
+ next_port_x <= x"0200";
+ elsif( stored_ports(10) = '1' ) then
+ next_port_x <= x"0400";
+ elsif( stored_ports(11) = '1' ) then
+ next_port_x <= x"0800";
+ elsif( stored_ports(12) = '1' ) then
+ next_port_x <= x"1000";
+ elsif( stored_ports(13) = '1' ) then
+ next_port_x <= x"2000";
+ elsif( stored_ports(14) = '1' ) then
+ next_port_x <= x"4000";
+ elsif( stored_ports(15) = '1' ) then
+ next_port_x <= x"8000";\r
+ else\r
+ next_port_x <= x"0000";
+ end if;
+ end process THE_NEXT_PORT_PROC;\r
+\r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ THE_FSM: process( CLK, CLEAR )\r
+ begin\r
+ if ( CLEAR = '1' ) then\r
+ STATE <= IDLE;\r
+ elsif( rising_edge(CLK) ) then\r
+ STATE <= NEXT_STATE;\r
+ end if;\r
+ end process THE_FSM;\r
+\r
+ THE_STATE_TRANSITIONS: process( STATE, gather_needed_x, all_ports_done_x )\r
+ begin\r
+ store_ports_x <= '0';\r
+\r
+ case STATE is\r
+\r
+ when IDLE =>\r
+ if( gather_needed_x = '1' ) then\r
+ NEXT_STATE <= STORE;\r
+ store_ports_x <= '1';\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when STORE =>\r
+ NEXT_STATE <= DO_PORTS;\r
+\r
+ when DO_PORTS =>\r
+ if( all_ports_done_x = '1' ) then\r
+ NEXT_STATE <= DELAY;\r
+ else\r
+ NEXT_STATE <= DO_PORTS;\r
+ end if;\r
+\r
+ when DELAY =>\r
+ NEXT_STATE <= CLEANUP;\r
+\r
+ when CLEANUP =>\r
+ if( gather_needed_x = '1' ) then\r
+ NEXT_STATE <= STORE;\r
+ store_ports_x <= '1';\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when others =>\r
+ NEXT_STATE <= IDLE;\r
+ end case;\r
+ end process THE_STATE_TRANSITIONS;\r
+\r
+\r
+\r
+end architecture;\r
FRAME_REQ_IN : in std_logic; -- one pulse starts readout of frame stored in ring buffer\r
FRAME_ACK_OUT : out std_logic; -- one pulse for "end of frame"\r
FRAME_AVAIL_OUT : out std_logic; -- number of frames stored in ring buffer\r
+ FRAME_START_OUT : out std_logic; -- StartOfFrame signal\r
--\r
DEBUG : out std_logic_vector(15 downto 0)\r
);\r
signal fifo_wr_int : std_logic;\r
signal empty_read_ack : std_logic;\r
signal normal_read_ack : std_logic;\r
- \r
+ signal sof_int : std_logic;\r
signal frames_avail : unsigned(7 downto 0);\r
\r
\r
rd_ram <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty = '0')) else '0';\r
ce_rd_ptr <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty = '0')) else '0';\r
\r
+ sof_int <= FRAME_REQ_IN and not frame_requested when rising_edge(CLK);\r
+ \r
FRAME_ACK_OUT <= normal_read_ack or empty_read_ack;\r
\r
+ FRAME_START_OUT <= sof_int;\r
+ \r
FIFO_Q_OUT <= ram_q;\r
\r
fifo_wr_int <= rd_ram when rising_edge(CLK);\r
--- /dev/null
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+library work;\r
+\r
+entity scatter_ports is\r
+ port(\r
+ CLK : in std_logic;\r
+ CLEAR : in std_logic;\r
+ RESET : in std_logic;\r
+ --\r
+ FRAME_AVAIL_IN : in std_logic := '0';\r
+ FRAME_REQ_OUT : out std_logic;\r
+ FRAME_ACK_IN : in std_logic := '0';\r
+ CYCLE_DONE_OUT : out std_logic;\r
+ --\r
+ DEBUG : out std_logic_vector(15 downto 0)\r
+ );\r
+end entity scatter_ports;\r
+\r
+architecture scatter_ports_arch of scatter_ports is\r
+\r
+-- Components\r
+\r
+-- state machine signals\r
+ type state_t is (IDLE, DO_PORT, DELAY, CLEANUP);\r
+ signal STATE, NEXT_STATE : state_t;\r
+\r
+-- Signals\r
+ signal req_int : std_logic;\r
+ signal req_x : std_logic;\r
+\r
+begin\r
+\r
+ CYCLE_DONE_OUT <= '1' when STATE = CLEANUP else '0';
+\r
+ FRAME_REQ_OUT <= req_int;\r
+\r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ THE_FSM: process( CLK, CLEAR )\r
+ begin\r
+ if ( CLEAR = '1' ) then\r
+ STATE <= IDLE;\r
+ req_int <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ STATE <= NEXT_STATE;\r
+ req_int <= req_x;\r
+ end if;\r
+ end process THE_FSM;\r
+\r
+ THE_STATE_TRANSITIONS: process( STATE, FRAME_AVAIL_IN, FRAME_ACK_IN )\r
+ begin\r
+ req_x <= '0';\r
+\r
+ case STATE is\r
+\r
+ when IDLE =>\r
+ if( FRAME_AVAIL_IN = '1' ) then\r
+ NEXT_STATE <= DO_PORT;\r
+ req_x <= '1';\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when DO_PORT =>\r
+ if( FRAME_ACK_IN = '1' ) then\r
+ NEXT_STATE <= DELAY;\r
+ else\r
+ NEXT_STATE <= DO_PORT;\r
+ end if;\r
+\r
+ when DELAY =>\r
+ NEXT_STATE <= CLEANUP;\r
+\r
+ when CLEANUP =>\r
+ if( FRAME_AVAIL_IN = '1' ) then\r
+ NEXT_STATE <= DO_PORT;\r
+ req_x <= '1';\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when others =>\r
+ NEXT_STATE <= IDLE;\r
+ end case;\r
+ end process THE_STATE_TRANSITIONS;\r
+\r
+\r
+\r
+end architecture;\r
FIFO_FULL_OUT : out std_logic;\r
FIFO_WR_IN : in std_logic;\r
FIFO_D_IN : in std_logic_vector(8 downto 0);\r
+ -- Link stuff\r
+ FRAME_START_IN : in std_logic;\r
+ LINK_ACTIVE_IN : in std_logic;\r
--\r
DEBUG : out std_logic_vector(15 downto 0)\r
);\r
);\r
end component fifo_4k_9;\r
\r
+-- component fifo_4k_9\r
+-- port(\r
+-- DATA : in std_logic_vector(8 downto 0); \r
+-- WRCLOCK : in std_logic;\r
+-- RDCLOCK : in std_logic;\r
+-- WREN : in std_logic; \r
+-- RDEN : in std_logic;\r
+-- RESET : in std_logic;\r
+-- RPRESET : in std_logic; \r
+-- Q : out std_logic_vector(8 downto 0);\r
+-- EMPTY : out std_logic; \r
+-- FULL : out std_logic;\r
+-- ALMOSTEMPTY : out std_logic; \r
+-- ALMOSTFULL : out std_logic\r
+-- );\r
+-- end component fifo_4k_9;\r
+ \r
-- state machine signals\r
\r
-- Signals\r
signal frame_read : std_logic;\r
signal mac_fifoeof : std_logic;\r
signal mac_tx_read : std_logic;\r
- \r
+ signal frame_active : std_logic;\r
+ signal fifo_wr : std_logic;\r
+\r
begin\r
\r
+ -- FrameActice signal - used to inhibt acceptance of runt frames\r
+ THE_FRAME_ACTIVE_PROC: process( CLK, CLEAR )\r
+ begin\r
+ if( CLEAR = '1' ) then\r
+ frame_active <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ if ( FRAME_START_IN = '1' ) then\r
+ frame_active <= LINK_ACTIVE_IN;\r
+ elsif( frame_written = '1' ) then\r
+ frame_active <= '0';\r
+ end if;\r
+ end if;\r
+ end process THE_FRAME_ACTIVE_PROC;\r
+\r
+ fifo_wr <= FIFO_WR_IN and frame_active;\r
+\r
-- TX FIFO storing full outgoing frames\r
THE_TX_FIFO: fifo_4k_9\r
port map(\r
DATA => FIFO_D_IN,\r
CLOCK => CLK,\r
- WREN => FIFO_WR_IN,\r
+ WREN => fifo_wr, --FIFO_WR_IN,\r
RDEN => MAC_TX_READ_IN,\r
RESET => CLEAR,\r
Q(8) => mac_fifoeof,\r
FULL => open,\r
ALMOSTFULL => FIFO_FULL_OUT\r
);\r
- \r
+\r
+-- -- TX FIFO storing full outgoing frames\r
+-- THE_TX_FIFO: fifo_4k_9\r
+-- port map(\r
+-- DATA => FIFO_D_IN,\r
+-- WRCLOCK => CLK,\r
+-- RDCLOCK => CLK,\r
+-- WREN => fifo_wr, --FIFO_WR_IN,\r
+-- RDEN => MAC_TX_READ_IN,\r
+-- RESET => CLEAR,\r
+-- RPRESET => CLEAR, \r
+-- Q(8) => mac_fifoeof,\r
+-- Q(7 downto 0) => MAC_TX_DATA_OUT,\r
+-- EMPTY => MAC_FIFOEMPTY_OUT, \r
+-- FULL => open,\r
+-- ALMOSTEMPTY => open, \r
+-- ALMOSTFULL => FIFO_FULL_OUT\r
+-- );\r
+ \r
MAC_FIFOEOF_OUT <= mac_fifoeof;\r
\r
mac_tx_read <= MAC_TX_READ_IN when rising_edge(CLK);\r
\r
-- one frame written to FIFO\r
- frame_written <= '1' when (FIFO_D_IN(8) = '1') and (FIFO_WR_IN = '1') else '0';\r
+ frame_written <= '1' when (FIFO_D_IN(8) = '1') and (FIFO_WR_IN = '1') and (frame_active = '1') else '0';\r
\r
-- one frame read from FIFO\r
frame_read <= '1' when (mac_fifoeof = '1') and (mac_tx_read = '1') else '0';\r