Markus Koch
876693ca5f
Else, the CPU would get the part old / half current byte. This enables boot loader baud rates in excess of 19200 baud.
126 lines
3.2 KiB
VHDL
126 lines
3.2 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_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;
|