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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [rtl/] [verilog/] [uart16550/] [bench/] [verilog/] [uart_device.v] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1327 jcastillo
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  uart_device.v                                               ////
4
////                                                              ////
5
////  This file is part of the "uart16550" project                ////
6
////  http://www.opencores.org/projects/uart16550/                ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - tadej@opencores.org (Tadej Markovic)                  ////
10
////      - igorm@opencores.org (Igor Mohor)                      ////
11
////                                                              ////
12
////  All additional information is avaliable in the README.txt   ////
13
////  file.                                                       ////
14
////                                                              ////
15
////                                                              ////
16
//////////////////////////////////////////////////////////////////////
17
////                                                              ////
18
//// Copyright (C) 2000 - 2004 authors                            ////
19
////                                                              ////
20
//// This source file may be used and distributed without         ////
21
//// restriction provided that this copyright statement is not    ////
22
//// removed from the file and that any derivative work contains  ////
23
//// the original copyright notice and the associated disclaimer. ////
24
////                                                              ////
25
//// This source file is free software; you can redistribute it   ////
26
//// and/or modify it under the terms of the GNU Lesser General   ////
27
//// Public License as published by the Free Software Foundation; ////
28
//// either version 2.1 of the License, or (at your option) any   ////
29
//// later version.                                               ////
30
////                                                              ////
31
//// This source is distributed in the hope that it will be       ////
32
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
33
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
34
//// PURPOSE.  See the GNU Lesser General Public License for more ////
35
//// details.                                                     ////
36
////                                                              ////
37
//// You should have received a copy of the GNU Lesser General    ////
38
//// Public License along with this source; if not, download it   ////
39
//// from http://www.opencores.org/lgpl.shtml                     ////
40
////                                                              ////
41
//////////////////////////////////////////////////////////////////////
42
//
43
// CVS Revision History
44
//
45
// $Log: not supported by cvs2svn $
46
// Revision 1.1  2004/03/27 03:55:16  tadejm
47
// Testbench with complete selfchecking. BUG is that THRE status is set at the end of last sent bit when TX FIFO is empty instead when only TX FIFO gets empty. This causes testcases not to finish.
48
//
49
//
50
//
51
 
52
 
53
`include "uart_testbench_defines.v"
54
`include "timescale.v"
55
 
56
module uart_device
57
(
58
    // UART signals
59
    stx_i,
60
    srx_o,
61
    // Modem signals
62
    rts_i,
63
    cts_o,
64
    dtr_i,
65
    dsr_o,
66
    ri_o,
67
    dcd_o
68
);
69
 
70
 
71
// IN/OUT signals
72
//###############
73
 
74
  // UART signals
75
  input           stx_i;
76
  output          srx_o;
77
  // Modem signals
78
  input           rts_i;
79
  output          cts_o;
80
  input           dtr_i;
81
  output          dsr_o;
82
  output          ri_o;
83
  output          dcd_o;
84
 
85
 
86
// INTERNAL signals
87
//#################
88
 
89
 
90
  // Clock generation signals
91
  //#########################
92
 
93
    // Operational and transmission clock signals
94
    reg          rx_clk;         // RX device clock with period T_clk_period (should be equal to wb_clk_period)
95
    reg          tx_clk;         // TX device clock with period (T_clk_period + T_clk_delay)
96
    reg          tx_clk_divided; // divided TX device clock with period ((T_clk_period + T_clk_delay) * T_divisor * 16)
97
    // Clock enable signals
98
    reg          rx_clk_en = 1'b1;
99
    reg          tx_clk_en = 1'b1;
100
    reg          tx_clk_divided_en = 1'b1;
101
    // Clock period variables
102
    real         T_clk_period = 20;
103
    real         T_clk_delay = 0;
104
    integer      T_divisor = 5;
105
 
106
 
107
  // IN/OUT assignment signals
108
  //##########################
109
 
110
    // Modem signals
111
    wire         rts;
112
    wire         dtr;
113
 
114
 
115
  // UART receiver signals
116
  //######################
117
 
118
    // RX packet control signals
119
    wire         rx;
120
    reg   [3:0]  rx_length;
121
    reg          rx_odd_parity;
122
    reg          rx_even_parity;
123
    reg          rx_stick1_parity;
124
    reg          rx_stick0_parity;
125
    reg          rx_parity_enabled;
126
    reg          rx_stop_bit_1;
127
    reg          rx_stop_bit_1_5;
128
    reg          rx_stop_bit_2;
129
    // RX logic signals
