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

Subversion Repositories uart6551

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 robfinch
// ============================================================================
2
//        __
3 13 robfinch
//   \\__/ o\    (C) 2004-2023  Robert Finch, Waterloo
4 2 robfinch
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//
9 8 robfinch
// BSD 3-Clause License
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12 2 robfinch
//
13 8 robfinch
// 1. Redistributions of source code must retain the above copyright notice, this
14
//    list of conditions and the following disclaimer.
15
//
16
// 2. Redistributions in binary form must reproduce the above copyright notice,
17
//    this list of conditions and the following disclaimer in the documentation
18
//    and/or other materials provided with the distribution.
19
//
20
// 3. Neither the name of the copyright holder nor the names of its
21
//    contributors may be used to endorse or promote products derived from
22
//    this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
//
35 2 robfinch
// ============================================================================
36
//
37
`define IDLE    0
38
`define CNT             1
39
 
40 9 robfinch
`define UART_NO_TX_FIFO 1'b1
41 3 robfinch
 
42 2 robfinch
module uart6551Tx(rst, clk, cyc, cs, wr, din, ack,
43
        fifoEnable, fifoClear, txBreak,
44
        frameSize, wordLength, parityCtrl, baud16x_ce,
45
        cts, clear, txd, full, empty, qcnt);
46
 
47
input rst;
48
input clk;
49
input cyc;                      // bus cycle valid
50
input cs;                       // core select
51
input wr;                       // write transmitter
52
input [7:0] din;                // fifo data in
53
output ack;
54
 
55
input fifoEnable;
56
input fifoClear;
57
input txBreak;
58
input [7:0] frameSize;
59
input [3:0] wordLength;
60
input [2:0] parityCtrl;
61
input baud16x_ce;       // baud rate clock enable
62
input cts;                      // clear to send
63
input clear;            // clear transmitter
64
output reg txd;         // external serial output
65
output full;            // fifo is full
66
output empty;           // fifo is empty
67
output [3:0] qcnt;      // number of characters queued
68
 
69
reg [7:0] t1;
70
reg [11:0] t2;
71
reg [11:0] tx_data;     // transmit data working reg (raw)
72 9 robfinch
typedef enum logic {
73
        IDLE = 1'b0,
74
        XMIT
75
} state_t;
76
state_t state;          // state machine state
77 2 robfinch
reg [7:0] cnt;          // baud clock counter
78
reg rd;
79
reg p1, p2;                     // parity bit
80
 
81
assign ack = cyc & cs;
82
edge_det ued1 (.rst(rst), .clk(clk), .ce(1'b1), .i(ack & wr), .pe(awr), .ne(), .ee());
83
 
84
`ifdef UART_NO_TX_FIFO
85 3 robfinch
reg [7:0] fdo2;
86 2 robfinch
reg empty;
87
 
