OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [o8_async_serial.vhd] - Blame information for rev 215

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jshamlet
-- Copyright (c)2020 Jeremy Seth Henry
2
-- All rights reserved.
3
--
4
-- Redistribution and use in source and binary forms, with or without
5
-- modification, are permitted provided that the following conditions are met:
6
--     * Redistributions of source code must retain the above copyright
7
--       notice, this list of conditions and the following disclaimer.
8
--     * Redistributions in binary form must reproduce the above copyright
9
--       notice, this list of conditions and the following disclaimer in the
10
--       documentation and/or other materials provided with the distribution,
11
--       where applicable (as part of a user interface, debugging port, etc.)
12
--
13
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
14
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
17
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 213 jshamlet
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 207 jshamlet
--
24
-- VHDL Units :  o8_async_serial
25
-- Description:  Provides a single 8-bit, asynchronous transceiver. While the
26
--               width is fixed at 8-bits, the bit rate and parity controls
27
--               are settable via generics.
28 209 jshamlet
--
29 213 jshamlet
-- Register Map:
30
-- Offset  Bitfield Description                        Read/Write
31
--   0x00  AAAAAAAA TX Data (WR) RX Data (RD)             (RW)
32
--   0x01  DCBA---- FIFO Status                           (RO)
33
--                  A: RX FIFO Empty
34
--                  B: RX FIFO almost full (922/1024)
35
--                  C: TX FIFO Empty
36
--                  D: TX FIFO almost full (922/1024)
37
--
38 209 jshamlet
-- Note: The baud rate generator will produce an approximate frequency. The
39
--        final bit rate should be within +/- 1% of the true bit rate to
40
--        ensure the receiver can successfully receive. With a sufficiently
41
--        high core clock, this is generally achievable for common PC serial
42
--        data rates.
43 213 jshamlet
--
44
-- Revision History
45
-- Author          Date     Change
46
------------------ -------- ---------------------------------------------------
47
-- Seth Henry      12/20/19 Design Start
48
-- Seth Henry      04/10/20 Code cleanup and register documentation
49 207 jshamlet
 
50
library ieee;
51
use ieee.std_logic_1164.all;
52
use ieee.std_logic_unsigned.all;
53
use ieee.std_logic_arith.all;
54
use ieee.std_logic_misc.all;
55
 
56
library work;
57
  use work.open8_pkg.all;
58
 
59
entity o8_async_serial is
60
generic(
61 213 jshamlet
  Disable_Transmit      : boolean := FALSE;
62
  Disable_Receive       : boolean := FALSE;
63 207 jshamlet
  Bit_Rate              : real;
64
  Enable_Parity         : boolean;
65
  Parity_Odd_Even_n     : std_logic;
66
  Sys_Freq              : real;
67
  Reset_Level           : std_logic;
68
  Address               : ADDRESS_TYPE
69
);
70
port(
71
  Clock                 : in  std_logic;
72
  Reset                 : in  std_logic;
73
  --
74
  Bus_Address           : in  ADDRESS_TYPE;
75
  Wr_Enable             : in  std_logic;
76
  Wr_Data               : in  DATA_TYPE;
77
  Rd_Enable             : in  std_logic;
78
  Rd_Data               : out DATA_TYPE;
79
  --
80
  TX_Out                : out std_logic;
81
  CTS_In                : in  std_logic;
82
  RX_In                 : in  std_logic;
83
  RTS_Out               : out std_logic
84
);
85
end entity;
86
 
87
architecture behave of o8_async_serial is
88
 
89
  signal FIFO_Reset          : std_logic := '0';
90
 
91
  constant User_Addr         : std_logic_vector(15 downto 1) :=
92
                                Address(15 downto 1);
93
  alias  Comp_Addr           is Bus_Address(15 downto 1);
94
  signal Addr_Match          : std_logic := '0';
95
 
96
  alias  Reg_Addr            is Bus_Address(0);
97
  signal Reg_Sel             : std_logic := '0';
98
  signal Rd_En               : std_logic := '0';
