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

Subversion Repositories wbuart32

[/] [wbuart32/] [trunk/] [rtl/] [txuart.v] - Blame information for rev 15

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

Line No. Rev Author Line
1 2 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    txuart.v
4
//
5
// Project:     wbuart32, a full featured UART with simulator
6
//
7
// Purpose:     Transmit outputs over a single UART line.
8
//
9
//      To interface with this module, connect it to your system clock,
10
//      pass it the 32 bit setup register (defined below) and the byte
11
//      of data you wish to transmit.  Strobe the i_wr line high for one
12
//      clock cycle, and your data will be off.  Wait until the 'o_busy'
13
//      line is low before strobing the i_wr line again--this implementation
14
//      has NO BUFFER, so strobing i_wr while the core is busy will just
15
//      cause your data to be lost.  The output will be placed on the o_txuart
16
//      output line.  If you wish to set/send a break condition, assert the
17
//      i_break line otherwise leave it low.
18
//
19
//      There is a synchronous reset line, logic high.
20
//
21
//      Now for the setup register.  The register is 32 bits, so that this
22
//      UART may be set up over a 32-bit bus.
23
//
24 9 dgisselq
//      i_setup[30]     Set this to zero to use hardware flow control, and to
25
//              one to ignore hardware flow control.  Only works if the hardware
26
//              flow control has been properly wired.
27
//
28
//              If you don't want hardware flow control, fix the i_rts bit to
29
//              1'b1, and let the synthesys tools optimize out the logic.
30
//
31 2 dgisselq
//      i_setup[29:28]  Indicates the number of data bits per word.  This will
32 9 dgisselq
//              either be 2'b00 for an 8-bit word, 2'b01 for a 7-bit word, 2'b10
33
//              for a six bit word, or 2'b11 for a five bit word.
34 2 dgisselq
//
35
//      i_setup[27]     Indicates whether or not to use one or two stop bits.
36
//              Set this to one to expect two stop bits, zero for one.
37
//
38
//      i_setup[26]     Indicates whether or not a parity bit exists.  Set this
39
//              to 1'b1 to include parity.
40
//
41
//      i_setup[25]     Indicates whether or not the parity bit is fixed.  Set
42
//              to 1'b1 to include a fixed bit of parity, 1'b0 to allow the
43
//              parity to be set based upon data.  (Both assume the parity
44
//              enable value is set.)
45
//
46
//      i_setup[24]     This bit is ignored if parity is not used.  Otherwise,
47
//              in the case of a fixed parity bit, this bit indicates whether
48
//              mark (1'b1) or space (1'b0) parity is used.  Likewise if the
49
//              parity is not fixed, a 1'b1 selects even parity, and 1'b0
50
//              selects odd.
51
//
52
//      i_setup[23:0]   Indicates the speed of the UART in terms of clocks.
53
//              So, for example, if you have a 200 MHz clock and wish to
54
//              run your UART at 9600 baud, you would take 200 MHz and divide
55
//              by 9600 to set this value to 24'd20834.  Likewise if you wished
56
//              to run this serial port at 115200 baud from a 200 MHz clock,
57
//              you would set the value to 24'd1736
58
//
59
//      Thus, to set the UART for the common setting of an 8-bit word, 
60
//      one stop bit, no parity, and 115200 baud over a 200 MHz clock, you
61
//      would want to set the setup value to:
62
//
63
//      32'h0006c8              // For 115,200 baud, 8 bit, no parity
64
//      32'h005161              // For 9600 baud, 8 bit, no parity
65
//      
66
//
67
// Creator:     Dan Gisselquist, Ph.D.
68
//              Gisselquist Technology, LLC
69
//
70
////////////////////////////////////////////////////////////////////////////////
71
//
72 9 dgisselq
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
73 2 dgisselq
//
74
// This program is free software (firmware): you can redistribute it and/or
75
// modify it under the terms of  the GNU General Public License as published
76
// by the Free Software Foundation, either version 3 of the License, or (at
77
// your option) any later version.
78
//
79
// This program is distributed in the hope that it will be useful, but WITHOUT
80
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
81
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
82
// for more details.
83
//
84
// You should have received a copy of the GNU General Public License along
85 9 dgisselq
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
86 2 dgisselq
// target there if the PDF file isn't present.)  If not, see
87
// <http://www.gnu.org/licenses/> for a copy.
88
//
89
// License:     GPL, v3, as defined and found on www.gnu.org,
90
//              http://www.gnu.org/licenses/gpl.html
91
//
92
//
93
////////////////////////////////////////////////////////////////////////////////
94
//
95
//
96
`define TXU_BIT_ZERO    4'h0
97
`define TXU_BIT_ONE     4'h1
98
`define TXU_BIT_TWO     4'h2
99
`define TXU_BIT_THREE   4'h3
100
`define TXU_BIT_FOUR    4'h4
101
`define TXU_BIT_FIVE    4'h5
102
`define TXU_BIT_SIX     4'h6
103
`define TXU_BIT_SEVEN   4'h7
104
`define TXU_PARITY      4'h8    // Constant 1
105
`define TXU_STOP        4'h9    // Constant 1
106
`define TXU_SECOND_STOP 4'ha
107
// 4'hb // Unused
108
// 4'hc // Unused
109
// `define      TXU_START       4'hd    // An unused state
110
`define TXU_BREAK       4'he
111
`define TXU_IDLE        4'hf
112
//
113
//
114 9 dgisselq
module txuart(i_clk, i_reset, i_setup, i_break, i_wr, i_data,
115 15 dgisselq
                i_cts_n, o_uart_tx, o_busy);
