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 3

Go to most recent revision | 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
      end
290
    else if (parity != `_parityoff)
291
      begin
292
      $error("un-configured parity");
293
      end
294 2 HanySalah
    // Stop bit(s)
295
    repeat (num_stop_bits)
296
      begin
297
      push_bit_serout(1'b1);
298
      end
299
 
300
  endtask:push_field_serout
301
 
302 3 HanySalah
  // Through the following task, UART BFM will catpure UART field from serial output port based on
303
  // the configured start_bit field. The following sequence is carried out :
304
  // 1- Wait start bit.
305
  // 2- Catpure the following eight bits in packed byte depending on the configured start bit.
306
  // 3- Depending on the configured number of stop bits, the stop bit(s) are captured.
307
  //    - In case that stop bit(s) is zero, the testbench will assign testbench error.
308
  // BFM will assign testbench error in case of un-configured start_bit field.
309 2 HanySalah
  task catch_field_serout (output byte data);
310
    bit end_bit;
311
 
312
    // wait start bit
313
    wait(ser_out == 1'b0);
314
    case(start_bit)
315
      `lsb_first:
316
        begin
317
        for (int index=0;index<8;index++)
318
          begin
319
          catch_bit_serout(data[index]);
320
          end
321
        end
322
      `msb_first:
323
        begin
324
        for (int index=7;index>=0;index--)
325
          begin
326
          catch_bit_serout(data[index]);
327
          end
328
        end
329
      default:
330
        begin
331
        $error("Undefined serial mode");
332
        end
333
    endcase
334
    catch_bit_serout(end_bit);
335
    if(end_bit != 1'b1)
336
      begin
337
      $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
338
      end
339
    if (num_stop_bits == 2)
340
      begin
341
      catch_bit_serout(end_bit);
342
      if(end_bit != 1'b1)
343
        begin
344
        $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
345
        end
346
      end
347
  endtask:catch_field_serout
348
 
349 3 HanySalah
  // Through the following task, UART BFM will catpure UART field from serial input port based on
350
  // the configured start_bit field. The applied sequence here differs from the one applied on
351
  // capture field from serial output port since wrong and unknown commands are forced to the DUT
352
  // on the UART interface. The DUT is supposed to make no response to such commands.
353
  // This routine pays concern to this issue by initiating two parallel threads at the beginning;
354
  // 1- The first one run in the background to wait response time and triggered some internal
355
  //    event (terminate event). It also set internal bit (path_select) to zero to make an
356
  // indication that no response has been made.
357
  // 2- The second one includes two parallel sub-threads:
358
  //    a- The first one wait start bit.
359
  //    b- The other one wait terminate event triggering.
360
  //    Whenever one of those sub-threads is terminated, The main thread is joined.
361
  // The following sequence is carried out in case that start bit is captured:
362
  // 1- Wait start bit.
363
  // 2- Catpure the following eight bits in packed byte depending on the configured start bit.
364
  // 3- Depending on the configured number of stop bits, the stop bit(s) are captured.
365
  //    - In case that stop bit(s) is zero, the testbench will assign testbench error.
366
  // BFM will assign testbench error in case of un-configured start_bit field.
367 2 HanySalah
  task catch_field_serin (output byte data);
368
    bit end_bit;
369 3 HanySalah
    bit path_select;
370
    event terminate;
371
    path_select = 1'b1;
372
    fork
373
      begin
374
      #response_time;
375
      -> terminate;
376
      path_select = 1'b0;
377
      end
378
    join_none
379 2 HanySalah
 
380 3 HanySalah
    fork
381
      wait (ser_in == 1'b0);
382
      wait (terminate);
383
    join_any
384
 
385
    if (path_select)
386
      begin
387
      #(`buad_clk_period/2);
388
      case(start_bit)
389
        `lsb_first:
390 2 HanySalah
          begin
391 3 HanySalah
          for (int index=0;index<8;index++)
392
            begin
393
            catch_bit_serin(data[index]);
394
            end
395 2 HanySalah
          end
396 3 HanySalah
        `msb_first:
397 2 HanySalah
          begin
398 3 HanySalah
          for (int index=7;index>=0;index--)
399
            begin
400
            catch_bit_serin(data[index]);
401
            end
402 2 HanySalah
          end
403 3 HanySalah
        default:
404
          begin
405
          $error("Undefined serial mode");
406
          end
407
      endcase
408 2 HanySalah
      catch_bit_serin(end_bit);
