trashernet-soc/fpga/hdl/design/uart_wb.vhd

124 lines
3.1 KiB
VHDL

-- -------------------------------------------------------------------------- --
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
-- -------------------------------------------------------------------------- --
-- TODO
-- -------------------------------------------------------------------------- --
-- Author : Markus Koch <markus@notsyncing.net>
-- 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_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;
in_data_available <= '0';
end if;
end if;
end if;
if in_data_valid then
in_data_available <= '1';
end if;
end if;
end process wb_if;
wb_o.err <= '0';
wb_o.stall <= '0';
wb_o.rty <= '0';
end architecture rtl;