88 9 robfinch
always_ff @(posedge clk)
89 3 robfinch
        if (awr) fdo2 <= {3'd0,din};
90 2 robfinch
 
91 9 robfinch
always_ff @(posedge clk)
92 13 robfinch
if (rst)
93
        empty <= 1;
94
else begin
95
        if (awr) empty <= 0;
96
        else if (rd) empty <= 1;
97
end
98 2 robfinch
 
99
assign full = ~empty;
100 3 robfinch
wire [7:0] fdo = fdo2;
101 2 robfinch
`else
102 3 robfinch
reg [7:0] fdo2;
103 9 robfinch
always_ff @(posedge clk)
104 3 robfinch
        if (awr) fdo2 <= {3'd0,din};
105 2 robfinch
// generate an empty signal for when the fifo is disabled
106
reg fempty2;
107 9 robfinch
always_ff @(posedge clk)
108 13 robfinch
if (rst)
109
        fempty2 <= 1;
110
else begin
111
        if (awr) fempty2 <= 0;
112
        else if (rd) fempty2 <= 1;
113
end
114 2 robfinch
 
115 3 robfinch
wire [7:0] fdo1;                // fifo data output
116 2 robfinch
wire rdf = fifoEnable ? rd : awr;
117
wire fempty;
118
wire ffull;
119
uart6551Fifo #(.WID(8)) fifo0
120
(
121
  .clk(clk),
122
  .rst(rst|clear|fifoClear),
123
  .din(din),
124
  .wr(awr),
125
  .rd(rdf),
126 3 robfinch
  .dout(fdo1),
127 2 robfinch
  .full(ffull),
128
  .empty(fempty),
129
  .ctr(qcnt)
130
);
131
assign empty = fifoEnable ? fempty : fempty2;
132
assign full = fifoEnable ? ffull : ~fempty2;
133 3 robfinch
wire [7:0] fdo = fifoEnable ? fdo1 : fdo2;
134 2 robfinch
`endif
135
 
136
// mask transmit data for word length
137
// this mask is needed for proper parity generation
138
integer n;
139
reg [7:0] mask;
140 9 robfinch
always_comb
141 2 robfinch
        for (n = 0; n < 8; n = n + 1)
142
                mask[n] = n < wordLength ? 1'b1 : 1'b0;
143
 
144 9 robfinch
always_comb
145 2 robfinch
if (txBreak)
146
        t1 <= 0;
147
else
148
        t1 <= fdo & mask;
149
 
150
 
151
// compute parity bit
152 9 robfinch
always_comb
153 2 robfinch
begin
154
        case (parityCtrl)
155
        3'b001: p1 <= ~^t1;// odd parity
156
        3'b011: p1 <= ^t1;      // even parity
157
        3'b101: p1 <= 1;        // mark bit
158
        3'b111: p1 <= 0;        // space bit
159
        default: p1 <= 1;       // stop bit when no parity
160
        endcase
161
end
162
 
163
/*
164
Could pipeline this, but then watch out for empty signal control
165
always @(posedge clk)
166
        if (ce) t2 <= t1;
167
 
168
always @(posedge clk)
169
        if (ce) p2 <= p1;
170
*/
171
// Insert start, parity bit and stop
172 9 robfinch
always_comb
173 2 robfinch
case(wordLength)
174
4'd5:   t2 <= {5'b11111,p1,t1[4:0],1'b0};
175
4'd6:   t2 <= {4'b1111,p1,t1[5:0],1'b0};
176
4'd7:   t2 <= {3'b111,p1,t1[6:0],1'b0};
177
default:        t2 <= {2'b11,p1,t1[7:0],1'b0};
178
endcase
179
 
180 9 robfinch
always_ff @(posedge clk)
181 2 robfinch
if (rst)
182 9 robfinch
        state <= IDLE;
183 2 robfinch
else begin
184
        if (clear)
185 9 robfinch
                state <= IDLE;
186 2 robfinch
        if (baud16x_ce) begin
187
                case(state)
188 9 robfinch
                IDLE:
189
                        if (((!empty && cts)||txBreak) && cnt==frameSize)
190
                                state <= XMIT;
191
                XMIT:
192
                        if (cnt==frameSize-1)
193
                                state <= IDLE;
194 2 robfinch
                endcase
195
        end
196
end
197
 
198 9 robfinch
always_ff @(posedge clk)
199 2 robfinch
if (rst)
200
        cnt <= 8'h00;
201
else begin
202
        if (clear)
203
                cnt <= 8'h00;
204
        if (baud16x_ce) begin
205 9 robfinch
                if (cnt==frameSize)
206
                        cnt <= 8'h0;
207
                else
208 2 robfinch
                        cnt <= cnt + 8'd1;
209
        end
210
end
211
 
212 9 robfinch
always_ff @(posedge clk)
213 2 robfinch
if (rst)
214
        rd <= 0;
215
else begin
216
        rd <= 0;
217
        if (clear)
218
                rd <= 0;
219 9 robfinch
        if (baud16x_ce)
220 2 robfinch
                case(state)
221 9 robfinch
                IDLE:
222
                        if (((!empty && cts)||txBreak) && cnt==frameSize)
223 2 robfinch
                                rd <= 1;
224 9 robfinch
                default:        ;
225 2 robfinch
                endcase
226
end
227
 
228 9 robfinch
always_ff @(posedge clk)
229 2 robfinch
if (rst)
230
        tx_data <= 12'hFFF;
231
else begin
232
        if (baud16x_ce) begin
233
                case(state)
234 9 robfinch
                IDLE:
235
                        if (((!empty && cts)||txBreak) && cnt==frameSize)
236 2 robfinch
                                tx_data <= t2;
237 9 robfinch
                XMIT:
238 2 robfinch
                        // Shift the data out. LSB first.
239
                        if (cnt[3:0]==4'hF)
240
                                tx_data <= {1'b1,tx_data[11:1]};
241
                endcase
242
        end
243
end
244
 
245 9 robfinch
always_ff @(posedge clk)
246 2 robfinch
if (rst)
247
        txd <= 1'b1;
248
else
249
        txd <= tx_data[0];
250
 
251
endmodule

powered by: WebSVN 2.1.0

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