URL
https://opencores.org/ocsvn/cortexi/cortexi/trunk
Subversion Repositories cortexi
Compare Revisions
- This comparison shows the changes necessary to convert path
/cortexi
- from Rev 8 to Rev 9
- ↔ Reverse comparison
Rev 8 → Rev 9
/trunk/uart.vhd
0,0 → 1,191
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.STD_LOGIC_ARITH.ALL; |
use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
-- uart baudrate |
-- baudrate register = 1 => clk / 8 |
-- baudrate register = 2 => clk / 12 |
-- baudrate register = N => clk / ((N + 1) * 4) |
|
entity uart is |
Port ( clk : in std_logic; |
rst : in std_logic; |
datain : in std_logic_vector(7 downto 0); |
dataout : out std_logic_vector(7 downto 0); |
addr : in std_logic_vector(2 downto 0); |
cs : in std_logic; |
wr : in std_logic; |
serIn : in std_logic; |
serOut : out std_logic); |
end uart; |
|
architecture Behavioral of uart is |
|
type UARTregisters is array (0 to 7) of std_logic_vector(7 downto 0); |
signal registers : UARTregisters; |
signal txBaud : std_logic_vector(15 downto 0); |
signal rxBaud : std_logic_vector(15 downto 0); |
signal txFSM : std_logic_vector(3 downto 0); |
signal rxFSM : std_logic_vector(3 downto 0); |
signal txTick : std_logic_vector(2 downto 0); |
signal rxTick : std_logic_vector(2 downto 0); |
signal txBit : std_logic_vector(2 downto 0); |
signal rxBit : std_logic_vector(2 downto 0); |
signal sendRequest : std_logic; |
signal serInput : std_logic; |
|
begin |
|
process(clk, rst) |
begin |
if falling_edge(clk) then |
if rst = '0' then |
for i in 0 to 7 loop |
registers(i) <= x"00"; |
end loop; |
txBaud <= x"0000"; |
rxBaud <= x"0000"; |
dataout <= x"00"; |
sendRequest <= '0'; |
txFSM <= "0000"; |
rxFSM <= "0000"; |
txTick <= "000"; |
rxTick <= "000"; |
txBit <= "000"; |
rxBit <= "000"; |
serOut <= '1'; |
serInput <= '1'; |
else |
serInput <= serIn; |
-------- access to UART registers ----------------------- |
if cs = '0' then -- uart selected |
if wr = '0' then -- write access |
registers(conv_integer(addr)) <= datain; |
if addr = "000" then |
sendRequest <= '1'; |
end if; |
else |
if addr = "001" then |
registers(4)(1) <= '0'; -- data ready |
registers(4)(2) <= '0'; -- frame error |
end if; |
dataout <= registers(conv_integer(addr)); |
end if; |
end if; |
-------- baudrate --------------------------------------- |
txBaud <= txBaud + 1; |
if txBaud = (registers(2) & registers(3)) then |
txBaud <= x"0000"; |
end if; |
rxBaud <= rxBaud + 1; |
if rxBaud = (registers(2) & registers(3)) then |
rxBaud <= x"0000"; |
end if; |
-------- transmitter ------------------------------------ |
case txFSM is |
when "0000" => --##### tx idle ##### |
if sendRequest = '1' then |
registers(4)(0) <= '1'; -- tx busy |
sendRequest <= '0'; |
txFSM <= "0001"; |
txBaud <= x"0000"; |
txTick <= "000"; |
txBit <= "000"; |
serOut <= '0'; -- start bit |
end if; |
when "0001" => --##### send start bit ##### |
if txBaud = x"0000" then |
txTick <= txTick + 1; |
if txTick = "011" then |
txTick <= "000"; |
txFSM <= "0010"; |
serOut <= registers(0)(conv_integer(txBit)); |
txBit <= txBit + 1; |
end if; |
end if; |
when "0010" => --##### send data bits ##### |
if txBaud = x"0000" then |
txTick <= txTick + 1; |
if txTick = "011" then |
txTick <= "000"; |
serOut <= registers(0)(conv_integer(txBit)); |
txBit <= txBit + 1; |
if txBit = "111" then |
txFSM <= "0011"; |
end if; |
end if; |
end if; |
when "0011" => --##### send stop bit ##### |
if txBaud = x"0000" then |
txTick <= txTick + 1; |
if txTick = "011" then |
txTick <= "000"; |
serOut <= '1'; |
txFSM <= "0100"; |
end if; |
end if; |
when "0100" => --##### finishing stop bit ##### |
if txBaud = x"0000" then |
txTick <= txTick + 1; |
if txTick = "011" then |
txFSM <= "0000"; |
registers(4)(0) <= '0'; -- tx ready |
end if; |
end if; |
when others => |
txFSM <= "0000"; |
end case; -- txFSM |
-------- receiver ------------------------------------ |
case rxFSM is |
when "0000" => --##### awaiting start bit ##### |
if serInput = '0' then |
rxBaud <= x"0000"; |
rxTick <= "000"; |
rxFSM <= "0001"; |
end if; |
when "0001" => --##### cnt to middle start bit ##### |
if rxBaud = x"0000" then |
rxTick <= rxTick + 1; |
if rxTick = "001" then |
if serInput = '1' then -- false start bit |
rxFSM <= "0000"; |
else |
rxTick <= "000"; |
rxBit <= "000"; |
rxFSM <= "0010"; |
end if; |
end if; |
end if; |
when "0010" => --##### receive bits ###### |
if rxBaud = x"0000" then |
rxTick <= rxTick + 1; |
if rxTick = "011" then |
rxTick <= "000"; |
registers(1)(conv_integer(rxBit)) <= serInput; |
rxBit <= rxBit + 1; |
if rxBit = "111" then -- last bit |
rxFSM <= "0011"; |
end if; |
end if; |
end if; |
when "0011" => --##### receive stop bit ##### |
if rxBaud = x"0000" then |
rxTick <= rxTick + 1; |
if rxTick = "011" then |
if serInput = '0' then |
registers(4)(2) <= '1'; -- frame error |
else |
registers(4)(1) <= '1'; -- data ready |
end if; |
rxFSM <= "0000"; |
end if; |
end if; |
when others => |
rxFSM <= "0000"; |
end case; -- rxFSM |
end if; -- rst = '0' |
end if; -- rising_edge(clk) |
end process; |
|
end Behavioral; |