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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [interfaces/] [uart_interface.sv] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 HanySalah
//-------------------------------------------------------------------------------------------------
2 2 HanySalah
//
3
//                             UART2BUS VERIFICATION
4
//
5 3 HanySalah
//-------------------------------------------------------------------------------------------------
6 2 HanySalah
// CREATOR    : HANY SALAH
7
// PROJECT    : UART2BUS UVM TEST BENCH
8 3 HanySalah
// UNIT       : INTERFACE
9
//-------------------------------------------------------------------------------------------------
10
// TITLE      : UART BFM
11
// DESCRIPTION: THIS FILE ACT AS UART MASTER DEVICE APPLY REQUESTS TO THE DUT ACROSS THE STANDARD
12
//              INTERFACES. IT ALSO INCLUDES ALL THE USER AND STANDARD ROUTINES THAT ARE NEED TO
13
//              APPLY, RECEIVE AND MONITOR UART DIFFERENT ACTIVITIES.
14
//-------------------------------------------------------------------------------------------------
15 2 HanySalah
// LOG DETAILS
16
//-------------
17
// VERSION      NAME        DATE        DESCRIPTION
18
//    1       HANY SALAH    25122015    FILE CREATION
19
//    2       HANY SALAH    07012016    ADD USER ROUTINE, TEXT MODE ROUTINES.
20
//    3       HANY SALAH    21012016    REPLACE PUSH BYTE WITH PUSH FIELD
21 3 HanySalah
//    4       HANY SALAH    31012016    ADD FAULT AND INVALID COMMAND INDICATORS
22
//    5       HANY SALAH    13022016    IMPROVE BLOCK DESCRIPTION & ADD COMMENTS.
23
//    6       HANY SALAH    15022016    ENHANCE BLOCK COMMENTS
24
//    7       HANY SALAH    16022016    ENHANCE BLOCK COMMENTS
25
//    8       HANY SALAH    17022016    FINALIZE BLOCK COMMENTS
26
//-------------------------------------------------------------------------------------------------
27
// ALL COPYRIGHTS ARE RESERVED FOR THE PRODUCER ONLY .THIS FILE IS PRODUCED FOR OPENCORES MEMBERS
28
// ONLY AND IT IS PROHIBTED TO USE THIS MATERIAL WITHOUT THE CREATOR'S PERMISSION
29
//-------------------------------------------------------------------------------------------------
30 2 HanySalah
`include "defin_lib.svh"
31 3 HanySalah
interface uart_interface (input bit clock,        // UART Clock Signal
32 2 HanySalah
                          input bit reset);       // Global Asynchronous Reset Signal
33
 
34 3 HanySalah
//-------------------------------------------------------------------------------------------------
35 2 HanySalah
//
36 3 HanySalah
//                                       BFM PARAMETERS
37 2 HanySalah
//
38 3 HanySalah
//-------------------------------------------------------------------------------------------------
39
  // BFM Paramenters are the ones which are set in the test file and are propagated in the whole
40
  // test-bench. They are defined indetails through test file and specifications document.
41
  // The range of possible values for all the BFM paramters is stated beside each one
42
  //
43
  // Define the active clock edge
44 2 HanySalah
  int                 act_edge;     // 2: negative edge   1: positive edge
45 3 HanySalah
 
46
  // Define the first transferred bit from the byte.
47 2 HanySalah
  int                 start_bit;    // 2: LSB first       1: MSB first
48 3 HanySalah
 
49
  // Define the number of stop bits of each UART field
50 2 HanySalah
  int                 num_stop_bits;// 2: two stop bits   1: one stop bits
51 3 HanySalah
 
52
  // Define the number of actual bits inbetween the start and stop bits.
53 2 HanySalah
  int                 num_bits;     // 7: seven bits data 8: eight bits data
54 3 HanySalah
 
55
  // Define the representation of data through the text mode.
56 2 HanySalah
  int                 data_rep;     // 2: binarry         1: ASCII
57 3 HanySalah
 
58
  // Define the parity mode used.
59
  int                 parity;       // 3: parity odd      2: parity even        1: parity off
60
 
61
  // Define the maximum allowable time between the UART request and the DUT response.
62 2 HanySalah
  time                response_time;
63
 
64 3 HanySalah
  // Define the authorization of false data usage.
65
  int                 falsedata_gen_en;
66 2 HanySalah
 
67 3 HanySalah
//-------------------------------------------------------------------------------------------------
68 2 HanySalah
//
69 3 HanySalah
//                                      UART SIGNLAS
70 2 HanySalah
//
71 3 HanySalah
//-------------------------------------------------------------------------------------------------
72 2 HanySalah
 
73
  logic               ser_in;         // Serial Data Input
74
  logic               ser_out;        // Serial Data Ouptut
75
 
76 3 HanySalah
//-------------------------------------------------------------------------------------------------
77 2 HanySalah
//
78 3 HanySalah
//                                 USER VARIABLES DECLARATIONS
79 2 HanySalah
//
80 3 HanySalah
//-------------------------------------------------------------------------------------------------
81 2 HanySalah
 
82 3 HanySalah
  // The user variables are those ones which facilitate the usage of BFM and they aren't mentioned
83
  // in the standard.
84
  //
85
  // Start_trans event is triggered by the driver at the start of each transaction. it would let
86
  // the other components wake up and poll the UART bus.
87
  // By triggereing this event, other connected components would know that some UART transaction
88
  // would be forced on the UART busses.
89 2 HanySalah
  event start_trans;
90
 
91 3 HanySalah
  // The following two bits are used only in case of apply wrong modes or wrong commands as the
92
  // following:
93
  // wrong_data_ctrl is drived by the driver to state that whether the wrong applied command
94
  // is read or write.
95
  // Actuall BFM shouldn't discriminate between both of types. Its response should be nothing!!.
96
  // But this indication facilitates the scoreboard work.
97
  bit wrong_data_ctrl;           //0:read      1: write
98 2 HanySalah
 
99 3 HanySalah
  // wrong_mode_ctrl is also drived by the driver to state whether the wrong applied mode is
100
  // text or binary.
101
  // Actuall BFM also shouldn't discriminate between both of types. Its response should be
102
  // nothing. But this indication facilitates the scoreboard work.
103
  bit wrong_mode_ctrl;           //0:text      1: binary
104
 
105
//-------------------------------------------------------------------------------------------------
106 2 HanySalah
//
107 3 HanySalah
//                                       USER ROUTINES
108 2 HanySalah
//
109 3 HanySalah
//-------------------------------------------------------------------------------------------------
110 2 HanySalah
 
111 3 HanySalah
  // Through This routine, the uart bfm initializes its configuration parameters described above.
112 2 HanySalah
  function void set_configuration ( int _edge,
113
                                    int first_bit,
114
                                    int _numstopbits,
115
                                    int _numbits,
116
                                    int _datarep,
117
                                    int _paritymode,
118 3 HanySalah
                                    time _resp,
119
                                    int _flse_en);
120 2 HanySalah
    act_edge        = _edge;
121
    start_bit       = first_bit;
122
    num_stop_bits   = _numstopbits;
123
    num_bits        = _numbits;
124
    data_rep        = _datarep;
125
    parity          = _paritymode;
126
    response_time   = _resp;
127 3 HanySalah
    falsedata_gen_en= _flse_en;
128 2 HanySalah
  endfunction: set_configuration
129
 
130
 
131 3 HanySalah
  // Through the following routine, the UART BFM makes an event that some transaction would be
132
  // forced on UART signals
133 2 HanySalah
  function void set_event ();
134
    -> start_trans ;
135
  endfunction:set_event
136
 
137 3 HanySalah
  // This routine is used to force data directly on serial out bus. This routine transform one
138
  // bit only to the form of uart. This form is defined in the definition library.
139
  // High value is defined by the macro `one.
140
  // Low value is defined by the macro `zero.
141 2 HanySalah
  function void force_sout(bit x);
142
    case (x)
143
      1'b1:
144
        begin
145 3 HanySalah
        ser_out = `one;
146 2 HanySalah
        end
147
      1'b0:
148
        begin
149 3 HanySalah
        ser_out = `zero;
