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 242

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 224 jshamlet
-- Seth Henry      04/16/20 Modified to use Open8 bus record
50 207 jshamlet
 
51
library ieee;
52
use ieee.std_logic_1164.all;
53
use ieee.std_logic_unsigned.all;
54
use ieee.std_logic_arith.all;
55
use ieee.std_logic_misc.all;
56
 
57
library work;
58
  use work.open8_pkg.all;
59
 
60
entity o8_async_serial is
61
generic(
62 217 jshamlet
  Disable_Transmit           : boolean := FALSE;
63
  Disable_Receive            : boolean := FALSE;
64
  Bit_Rate                   : real;
65
  Enable_Parity              : boolean;
66
  Parity_Odd_Even_n          : std_logic;
67 224 jshamlet
  Clock_Frequency            : real;
68 217 jshamlet
  Address                    : ADDRESS_TYPE
69 207 jshamlet
);
70
port(
71 223 jshamlet
  Open8_Bus                  : in  OPEN8_BUS_TYPE;
72 217 jshamlet
  Rd_Data                    : out DATA_TYPE;
73 207 jshamlet
  --
74 217 jshamlet
  TX_Out                     : out std_logic;
75
  CTS_In                     : in  std_logic;
76
  RX_In                      : in  std_logic;
77
  RTS_Out                    : out std_logic
78 207 jshamlet
);
79
end entity;
80
 
81
architecture behave of o8_async_serial is
82
 
83 224 jshamlet
  alias Clock                is Open8_Bus.Clock;
84
  alias Reset                is Open8_Bus.Reset;
85
  alias uSec_Tick            is Open8_Bus.uSec_Tick;
86
 
87 207 jshamlet
  signal FIFO_Reset          : std_logic := '0';
88
 
89
  constant User_Addr         : std_logic_vector(15 downto 1) :=
90
                                Address(15 downto 1);
91 223 jshamlet
  alias  Comp_Addr           is Open8_Bus.Address(15 downto 1);
92 207 jshamlet
  signal Addr_Match          : std_logic := '0';
93
 
94 223 jshamlet
  alias  Reg_Addr            is Open8_Bus.Address(0);
95 207 jshamlet
  signal Reg_Sel             : std_logic := '0';
96
  signal Rd_En               : std_logic := '0';
97
 
98
  signal TX_FIFO_Wr_En       : std_logic := '0';
99 223 jshamlet
  alias  TX_FIFO_Wr_Data     is Open8_Bus.Wr_Data;
100 207 jshamlet
  signal TX_FIFO_Rd_En       : std_logic := '0';
101
  signal TX_FIFO_Empty       : std_logic := '0';
102
  signal TX_FIFO_AFull       : std_logic := '0';
103
  signal TX_FIFO_Rd_Data     : DATA_TYPE := x"00";
104
 
105
  alias  Tx_Data             is TX_FIFO_Rd_Data;
106
 
107
  type TX_CTRL_STATES is (IDLE, TX_BYTE, TX_START, TX_WAIT );
108
  signal TX_Ctrl             : TX_CTRL_STATES := IDLE;
109
 
110
  signal TX_Xmit             : std_logic := '0';
111
  signal TX_Done             : std_logic := '0';
112
 
113 224 jshamlet
  constant BAUD_RATE_DIV     : integer := integer(Clock_Frequency / Bit_Rate);
114 207 jshamlet
 
115
  signal CTS_sr              : std_logic_vector(3 downto 0) := "0000";
116
  alias  CTS_Okay            is CTS_sr(3);
117
 
118
  signal RX_FIFO_Wr_En       : std_logic := '0';
119 209 jshamlet
  signal RX_FIFO_Wr_Data     : DATA_TYPE := x"00";
120
  signal RX_FIFO_Rd_En       : std_logic := '0';
121
  signal RX_FIFO_Empty       : std_logic := '0';
122
  signal RX_FIFO_AFull       : std_logic := '0';
123
  signal RX_FIFO_Rd_Data     : DATA_TYPE := x"00";
124 207 jshamlet
 
125
begin
126
 
127
  Addr_Match                 <= '1' when Comp_Addr = User_Addr else '0';
128
 
129
  io_reg: process( Clock, Reset )
130
  begin
131
    if( Reset = Reset_Level )then
132 217 jshamlet
      Rd_En                  <= '0';
133
      Rd_Data                <= OPEN8_NULLBUS;
134
      RTS_Out                <= '0';
135 207 jshamlet
    elsif( rising_edge( Clock ) )then
136 217 jshamlet
      Rd_Data                <= OPEN8_NULLBUS;
137 223 jshamlet
      Rd_En                  <= Addr_Match and Open8_Bus.Rd_En;
138 217 jshamlet
      Reg_Sel                <= Reg_Addr;
139 207 jshamlet
      if( Rd_En = '1' and Reg_Sel = '1' )then
140 217 jshamlet
        Rd_Data(4)           <= RX_FIFO_Empty;
141
        Rd_Data(5)           <= RX_FIFO_AFull;
142
        Rd_Data(6)           <= TX_FIFO_Empty;
143
        Rd_Data(7)           <= TX_FIFO_AFull;
144 207 jshamlet
      end if;
145
      if( Rd_En = '1' and Reg_Sel = '0' )then
146 217 jshamlet
        Rd_Data              <= RX_FIFO_Rd_Data;
147 207 jshamlet
      end if;
148 217 jshamlet
      RTS_Out                <= not RX_FIFO_AFull;
149 207 jshamlet
    end if;
150
  end process;
151
 
152 213 jshamlet
TX_Disabled : if( Disable_Transmit )generate
153
 
154
  TX_FIFO_Empty              <= '1';
155
  TX_FIFO_AFull              <= '0';
156
  TX_Out                     <= '1';
157
 
158
end generate;
159
 
160
TX_Enabled : if( not Disable_Transmit )generate
161
 
162 223 jshamlet
  TX_FIFO_Wr_En              <= Open8_Bus.Wr_En and
163
                                Addr_Match and
164
                                (not Reg_Addr);
165 207 jshamlet
 
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 223 jshamlet
  RX_FIFO_Rd_En              <= Open8_Bus.Rd_En and
268
                                Addr_Match and
269
                                (not Reg_Addr);
270 207 jshamlet
 
271
  U_RX_FIFO : entity work.fifo_1k_core
272
  port map(
273
    aclr                     => FIFO_Reset,
274
    clock                    => Clock,
275
    data                     => RX_FIFO_Wr_Data,
276
    rdreq                    => RX_FIFO_Rd_En,
277
    wrreq                    => RX_FIFO_Wr_En,
278
    empty                    => RX_FIFO_Empty,
279
    almost_full              => RX_FIFO_AFull,
280
    q                        => RX_FIFO_Rd_Data
281
  );
282
 
283 213 jshamlet
end generate;
284
 
285 207 jshamlet
end architecture;

powered by: WebSVN 2.1.0

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