-- -------------------------------------------------------------------------- -- -- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- -- -------------------------------------------------------------------------- -- -- TODO -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None -- License : Mozilla Public License (MPL) Version 2 -- -------------------------------------------------------------------------- -- -- ADDR0: RD: [...] TX_BUSY TX_DATA_FULL RX_DATA_EMPTY library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library generics; use generics.all; use generics.wishbone_pkg.all; entity uart_wb is generic( F_CLK : integer; BAUD_RATE : integer := 115200 ); port( clk : in std_logic; rst : in std_logic; -- Wishbone IF wb_o : out wishbone_slave_out; -- Wishbone bus (out) wb_i : in wishbone_slave_in; -- Wishbone bus (in) serial_out : out std_logic; serial_in : in std_logic ); end entity uart_wb; architecture rtl of uart_wb is signal wb_adr : unsigned(2 downto 0); signal status_register : std_logic_vector(31 downto 0); signal in_data : std_logic_vector(7 downto 0); signal in_data_latched : std_logic_vector(in_data'range); signal in_data_valid : std_logic; signal in_data_available : std_logic; signal out_data : std_logic_vector(in_data'range); signal out_data_valid : std_logic; signal out_data_latched : std_logic; signal out_busy : std_logic; begin uart_tx_inst : entity generics.uart_tx generic map( F_CLK => F_CLK, BAUD_RATE => BAUD_RATE ) port map( clk => clk, rst_a => rst, data => out_data, data_valid => out_data_valid, data_latched => out_data_latched, busy => out_busy, serial_out => serial_out ); uart_rx_inst : entity generics.uart_rx generic map( F_CLK => F_CLK, BAUD_RATE => BAUD_RATE ) port map( clk => clk, rst_a => rst, data => in_data, data_valid => in_data_valid, serial_in_a => serial_in ); wb_adr <= unsigned(wb_i.adr(wb_adr'range)); status_register <= x"000000" & "00000" & out_busy & out_data_valid & (not in_data_available); wb_if : process(clk, rst) is begin if rst then in_data_available <= '0'; out_data_valid <= '0'; wb_o.ack <= '0'; elsif rising_edge(clk) then wb_o.ack <= '0'; if out_data_latched then out_data_valid <= '0'; end if; if (wb_i.CYC and wb_i.STB) then wb_o.ack <= '1'; if wb_adr = 0 then -- status reg wb_o.dat <= status_register; else -- data reg (write to transmit, read to retrieve) if wb_i.we then out_data <= wb_i.dat(out_data'range); out_data_valid <= '1'; else wb_o.dat <= x"000000" & in_data_latched; in_data_available <= '0'; end if; end if; end if; if in_data_valid then in_data_available <= '1'; in_data_latched <= in_data; end if; end if; end process wb_if; wb_o.err <= '0'; wb_o.stall <= '0'; wb_o.rty <= '0'; end architecture rtl;