150 2 HanySalah
        end
151
    endcase
152
  endfunction:force_sout
153
 
154 3 HanySalah
  // Through this routine, the uart bfm push bit on the serial ouptut port ser_out based on the
155
  // configured active edge field, UART will push bit on data. BFM will assign testbench error in
156
  // case of un-configured active edge.
157 2 HanySalah
  task push_bit_serout (input bit data);
158
    case (act_edge)
159
      `_negedge:
160
        begin
161
        @(negedge clock)
162
          begin
163
          force_sout(data);
164
          end
165
        end
166
      `_posedge:
167
        begin
168
        @(posedge clock)
169
          begin
170
          force_sout(data);
171
          end
172
        end
173
      default:
174
        begin
175 3 HanySalah
        $error("Non-configured active edge");
176 2 HanySalah
        end
177
    endcase
178
  endtask:push_bit_serout
179
 
180 3 HanySalah
  // The following task will catch single bit from serial output port ser_out based on the config-
181
  // ured active edge field, UART will capture data bit. Based on the configured active edge, this
182
  // method block the execution till the correct clock edge and then make delay of a quarter of
183
  // clock period to guarnttee the stability of data on the serial output port.
184
  // BFM will assign testbench error in case of un-configured active edge.
185 2 HanySalah
  task catch_bit_serout (output bit data);
186
    case (act_edge)
187
      `_negedge:
188
        begin
189
        @(negedge clock)
190
          begin
191
          #(`buad_clk_period/4) data = ser_out;
192
          end
193
        end
194
      `_posedge:
195
        begin
196
        @(posedge clock)
197
          begin
198
          #(`buad_clk_period/4) data = ser_out;
199
          end
200
        end
201
      default:
202
        begin
203 3 HanySalah
        $error("Non-configured active edge");
204 2 HanySalah
        end
205
    endcase
206
  endtask:catch_bit_serout
207
 
208 3 HanySalah
  // The following task will catch single bit from serial input port ser_in based on the config-
209
  // ured active edge field, UART will capture data bit. Based on the configured active edge, this
210
  // method block the execution till the correct clock edge and then make delay of a quarter of
211
  // clock period to guarnttee the stability of data on the serial input port.
212
  // BFM will assign testbench error in case of un-configured active edge.
213 2 HanySalah
  task catch_bit_serin (output bit data);
214
    case (act_edge)
215
      `_negedge:
216
        begin
217
        @(negedge clock)
218
          begin
219
          #(`buad_clk_period/4) data = ser_in;
220
          end
221
        end
222
      `_posedge:
223
        begin
224
        @(posedge clock)
225
          begin
226
          #(`buad_clk_period/4)data = ser_in;
227
          end
228
        end
229
      default:
230
        begin
231 3 HanySalah
        $error("Non-configured active edge");
232 2 HanySalah
        end
233
    endcase
234
  endtask:catch_bit_serin
235
 
236 3 HanySalah
  // Through the following task, UART BFM will force data byte on serial output port based on the
237
  // configured start_bit field. This mode encapsulate the data byte inbetween start,stop and even
238
  // parity bits. The sequence would be the following:
239
  // 1- Force zero bit on the serial output port as start bit.
240
  // 2- Send the data byte serially bit by bit.
241
  // 3- Accoriding to configured parity, force parity bit (optional).
242
  // 4- Insert one or two stop bits according to BFM configuration.
243
  // BFM will assign testbench error in case of un-configured parameters.
244 2 HanySalah
  task push_field_serout (input byte data);
245 3 HanySalah
 
246
    bit temp;
247
 
248 2 HanySalah
    // start bit
