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

Subversion Repositories uart6551

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

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 6 robfinch
`define READ1   1
39
`define READ2   2
40
`define CNT             3
41 5 robfinch
 
42
//`define UART_NO_TX_FIFO       1'b1
43
 
44
module uart6551Tx_x12 (rst, clk, cyc, cs, wr, din, ack,
45
        fifoEnable, fifoClear, txBreak,
46
        frameSize, wordLength, parityCtrl, baud16x_ce,
47
        cts, clear, txd, full, empty, qcnt);
48
 
49
input rst;
50
input clk;
51
input cyc;                      // bus cycle valid
52
input cs;                       // core select
53
input wr;                       // write transmitter
54
input [11:0] din;               // fifo data in
55
output ack;
56
 
57
input fifoEnable;
58
input fifoClear;
59
input txBreak;
60
input [8:0] frameSize;
61
input [3:0] wordLength;
62
input [2:0] parityCtrl;
63
input baud16x_ce;       // baud rate clock enable
64
input cts;                      // clear to send
65
input clear;            // clear transmitter
66
output reg txd;         // external serial output
67
output full;            // fifo is full
68
output empty;           // fifo is empty
69 6 robfinch
output [5:0] qcnt;      // number of characters queued
70 5 robfinch
 
71
reg [11:0] t1;
72
reg [15:0] t2;
73
reg [15:0] tx_data;     // transmit data working reg (raw)
74 6 robfinch
reg [1:0] state;                // state machine state
75 5 robfinch
reg [8:0] cnt;          // baud clock counter
76
reg rd;
77
reg p1, p2;                     // parity bit
78
 
79
assign ack = cyc & cs;
80
edge_det ued1 (.rst(rst), .clk(clk), .ce(1'b1), .i(ack & wr), .pe(awr), .ne(), .ee());
81
 
82
`ifdef UART_NO_TX_FIFO
83
reg [11:0] fdo2;
84
reg empty;
85
 
86
always_ff @(posedge clk)
87
        if (awr) fdo2 <= {3'd0,din};
88
 
89
always_ff @(posedge clk)
90
        begin
91
                if (awr) empty <= 0;
92
                else if (rd) empty <= 1;
93
        end
94
 
95
assign full = ~empty;
96
wire [11:0] fdo = fdo2;
97
`else
98
reg [11:0] fdo2;
99
always_ff @(posedge clk)
100 6 robfinch
        if (awr) fdo2 <= din;
101 5 robfinch
// generate an empty signal for when the fifo is disabled
102
reg fempty2;
103
always_ff @(posedge clk)
104
        if (rst)
105
                fempty2 <= 1;
106
        else begin
107
                if (awr) fempty2 <= 0;
108
                else if (rd) fempty2 <= 1;
109
        end
110
 
111
 
112
wire [11:0] fdo1;               // fifo data output
113
wire rdf = fifoEnable ? rd : awr;
114
wire fempty;
115
wire ffull;
116 6 robfinch
// Distributed RAM fifo (vendor supplied):
117
//      Standard fifo
118
//      64 entries deep
119
//      12 bits wide
120
uart6551TxFifo fifo1 (
121
  .clk(clk),                // input wire clk
122
  .srst(rst|clear|fifoClear),              // input wire srst
123
  .din(din),                // input wire [11 : 0] din
124
  .wr_en(awr),            // input wire wr_en
125
  .rd_en(rdf),            // input wire rd_en
126
  .dout(fdo1),              // output wire [11 : 0] dout
127
  .full(ffull),              // output wire full
128
  .empty(fempty),            // output wire empty
129
  .data_count(qcnt)  // output wire [4 : 0] data_count
130 5 robfinch
);
131
assign empty = fifoEnable ? fempty : fempty2;
132
assign full = fifoEnable ? ffull : ~fempty2;
133
wire [11:0] fdo = fifoEnable ? fdo1 : fdo2;
134
`endif
135
 
136
// mask transmit data for word length
137
// this mask is needed for proper parity generation
138
integer n;
139
reg [11:0] mask;
140
always @*
141
        for (n = 0; n < 12; n = n + 1)
142
                mask[n] = n < wordLength ? 1'b1 : 1'b0;
143
 
144
always_comb
145
if (txBreak)
146
        t1 <= 0;
147
else
148
        t1 <= fdo & mask;
149
 
150
 
151
// compute parity bit
152
always_comb
153
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
always_comb
173
case(wordLength)
174
4'd4:   t2 <= {10'h3FF,p1,t1[3:0],1'b0};
175
4'd5:   t2 <= {9'h1FF,p1,t1[4:0],1'b0};
176
4'd6:   t2 <= {8'hFF,p1,t1[5:0],1'b0};
177
4'd7:   t2 <= {7'h7F,p1,t1[6:0],1'b0};
178
4'd8:   t2 <= {6'h3F,p1,t1[7:0],1'b0};
179
4'd9:   t2 <= {5'b11111,p1,t1[8:0],1'b0};
180
4'd10:  t2 <= {4'b1111,p1,t1[9:0],1'b0};
181
4'd11:  t2 <= {3'b111,p1,t1[10:0],1'b0};
182
4'd12:  t2 <= {2'b11,p1,t1[11:0],1'b0};
183
default:        t2 <= {6'h3F,p1,t1[7:0],1'b0};
184
endcase
185
 
186
always_ff @(posedge clk)
187
if (rst)
188
        state <= `IDLE;
189
else begin
190
        if (clear)
191
                state <= `IDLE;
192
        if (baud16x_ce) begin
193
                case(state)
194
                `IDLE:
195
                        if ((!empty && cts)||txBreak)
196 6 robfinch
                                state <= `READ1;
197
                `READ1:
198
                        state <= `READ2;
199
                `READ2:
200
                        state <= `CNT;
201 5 robfinch
                `CNT:
202
                        if (cnt==frameSize)
203
                                state <= `IDLE;
204
                endcase
205
        end
206
end
207
 
208
always_ff @(posedge clk)
209
if (rst)
210
        cnt <= 9'h00;
211
else begin
212
        if (clear)
213
                cnt <= 9'h00;
214
        if (baud16x_ce) begin
215
                case(state)
216
                `IDLE:
217
                        cnt <= 9'h00;
218
                `CNT:
219
                        cnt <= cnt + 2'd1;
220
                endcase
221
        end
222
end
223
 
224
always_ff @(posedge clk)
225
if (rst)
226
        rd <= 0;
227
else begin
228
        rd <= 0;
229
        if (clear)
230
                rd <= 0;
231
        if (baud16x_ce) begin
232
                case(state)
233
                `IDLE:
234
                        if ((!empty && cts)||txBreak)
235
                                rd <= 1;
236
                endcase
237
        end
238
end
239
 
240
always_ff @(posedge clk)
241
if (rst)
242
        tx_data <= 16'hFFFF;
243
else begin
244
        if (baud16x_ce) begin
245
                case(state)
246 6 robfinch
                `READ2:
247
                        tx_data <= t2;
248 5 robfinch
                `CNT:
249
                        // Shift the data out. LSB first.
250
                        if (cnt[3:0]==4'hF)
251
                                tx_data <= {1'b1,tx_data[15:1]};
252
                endcase
253
        end
254
end
255
 
256
always_ff @(posedge clk)
257
if (rst)
258
        txd <= 1'b1;
259
else
260
        txd <= tx_data[0];
261
 
262
endmodule

powered by: WebSVN 2.1.0

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