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

Subversion Repositories wbuart32

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

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 17 dgisselq
`default_nettype        none
97
//
98 2 dgisselq
`define TXU_BIT_ZERO    4'h0
99
`define TXU_BIT_ONE     4'h1
100
`define TXU_BIT_TWO     4'h2
101
`define TXU_BIT_THREE   4'h3
102
`define TXU_BIT_FOUR    4'h4
103
`define TXU_BIT_FIVE    4'h5
104
`define TXU_BIT_SIX     4'h6
105
`define TXU_BIT_SEVEN   4'h7
106
`define TXU_PARITY      4'h8    // Constant 1
107
`define TXU_STOP        4'h9    // Constant 1
108
`define TXU_SECOND_STOP 4'ha
109
// 4'hb // Unused
110
// 4'hc // Unused
111
// `define      TXU_START       4'hd    // An unused state
112
`define TXU_BREAK       4'he
113
`define TXU_IDLE        4'hf
114
//
115
//
116 9 dgisselq
module txuart(i_clk, i_reset, i_setup, i_break, i_wr, i_data,
117 15 dgisselq
                i_cts_n, o_uart_tx, o_busy);
118 9 dgisselq
        parameter       [30:0]   INITIAL_SETUP = 31'd868;
119 17 dgisselq
        input   wire            i_clk, i_reset;
120
        input   wire    [30:0]   i_setup;
121
        input   wire            i_break;
122
        input   wire            i_wr;
123
        input   wire    [7:0]    i_data;
124 9 dgisselq
        // Hardware flow control Ready-To-Send bit.  Set this to one to use
125
        // the core without flow control.  (A more appropriate name would be
126
        // the Ready-To-Receive bit ...)
127 17 dgisselq
        input   wire            i_cts_n;
128 9 dgisselq
        // And the UART input line itself
129 5 dgisselq
        output  reg             o_uart_tx;
130 9 dgisselq
        // A line to tell others when we are ready to accept data.  If
131
        // (i_wr)&&(!o_busy) is ever true, then the core has accepted a byte
132
        // for transmission.
133 2 dgisselq
        output  wire            o_busy;
134
 
135
        wire    [27:0]   clocks_per_baud, break_condition;
136
        wire    [1:0]    data_bits;
137 6 dgisselq
        wire            use_parity, parity_even, dblstop, fixd_parity,
138 9 dgisselq
                        fixdp_value, hw_flow_control;
139
        reg     [30:0]   r_setup;
140 2 dgisselq
        assign  clocks_per_baud = { 4'h0, r_setup[23:0] };
141
        assign  break_condition = { r_setup[23:0], 4'h0 };
142 9 dgisselq
        assign  hw_flow_control = !r_setup[30];
143
        assign  data_bits       =  r_setup[29:28];
144
        assign  dblstop         =  r_setup[27];
145
        assign  use_parity      =  r_setup[26];
146
        assign  fixd_parity     =  r_setup[25];
147
        assign  parity_even     =  r_setup[24];
148
        assign  fixdp_value     =  r_setup[24];
149 2 dgisselq
 
150
        reg     [27:0]   baud_counter;
151
        reg     [3:0]    state;
152
        reg     [7:0]    lcl_data;
153
        reg             calc_parity, r_busy, zero_baud_counter;
154
 
155 9 dgisselq
 
156
        // First step ... handle any hardware flow control, if so enabled.
157
        //
158
        // Clock in the flow control data, two clocks to avoid metastability
159
        // Default to using hardware flow control (uart_setup[30]==0 to use it).
160
        // Set this high order bit off if you do not wish to use it.
161 15 dgisselq
        reg     q_cts_n, qq_cts_n, ck_cts;
162
        // While we might wish to give initial values to q_rts and ck_cts,
163 9 dgisselq
        // 1) it's not required since the transmitter starts in a long wait
164
        // state, and 2) doing so will prevent the synthesizer from optimizing
165
        // this pin in the case it is hard set to 1'b1 external to this
166
        // peripheral.
167
        //
168 15 dgisselq
        // initial      q_cts_n  = 1'b1;
169
        // initial      qq_cts_n = 1'b1;
170
        // initial      ck_cts   = 1'b0;
171 9 dgisselq
        always  @(posedge i_clk)
172 15 dgisselq
                q_cts_n <= i_cts_n;
173 9 dgisselq
        always  @(posedge i_clk)
174 15 dgisselq
                qq_cts_n <= q_cts_n;
175 9 dgisselq
        always  @(posedge i_clk)
176 15 dgisselq
                ck_cts <= (!qq_cts_n)||(!hw_flow_control);
177 9 dgisselq
 
178 5 dgisselq
        initial o_uart_tx = 1'b1;
179 2 dgisselq
        initial r_busy = 1'b1;
180
        initial state  = `TXU_IDLE;
181
        initial lcl_data= 8'h0;
182
        initial calc_parity = 1'b0;
183
        // initial      baud_counter = clocks_per_baud;//ILLEGAL--not constant
184
        always @(posedge i_clk)
185
        begin
186
                if (i_reset)
187
                begin
188
                        r_busy <= 1'b1;
189
                        state <= `TXU_IDLE;
190
                end else if (i_break)
191
                begin
192
                        state <= `TXU_BREAK;
193
                        r_busy <= 1'b1;
194 6 dgisselq
                end else if (!zero_baud_counter)
195 2 dgisselq
                begin // r_busy needs to be set coming into here
196
                        r_busy <= 1'b1;
197
                end else if (state == `TXU_BREAK)
198
                begin
199
                        state <= `TXU_IDLE;
200
                        r_busy <= 1'b1;
201
                end else if (state == `TXU_IDLE)        // STATE_IDLE
