Root/plasma/logic/uart.vhd

1---------------------------------------------------------------------
2-- TITLE: UART
3-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4-- DATE CREATED: 5/29/02
5-- FILENAME: uart.vhd
6-- PROJECT: Plasma CPU core
7-- COPYRIGHT: Software placed into the public domain by the author.
8-- Software 'as is' without warranty. Author liable for nothing.
9-- DESCRIPTION:
10-- Implements the UART.
11---------------------------------------------------------------------
12library ieee;
13use ieee.std_logic_1164.all;
14use ieee.std_logic_misc.all;
15use ieee.std_logic_arith.all;
16use ieee.std_logic_textio.all;
17use ieee.std_logic_unsigned.all;
18use std.textio.all;
19use work.mlite_pack.all;
20
21entity uart is
22   generic(log_file : string := "UNUSED");
23   port(clk : in std_logic;
24        reset : in std_logic;
25        cs : in std_logic;
26        nRdWr : in std_logic;
27        data_in : in std_logic_vector(7 downto 0);
28        data_out : out std_logic_vector(7 downto 0);
29        uart_read : in std_logic;
30        uart_write : out std_logic;
31        busy_write : out std_logic;
32        data_avail : out std_logic);
33end; --entity uart
34
35architecture logic of uart is
36   signal delay_write_reg : std_logic_vector(9 downto 0);
37   signal bits_write_reg : std_logic_vector(3 downto 0);
38   signal data_write_reg : std_logic_vector(8 downto 0);
39   signal delay_read_reg : std_logic_vector(9 downto 0);
40   signal bits_read_reg : std_logic_vector(3 downto 0);
41   signal data_read_reg : std_logic_vector(7 downto 0);
42   signal data_save_reg : std_logic_vector(17 downto 0);
43   signal busy_write_sig : std_logic;
44   signal read_value_reg : std_logic_vector(6 downto 0);
45   signal uart_read2 : std_logic;
46   signal enable_read : std_logic;
47   signal enable_write : std_logic;
48
49begin
50
51interface_proc: process(cs, nRdWr)
52begin
53  if cs = '1' then
54    if nRdWr = '1' then
55      enable_read <= '0';
56      enable_write <= '1';
57    else
58      enable_read <= '1';
59      enable_write <= '0';
60    end if;
61  else
62    enable_read <= '0';
63    enable_write <= '0';
64  end if;
65end process;
66
67uart_proc: process(clk, reset, enable_read, enable_write, data_in,
68                   data_write_reg, bits_write_reg, delay_write_reg,
69                   data_read_reg, bits_read_reg, delay_read_reg,
70                   data_save_reg, read_value_reg, uart_read2,
71                   busy_write_sig, uart_read)
72   constant COUNT_VALUE : std_logic_vector(9 downto 0) :=
73-- "0100011110"; --33MHz/2/57600Hz = 0x11e
74-- "1101100100"; --50MHz/57600Hz = 0x364
75      "0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2
76-- "0011011001"; --12.5MHz/57600Hz = 0xd9
77-- "0000000100"; --for debug (shorten read_value_reg)
78begin
79   uart_read2 <= read_value_reg(read_value_reg'length - 1);
80
81   if reset = '1' then
82      data_write_reg <= ZERO(8 downto 1) & '1';
83      bits_write_reg <= "0000";
84      delay_write_reg <= ZERO(9 downto 0);
85      read_value_reg <= ONES(read_value_reg'length-1 downto 0);
86      data_read_reg <= ZERO(7 downto 0);
87      bits_read_reg <= "0000";
88      delay_read_reg <= ZERO(9 downto 0);
89      data_save_reg <= ZERO(17 downto 0);
90   elsif rising_edge(clk) then
91
92      --Write UART
93      if bits_write_reg = "0000" then --nothing left to write?
94         if enable_write = '1' then
95            delay_write_reg <= ZERO(9 downto 0); --delay before next bit
96            bits_write_reg <= "1010"; --number of bits to write
97            data_write_reg <= data_in & '0'; --remember data & start bit
98         end if;
99      else
100         if delay_write_reg /= COUNT_VALUE then
101            delay_write_reg <= delay_write_reg + 1; --delay before next bit
102         else
103            delay_write_reg <= ZERO(9 downto 0); --reset delay
104            bits_write_reg <= bits_write_reg - 1; --bits left to write
105            data_write_reg <= '1' & data_write_reg(8 downto 1);
106         end if;
107      end if;
108
109      --Average uart_read signal
110      if uart_read = '1' then
111         if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then
112            read_value_reg <= read_value_reg + 1;
113         end if;
114      else
115         if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then
116            read_value_reg <= read_value_reg - 1;
117         end if;
118      end if;
119
120      --Read UART
121      if delay_read_reg = ZERO(9 downto 0) then --done delay for read?
122         if bits_read_reg = "0000" then --nothing left to read?
123            if uart_read2 = '0' then --wait for start bit
124               delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period
125               bits_read_reg <= "1001"; --bits left to read
126            end if;
127         else
128            delay_read_reg <= COUNT_VALUE; --initialize delay
129            bits_read_reg <= bits_read_reg - 1; --bits left to read
130            data_read_reg <= uart_read2 & data_read_reg(7 downto 1);
131         end if;
132      else
133         delay_read_reg <= delay_read_reg - 1; --delay
134      end if;
135
136      --Control character buffer
137      if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then
138         if data_save_reg(8) = '0' or
139               (enable_read = '1' and data_save_reg(17) = '0') then
140            --Empty buffer
141            data_save_reg(8 downto 0) <= '1' & data_read_reg;
142         else
143            --Second character in buffer
144            data_save_reg(17 downto 9) <= '1' & data_read_reg;
145            if enable_read = '1' then
146               data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
147            end if;
148         end if;
149      elsif enable_read = '1' then
150         data_save_reg(17) <= '0'; --data_available
151         data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
152      end if;
153   end if; --rising_edge(clk)
154
155   uart_write <= data_write_reg(0);
156   if bits_write_reg /= "0000"
157-- Comment out the following line for full UART simulation (much slower)
158   and log_file = "UNUSED"
159   then
160      busy_write_sig <= '1';
161   else
162      busy_write_sig <= '0';
163   end if;
164   busy_write <= busy_write_sig;
165   data_avail <= data_save_reg(8);
166   data_out <= data_save_reg(7 downto 0);
167   
168end process; --uart_proc
169
170end; --architecture logic
171

Archive Download this file

Branches:
master



interactive