130
    wire  [3:0]  rx_total_length;
131
    wire  [5:0]  rx_break_detection_length;
132
    reg          rx_packet_end;
133
    reg          rx_packet_end_q;
134
    reg          rx_clk_cnt_en;
135
    reg  [31:0]  rx_clk_cnt;
136
    reg          rx_sample_clock;
137
    integer      rx_bit_index;
138
    integer      rx_stop_bit_index;
139
    reg   [7:0]  rx_data;
140
    reg   [1:0]  rx_stop;
141
    reg          rx_framing_error;
142
    reg          rx_parity;
143
    reg          rx_parity_error;
144
    reg          rx_break_detected;
145
    reg          rx_break_detected_q;
146
    reg  [31:0]  rx_break_cnt;
147
    // RX events
148
    event        device_received_packet;
149
    event        device_received_last_bit;
150
    event        device_received_stop_bit;
151
    event        device_detected_rx_break;
152
 
153
 
154
  // UART transmitter signals
155
  //#########################
156
 
157
    // TX packet control signals
158
    reg          tx;
159
    reg   [3:0]  tx_length;
160
    reg          tx_odd_parity;
161
    reg          tx_even_parity;
162
    reg          tx_stick1_parity;
163
    reg          tx_stick0_parity;
164
    reg          tx_parity_enabled;
165
    reg          tx_parity_wrong;
166
    reg          tx_framing_wrong;
167
    // TX logic signals
168
    reg  [23:0]  tx_glitch_num;
169
    reg          start_tx_glitch_cnt;
170
    reg  [31:0]  tx_glitch_cnt;
171
    reg          tx_glitch;
172
    reg          tx_break_enable;
173
    reg  [15:0]  tx_break_num;
174
    reg          start_tx_break_cnt;
175
    reg  [31:0]  tx_break_cnt;
176
    reg          tx_break;
177
    // TX test signals
178
    reg   [7:0]  sent_data;
179
    reg          tx_accept_next_framing_err;
180
    reg          tx_framing_err;
181
    reg          tx_framing_glitch_err;
182
    // TX events
183
    event        device_sent_packet;
184
    event        sent_packet_received;
185
 
186
 
187
// Clock generation
188
//#################
189
 
190
  // Example of TESTBENCH's task for setting UART clock period:
191
  //    ----------------
192
  //    task set_uart_clk_period;
193
  //      input [31:0]  clk_period;
194
  //    begin
195
  //      //@(posedge testbench.uart_device.clk);
196
  //      testbench.uart_device.T_clk_period = clk_period;
197
  //    end
198
  //    endtask // set_uart_clk_period
199
  //    ----------------
200
  // Example of TESTBENCH's task for setting UART clock rising edge 
201
  // delayed for time_delay_i after WB clock rising edge:
202
  //    ----------------
203
  //    task uart_clk_follows_wb_clk;
204
  //      input [31:0]  time_delay_i;
205
  //      integer       time_delay;
206
  //    begin
207
  //      time_delay = time_delay_i;
208
  //      @(posedge testbench.uart_device.clk);
209
  //      testbench.uart_device.clk_en = 1'b0;
210
  //      @(posedge wb_clk);
211
  //      #time_delay testbench.uart_device.clk = 1'b1;
212
  //      testbench.uart_device.clk_en = 1'b1;
213
  //    end
214
  //    endtask // uart_clk_follows_wb_clk
215
  //    ----------------
216
 
217
  // rx_clk rising edge
218
  always@(posedge rx_clk)
219
    if (rx_clk_en)
220
      #(T_clk_period / 2) rx_clk = 1'b0;
221
  // rx_clk falling edge
222
  always@(negedge rx_clk)
223
    if (rx_clk_en)
224
      #(T_clk_period / 2) rx_clk = 1'b1;
225
 
226
  // tx_clk rising edge
227
  always@(posedge tx_clk)
228
    if (tx_clk_en)
229
      #((T_clk_period + T_clk_delay) / 2) tx_clk = 1'b0;
230
  // tx_clk falling edge
231
  always@(negedge tx_clk)
232
    if (tx_clk_en)
233
      #((T_clk_period + T_clk_delay) / 2) tx_clk = 1'b1;
234
 
235
  // tx_clk_divided rising edge
236
  always@(posedge tx_clk_divided)
237
    if (tx_clk_divided_en)
238
      #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) tx_clk_divided = 1'b0;
239
  // tx_clk_divided falling edge
240
  always@(negedge tx_clk_divided)
241
    if (tx_clk_divided_en)
