mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-02-13 03:14:05 +00:00
122 lines
4.3 KiB
VHDL
122 lines
4.3 KiB
VHDL
-- Copyright (c) 2015, $ME
|
|
-- All rights reserved.
|
|
--
|
|
-- Redistribution and use in source and synthezised forms, with or without modification, are permitted
|
|
-- provided that the following conditions are met:
|
|
--
|
|
-- 1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
|
-- and the following disclaimer.
|
|
--
|
|
-- 2. Redistributions in synthezised form must reproduce the above copyright notice, this list of conditions
|
|
-- and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
--
|
|
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
-- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
-- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
-- POSSIBILITY OF SUCH DAMAGE.
|
|
--
|
|
--
|
|
-- complete uart
|
|
--
|
|
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
|
|
entity uart is
|
|
generic (
|
|
sysclk : integer := 50_000_000; -- 50MHz
|
|
baudrate : integer := 115_200
|
|
);
|
|
port (
|
|
clk : in std_logic;
|
|
|
|
cs_n : in std_logic; -- negative
|
|
rd_n : in std_logic; -- negative
|
|
wr_n : in std_logic; -- negative
|
|
|
|
addr : in std_logic_vector(0 downto 0);
|
|
|
|
dIn : in std_logic_vector(7 downto 0);
|
|
dOut : out std_logic_vector(7 downto 0);
|
|
|
|
txd : out std_logic;
|
|
rxd : in std_logic
|
|
);
|
|
end uart;
|
|
|
|
architecture rtl of uart is
|
|
constant maxPreScaler : integer := (sysclk/baudrate)-1;
|
|
constant halfBitCnt : integer := maxPreScaler*2/3;
|
|
|
|
signal preScalerTx : integer range 0 to maxPreScaler;
|
|
signal txCnt : integer range 0 to 10 := 0;
|
|
signal txShift : std_logic_vector(9 downto 0) := (others => '1');
|
|
|
|
signal preScalerRx : integer range 0 to maxPreScaler;
|
|
signal rxShift : std_logic_vector(8 downto 0) := (others => '1');
|
|
signal rxInShift : std_logic_vector(3 downto 0) := (others => '0');
|
|
signal rxBuff : std_logic_vector(7 downto 0) := (others => '0');
|
|
signal receiving : boolean := false;
|
|
begin
|
|
dOut <= std_logic_vector(to_unsigned(txCnt,dOut'length)) when addr(0)='0'
|
|
else rxBuff;
|
|
|
|
-- transmit data
|
|
tx : process
|
|
begin
|
|
wait until rising_edge(clk);
|
|
|
|
if (wr_n='0' and cs_n='0' and addr(0)='0' and txCnt=0) then
|
|
txShift <= '1' & dIn & '0';
|
|
txCnt <= 10;
|
|
preScalerTx <= 0;
|
|
elsif (txCnt/=0) then
|
|
if (preScalerTx=maxPreScaler) then
|
|
preScalerTx <= 0;
|
|
|
|
txShift <= '1' & txShift(txShift'left downto 1);
|
|
|
|
txCnt <= txCnt - 1;
|
|
else
|
|
preScalerTx <= preScalerTx + 1;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
txd <= txShift(0);
|
|
|
|
-- receive data
|
|
rx : process
|
|
begin
|
|
wait until rising_edge(clk);
|
|
|
|
rxInShift <= rxInShift(rxInShift'left-1 downto 0) & rxd;
|
|
|
|
if (wr_n='0' and cs_n='0' and addr(0)='1') then
|
|
rxBuff <= (others => '0');
|
|
end if;
|
|
|
|
if (receiving) then
|
|
if (preScalerRx=maxPreScaler) then
|
|
preScalerRx <= 0;
|
|
rxShift <= rxInShift(rxInShift'left) & rxShift(rxShift'left downto 1);
|
|
|
|
if (rxShift(0)='0') then
|
|
receiving <= false;
|
|
rxBuff <= rxShift(rxShift'left downto 1);
|
|
end if;
|
|
else
|
|
preScalerRx <= preScalerRx + 1;
|
|
end if;
|
|
elsif (rxInShift(rxInShift'left)='1' and rxInShift(rxInShift'left-1)='0') then
|
|
receiving <= true;
|
|
rxShift <= (others => '1');
|
|
preScalerRx <= halfBitCnt;
|
|
end if;
|
|
end process;
|
|
end;
|