fpga: Implement functional Ethernet controller
This commit is contained in:
		
							parent
							
								
									79b1153df7
								
							
						
					
					
						commit
						e81166a82c
					
				| @ -38,8 +38,8 @@ set_io eth_tx_p[1] 2 | ||||
| set_io eth_tx_p[2] 4 | ||||
| set_io eth_tx_p[3] 3 | ||||
| 
 | ||||
| set_io eth_led_green 40 | ||||
| set_io eth_led_orange 41 | ||||
| set_io eth_led_green_n 40 | ||||
| set_io eth_led_orange_n 41 | ||||
| 
 | ||||
| set_io led_user 34 | ||||
| 
 | ||||
|  | ||||
| @ -25,35 +25,35 @@ entity top is | ||||
| 		UART_BAUD : integer := 19200 | ||||
| 	); | ||||
| 	port( | ||||
| 		clk_50m        : in    std_logic; -- System clock | ||||
| 		clk_50m          : in    std_logic; -- System clock | ||||
| 
 | ||||
| 		-- UART | ||||
| 		uart_tx        : out   std_logic; -- UART TX | ||||
| 		uart_rx        : in    std_logic; -- UART RX | ||||
| 		uart_tx          : out   std_logic; -- UART TX | ||||
| 		uart_rx          : in    std_logic; -- UART RX | ||||
| 
 | ||||
| 		-- Trashernet | ||||
| 		eth_rx_p       : in    std_logic; -- Ethernet RX+ | ||||
| 		eth_rx_p         : in    std_logic; -- Ethernet RX+ | ||||
| 		--eth_rx_n       : in    std_logic; -- Ethernet RX- | ||||
| 		eth_tx_p       : out   std_logic_vector(3 downto 0); -- Ethernet TX+ | ||||
| 		eth_tx_n       : out   std_logic_vector(3 downto 0); -- Ethernet TX- | ||||
| 		eth_tx_p         : out   std_logic_vector(3 downto 0); -- Ethernet TX+ | ||||
| 		eth_tx_n         : out   std_logic_vector(3 downto 0); -- Ethernet TX- | ||||
| 
 | ||||
| 		-- LEDs | ||||
| 		eth_led_green  : out   std_logic; | ||||
| 		eth_led_orange : out   std_logic; | ||||
| 		led_user       : out   std_logic; -- | ||||
| 		eth_led_green_n  : out   std_logic; | ||||
| 		eth_led_orange_n : out   std_logic; | ||||
| 		led_user         : out   std_logic; -- | ||||
| 
 | ||||
| 		-- PSRAM IF | ||||
| 		psram_ce_n     : out   std_logic; | ||||
| 		psram_sclk     : out   std_logic; | ||||
| 		psram_sio      : inout std_logic_vector(3 downto 0); -- | ||||
| 		psram_ce_n       : out   std_logic; | ||||
| 		psram_sclk       : out   std_logic; | ||||
| 		psram_sio        : inout std_logic_vector(3 downto 0); -- | ||||
| 
 | ||||
| 		-- Config Flash | ||||
| 		flash_ce_n     : out   std_logic; | ||||
| 		flash_sclk     : out   std_logic; | ||||
| 		flash_sio      : inout std_logic_vector(3 downto 0); -- | ||||
| 		flash_ce_n       : out   std_logic; | ||||
| 		flash_sclk       : out   std_logic; | ||||
| 		flash_sio        : inout std_logic_vector(3 downto 0); -- | ||||
| 
 | ||||
| 		-- PMOD | ||||
| 		pmod           : inout std_logic_vector(7 downto 0) | ||||
| 		pmod             : inout std_logic_vector(7 downto 0) | ||||
| 	); | ||||
| end entity top; | ||||
| 
 | ||||
| @ -69,6 +69,9 @@ architecture rtl of top is | ||||
| 	signal eth_tx_n_i : std_logic; | ||||
| 	signal eth_rx_p_i : std_logic; | ||||
| 
 | ||||
| 	signal eth_led_green  : std_logic; | ||||
| 	signal eth_led_orange : std_logic; | ||||
| 
 | ||||
| 	-- System Timer | ||||
| 	signal irq_timer : std_logic; | ||||
| 
 | ||||
| @ -247,7 +250,9 @@ begin | ||||
| 			wb_i    => wb_eth_i, | ||||
| 			rx_p    => eth_rx_p_i, | ||||
| 			tx_p    => eth_tx_p_i, | ||||
| 			tx_n    => eth_tx_n_i | ||||
| 			tx_n    => eth_tx_n_i, | ||||
| 			led_rx  => eth_led_green, | ||||
| 			led_tx  => eth_led_orange | ||||
| 		); | ||||
| 	eth_tx_p <= (others => eth_tx_p_i); | ||||
| 	eth_tx_n <= (others => eth_tx_n_i); | ||||
| @ -264,9 +269,9 @@ begin | ||||
| 			mask      => wishbone_masks | ||||
| 		); | ||||
| 
 | ||||