242
      #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) tx_clk_divided = 1'b1;
243
 
244
  // Inital CLK values
245
  initial
246
  begin:device
247
    rx_clk = 1'b0;
248
    tx_clk = 1'b0;
249
    tx_clk_divided = 1'b0;
250
  end
251
 
252
 
253
// IN/OUT assignments
254
//###################
255
 
256
  // UART output
257
  assign srx_o = (tx ^ tx_glitch) & ~tx_break;
258
  // Modem output
259
  assign cts_o  = 0;
260
  assign dsr_o  = 0;
261
  assign ri_o   = 0;
262
  assign dcd_o  = 0;
263
  // UART input
264
  assign rx = stx_i;
265
  // Modem input
266
  assign rts = rts_i;
267
  assign dtr = dtr_i;
268
 
269
 
270
// UART receiver
271
//##############
272
 
273
  // Initial values for RX
274
  initial
275
  begin
276
    // Default LENGTH
277
    rx_length = 8;
278
    // Default PARITY
279
    rx_odd_parity     = 1'b0;
280
    rx_even_parity    = 1'b0;
281
    rx_stick1_parity  = 1'b0;
282
    rx_stick0_parity  = 1'b0;
283
    rx_parity_enabled = 1'b0;
284
    // Default STOP
285
    rx_stop_bit_1   = 1'b1;
286
    rx_stop_bit_1_5 = 1'b0;
287
    rx_stop_bit_2   = 1'b0;
288
  end
289
 
290
  // Total length of RX packet (for proper generation of the rx_packet_end signal): 
291
  //   data length + parity + 1 stop bit + second stop bit (when enabled)
292
  assign rx_total_length = rx_length + rx_parity_enabled + 1 + rx_stop_bit_2;
293
  //   +1 is used because start bit was not included in rx_total_length.
294
  assign rx_break_detection_length = rx_total_length + 1;
295
 
296
  // Generating rx_clk_cnt_en signal.
297
  always@(posedge rx_clk)
298
  begin
299
    if (~rx_clk_cnt_en)
300
    begin
301
      wait (~rx);
302
    end
303
    rx_clk_cnt_en = 1;
304
    rx_packet_end = 0;
305
    wait (rx_packet_end);
306
    rx_clk_cnt_en = 0;
307
    wait (rx); // Must be high to continue, because of break condition
308
  end
309
 
310
  // Counter used in data reception
311
  always@(posedge rx_clk)
312
  begin
313
    if (rx_clk_cnt_en)
314
    begin
315
      if (rx_clk_cnt == (8 * T_divisor - 1) & rx) // False start bit detection
316
        rx_packet_end = 1;
317
      if (rx_clk_cnt_en) // Checking is still enabled after devisor clocks
318
        rx_clk_cnt <= #1 rx_clk_cnt + 1;
319
      else
320
        rx_clk_cnt <= #1 0;
321
    end
322
    else
323
      rx_clk_cnt <= #1 0;
324
  end
325
 
326
  // Delayed rx_packet_end signal
327
  always@(posedge rx_clk)
328
    rx_packet_end_q = rx_packet_end;
329
 
330
  // Generating sample clock and end of the frame (Received data is sampled with this clock)
331
  always@(posedge rx_clk)
332
  begin
333
    if (rx_clk_cnt == 8 * T_divisor - 1)
334
      rx_bit_index = 0;
335
    else if (rx_clk_cnt == (8 * T_divisor + 16 * T_divisor * (rx_bit_index + 1) - 1))
336
    begin
337
      rx_sample_clock = 1;
338
      rx_bit_index = rx_bit_index + 1;
339
      if (rx_bit_index == rx_total_length)
340
        rx_packet_end = 1;
341
    end
342
    else
343
      rx_sample_clock = 0;
344
  end
345
 
346
  // Sampling data (received data)
347
  always@(posedge rx_clk)
348
  begin
349
    if (rx_sample_clock)
350
    begin
351
      if (rx_bit_index <= rx_length) // Sampling data
352
      begin
353
        rx_stop_bit_index <= 0; // Stop bit index reset at the beginning of the data stage
354
//        $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading data bits = %0x", rx_bit_index, rx);
355
        rx_data[rx_bit_index - 1] = rx;
356
        if (rx_bit_index == rx_length)
357
          -> device_received_last_bit;
358
      end
359
      else
360
      begin
361
        if (rx_bit_index == (rx_length + 1))
362
        begin
363
          if (rx_parity_enabled)
364
          begin