116 9 dgisselq
        parameter       [30:0]   INITIAL_SETUP = 31'd868;
117 2 dgisselq
        input                   i_clk, i_reset;
118 9 dgisselq
        input           [30:0]   i_setup;
119 2 dgisselq
        input                   i_break;
120
        input                   i_wr;
121
        input           [7:0]    i_data;
122 9 dgisselq
        // Hardware flow control Ready-To-Send bit.  Set this to one to use
123
        // the core without flow control.  (A more appropriate name would be
124
        // the Ready-To-Receive bit ...)
125 15 dgisselq
        input                   i_cts_n;
126 9 dgisselq
        // And the UART input line itself
127 5 dgisselq
        output  reg             o_uart_tx;
128 9 dgisselq
        // A line to tell others when we are ready to accept data.  If
129
        // (i_wr)&&(!o_busy) is ever true, then the core has accepted a byte
130
        // for transmission.
131 2 dgisselq
        output  wire            o_busy;
132
 
133
        wire    [27:0]   clocks_per_baud, break_condition;
134
        wire    [1:0]    data_bits;
135 6 dgisselq
        wire            use_parity, parity_even, dblstop, fixd_parity,
136 9 dgisselq
                        fixdp_value, hw_flow_control;
137
        reg     [30:0]   r_setup;
138 2 dgisselq
        assign  clocks_per_baud = { 4'h0, r_setup[23:0] };
139
        assign  break_condition = { r_setup[23:0], 4'h0 };
140 9 dgisselq
        assign  hw_flow_control = !r_setup[30];
141
        assign  data_bits       =  r_setup[29:28];
142
        assign  dblstop         =  r_setup[27];
143
        assign  use_parity      =  r_setup[26];
144
        assign  fixd_parity     =  r_setup[25];
145
        assign  parity_even     =  r_setup[24];
146
        assign  fixdp_value     =  r_setup[24];
147 2 dgisselq
 
148
        reg     [27:0]   baud_counter;
149
        reg     [3:0]    state;
150
        reg     [7:0]    lcl_data;
151
        reg             calc_parity, r_busy, zero_baud_counter;
152
 
153 9 dgisselq
 
154
        // First step ... handle any hardware flow control, if so enabled.
155
        //
156
        // Clock in the flow control data, two clocks to avoid metastability
157
        // Default to using hardware flow control (uart_setup[30]==0 to use it).
158
        // Set this high order bit off if you do not wish to use it.
159 15 dgisselq
        reg     q_cts_n, qq_cts_n, ck_cts;
160
        // While we might wish to give initial values to q_rts and ck_cts,
161 9 dgisselq
        // 1) it's not required since the transmitter starts in a long wait
162
        // state, and 2) doing so will prevent the synthesizer from optimizing
163
        // this pin in the case it is hard set to 1'b1 external to this
164
        // peripheral.
165
        //
166 15 dgisselq
        // initial      q_cts_n  = 1'b1;
167
        // initial      qq_cts_n = 1'b1;
168
        // initial      ck_cts   = 1'b0;
169 9 dgisselq
        always  @(posedge i_clk)
170 15 dgisselq
                q_cts_n <= i_cts_n;
171 9 dgisselq
        always  @(posedge i_clk)
172 15 dgisselq
                qq_cts_n <= q_cts_n;
173 9 dgisselq
        always  @(posedge i_clk)
174 15 dgisselq
                ck_cts <= (!qq_cts_n)||(!hw_flow_control);
175 9 dgisselq
 
176 5 dgisselq
        initial o_uart_tx = 1'b1;
177 2 dgisselq
        initial r_busy = 1'b1;
178
        initial state  = `TXU_IDLE;
179
        initial lcl_data= 8'h0;
180
        initial calc_parity = 1'b0;
181
        // initial      baud_counter = clocks_per_baud;//ILLEGAL--not constant
182
        always @(posedge i_clk)
183
        begin
184
                if (i_reset)
185
                begin
186
                        r_busy <= 1'b1;
187
                        state <= `TXU_IDLE;
188
                end else if (i_break)
189
                begin
190
                        state <= `TXU_BREAK;
191
                        r_busy <= 1'b1;
192 6 dgisselq
                end else if (!zero_baud_counter)
193 2 dgisselq
                begin // r_busy needs to be set coming into here
194
                        r_busy <= 1'b1;
195
                end else if (state == `TXU_BREAK)
196
                begin
197
                        state <= `TXU_IDLE;
198
                        r_busy <= 1'b1;
199
                end else if (state == `TXU_IDLE)        // STATE_IDLE