249
    push_bit_serout(1'b0);
250
 
251
    // data fields
252
    case (start_bit)
253
      `lsb_first:
254
        begin
255
        for (int index=0;index<8;index++)
256
          begin
257
          push_bit_serout(data[index]);
258
          end
259
        end
260
      `msb_first:
261
        begin
262
        for (int index=7;index>=0;index--)
263
          begin
264
          push_bit_serout(data[index]);
265
          end
266
        end
267
      default:
268
        begin
269
        $error("Undefined serial mode");
270
        end
271
    endcase
272 3 HanySalah
    // parity bits
273
    if(parity == `_parityeven)
274
      begin
275
      temp=1'b1;
276
      for (int index=0;index <8;index++)
277
        begin
278
        temp = temp ^ data [index];
279
        end
280
      end
281
    else if(parity == `_parityodd)
282
      begin
283
      temp=1'b0;
284
      for (int index=0;index <8;index++)
285
        begin
286
        temp = temp ^ data [index];
287
        end
288
      end
289
    else if (parity != `_parityoff)
290
      begin
291
      $error("un-configured parity");
292
      end
293 2 HanySalah
    // Stop bit(s)
294
    repeat (num_stop_bits)
295
      begin
296
      push_bit_serout(1'b1);
297
      end
298
 
299
  endtask:push_field_serout
300
 
301 3 HanySalah
  // Through the following task, UART BFM will catpure UART field from serial output port based on
302
  // the configured start_bit field. The following sequence is carried out :
303
  // 1- Wait start bit.
304
  // 2- Catpure the following eight bits in packed byte depending on the configured start bit.
305
  // 3- Depending on the configured number of stop bits, the stop bit(s) are captured.
306
  //    - In case that stop bit(s) is zero, the testbench will assign testbench error.
307
  // BFM will assign testbench error in case of un-configured start_bit field.
308 2 HanySalah
  task catch_field_serout (output byte data);
309
    bit end_bit;
310
 
311
    // wait start bit
312
    wait(ser_out == 1'b0);
313
    case(start_bit)
314
      `lsb_first:
315
        begin
316
        for (int index=0;index<8;index++)
317
          begin
318
          catch_bit_serout(data[index]);
319
          end
320
        end
321
      `msb_first:
322
        begin
323
        for (int index=7;index>=0;index--)
324
          begin
325
          catch_bit_serout(data[index]);
326
          end
327
        end
328
      default:
329
        begin
330
        $error("Undefined serial mode");
331
        end
332
    endcase
333
    catch_bit_serout(end_bit);
334
    if(end_bit != 1'b1)
335
      begin
336
      $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
337
      end
338
    if (num_stop_bits == 2)
339
      begin
340
      catch_bit_serout(end_bit);
341
      if(end_bit != 1'b1)
342
        begin
343
        $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
344
        end
345
      end
346
  endtask:catch_field_serout
347
 
348 3 HanySalah
  // Through the following task, UART BFM will catpure UART field from serial input port based on
349
  // the configured start_bit field. The applied sequence here differs from the one applied on
350
  // capture field from serial output port since wrong and unknown commands are forced to the DUT
351
  // on the UART interface. The DUT is supposed to make no response to such commands.
352
  // This routine pays concern to this issue by initiating two parallel threads at the beginning;
353
  // 1- The first one run in the background to wait response time and triggered some internal
354
  //    event (terminate event). It also set internal bit (path_select) to zero to make an
355
  // indication that no response has been made.
356
  // 2- The second one includes two parallel sub-threads:
357
  //    a- The first one wait start bit.
358
  //    b- The other one wait terminate event triggering.
359
  //    Whenever one of those sub-threads is terminated, The main thread is joined.
360
  // The following sequence is carried out in case that start bit is captured:
361
  // 1- Wait start bit.
362
  // 2- Catpure the following eight bits in packed byte depending on the configured start bit.
363
  // 3- Depending on the configured number of stop bits, the stop bit(s) are captured.
364
  //    - In case that stop bit(s) is zero, the testbench will assign testbench error.
365
  // BFM will assign testbench error in case of un-configured start_bit field.
366 2 HanySalah
  task catch_field_serin (output byte data);
367
    bit end_bit;
368 3 HanySalah
    bit path_select;
369
    event terminate;
370
    path_select = 1'b1;
371
    fork
372
      begin
373
      #response_time;
374
      -> terminate;
375
      path_select = 1'b0;
376
      end
377
    join_none
378 2 HanySalah
 
379 3 HanySalah
    fork
380
      wait (ser_in == 1'b0);
381
      wait (terminate);
382
    join_any
383
 
384
    if (path_select)
385
      begin
386
      #(`buad_clk_period/2);
387
      case(start_bit)
388
        `lsb_first:
389 2 HanySalah
          begin
390 3 HanySalah
          for (int index=0;index<8;index++)
391
            begin
392
            catch_bit_serin(data[index]);
393
            end
394 2 HanySalah
          end
395 3 HanySalah
        `msb_first:
396 2 HanySalah
          begin
397 3 HanySalah
          for (int index=7;index>=0;index--)
398
            begin
399
            catch_bit_serin(data[index]);
400
            end
401 2 HanySalah
          end
402 3 HanySalah
        default:
403
          begin
404
          $error("Undefined serial mode");
405
          end
406
      endcase
407 2 HanySalah
      catch_bit_serin(end_bit);
408
      if(end_bit != 1'b1)
409
        begin
410
        $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
411
        end
412 3 HanySalah
      if (num_stop_bits == 2)
413
        begin
414
        catch_bit_serin(end_bit);
415
        if(end_bit != 1'b1)
416
          begin
417
          $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
418
          end
419
        end
420 2 HanySalah
      end
421 3 HanySalah
 
422 2 HanySalah
  endtask:catch_field_serin
423
 
424 3 HanySalah
  // Through the following function, the byte is reversed in the manner where the byte is merrored
425 2 HanySalah
  function byte reverse_byte (byte data);
426
    byte tmp;
427
    for (int index=0;index<8;index++)
428
      begin
429
      tmp[index] = data[7-index];
430
      end
431
    return tmp;
432
  endfunction:reverse_byte
433
 
434 3 HanySalah
//-------------------------------------------------------------------------------------------------
435 2 HanySalah
//
436 3 HanySalah
//                                      UART ROUTINES
437 2 HanySalah
//
438 3 HanySalah
//-------------------------------------------------------------------------------------------------
439 2 HanySalah
 
440 3 HanySalah
  // This method is provided to initiate write request in UART text mode. This task is accomplis-
441
  // hed through the following sequence:
442
  // 1- The first field :(Prefix Character)
443
  //    Depending on whether the mode type is text or wrong text and whether the prefix is small
444
  //    or capital character, the BFM force the prefix field. In case of wrong text type, the init-
445
  //    ial field is the provided wrong_prefix input. also internal wrong_mode_ctrl bit is cleared.
446
  //    - In case of undefined type, testbench assign testbench error.
447
  //                               -----------------------
448
  // 2- The second field:(White Space Character)
449
  //    Depending on whether the used white space type is a single space, a tab space or provided
450
  //    wrong space character is forced on the serial output port.
451
  //                               -----------------------
452
  // 3- The third field:(Data Character)
453
  //    - In case of the data representation is binary, the data input character is encapsulated
454
  //      in UART field and forced in single field.
455
  //    - In case of the data representation is ASCII, the data input character is divided into
456
  //      two nipples. Each one is converted to ASCII character and sent separately in UART field.
457
  //      The most significant nipple is sent first.
458
  //                               -----------------------
459
  // 4- The forth field:(White Space Character)
460
  //    Depending on whether the used white space type is a single space, a tab space or provided
461
  //    wrong space character is forced on the serial output port.
462
  //                               -----------------------
463
  // 5- The fifth field:(Address Two-Character)
464
  //    - In case of the data representation is binary, the address input two-character is divided
465
  //      into two characters. They are encapsulated into two successive UART fields.
466
  //    - In case of the data representation is ASCII, the address input two-character is divided
467
  //      into four nipples. Each one is converted to ASCII character and sent separately in UART
468
  //      field. The ASCII characters are sent where the most significant nipple is sent first.
469
  //                               -----------------------
470
  // 6- The sixth field:(End-Of-Line Character):
471
  //    Depending on whether the used EOL type is CR, LF or provided wrong space character is
472
  //    forced on the serial output port.
473
  //                               -----------------------
474
  task write_text_mode(input int _type,
475
                       input byte wrong_prefix,
476
                       input int alph,
477 2 HanySalah
                       input int scp_type1,
478
                       input byte space_wrong1,
479
                       input int scp_type2,
480
                       input byte space_wrong2,
481
                       input int eol,
482
                       input byte eol_wrong,
483
                       input bit [`size-1:0] address,
484
                       input byte data);
485
    // Write procedures
486 3 HanySalah
    // First Field
487
    case (_type)
488
      `text_mode:
489 2 HanySalah
        begin
490 3 HanySalah
        if (alph == `small_let)
491
          begin
492
          push_field_serout(`w);
493
          end
494
        else if (alph == `capital_let)
495
          begin
496
          push_field_serout(`W);
497
          end
498
        else
499
          $error("Testbench error .. No capitar or small letter is choosed");
500 2 HanySalah
        end
501 3 HanySalah
      `wrong_mode_txt:
502 2 HanySalah
        begin
503 3 HanySalah
        push_field_serout(wrong_prefix);
504
        wrong_mode_ctrl = 1'b0;
505 2 HanySalah
        end
506 3 HanySalah
      default:
507 2 HanySalah
        begin
508 3 HanySalah
        $error("Undefined communication mode ..");
509 2 HanySalah
        end
510 3 HanySalah
    endcase
511 2 HanySalah
 
512 3 HanySalah
    // Second Field
513
    if (scp_type1 == `single_space)
514
      begin
515
      push_field_serout(`space);
516
      end
517
    else if (scp_type1 == `tab_space)
518
      begin
519
      push_field_serout(`tab);
520
      end
521
    else if (scp_type1 == `space_wrong)
522
      begin
523
      push_field_serout(space_wrong1);
524
      end
525
    else
526
      $error("Testbench error .. No single space or multiple space is choosed");
527 2 HanySalah
 
528 3 HanySalah
    // third field
529
    case (data_rep)
530
      `binary_rep:
531 2 HanySalah
        begin
532 3 HanySalah
        push_field_serout(data);
533 2 HanySalah
        end
534 3 HanySalah
      `ascii_rep:
535 2 HanySalah
        begin
536 3 HanySalah
        push_field_serout(bin_asci_conv(data[7:4]));
537
        push_field_serout(bin_asci_conv(data[3:0]));
538 2 HanySalah
        end
539 3 HanySalah
      default:$error("undefined data representation");
540
    endcase
541 2 HanySalah
 
542 3 HanySalah
    // forth field
543
    if (scp_type2 == `single_space)
544
      begin
545
      push_field_serout(`space);
546
      end
547
    else if (scp_type2 == `tab_space)
548
      begin
549
      push_field_serout(`tab);
550
      end
551
    else if (scp_type2 == `space_wrong)
552
      begin
553
      push_field_serout(space_wrong2);
554
      end
555
    else
556
      $error("Testbench error .. No single or multiple space is choosed");
557
    // fivth field
558
    case (data_rep)
559
      `binary_rep:
560 2 HanySalah
        begin
561 3 HanySalah
        push_field_serout(address[15:08]);
562
        push_field_serout(address[07:00]);
563 2 HanySalah
        end
564 3 HanySalah
      `ascii_rep:
565 2 HanySalah
        begin
566 3 HanySalah
        push_field_serout(bin_asci_conv(address[15:12]));
567
        push_field_serout(bin_asci_conv(address[11:08]));
568
        push_field_serout(bin_asci_conv(address[07:04]));
569
        push_field_serout(bin_asci_conv(address[03:00]));
570 2 HanySalah
        end
571 3 HanySalah
      default:$error("undefined data representation");
572
    endcase
573
 
574
    // sixth Field
575
    if (eol == `cr_eol)
576
      begin
577
      push_field_serout(`CR);
578
      end
579
    else if (eol == `lf_eol)
580
      begin
581
      push_field_serout(`LF);
582
      end
583
    else if (eol == `eol_wrong)
584
      begin
585
      push_field_serout(eol_wrong);
586
      end
587
    else
588
      $error("Testbench error .. either CR or LF isn't choosed as eol");
589 2 HanySalah
  endtask:write_text_mode
590
 
591 3 HanySalah
  // This method is provided to initiate read request in UART text mode. This task is accomplis-
592
  // hed through the following sequence:
593
  // 1- The first field :(Prefix Character)
594
  //    Depending on whether the mode type is text or wrong text and whether the prefix is small
595
  //    or capital character, the BFM force the prefix field. In case of wrong text type, the init-
596
  //    ial field is the provided wrong_prefix input. also internal wrong_mode_ctrl bit is cleared.
597
  //    - In case of undefined type, testbench assign testbench error.
598
  //                               -----------------------
599
  // 2- The second field:(White Space Character)
600
  //    Depending on whether the used white space type is a single space, a tab space or provided
601
  //    wrong space character is forced on the serial output port.
602
  //                               -----------------------
603
  // 3- The third field:(Address Two-Character)
604
  //    - In case of the data representation is binary, the address input two-character is divided
605
  //      into two characters. They are encapsulated into two successive UART fields.
606
  //    - In case of the data representation is ASCII, the address input two-character is divided
607
  //      into four nipples. Each one is converted to ASCII character and sent separately in UART
608
  //      field. The ASCII characters are sent where the most significant nipple is sent first.
609
  //                               -----------------------
610
  // 4- The forth field:(End-Of-Line Character):
611
  //    Depending on whether the used EOL type is CR, LF or provided wrong space character is
612
  //    forced on the serial output port.
613
  //                               -----------------------
614
  // GETTING RESPONSE :
615
  //    Since we may have no response due to either DUT internal bug or the forced request is
616
  //    wrong (wrong mode, wrong white space, wrong eol), two parallel threads are initiated; The
617
  //    first one is to wait for response time and the other one waits start bit on the serial
618
  //    input port. Both the two threads are terminated by meeting only one of the two events.
619
  //    In case of the start bit is captured and according to the configured the data representa-
620
  //    tion.
621
  //    - If it is binary, the following UART field is captured and its data is considered to be
622
  //      the requested data.
623
  //    - If it is ASCII, the two successive UART fields is captured and each byte is converted to
624
  //      binary nipple.
625
  //    The following character is captured and it must be CR.
626
  //    The following character is captured and it must be LF.
627
  //    - If the last two characters aren't as indicated above, the testbench will assign testbench
628
  //      error.
629
  //                               -----------------------
630
  task read_text_mode (input int _type,
631
                       input byte wrong_prefix,
632
                       input int alph,
633 2 HanySalah
                       input int scp_type,
634
                       input byte space_wrong,
635
                       input int eol,
636
                       input byte eol_wrong,
637 3 HanySalah
                       input bit [`size-1:0] address,
638
                       input byte false_data,
639
                       input int false_data_en);
640 2 HanySalah
    byte data;
641
    byte temp;
642
    byte char1,char2;
643
    bit miss;
644
    // Read Request
645 3 HanySalah
    // First Field
646
    case (_type)
647
      `text_mode:
648 2 HanySalah
        begin
649 3 HanySalah
        if (alph == `small_let)
650
          begin
651
          push_field_serout(`r);
652
          end
653
        else if (alph == `capital_let)
654
          begin
655
          push_field_serout(`R);
656
          end
657
        else
658
          $error("Testbench error .. No capitar or small letter is choosed");
659 2 HanySalah
        end
660 3 HanySalah
      `wrong_mode_txt:
661 2 HanySalah
        begin
662 3 HanySalah
        push_field_serout(wrong_prefix);
663
        wrong_mode_ctrl = 1'b0;
664 2 HanySalah
        end
665 3 HanySalah
      default:
666 2 HanySalah
        begin
667 3 HanySalah
        $error("Undefined communication mode ..");
668 2 HanySalah
        end
669 3 HanySalah
    endcase
670
 
671
    // Second Field
672
    if (scp_type == `single_space)
673
      begin
674
      push_field_serout(`space);
675
      end
676
    else if (scp_type == `tab_space)
677
      begin
678
      push_field_serout(`tab);
679
      end
680
    else if (scp_type == `space_wrong)
681
      begin
682
      push_field_serout(space_wrong);
683
      end
684
    else
685
      $error("Testbench error .. No single or multiple white space is choosed");
686
 
687
    // Third Field
688
    case (data_rep)
689
      `binary_rep:
690 2 HanySalah
        begin
691 3 HanySalah
        push_field_serout(address[15:08]);
692
        push_field_serout(address[07:00]);
693 2 HanySalah
        end
694 3 HanySalah
      `ascii_rep:
695 2 HanySalah
        begin
696 3 HanySalah
        push_field_serout(bin_asci_conv(address[15:12]));
697
        push_field_serout(bin_asci_conv(address[11:08]));
698
        push_field_serout(bin_asci_conv(address[07:04]));
699
        push_field_serout(bin_asci_conv(address[03:00]));
700 2 HanySalah
        end
701 3 HanySalah
      default:$error("undefined data representation");
702
    endcase
703 2 HanySalah
 
704 3 HanySalah
    // Forth Field
705
    if (eol == `cr_eol)
706
      begin
707
      push_field_serout(`CR);
708
      end
709
    else if (eol == `lf_eol)
710
      begin
711
      push_field_serout(`LF);
712
      end
713
    else if (eol == `eol_wrong)
714
      begin
715
      push_field_serout(eol_wrong);
716
      end
717
    else
718
      $error("Testbench error .. No CR or LF is choosed");
719
 
720
    miss = 1'b0;
721
    fork
722
      begin: miss_response_thread
723
      # response_time;
724
      disable capture_response_thread;
725
      miss = 1'b1;
726
      end
727
 
728
      begin: capture_response_thread
729
      wait(ser_in == 1'b0);
730
      disable miss_response_thread;
731
      end
732
    join
733
    // Capture Response
734
    if (miss == 1'b0)
735
      begin
736
      if (false_data_en ==`_yes && falsedata_gen_en == `_yes)
737
        begin
738
        fork
739
        push_field_serout(false_data);
740
        join_none
741
        end
742 2 HanySalah
      case (data_rep)
743
        `binary_rep:
744
          begin
745 3 HanySalah
          catch_field_serin(data);
746 2 HanySalah
          end
747
        `ascii_rep:
748
          begin
749 3 HanySalah
          catch_field_serin(temp);
750
          data[7:4] = asci_bin_conv(temp);
751
          catch_field_serin(temp);
752
          data[3:0] = asci_bin_conv(temp);
753 2 HanySalah
          end
754 3 HanySalah
        default:
755 2 HanySalah
          begin
756 3 HanySalah
          $error("Undefined data representation");
757
          $stop;
758 2 HanySalah
          end
759 3 HanySalah
      endcase
760
      catch_field_serin(char1);
761
      catch_field_serin(char2);
762
      if (char1 != `CR || char2 != `LF)
763 2 HanySalah
        begin
764 3 HanySalah
        $error("EOL is refuesed");
765 2 HanySalah
        end
766 3 HanySalah
      end
767 2 HanySalah
  endtask:read_text_mode
768
 
769 3 HanySalah
  // This method is provided to initiate write request in UART binary mode. This task is accompli-
770
  // shed through the following sequence:
771
  //                               -----------------------
772
  //          NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO DEFINED UART FIELD FORM
773
  //                               -----------------------
774
  // 1- The first byte :(Prefix byte)
775
  //    Depending on whether the mode type is binary or wrong binary the BFM force the prefix field
776
  //    In case of wrong binary type, the initial field is the provided wrong_prefix input. also
777
  //    internal wrong_mode_ctrl bit is set.
778
  //    - In case of undefined type, testbench assign testbench error.
779
  //                               -----------------------
780
  // 2- The second byte:(Command byte)
781
  //    Depending on whether the command is valid or invalid command, the two bits of the command
782
  //    are assigned. Also the auto increment bit and acknowledge request bit are assigned
783
  //                               -----------------------
784
  // 3- The third byte:(Address highest byte)
785
  //    - The address bits [15:08] .
786
  //                               -----------------------
787
  // 4- The forth field:(Address lowest byte)
788
  //    - The address bits [07:00] .
789
  //                               -----------------------
790
  // 5- The fifth field:(Length Of Data byte)
791
  //    - The number of data bytes inclosed into this stimulus.
792
  //                               -----------------------
793
  // 6- The rest fields:(Data):
794
  //    Data Bytes are sent one by one.
795
  //                               -----------------------
796
  // GETTING RESPONSE:
797
  //    In case that the command includes acknowledge request, UART BFM will wait for the ackno-
798
  //    wledge unified character.
799
  //                               -----------------------
800
  task automatic write_binary_mode (input int _type,
801
                                    input byte wrong_prefix,
802
                                    input int command,
803
                                    input int reqack,
804 2 HanySalah
                                    input int reqinc,
805
                                    input int unsigned data_length,
806
                                    input bit [`size-1:0] address,
807
                                    ref byte data []);
808
    byte tmp;
809
    int unsigned index;
810
 
811
    // first byte : binary prefix
812 3 HanySalah
    case(_type)
813
    `binary_mode:
814
      begin
815
      push_field_serout(`bin_prfx);
816
      end
817
    `wrong_mode_binry:
818
      begin
819
      push_field_serout(wrong_prefix);
820
      wrong_mode_ctrl = 1'b1;
821
      end
822
    default:
823
      begin
824
      $error("Undefined Communication Mode");
825
      end
826
    endcase
827 2 HanySalah
 
828
    // second byte : command
829 3 HanySalah
    case(command)
830
      `write_comm:
831
        begin
832
        tmp[5:4] = `write_ctrl;
833
        end
834
      `wrong_comm_write:
835
        begin
836
        tmp[5:4] = `invalid_ctrl;
837
        wrong_data_ctrl = 1'b1;
838
        end
839
      default:
840
        begin
841
        $error("Undefined Command");
842
        end
843
    endcase
844 2 HanySalah
    tmp[5:4] = 2'b10;
845
    if(reqinc==`_yes)
846
      begin
847
      tmp[1] = 1'b0;
848
      end
849
    else if (reqinc == `_no)
850
      begin
851
      tmp[1] = 1'b1;
852
      end
853
    else
854
      begin
855
      $error("undefined increment request");
856
      end
857
 
858
    if(reqack==`_yes)
859
      begin
860
      tmp[0] = 1'b1;
861
      end
862
    else if (reqack == `_no)
863
      begin
864
      tmp[0] = 1'b0;
865
      end
866
    else
867
      begin
868
      $error("undefined acknowledge request");
869
      end
870
    push_field_serout(tmp);
871
 
872
    // Third byte : higher byte of address
873
    push_field_serout(address[15:08]);
874
 
875
    // Forth byte : Lower byte of address
876
    push_field_serout(address[07:00]);
877
 
878
    // Fifth byte : data length
879
    push_field_serout(data_length);
880
 
881
    index = 0;
882
    while(index
883
      begin
884
      push_field_serout(data[index]);
885
      index++;
886
      end
887
 
888
    if (reqack == `_yes)
889
      begin
890
      catch_field_serin(tmp);
891
      if (tmp != `ACK)
892
        begin
893
        $error("The captured acknowledge isn't as unified character");
894
        end
895
      end
896
  endtask:write_binary_mode
897
 
898 3 HanySalah
  // This method is provided to initiate read request in UART binary mode. This task is accompli-
899
  // shed through the following sequence:
900
  //                               -----------------------
901
  //          NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO UART DEFINED FIELD FORM
902
  //                               -----------------------
903
  // 1- The first byte :(Prefix byte)
904
  //    Depending on whether the mode type is binary or wrong binary the BFM force the prefix field
905
  //    In case of wrong binary type, the initial field is the provided wrong_prefix input. also
906
  //    internal wrong_mode_ctrl bit is set.
907
  //    - In case of undefined type, testbench assign testbench error.
908
  //                               -----------------------
909
  // 2- The second byte:(Command byte)
910
  //    Depending on whether the command is valid or invalid command, the two bits of the command
911
  //    are assigned. Also the auto increment bit and acknowledge request bit are assigned
912
  //                               -----------------------
913
  // 3- The third byte:(Address highest byte)
914
  //    - The address bits [15:08] .
915
  //                               -----------------------
916
  // 4- The forth field:(Address lowest byte)
917
  //    - The address bits [07:00] .
918
  //                               -----------------------
919
  // 5- The fifth field:(Length Of Data byte)
920
  //    - The number of data bytes inclosed into this stimulus.
921
  //                               -----------------------
922
  // GETTING RESPONSE:
923
  //    Through this field, three independent parallel processes are carried out :
924
  //    i- The first one is mendatory and is responsible for capturing the UART fields drived by
925
  //       The DUT on the serial input port. Also it is responsible for capturing the acknowledge
926
  //       byte in case that the command include acknowledge request.
927
  //   ii- The second one is responsible for terminating this routine in case that no response has
928
  //       been driven by the DUT within the response time.
929
  //  iii- The last one is to drive dummy UART fields. It is used only when both the internal
930
  //       false data enable and the global false data enable are set. Refer to UART testbench
931
  //       specifications document for more details.
932
  //                               -----------------------
933
  task automatic read_binary_mode  (input int _type,
934
                                    input byte wrong_prefix,
935
                                    input int _command,
936
                                    input int reqack,
937 2 HanySalah
                                    input int reqinc,
938
                                    input int unsigned data_length,
939
                                    input bit [`size-1:0] address,
940 3 HanySalah
                                    ref byte data [],
941
                                    ref byte false_data [],
942
                                    input bit false_data_en);
943 2 HanySalah
    byte tmp;
944
    int unsigned index;
945 3 HanySalah
    int unsigned index_false;
946 2 HanySalah
 
947
    // first byte : binary prefix
948 3 HanySalah
    case (_type)
949
      `binary_mode:
950
        begin
951
        push_field_serout(`bin_prfx);
