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

Subversion Repositories System11

[/] [System11/] [trunk/] [rtl/] [vhdl/] [txunit3.vhd] - Blame information for rev 7

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

Line No. Rev Author Line
1 4 dilbert57
--===========================================================================--
2
--
3
--  S Y N T H E Z I A B L E    miniUART   C O R E
4
--
5
--  www.OpenCores.Org - January 2000
6
--  This core adheres to the GNU public license  
7
--
8
-- Design units   : miniUART core for the System68
9
--
10
-- File name      : txunit2.vhd
11
--
12
-- Purpose        : Implements an miniUART device for communication purposes 
13
--                  between the CPU68 processor and the Host computer through
14
--                  an RS-232 communication protocol.
15
--                  
16
-- Dependencies   : IEEE.Std_Logic_1164
17
--
18
--===========================================================================--
19
-------------------------------------------------------------------------------
20
-- Revision list
21
-- Version   Author                 Date                        Changes
22
--
23
-- 0.1      Ovidiu Lupas       15 January 2000                 New model
24
-- 2.0      Ovidiu Lupas       17 April   2000    unnecessary variable removed
25
--  olupas@opencores.org
26
--
27
-- 3.0      John Kent           5 January 2003    added 6850 word format control
28
-- 3.1      John Kent          12 January 2003    Rearranged state machine code
29
-- 3.2      John Kent          30 March 2003      Revamped State machine
30
-- 3.3      John Kent          16 January 2004    Major re-write - added baud rate gen
31
--
32
--  dilbert57@opencores.org
33
--
34
-------------------------------------------------------------------------------
35
-- Description    : 
36
-------------------------------------------------------------------------------
37
-- Entity for the Tx Unit                                                    --
38
-------------------------------------------------------------------------------
39
library ieee;
40
use ieee.std_logic_1164.all;
41
use ieee.numeric_std.all;
42
use ieee.std_logic_unsigned.all;
43
 
44
-------------------------------------------------------------------------------
45
-- Transmitter unit
46
-------------------------------------------------------------------------------
47
entity TxUnit is
48
  port (
49
     Clk    : in  Std_Logic;  -- Clock signal
50
     Reset  : in  Std_Logic;  -- Reset input
51
     LoadD  : in  Std_Logic;  -- Load transmit data
52
     DAIn   : in  Std_Logic_Vector(7 downto 0);
53
     WdFmt  : in  Std_Logic_Vector(2 downto 0); -- word format
54
     BdFmt  : in  Std_Logic_Vector(1 downto 0); -- baud format
55
     TxClk  : in  Std_Logic;  -- Enable input
56
     TxDat  : out Std_Logic;  -- RS-232 data output
57
     TBE    : out Std_Logic );  -- Tx buffer empty
58
end; --================== End of entity ==============================--
59
-------------------------------------------------------------------------------
60
-- Architecture for TxUnit
61
-------------------------------------------------------------------------------
62
architecture Behaviour of TxUnit is
63
  type TxStateType is ( TxIdle_State, Start_State, Data_State, Parity_State, Stop_State );
64
  -----------------------------------------------------------------------------
65
  -- Signals
66
  -----------------------------------------------------------------------------
67
  signal TxClkDel  : Std_Logic;             -- Delayed Tx Input Clock
68
  signal TxClkEdge : Std_Logic;             -- Tx Input Clock Edge pulse
69
  signal TxClkCnt  : Std_Logic_Vector(5 downto 0); -- Tx Baud Clock Counter
70
  signal TxBdDel   : Std_Logic;             -- Delayed Tx Baud Clock
71
  signal TxBdEdge  : Std_Logic;             -- Tx Baud Clock Edge pulse
72
  signal TxBdClk    : Std_Logic;            -- Tx Baud Clock
73
 
74
  signal TBuff     : Std_Logic_Vector(7 downto 0); -- transmit buffer
75
  signal TBufE     : Std_Logic;                    -- Transmit Buffer Empty
76
 
77
  signal TReg      : Std_Logic_Vector(7 downto 0); -- transmit register
78
  signal TxParity  : Std_logic;                    -- Parity Bit
79
  signal DataCnt   : Std_Logic_Vector(3 downto 0); -- Data Bit Counter
80
  signal TRegE     : Std_Logic;                    --  Transmit Register empty
81
  signal TRegEDel  : Std_Logic;                    --  Transmit Register empty