365
//            $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading parity bits = %0x", rx_bit_index, rx);
366
          end
367
          else
368
          begin
369
            -> device_received_stop_bit;
370
            rx_stop[rx_stop_bit_index] = rx;
371
            rx_stop_bit_index <= rx_stop_bit_index + 1;
372
          end
373
          rx_parity = rx & rx_parity_enabled;
374
        end
375
        if (rx_bit_index >= (rx_length + 1 + rx_parity_enabled))
376
        begin
377
//          $display("\t\t\t\t\t\t\t(rx_bit_index = %0d) Reading stop bits = %0x", rx_bit_index, rx);
378
          rx_stop[rx_stop_bit_index] = rx;
379
          rx_stop_bit_index <= rx_stop_bit_index + 1;
380
        end
381
      end
382
    end
383
 
384
    // Filling the rest of the data with 0
385
    if (rx_length == 5)
386
      rx_data[7:5] = 0;
387
    if (rx_length == 6)
388
      rx_data[7:6] = 0;
389
    if (rx_length == 7)
390
      rx_data[7] = 0;
391
 
392
    // Framing error generation
393
    //   When 1 or 1.5 stop bits are used, only first stop bit is checked
394
    rx_framing_error = (rx_stop_bit_1 | rx_stop_bit_1_5) ? ~rx_stop[0] : ~(&rx_stop[1:0]);
395
 
396
    // Parity error generation
397
    if (rx_odd_parity)
398
      rx_parity_error = ~(^{rx_data, rx_parity});
399
    else if (rx_even_parity)
400
      rx_parity_error = ^{rx_data, rx_parity};
401
    else if (rx_stick0_parity)
402
      rx_parity_error = rx_parity;
403
    else if (rx_stick1_parity)
404
      rx_parity_error = ~rx_parity;
405
    else
406
      rx_parity_error = 0;
407
  end
408
 
409
  // Break detection
410
  always@(posedge rx_clk)
411
  begin
412
    rx_break_detected_q <= rx_break_detected;
413
    if (rx)
414
    begin
415
      rx_break_cnt = 0;         // Reseting counter
416
      rx_break_detected = 0;       // Clearing break detected signal
417
    end
418
    else
419
      rx_break_cnt = rx_break_cnt + 1;
420
    if (rx_break_cnt == rx_break_detection_length * 16 * T_divisor)
421
    begin
422
//      $display("\n(%0t) Break_detected.", $time);
423
      rx_break_detected <= 1;
424
      -> device_detected_rx_break;
425
    end
426
  end
427
 
428
  // Writing received data
429
  always@(posedge rx_clk)
430
  begin
431
    if ((rx_packet_end & ~rx_packet_end_q) | (rx_break_detected & ~rx_break_detected_q))
432
    begin
433
      wait (rx | rx_break_detected); // Waiting for "end of cycle detected" or "break to be activated"
434
      // rx_break_detected
435
      //   rx_length
436
      //   rx_parity_enabled
437
      //     rx_odd_parity | rx_even_parity | rx_stick1_parity | rx_stick0_parity
438
      //   rx_stop_bit_1 | rx_stop_bit_1_5 | rx_stop_bit_2
439
      -> device_received_packet;
440
    end
441
  end
442
 
443
 
444
// UART transmitter
445
//#################
446
 
447
  // Initial values for TX
448
  initial
449
  begin
450
    // Default LENGTH
451
    tx_length = 8;
452
    // Default PARITY
453
    tx_odd_parity     = 1'b0;
454
    tx_even_parity    = 1'b0;
455
    tx_stick1_parity  = 1'b0;
456
    tx_stick0_parity  = 1'b0;
457
    tx_parity_enabled = 1'b0;
458
    // Default CORRECT PARITY
459
    tx_parity_wrong = 1'b0;
460
    // Default CORRECT FRAME
461
    tx_framing_wrong = 1'b0;
462
    tx_framing_err        = 0;
463
    tx_framing_glitch_err = 0;
464
    // Default NO GLITCH
465
    tx_glitch_num = 24'h0;
466
    // Default NO BREAK
467
    tx_break_enable = 1'b0;
468
    tx_break_num = 16'h0;
469
  end
470
 
471
  // Counter for TX glitch generation
472
  always@(posedge tx_clk or posedge start_tx_glitch_cnt)
473
  begin
474
    if (start_tx_glitch_cnt)
475
    begin
476
      tx_glitch_cnt <= tx_glitch_cnt + 1;