| 	eth_led_green  <= uart_tx; | ||||
| 	eth_led_orange <= uart_rx; | ||||
| 	led_user       <= not psram_ce_n; | ||||
| 	eth_led_green_n  <= not eth_led_green; | ||||
| 	eth_led_orange_n <= not eth_led_orange; | ||||
| 	led_user         <= not uart_tx or not uart_rx; | ||||
| 
 | ||||
| 	flash_ce_n <= 'Z'; | ||||
| 	flash_sclk <= 'Z'; | ||||
|  | ||||
| @ -37,7 +37,10 @@ entity trashernet_phy_wb is | ||||
| 		-- Ethernet physical signals | ||||
| 		rx_p    : in  std_logic; | ||||
| 		tx_p    : out std_logic; | ||||
| 		tx_n    : out std_logic | ||||
| 		tx_n    : out std_logic; | ||||
| 		-- LEDs | ||||
| 		led_tx  : out std_logic; | ||||
| 		led_rx  : out std_logic | ||||
| 	); | ||||
| end entity trashernet_phy_wb; | ||||
| 
 | ||||
| @ -46,6 +49,9 @@ architecture RTL of trashernet_phy_wb is | ||||
| 	signal phy_out : phy_out_t;         -- PHY application IF (out) | ||||
| 	signal phy_in  : phy_in_t;          -- PHY application IF (in) | ||||
| 
 | ||||
| 	signal mac_out : raw_mac_out_t;     -- MAC application IF (out) | ||||
| 	signal mac_in  : raw_mac_in_t;      -- MAC application IF (in) | ||||
| 
 | ||||
| 	signal wb_adr : unsigned(2 downto 2); | ||||
| 
 | ||||
| 	signal status_register : std_logic_vector(31 downto 0); | ||||
| @ -57,6 +63,11 @@ architecture RTL of trashernet_phy_wb is | ||||
| 	signal tx_fifo_commit : std_logic; | ||||
| 	signal tx_fifo_empty  : std_logic; | ||||
| 	signal tx_fifo_data   : std_logic_vector(7 downto 0); | ||||
| 
 | ||||