82
  signal TRegEEdge : Std_Logic;
83
  signal TxState   : TxStateType;
84
  signal TxDbit    : Std_Logic;
85
begin
86
 
87
  ---------------------------------------------------------------------
88
  -- Transmit Clock Edge Detection
89
  -- A falling edge will produce a one clock cycle pulse
90
  ---------------------------------------------------------------------
91
  txunit_clock_edge : process(Clk, Reset, TxClk, TxClkDel )
92
  begin
93
    if Reset = '1' then
94
           TxClkDel  <= TxClk;
95
                TxClkEdge <= '0';
96
         elsif Clk'event and Clk = '0' then
97
           TxClkDel  <= TxClk;
98
                TxClkEdge <= TxClkDel and (not TxClk);
99
         end if;
100
  end process;
101
 
102
 
103
  ---------------------------------------------------------------------
104
  -- Transmit Clock Divider
105
  -- Advance the count only on an input clock pulse
106
  ---------------------------------------------------------------------
107
  txunit_clock_divide : process(Clk, Reset, TxClkEdge, TxClkCnt )
108
  begin
109
    if Reset = '1' then
110
           TxClkCnt <= "000000";
111
         elsif Clk'event and Clk = '0' then
112
           if TxClkEdge = '1' then
113
                  TxClkCnt <= TxClkCnt + "000001";
114
      else
115
                  TxClkCnt <= TxClkCnt;
116
      end if; -- TxClkEdge
117
         end if;        -- reset / clk
118
  end process;
119
 
120
  ---------------------------------------------------------------------
121
  -- Receiver Clock Selector
122
  -- Select output then look for rising edge
123
  ---------------------------------------------------------------------
124
  txunit_clock_select : process(Clk, Reset, BdFmt, TxClk, TxClkCnt,
125
                                TxBdDel, TxBdEdge )
126
  begin
127
  -- BdFmt
128
  -- 0 0     - Baud Clk divide by 1
129
  -- 0 1     - Baud Clk divide by 16
130
  -- 1 0     - Baud Clk divide by 64
131
  -- 1 1     - reset
132
    case BdFmt is
133
         when "00" =>     -- Div by 1
134
           TxBdClk <= TxClk;
135
         when "01" =>     -- Div by 16
136
           TxBdClk <= TxClkCnt(3);
137
         when "10" =>     -- Div by 64
138
           TxBdClk <= TxClkCnt(5);
139
         when others =>  -- reset
140
           TxBdClk <= '0';
141
    end case;
142
 
143
    if Reset = '1' then
144
           TxBdDel  <= TxBdClk;
145
                TxBdEdge <= '0';
146
         elsif Clk'event and Clk = '0' then
147
           TxBdDel  <= TxBdClk;
148
                TxBdEdge <= TxBdClk and (not TxBdDel);
149
         end if;
150
  end process;
151
 
152
  ---------------------------------------------------------------------
153
  -- Transmit Buffer Empty Edge
154
  -- generate a negative edge pulse
155
  ---------------------------------------------------------------------
156
  txunit_busy : process(Clk, Reset, TRegE, TRegEDel )
157
  begin
158
     if Reset = '1' then
159
              TRegEDel  <= '0';
160
                        TRegEEdge <= '0';
161
     elsif Clk'event and Clk = '0' then
162
            TRegEDel  <= TRegE;
163
                 TRegEEdge <= TregEDel and (not TRegE ); -- falling edge
164
     end if;
165
   end process;
166
 
167
  ---------------------------------------------------------------------
168
  -- Transmitter activation process
169
  ---------------------------------------------------------------------
170
  txunit_write : process(Clk, Reset, LoadD, DAIn, TBufE, TRegEEdge )
171
  begin
172
     if Reset = '1' then
173
           TBufE   <= '1';
174
                          TBuff   <= "00000000";
175
     elsif Clk'event and Clk = '0' then
176
                     if LoadD = '1' then
177
                            TBuff <= DAIn;
178
             TBufE <= '0';
179
                          else
180
                            TBuff <= TBuff;
181
             if (TBufE = '0') and (TRegEEdge = '1') then
182
                                   -- Once the transmitter is started 
183
                                        -- We can flag the buffer empty again.
184
               TBufE <= '1';
185
                                 else
186
               TBufE <= TBufE;
187
                                 end if;
188
                          end if;
189
    end if; -- clk / reset