409
      if(end_bit != 1'b1)
410
        begin
411
        $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
412
        end
413 3 HanySalah
      if (num_stop_bits == 2)
414
        begin
415
        catch_bit_serin(end_bit);
416
        if(end_bit != 1'b1)
417
          begin
418
          $error("at time =%0t ,, the first end bit = %0b",$time,end_bit);
419
          end
420
        end
421 2 HanySalah
      end
422 3 HanySalah
 
423 2 HanySalah
  endtask:catch_field_serin
424
 
425 3 HanySalah
  // Through the following function, the byte is reversed in the manner where the byte is merrored
426 2 HanySalah
  function byte reverse_byte (byte data);
427
    byte tmp;
428
    for (int index=0;index<8;index++)
429
      begin
430
      tmp[index] = data[7-index];
431
      end
432
    return tmp;
433
  endfunction:reverse_byte
434
 
435 3 HanySalah
//-------------------------------------------------------------------------------------------------
436 2 HanySalah
//
437 3 HanySalah
//                                      UART ROUTINES
438 2 HanySalah
//
439 3 HanySalah
//-------------------------------------------------------------------------------------------------
440 2 HanySalah
 
441 3 HanySalah
  // This method is provided to initiate write request in UART text mode. This task is accomplis-
442
  // hed through the following sequence:
443
  // 1- The first field :(Prefix Character)
444
  //    Depending on whether the mode type is text or wrong text and whether the prefix is small
445
  //    or capital character, the BFM force the prefix field. In case of wrong text type, the init-
446
  //    ial field is the provided wrong_prefix input. also internal wrong_mode_ctrl bit is cleared.
447
  //    - In case of undefined type, testbench assign testbench error.
448
  //                               -----------------------
449
  // 2- The second field:(White Space Character)
450
  //    Depending on whether the used white space type is a single space, a tab space or provided
451
  //    wrong space character is forced on the serial output port.
452
  //                               -----------------------
453
  // 3- The third field:(Data Character)
454
  //    - In case of the data representation is binary, the data input character is encapsulated
455
  //      in UART field and forced in single field.
456
  //    - In case of the data representation is ASCII, the data input character is divided into
457
  //      two nipples. Each one is converted to ASCII character and sent separately in UART field.
458
  //      The most significant nipple is sent first.
459
  //                               -----------------------
460
  // 4- The forth field:(White Space Character)
461
  //    Depending on whether the used white space type is a single space, a tab space or provided
462
  //    wrong space character is forced on the serial output port.
463
  //                               -----------------------
464
  // 5- The fifth field:(Address Two-Character)
465
  //    - In case of the data representation is binary, the address input two-character is divided
466
  //      into two characters. They are encapsulated into two successive UART fields.
467
  //    - In case of the data representation is ASCII, the address input two-character is divided
468
  //      into four nipples. Each one is converted to ASCII character and sent separately in UART
469
  //      field. The ASCII characters are sent where the most significant nipple is sent first.
470
  //                               -----------------------
471
  // 6- The sixth field:(End-Of-Line Character):
472
  //    Depending on whether the used EOL type is CR, LF or provided wrong space character is
473
  //    forced on the serial output port.
474
  //                               -----------------------
475
  task write_text_mode(input int _type,
476
                       input byte wrong_prefix,
477
                       input int alph,
478 2 HanySalah
                       input int scp_type1,
479
                       input byte space_wrong1,
480
                       input int scp_type2,
481
                       input byte space_wrong2,
482
                       input int eol,
483
                       input byte eol_wrong,
484
                       input bit [`size-1:0] address,
485
                       input byte data);
486
    // Write procedures
487 3 HanySalah
    // First Field
488
    case (_type)
489
      `text_mode:
490 2 HanySalah
        begin
491 3 HanySalah
        if (alph == `small_let)
492
          begin
493
          push_field_serout(`w);
494
          end
495
        else if (alph == `capital_let)
496
          begin
497
          push_field_serout(`W);
498
          end
499
        else
500
          $error("Testbench error .. No capitar or small letter is choosed");
501 2 HanySalah
        end
502 3 HanySalah
      `wrong_mode_txt:
503 2 HanySalah
        begin
504 3 HanySalah
        push_field_serout(wrong_prefix);
505
        wrong_mode_ctrl = 1'b0;
506 2 HanySalah
        end
507 3 HanySalah
      default:
508 2 HanySalah
        begin
509 3 HanySalah
        $error("Undefined communication mode ..");
510 2 HanySalah
        end
511 3 HanySalah
    endcase
512 2 HanySalah
 
513 3 HanySalah
    // Second Field
514
    if (scp_type1 == `single_space)
515
      begin
516
      push_field_serout(`space);
517
      end
518
    else if (scp_type1 == `tab_space)
519
      begin
520
      push_field_serout(`tab);
521
      end
522
    else if (scp_type1 == `space_wrong)
523
      begin
524
      push_field_serout(space_wrong1);
525
      end
526
    else
527
      $error("Testbench error .. No single space or multiple space is choosed");
528 2 HanySalah
 
529 3 HanySalah
    // third field
530
    case (data_rep)
531
      `binary_rep:
532 2 HanySalah
        begin
533 3 HanySalah
        push_field_serout(data);
534 2 HanySalah
        end
535 3 HanySalah
      `ascii_rep:
536 2 HanySalah
        begin
537 3 HanySalah
        push_field_serout(bin_asci_conv(data[7:4]));
538
        push_field_serout(bin_asci_conv(data[3:0]));
539 2 HanySalah
        end
540 3 HanySalah
      default:$error("undefined data representation");
541
    endcase
542 2 HanySalah
 
543 3 HanySalah
    // forth field
544
    if (scp_type2 == `single_space)
545
      begin
546
      push_field_serout(`space);
547
      end
548
    else if (scp_type2 == `tab_space)
549
      begin
550
      push_field_serout(`tab);
551
      end
552
    else if (scp_type2 == `space_wrong)
553
      begin
554
      push_field_serout(space_wrong2);
555
      end
556
    else
557
      $error("Testbench error .. No single or multiple space is choosed");
558
    // fivth field
559
    case (data_rep)
560
      `binary_rep:
561 2 HanySalah
        begin
562 3 HanySalah
        push_field_serout(address[15:08]);
563
        push_field_serout(address[07:00]);
564 2 HanySalah
        end
565 3 HanySalah
      `ascii_rep:
566 2 HanySalah
        begin
567 3 HanySalah
        push_field_serout(bin_asci_conv(address[15:12]));
568
        push_field_serout(bin_asci_conv(address[11:08]));
569
        push_field_serout(bin_asci_conv(address[07:04]));
570
        push_field_serout(bin_asci_conv(address[03:00]));
571 2 HanySalah
        end
572 3 HanySalah
      default:$error("undefined data representation");
573
    endcase
574
 
575
    // sixth Field
576
    if (eol == `cr_eol)
577
      begin
578
      push_field_serout(`CR);
579
      end
580
    else if (eol == `lf_eol)
581
      begin
582
      push_field_serout(`LF);
583
      end
584
    else if (eol == `eol_wrong)
585
      begin
586
      push_field_serout(eol_wrong);
587
      end
588
    else
589
      $error("Testbench error .. either CR or LF isn't choosed as eol");
590 2 HanySalah
  endtask:write_text_mode
591
 
592 3 HanySalah
  // This method is provided to initiate read request in UART text mode. This task is accomplis-
593
  // hed through the following sequence:
594
  // 1- The first field :(Prefix Character)
595
  //    Depending on whether the mode type is text or wrong text and whether the prefix is small
596
  //    or capital character, the BFM force the prefix field. In case of wrong text type, the init-
597
  //    ial field is the provided wrong_prefix input. also internal wrong_mode_ctrl bit is cleared.
598
  //    - In case of undefined type, testbench assign testbench error.
599
  //                               -----------------------
600
  // 2- The second field:(White Space Character)
601
  //    Depending on whether the used white space type is a single space, a tab space or provided
602
  //    wrong space character is forced on the serial output port.
603
  //                               -----------------------
604
  // 3- The third field:(Address Two-Character)
605
  //    - In case of the data representation is binary, the address input two-character is divided
606
  //      into two characters. They are encapsulated into two successive UART fields.
607
  //    - In case of the data representation is ASCII, the address input two-character is divided
608
  //      into four nipples. Each one is converted to ASCII character and sent separately in UART
609
  //      field. The ASCII characters are sent where the most significant nipple is sent first.
610
  //                               -----------------------
611
  // 4- The forth field:(End-Of-Line Character):
612
  //    Depending on whether the used EOL type is CR, LF or provided wrong space character is
613
  //    forced on the serial output port.
614
  //                               -----------------------
615
  // GETTING RESPONSE :
616
  //    Since we may have no response due to either DUT internal bug or the forced request is
617
  //    wrong (wrong mode, wrong white space, wrong eol), two parallel threads are initiated; The
618
  //    first one is to wait for response time and the other one waits start bit on the serial
619
  //    input port. Both the two threads are terminated by meeting only one of the two events.
620
  //    In case of the start bit is captured and according to the configured the data representa-
621
  //    tion.
622
  //    - If it is binary, the following UART field is captured and its data is considered to be
623
  //      the requested data.
624
  //    - If it is ASCII, the two successive UART fields is captured and each byte is converted to
625
  //      binary nipple.
626
  //    The following character is captured and it must be CR.
627
  //    The following character is captured and it must be LF.
628
  //    - If the last two characters aren't as indicated above, the testbench will assign testbench
629
  //      error.
630
  //                               -----------------------
631
  task read_text_mode (input int _type,
632
                       input byte wrong_prefix,
633
                       input int alph,
634 2 HanySalah
                       input int scp_type,
635
                       input byte space_wrong,
636
                       input int eol,
637
                       input byte eol_wrong,
638 3 HanySalah
                       input bit [`size-1:0] address,
639
                       input byte false_data,
640
                       input int false_data_en);
641 2 HanySalah
    byte data;
642
    byte temp;
643
    byte char1,char2;
644
    bit miss;
645
    // Read Request
646 3 HanySalah
    // First Field
647
    case (_type)
648
      `text_mode:
649 2 HanySalah
        begin
650 3 HanySalah
        if (alph == `small_let)
651
          begin
652
          push_field_serout(`r);
653
          end
654
        else if (alph == `capital_let)
655
          begin
656
          push_field_serout(`R);
657
          end
658
        else
659
          $error("Testbench error .. No capitar or small letter is choosed");
660 2 HanySalah
        end
661 3 HanySalah
      `wrong_mode_txt:
662 2 HanySalah
        begin
663 3 HanySalah
        push_field_serout(wrong_prefix);
664
        wrong_mode_ctrl = 1'b0;
665 2 HanySalah
        end
666 3 HanySalah
      default:
667 2 HanySalah
        begin
668 3 HanySalah
        $error("Undefined communication mode ..");
669 2 HanySalah
        end
670 3 HanySalah
    endcase
671
 
672
    // Second Field
673
    if (scp_type == `single_space)
674
      begin
675
      push_field_serout(`space);
676
      end
677
    else if (scp_type == `tab_space)
678
      begin
679
      push_field_serout(`tab);
680
      end
681
    else if (scp_type == `space_wrong)
682
      begin
683
      push_field_serout(space_wrong);
684
      end
685
    else
686
      $error("Testbench error .. No single or multiple white space is choosed");
687
 
688
    // Third Field
689
    case (data_rep)
690
      `binary_rep:
691 2 HanySalah
        begin
692 3 HanySalah
        push_field_serout(address[15:08]);
693
        push_field_serout(address[07:00]);
694 2 HanySalah
        end
695 3 HanySalah
      `ascii_rep:
696 2 HanySalah
        begin
697 3 HanySalah
        push_field_serout(bin_asci_conv(address[15:12]));
698
        push_field_serout(bin_asci_conv(address[11:08]));
699
        push_field_serout(bin_asci_conv(address[07:04]));
700
        push_field_serout(bin_asci_conv(address[03:00]));
701 2 HanySalah
        end
702 3 HanySalah
      default:$error("undefined data representation");
703
    endcase
704 2 HanySalah
 
705 3 HanySalah
    // Forth Field
706
    if (eol == `cr_eol)
707
      begin
708
      push_field_serout(`CR);
709
      end
710
    else if (eol == `lf_eol)
711
      begin
712
      push_field_serout(`LF);
713
      end
714
    else if (eol == `eol_wrong)
715
      begin
716
      push_field_serout(eol_wrong);
717
      end
718
    else
719
      $error("Testbench error .. No CR or LF is choosed");
720
 
721
    miss = 1'b0;
722
    fork
723
      begin: miss_response_thread
724
      # response_time;
725
      disable capture_response_thread;
726
      miss = 1'b1;
727
      end
728
 
729
      begin: capture_response_thread
730
      wait(ser_in == 1'b0);
731
      disable miss_response_thread;
732
      end
733
    join
734
    // Capture Response
735
    if (miss == 1'b0)
736
      begin
737
      if (false_data_en ==`_yes && falsedata_gen_en == `_yes)
738
        begin
739
        fork
740
        push_field_serout(false_data);
741
        join_none
742
        end
743 2 HanySalah
      case (data_rep)
744
        `binary_rep:
745
          begin
746 3 HanySalah
          catch_field_serin(data);
747 2 HanySalah
          end
748
        `ascii_rep:
749
          begin
750 3 HanySalah
          catch_field_serin(temp);
751
          data[7:4] = asci_bin_conv(temp);
752
          catch_field_serin(temp);
753
          data[3:0] = asci_bin_conv(temp);
754 2 HanySalah
          end
755 3 HanySalah
        default:
756 2 HanySalah
          begin
757 3 HanySalah
          $error("Undefined data representation");
758
          $stop;
759 2 HanySalah
          end
760 3 HanySalah
      endcase
761
      catch_field_serin(char1);
762
      catch_field_serin(char2);
763
      if (char1 != `CR || char2 != `LF)
764 2 HanySalah
        begin
765 3 HanySalah
        $error("EOL is refuesed");
766 2 HanySalah
        end
767 3 HanySalah
      end
768 2 HanySalah
  endtask:read_text_mode
769
 
770 3 HanySalah
  // This method is provided to initiate write request in UART binary mode. This task is accompli-
771
  // shed through the following sequence:
772
  //                               -----------------------
773
  //          NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO DEFINED UART FIELD FORM
774
  //                               -----------------------
775
  // 1- The first byte :(Prefix byte)
776
  //    Depending on whether the mode type is binary or wrong binary the BFM force the prefix field
777
  //    In case of wrong binary type, the initial field is the provided wrong_prefix input. also
778
  //    internal wrong_mode_ctrl bit is set.
779
  //    - In case of undefined type, testbench assign testbench error.
780
  //                               -----------------------
781
  // 2- The second byte:(Command byte)
782
  //    Depending on whether the command is valid or invalid command, the two bits of the command
783
  //    are assigned. Also the auto increment bit and acknowledge request bit are assigned
784
  //                               -----------------------
785
  // 3- The third byte:(Address highest byte)
786
  //    - The address bits [15:08] .
787
  //                               -----------------------
788
  // 4- The forth field:(Address lowest byte)
789
  //    - The address bits [07:00] .
790
  //                               -----------------------
791
  // 5- The fifth field:(Length Of Data byte)
792
  //    - The number of data bytes inclosed into this stimulus.
793
  //                               -----------------------
794
  // 6- The rest fields:(Data):
795
  //    Data Bytes are sent one by one.
796
  //                               -----------------------
797
  // GETTING RESPONSE:
798
  //    In case that the command includes acknowledge request, UART BFM will wait for the ackno-
799
  //    wledge unified character.
800
  //                               -----------------------
801
  task automatic write_binary_mode (input int _type,
802
                                    input byte wrong_prefix,
803
                                    input int command,
804
                                    input int reqack,
805 2 HanySalah
                                    input int reqinc,
806
                                    input int unsigned data_length,
807
                                    input bit [`size-1:0] address,
808
                                    ref byte data []);
809
    byte tmp;
810
    int unsigned index;
811
 
812
    // first byte : binary prefix
813 3 HanySalah
    case(_type)
814
    `binary_mode:
815
      begin
816
      push_field_serout(`bin_prfx);
817
      end
818
    `wrong_mode_binry:
819
      begin
820
      push_field_serout(wrong_prefix);
821
      wrong_mode_ctrl = 1'b1;
822
      end
823
    default:
824
      begin
825
      $error("Undefined Communication Mode");
826
      end
827
    endcase
828 2 HanySalah
 
829
    // second byte : command
830 3 HanySalah
    case(command)
831
      `write_comm:
832
        begin
833
        tmp[5:4] = `write_ctrl;
834
        end
835
      `wrong_comm_write:
836
        begin
837
        tmp[5:4] = `invalid_ctrl;
838
        wrong_data_ctrl = 1'b1;
839
        end
840
      default:
841
        begin
842
        $error("Undefined Command");
843
        end
844
    endcase
845 2 HanySalah
    tmp[5:4] = 2'b10;
846
    if(reqinc==`_yes)
847
      begin
848
      tmp[1] = 1'b0;
849
      end
850
    else if (reqinc == `_no)
851
      begin
852
      tmp[1] = 1'b1;
853
      end
854
    else
855
      begin
856
      $error("undefined increment request");
857
      end
858
 
859
    if(reqack==`_yes)
860
      begin
861
      tmp[0] = 1'b1;
862
      end
863
    else if (reqack == `_no)
864
      begin
865
      tmp[0] = 1'b0;
866
      end
867
    else
868
      begin
869
      $error("undefined acknowledge request");
870
      end
871
    push_field_serout(tmp);
872
 
873
    // Third byte : higher byte of address
874
    push_field_serout(address[15:08]);
875
 
876
    // Forth byte : Lower byte of address
877
    push_field_serout(address[07:00]);
878
 
879
    // Fifth byte : data length
880
    push_field_serout(data_length);
881
 
882
    index = 0;
883
    while(index
884
      begin
885
      push_field_serout(data[index]);
886
      index++;
887
      end
888
 
889
    if (reqack == `_yes)
890
      begin
891
      catch_field_serin(tmp);
892
      if (tmp != `ACK)
893
        begin
894
        $error("The captured acknowledge isn't as unified character");
895
        end
896
      end
897
 
898
  endtask:write_binary_mode
899
 
900 3 HanySalah
  // This method is provided to initiate read request in UART binary mode. This task is accompli-
901
  // shed through the following sequence:
902
  //                               -----------------------
903
  //          NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO UART DEFINED FIELD FORM
904
  //                               -----------------------
905
  // 1- The first byte :(Prefix byte)
906
  //    Depending on whether the mode type is binary or wrong binary the BFM force the prefix field
907
  //    In case of wrong binary type, the initial field is the provided wrong_prefix input. also
908
  //    internal wrong_mode_ctrl bit is set.
909
  //    - In case of undefined type, testbench assign testbench error.
910
  //                               -----------------------
911
  // 2- The second byte:(Command byte)
912
  //    Depending on whether the command is valid or invalid command, the two bits of the command
913
  //    are assigned. Also the auto increment bit and acknowledge request bit are assigned
914
  //                               -----------------------
915
  // 3- The third byte:(Address highest byte)
916
  //    - The address bits [15:08] .
917
  //                               -----------------------
918
  // 4- The forth field:(Address lowest byte)
919
  //    - The address bits [07:00] .
920
  //                               -----------------------
921
  // 5- The fifth field:(Length Of Data byte)
922
  //    - The number of data bytes inclosed into this stimulus.
923
  //                               -----------------------
924
  // GETTING RESPONSE:
925
  //    Through this field, three independent parallel processes are carried out :
926
  //    i- The first one is mendatory and is responsible for capturing the UART fields drived by
927
  //       The DUT on the serial input port. Also it is responsible for capturing the acknowledge
928
  //       byte in case that the command include acknowledge request.
929
  //   ii- The second one is responsible for terminating this routine in case that no response has
930
  //       been driven by the DUT within the response time.
931
  //  iii- The last one is to drive dummy UART fields. It is used only when both the internal
932
  //       false data enable and the global false data enable are set. Refer to UART testbench
933
  //       specifications document for more details.
934
  //                               -----------------------
935
  task automatic read_binary_mode  (input int _type,
936
                                    input byte wrong_prefix,
937
                                    input int _command,
938
                                    input int reqack,
939 2 HanySalah
                                    input int reqinc,
940
                                    input int unsigned data_length,
941
                                    input bit [`size-1:0] address,
942 3 HanySalah
                                    ref byte data [],
943
                                    ref byte false_data [],
944
                                    input bit false_data_en);
