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

Subversion Repositories System09

[/] [System09/] [rev_86/] [rtl/] [VHDL/] [ACIA_TX.vhd] - Blame information for rev 147

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

Line No. Rev Author Line
1 19 dilbert57
--===========================================================================--
2
--
3
--  S Y N T H E Z I A B L E    ACIA 6850   C O R E
4
--
5
--  www.OpenCores.Org - January 2007
6
--  This core adheres to the GNU public license  
7
--
8
-- Design units   : 6850 ACIA core for the System68/09
9
--
10
-- File name      : ACIA_TX.vhd
11
--
12
-- Purpose        : Implements an ACIA device for communication purposes 
13
--                  between the FPGA processor and the Host computer through
14
--                  a RS-232 communication protocol.
15
--                  
16
-- Dependencies   : ieee.std_logic_1164
17
--                  ieee.numeric_std
18
--                  ieee.std_logic_unsigned
19
--
20
--===========================================================================--
21
-------------------------------------------------------------------------------
22
-- Revision list
23
-- Version  Author        Date                        Changes
24
--
25
-- 0.1      Ovidiu Lupas  15 January 2000    New model
26
-- 2.0      Ovidiu Lupas  17 April   2000    unnecessary variable removed
27
--
28
-- 3.0      John Kent      5 January 2003    added 6850 word format control
29
-- 3.1      John Kent     12 January 2003    Rearranged state machine code
30
-- 3.2      John Kent     30 March 2003      Revamped State machine
31
-- 3.3      John Kent     16 January 2004    Major re-write - added baud rate gen
32
--      4.0      John Kent      3 February 2007   renamed txunit to ACIA_TX
33
-- 4.1      John Kent      4 February 2007   Cleaned up transmiter
34
-- 4.2      John Kent     25 Februauy 2007   Modify sensitivity lists and
35
--                                           split Tx Baud Clock select
36
--                                           and edge detection.
37
--  dilbert57@opencores.org
38
--
39
-------------------------------------------------------------------------------
40
library ieee;
41
use ieee.std_logic_1164.all;
42
use ieee.numeric_std.all;
43
use ieee.std_logic_unsigned.all;
44
 
45
-------------------------------------------------------------------------------
46
-- Entity for the ACIA Transmitter
47
-------------------------------------------------------------------------------
48
entity ACIA_TX is
49
  port (
50
     Clk    : in  Std_Logic;                    -- CPU Clock signal
51
     TxRst  : in  Std_Logic;                    -- Reset input
52
     TxWr   : in  Std_Logic;                    -- Load transmit data
53
     TxDin  : in  Std_Logic_Vector(7 downto 0);  -- Transmit data input.
54
     WdFmt  : in  Std_Logic_Vector(2 downto 0); -- word format
55
     BdFmt  : in  Std_Logic_Vector(1 downto 0); -- baud format
56
     TxClk  : in  Std_Logic;                    -- Enable input
57
     TxDat  : out Std_Logic;                    -- RS-232 data bit output
58
     TxEmp  : out Std_Logic );                  -- Tx buffer empty
59
end ACIA_TX; --================== End of entity ==============================--
60
 
61
-------------------------------------------------------------------------------
62
-- Architecture for  ACIA_TX
63
-------------------------------------------------------------------------------
64
 
65
architecture rtl of ACIA_TX is
66
 
67
  type TxStateType is ( Tx1Stop_State, TxStart_State,
68
                        TxData_State, TxParity_State, Tx2Stop_State );
69
 
70
  -----------------------------------------------------------------------------
71
  -- Signals
72
  -----------------------------------------------------------------------------
73
 
74
  signal TxClkDel   : Std_Logic := '0';             -- Delayed Tx Input Clock
75
  signal TxClkEdge  : Std_Logic := '0';             -- Tx Input Clock Edge pulse
76
  signal TxClkCnt   : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Tx Baud Clock Counter
77
  signal TxBdDel    : Std_Logic := '0';             -- Delayed Tx Baud Clock
78
  signal TxBdEdge   : Std_Logic := '0';             -- Tx Baud Clock Edge pulse
79
  signal TxBdClk    : Std_Logic := '0';             -- Tx Baud Clock
80
  signal TxShiftReg : Std_Logic_Vector(7 downto 0) := (others => '0'); -- Transmit shift register
81
  signal TxParity   : Std_logic := '0';             -- Parity Bit