202
                begin
203 6 dgisselq
                        if ((i_wr)&&(!r_busy))
204 2 dgisselq
                        begin   // Immediately start us off with a start bit
205
                                r_busy <= 1'b1;
206
                                case(data_bits)
207
                                2'b00: state <= `TXU_BIT_ZERO;
208
                                2'b01: state <= `TXU_BIT_ONE;
209
                                2'b10: state <= `TXU_BIT_TWO;
210
                                2'b11: state <= `TXU_BIT_THREE;
211
                                endcase
212
                        end else begin // Stay in idle
213 15 dgisselq
                                r_busy <= !ck_cts;
214 2 dgisselq
                        end
215
                end else begin
216
                        // One clock tick in each of these states ...
217
                        // baud_counter <= clocks_per_baud - 28'h01;
218
                        r_busy <= 1'b1;
219
                        if (state[3] == 0) // First 8 bits
220
                        begin
221
                                if (state == `TXU_BIT_SEVEN)
222
                                        state <= (use_parity)?`TXU_PARITY:`TXU_STOP;
223
                                else
224 23 dgisselq
                                        state <= state + 1'b1;
225 2 dgisselq
                        end else if (state == `TXU_PARITY)
226
                        begin
227
                                state <= `TXU_STOP;
228
                        end else if (state == `TXU_STOP)
229
                        begin // two stop bit(s)
230
                                if (dblstop)
231
                                        state <= `TXU_SECOND_STOP;
232
                                else
233
                                        state <= `TXU_IDLE;
234
                        end else // `TXU_SECOND_STOP and default:
235
                        begin
236
                                state <= `TXU_IDLE; // Go back to idle
237
                                // Still r_busy, since we need to wait
238
                                // for the baud clock to finish counting
239
                                // out this last bit.
240
                        end
241
                end
242
        end
243
 
244 6 dgisselq
        // o_busy
245
        //
246
        // This is a wire, designed to be true is we are ever busy above.
247
        // originally, this was going to be true if we were ever not in the
248
        // idle state.  The logic has since become more complex, hence we have
249
        // a register dedicated to this and just copy out that registers value.
250 2 dgisselq
        assign  o_busy = (r_busy);
251
 
252
 
253 6 dgisselq
        // r_setup
254
        //
255
        // Our setup register.  Accept changes between any pair of transmitted
256
        // words.  The register itself has many fields to it.  These are
257
        // broken out up top, and indicate what 1) our baud rate is, 2) our
258
        // number of stop bits, 3) what type of parity we are using, and 4)
259
        // the size of our data word.
260 14 dgisselq
        initial r_setup = INITIAL_SETUP;
261 6 dgisselq
        always @(posedge i_clk)
262
                if (state == `TXU_IDLE)
263
                        r_setup <= i_setup;
264
 