190
    TBE <= TBufE;
191
 
192
  end process;
193
 
194
  -----------------------------------------------------------------------------
195
  -- Implements the Tx unit
196
  -----------------------------------------------------------------------------
197
  txunit_transmit :  process(Reset, Clk, TxState, TxDbit, TBuff, TReg,
198
                             TxBdEdge, TxParity, DataCnt, WdFmt,
199
                                                                          TBufE, TRegE )
200
  begin
201
         if Reset = '1' then
202
          TxDbit   <= '1';
203
               TReg     <= "00000000";
204
                    TxParity <= '0';
205
                    DataCnt  <= "0000";
206
          TRegE    <= '1';
207
                    TxState  <= TxIdle_State;
208
    elsif Clk'event and Clk = '0' then
209
      if TxBdEdge = '1' then
210
        case TxState is
211
        when TxIdle_State =>  -- TxIdle_State (also 1st or 2nd Stop bit)
212
          TxDbit     <= '1';
213
               TReg       <= TBuff;
214
                    TxParity   <= '0';
215
                    DataCnt    <= "0000";
216
          TRegE      <= '1';
217
                    if TBufE = '0' then
218
             TxState <= Start_State;
219
               else
220
             TxState <= TxIdle_State;
221
                    end if;
222
 
223
        when Start_State =>
224
          TxDbit   <= '0';           -- Start bit
225
                    TReg     <= TReg;
226
               TxParity <= '0';
227
                    if WdFmt(2) = '0' then
228
                      DataCnt <= "0110";       -- 7 data + parity
229
               else
230
            DataCnt <= "0111";       -- 8 data
231
               end if;
232
          TRegE    <= '0';
233
          TxState  <= Data_State;
234
 
235
        when Data_State =>
236
          TxDbit   <= TReg(0);
237
          TReg     <= '1' & TReg(7 downto 1);
238
          TxParity <= TxParity xor TReg(0);
239
          TRegE    <= '0';
240
                    DataCnt  <= DataCnt - "0001";
241
                    if DataCnt = "0000" then
242
                 if (WdFmt(2) = '1') and (WdFmt(1) = '0') then
243
                             if WdFmt(0) = '0' then         -- 8 data bits
244
                TxState <= Stop_State;       -- 2 stops
245
                             else
246
                                    TxState <= TxIdle_State;     -- 1 stop
247
                        end if;
248
                      else
249
                             TxState <= Parity_State;       -- parity
250
                      end if;
251
                 else
252
            TxState  <= Data_State;
253
                    end if;
254
 
255
        when Parity_State =>           -- 7/8 data + parity bit
256
               if WdFmt(0) = '0' then
257
                            TxDbit <= not( TxParity );   -- even parity
258
                    else
259
                            TXDbit <= TxParity;          -- odd parity
260
               end if;
261
                    Treg     <= Treg;
262
                    TxParity <= '0';
263
          TRegE    <= '0';
264
                    DataCnt  <= "0000";
265
                    if WdFmt(1) = '0' then
266
                           TxState <= Stop_State; -- 2 stops
267
                    else
268
                           TxState <= TxIdle_State; -- 1 stop
269
                    end if;
270
 
271
        when Stop_State => -- first stop bit
272
          TxDbit     <= '1';           -- 2 stop bits
273
               Treg       <= Treg;
274
                    TxParity   <= '0';
275
                    DataCnt    <= "0000";
276
          TRegE      <= '0';
277
                    TxState    <= TxIdle_State;
278
 
279
        when others =>  -- Undefined
280
          TxDbit     <= TxDbit;
281
               Treg       <= Treg;
282
                    TxParity   <= '0';
283
                    DataCnt    <= "0000";
284
          TRegE      <= TregE;
285
          TxState    <= TxIdle_State;
286
 
287
        end case; -- TxState
288
 
289
                else -- TxBdEdge
290
                  TxDbit   <= TxDbit;
291
             TReg     <= TReg;
292
                  TxParity <= TxParity;
293
                  DataCnt  <= DataCnt;
294
        TRegE    <= TRegE;
295
                  TxState  <= TxState;
296
                end if; -- TxBdEdge
297
         end if;         -- clk / reset
298
 
299
         TxDat <= TxDbit;
300
  end process;
301
 
302
end Behaviour; --=================== End of architecture ====================--

powered by: WebSVN 2.1.0

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