945 2 HanySalah
    byte tmp;
946
    int unsigned index;
947 3 HanySalah
    int unsigned index_false;
948 2 HanySalah
 
949
    // first byte : binary prefix
950 3 HanySalah
    case (_type)
951
      `binary_mode:
952
        begin
953
        push_field_serout(`bin_prfx);
954
        end
955
      `wrong_mode_binry:
956
        begin
957
        push_field_serout(wrong_prefix);
958
        wrong_mode_ctrl = 1'b1;
959
        end
960
      default:
961
        begin
962
        $error("Undefined Communication Mode");
963
        end
964
    endcase
965 2 HanySalah
 
966
    // second byte : command
967 3 HanySalah
    case (_command)
968
      `read_comm:
969
        begin
970
        tmp[5:4] = `read_ctrl;
971
        end
972
      `wrong_comm_read:
973
        begin
974
        tmp[5:4] = `invalid_ctrl;
975
        wrong_data_ctrl = 1'b0;
976
        end
977
      default:
978
        begin
979
        $error("Undefined Command type");
980
        end
981
    endcase
982
 
983 2 HanySalah
    if(reqinc==`_yes)
984
      begin
985
      tmp[1] = 1'b0;
986
      end
987
    else if (reqinc == `_no)
988
      begin
989
      tmp[1] = 1'b1;
990
      end
991
    else
992 3 HanySalah
      $error("undefined acknowledge request");
993
      end
994 2 HanySalah
      begin
995
      $error("undefined increment request");
996
      end
997
 
998
    if(reqack==`_yes)