| 	signal rx_fifo_empty       : std_logic; | ||||
| 	signal rx_bitcount         : std_logic_vector(10 downto 0); | ||||
| 	signal rx_fifo_block_count : std_logic_vector(rx_bitcount'range); | ||||
| 	signal rx_block_next       : std_logic; | ||||
| begin | ||||
| 	trashernet_phy_inst : entity trashernet.trashernet_phy_cdc | ||||
| 		generic map( | ||||
| @ -74,6 +85,16 @@ begin | ||||
| 			tx_n    => tx_n | ||||
| 		); | ||||
| 
 | ||||
| 	trashernet_raw_mac_inst : entity trashernet.trashernet_raw_mac | ||||
| 		port map( | ||||
| 			clk     => clk, | ||||
| 			rst     => rst, | ||||
| 			phy_out => phy_out, | ||||
| 			phy_in  => phy_in, | ||||
| 			mac_out => mac_out, | ||||
| 			mac_in  => mac_in | ||||
| 		); | ||||
| 
 | ||||
| 	rx_fifo_inst : entity generics.fifo_block | ||||
| 		generic map( | ||||
| 			SIZE => 2047 | ||||
| @ -82,18 +103,48 @@ begin | ||||
| 			clk        => clk, | ||||
| 			rst_a      => '0', | ||||
| 			clr        => rst, | ||||
| 			data_in    => phy_out.rx_data, | ||||
| 			write      => phy_out.rx_data_valid, | ||||
| 			commit     => not phy_out.rx_active, | ||||
| 			abort      => '0', | ||||
| 			data_in    => mac_out.rx_mac_data, | ||||
| 			write      => mac_out.rx_mac_valid, | ||||
| 			commit     => mac_out.rx_mac_crc_ok, | ||||
| 			abort      => mac_out.rx_mac_crc_error, | ||||
| 			full       => open, | ||||
| 			data_out   => rx_fifo_data, | ||||
| 			data_first => open, | ||||
| 			empty      => open, | ||||
| 			empty      => rx_fifo_empty, | ||||
| 			read       => rx_fifo_read, | ||||
| 			usage      => open | ||||
| 		); | ||||
| 
 | ||||
| 	fifo_inst : entity generics.fifo | ||||
| 		generic map( | ||||
| 			SIZE => 31 | ||||
| 		) | ||||
| 		port map( | ||||
| 			clk      => clk, | ||||
| 			rst_a    => '0', | ||||
| 			clr      => rst, | ||||
| 			data_in  => rx_bitcount, | ||||
| 			write    => mac_out.rx_mac_crc_ok, | ||||
| 			full     => open, | ||||
| 			data_out => rx_fifo_block_count, | ||||
| 			empty    => open, | ||||
| 			read     => rx_block_next, | ||||
| 			usage    => open | ||||
| 		); | ||||
| 
 | ||||
| 	rxcount : process(rst, clk) is | ||||
| 	begin | ||||
| 		if rst then | ||||
| 			rx_bitcount <= (others => '0'); | ||||
| 
 | ||||
| 		elsif rising_edge(clk) then | ||||
| 			if mac_out.rx_mac_crc_error or mac_out.rx_mac_crc_ok then | ||||
| 				rx_bitcount <= (others => '0'); | ||||
| 			elsif mac_out.rx_mac_valid then | ||||
| 				rx_bitcount <= std_logic_vector(unsigned(rx_bitcount) + 1); | ||||
| 			end if; | ||||
| 		end if; | ||||
| 	end process rxcount; | ||||
| 	tx_fifo_inst : entity generics.fifo_block | ||||
| 		generic map( | ||||
| 			SIZE => 2047 | ||||
| @ -110,7 +161,7 @@ begin | ||||
| 			data_out   => tx_fifo_data, | ||||
| 			data_first => open, | ||||
| 			empty      => tx_fifo_empty, | ||||
| 			read       => phy_out.tx_data_ack, | ||||
| 			read       => mac_out.tx_mac_data_ack, | ||||
| 			usage      => open | ||||
| 		); | ||||
| 
 | ||||
| @ -122,12 +173,14 @@ begin | ||||
| 			rx_fifo_read   <= '0'; | ||||
| 			tx_fifo_write  <= '0'; | ||||
| 			tx_fifo_commit <= '0'; | ||||
| 			rx_block_next  <= '0'; | ||||
| 
 | ||||
| 		elsif rising_edge(clk) then | ||||
| 			wb_o.ack       <= '0'; | ||||
| 			rx_fifo_read   <= '0'; | ||||
| 			tx_fifo_write  <= '0'; | ||||
| 			tx_fifo_commit <= '0'; | ||||
| 			rx_block_next  <= '0'; | ||||
| 
 | ||||
| 			if (wb_i.cyc and wb_i.stb) then | ||||
| 				wb_o.ack <= '1'; | ||||
| @ -136,7 +189,8 @@ begin | ||||
| 					wb_o.dat <= status_register; | ||||
| 					if wb_o.ack = '0' then | ||||
| 						if wb_i.we = '1' then | ||||
| 							tx_fifo_commit <= '1'; | ||||
| 							tx_fifo_commit <= wb_i.dat(2); | ||||
| 							rx_block_next  <= wb_i.dat(1); | ||||
| 						end if; | ||||
| 					end if; | ||||
| 				else | ||||
| @ -159,8 +213,43 @@ begin | ||||
| 	wb_o.rty   <= '1'; | ||||
| 	wb_o.stall <= '0'; | ||||
| 
 | ||||
| 	phy_in.tx_data_en <= not tx_fifo_empty; -- FIXME: this does not care about inter-packet gaps indicated by `data_first` | ||||
| 	phy_in.tx_data    <= tx_fifo_data; | ||||
| 	mac_in.tx_mac_data_en <= not tx_fifo_empty; -- FIXME: this does not care about inter-packet gaps indicated by `data_first` | ||||
| 	mac_in.tx_mac_data    <= tx_fifo_data; | ||||
| 
 | ||||
| 	status_register <= (x"0000" & x"000" & "000" & phy_out.carrier_detect); | ||||
| 	status_register <= ("0" & x"0" & rx_fifo_block_count & -- 31..16 | ||||
| 	                    x"000" & "0" & (not tx_fifo_empty) & (not rx_fifo_empty) & phy_out.carrier_detect); | ||||
| 
 | ||||
| 	ledstretch : process(clk) is | ||||
| 		constant CMAX : integer := integer(0.2 / (1.0 / real(F_CLK))); | ||||
| 		variable cnt  : integer range 0 to CMAX; | ||||
| 	begin | ||||
| 		if rising_edge(clk) then | ||||
| 			if cnt = 0 then | ||||
| 				led_rx <= phy_out.carrier_detect; | ||||
| 				if phy_out.rx_active then | ||||
| 					cnt := CMAX; | ||||
| 				end if; | ||||
| 			else | ||||
| 				led_rx <= '0'; | ||||
| 				cnt    := cnt - 1; | ||||
| 			end if; | ||||
| 		end if; | ||||
| 	end process ledstretch; | ||||
| 
 | ||||
| 	ledstretch2 : process(clk) is | ||||
| 		constant CMAX : integer := integer(0.2 / (1.0 / real(F_CLK))); | ||||
| 		variable cnt  : integer range 0 to CMAX; | ||||
| 	begin | ||||
| 		if rising_edge(clk) then | ||||
| 			if cnt = 0 then | ||||
| 				led_tx <= '0'; | ||||
| 				if phy_out.tx_active then | ||||
| 					cnt := CMAX; | ||||
| 				end if; | ||||
| 			else | ||||
| 				led_tx <= '1'; | ||||
| 				cnt    := cnt - 1; | ||||
| 			end if; | ||||
| 		end if; | ||||
| 	end process ledstretch2; | ||||
| end architecture RTL; | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| Subproject commit 21a0d0e69aeacf9747bfac0262e0d7ca30a691d9 | ||||
| Subproject commit 206332f3d1c1f5b704bad09b1380a8aed8b736aa | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user