265
        // lcl_data
266
        //
267
        // This is our working copy of the i_data register which we use
268
        // when transmitting.  It is only of interest during transmit, and is
269
        // allowed to be whatever at any other time.  Hence, if r_busy isn't
270
        // true, we can always set it.  On the one clock where r_busy isn't
271
        // true and i_wr is, we set it and r_busy is true thereafter.
272
        // Then, on any zero_baud_counter (i.e. change between baud intervals)
273
        // we simple logically shift the register right to grab the next bit.
274
        always @(posedge i_clk)
275
                if (!r_busy)
276
                        lcl_data <= i_data;
277
                else if (zero_baud_counter)
278
                        lcl_data <= { 1'b0, lcl_data[7:1] };
279
 
280
        // o_uart_tx
281
        //
282
        // This is the final result/output desired of this core.  It's all
283
        // centered about o_uart_tx.  This is what finally needs to follow
284
        // the UART protocol.
285
        //
286
        // Ok, that said, our rules are:
287
        //      1'b0 on any break condition
288
        //      1'b0 on a start bit (IDLE, write, and not busy)
289
        //      lcl_data[0] during any data transfer, but only at the baud
290
        //              change
291
        //      PARITY -- During the parity bit.  This depends upon whether or
292
        //              not the parity bit is fixed, then what it's fixed to,
293
        //              or changing, and hence what it's calculated value is.
294
        //      1'b1 at all other times (stop bits, idle, etc)
295
        always @(posedge i_clk)
296
                if (i_reset)
297
                        o_uart_tx <= 1'b1;
298
                else if ((i_break)||((i_wr)&&(!r_busy)))
299
                        o_uart_tx <= 1'b0;
300
                else if (zero_baud_counter)
301
                        casez(state)
302
                        4'b0???:        o_uart_tx <= lcl_data[0];
303
                        `TXU_PARITY:    o_uart_tx <= calc_parity;
304
                        default:        o_uart_tx <= 1'b1;
305
                        endcase
306
 
307
 
308
        // calc_parity
309
        //
310
        // Calculate the parity to be placed into the parity bit.  If the
311
        // parity is fixed, then the parity bit is given by the fixed parity
312
        // value (r_setup[24]).  Otherwise the parity is given by the GF2
313
        // sum of all the data bits (plus one for even parity).
314
        always @(posedge i_clk)
315
                if (fixd_parity)
316
                        calc_parity <= fixdp_value;
317
                else if (zero_baud_counter)
318
                begin
319
                        if (state[3] == 0) // First 8 bits of msg
320
                                calc_parity <= calc_parity ^ lcl_data[0];
321
                        else
322
                                calc_parity <= parity_even;
323
                end else if (!r_busy)
324
                        calc_parity <= parity_even;
325
 
326
 
327
        // All of the above logic is driven by the baud counter.  Bits must last
328
        // clocks_per_baud in length, and this baud counter is what we use to
329
        // make certain of that.
330
        //
331
        // The basic logic is this: at the beginning of a bit interval, start
332
        // the baud counter and set it to count clocks_per_baud.  When it gets
333
        // to zero, restart it.
334
        //
335
        // However, comparing a 28'bit number to zero can be rather complex--
336
        // especially if we wish to do anything else on that same clock.  For
337
        // that reason, we create "zero_baud_counter".  zero_baud_counter is
338
        // nothing more than a flag that is true anytime baud_counter is zero.
339
        // It's true when the logic (above) needs to step to the next bit.
340
        // Simple enough?
341
        //
342
        // I wish we could stop there, but there are some other (ugly)
343
        // conditions to deal with that offer exceptions to this basic logic.
344
        //
345
        // 1. When the user has commanded a BREAK across the line, we need to
346
        // wait several baud intervals following the break before we start
347
        // transmitting, to give any receiver a chance to recognize that we are
348
        // out of the break condition, and to know that the next bit will be
349
        // a stop bit.
350
        //
351
        // 2. A reset is similar to a break condition--on both we wait several
352
        // baud intervals before allowing a start bit.
353
        //
354
        // 3. In the idle state, we stop our counter--so that upon a request
355
        // to transmit when idle we can start transmitting immediately, rather
356
        // than waiting for the end of the next (fictitious and arbitrary) baud
357
        // interval.
358
        //
359
        // When (i_wr)&&(!r_busy)&&(state == `TXU_IDLE) then we're not only in
