--- /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
+ 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);\r
+ 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 )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ stored_ports(I) <= '0';\r
+ elsif( 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 )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( RESET = '1' ) then\r
+ select_ports <= (others => '0');\r
+ else\r
+ select_ports <= next_port_x;\r
+ end if;\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\r
+ next_port_x <= x"0002";\r
+ elsif( stored_ports(2) = '1' ) then\r
+ next_port_x <= x"0004";\r
+ elsif( stored_ports(3) = '1' ) then\r
+ next_port_x <= x"0008";\r
+ elsif( stored_ports(4) = '1' ) then\r
+ next_port_x <= x"0010";\r
+ elsif( stored_ports(5) = '1' ) then\r
+ next_port_x <= x"0020";\r
+ elsif( stored_ports(6) = '1' ) then\r
+ next_port_x <= x"0040";\r
+ elsif( stored_ports(7) = '1' ) then\r
+ next_port_x <= x"0080";\r
+ elsif( stored_ports(8) = '1' ) then\r
+ next_port_x <= x"0100";\r
+ elsif( stored_ports(9) = '1' ) then\r
+ next_port_x <= x"0200";\r
+ elsif( stored_ports(10) = '1' ) then\r
+ next_port_x <= x"0400";\r
+ elsif( stored_ports(11) = '1' ) then\r
+ next_port_x <= x"0800";\r
+ elsif( stored_ports(12) = '1' ) then\r
+ next_port_x <= x"1000";\r
+ elsif( stored_ports(13) = '1' ) then\r
+ next_port_x <= x"2000";\r
+ elsif( stored_ports(14) = '1' ) then\r
+ next_port_x <= x"4000";\r
+ elsif( stored_ports(15) = '1' ) then\r
+ next_port_x <= x"8000";\r
+ else\r
+ next_port_x <= x"0000";\r
+ end if;\r
+ end process THE_NEXT_PORT_PROC;\r
+\r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ THE_FSM: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( RESET = '1' ) then\r
+ STATE <= IDLE;\r
+ else\r
+ STATE <= NEXT_STATE;\r
+ end if;\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
+end architecture;\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 gbe_lsm is\r
+ port(\r
+ CLK : in std_logic;\r
+ RESET : in std_logic;\r
+ -- \r
+ MAC_AN_COMPLETE_IN : in std_logic; -- PCS Autonegotiation completed\r
+ MAC_READY_CONF_IN : in std_logic; -- MAC configuration completed\r
+ MAC_RECONF_OUT : out std_logic; -- start MAC configuration\r
+ --\r
+ LINK_ACTIVE_OUT : out std_logic;\r
+ --\r
+ DEBUG : out std_logic_vector(15 downto 0)\r
+ );\r
+end entity gbe_lsm;\r
+\r
+architecture gbe_lsm_arch of gbe_lsm is\r
+\r
+-- Components\r
+\r
+-- state machine signals\r
+ type state_t is (INACTIVE,WAIT_PCS,ENABLE_MAC,DELAY,ACTIVATED);\r
+ signal STATE, NEXT_STATE : state_t;\r
+\r
+-- Signals\r
+ signal dly_ctr : unsigned(15 downto 0);\r
+ signal ce_dly_ctr : std_logic;\r
+ signal rst_dly_ctr : std_logic;\r
+ signal dly_ctr_done : std_logic;\r
+ signal reconf_mac : std_logic;\r
+\r
+begin\r
+\r
+ MAC_RECONF_OUT <= reconf_mac;\r
+\r
+ LINK_ACTIVE_OUT <= '1' when (STATE = ACTIVATED) else '0';\r
+ \r
+ THE_DLY_CTR: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ dly_ctr <= (others => '0');\r
+ elsif( rst_dly_ctr = '1' ) then\r
+ dly_ctr <= (others => '0');\r
+ elsif( ce_dly_ctr = '1' ) then\r
+ dly_ctr <= dly_ctr + 1;\r
+ end if;\r
+ end if;\r
+ end process THE_DLY_CTR;\r
+ \r
+ dly_ctr_done <= '1' when dly_ctr = x"ffff" else '0';\r
+\r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ THE_FSM: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( RESET = '1' ) then\r
+ STATE <= INACTIVE;\r
+ else\r
+ STATE <= NEXT_STATE;\r
+ end if;\r
+ end if;\r
+ end process THE_FSM;\r
+\r
+ THE_STATE_TRANSITIONS: process( STATE, MAC_AN_COMPLETE_IN, MAC_READY_CONF_IN, dly_ctr_done )\r
+ begin\r
+ reconf_mac <= '0';\r
+ ce_dly_ctr <= '0';\r
+ rst_dly_ctr <= '0';\r
+ \r
+ case STATE is\r
+\r
+ when INACTIVE =>\r
+ rst_dly_ctr <= '1';\r
+ if( MAC_AN_COMPLETE_IN = '1' ) then\r
+ NEXT_STATE <= WAIT_PCS;\r
+ else\r
+ NEXT_STATE <= INACTIVE;\r
+ end if;\r
+\r
+ when WAIT_PCS =>\r
+ ce_dly_ctr <= '1';\r
+ if( MAC_AN_COMPLETE_IN = '0' ) then\r
+ NEXT_STATE <= INACTIVE;\r
+ else\r
+ if( dly_ctr_done = '1' ) then \r
+ NEXT_STATE <= ENABLE_MAC;\r
+ reconf_mac <= '1';\r
+ else\r
+ NEXT_STATE <= WAIT_PCS;\r
+ end if;\r
+ end if;\r
+\r
+ when ENABLE_MAC =>\r
+ rst_dly_ctr <= '1';\r
+ if( MAC_AN_COMPLETE_IN = '0' ) then\r
+ NEXT_STATE <= INACTIVE;\r
+ else\r
+ if( MAC_READY_CONF_IN = '1' ) then\r
+ NEXT_STATE <= DELAY;\r
+ else \r
+ NEXT_STATE <= ENABLE_MAC;\r
+ end if;\r
+ end if;\r
+\r
+ when DELAY =>\r
+ ce_dly_ctr <= '1';\r
+ if( MAC_AN_COMPLETE_IN = '0' ) then\r
+ NEXT_STATE <= INACTIVE;\r
+ else\r
+ if( dly_ctr_done = '1' ) then\r
+ NEXT_STATE <= ACTIVATED;\r
+ else \r
+ NEXT_STATE <= DELAY;\r
+ end if;\r
+ end if;\r
+ \r
+ when ACTIVATED =>\r
+ rst_dly_ctr <= '1';\r
+ if( MAC_AN_COMPLETE_IN = '0' ) then\r
+ NEXT_STATE <= INACTIVE;\r
+ else\r
+ NEXT_STATE <= ACTIVATED;\r
+ end if;\r
+\r
+ when others =>\r
+ NEXT_STATE <= INACTIVE;\r
+ end case;\r
+ end process THE_STATE_TRANSITIONS;\r
+\r
+end architecture;\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 rx_rb is\r
+ port(\r
+ CLK : in std_logic;\r
+ RESET : in std_logic;\r
+ -- MAC interface (RX)\r
+ MAC_RX_DATA_IN : in std_logic_vector(7 downto 0); -- RX data from TSMAC\r
+ MAC_RX_WR_IN : in std_logic; -- RX data write from TSMAC\r
+ MAC_RX_EOF_IN : in std_logic; -- RX EndOfFrame from TSMAC\r
+ MAC_RX_ERROR_IN : in std_logic; -- RX Error from TSMAC\r
+ MAC_RX_FIFOFULL_OUT : out std_logic;\r
+ -- FIFO interface (TX)\r
+ FIFO_FULL_IN : in std_logic; -- TX fifo full, delay read from ring buffer\r
+ FIFO_WR_OUT : out std_logic; -- TX fifo write\r
+ FIFO_Q_OUT : out std_logic_vector(8 downto 0); -- TX data\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
+end entity rx_rb;\r
+\r
+architecture rx_rb_arch of rx_rb is\r
+\r
+-- Components\r
+ component rb_4k_9\r
+ port(\r
+ WRADDRESS : in std_logic_vector(11 downto 0); \r
+ RDADDRESS : in std_logic_vector(11 downto 0); \r
+ DATA : in std_logic_vector(8 downto 0); \r
+ WE : in std_logic; \r
+ RDCLOCK : in std_logic; \r
+ RDCLOCKEN : in std_logic; \r
+ RESET : in std_logic; \r
+ WRCLOCK : in std_logic; \r
+ WRCLOCKEN : in std_logic; \r
+ Q : out std_logic_vector(8 downto 0)\r
+ );\r
+ end component rb_4k_9;\r
+\r
+-- state machine signals\r
+ type state_t is (RX_DENY,RX_READY,RX_FRAME,FRAME_OK,FRAME_BAD,FORWARD,SKIP);\r
+ signal STATE, NEXT_STATE : state_t;\r
+\r
+-- Signals\r
+ signal rd_ptr : unsigned(11 downto 0);\r
+ signal wr_ptr : unsigned(11 downto 0);\r
+ signal last_wr_ptr : std_logic_vector(11 downto 0);\r
+ signal rb_used : unsigned(11 downto 0);\r
+ signal rb_full : std_logic;\r
+ signal rb_empty : std_logic;\r
+ signal ce_wr_ptr : std_logic;\r
+ signal ld_wr_ptr : std_logic;\r
+ signal ce_rd_ptr : std_logic;\r
+ signal wr_ram : std_logic;\r
+ signal rd_ram : std_logic;\r
+ signal ram_q : std_logic_vector(8 downto 0);\r
+ signal frame_active : std_logic;\r
+ signal frame_requested : std_logic;\r
+ signal fifo_wr_int : std_logic;\r
+ signal empty_read_ack : std_logic;\r
+ signal normal_read_ack : std_logic;\r
+ signal sof_int : std_logic;\r
+ signal frames_avail : unsigned(7 downto 0);\r
+\r
+\r
+begin\r
+\r
+ -- FrameActive: we must not change to "receive" in the middle of a frame\r
+ -- when "buffer full" condition is deasserted\r
+ THE_FRAME_ACTIVE_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ frame_active <= '0';\r
+ elsif( (MAC_RX_WR_IN = '1') and (frame_active = '0') ) then\r
+ frame_active <= '1';\r
+ elsif( (MAC_RX_EOF_IN = '1') and (frame_active = '1') ) then\r
+ frame_active <= '0';\r
+ end if;\r
+ end if;\r
+ end process THE_FRAME_ACTIVE_PROC;\r
+\r
+ -- Write pointer for ring buffer\r
+ THE_WR_PTR_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ wr_ptr <= (others => '0');\r
+ elsif( ld_wr_ptr = '1' ) then\r
+ wr_ptr <= unsigned(last_wr_ptr);\r
+ elsif( ce_wr_ptr = '1' ) then\r
+ wr_ptr <= wr_ptr + 1;\r
+ end if;\r
+ end if;\r
+ end process THE_WR_PTR_PROC;\r
+\r
+ -- Read pointer for ring buffer\r
+ THE_RD_PTR_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ rd_ptr <= (others => '0');\r
+ elsif( ce_rd_ptr = '1' ) then\r
+ rd_ptr <= rd_ptr + 1;\r
+ end if;\r
+ end if;\r
+ end process THE_RD_PTR_PROC;\r
+\r
+ -- ring buffer fill level\r
+ rb_used <= wr_ptr - rd_ptr;\r
+ \r
+ -- ring buffer full \r
+ -- TAKE CARE: the last byte of a frame is taken into account\r
+ -- by "one less" for the full condition\r
+ rb_full <= '1' when (rb_used(11 downto 1) = b"1111_1111_111") else '0';\r
+\r
+ rb_empty <= '1' when (rb_used(11 downto 0) = b"0000_0000_0000") else '0';\r
+\r
+ MAC_RX_FIFOFULL_OUT <= rb_full;\r
+ \r
+ -- last write pointer: used to drop a broken frame, in case\r
+ THE_LAST_WR_PTR_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ last_wr_ptr <= (others => '0');\r
+ elsif( (STATE = RX_READY) and (MAC_RX_WR_IN = '1') ) then\r
+ last_wr_ptr <= std_logic_vector(wr_ptr);\r
+ end if;\r
+ end if;\r
+ end process THE_LAST_WR_PTR_PROC;\r
+\r
+ -- DPRAM as ring buffer\r
+ THE_DP_RAM: rb_4k_9\r
+ port map(\r
+ WRADDRESS => std_logic_vector(wr_ptr),\r
+ RDADDRESS => std_logic_vector(rd_ptr),\r
+ DATA(8) => MAC_RX_EOF_IN,\r
+ DATA(7 downto 0) => MAC_RX_DATA_IN,\r
+ WE => wr_ram,\r
+ RDCLOCK => CLK,\r
+ RDCLOCKEN => '1',\r
+ RESET => RESET,\r
+ WRCLOCK => CLK,\r
+ WRCLOCKEN => '1',\r
+ Q => ram_q\r
+ );\r
+\r
+ -- write signal\r
+ wr_ram <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) or\r
+ ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) \r
+ else '0';\r
+ ce_wr_ptr <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) or\r
+ ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full = '0')) \r
+ else '0';\r
+\r
+ -- FrameReq signal, one pulse only\r
+ THE_FRAME_REQ_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ frame_requested <= '0';\r
+ elsif( (FRAME_REQ_IN = '1') and (frame_requested = '0') ) then\r
+ frame_requested <= '1';\r
+ elsif( ((ram_q(8) = '1') and (frame_requested = '1')) or (empty_read_ack = '1') ) then\r
+ frame_requested <= '0';\r
+ end if;\r
+ end if;\r
+ end process THE_FRAME_REQ_PROC;\r
+\r
+ -- EmptyReadAck signal, used to handle a request to RX_RB with no frame to send\r
+ empty_read_ack <= FRAME_REQ_IN and rb_empty when rising_edge(CLK);\r
+ \r
+ -- NormalReadAck signal\r
+ normal_read_ack <= ram_q(8) and fifo_wr_int;\r
+ \r
+ -- read signal\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
+ \r
+ FIFO_WR_OUT <= fifo_wr_int;\r
+ \r
+ -- FramesAvailable counter\r
+ THE_FRAMES_AVAIL_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ frames_avail <= (others => '0');\r
+ elsif( (STATE = FRAME_OK) and (normal_read_ack = '0') ) then\r
+ -- one frame written successfully\r
+ frames_avail <= frames_avail + 1;\r
+ elsif( (STATE /= FRAME_OK) and (normal_read_ack = '1') ) then\r
+ -- one frame read successfully\r
+ frames_avail <= frames_avail - 1;\r
+ end if;\r
+ end if;\r
+ end process THE_FRAMES_AVAIL_PROC;\r
+ \r
+ FRAME_AVAIL_OUT <= '1' when (frames_avail /= x"00") else '0';\r
+\r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ THE_FSM: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( RESET = '1' ) then\r
+ STATE <= RX_DENY;\r
+ else\r
+ STATE <= NEXT_STATE;\r
+ end if;\r
+ end if;\r
+ end process THE_FSM;\r
+\r
+ THE_STATE_TRANSITIONS: process( STATE, MAC_RX_WR_IN, MAC_RX_EOF_IN, MAC_RX_ERROR_IN, frame_active, rb_full )\r
+ begin\r
+ ld_wr_ptr <= '0';\r
+ \r
+ case STATE is\r
+\r
+ when RX_DENY =>\r
+ if( (frame_active = '0') and (rb_full = '0') ) then\r
+ NEXT_STATE <= RX_READY;\r
+ else\r
+ NEXT_STATE <= RX_DENY;\r
+ end if;\r
+ \r
+ when RX_READY =>\r
+ if( MAC_RX_WR_IN = '1' ) then\r
+ NEXT_STATE <= RX_FRAME;\r
+ else\r
+ NEXT_STATE <= RX_READY;\r
+ end if;\r
+ \r
+ when RX_FRAME =>\r
+ if ( (MAC_RX_EOF_IN = '1') and (MAC_RX_ERROR_IN = '0') and (rb_full = '0') ) then\r
+ NEXT_STATE <= FRAME_OK;\r
+ elsif( (MAC_RX_EOF_IN = '1') and ((MAC_RX_ERROR_IN = '1') or (rb_full = '1')) ) then\r
+ NEXT_STATE <= FRAME_BAD;\r
+ ld_wr_ptr <= '1';\r
+ else\r
+ NEXT_STATE <= RX_FRAME;\r
+ end if;\r
+ \r
+ when FRAME_OK =>\r
+ NEXT_STATE <= FORWARD;\r
+ \r
+ when FORWARD =>\r
+ if( rb_full = '0' ) then\r
+ NEXT_STATE <= RX_READY;\r
+ else\r
+ NEXT_STATE <= RX_DENY;\r
+ end if;\r
+\r
+ when FRAME_BAD =>\r
+ NEXT_STATE <= SKIP;\r
+ \r
+ when SKIP =>\r
+ if( rb_full = '0' ) then\r
+ NEXT_STATE <= RX_READY;\r
+ else\r
+ NEXT_STATE <= RX_DENY;\r
+ end if;\r
+\r
+ when others =>\r
+ NEXT_STATE <= RX_DENY;\r
+ end case;\r
+ end process THE_STATE_TRANSITIONS;\r
+\r
+end architecture;\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
+ RESET : in std_logic;\r
+ --\r
+ FIFO_FULL_IN : in std_logic_vector(15 downto 0) := (others => '0');\r
+ FIFO_FULL_OUT : out std_logic;\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
+\r
+ FRAME_REQ_OUT <= req_int;\r
+\r
+ FIFO_FULL_OUT <= '0' when FIFO_FULL_IN = x"0000" else '1';\r
+ \r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ THE_FSM: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( RESET = '1' ) then\r
+ STATE <= IDLE;\r
+ req_int <= '0';\r
+ else\r
+ STATE <= NEXT_STATE;\r
+ req_int <= req_x;\r
+ end if;\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
+end architecture;\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 tx_fifo is\r
+ port(\r
+ CLK : in std_logic;\r
+ RESET : in std_logic;\r
+ -- MAC interface\r
+ MAC_TX_DATA_OUT : out std_logic_vector(7 downto 0);\r
+ MAC_TX_READ_IN : in std_logic;\r
+ MAC_FIFOEOF_OUT : out std_logic; -- end of frame marker\r
+ MAC_FIFOEMPTY_OUT : out std_logic; -- must never happen during TX\r
+ MAC_FIFOAVAIL_OUT : out std_logic; -- starts TX process in MAC\r
+ MAC_TX_DONE_IN : in std_logic; -- frame sent\r
+ -- FIFO interface\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
+end entity tx_fifo;\r
+\r
+architecture tx_fifo_arch of tx_fifo is\r
+\r
+-- Components\r
+ component fifo_4k_9\r
+ port(\r
+ DATA : in std_logic_vector(8 downto 0); \r
+ CLOCK : in std_logic;\r
+ WREN : in std_logic; \r
+ RDEN : in std_logic;\r
+ RESET : in std_logic;\r
+ Q : out std_logic_vector(8 downto 0);\r
+ EMPTY : out std_logic; \r
+ FULL : 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 frames_avail : unsigned(7 downto 0);\r
+ signal frame_written : std_logic;\r
+ signal frame_read : std_logic;\r
+ signal mac_fifoeof : std_logic;\r
+ signal mac_tx_read : std_logic;\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 )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ frame_active <= '0';\r
+ elsif( 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,\r
+ RDEN => MAC_TX_READ_IN,\r
+ RESET => RESET,\r
+ Q(8) => mac_fifoeof,\r
+ Q(7 downto 0) => MAC_TX_DATA_OUT,\r
+ EMPTY => MAC_FIFOEMPTY_OUT, \r
+ FULL => 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') 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
+\r
+ -- FramesAvailable counter\r
+ THE_FRAMES_AVAIL_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( RESET = '1' ) then\r
+ frames_avail <= (others => '0');\r
+ elsif( (frame_written = '1') and (frame_read = '0') ) then\r
+ -- one frame written successfully\r
+ frames_avail <= frames_avail + 1;\r
+ elsif( (frame_written = '0') and (frame_read = '1') ) then\r
+ -- one frame read successfully\r
+ frames_avail <= frames_avail - 1;\r
+ end if;\r
+ end if;\r
+ end process THE_FRAMES_AVAIL_PROC;\r
+\r
+ MAC_FIFOAVAIL_OUT <= '1' when (frames_avail /= x"00") else '0';\r
+\r
+end architecture;\r