99
 
100
  signal TX_FIFO_Wr_En       : std_logic := '0';
101
  alias  TX_FIFO_Wr_Data     is Wr_Data;
102
  signal TX_FIFO_Rd_En       : std_logic := '0';
103
  signal TX_FIFO_Empty       : std_logic := '0';
104
  signal TX_FIFO_AFull       : std_logic := '0';
105
  signal TX_FIFO_Rd_Data     : DATA_TYPE := x"00";
106
 
107
  alias  Tx_Data             is TX_FIFO_Rd_Data;
108
 
109
  type TX_CTRL_STATES is (IDLE, TX_BYTE, TX_START, TX_WAIT );
110
  signal TX_Ctrl             : TX_CTRL_STATES := IDLE;
111
 
112
  signal TX_Xmit             : std_logic := '0';
113
  signal TX_Done             : std_logic := '0';
114
 
115
  constant BAUD_RATE_DIV     : integer := integer(Sys_Freq / Bit_Rate);
116
 
117
  signal CTS_sr              : std_logic_vector(3 downto 0) := "0000";
118
  alias  CTS_Okay            is CTS_sr(3);
119
 
120
  signal RX_FIFO_Wr_En       : std_logic := '0';
121 209 jshamlet
  signal RX_FIFO_Wr_Data     : DATA_TYPE := x"00";
122
  signal RX_FIFO_Rd_En       : std_logic := '0';
123
  signal RX_FIFO_Empty       : std_logic := '0';
124
  signal RX_FIFO_AFull       : std_logic := '0';
125
  signal RX_FIFO_Rd_Data     : DATA_TYPE := x"00";
126 207 jshamlet
 
127
begin
128
 
129
  Addr_Match                 <= '1' when Comp_Addr = User_Addr else '0';
130
 
131
  io_reg: process( Clock, Reset )
132
  begin
133
    if( Reset = Reset_Level )then
134
      Rd_En             <= '0';
135
      Rd_Data           <= OPEN8_NULLBUS;
136
      RTS_Out           <= '0';
137
    elsif( rising_edge( Clock ) )then
138
      Rd_Data           <= OPEN8_NULLBUS;
139
      Rd_En             <= Rd_Enable and Addr_Match;
140
      Reg_Sel           <= Reg_Addr;
141
      if( Rd_En = '1' and Reg_Sel = '1' )then
142
        Rd_Data(4)      <= RX_FIFO_Empty;
143
        Rd_Data(5)      <= RX_FIFO_AFull;
144
        Rd_Data(6)      <= TX_FIFO_Empty;
145
        Rd_Data(7)      <= TX_FIFO_AFull;
146
      end if;
147
      if( Rd_En = '1' and Reg_Sel = '0' )then
148
        Rd_Data         <= RX_FIFO_Rd_Data;
149
      end if;
150
      RTS_Out           <= not RX_FIFO_AFull;
151
    end if;
152
  end process;
153
 
154 213 jshamlet
TX_Disabled : if( Disable_Transmit )generate
155
 
156
  TX_FIFO_Empty              <= '1';
157
  TX_FIFO_AFull              <= '0';
158
  TX_Out                     <= '1';
159
 
160
end generate;
161
 
162
TX_Enabled : if( not Disable_Transmit )generate
163
 
164 207 jshamlet
  TX_FIFO_Wr_En              <= Wr_Enable and Addr_Match and not Reg_Addr;
165
 
166
  FIFO_Reset                 <= '1' when Reset = Reset_Level else '0';
167
 
168
  U_TX_FIFO : entity work.fifo_1k_core
169
  port map(
170
    aclr                     => FIFO_Reset,
171
    clock                    => Clock,
172
    data                     => TX_FIFO_Wr_Data,
173
    rdreq                    => TX_FIFO_Rd_En,
174
    wrreq                    => TX_FIFO_Wr_En,
175
    empty                    => TX_FIFO_Empty,
176
    almost_full              => TX_FIFO_AFull,
177
    q                        => TX_FIFO_Rd_Data
178
  );