360
        // the idle state, but we also just accepted a command to start writing
361
        // the next word.  At this point, the baud counter needs to be reset
362
        // to the number of clocks per baud, and zero_baud_counter set to zero.
363
        //
364
        // The logic is a bit twisted here, in that it will only check for the
365
        // above condition when zero_baud_counter is false--so as to make
366
        // certain the STOP bit is complete.
367 2 dgisselq
        initial zero_baud_counter = 1'b0;
368
        initial baud_counter = 28'h05;
369
        always @(posedge i_clk)
370
        begin
371
                zero_baud_counter <= (baud_counter == 28'h01);
372
                if ((i_reset)||(i_break))
373 5 dgisselq
                begin
374 2 dgisselq
                        // Give ourselves 16 bauds before being ready
375
                        baud_counter <= break_condition;
376 5 dgisselq
                        zero_baud_counter <= 1'b0;
377 6 dgisselq
                end else if (!zero_baud_counter)
378 2 dgisselq
                        baud_counter <= baud_counter - 28'h01;
379
                else if (state == `TXU_BREAK)
380 6 dgisselq
                        // Give us four idle baud intervals before becoming
381
                        // available
382 2 dgisselq
                        baud_counter <= clocks_per_baud<<2;
383
                else if (state == `TXU_IDLE)
384
                begin
385 6 dgisselq
                        baud_counter <= 28'h0;
386
                        zero_baud_counter <= 1'b1;
387
                        if ((i_wr)&&(!r_busy))
388
                        begin
389 2 dgisselq
                                baud_counter <= clocks_per_baud - 28'h01;
390 6 dgisselq
                                zero_baud_counter <= 1'b0;
391
                        end
392 2 dgisselq
                end else
393
                        baud_counter <= clocks_per_baud - 28'h01;
394
        end
395 23 dgisselq
 
396
`ifdef  FORMAL
397
        reg             fsv_parity;
398
        reg     [30:0]   fsv_setup;
399
        reg     [7:0]    fsv_data;
400
 
401
        always @(posedge i_clk)
402
                if ((i_wr)&&(!o_busy))
403
                        fsv_data <= i_data;
404
 
405
        always @(posedge i_clk)
406
                if ((i_wr)&&(!o_busy))
407
                        fsv_setup <= i_setup;
408
 
409
        always @(posedge i_clk)
410
                assert(zero_baud_counter == (baud_counter == 0));
411
 
412
        always @(*)
413
                assume(i_setup[21:0] >= 2);
414
        always @(*)
415
                assume(i_setup[21:0] <= 16);
416
 
417
        // A single baud interval
418
        sequence        BAUD_INTERVAL(DAT, SR, ST);
419
                ((o_uart_tx == DAT)&&(state == ST)
420
                        &&(lcl_data == SR)
421
                        &&(baud_counter == fsv_setup[21:0]-1)
422
                        &&(!zero_baud_counter))
423
                ##1 ((o_uart_tx == DAT)&&(state == ST)
424
                        &&(lcl_data == SR)
425
                        &&(baud_counter == $past(baud_counter)-1)
426
                        &&(baud_counter > 0)
427
                        &&(baud_counter < fsv_setup[21:0])
428
                        &&(!zero_baud_counter))[*0:$]
429
                ##1 (o_uart_tx == DAT)&&(state == ST)
430
                        &&(lcl_data == SR)
431
                        &&(zero_baud_counter);
432
        endsequence
433
 
434
        //
435
        // One byte transmitted
436
        //
437
        // DATA = the byte that is sent
438
        // CKS  = the number of clocks per bit
439
        //
440
        sequence        SEND5(DATA);
441
                BAUD_INTERVAL(1'b0, DATA, 4'h3)
442
                ##1 BAUD_INTERVAL(DATA[0], {{(1){1'b1}},DATA[7:1]}, 4'h4)
443
                ##1 BAUD_INTERVAL(DATA[1], {{(2){1'b1}},DATA[7:2]}, 4'h5)
444
                ##1 BAUD_INTERVAL(DATA[2], {{(3){1'b1}},DATA[7:3]}, 4'h6)
445
                ##1 BAUD_INTERVAL(DATA[3], {{(4){1'b1}},DATA[7:4]}, 4'h7)
446
                ##1 BAUD_INTERVAL(DATA[4], {{(5){1'b1}},DATA[7:5]}, 4'h8);
447
        endsequence
448
 
449
        sequence        SEND6(DATA);
450
                BAUD_INTERVAL(1'b0, DATA, 4'h2)
451
                ##1 BAUD_INTERVAL(DATA[0], {{(1){1'b1}},DATA[7:1]}, 4'h3)
452
                ##1 BAUD_INTERVAL(DATA[1], {{(2){1'b1}},DATA[7:2]}, 4'h4)
453
                ##1 BAUD_INTERVAL(DATA[2], {{(3){1'b1}},DATA[7:3]}, 4'h5)
454
                ##1 BAUD_INTERVAL(DATA[3], {{(4){1'b1}},DATA[7:4]}, 4'h6)
455
                ##1 BAUD_INTERVAL(DATA[4], {{(5){1'b1}},DATA[7:5]}, 4'h7)
456
                ##1 BAUD_INTERVAL(DATA[5], {{(6){1'b1}},DATA[7:6]}, 4'h8);
457
        endsequence
458
 
459
        sequence        SEND7(DATA);
460
                BAUD_INTERVAL(1'b0, DATA, 4'h1)
461
                ##1 BAUD_INTERVAL(DATA[0], {{(1){1'b1}},DATA[7:1]}, 4'h2)
462
                ##1 BAUD_INTERVAL(DATA[1], {{(2){1'b1}},DATA[7:2]}, 4'h3)
463
                ##1 BAUD_INTERVAL(DATA[2], {{(3){1'b1}},DATA[7:3]}, 4'h4)
464
                ##1 BAUD_INTERVAL(DATA[3], {{(4){1'b1}},DATA[7:4]}, 4'h5)
465
                ##1 BAUD_INTERVAL(DATA[4], {{(5){1'b1}},DATA[7:5]}, 4'h6)
466
                ##1 BAUD_INTERVAL(DATA[5], {{(6){1'b1}},DATA[7:6]}, 4'h7)
467
                ##1 BAUD_INTERVAL(DATA[6], {{(7){1'b1}},DATA[7:7]}, 4'h8);
468
        endsequence
469
 
470
        sequence        SEND8(DATA);
471
                BAUD_INTERVAL(1'b0, DATA, 4'h0)
472
                ##1 BAUD_INTERVAL(DATA[0], {{(1){1'b1}},DATA[7:1]}, 4'h1)
473
                ##1 BAUD_INTERVAL(DATA[1], {{(2){1'b1}},DATA[7:2]}, 4'h2)
474
                ##1 BAUD_INTERVAL(DATA[2], {{(3){1'b1}},DATA[7:3]}, 4'h3)
475
                ##1 BAUD_INTERVAL(DATA[3], {{(4){1'b1}},DATA[7:4]}, 4'h4)
476
                ##1 BAUD_INTERVAL(DATA[4], {{(5){1'b1}},DATA[7:5]}, 4'h5)
477
                ##1 BAUD_INTERVAL(DATA[5], {{(6){1'b1}},DATA[7:6]}, 4'h6)
478
                ##1 BAUD_INTERVAL(DATA[6], {{(7){1'b1}},DATA[7:7]}, 4'h7)
479
                ##1 BAUD_INTERVAL(DATA[7], 8'hff, 4'h8);
480
        endsequence
481
 
482
        always @(posedge i_clk)
483
        if (fsv_setup[25])
484
                fsv_parity <= fsv_setup[24];
485
        else
486
                case(fsv_setup[29:28])
487
                2'b00: fsv_parity <= (^fsv_data[4:0]) ^ fsv_setup[24];
488
                2'b01: fsv_parity <= (^fsv_data[5:0]) ^ fsv_setup[24];
489
                2'b10: fsv_parity <= (^fsv_data[6:0]) ^ fsv_setup[24];
490
                2'b11: fsv_parity <= (^fsv_data[7:0]) ^ fsv_setup[24];
491
                endcase
492
 
493
        assert property( @(posedge i_clk)
494
                (o_busy)[*2] |=> $stable(fsv_parity));
495
 
496
        assert property( @(posedge i_clk)
497
                (o_busy) |=> $stable(fsv_data));
498
 
499
        assert property( @(posedge i_clk)
500
                (o_busy) |=> $stable(fsv_setup));
501
 
502
        sequence        SENDPARITY(SETUP);
503
                        ((o_uart_tx == fsv_parity)&&(state == `TXU_PARITY)
