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

Subversion Repositories uart6551

[/] [uart6551/] [trunk/] [trunk/] [rtl/] [uart6551Tx.sv] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2004-2019  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//
9
// This source file is free software: you can redistribute it and/or modify
10
// it under the terms of the GNU Lesser General Public License as published
11
// by the Free Software Foundation, either version 3 of the License, or
12
// (at your option) any later version.
13
//
14
// This source file is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
// GNU General Public License for more details.
18
//
19
// You should have received a copy of the GNU General Public License
20
// along with this program.  If not, see .
21
//
22
// ============================================================================
23
//
24
`define IDLE    0
25
`define CNT             1
26
 
27
module uart6551Tx(rst, clk, cyc, cs, wr, din, ack,
28
        fifoEnable, fifoClear, txBreak,
29
        frameSize, wordLength, parityCtrl, baud16x_ce,
30
        cts, clear, txd, full, empty, qcnt);
31
 
32
input rst;
33
input clk;
34
input cyc;                      // bus cycle valid
35
input cs;                       // core select
36
input wr;                       // write transmitter
37
input [7:0] din;                // fifo data in
38
output ack;
39
 
40
input fifoEnable;
41
input fifoClear;
42
input txBreak;
43
input [7:0] frameSize;
44
input [3:0] wordLength;
45
input [2:0] parityCtrl;
46
input baud16x_ce;       // baud rate clock enable
47
input cts;                      // clear to send
48
input clear;            // clear transmitter
49
output reg txd;         // external serial output
50
output full;            // fifo is full
51
output empty;           // fifo is empty
52
output [3:0] qcnt;      // number of characters queued
53
 
54
reg [7:0] t1;
55
reg [11:0] t2;
56
reg [11:0] tx_data;     // transmit data working reg (raw)
57
reg state;                      // state machine state
58
reg [7:0] cnt;          // baud clock counter
59
reg rd;
60
reg p1, p2;                     // parity bit
61
 
62
assign ack = cyc & cs;
63
edge_det ued1 (.rst(rst), .clk(clk), .ce(1'b1), .i(ack & wr), .pe(awr), .ne(), .ee());
64
 
65
`ifdef UART_NO_TX_FIFO
66
reg [7:0] fdo;
67
reg empty;
68
 
69
always @(posedge clk)
70
        if (awr) fdo <= {3'd0,din};
71
 
72
always @(posedge clk)
73
        begin
74
                if (awr) empty <= 0;
75
                else if (rd) empty <= 1;
76
        end
77
 
78
assign full = ~empty;
79
`else
80
// generate an empty signal for when the fifo is disabled
81
reg fempty2;
82
always @(posedge clk)
83
        if (rst)
84
                fempty2 <= 1;
85
        else begin
86
                if (awr) fempty2 <= 0;
87
                else if (rd) fempty2 <= 1;
88
        end
89
 
90
 
91
wire [7:0] fdo;         // fifo data output
92
wire rdf = fifoEnable ? rd : awr;
93
wire fempty;
94
wire ffull;
95
uart6551Fifo #(.WID(8)) fifo0
96
(
97
  .clk(clk),
98
  .rst(rst|clear|fifoClear),
99
  .din(din),
100
  .wr(awr),
101
  .rd(rdf),
102
  .dout(fdo),
103
  .full(ffull),
104
  .empty(fempty),
105
  .ctr(qcnt)
106
);
107
assign empty = fifoEnable ? fempty : fempty2;
108
assign full = fifoEnable ? ffull : ~fempty2;
109
`endif
110
 
111
 
112
// mask transmit data for word length
113
// this mask is needed for proper parity generation
114
integer n;
115
reg [7:0] mask;
116
always @*
117
        for (n = 0; n < 8; n = n + 1)
118
                mask[n] = n < wordLength ? 1'b1 : 1'b0;
119
 
120
always @*
121
if (txBreak)
122
        t1 <= 0;
123
else
124
        t1 <= fdo & mask;
125
 
126
 
127
// compute parity bit
128
always @*
129
begin
130
        case (parityCtrl)
131
        3'b001: p1 <= ~^t1;// odd parity
132
        3'b011: p1 <= ^t1;      // even parity
133
        3'b101: p1 <= 1;        // mark bit
134
        3'b111: p1 <= 0;        // space bit
135
        default: p1 <= 1;       // stop bit when no parity
136
        endcase
137
end
138
 
139
/*
140
Could pipeline this, but then watch out for empty signal control
141
always @(posedge clk)
142
        if (ce) t2 <= t1;
143
 
144
always @(posedge clk)
145
        if (ce) p2 <= p1;
146
*/
147
// Insert start, parity bit and stop
148
always @*
149
case(wordLength)
150
4'd5:   t2 <= {5'b11111,p1,t1[4:0],1'b0};
151
4'd6:   t2 <= {4'b1111,p1,t1[5:0],1'b0};
152
4'd7:   t2 <= {3'b111,p1,t1[6:0],1'b0};
153
default:        t2 <= {2'b11,p1,t1[7:0],1'b0};
154
endcase
155
 
156
always @(posedge clk)
157
if (rst)
158
        state <= `IDLE;
159
else begin
160
        if (clear)
161
                state <= `IDLE;
162
        if (baud16x_ce) begin
163
                case(state)
164
                `IDLE:
165
                        if ((!empty && cts)||txBreak)
166
                                state <= `CNT;
167
                `CNT:
168
                        if (cnt==frameSize)
169
                                state <= `IDLE;
170
                endcase
171
        end
172
end
173
 
174
always @(posedge clk)
175
if (rst)
176
        cnt <= 8'h00;
177
else begin
178
        if (clear)
179
                cnt <= 8'h00;
180
        if (baud16x_ce) begin
181
                case(state)
182
                `IDLE:
183
                        cnt <= 8'h00;
184
                `CNT:
185
                        cnt <= cnt + 8'd1;
186
                endcase
187
        end
188
end
189
 
190
always @(posedge clk)
191
if (rst)
192
        rd <= 0;
193
else begin
194
        rd <= 0;
195
        if (clear)
196
                rd <= 0;
197
        if (baud16x_ce) begin
198
                case(state)
199
                `IDLE:
200
                        if ((!empty && cts)||txBreak)
201
                                rd <= 1;
202
                endcase
203
        end
204
end
205
 
206
always @(posedge clk)
207
if (rst)
208
        tx_data <= 12'hFFF;
209
else begin
210
        if (baud16x_ce) begin
211
                case(state)
212
                `IDLE:
213
                        if ((!empty && cts)||txBreak)
214
                                tx_data <= t2;
215
                `CNT:
216
                        // Shift the data out. LSB first.
217
                        if (cnt[3:0]==4'hF)
218
                                tx_data <= {1'b1,tx_data[11:1]};
219
                endcase
220
        end
221
end
222
 
223
always @(posedge clk)
224
if (rst)
225
        txd <= 1'b1;
226
else
227
        txd <= tx_data[0];
228
 
229
endmodule

powered by: WebSVN 2.1.0

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