Select Git revision
uart_sctrl.vhd
uart_sctrl.vhd 4.98 KiB
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.trb_net_std.all;
-- use work.version.all;
--
-- library machxo2;
-- use machxo2.all;
entity uart_sctrl is
generic(
CLOCK_SPEED : integer := 33250000;
BAUD : integer := 115200
);
port(
CLK : in std_logic;
RESET : in std_logic;
UART_RX : in std_logic;
UART_TX : out std_logic;
DATA_OUT : out std_logic_vector(31 downto 0);
ADDR_OUT : out std_logic_vector(7 downto 0);
WRITE_OUT : out std_logic;
READ_OUT : out std_logic;
DATA_IN : in std_logic_vector(31 downto 0);
READY_IN : in std_logic;
BUSY_OUT : out std_logic;
DEBUG : out std_logic_vector(15 downto 0)
);
end entity;
architecture uart_sctrl_arch of uart_sctrl is
constant CLK_DIV : integer := CLOCK_SPEED/BAUD;
signal rx_data : std_logic_vector(7 downto 0);
signal tx_data : std_logic_vector(7 downto 0);
signal rx_ready : std_logic;
signal tx_send : std_logic;
signal tx_ready : std_logic;
signal bytecount : integer range 0 to 9;
signal txbytecount : integer range 0 to 7;
type rx_state_t is (IDLE,START,START2,DO_COMMAND);
type tx_state_t is (DO_READ,SEND_BYTE1,SEND_BYTE2,SEND_BYTE3,SEND_TERM,SEND_FINISH, SEND_WAIT);
signal state : rx_state_t;
signal txstate : tx_state_t;
signal txbuf : unsigned(7 downto 0);
signal addr_data : std_logic_vector(39 downto 0);
signal addr_data_tx : std_logic_vector(31 downto 0);
signal timer : unsigned(25 downto 0) := (others => '0');
signal timeout : std_logic := '0';
signal cmd_wr : std_logic := '0';
signal cmd_rd : std_logic := '0';
begin
THE_RX : entity work.uart_rec
port map(
CLK_DIV => CLK_DIV,
CLK => CLK,
RST => RESET, RX => UART_RX,
DATA_OUT => rx_data,
DATA_WAITING => rx_ready
);
THE_TX : entity work.uart_trans
port map(
CLK_DIV => CLK_DIV,
CLK => CLK,
RST => RESET,
DATA_IN => tx_data,
SEND => tx_send,
READY => tx_ready,
TX => UART_TX
);
PROC_RX : process
variable tmp2 : unsigned(7 downto 0);
begin
wait until rising_edge(CLK);
READ_OUT <= '0';
WRITE_OUT <= '0';
timer <= timer + 1;
case state is
when IDLE =>
cmd_rd <= '0';
cmd_wr <= '0';
bytecount <= 9;
timer <= (others => '0');
if rx_ready = '1' then
state <= START;
if rx_data = x"52" then
cmd_rd <= '1';
elsif rx_data = x"57" then
cmd_wr <= '1';
else
state <= IDLE;
end if;
end if;
when START =>
if rx_data >= x"40" then
tmp2 := unsigned(rx_data) + x"09";
else
tmp2 := unsigned(rx_data);
end if;
if rx_ready = '1' then
state <= START2;
end if;
when START2 =>
addr_data(bytecount*4+3 downto bytecount*4) <= std_logic_vector(tmp2(3 downto 0));
bytecount <= bytecount - 1;
if (bytecount = 0 and cmd_wr = '1') or (bytecount = 8 and cmd_rd = '1') then
state <= DO_COMMAND;
else
state <= START;
end if;
when DO_COMMAND =>
WRITE_OUT <= cmd_wr;
READ_OUT <= cmd_rd;
state <= IDLE;
end case;
if RESET = '1' or timeout = '1' then
state <= IDLE;
end if;
end process;
PROC_TX : process begin
wait until rising_edge(CLK);
tx_send <= '0';
case txstate is
--Read cycle
when DO_READ =>
if READY_IN = '1' then
addr_data_tx(31 downto 0) <= DATA_IN;
tx_send <= '1';
txbuf <= x"52";
txstate <= SEND_BYTE1;
txbytecount <= 7;
end if;
when SEND_BYTE1 =>
txbuf <= x"0" & unsigned(addr_data_tx(txbytecount*4+3 downto txbytecount*4));
txstate <= SEND_BYTE2;
when SEND_BYTE2 =>
if txbuf(3 downto 0) > x"9" then
txbuf <= txbuf + x"41" - x"0a";
else
txbuf <= txbuf + x"30";
end if;
txstate <= SEND_BYTE3;
when SEND_BYTE3 =>
if tx_ready = '1' then
tx_send <= '1';
if txbytecount = 0 then
txstate <= SEND_TERM;
else
txbytecount <= txbytecount - 1;
txstate <= SEND_BYTE1;
end if;
end if;
when SEND_TERM=>
if tx_ready = '1' then
tx_send <= '1';
txbuf <= x"0d";
txstate <= SEND_FINISH;
end if;
when SEND_FINISH=>
if tx_ready = '1' then
tx_send <= '1';
txbuf <= x"0a";
txstate <= SEND_WAIT;
end if;
when SEND_WAIT =>
if tx_ready = '1' then
txstate <= DO_READ;
end if;
end case;
if RESET = '1' then
txstate <= DO_READ;
end if;
end process;
DATA_OUT <= addr_data(31 downto 0);
ADDR_OUT <= addr_data(39 downto 32);
tx_data <= std_logic_vector(txbuf);
timeout <= timer(20);
BUSY_OUT <= '0' when txstate = DO_READ else '1';
end architecture;