504
                                &&(SETUP[26])
505
                                &&(baud_counter == SETUP[21:0]-1)
506
                                &&(!zero_baud_counter))
507
                        ##1 ((o_uart_tx == fsv_parity)&&(state == `TXU_PARITY)
508
                                &&(SETUP[26])
509
                                &&(baud_counter < SETUP[21:0])
510
                                &&(baud_counter > 0)
511
                                &&(baud_counter == $past(baud_counter)-1)
512
                                &&(!zero_baud_counter))[*0:$]
513
                        ##1 (o_uart_tx == fsv_parity)&&(state == `TXU_PARITY)
514
                                &&(SETUP[26])
515
                                &&(zero_baud_counter);
516
        endsequence
517
 
518
        sequence        SENDSINGLESTOP(CKS,ST);
519
                ((o_uart_tx == 1'b1)&&(state == ST)
520
                        &&(baud_counter == CKS-1)
521
                        &&(!zero_baud_counter))
522
                ##1 ((o_uart_tx == 1'b1)&&(state == ST)
523
                        &&(baud_counter > 0)
524
                        &&(baud_counter == $past(baud_counter)-1)
525
                        &&(!zero_baud_counter))[*0:$]
526
                ##1 (o_uart_tx == 1'b1)&&(state == ST)