200
                begin
201 6 dgisselq
                        if ((i_wr)&&(!r_busy))
202 2 dgisselq
                        begin   // Immediately start us off with a start bit
203
                                r_busy <= 1'b1;
204
                                case(data_bits)
205
                                2'b00: state <= `TXU_BIT_ZERO;
206
                                2'b01: state <= `TXU_BIT_ONE;
207
                                2'b10: state <= `TXU_BIT_TWO;
208
                                2'b11: state <= `TXU_BIT_THREE;
209
                                endcase
210
                        end else begin // Stay in idle
211 15 dgisselq
                                r_busy <= !ck_cts;
212 2 dgisselq
                        end
213
                end else begin
214
                        // One clock tick in each of these states ...
215
                        // baud_counter <= clocks_per_baud - 28'h01;
216
                        r_busy <= 1'b1;
217
                        if (state[3] == 0) // First 8 bits
218
                        begin
219
                                if (state == `TXU_BIT_SEVEN)
220
                                        state <= (use_parity)?`TXU_PARITY:`TXU_STOP;
221
                                else
222
                                        state <= state + 1;
223
                        end else if (state == `TXU_PARITY)
224
                        begin
225
                                state <= `TXU_STOP;
226
                        end else if (state == `TXU_STOP)
227
                        begin // two stop bit(s)
228
                                if (dblstop)
229
                                        state <= `TXU_SECOND_STOP;
230
                                else
231
                                        state <= `TXU_IDLE;
232
                        end else // `TXU_SECOND_STOP and default:
233
                        begin
234
                                state <= `TXU_IDLE; // Go back to idle
235
                                // Still r_busy, since we need to wait
236
                                // for the baud clock to finish counting
237
                                // out this last bit.
238
                        end
239
                end
240
        end
241
 
242 6 dgisselq
        // o_busy
243
        //
244
        // This is a wire, designed to be true is we are ever busy above.
245
        // originally, this was going to be true if we were ever not in the
246
        // idle state.  The logic has since become more complex, hence we have
247
        // a register dedicated to this and just copy out that registers value.
248 2 dgisselq
        assign  o_busy = (r_busy);
249
 
250
 
251 6 dgisselq
        // r_setup
252
        //
253
        // Our setup register.  Accept changes between any pair of transmitted
254
        // words.  The register itself has many fields to it.  These are
255
        // broken out up top, and indicate what 1) our baud rate is, 2) our
256
        // number of stop bits, 3) what type of parity we are using, and 4)
257
        // the size of our data word.
258 14 dgisselq
        initial r_setup = INITIAL_SETUP;
259 6 dgisselq
        always @(posedge i_clk)
260
                if (state == `TXU_IDLE)
261
                        r_setup <= i_setup;
262
 
263
        // lcl_data
264
        //
265
        // This is our working copy of the i_data register which we use
266
        // when transmitting.  It is only of interest during transmit, and is
267
        // allowed to be whatever at any other time.  Hence, if r_busy isn't
268
        // true, we can always set it.  On the one clock where r_busy isn't
269
        // true and i_wr is, we set it and r_busy is true thereafter.
270
        // Then, on any zero_baud_counter (i.e. change between baud intervals)
271
        // we simple logically shift the register right to grab the next bit.
272
        always @(posedge i_clk)
273
                if (!r_busy)
274
                        lcl_data <= i_data;
275
                else if (zero_baud_counter)