82
  signal TxBitCount : Std_Logic_Vector(2 downto 0) := (others => '0'); -- Data Bit Counter
83
  signal TxReq      : Std_Logic := '0';             -- Request Transmit
84
  signal TxAck      : Std_Logic := '0';             -- Transmit Commenced
85
  signal TxState    : TxStateType;                                               -- Transmitter state
86
 
87
begin
88
 
89
  ---------------------------------------------------------------------
90
  -- Transmit Clock Edge Detection
91
  -- A falling edge will produce a one clock cycle pulse
92
  ---------------------------------------------------------------------
93
 
94
--  acia_tx_clock_edge : process(Clk, TxRst, TxClk, TxClkDel )
95
  acia_tx_clock_edge : process( TxRst, Clk )
96
  begin
97
    if TxRst = '1' then
98
           TxClkDel  <= '0';
99
                TxClkEdge <= '0';
100
         elsif Clk'event and Clk = '0' then
101
           TxClkDel  <= TxClk;
102
                TxClkEdge <= TxClkDel and (not TxClk);
103
         end if;
104
  end process;
105
 
106
 
107
  ---------------------------------------------------------------------
108
  -- Transmit Clock Divider
109
  -- Advance the count only on an input clock pulse
110
  ---------------------------------------------------------------------
111
 
112
--  acia_tx_clock_divide : process( Clk, TxRst, TxClkEdge, TxClkCnt )
113
  acia_tx_clock_divide : process( TxRst, Clk )
114
  begin
115
    if TxRst = '1' then
116
           TxClkCnt <= "000000";
117
         elsif Clk'event and Clk = '0' then
118
           if TxClkEdge = '1' then
119
                  TxClkCnt <= TxClkCnt + "000001";
120
      end if; -- TxClkEdge
121
         end if;        -- reset / clk
122
  end process;
123
 
124
  ---------------------------------------------------------------------
125
  -- Transmit Baud Clock Selector
126
  ---------------------------------------------------------------------
127
  acia_tx_baud_clock_select : process( BdFmt, TxClk, TxClkCnt )
128
  begin
129
  -- BdFmt
130
  -- 0 0     - Baud Clk divide by 1
131
  -- 0 1     - Baud Clk divide by 16
132
  -- 1 0     - Baud Clk divide by 64
133
  -- 1 1     - reset
134
    case BdFmt is
135
         when "00" =>     -- Div by 1
136
           TxBdClk <= TxClk;
137
         when "01" =>     -- Div by 16
138
           TxBdClk <= TxClkCnt(3);
139
         when "10" =>     -- Div by 64
140
           TxBdClk <= TxClkCnt(5);
141
         when others =>  -- reset
142
           TxBdClk <= '0';
143
    end case;
144
  end process;
145
 
146
  ---------------------------------------------------------------------
147
  -- Transmit Baud Clock Edge Detector
148
  ---------------------------------------------------------------------
149
  --
150
  -- Generate one clock pulse strobe on falling edge of Tx Baud Clock
151
  --
152
--  acia_tx_baud_clock_edge : process(Clk, TxRst, TxBdClk, TxBdDel )
153
  acia_tx_baud_clock_edge : process( TxRst, Clk )
154
  begin
155
    if TxRst = '1' then
156
           TxBdDel  <= '0';
157
                TxBdEdge <= '0';
158
         elsif Clk'event and Clk = '0' then
159
           TxBdDel  <= TxBdClk;
160
                TxBdEdge <= (not TxBdClk) and TxBdDel;
161
         end if;
162
  end process;
163
 
164
 
165
  ---------------------------------------------------------------------
166
  -- Transmitter activation process
167
  ---------------------------------------------------------------------
168
--  acia_tx_write : process(Clk, TxRst, TxWr, TxReq, TxAck )
169
  acia_tx_write : process( TxRst, Clk )
170
  begin
171
     if TxRst = '1' then
172
       TxReq <= '0';
173
       TxEmp <= '1';
174
     elsif Clk'event and Clk = '0' then
175
                 if TxWr = '1' then
176
         -- Write requests transmit
177
                        -- and clears the Empty Flag 
178
                        TxReq <= '1';
179
              TxEmp <= '0';
180
            else
181
         if (TxReq = '1') and (TxAck = '1') then
182
                          -- Once the transmitter is started 
183
                          -- We can clear request.
184
           TxReq <= '0';