527
                        &&(zero_baud_counter);
528
        endsequence
529
 
530
        sequence        SENDFULLSTOP(SETUP);
531
                ((!SETUP[27]) throughout SENDSINGLESTOP(SETUP[21:0],`TXU_STOP))
532
                or (SETUP[27]) throughout
533
                        SENDSINGLESTOP(SETUP[21:0],`TXU_STOP)
534
                        ##1 SENDSINGLESTOP(SETUP[21:0],`TXU_SECOND_STOP);
535
        endsequence
536
 
537
        sequence        UART_IDLE;
538
                (!o_busy)&&(o_uart_tx)&&(zero_baud_counter);
539
        endsequence
540
 
541
        assert property ( @(posedge i_clk) (!o_busy) |-> UART_IDLE);
542
 
543
 
544
        assert property ( @(posedge i_clk)
545
                (i_wr)&&(!o_busy)&&(i_setup[29:28]==2'b00) |=>
546
                        ((o_busy) throughout
547
                                SEND5(fsv_data)
548
                                ##1 SENDPARITY(fsv_setup)
549
                                ##1 SENDFULLSTOP(fsv_setup)
550
                        )
551
                ##1 UART_IDLE);
552
 
553
        assert property ( @(posedge i_clk)
554
                (i_wr)&&(!o_busy)&&(i_setup[29:28]==2'b01) |=>
555
                        ((o_busy) throughout
556
                                SEND6(fsv_data)
557
                                ##1 SENDPARITY(fsv_setup)
558
                                ##1 SENDFULLSTOP(fsv_setup)
559
                        )
560
                ##1 UART_IDLE);
561
 
562
        assert property ( @(posedge i_clk)
563
                (i_wr)&&(!o_busy)&&(i_setup[29:28]==2'b10) |=>
564
                        ((o_busy) throughout
565
                                SEND7(fsv_data)
566
                                ##1 SENDPARITY(fsv_setup)
567
                                ##1 SENDFULLSTOP(fsv_setup)
568
                        )
569
                ##1 UART_IDLE);
570
 
571
        assert property ( @(posedge i_clk)
572
                (i_wr)&&(!o_busy)&&(i_setup[29:28]==2'b11) |=>
573
                        ((o_busy) throughout
574
                                SEND8(fsv_data)
575
                                ##1 SENDPARITY(fsv_setup)
576
                                ##1 SENDFULLSTOP(fsv_setup)
577
                        )
578
                ##1 UART_IDLE);
579
 
580
`endif  // FORMAL
581 2 dgisselq
endmodule
582
 

powered by: WebSVN 2.1.0

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