179
 
180
  tx_FSM: process( Clock, Reset )
181
  begin
182
    if( Reset = Reset_Level )then
183
      TX_Ctrl                <= IDLE;
184
      TX_Xmit                <= '0';
185
      TX_FIFO_Rd_En          <= '0';
186
      CTS_sr                 <= (others => '0');
187
    elsif( rising_edge(Clock) )then
188
      TX_Xmit                <= '0';
189
      TX_FIFO_Rd_En          <= '0';
190
      CTS_sr                 <= CTS_sr(2 downto 0) & CTS_In;
191
 
192
      case( TX_Ctrl )is
193
        when IDLE =>
194
          if( TX_FIFO_Empty = '0' and CTS_Okay = '1' )then
195
            TX_FIFO_Rd_En    <= '1';
196
            TX_Ctrl          <= TX_BYTE;
197
          end if;
198
 
199
        when TX_BYTE =>
200
          TX_Xmit            <= '1';
201
          TX_Ctrl            <= TX_START;
202
 
203
        when TX_START =>
204
          if( Tx_Done = '0' )then
205
            TX_Ctrl          <= TX_WAIT;
206
          end if;
207
 
208
        when TX_WAIT =>
209
          if( Tx_Done = '1' )then
210
            TX_Ctrl          <= IDLE;
211
          end if;
212
 
213
        when others => null;
214
      end case;
215
 
216
    end if;
217
  end process;
218
 
219
  U_TX : entity work.async_ser_tx
220
  generic map(
221
    Reset_Level              => Reset_Level,
222
    Enable_Parity            => Enable_Parity,
223
    Parity_Odd_Even_n        => Parity_Odd_Even_n,
224
    Clock_Divider            => BAUD_RATE_DIV
225
  )
226
  port map(
227
    Clock                    => Clock,
228
    Reset                    => Reset,
229
    --
230
    Tx_Data                  => Tx_Data,
231
    Tx_Valid                 => TX_Xmit,
232
    --
233
    Tx_Out                   => TX_Out,
234
    Tx_Done                  => Tx_Done
235
  );
236
 
237 213 jshamlet
end generate;
238
 
239
RX_Disabled : if( Disable_Transmit )generate
240
 
241
  RX_FIFO_Empty              <= '1';
242
  RX_FIFO_AFull              <= '0';
243
  RX_FIFO_Rd_Data            <= x"00";
244
 
245
end generate;
246
 
247
RX_Enabled : if( not Disable_Receive )generate
248
 
249 207 jshamlet
  U_RX : entity work.async_ser_rx
250
  generic map(
251
    Reset_Level              => Reset_Level,
252
    Enable_Parity            => Enable_Parity,
253
    Parity_Odd_Even_n        => Parity_Odd_Even_n,
254
    Clock_Divider            => BAUD_RATE_DIV
255
  )
256
  port map(
257
    Clock                    => Clock,
258
    Reset                    => Reset,
259
    --
260
    Rx_In                    => RX_In,
261
    --
262
    Rx_Data                  => RX_FIFO_Wr_Data,
263
    Rx_Valid                 => RX_FIFO_Wr_En,
264
    Rx_PErr                  => open
265
  );
266
 
267
  RX_FIFO_Rd_En              <= Rd_Enable and Addr_Match and not Reg_Addr;
268
 
269
  U_RX_FIFO : entity work.fifo_1k_core
270
  port map(
271
    aclr                     => FIFO_Reset,
272
    clock                    => Clock,
273
    data                     => RX_FIFO_Wr_Data,
274
    rdreq                    => RX_FIFO_Rd_En,
275
    wrreq                    => RX_FIFO_Wr_En,
276
    empty                    => RX_FIFO_Empty,
277
    almost_full              => RX_FIFO_AFull,
278
    q                        => RX_FIFO_Rd_Data
279
  );
280
 
281 213 jshamlet
end generate;
282
 
283 207 jshamlet
end architecture;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.