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

Subversion Repositories wbuart32

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

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

powered by: WebSVN 2.1.0

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