999
      begin
1000
      tmp[0] = 1'b1;
1001
      end
1002
    else if (reqack == `_no)
1003
      begin
1004
      tmp[0] = 1'b0;
1005
      end
1006
    else
1007
      begin
1008
    push_field_serout(tmp);
1009
 
1010
    // Third byte : higher byte of address
1011
    push_field_serout(address[15:08]);
1012
 
1013
    // Forth byte : Lower byte of address
1014
    push_field_serout(address[07:00]);
1015
 
1016
    // Fifth byte : data length
1017 3 HanySalah
    if (data_length == 256)
1018 2 HanySalah
      begin
1019 3 HanySalah
      tmp = 8'b00;
1020 2 HanySalah
      end
1021 3 HanySalah
    else
1022
      begin
1023
      tmp = data_length;
1024
      end
1025
    push_field_serout(tmp);
1026 2 HanySalah
 
1027 3 HanySalah
    index = 0;
1028
 
1029
    fork
1030
      if(false_data_en == `_yes && falsedata_gen_en == `_yes)
1031
        begin
1032
        while(index_false
1033
          begin
1034
          push_field_serout(false_data[index_false]);
1035
          index_false++;
1036
          end
1037
        end
1038
      while(index
1039
        begin
1040
        catch_field_serin(data[index]);
1041
        index++;
1042
        end
1043
    join
1044 2 HanySalah
    if (reqack == `_yes)