477
      if (tx_glitch_cnt == ((tx_glitch_num - 1) * T_divisor))
478
        tx_glitch = 1'b1;
479
      else if (tx_glitch_cnt == (tx_glitch_num * T_divisor))
480
      begin
481
        tx_glitch = 1'b0;
482
        start_tx_glitch_cnt = 1'b0;
483
      end
484
    end
485
    else
486
      tx_glitch_cnt <= 0;
487
  end
488
 
489
  // Break setting & break counter
490
  always@(posedge tx_clk)
491
  begin
492
    if (tx_break_enable && (tx_break_cnt == (tx_break_num * T_divisor)))
493
    begin
494
      start_tx_break_cnt = 0;
495
    end
496
    else if (start_tx_break_cnt)
497
    begin
498
      tx_break_cnt = tx_break_cnt + 1;
499
      tx_break = 1;
500
    end
501
    else
502
    begin
503
      tx_break_cnt = 0;
504
      tx_break = 0;
505
    end
506
  end
507
 
508
  // Sending packets
509
  task send_packet;
510
    input          tx_random_i;
511
    input   [7:0]  tx_data_i;
512
    input          num_of_tx_data_i;
513
    reg     [7:0]  tx_data;
514
    reg            tx_parity_xor;
515
    integer        tx_bit_index;
516
    integer        num_of_tx_data;
517
    reg            last_tx_data;
518
  begin
519
    // SEVERE ERROR