185
                   elsif (TxReq = '0') and (TxAck = '0') then
186
                          -- When the transmitter is finished
187
                          -- We can flag transmit empty
188
                          TxEmp <= '1';
189
                   end if;
190
                end if;
191
    end if; -- clk / reset
192
  end process;
193
 
194
  -----------------------------------------------------------------------------
195
  -- Implements the Tx unit
196
  -----------------------------------------------------------------------------
197
  -- WdFmt - Bits[4..2]
198
  -- 0 0 0   - 7 data, even parity, 2 stop
199
  -- 0 0 1   - 7 data, odd  parity, 2 stop
200
  -- 0 1 0   - 7 data, even parity, 1 stop
201
  -- 0 1 1   - 7 data, odd  parity, 1 stop
202
  -- 1 0 0   - 8 data, no   parity, 2 stop
203
  -- 1 0 1   - 8 data, no   parity, 1 stop
204
  -- 1 1 0   - 8 data, even parity, 1 stop
205
  -- 1 1 1   - 8 data, odd  parity, 1 stop
206
--  acia_tx_transmit :  process(TxRst, Clk, TxState, TxDin, WdFmt,  
207
--                              TxShiftReg, TxBdEdge, TxParity, TxBitCount,
208
--                                   TxReq, TxAck )
209
  acia_tx_transmit :  process( TxRst, Clk )
210
  begin
211
         if TxRst = '1' then
212
          TxDat      <= '1';
213
               TxShiftReg <= "00000000";
214
                    TxParity   <= '0';
215
                    TxBitCount <= "000";
216
          TxAck      <= '0';
217
                    TxState    <= Tx1Stop_State;
218
    elsif Clk'event and Clk = '0' then
219
      if TxBdEdge = '1' then
220
        case TxState is
221
        when Tx1Stop_State =>           -- Last Stop bit state
222
          TxDat <= '1';
223
          TxAck <= '0';                                 -- Transmitter halted
224
                    if TxReq = '1' then
225
             TxState <= TxStart_State;
226
                    end if;
227
 
228
        when TxStart_State =>
229
          TxDat      <= '0';            -- Start bit
230
               TxShiftReg <= TxDin;                 -- Load Shift reg with Tx Data
231
                    TxParity   <= '0';
232
                    if WdFmt(2) = '0' then
233
                      TxBitCount <= "110";       -- 7 data + parity
234
               else
235
            TxBitCount <= "111";       -- 8 data
236
               end if;
237
          TxAck      <= '1';                             -- Flag transmit started
238
          TxState    <= TxData_State;
239
 
240
        when TxData_State =>
241
          TxDat       <= TxShiftReg(0);
242
          TxShiftReg  <= '1' & TxShiftReg(7 downto 1);
243
          TxParity    <= TxParity xor TxShiftReg(0);
244
                    TxBitCount  <= TxBitCount - "001";
245
                    if TxBitCount = "000" then
246
                 if (WdFmt(2) = '1') and (WdFmt(1) = '0') then
247
                             if WdFmt(0) = '0' then          -- 8 data bits
248
                TxState <= Tx2Stop_State;     -- 2 stops
249
                             else
250
                                    TxState <= Tx1Stop_State;     -- 1 stop
251
                        end if;
252
                      else
253
                             TxState <= TxParity_State;      -- parity
254
                      end if;
255
                    end if;
256
 
257
        when TxParity_State =>                -- 7/8 data + parity bit
258
               if WdFmt(0) = '0' then
259
                            TxDat <= not( TxParity );        -- even parity
260
                    else
261
                            TxDat <= TxParity;               -- odd parity
262
               end if;
263
                    if WdFmt(1) = '0' then
264
                           TxState <= Tx2Stop_State;         -- 2 stops
265
                    else
266
                           TxState <= Tx1Stop_State;         -- 1 stop
267
                    end if;
268
 
269
        when Tx2Stop_State =>                 -- first of two stop bits
270
          TxDat   <= '1';
271
                    TxState <= Tx1Stop_State;
272
 
273
        when others =>  -- Undefined
274
          TxDat   <= '1';
275
          TxState <= Tx1Stop_State;
276
 
277
        end case; -- TxState
278
 
279
                end if; -- TxBdEdge
280
         end if;         -- clk / reset
281
 
282
  end process;
283
 
284
end rtl; --=================== End of architecture ====================--

powered by: WebSVN 2.1.0

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