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

Subversion Repositories uart6551

[/] [uart6551/] [trunk/] [trunk/] [rtl/] [uart6551Tx_x12.sv] - Blame information for rev 5

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

Line No. Rev Author Line
1 5 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2004-2022  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//
9
// 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
//
13
// 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
// ============================================================================
36
//
37
`define IDLE    0
38
`define CNT             1
39
 
40
//`define UART_NO_TX_FIFO       1'b1
41
 
42
module uart6551Tx_x12 (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 [11:0] din;               // fifo data in
53
output ack;
54
 
55
input fifoEnable;
56
input fifoClear;
57
input txBreak;
58
input [8: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 [11:0] t1;
70
reg [15:0] t2;
71
reg [15:0] tx_data;     // transmit data working reg (raw)
72
reg state;                      // state machine state
73
reg [8:0] cnt;          // baud clock counter
74
reg rd;
75
reg p1, p2;                     // parity bit
76
 
77
assign ack = cyc & cs;
78
edge_det ued1 (.rst(rst), .clk(clk), .ce(1'b1), .i(ack & wr), .pe(awr), .ne(), .ee());
79
 
80
`ifdef UART_NO_TX_FIFO
81
reg [11:0] fdo2;
82
reg empty;
83
 
84
always_ff @(posedge clk)
85
        if (awr) fdo2 <= {3'd0,din};
86
 
87
always_ff @(posedge clk)
88
        begin
89
                if (awr) empty <= 0;
90
                else if (rd) empty <= 1;
91
        end
92
 
93
assign full = ~empty;
94
wire [11:0] fdo = fdo2;
95
`else
96
reg [11:0] fdo2;
97
always_ff @(posedge clk)
98
        if (awr) fdo2 <= {3'd0,din};
99
// generate an empty signal for when the fifo is disabled
100
reg fempty2;
101
always_ff @(posedge clk)
102
        if (rst)
103
                fempty2 <= 1;
104
        else begin
105
                if (awr) fempty2 <= 0;
106
                else if (rd) fempty2 <= 1;
107
        end
108
 
109
 
110
wire [11:0] fdo1;               // fifo data output
111
wire rdf = fifoEnable ? rd : awr;
112
wire fempty;
113
wire ffull;
114
uart6551Fifo #(.WID(12)) fifo0
115
(
116
  .clk(clk),
117
  .rst(rst|clear|fifoClear),
118
  .din(din),
119
  .wr(awr),
120
  .rd(rdf),
121
  .dout(fdo1),
122
  .full(ffull),
123
  .empty(fempty),
124
  .ctr(qcnt)
125
);
126
assign empty = fifoEnable ? fempty : fempty2;
127
assign full = fifoEnable ? ffull : ~fempty2;
128
wire [11:0] fdo = fifoEnable ? fdo1 : fdo2;
129
`endif
130
 
131
// mask transmit data for word length
132
// this mask is needed for proper parity generation
133
integer n;
134
reg [11:0] mask;
135
always @*
136
        for (n = 0; n < 12; n = n + 1)
137
                mask[n] = n < wordLength ? 1'b1 : 1'b0;
138
 
139
always_comb
140
if (txBreak)
141
        t1 <= 0;
142
else
143
        t1 <= fdo & mask;
144
 
145
 
146
// compute parity bit
147
always_comb
148
begin
149
        case (parityCtrl)
150
        3'b001: p1 <= ~^t1;// odd parity
151
        3'b011: p1 <= ^t1;      // even parity
152
        3'b101: p1 <= 1;        // mark bit
153
        3'b111: p1 <= 0;        // space bit
154
        default: p1 <= 1;       // stop bit when no parity
155
        endcase
156
end
157
 
158
/*
159
Could pipeline this, but then watch out for empty signal control
160
always @(posedge clk)
161
        if (ce) t2 <= t1;
162
 
163
always @(posedge clk)
164
        if (ce) p2 <= p1;
165
*/
166
// Insert start, parity bit and stop
167
always_comb
168
case(wordLength)
169
4'd4:   t2 <= {10'h3FF,p1,t1[3:0],1'b0};
170
4'd5:   t2 <= {9'h1FF,p1,t1[4:0],1'b0};
171
4'd6:   t2 <= {8'hFF,p1,t1[5:0],1'b0};
172
4'd7:   t2 <= {7'h7F,p1,t1[6:0],1'b0};
173
4'd8:   t2 <= {6'h3F,p1,t1[7:0],1'b0};
174
4'd9:   t2 <= {5'b11111,p1,t1[8:0],1'b0};
175
4'd10:  t2 <= {4'b1111,p1,t1[9:0],1'b0};
176
4'd11:  t2 <= {3'b111,p1,t1[10:0],1'b0};
177
4'd12:  t2 <= {2'b11,p1,t1[11:0],1'b0};
178
default:        t2 <= {6'h3F,p1,t1[7:0],1'b0};
179
endcase
180
 
181
always_ff @(posedge clk)
182
if (rst)
183
        state <= `IDLE;
184
else begin
185
        if (clear)
186
                state <= `IDLE;
187
        if (baud16x_ce) begin
188
                case(state)
189
                `IDLE:
190
                        if ((!empty && cts)||txBreak)
191
                                state <= `CNT;
192
                `CNT:
193
                        if (cnt==frameSize)
194
                                state <= `IDLE;
195
                endcase
196
        end
197
end
198
 
199
always_ff @(posedge clk)
200
if (rst)
201
        cnt <= 9'h00;
202
else begin
203
        if (clear)
204
                cnt <= 9'h00;
205
        if (baud16x_ce) begin
206
                case(state)
207
                `IDLE:
208
                        cnt <= 9'h00;
209
                `CNT:
210
                        cnt <= cnt + 2'd1;
211
                endcase
212
        end
213
end
214
 
215
always_ff @(posedge clk)
216
if (rst)
217
        rd <= 0;
218
else begin
219
        rd <= 0;
220
        if (clear)
221
                rd <= 0;
222
        if (baud16x_ce) begin
223
                case(state)
224
                `IDLE:
225
                        if ((!empty && cts)||txBreak)
226
                                rd <= 1;
227
                endcase
228
        end
229
end
230
 
231
always_ff @(posedge clk)
232
if (rst)
233
        tx_data <= 16'hFFFF;
234
else begin
235
        if (baud16x_ce) begin
236
                case(state)
237
                `IDLE:
238
                        if ((!empty && cts)||txBreak)
239
                                tx_data <= t2;
240
                `CNT:
241
                        // Shift the data out. LSB first.
242
                        if (cnt[3:0]==4'hF)
243
                                tx_data <= {1'b1,tx_data[15:1]};
244
                endcase
245
        end
246
end
247
 
248
always_ff @(posedge clk)
249
if (rst)
250
        txd <= 1'b1;
251
else
252
        txd <= tx_data[0];
253
 
254
endmodule

powered by: WebSVN 2.1.0

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