952
        end
953
      `wrong_mode_binry:
954
        begin
955
        push_field_serout(wrong_prefix);
956
        wrong_mode_ctrl = 1'b1;
957
        end
958
      default:
959
        begin
960
        $error("Undefined Communication Mode");
961
        end
962
    endcase
963 2 HanySalah
 
964
    // second byte : command
965 3 HanySalah
    case (_command)
966
      `read_comm:
967
        begin
968
        tmp[5:4] = `read_ctrl;
969
        end
970
      `wrong_comm_read:
971
        begin
972
        tmp[5:4] = `invalid_ctrl;
973
        wrong_data_ctrl = 1'b0;
974
        end
975
      default:
976
        begin
977
        $error("Undefined Command type");
978
        end
979
    endcase
980
 
981 2 HanySalah
    if(reqinc==`_yes)
982
      begin
983
      tmp[1] = 1'b0;
984
      end
985
    else if (reqinc == `_no)
986
      begin
987
      tmp[1] = 1'b1;
988
      end
989
    else
990
      begin
991
      $error("undefined increment request");
992
      end
993
 
994
    if(reqack==`_yes)
995
      begin
996
      tmp[0] = 1'b1;
997
      end
998
    else if (reqack == `_no)
999
      begin
1000
      tmp[0] = 1'b0;
1001
      end
1002
    else
1003 8 HanySalah
      begin
1004
      $error("undefined acknowledge request");
1005
      end
1006 2 HanySalah
    push_field_serout(tmp);
1007
 
1008
    // Third byte : higher byte of address
1009
    push_field_serout(address[15:08]);
1010
 
1011
    // Forth byte : Lower byte of address
1012
    push_field_serout(address[07:00]);
1013
 
1014
    // Fifth byte : data length
1015 3 HanySalah
    if (data_length == 256)
1016 2 HanySalah
      begin
1017 3 HanySalah
      tmp = 8'b00;
1018 2 HanySalah
      end
1019 3 HanySalah
    else
1020
      begin
1021
      tmp = data_length;
1022
      end
1023
    push_field_serout(tmp);
1024 2 HanySalah
 
1025 3 HanySalah
    index = 0;
1026
 
1027
    fork
1028
      if(false_data_en == `_yes && falsedata_gen_en == `_yes)
1029
        begin
1030
        while(index_false
1031
          begin
1032
          push_field_serout(false_data[index_false]);
1033
          index_false++;
1034
          end
1035
        end
1036
      while(index
1037
        begin
1038
        catch_field_serin(data[index]);
1039
        index++;
1040
        end
1041
    join
1042 2 HanySalah
    if (reqack == `_yes)