520
    if (// WRONG combinations of parameters for testing 
521
        ((T_clk_delay != 0) && (tx_parity_wrong || tx_framing_wrong))               ||
522
        ((T_clk_delay != 0) && (tx_glitch_num != 0))                                ||
523
        ((T_clk_delay != 0) && (tx_break_enable))                                   ||
524
        ((tx_parity_wrong || tx_framing_wrong) && (tx_glitch_num != 0))             ||
525
        ((tx_parity_wrong || tx_framing_wrong) && (tx_break_enable))                ||
526
        ((tx_glitch_num != 0) && (tx_break_enable))                                 ||
527
        (tx_glitch_num > ((tx_length + 2'h2 + tx_parity_enabled) * 16 * T_divisor)) || // with STOP bit
528
//        (tx_glitch_num > ((tx_length + 2'h1 + tx_parity_enabled) * 16 * T_divisor)) || // without STOP bit
529
        // WRONG input parameters
530
        (num_of_tx_data_i == 0)                                                     ||
531
        ((num_of_tx_data_i > 1) && tx_break_enable)
532
       )
533
    begin
534
      `SEVERE_ERROR("WRONG combination of parameters for testing UART receiver");
535
    end
536
 
537
    for (num_of_tx_data = 0;
538
         num_of_tx_data < num_of_tx_data_i;
539
         num_of_tx_data = (num_of_tx_data + 1'b1))
540
    begin
541
 
542
      if (num_of_tx_data == (num_of_tx_data_i - 1'b1))
543
        last_tx_data = 1'b1;
544
      else
545
        last_tx_data = 0;
546
 
547
      // TX data
548
      if (~tx_random_i)
549
        tx_data = tx_data_i;
550
      else
551
        tx_data = {$random}%256; // 0..255
552
 
553
      // Sending start bit
554
      @(posedge tx_clk_divided);
555
      tx = 0;
556
      if (tx_glitch_num > 0)
557
        start_tx_glitch_cnt = 1;            // enabling tx_glitch generation
558
      if (tx_break_enable)
559
        start_tx_break_cnt = 1;       // Start counter that counts break tx_length
560
      // Wait for almost 1 bit
561
      #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period
562
      #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
563
 
564
      // Sending tx_data bits
565
      for (tx_bit_index = 0; tx_bit_index < tx_length; tx_bit_index = tx_bit_index + 1)
566
      begin
567
        @(posedge tx_clk_divided);
568
        tx = tx_data[tx_bit_index];
569
      end
570
      // Wait for almost 1 bit
571
      #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period
572
      #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
573
 
574
      sent_data = tx_data;
575
 
576
      // Calculating parity
577
      if(tx_length == 5)
578
      begin
579
        tx_parity_xor = ^tx_data[4:0];
580
      end
581
      else if(tx_length == 6)
582
      begin
583
        tx_parity_xor = ^tx_data[5:0];
584
      end
585
      else if(tx_length == 7)
586
      begin
587
        tx_parity_xor = ^tx_data[6:0];
588
      end
589
      else if(tx_length == 8)
590
      begin
591
        tx_parity_xor = ^tx_data[7:0];
592
      end
593
      else
594
        $display("WRONG length of TX data packet");
595
 
596
      // Sending parity bit
597
      if (tx_parity_enabled)
598
      begin
599
        @(posedge tx_clk_divided);
600
        if (tx_odd_parity)
601
          tx = tx_parity_wrong ^ (~tx_parity_xor);
602
        else if (tx_even_parity)
603
          tx = tx_parity_wrong ^ tx_parity_xor;
604
        else if (tx_stick1_parity)
605
          tx = tx_parity_wrong ^ 1;
606
        else if (tx_stick0_parity)
607
          tx = tx_parity_wrong ^ 0;
608
        // Wait for almost 1 bit
609
        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period
610
        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
611
      end
612
 
613
      // Sending stop bit
614
      if (~tx_framing_wrong ||
615
          (tx_glitch_num != ((((tx_length + 2'h2 + tx_parity_enabled) * 2) - 1'b1) * 8 * T_divisor)))
616
      begin
617
        @(posedge tx_clk_divided);
618
        tx = 1;
619
        // Wait for almost 1 bit
620
        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period
621
        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
622
        -> device_sent_packet;
623
        @(sent_packet_received);
624
      end
625
      else if (~tx_framing_wrong ||
626
               (tx_glitch_num == ((((tx_length + 2'h2 + tx_parity_enabled) * 2) - 1'b1) * 8 * T_divisor)))
627
      begin
628
        @(posedge tx_clk_divided);
629
        tx = 1;
630
        // Wait for 1 bit
631
        @(posedge tx_clk_divided); // this will be like 2. stop bit
632
        -> device_sent_packet;
633
        @(sent_packet_received);
634
      end
635
      else if (tx_framing_wrong && last_tx_data)
636
      begin
637
        @(posedge tx_clk_divided);
638
        // Wrong stop | start bit
639
        tx = 0;
640
        @(posedge tx_clk_divided);
641
        -> device_sent_packet;
642
        @(sent_packet_received);
643
        tx_framing_wrong = 0;
644
        // TX data
645
        tx = 1;
646
        tx_data = 8'hFF;
647
        // Sending tx_data bits
648
        for (tx_bit_index = 0; tx_bit_index < tx_length; tx_bit_index = tx_bit_index + 1)
649
        begin
650
          @(posedge tx_clk_divided);
651
          tx = tx_data[tx_bit_index];
652
        end
653
        // Wait for almost 1 bit
654
        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period
655
        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
656
 
657
        sent_data = tx_data;
658
 
659
        // Calculating parity
660
        if(tx_length == 5)
661
        begin
662
          tx_parity_xor = ^tx_data[4:0];
663
        end
664
        else if(tx_length == 6)
665
        begin
666
          tx_parity_xor = ^tx_data[5:0];
667
        end
668
        else if(tx_length == 7)
669
        begin
670
          tx_parity_xor = ^tx_data[6:0];
671
        end
672
        else if(tx_length == 8)
673
        begin
674
          tx_parity_xor = ^tx_data[7:0];
675
        end
676
        else
677
          $display("WRONG length of TX data packet");
678
 
679
        // Sending parity bit
680
        if (tx_parity_enabled)
681
        begin
682
          @(posedge tx_clk_divided);
683
          if (tx_odd_parity)
684
            tx = tx_parity_wrong ^ (~tx_parity_xor);
685
          else if (tx_even_parity)
686
            tx = tx_parity_wrong ^ tx_parity_xor;
687
          else if (tx_stick1_parity)
688
            tx = tx_parity_wrong ^ 1;
689
          else if (tx_stick0_parity)
690
            tx = tx_parity_wrong ^ 0;
691
          // Wait for almost 1 bit
692
          #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period
693
          #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
694
        end
695
 
696
        // Stop bit
697
        @(posedge tx_clk_divided);
698
        tx = 1;
699
        // Wait for almost 1 bit
700
        #(((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor);       // wait half period
701
        #((((T_clk_period + T_clk_delay) / 2) * 16 * T_divisor) - 2); // wait 2 less than half period
702
        -> device_sent_packet;
703
        @(sent_packet_received);
704
        tx_framing_wrong = 1'b1;
705
      end
706
      else if (last_tx_data)
707
      begin
708
        @(posedge tx_clk_divided);
709
        -> device_sent_packet;
710
        @(sent_packet_received);
711
      end
712
    end
713
  end
714
  endtask // send_packet
715
 
716
 
717
endmodule

powered by: WebSVN 2.1.0

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