276
                        lcl_data <= { 1'b0, lcl_data[7:1] };
277
 
278
        // o_uart_tx
279
        //
280
        // This is the final result/output desired of this core.  It's all
281
        // centered about o_uart_tx.  This is what finally needs to follow
282
        // the UART protocol.
283
        //
284
        // Ok, that said, our rules are:
285
        //      1'b0 on any break condition
286
        //      1'b0 on a start bit (IDLE, write, and not busy)
287
        //      lcl_data[0] during any data transfer, but only at the baud
288
        //              change
289
        //      PARITY -- During the parity bit.  This depends upon whether or
290
        //              not the parity bit is fixed, then what it's fixed to,
291
        //              or changing, and hence what it's calculated value is.
292
        //      1'b1 at all other times (stop bits, idle, etc)
293
        always @(posedge i_clk)
294
                if (i_reset)
295
                        o_uart_tx <= 1'b1;
296
                else if ((i_break)||((i_wr)&&(!r_busy)))
297
                        o_uart_tx <= 1'b0;
298
                else if (zero_baud_counter)
299
                        casez(state)
300
                        4'b0???:        o_uart_tx <= lcl_data[0];
301
                        `TXU_PARITY:    o_uart_tx <= calc_parity;
302
                        default:        o_uart_tx <= 1'b1;
303
                        endcase
304
 
305
 
306
        // calc_parity
307
        //
308
        // Calculate the parity to be placed into the parity bit.  If the
309
        // parity is fixed, then the parity bit is given by the fixed parity
310
        // value (r_setup[24]).  Otherwise the parity is given by the GF2
311
        // sum of all the data bits (plus one for even parity).
312
        always @(posedge i_clk)
313
                if (fixd_parity)
314
                        calc_parity <= fixdp_value;
315
                else if (zero_baud_counter)
316
                begin
317
                        if (state[3] == 0) // First 8 bits of msg
318
                                calc_parity <= calc_parity ^ lcl_data[0];
319
                        else
320
                                calc_parity <= parity_even;
321
                end else if (!r_busy)
322
                        calc_parity <= parity_even;
323
 
324
 
325
        // All of the above logic is driven by the baud counter.  Bits must last
326
        // clocks_per_baud in length, and this baud counter is what we use to
327
        // make certain of that.
328
        //
329
        // The basic logic is this: at the beginning of a bit interval, start
330
        // the baud counter and set it to count clocks_per_baud.  When it gets
331
        // to zero, restart it.
332
        //
333
        // However, comparing a 28'bit number to zero can be rather complex--
334
        // especially if we wish to do anything else on that same clock.  For
335
        // that reason, we create "zero_baud_counter".  zero_baud_counter is
336
        // nothing more than a flag that is true anytime baud_counter is zero.
337
        // It's true when the logic (above) needs to step to the next bit.
338
        // Simple enough?
339
        //
340
        // I wish we could stop there, but there are some other (ugly)
341
        // conditions to deal with that offer exceptions to this basic logic.
342
        //
343
        // 1. When the user has commanded a BREAK across the line, we need to
344
        // wait several baud intervals following the break before we start
345
        // transmitting, to give any receiver a chance to recognize that we are
346
        // out of the break condition, and to know that the next bit will be
347
        // a stop bit.
348
        //
349
        // 2. A reset is similar to a break condition--on both we wait several
350
        // baud intervals before allowing a start bit.
351
        //
352
        // 3. In the idle state, we stop our counter--so that upon a request
353
        // to transmit when idle we can start transmitting immediately, rather
354
        // than waiting for the end of the next (fictitious and arbitrary) baud
355
        // interval.
356
        //
357
        // When (i_wr)&&(!r_busy)&&(state == `TXU_IDLE) then we're not only in
358
        // the idle state, but we also just accepted a command to start writing
359
        // the next word.  At this point, the baud counter needs to be reset
360
        // to the number of clocks per baud, and zero_baud_counter set to zero.
361
        //
362
        // The logic is a bit twisted here, in that it will only check for the
363
        // above condition when zero_baud_counter is false--so as to make
364
        // certain the STOP bit is complete.
365 2 dgisselq
        initial zero_baud_counter = 1'b0;
366
        initial baud_counter = 28'h05;
367
        always @(posedge i_clk)
368
        begin
369
                zero_baud_counter <= (baud_counter == 28'h01);
370
                if ((i_reset)||(i_break))
371 5 dgisselq
                begin
372 2 dgisselq
                        // Give ourselves 16 bauds before being ready
373
                        baud_counter <= break_condition;
374 5 dgisselq
                        zero_baud_counter <= 1'b0;
375 6 dgisselq
                end else if (!zero_baud_counter)
376 2 dgisselq
                        baud_counter <= baud_counter - 28'h01;
377
                else if (state == `TXU_BREAK)
378 6 dgisselq
                        // Give us four idle baud intervals before becoming
379
                        // available
380 2 dgisselq
                        baud_counter <= clocks_per_baud<<2;
381
                else if (state == `TXU_IDLE)
382
                begin
383 6 dgisselq
                        baud_counter <= 28'h0;
384
                        zero_baud_counter <= 1'b1;
385
                        if ((i_wr)&&(!r_busy))
386
                        begin
387 2 dgisselq
                                baud_counter <= clocks_per_baud - 28'h01;
388 6 dgisselq
                                zero_baud_counter <= 1'b0;
389
                        end
390 2 dgisselq
                end else
391
                        baud_counter <= clocks_per_baud - 28'h01;
392
        end
393
endmodule
394
 

powered by: WebSVN 2.1.0

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