1043
      begin
1044
      catch_field_serin(tmp);
1045 3 HanySalah
      if (tmp != `ACK && _type == `binary_mode && _command == `read_comm)
1046 2 HanySalah
        begin
1047
        $error("The captured acknowledge isn't as unified character");
1048
        end
1049
      end
1050
  endtask:read_binary_mode
1051
 
1052 3 HanySalah
  // This method is provided to initiate NOP command in UART binary mode. This task is accompli-
1053
  // shed through the following sequence:
1054
  //                               -----------------------
1055
  //          NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO UART DEFINED FIELD FORM
1056
  //                               -----------------------
1057
  // 1- The first byte :(Prefix byte)
1058
  //    Depending on whether the mode type is binary or wrong binary the BFM force the prefix field
1059
  //    In case of wrong binary type, the initial field is the provided wrong_prefix input. also
1060
  //    internal wrong_mode_ctrl bit is set.
1061
  //    - In case of undefined type, testbench assign testbench error.
1062
  //                               -----------------------
1063
  // 2- The second byte:(Command byte)
1064
  //    The two bits of commads are assigned. Also the auto increment bit and acknowledge request
1065
  //    bit are assigned
1066
  //                               -----------------------
1067
  // GETTING RESPONSE:
1068
  //    In case that the command includes acknowledge request, UART BFM will wait for the ackno-
1069
  //    wledge unified character.
1070
  //                               -----------------------
1071
  task nop_command (input int _type,
1072
                    input byte wrong_prefix,
1073
                    input int reqack,
1074 2 HanySalah
                    input int reqinc);
1075
    byte tmp;
1076
    int unsigned index;
1077
    // first byte : prefix
1078 3 HanySalah
    wrong_mode_ctrl = 1'b0;
1079
    // first byte : binary prefix
1080
    case (_type)
1081
      `binary_mode:
1082
        begin
1083
        push_field_serout(`bin_prfx);
1084
        end
1085
      `wrong_mode_binry:
1086
        begin
1087
        push_field_serout(wrong_prefix);
1088
        wrong_mode_ctrl = 1'b1;
1089
        end
1090
      default:
1091
        begin
1092
        $error("Undefined Communication Mode");
1093
        end
1094
    endcase
1095 2 HanySalah
 
1096
    // second byte :  command
1097
    tmp[5:4] = 2'b00;
1098
    if(reqinc==`_yes)
1099
      begin
1100
      tmp[1] = 1'b0;
1101
      end
1102
    else if (reqinc == `_no)
1103
      begin
1104
      tmp[1] = 1'b1;
1105
      end
1106
    else
1107
      begin
1108
      $error("undefined increment request");
1109
      end
1110
 
1111
    if(reqack==`_yes)
1112
      begin
1113
      tmp[0] = 1'b1;
1114
      end
1115
    else if (reqack == `_no)
1116
      begin
1117
      tmp[0] = 1'b0;
1118
      end
1119
    else
1120
      begin
1121
      $error("undefined acknowledge request");
1122
      end
1123
    push_field_serout(tmp);
1124
 
1125
    if(reqack==`_yes)
1126
      begin
1127
      catch_field_serin(tmp);
1128
      if(tmp!=`ACK)
1129
        begin
1130
        $error("Undefined acknowledge character");
1131
        end
1132
      end
1133
  endtask:nop_command
1134
 
1135 3 HanySalah
  // This task is used to make the bus idle for time (idle).
1136 2 HanySalah
  task wait_idle_time (time idle);
1137
    force_sout(1'b1);
1138
    #idle;
1139
  endtask: wait_idle_time
1140
 
1141 3 HanySalah
//-------------------------------------------------------------------------------------------------
1142 2 HanySalah
//
1143 3 HanySalah
//                                     MONITOR ROUTINES
1144 2 HanySalah
//
1145 3 HanySalah
//-------------------------------------------------------------------------------------------------
1146
  // This section of routines is used to monitor the UART signals and capture all the informations
1147
  // about the stimulus, DUT state and DUT response as well. Each one is described in details below
1148
  //
1149
  // This routine is used to wait for transaction start. It waits for start_trans triggering.
1150 2 HanySalah
  task wait_event();
1151
    wait (start_trans);
1152
  endtask:wait_event
1153
 
1154 3 HanySalah
  // This method is the main method of the monitoring routines used to capture the UART
1155
  // transactions on the UART interfaces. Whenever it is called, it carries out the following
1156
  // procedures:
1157
  // 1- Capture the first field loaded on the serial output port and detect the command type to be
1158
  //    either text read, text write, binary, wrong command. And according to the command, another
1159
  //    proper task will be called.
1160
  // NOTE: In case of wrong command, with the aid of internal bit wrong_mode_ctrl, UART BFM could
1161
  //       detect the actual type of wrong command.
1162
  //                               -----------------------
1163
  // 2- (I) In case that the command type is text, the dynamic array of data is initialized with
1164
  //        the standard size one byte. Also command and character type fields are assigned. Refer
1165
  //        to transaction fields for more informations about these fields.
1166
  //   (II) In case that the command type is binary, capture_binary_command task is called.
1167
  //  (III) In case that the command type is wrong, nothing is done.
1168
  task automatic capture_command (output int command_type,
1169
                                  output int _command,
1170
                                  output int _chartype,
1171
                                  output int _spacetype1,
1172
                                  output int space_wrong1,
1173
                                  output int _spacetype2,
1174
                                  output int space_wrong2,
1175
                                  output int _eoltype,
1176
                                  output int eol_wrong,
1177
                                  output bit [`size-1:0] address,
1178
                                  ref byte data [],
1179
                                  output byte acknowledge,
1180
                                  output int unsigned data_length,
1181
                                  output int _reqack,
1182
                                  output int _reqinc);
1183
 
1184
    byte temp;
1185
    byte read_byte;
1186
    catch_field_serout(read_byte);
1187
    case (read_byte)
1188
      `w:
1189
        begin
1190
        command_type  = `text_mode;
1191
        _command      = `write_comm;
1192
        _chartype     = `small_let;
1193
        data = new [1];
1194
        capture_text_write_command(_spacetype1,
1195
                                   space_wrong1,
1196
                                   _spacetype2,
1197
                                   space_wrong2,
1198
                                   _eoltype,
1199
                                   eol_wrong,
1200
                                   address,
1201
                                   data[0]);
1202
        end
1203
      `W:
1204
        begin
1205
        command_type  = `text_mode;
1206
        _command      = `write_comm;
1207
        _chartype     = `capital_let;
1208
        data = new [1];
1209
        capture_text_write_command(_spacetype1,
1210
                                   space_wrong1,
1211
                                   _spacetype2,
1212
                                   space_wrong2,
1213
                                   _eoltype,
1214
                                   eol_wrong,
1215
                                   address,
1216
                                   data[0]);
1217
        end
1218
      `r:
1219
        begin
1220
        command_type  = `text_mode;
1221
        _command      = `read_comm;
1222
        _chartype     = `small_let;
1223
        data = new [1];
1224
        capture_text_read_command(_spacetype1,
1225
                                  space_wrong1,
1226
                                  _eoltype,
1227
                                  eol_wrong,
1228
                                  address,
1229
                                  data [0]);
1230
        end
1231
      `R:
1232
        begin
1233
        command_type  = `text_mode;
1234
        _command      = `read_comm;
1235
        _chartype     = `capital_let;
1236
        data = new [1];
1237
        capture_text_read_command(_spacetype1,
1238
                                  space_wrong1,
1239
                                  _eoltype,
1240
                                  eol_wrong,
1241
                                  address,
1242
                                  data [0]);
1243
        end
1244
      `bin_prfx:
1245
        begin
1246
        command_type  = `binary_mode;
1247
        capture_binary_command(_command,
1248
                               _reqack,
1249
                               _reqinc,
1250
                               address,
1251
                               data_length,
1252
                               data,
1253
                               acknowledge);
1254
        end
1255
      default:
1256
        begin
1257
        if (wrong_mode_ctrl)
1258
          begin
1259
          command_type  = `wrong_mode_binry;
1260
          end
1261
        else
1262
          begin
1263
          command_type  = `wrong_mode_txt;
1264
          end
1265
        end
1266
    endcase
1267
  endtask:capture_command
1268
 
1269
  // This method is used to capture read command in text mode. Whenever it is called, the following
1270
  // procedures are carried out :
1271
  //                               -----------------------
1272
  // 1- Capture the second command field which includes the white space character.
1273
  //                               -----------------------
1274
  // 2- According to the configured data representation:
1275
  //    i- Binary representation: Catch the following two UART fields on the serial output port
1276
  //                              which include the current stimulus address.
1277
  //   ii- ASCII representation: Catch the following four UART fields on the serial output port
1278
  //                             which include the current stimulus address in ASCII format.their
1279
  //                             data bytes are converted to binary format.
1280
  //                               -----------------------
1281
  // 3- Capture the following field which includes the end of line character.
1282
  //                               -----------------------
1283
  // GETTING RESPONSE:
1284
  //  - Run two concurrent threads:
1285
  //    i- The first one is to wait response time.
1286
  //   ii- The second one is to capture the data UART fields on the serial input port.
1287
  //  - In case that no response is found, this task is terminated.
1288
  //  - After catch the data fields, the next two fields are also captured to check the two end
1289
  //    of line characters.
1290
  //                               -----------------------
1291 2 HanySalah
  task capture_text_read_command (output int _spacetype,
1292
                                  output int space_wrong,
1293
                                  output int _eoltype,
1294
                                  output int eol_wrong,
1295
                                  output bit [`size-1:0] address,
1296
                                  output byte data);
1297
    byte read_byte;
1298 3 HanySalah
    bit miss;
1299
 
1300 2 HanySalah
    catch_field_serout(read_byte);
1301
    case (read_byte)
1302
      `space:
1303
        begin
1304
        _spacetype  = `single_space;
1305
        end
1306
      `tab:
1307
        begin
1308
        _spacetype  = `tab_space;
1309
        end
1310
      default:
1311
        begin
1312
        _spacetype  = `space_wrong;
1313
        space_wrong = read_byte;
1314
        end
1315
    endcase
1316
 
1317
    case(data_rep)
1318
      `binary_rep:
1319
        begin
1320
        catch_field_serout(read_byte);
1321
        address[15:08] = read_byte;
1322
        catch_field_serout(read_byte);
1323
        address[07:00] = read_byte;
1324
        end
1325
      `ascii_rep:
1326
        begin
1327
        catch_field_serout(read_byte);
1328
        address[15:12] = asci_bin_conv(read_byte);
1329
        catch_field_serout(read_byte);
1330
        address[11:08] = asci_bin_conv(read_byte);
1331
        catch_field_serout(read_byte);
1332
        address[07:04] = asci_bin_conv(read_byte);
1333
        catch_field_serout(read_byte);
1334
        address[03:00] = asci_bin_conv(read_byte);
1335
        end
1336
      default:
1337
        begin
1338
        $error("undefined data representation");
1339
        $stop;
1340
        end
1341
    endcase
1342
 
1343
    catch_field_serout(read_byte);
1344
    case(read_byte)
1345
      `CR:
1346
        begin
1347
        _eoltype    = `cr_eol;
1348
        end
1349
      `LF:
1350
        begin
1351
        _eoltype    = `lf_eol;
1352
        end
1353
      default:
1354
        begin
1355
        _eoltype    = `eol_wrong;
1356
        eol_wrong   = read_byte;
1357
        end
1358
    endcase
1359
 
1360 3 HanySalah
    miss = 1'b0;
1361
    fork
1362
      begin: miss_response_thread
1363
      #response_time;
1364
      disable capture_response_thread;
1365
      miss = 1'b1;
1366
      end
1367
 
1368
      begin: capture_response_thread
1369
      wait(ser_in == 1'b0);
1370
      disable miss_response_thread;
1371
      end
1372
    join
1373
 
1374
    if (miss==1'b0)
1375
      begin
1376
      case(data_rep)
1377
        `binary_rep:
1378
          begin
1379
          catch_field_serin(read_byte);
1380
          data = read_byte;
1381
          end
1382
        `ascii_rep:
1383
          begin
1384
          catch_field_serin(read_byte);
1385
          data[7:4] = asci_bin_conv(read_byte);
1386
          catch_field_serin(read_byte);
1387
          data[3:0] = asci_bin_conv(read_byte);
1388
          end
1389
        default:
1390
          begin
1391
          $error("undefined data representation");
1392
          $stop;
1393
          end
1394
      endcase
1395
 
1396
      catch_field_serin(read_byte);
1397
      if (read_byte == `CR)
1398 2 HanySalah
        begin
1399
        catch_field_serin(read_byte);
1400 3 HanySalah
        if (read_byte != `LF)
1401
          begin
1402
          $error("the catpured byte isn't LF");
1403
          end
1404 2 HanySalah
        end
1405 3 HanySalah
      else if (read_byte == `LF)
1406 2 HanySalah
        begin
1407 3 HanySalah
        $error("The captured byte is LF instead of CR");
1408 2 HanySalah
        end
1409 3 HanySalah
      else
1410 2 HanySalah
        begin
1411 3 HanySalah
        $error("Fatal Error : final character in read request isn't CR and LF");
1412 2 HanySalah
        end
1413 3 HanySalah
      end
1414 2 HanySalah
 
1415
  endtask:capture_text_read_command
1416
 
1417 3 HanySalah
  // This method is used to capture write command in text mode. Whenever it is called, the follo-
1418
  // wing procedures are carried out :
1419
  //                               -----------------------
1420
  // 1- Capture the second command field which includes the white space character.
1421
  //                               -----------------------
1422
  // 2- According to the configured data representation:
1423
  //    i- Binary representation: Catch the following UART field on the serial output port
1424
  //                              which includes the current stimulus data.
1425
  //   ii- ASCII representation: Catch the following two UART fields on the serial output port
1426
  //                             which include the current stimulus data in ASCII format.their
1427
  //                             data bytes are converted to binary format.
1428
  //                               -----------------------
1429
  // 3- Capture the next field which includes the white space character.
1430
  //                               -----------------------
1431
  // 4- According to the configured data representation:
1432
  //    i- Binary representation: Catch the following two UART fields on the serial output port
1433
  //                              which include the current stimulus address.
1434
  //   ii- ASCII representation: Catch the following four UART fields on the serial output port
1435
  //                             which include the current stimulus address in ASCII format.their
1436
  //                             data bytes are converted to binary format.
1437
  //                               -----------------------
1438
  // 3- Capture the following field which includes the end of line character.
1439
  //                               -----------------------
1440 2 HanySalah
 
1441
  task capture_text_write_command ( output int _spacetype1,
1442
                                    output int space_wrong1,
1443
                                    output int _spacetype2,
1444
                                    output int space_wrong2,
1445
                                    output int _eoltype,
1446
                                    output int eol_wrong,
1447
                                    output bit [`size-1:0] address,
1448
                                    output byte data);
1449
 
1450
    byte read_byte;
1451
    catch_field_serout(read_byte);
1452
    case (read_byte)
1453
      `space:
1454
        begin
1455
        _spacetype1  = `single_space;
1456
        end
1457
      `tab:
1458
        begin
1459
        _spacetype1  = `tab_space;
1460
        end
1461
      default:
1462
        begin
1463
        _spacetype1  = `space_wrong;
1464
        space_wrong1 = read_byte;
1465
        end
1466
    endcase
1467
 
1468
    case(data_rep)
1469
      `binary_rep:
1470
        begin
1471
        catch_field_serout(read_byte);
1472
        data = read_byte;
1473
        end
1474
      `ascii_rep:
1475
        begin
1476
        catch_field_serout(read_byte);
1477
        data[7:4] = asci_bin_conv(read_byte);
1478
        catch_field_serout(read_byte);
1479
        data[3:0] = asci_bin_conv(read_byte);
1480
        end
1481
      default:
1482
        begin
1483
        $error("undefined data representation");
1484
        $stop;
1485
        end
1486
    endcase
1487
 
1488
    catch_field_serout(read_byte);
1489
    case (read_byte)
1490
      `space:
1491
        begin
1492
        _spacetype2  = `single_space;
1493
        end
1494
      `tab:
1495
        begin
1496
        _spacetype2  = `tab_space;
1497
        end
1498
      default:
1499
        begin
1500
        _spacetype2  = `space_wrong;
1501
        space_wrong2 = read_byte;
1502
        end
1503
    endcase
1504
 
1505
    case(data_rep)
1506
      `binary_rep:
1507
        begin
1508
        catch_field_serout(read_byte);
1509
        address[15:08] = read_byte;
1510
        catch_field_serout(read_byte);
1511
        address[07:00] = read_byte;
1512
        end
1513
      `ascii_rep:
1514
        begin
1515
        catch_field_serout(read_byte);
1516
        address[15:12] = asci_bin_conv(read_byte);
1517
        catch_field_serout(read_byte);
1518
        address[11:08] = asci_bin_conv(read_byte);
1519
        catch_field_serout(read_byte);
1520
        address[07:04] = asci_bin_conv(read_byte);
1521
        catch_field_serout(read_byte);
1522
        address[03:00] = asci_bin_conv(read_byte);
1523
        end
1524
      default:
1525
        begin
1526
        $error("Undefined data representation");
1527
        $stop;
1528
        end
1529
    endcase
1530
 
1531
    catch_field_serout(read_byte);
1532
    case(read_byte)
1533
      `CR:
1534
        begin
1535
        _eoltype    = `cr_eol;
1536
        end
1537
      `LF:
1538
        begin
1539
        _eoltype    = `lf_eol;
1540
        end
1541
      default:
1542
        begin
1543
        _eoltype    = `eol_wrong;
1544
        eol_wrong   = read_byte;
1545
        end
1546
    endcase
1547
  endtask: capture_text_write_command
1548
 
1549 3 HanySalah
  // This method is used to capture binary mode command. Whenever it is called, the following
1550
  // procedures are carried out :
1551
  //                               -----------------------
1552
  // 1- Capture and decode the second command field which includes the command, the acknowledge
1553
  //    request and also the address auto-increment enable.
1554
  //  - In case that the command bits indicate invalid command, BFM uses wrond_data_ctrl internal
1555
  //    bit to know wether this stimulus is wrong read or wrong write. No response should be driven
1556
  //    by the DUT in the both cases. But we need to discriminte between the two cases to facili-
1557
  //    tates the scoreboard job.
1558
  //                               -----------------------
1559
  // 2- Capture the following field which includes the higher byte of the command address.
1560
  //                               -----------------------
1561
  // 3- Capture the following field which includes the lower byte of the command address.
1562
  //                               -----------------------
1563
  // 4- Capture the next field which includes the number of data bytes.
1564
  //                               -----------------------
1565
  // 5- According to the decoded command:
1566
  //    i- Read Command   : Poll the serial input port and capture number of successive UART fields
1567
  //                        equal to the number of data bytes. In case of acknowledge request, ano-
1568
  //                        ther field is captured and compared to the standard acknowledge
1569
  //                        character
1570
  //
1571
  //   ii- Write Command  : Poll the serial output port and capture number of successive UART fie-
1572
  //                        lds equal to the number of data bytes. In case of acknowledge request,
1573
  //                        another field is captured on the serial input port and compare to the
1574
  //                        standard acknowledge character
1575
  //
1576
  //  iii- NOP Command    : In case of acknowledge request, another field is captured on the serial
1577
  //                        input port and compared to the standard acknowledge character
1578
  //
1579
  //  iv- Invalid Command : In case that it is wrong read command, the same sequence obligied at
1580
  //                        the valid read command is carried out.
1581
  //                        In case that it is wrond write command, the same sequence obligied at
1582
  //                        the valid write command is carried out.
1583
  //                               -----------------------
1584
  // NOTE: Since the number of data bytes is defined at the run-time, we use queue of bytes to
1585
  //       packetaize the data temporarily and re-assign it to the dynamic array of data.
1586
  //                               -----------------------
1587 2 HanySalah
  task automatic capture_binary_command (output int _command,
1588
                                         output int _reqack,
1589
                                         output int _reqinc,
1590
                                         output bit [15:0] address,
1591
                                         output int data_length,
1592 3 HanySalah
                                         ref byte data [],
1593 2 HanySalah
                                         output byte acknowledge);
1594
    byte read_byte;
1595
    int index;
1596
    byte que [$];
1597 3 HanySalah
 
1598 2 HanySalah
    // first byte
1599
    catch_field_serout(read_byte);
1600
    case(read_byte[5:4])
1601
      `nop_ctrl:
1602
        begin
1603
        _command = `nop_comm;
1604
        end
1605
      `read_ctrl:
1606
        begin
1607
        _command = `read_comm;
1608
        end
1609
      `write_ctrl:
1610
        begin
1611
        _command = `write_comm;
1612
        end
1613 3 HanySalah
      `invalid_ctrl:
1614
        begin
1615
        if(wrong_data_ctrl)
1616
          begin
1617
          _command = `wrong_comm_write;
1618
          end
1619
        else
1620
          begin
1621
          _command = `wrong_comm_read;
1622
          end
1623
        end
1624 2 HanySalah
      default:
1625
        begin
1626 3 HanySalah
        $error("invalid Command");
1627 2 HanySalah
        end
1628
    endcase
1629 3 HanySalah
 
1630 2 HanySalah
    if (read_byte[1])
1631
      begin
1632
      _reqinc = `_no;
1633
      end
1634
    else
1635
      begin
1636
      _reqinc = `_yes;
1637
      end
1638
    if (read_byte[0])
1639
      begin
1640
      _reqack = `_yes;
1641
      end
1642
    else
1643
      begin
1644
      _reqack = `_no;
1645
      end
1646 3 HanySalah
      if (_command != `nop_comm)
1647
        begin
1648
        catch_field_serout(read_byte);
1649
        address[15:08] = read_byte;
1650 2 HanySalah
 
1651 3 HanySalah
        catch_field_serout(read_byte);
1652
        address[07:00] = read_byte;
1653 2 HanySalah
 
1654 3 HanySalah
        catch_field_serout(read_byte);
1655
        if (read_byte == 8'h00)
1656
          begin
1657
          data_length = 256;
1658
          end
1659
        else
1660
          begin
1661
          data_length = read_byte;
1662
          end
1663 2 HanySalah
 
1664 3 HanySalah
        que.delete();
1665
        if (_command == `read_comm || _command == `wrong_comm_read)
1666 2 HanySalah
          begin
1667 3 HanySalah
          index=0;
1668
          while(index < data_length)
1669
            begin
1670
            catch_field_serin(read_byte);
1671
            que.push_back(read_byte);
1672
            index++;
1673
            end
1674 2 HanySalah
          end
1675 3 HanySalah
        else if (_command == `write_comm || _command == `wrong_comm_write)
1676 2 HanySalah
          begin
1677 3 HanySalah
          index=0;
1678
          while(index < data_length)
1679
            begin
1680
            catch_field_serout(read_byte);
1681
            que.push_back(read_byte);
1682
            index++;
1683
            end
1684 2 HanySalah
          end
1685 3 HanySalah
        data = new [que.size];
1686
        data = que;
1687 2 HanySalah
        end
1688 3 HanySalah
    if(_reqack == `_yes)
1689
      begin
1690
      catch_field_serin(acknowledge);
1691
      end
1692 2 HanySalah
  endtask:capture_binary_command
1693
 
1694 3 HanySalah
 endinterface:uart_interface

powered by: WebSVN 2.1.0

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