1045
      begin
1046
      catch_field_serin(tmp);
1047 3 HanySalah
      if (tmp != `ACK && _type == `binary_mode && _command == `read_comm)
1048 2 HanySalah
        begin
1049
        $error("The captured acknowledge isn't as unified character");
1050
        end
1051
      end
1052
  endtask:read_binary_mode
1053
 
1054 3 HanySalah
  // This method is provided to initiate NOP command in UART binary mode. This task is accompli-
1055
  // shed through the following sequence:
1056
  //                               -----------------------
1057
  //          NOTE :: ALL THE FOLLOWING BYTES ARE ENCAPSULATED INTO UART DEFINED FIELD FORM
1058
  //                               -----------------------
1059
  // 1- The first byte :(Prefix byte)
1060
  //    Depending on whether the mode type is binary or wrong binary the BFM force the prefix field
1061
  //    In case of wrong binary type, the initial field is the provided wrong_prefix input. also
1062
  //    internal wrong_mode_ctrl bit is set.
1063
  //    - In case of undefined type, testbench assign testbench error.
1064
  //                               -----------------------
1065
  // 2- The second byte:(Command byte)
1066
  //    The two bits of commads are assigned. Also the auto increment bit and acknowledge request
1067
  //    bit are assigned
1068
  //                               -----------------------
1069
  // GETTING RESPONSE:
1070
  //    In case that the command includes acknowledge request, UART BFM will wait for the ackno-
1071
  //    wledge unified character.
1072
  //                               -----------------------
1073
  task nop_command (input int _type,
1074
                    input byte wrong_prefix,
1075
                    input int reqack,
1076 2 HanySalah
                    input int reqinc);
1077
    byte tmp;
1078
    int unsigned index;
1079
    // first byte : prefix
1080 3 HanySalah
    wrong_mode_ctrl = 1'b0;
1081
    // first byte : binary prefix
1082
    case (_type)
1083
      `binary_mode:
1084
        begin
1085
        push_field_serout(`bin_prfx);
1086
        end
1087
      `wrong_mode_binry:
1088
        begin
1089
        push_field_serout(wrong_prefix);
1090
        wrong_mode_ctrl = 1'b1;
1091
        end
1092
      default:
1093
        begin
1094
        $error("Undefined Communication Mode");
1095
        end
1096
    endcase
1097 2 HanySalah
 
1098
    // second byte :  command
1099
    tmp[5:4] = 2'b00;
1100
    if(reqinc==`_yes)
1101
      begin
1102
      tmp[1] = 1'b0;
1103
      end
1104
    else if (reqinc == `_no)
1105
      begin
1106
      tmp[1] = 1'b1;
1107
      end
1108
    else
1109
      begin
1110
      $error("undefined increment request");
1111
      end
1112
 
1113
    if(reqack==`_yes)
1114
      begin
1115
      tmp[0] = 1'b1;
1116
      end
1117
    else if (reqack == `_no)
1118
      begin
1119
      tmp[0] = 1'b0;
1120
      end
1121
    else
1122
      begin
1123
      $error("undefined acknowledge request");
1124
      end
1125
    push_field_serout(tmp);
1126
 
1127
    if(reqack==`_yes)
1128
      begin
1129
      catch_field_serin(tmp);
1130
      if(tmp!=`ACK)
1131
        begin
1132
        $error("Undefined acknowledge character");
1133
        end
1134
      end
1135
  endtask:nop_command
1136
 
1137 3 HanySalah
  // This task is used to make the bus idle for time (idle).
1138 2 HanySalah
  task wait_idle_time (time idle);
1139
    force_sout(1'b1);
1140
    #idle;
1141
  endtask: wait_idle_time
1142
 
1143 3 HanySalah
//-------------------------------------------------------------------------------------------------
1144 2 HanySalah
//
1145 3 HanySalah
//                                     MONITOR ROUTINES
1146 2 HanySalah
//
1147 3 HanySalah
//-------------------------------------------------------------------------------------------------
1148
  // This section of routines is used to monitor the UART signals and capture all the informations
1149
  // about the stimulus, DUT state and DUT response as well. Each one is described in details below
1150
  //
1151
  // This routine is used to wait for transaction start. It waits for start_trans triggering.
1152 2 HanySalah
  task wait_event();
1153
    wait (start_trans);
1154
  endtask:wait_event
1155
 
1156 3 HanySalah
  // This method is the main method of the monitoring routines used to capture the UART
1157
  // transactions on the UART interfaces. Whenever it is called, it carries out the following
1158
  // procedures:
1159
  // 1- Capture the first field loaded on the serial output port and detect the command type to be
1160
  //    either text read, text write, binary, wrong command. And according to the command, another
1161
  //    proper task will be called.
1162
  // NOTE: In case of wrong command, with the aid of internal bit wrong_mode_ctrl, UART BFM could
1163
  //       detect the actual type of wrong command.
1164
  //                               -----------------------
1165
  // 2- (I) In case that the command type is text, the dynamic array of data is initialized with
1166
  //        the standard size one byte. Also command and character type fields are assigned. Refer
1167
  //        to transaction fields for more informations about these fields.
1168
  //   (II) In case that the command type is binary, capture_binary_command task is called.
1169
  //  (III) In case that the command type is wrong, nothing is done.
1170
  task automatic capture_command (output int command_type,
1171
                                  output int _command,
1172
                                  output int _chartype,
1173
                                  output int _spacetype1,
1174
                                  output int space_wrong1,
1175
                                  output int _spacetype2,
1176
                                  output int space_wrong2,
1177
                                  output int _eoltype,
1178
                                  output int eol_wrong,
1179
                                  output bit [`size-1:0] address,
1180
                                  ref byte data [],
1181
                                  output byte acknowledge,
1182
                                  output int unsigned data_length,
1183
                                  output int _reqack,
1184
                                  output int _reqinc);
1185
 
1186
    byte temp;
1187
    byte read_byte;
1188
    catch_field_serout(read_byte);
1189
    case (read_byte)
1190
      `w:
1191
        begin
1192
        command_type  = `text_mode;
1193
        _command      = `write_comm;
1194
        _chartype     = `small_let;
1195
        data = new [1];
1196
        capture_text_write_command(_spacetype1,
1197
                                   space_wrong1,
1198
                                   _spacetype2,
1199
                                   space_wrong2,
1200
                                   _eoltype,
1201
                                   eol_wrong,
1202
                                   address,
1203
                                   data[0]);
1204
        end
1205
      `W:
1206
        begin
1207
        command_type  = `text_mode;
1208
        _command      = `write_comm;
1209
        _chartype     = `capital_let;
1210
        data = new [1];
1211
        capture_text_write_command(_spacetype1,
1212
                                   space_wrong1,
1213
                                   _spacetype2,
1214
                                   space_wrong2,
1215
                                   _eoltype,
1216
                                   eol_wrong,
1217
                                   address,
1218
                                   data[0]);
1219
        end
1220
      `r:
1221
        begin
1222
        command_type  = `text_mode;
1223
        _command      = `read_comm;
1224
        _chartype     = `small_let;
1225
        data = new [1];
1226
        capture_text_read_command(_spacetype1,
1227
                                  space_wrong1,
1228
                                  _eoltype,
1229
                                  eol_wrong,
1230
                                  address,
1231
                                  data [0]);
1232
        end
1233
      `R:
1234
        begin
1235
        command_type  = `text_mode;
1236
        _command      = `read_comm;
1237
        _chartype     = `capital_let;
1238
        data = new [1];
1239
        capture_text_read_command(_spacetype1,
1240
                                  space_wrong1,
1241
                                  _eoltype,
1242
                                  eol_wrong,
1243
                                  address,
1244
                                  data [0]);
1245
        end
1246
      `bin_prfx:
1247
        begin
1248
        command_type  = `binary_mode;
1249
        capture_binary_command(_command,
1250
                               _reqack,
1251
                               _reqinc,
1252
                               address,
1253
                               data_length,
1254
                               data,
1255
                               acknowledge);
1256
        end
1257
      default:
1258
        begin
1259
        if (wrong_mode_ctrl)
1260
          begin
1261
          command_type  = `wrong_mode_binry;
1262
          end
1263
        else
1264
          begin
1265
          command_type  = `wrong_mode_txt;
1266
          end
1267
        end
1268
    endcase
1269
  endtask:capture_command
1270
 
1271
  // This method is used to capture read command in text mode. Whenever it is called, the following
1272
  // procedures are carried out :
1273
  //                               -----------------------
1274
  // 1- Capture the second command field which includes the white space character.
1275
  //                               -----------------------
1276
  // 2- According to the configured data representation:
1277
  //    i- Binary representation: Catch the following two UART fields on the serial output port
1278
  //                              which include the current stimulus address.
1279
  //   ii- ASCII representation: Catch the following four UART fields on the serial output port
1280
  //                             which include the current stimulus address in ASCII format.their
1281
  //                             data bytes are converted to binary format.
1282
  //                               -----------------------
1283
  // 3- Capture the following field which includes the end of line character.
1284
  //                               -----------------------
1285
  // GETTING RESPONSE:
1286
  //  - Run two concurrent threads:
1287
  //    i- The first one is to wait response time.
1288
  //   ii- The second one is to capture the data UART fields on the serial input port.
1289
  //  - In case that no response is found, this task is terminated.
1290
  //  - After catch the data fields, the next two fields are also captured to check the two end
1291
  //    of line characters.
1292
  //                               -----------------------
1293 2 HanySalah
  task capture_text_read_command (output int _spacetype,
1294
                                  output int space_wrong,
1295
                                  output int _eoltype,
1296
                                  output int eol_wrong,
1297
                                  output bit [`size-1:0] address,
1298
                                  output byte data);
1299
    byte read_byte;
1300 3 HanySalah
    bit miss;
1301
 
1302 2 HanySalah
    catch_field_serout(read_byte);
1303
    case (read_byte)
1304
      `space:
1305
        begin
1306
        _spacetype  = `single_space;
1307
        end
1308
      `tab:
1309
        begin
1310
        _spacetype  = `tab_space;
1311
        end
1312
      default:
1313
        begin
1314
        _spacetype  = `space_wrong;
1315
        space_wrong = read_byte;
1316
        end
1317
    endcase
1318
 
1319
    case(data_rep)
1320
      `binary_rep:
1321
        begin
1322
        catch_field_serout(read_byte);
1323
        address[15:08] = read_byte;
1324
        catch_field_serout(read_byte);
1325
        address[07:00] = read_byte;
1326
        end
1327
      `ascii_rep:
1328
        begin
1329
        catch_field_serout(read_byte);
1330
        address[15:12] = asci_bin_conv(read_byte);
1331
        catch_field_serout(read_byte);
1332
        address[11:08] = asci_bin_conv(read_byte);
1333
        catch_field_serout(read_byte);
1334
        address[07:04] = asci_bin_conv(read_byte);
1335
        catch_field_serout(read_byte);
1336
        address[03:00] = asci_bin_conv(read_byte);
1337
        end
1338
      default:
1339
        begin
1340
        $error("undefined data representation");
1341
        $stop;
1342
        end
1343
    endcase
1344
 
1345
    catch_field_serout(read_byte);
1346
    case(read_byte)
1347
      `CR:
1348
        begin
1349
        _eoltype    = `cr_eol;
1350
        end
1351
      `LF:
1352
        begin
1353
        _eoltype    = `lf_eol;
1354
        end
1355
      default:
1356
        begin
1357
        _eoltype    = `eol_wrong;
1358
        eol_wrong   = read_byte;
1359
        end
1360
    endcase
1361
 
1362 3 HanySalah
    miss = 1'b0;
1363
    fork
1364
      begin: miss_response_thread
1365
      #response_time;
1366
      disable capture_response_thread;
1367
      miss = 1'b1;
1368
      end
1369
 
1370
      begin: capture_response_thread
1371
      wait(ser_in == 1'b0);
1372
      disable miss_response_thread;
1373
      end
1374
    join
1375
 
1376
    if (miss==1'b0)
1377
      begin
1378
      case(data_rep)
1379
        `binary_rep:
1380
          begin
1381
          catch_field_serin(read_byte);
1382
          data = read_byte;
1383
          end
1384
        `ascii_rep:
1385
          begin
1386
          catch_field_serin(read_byte);
1387
          data[7:4] = asci_bin_conv(read_byte);
1388
          catch_field_serin(read_byte);
1389
          data[3:0] = asci_bin_conv(read_byte);
1390
          end
1391
        default:
1392
          begin
1393
          $error("undefined data representation");
1394
          $stop;
1395
          end
1396
      endcase
1397
 
1398
      catch_field_serin(read_byte);
1399
      if (read_byte == `CR)
1400 2 HanySalah
        begin
1401
        catch_field_serin(read_byte);
1402 3 HanySalah
        if (read_byte != `LF)
1403
          begin
1404
          $error("the catpured byte isn't LF");
1405
          end
1406 2 HanySalah
        end
1407 3 HanySalah
      else if (read_byte == `LF)
1408 2 HanySalah
        begin
1409 3 HanySalah
        $error("The captured byte is LF instead of CR");
1410 2 HanySalah
        end
1411 3 HanySalah
      else
1412 2 HanySalah
        begin
1413 3 HanySalah
        $error("Fatal Error : final character in read request isn't CR and LF");
1414 2 HanySalah
        end
1415 3 HanySalah
      end
1416 2 HanySalah
 
1417
  endtask:capture_text_read_command
1418
 
1419 3 HanySalah
  // This method is used to capture write command in text mode. Whenever it is called, the follo-
1420
  // wing procedures are carried out :
1421
  //                               -----------------------
1422
  // 1- Capture the second command field which includes the white space character.
1423
  //                               -----------------------
1424
  // 2- According to the configured data representation:
1425
  //    i- Binary representation: Catch the following UART field on the serial output port
1426
  //                              which includes the current stimulus data.
1427
  //   ii- ASCII representation: Catch the following two UART fields on the serial output port
1428
  //                             which include the current stimulus data in ASCII format.their
1429
  //                             data bytes are converted to binary format.
1430
  //                               -----------------------
1431
  // 3- Capture the next field which includes the white space character.
1432
  //                               -----------------------
1433
  // 4- According to the configured data representation:
1434
  //    i- Binary representation: Catch the following two UART fields on the serial output port
1435
  //                              which include the current stimulus address.
1436
  //   ii- ASCII representation: Catch the following four UART fields on the serial output port
1437
  //                             which include the current stimulus address in ASCII format.their
1438
  //                             data bytes are converted to binary format.
1439
  //                               -----------------------
1440
  // 3- Capture the following field which includes the end of line character.
1441
  //                               -----------------------
1442 2 HanySalah
 
1443
  task capture_text_write_command ( output int _spacetype1,
1444
                                    output int space_wrong1,
1445
                                    output int _spacetype2,
1446
                                    output int space_wrong2,
1447
                                    output int _eoltype,
1448
                                    output int eol_wrong,
1449
                                    output bit [`size-1:0] address,
1450
                                    output byte data);
1451
 
1452
    byte read_byte;
1453
    catch_field_serout(read_byte);
1454
    case (read_byte)
1455
      `space:
1456
        begin
1457
        _spacetype1  = `single_space;
1458
        end
1459
      `tab:
1460
        begin
1461
        _spacetype1  = `tab_space;
1462
        end
1463
      default:
1464
        begin
1465
        _spacetype1  = `space_wrong;
1466
        space_wrong1 = read_byte;
1467
        end
1468
    endcase
1469
 
1470
    case(data_rep)
1471
      `binary_rep:
1472
        begin
1473
        catch_field_serout(read_byte);
1474
        data = read_byte;
1475
        end
1476
      `ascii_rep:
1477
        begin
1478
        catch_field_serout(read_byte);
1479
        data[7:4] = asci_bin_conv(read_byte);
1480
        catch_field_serout(read_byte);
1481
        data[3:0] = asci_bin_conv(read_byte);
1482
        end
1483
      default:
1484
        begin
1485
        $error("undefined data representation");
1486
        $stop;
1487
        end
1488
    endcase
1489
 
1490
    catch_field_serout(read_byte);
1491
    case (read_byte)
1492
      `space:
1493
        begin
1494
        _spacetype2  = `single_space;
1495
        end
1496
      `tab:
1497
        begin
1498
        _spacetype2  = `tab_space;
1499
        end
1500
      default:
1501
        begin
1502
        _spacetype2  = `space_wrong;
1503
        space_wrong2 = read_byte;
1504
        end
1505
    endcase
1506
 
1507
    case(data_rep)
1508
      `binary_rep:
1509
        begin
1510
        catch_field_serout(read_byte);
1511
        address[15:08] = read_byte;
1512
        catch_field_serout(read_byte);
1513
        address[07:00] = read_byte;
1514
        end
1515
      `ascii_rep:
1516
        begin
1517
        catch_field_serout(read_byte);
1518
        address[15:12] = asci_bin_conv(read_byte);
1519
        catch_field_serout(read_byte);
1520
        address[11:08] = asci_bin_conv(read_byte);
1521
        catch_field_serout(read_byte);
1522
        address[07:04] = asci_bin_conv(read_byte);
1523
        catch_field_serout(read_byte);
1524
        address[03:00] = asci_bin_conv(read_byte);
1525
        end
1526
      default:
1527
        begin
1528
        $error("Undefined data representation");
1529
        $stop;
1530
        end
1531
    endcase
1532
 
1533
    catch_field_serout(read_byte);
1534
    case(read_byte)
1535
      `CR:
1536
        begin
1537
        _eoltype    = `cr_eol;
1538
        end
1539
      `LF:
1540
        begin
1541
        _eoltype    = `lf_eol;
1542
        end
1543
      default:
1544
        begin
1545
        _eoltype    = `eol_wrong;
1546
        eol_wrong   = read_byte;
1547
        end
1548
    endcase
1549
  endtask: capture_text_write_command
1550
 
1551 3 HanySalah
  // This method is used to capture binary mode command. Whenever it is called, the following
1552
  // procedures are carried out :
1553
  //                               -----------------------
1554
  // 1- Capture and decode the second command field which includes the command, the acknowledge
1555
  //    request and also the address auto-increment enable.
1556
  //  - In case that the command bits indicate invalid command, BFM uses wrond_data_ctrl internal
1557
  //    bit to know wether this stimulus is wrong read or wrong write. No response should be driven
1558
  //    by the DUT in the both cases. But we need to discriminte between the two cases to facili-
1559
  //    tates the scoreboard job.
1560
  //                               -----------------------
1561
  // 2- Capture the following field which includes the higher byte of the command address.
1562
  //                               -----------------------
1563
  // 3- Capture the following field which includes the lower byte of the command address.
1564
  //                               -----------------------
1565
  // 4- Capture the next field which includes the number of data bytes.
1566
  //                               -----------------------
1567
  // 5- According to the decoded command:
1568
  //    i- Read Command   : Poll the serial input port and capture number of successive UART fields
1569
  //                        equal to the number of data bytes. In case of acknowledge request, ano-
1570
  //                        ther field is captured and compared to the standard acknowledge
1571
  //                        character
1572
  //
1573
  //   ii- Write Command  : Poll the serial output port and capture number of successive UART fie-
1574
  //                        lds equal to the number of data bytes. In case of acknowledge request,
1575
  //                        another field is captured on the serial input port and compare to the
1576
  //                        standard acknowledge character
1577
  //
1578
  //  iii- NOP Command    : In case of acknowledge request, another field is captured on the serial
1579
  //                        input port and compared to the standard acknowledge character
1580
  //
1581
  //  iv- Invalid Command : In case that it is wrong read command, the same sequence obligied at
1582
  //                        the valid read command is carried out.
1583
  //                        In case that it is wrond write command, the same sequence obligied at
1584
  //                        the valid write command is carried out.
1585
  //                               -----------------------
1586
  // NOTE: Since the number of data bytes is defined at the run-time, we use queue of bytes to
1587
  //       packetaize the data temporarily and re-assign it to the dynamic array of data.
1588
  //                               -----------------------
1589 2 HanySalah
  task automatic capture_binary_command (output int _command,
1590
                                         output int _reqack,
1591
                                         output int _reqinc,
1592
                                         output bit [15:0] address,
1593
                                         output int data_length,
1594 3 HanySalah
                                         ref byte data [],
1595 2 HanySalah
                                         output byte acknowledge);
1596
    byte read_byte;
1597
    int index;
1598
    byte que [$];
1599 3 HanySalah
 
1600 2 HanySalah
    // first byte
1601
    catch_field_serout(read_byte);
1602
    case(read_byte[5:4])
1603
      `nop_ctrl:
1604
        begin
1605
        _command = `nop_comm;
1606
        end
1607
      `read_ctrl:
1608
        begin
1609
        _command = `read_comm;
1610
        end
1611
      `write_ctrl:
1612
        begin
1613
        _command = `write_comm;
1614
        end
1615 3 HanySalah
      `invalid_ctrl:
1616
        begin
1617
        if(wrong_data_ctrl)
1618
          begin
1619
          _command = `wrong_comm_write;
1620
          end
1621
        else
1622
          begin
1623
          _command = `wrong_comm_read;
1624
          end
1625
        end
1626 2 HanySalah
      default:
1627
        begin
1628 3 HanySalah
        $error("invalid Command");
1629 2 HanySalah
        end
1630
    endcase
1631 3 HanySalah
 
1632 2 HanySalah
    if (read_byte[1])
1633
      begin
1634
      _reqinc = `_no;
1635
      end
1636
    else
1637
      begin
1638
      _reqinc = `_yes;
1639
      end
1640
    if (read_byte[0])
1641
      begin
1642
      _reqack = `_yes;
1643
      end
1644
    else
1645
      begin
1646
      _reqack = `_no;
1647
      end
1648 3 HanySalah
      if (_command != `nop_comm)
1649
        begin
1650
        catch_field_serout(read_byte);
1651
        address[15:08] = read_byte;
1652 2 HanySalah
 
1653 3 HanySalah
        catch_field_serout(read_byte);
1654
        address[07:00] = read_byte;
1655 2 HanySalah
 
1656 3 HanySalah
        catch_field_serout(read_byte);
1657
        if (read_byte == 8'h00)
1658
          begin
1659
          data_length = 256;
1660
          end
1661
        else
1662
          begin
1663
          data_length = read_byte;
1664
          end
1665 2 HanySalah
 
1666 3 HanySalah
        que.delete();
1667
        if (_command == `read_comm || _command == `wrong_comm_read)
1668 2 HanySalah
          begin
1669 3 HanySalah
          index=0;
1670
          while(index < data_length)
1671
            begin
1672
            catch_field_serin(read_byte);
1673
            que.push_back(read_byte);
1674
            index++;
1675
            end
1676 2 HanySalah
          end
1677 3 HanySalah
        else if (_command == `write_comm || _command == `wrong_comm_write)
1678 2 HanySalah
          begin
1679 3 HanySalah
          index=0;
1680
          while(index < data_length)
1681
            begin
1682
            catch_field_serout(read_byte);
1683
            que.push_back(read_byte);
1684
            index++;
1685
            end
1686 2 HanySalah
          end
1687 3 HanySalah
        data = new [que.size];
1688
        data = que;
1689 2 HanySalah
        end
1690 3 HanySalah
    if(_reqack == `_yes)
1691
      begin
1692
      catch_field_serin(acknowledge);
1693
      end
1694 2 HanySalah
  endtask:capture_binary_command
1695
 
1696 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.