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

Subversion Repositories usb2uart

[/] [usb2uart/] [trunk/] [verify/] [agents/] [usb/] [usb_agent.v] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 dinesha
 
2
`timescale 1 ns/ 1 ns
3
module usb_agent (
4
        dpls,
5
        dmns
6
       );
7
 
8
inout         dpls, dmns;
9
wire  [24:0] ControlPkt;
10
 
11
 
12
 
13
    assign dpls = 1'bz;
14
    assign dmns = 1'bz;
15
 
16
    pullup(dpls);
17
    pulldown(dmns);
18
 
19
 
20
    // ------------------------------
21
    // Module Instantiations.---------------
22
    // ------------------------------
23
 
24
 
25
    // a. Host Bus Model Instantiation.
26
 
27
    host_usb_bfm bfm_inst( .DPLS( dpls ),
28
                      .DMNS( dmns ),
29
                      .ControlPkt( ControlPkt)
30
                    );
31
 
32
 
33
 
34
 
35
 
36
endmodule
37
 
38
module host_usb_bfm(
39
                DPLS,
40
                DMNS,
41
                ControlPkt
42
              );
43
 
44
inout       DPLS;
45
inout       DMNS;
46
output [24:0] ControlPkt;
47
 
48
wire        DPLS;
49
wire        DMNS;
50
 
51
reg         zDPLS;              // this register is driven in host_usb_drvr.v
52
reg         zDMNS;              // this register is driven in host_usb_drvr.v
53
 
54
wire        clk;                // clock
55
 
56
// encoder signals
57
reg         enc_enbl;           // signal to enable encoder block
58
reg         enc_reset_n;        // signal to reset encoder block
59
reg [7:0]   enc_data_in;        // byte wide data being pumped into the encoder
60
wire        enc_count_out;      // wire for encoder count_out signal
61
wire        enc_data_out_valid; // wire for encoder data_out_valid signal
62
reg         enc_last_byte;
63
wire [3:0]  enc_bit_count_out;
64
 
65
// decoder signals
66
reg         dec_enbl;           // signal to enable decoder block
67
reg         dec_reset_n;        // signal to reset decoder block
68
wire        dec_ser_data_rdy;   // signal to indicate serial data is ready
69
wire        dec_par_data_rdy;   // signal to indicate parallel data is ready
70
wire [7:0]  dec_par_data_out;   // parallel data out from decoder
71
wire [31:0] dec_recv_bit_count; // gives the number of bits received so far
72
wire        dec_bit_stuff_err;  // goes high if there is a bit stuff error in
73
                                // the present data stream
74
// dpll signals
75
reg         clk48;
76
reg         clk6;
77
reg         dpll_reset_n;
78
wire        dpll_clk;
79
reg         rec_clk;
80
wire        clk4x;
81
 
82
// Jitter control registers
83
 
84
integer     tmpJitterPeriod;
85
integer     tmpJitterCount;
86
 
87
// clock related registers
88
reg         HSClkComp;  // compensation when generating the 4x clock
89
reg         HSClkCompToggle;
90
 
91
////////////////////////////////////////////////
92
//                                            //
93
//  Added to accomodate 1 ms slots and files  //
94
//                                            //
95
////////////////////////////////////////////////
96
 
97
// reg [24:0]  ControlPkt;
98
 
99
// Control Packet format;
100
 
101
//   [0]    :  1 - Assert BufOk/0 - Donot assert BufOk.
102
//   [1]    :  1 - Create BufOk Error/0 - Donot Create BufOk Error.
103
//   [9:2]  :  Start Byte for In Transfers.
104
//   [10]   :  1 - Create a 4 Clock Protocol violation/0 - donot create vio.
105
//   [20:11]:  Errors after num transfers.
106
//   [21]   :  Stalled or Not.
107
//   [22]   :  Check for data on Application Bus during Writes.
108
//   [23]   :  Check for the Hshk on the Application Bus.
109
//   [24]   :  If check for hshkis true, 1'b1 = XfrAck, 1'b0 = XfrNack.
110
 
111
// integer   ByteCount;
112
// integer   Status ;
113
 
114
reg [6:0] dutAddr;
115
reg       sofOnFlag ;
116
integer   sofPeriod ;
117
reg       interruptOnFlag ;
118
reg       interruptRequest ;
119
integer   interruptTimer ;
120
integer   interruptPeriod ;
121
reg       controlRequest ;
122
reg       controlGrant ;
123
reg       bulkInOnFlag ;
124
reg       bulkOutOnFlag ;
125
 
126
parameter DumpToFile = 1;
127
 
128
parameter IN_OUT_BUF_SIZE     = 2048,    // outgoing buffer data size
129
          IN_OUT_BUF_PTR_SIZE = 12,      // number of bits in out buff pointer
130
 
131
          XMIT_BUF_SIZE       = 1028,    // Xmitbuffer size
132
          RECV_BUF_SIZE       = 1028;    // Recvbuffer size
133
 
134
parameter OUT_TOKEN           = 4'b0001,
135
          IN_TOKEN            = 4'b1001,
136
          SOF_TOKEN           = 4'b0101,
137
          SETUP_TOKEN         = 4'b1101,
138
          DATA0               = 4'b0011,
139
          DATA1               = 4'b1011,
140
          ACK                 = 4'b0010,
141
          NAK                 = 4'b1010,
142
          STALL               = 4'b1110,
143
          PREAMBLE            = 4'b1100;
144
 
145
parameter GET_CONFIGURATION   = 01,  // Standard Request Codes for end points
146
          GET_DESCRIPTOR      = 02,
147
          GET_INTERFACE       = 03,
148
          GET_MAX_PACKET      = 04,
149
          GET_STATUS          = 05,
150
          SET_ADDRESS         = 06,
151
          SET_CONFIGURATION   = 07,
152
          SET_DESCRIPTOR      = 08,
153
          SET_IDLE            = 09,
154
          SET_INTERFACE       = 10,
155
          SET_MAX_PACKET      = 11,
156
          SET_REMOTE_WAKEUP   = 12,
157
          SET_STATUS          = 13;
158
 
159
parameter DEVICE              = 1, // Descriptor Types
160
          CONFIGURATION       = 2,
161
          STRING              = 3,
162
          INTERFACE           = 4,
163
          ENDPOINT            = 5;
164
 
165
parameter GET_HUB_STATUS      = 0, // Hub class request codes
166
          GET_PORT_STATUS     = 0,
167
          CLEAR_FEATURE       = 1,
168
          GET_STATE           = 2,
169
          SET_FEATURE         = 3,
170
          // reserved for future use 4-5
171
          GET_HUB_DESCRIPTOR  = 6,
172
          SET_HUB_DESCRIPTOR  = 7;
173
 
174
parameter C_HUB_LOCAL_POWER   = 00, // Hub class feature selectors
175
          C_HUB_OVER_CURRENT  = 01,
176
          PORT_CONNECTION     = 00,
177
          PORT_ENABLE         = 01,
178
          PORT_SUSPEND        = 02,
179
          PORT_OVER_CURRENT   = 03,
180
          PORT_RESET          = 04,
181
          PORT_POWER          = 08,
182
          PORT_LOW_SPEED      = 09,
183
          C_PORT_CONNECTION   = 16,
184
          C_PORT_ENABLE       = 17,
185
          C_PORT_SUSPEND      = 18,
186
          C_PORT_OVER_CURRENT = 19,
187
          C_PORT_RESET        = 20;
188
 
189
parameter true                = 1'b1,
190
          True                = 1'b1,
191
          TRUE                = 1'b1,
192
          false               = 1'b0,
193
          False               = 1'b0,
194
          FALSE               = 1'b0;
195
 
196
parameter HIGH_SPEED          = 1'b1,
197
          LOW_SPEED           = 1'b0;
198
 
199
parameter J                   = 2'b10, // high speed idle state {DPLS, DMNS}
200
          K                   = 2'b01, // low speed idle state  {DPLS, DMNS}
201
          SE0                 = 2'b00, // single ended zero     {DPLS, DMNS}
202
          SE1                 = 2'b11; // single ended 1        {DPLS, DMNS}
203
 
204
parameter MAX_CNTRL_INTERLEAVE= 6;  // number of control transactions that can
205
                                    // interleaved
206
 
207
parameter NUM_ENDPT_FILES     = 12; // number of transmit files associtated
208
                                    // with endpoints
209
 
210
parameter READ                = 2'b10;
211
parameter WRITE               = 2'b11;
212
 
213
parameter BINARY              = 1'b0;
214
parameter HEX                 = 1'b1;
215
 
216
parameter XMIT_BUF            = 4'b0000;
217
parameter OUT_BUFF            = 4'b0001;
218
 
219
parameter NumCharsInFileName  = 20; // number of characters in a file name
220
parameter CharByte            = 8;  // number of bits for a character
221
parameter MaxFileSize         = 9 * 1024; // 9k file size
222
 
223
reg [7:0]   in_out_buf            [0 : IN_OUT_BUF_SIZE - 1];
224
reg [11:0]  in_out_buf_ptr;
225
 
226
reg [7:0]   XmitBuffer        [0 : XMIT_BUF_SIZE]; // Xmit buffer
227
reg [7:0]   RecvBuffer        [0 : RECV_BUF_SIZE]; // Recv buffer
228
 
229
reg [10:0]  FrameNumber;   // frame number
230
 
231
reg [15:0]  InDataToggle       [127:0]; // set\unset Data0/Data1 for data Xfers
232
reg [15:0]  OutDataToggle      [127:0]; // set\unset Data0/Data1 for data Xfers
233
 
234
reg         TimeOut;        // register to specify timeout
235
integer     TimeOutVal;     // value to specify for how many bit times
236
                            // to wait for before time out
237
 
238
reg [31:0]  ResponseLatency; // turnaround time for the host before
239
                             // responding
240
reg         IsoHeadGen;     // specifies if a header is generated for an 
241
                            // isochronous transfer or not
242
 
243
reg         GenCrc16Err;   // specifies if a crc error is to be generated or not
244
reg [15:0]  Crc16ErrMask;  // a particular crc bit is inverted according to the
245
                           // bit in the Mask is high
246
 
247
reg         GenCrc5Err;    // specifies if a crc error is to be generated or not
248
reg [4:0]   Crc5ErrMask;   // a particular crc bit is inverted according to the
249
                           // bit in the Mask is high
250
 
251
reg         ReportResults;  // reports results to a file
252
reg [NumCharsInFileName * CharByte : 1] ResultsFile;    // reports file name 
253
integer     ResultsFp;      // filepointer for reults file
254
 
255
reg         ReportErrors;
256
 
257
integer     PulseWidth;     // PulseWidth of USB clock
258
 
259
reg         SyncField;      // specifies if a correct/incorrect sync field is to
260
                            // be sent
261
reg [31:0]  SyncLevel;      // at which point in a task to corrupt the SyncField
262
reg [31:0]  SetSyncLevel;   // set this value before calling SendData
263
reg [7:0]   SyncFieldMask;  // specifies how the sync field is to be corrupted
264
 
265
reg         GenSE0Error;    // generate a SE0 error
266
reg [31:0]  SE0BitTimes;    // generate SE0 for this many bit times
267
reg [31:0]  SE0ErrorLevel;  // = 0 : generates a SE0 error after a sync field
268
                            // = 1 : generates a SE0 error after data
269
                            // = 2 : generates a SE0 error after a handshake
270
 
271
 
272
reg         HshkPidIntegrity; // specifies if correct ACKs should be sent
273
reg [7:0]   HshkPidIntegrityMask; // Mask according to which ACK's are corrupted
274
 
275
reg         BitStuffErr;
276
 
277
integer     RespTimeOutVal; // bit times to wait for when no response is to be
278
                            // sent
279
 
280
integer     tmpCounter;   // a scratch variable to be used any where
281
 
282
event       DoesNotOccur; // an event which will not be triggered to
283
                          // used to suspend threads
284
 
285
reg  [31:0]  StartTime;    // start time of a transaction
286
reg  [31:0]  StopTime;     // stop time of a transaction
287
reg  [31:0]  SE0StartTime; // start time of a single ended 0
288
reg  [31:0]  SE0StopTime;  // stop of a single ended 0
289
 
290
reg  [31:0]  SelfName;     // 4 byte wide register to differentiate between
291
                           // instantiations
292
 
293
 
294
// info about a current control transaction
295
 
296
reg  [1:0]   CntrlTransType  [1 : MAX_CNTRL_INTERLEAVE];
297
                               // type of control transaction
298
                               // 00 no control transaction in progress
299
                               // 01 control_rd transaction in progress
300
                               // 11 control_wr transaction in progress
301
reg  [6:0]   CntrlTransAddr  [1 : MAX_CNTRL_INTERLEAVE];
302
                               // address to which a cntrl trans is in progress
303
reg  [3:0]   CntrlTransEndP  [1 : MAX_CNTRL_INTERLEAVE];
304
                               // End Pnt to which a cntrl trans is in progress
305
reg  [15:0]  CntrlTransDlen  [1 : MAX_CNTRL_INTERLEAVE];
306
                               // data length for this control transaction
307
 
308
 
309
reg  [NumCharsInFileName * CharByte : 1] SendDataFileName;
310
     // File from which data to be sent is taken from, format is 1 byte per line
311
     // in hex format
312
 
313
reg  [NumCharsInFileName * CharByte : 1] RecvDataFileName;
314
     // File to which received data is logged to, format is 1 byte per line in
315
     // hex format
316
 
317
reg  [NumCharsInFileName * CharByte : 1] ErrorFileName;
318
     // file name to report errors
319
 
320
reg  [31:0]  RecvDataFp;   // file pointer to RecvDataFileName
321
 
322
reg  [31:0]  SendDataOfst; // offset into SendDataFileName
323
 
324
reg  [31:0]  ErrorFileFp;    // file pointer of the error file
325
 
326
 
327
reg  [NumCharsInFileName * CharByte : 1]  EndPtFileName [1 : NUM_ENDPT_FILES];
328
     // array to store file names associated with end points
329
reg  [1:0]                                EndPtFileMode [1 : NUM_ENDPT_FILES];
330
     // array to store read/write mode info for each file
331
reg  [31:0]                               EndPtFp [1 : NUM_ENDPT_FILES];
332
reg  [10:0]                               EndPtFileInfo [1 : NUM_ENDPT_FILES];
333
reg  [31:0]                               EndPtFileOfst [1 : NUM_ENDPT_FILES];
334
     // offset into the file if it is in write mode
335
 
336
 
337
reg          Debug;   // debugging messages are turned on if set to true
338
 
339
 
340
reg          GenDataPidErr;  // generates a data pid integrity error
341
reg  [7:0]   DataPidErrMask; // error mask for generating
342
reg          GenTokenErr;    // generates a token pid integrity error
343
reg  [7:0]   TokenErrMask;   // token error mask
344
 
345
reg          DeviceSpeed;    // low speed or high speed
346
 
347
reg          GenByteBoundary; // generate a byte boundary error
348
 
349
reg          SendPreamble;
350
 
351
// registers to log simulation results
352
 
353
reg  [31:0]  NumBulkInTrans;      // number of bulk in transactions
354
reg  [31:0]  NumSucBulkInTrans;   // number of successful bulk in transctions
355
reg  [31:0]  NumBulkOutTrans;     // number of bulk out transactions
356
reg  [31:0]  NumSucBulkOutTrans;  // number of successful bulk out transactions
357
reg  [31:0]  NumIsoInTrans;       // number of iso in transactions
358
reg  [31:0]  NumSucIsoInTrans;    // number of successful iso in transactions
359
reg  [31:0]  NumIsoOutTrans;      // number of iso out transactions
360
reg  [31:0]  NumSOF;              // number of SOF's sent
361
reg  [31:0]  NumCntrlRdTrans;     // number of control reads
362
reg  [31:0]  NumSucCntrlRdTrans;  // number of successful control reads
363
reg  [31:0]  NumCntrlWrTrans;     // number of control writes
364
reg  [31:0]  NumSucCntrlWrTrans;  // number of successful control writes
365
reg  [31:0]  NumIntrptTrans;      // number of interrupt transactions
366
reg  [31:0]  NumSucIntrptTrans;   // number of successful interrupt transactions
367
reg  [31:0]  NumIntrOutTrans;     // number of interrupt out transactions
368
reg  [31:0]  NumSucIntrOutTrans;  // number of successful interrupt out transactions
369
reg  [31:0]  NumResets;           // number of resets
370
 
371
 
372
// registers to store jitter information
373
 
374
integer HighJitterTime;     // time by which high time pulse width is modified
375
integer LowJitterTime;      // time by which low time pulse width is modified
376
integer JitterPeriod;       // specifies in pulse numbers when the Jitter is
377
                            // to be repeated
378
integer JitterCount;        // number of pulses for which jitter is induced
379
reg     JitterOnOff;        // specifies if jitter is being induced or not
380
 
381
reg     task_in_progress;
382
 
383
                            // SOF's
384
reg     hs_clk;             // high speed clock
385
reg     ls_clk;             // low-speed clock
386
reg     clk_swtch;          // clock switch
387
 
388
 
389
reg [31:0]  SetupDataLen;
390
 
391
reg     GenByteBoundaryPos;
392
reg     BoundaryBitVal;
393
 
394
integer     ModifyGran;
395
 
396
 
397
 
398
task DispErrMsg;
399
 
400
input [6:0] address;
401
input [3:0] EndPt;
402
input [31:0] ErrMsgNo;
403
 
404
begin
405
    if (ReportErrors == FALSE) disable DispErrMsg;
406
    if ((ErrorFileFp == 0) & (ErrorFileName == "")) begin
407
        $display("No file name specified to log errors.");
408
        disable DispErrMsg;
409
    end
410
    if (ErrorFileFp == 0) ErrorFileFp = $fopen(ErrorFileName);
411
    if ((ErrMsgNo >= 0) & (ErrMsgNo <= 32)) $fwrite(ErrorFileFp, "Error %0d :", (500 + ErrMsgNo));
412
    case (ErrMsgNo)
413
    0: $fdisplay(ErrorFileFp, "Time out for bulk in transfer at address %h for End Point %h at time %0t", address, EndPt, $time);
414
    1: $fdisplay(ErrorFileFp, "Time out for iso in transfer at address %h for End Point %h at time %0t", address, EndPt, $time);
415
    2: $fdisplay(ErrorFileFp, "Time out for interrupt transfer at address %h for End Point %h at time %0t", address, EndPt, $time);
416
    3: $fdisplay(ErrorFileFp, "Time out for control transfer at address %h for End Point %h at time %0t", address, EndPt, $time); //this EndPt value should be zero
417
    4: $fdisplay(ErrorFileFp, "Time out for bulk out transfer at address %h for End Point %h at time %0t", address, EndPt, $time);
418
    5: $fdisplay(ErrorFileFp, "Pid error at address %h for End Point %h at time %0t", address, EndPt, $time);
419
    6: $fdisplay(ErrorFileFp, "Short packet at address %h for End Point %h at time %0t", address, EndPt, $time);
420
    7: $fdisplay(ErrorFileFp, "CRC error for token packet at address %h for End Point %h at time %0t", address, EndPt, $time);
421
    8: $fdisplay(ErrorFileFp, "CRC error for data at address %h for End Point %h at time %0t", address, EndPt, $time);
422
    9: $fdisplay(ErrorFileFp, "Incorrect token received at address %h for End Point %h at time %0t", address, EndPt, $time);
423
    10: $fdisplay(ErrorFileFp, "Incorrect Data0/Data1 toggle received at address %h for End Point %h at time %0t", address, EndPt, $time);
424
    11: $fdisplay(ErrorFileFp, "NAK recevied at address %h for End Point %h at time %0t", address, EndPt, $time);
425
    12: $fdisplay(ErrorFileFp, "STALL received at address %h for End Point %h at time %0t", address, EndPt, $time);
426
    13: $fdisplay(ErrorFileFp, "Incorrect handshake received at address %h for End Point %h at time %0t", address, EndPt, $time);
427
    14: $fdisplay(ErrorFileFp, "Long packet at address %h for End Point %h at time %0t", address, EndPt, $time);
428
    15: $fdisplay(ErrorFileFp, "Corrupted handshake received at address %h for End Point %h at time %0t", address, EndPt, $time);
429
    16: $fdisplay(ErrorFileFp, "Device error at address %h for End Point %h at time %0t", address, EndPt, $time);
430
    17: $fdisplay(ErrorFileFp, "Invalid wIndex value for control transfer to address %h at time %0t", address, $time);
431
    18: $fdisplay(ErrorFileFp, "Invalid RequestType for control transfer to address %h at time %0t", address, $time);
432
    19: $fdisplay(ErrorFileFp, "Invalid wValue value for control transfer to address %h at time %0t", address, $time);
433
    20: $fdisplay(ErrorFileFp, "Invalid data length during data phase for control transfer to address %0h and End Point %0h at time %0t", address, EndPt, $time);
434
    21: $fdisplay(ErrorFileFp, "No setup transaction in progress to do a control_in or a control_out or a status transaction at time %0t", $time);
435
    22: $fdisplay(ErrorFileFp, "Doing a control_in when a control_out is expected and vice-versa at time %0t", $time);
436
    23: $fdisplay(ErrorFileFp, "Doing a control_in or control_out when the number of bytes specified by wLength have been received or sent at time %0t", $time);
437
    24: $fdisplay(ErrorFileFp, "Doing a status_in when a status_out is expected and vice-versa at time %0t", $time);
438
    25: $fdisplay(ErrorFileFp, "Received a DATA0 token during the status phase of a control transaction at address %0h, EndPt %0h, at time %0t", address, EndPt, $time);
439
    26: $fdisplay(ErrorFileFp, "Incorrect sync field at time %0t", $time);
440
    27: $fdisplay(ErrorFileFp, "Bit Stuffing error at time %0t", $time);
441
    28: $fdisplay(ErrorFileFp, "Eop incorrect at time %0t", $time);
442
    29: $fdisplay(ErrorFileFp, "Null File Name passed to command at time %0t", $time);
443
    30: $fdisplay(ErrorFileFp, "Offset into file greater than size of file at time %0t", $time);
444
    31: $fdisplay(ErrorFileFp, "Command not supported by a low speed device issued at time %0t.", $time);
445
    32: $fdisplay(ErrorFileFp, "Command not supported by command line interface issued at time %0t.", $time);
446
endcase
447
end
448
endtask
449
 
450
//bit 0 has the IN DataToggle and bit 1 has the OUT DataToggle
451
function [1:0] CheckDataToggle;
452
input [6:0]  address;
453
input [3:0]  EndPt;
454
 
455
reg   [15:0] tmpReg1;
456
reg   [15:0] tmpReg2;
457
 
458
begin
459
    tmpReg1 = InDataToggle[address];
460
    tmpReg2 = OutDataToggle[address];
461
    if ((EndPt < 16) & (EndPt >= 0)) begin
462
        CheckDataToggle[0] = tmpReg1[EndPt];
463
        CheckDataToggle[1] = tmpReg2[EndPt];
464
    end
465
    else CheckDataToggle = 0;  // default
466
end
467
endfunction
468
 
469
function CheckDataToggleIN;
470
input [6:0]  address;
471
input [3:0]  EndPt;
472
 
473
reg   [15:0] tmpReg;
474
 
475
begin
476
    tmpReg = InDataToggle[address];
477
    if ((EndPt < 16) & (EndPt >= 0)) CheckDataToggleIN = tmpReg[EndPt];
478
    else CheckDataToggleIN = 0;  // default
479
end
480
endfunction
481
 
482
function CheckDataToggleOUT;
483
input [6:0]  address;
484
input [3:0]  EndPt;
485
 
486
reg   [15:0] tmpReg;
487
 
488
begin
489
    tmpReg = OutDataToggle[address];
490
    if ((EndPt < 16) & (EndPt >= 0)) CheckDataToggleOUT = tmpReg[EndPt];
491
    else CheckDataToggleOUT = 0;  // default
492
end
493
endfunction
494
 
495
task SetDataToggle;
496
input [6:0]  address;
497
input [3:0]  EndPt;
498
input [1:0]  SetVal; //value to which the toggle value should be changed to
499
                     // index 0 has the IN value and index 1 has the OUT value
500
reg   [15:0] tmpReg;
501
begin
502
    tmpReg = InDataToggle[address];
503
    if ((SetVal[0] == 0) | (SetVal[0] == 1)) tmpReg[EndPt] = SetVal;
504
    else tmpReg[EndPt] = 0; // default
505
    InDataToggle[address] = tmpReg;
506
    tmpReg = OutDataToggle[address];
507
    if ((SetVal[1] == 0) | (SetVal[1] == 1)) tmpReg[EndPt] = SetVal;
508
    else tmpReg[EndPt] = 0; // default
509
    OutDataToggle[address] = tmpReg;
510
end
511
endtask
512
 
513
task SetDataToggleIN;
514
input [6:0]  address;
515
input [3:0]  EndPt;
516
input SetVal; //value to which the toggle value should be changed to
517
reg   [15:0] tmpReg;
518
begin
519
    tmpReg = InDataToggle[address];
520
    if ((SetVal == 0) | (SetVal == 1)) tmpReg[EndPt] = SetVal;
521
    else tmpReg[EndPt] = 0; // default
522
    InDataToggle[address] = tmpReg;
523
end
524
endtask
525
 
526
task SetDataToggleOUT;
527
input [6:0]  address;
528
input [3:0]  EndPt;
529
input SetVal; //value to which the toggle value should be changed to
530
reg   [15:0] tmpReg;
531
begin
532
    tmpReg = OutDataToggle[address];
533
    if ((SetVal == 0) | (SetVal == 1)) tmpReg[EndPt] = SetVal;
534
    else tmpReg[EndPt] = 0; // default
535
    OutDataToggle[address] = tmpReg;
536
end
537
endtask
538
 
539
function [7:0] CorruptHshk;
540
input  [7:0] funHshk;
541
reg    [7:0] tmpReg;
542
reg    [4:0] i;
543
begin
544
tmpReg = funHshk;
545
if (HshkPidIntegrity == TRUE) begin
546
    for (i = 0; i < 8; i = i + 1) begin
547
        if (HshkPidIntegrityMask[i] == 1'b1) tmpReg[i] = ~tmpReg[i];
548
    end
549
end
550
CorruptHshk = tmpReg;
551
end
552
endfunction
553
 
554
 
555
////////////////////////////////////////////////////////////////////////////////
556
//
557
//  swap2 : swaps around the bits in half a nibble
558
//
559
////////////////////////////////////////////////////////////////////////////////
560
function [1:0] swap2;
561
input    [1:0] SwapBits;
562
begin
563
swap2 = {SwapBits[0], SwapBits[1]};
564
end
565
endfunction
566
 
567
 
568
////////////////////////////////////////////////////////////////////////////////
569
//
570
//  swap8 : swaps around the bits in a byte and returns the swapped byte
571
//
572
////////////////////////////////////////////////////////////////////////////////
573
function [7:0] swap8;
574
input    [7:0] SwapByte;
575
begin
576
swap8 = {SwapByte[0], SwapByte[1], SwapByte[2], SwapByte[3], SwapByte[4], SwapByte[5], SwapByte[6], SwapByte[7]};
577
end
578
endfunction
579
 
580
////////////////////////////////////////////////////////////////////////////////
581
//
582
//  DumpData : dumps the data received into in_out_buf to a file
583
//  Inputs   : address   : device address to which data is dumped to the 
584
//                         associated file, 7 bits
585
//             EndPt     : End Point number, 4 bits
586
//             ByteCount : number of bytes to dump from in_out_buf to the file
587
//
588
////////////////////////////////////////////////////////////////////////////////
589
task DumpData;
590
 
591
input   [6:0]  address;
592
input   [3:0]  EndPt;
593
input   [3:0]  DataToggle;
594
input   [31:0] ByteCount;
595
 
596
integer        i;
597
integer        j;
598
 
599
reg     [39:0] DataToggleString;
600
reg            Match;
601
 
602
begin
603
DataToggleString = (DataToggle == DATA0) ? "DATA0" : "DATA1" ;
604
Match = FALSE;
605
for (i = 1; i <= NUM_ENDPT_FILES; i = i + 1) begin
606
   if (EndPtFileInfo[i] == {EndPt, address}) begin
607
       if ((EndPtFp[i] > 0) & (EndPtFileMode[i] == WRITE)) begin
608
           $fdisplay (EndPtFp[i], "//address = %b, EndPt = %b, Data Toggle = %0s at time = %0t", address, EndPt, DataToggleString, $time);
609
           //for (j = 1; j <= ByteCount; j = j + 1) $fwrite (EndPtFp[i], "%h, ", in_out_buf [j]);
610
           for (j = 1; j <= ByteCount; j = j + 1) $fdisplay (EndPtFp[i], "%h", in_out_buf[j]);
611
           $fdisplay(EndPtFp[i], "\n");
612
           Match = TRUE;
613
       end
614
       i = NUM_ENDPT_FILES + 1;
615
   end
616
end
617
 
618
if (Match == FALSE) begin // no file name associated with this address
619
                          // dump data into the common bucket(file)
620
    if (RecvDataFp == 0) RecvDataFp = $fopen(RecvDataFileName);
621
    $fdisplay (RecvDataFp, "//address = %b, EndPt = %b, Data Toggle = %0s at time = %0t", address, EndPt, DataToggleString, $time);
622
    //for (j = 1; j <= ByteCount; j = j + 1) $fwrite (RecvDataFp, "%h, ", in_out_buf[j]);
623
    for (j = 1; j <= ByteCount; j = j + 1) $fdisplay (RecvDataFp, "%h", in_out_buf[j]);
624
    $fdisplay(RecvDataFp, "\n");
625
end
626
 
627
end
628
endtask
629
 
630
 
631
 
632
function [7:0] CorruptDataPid;
633
input [7:0]    funDataPid;
634
integer        i;
635
reg   [7:0]    tmpReg;
636
begin
637
tmpReg = funDataPid;
638
if (GenDataPidErr == TRUE) begin
639
    for ( i = 0; i < 8; i = i + 1) begin
640
        if (DataPidErrMask[i] == 1'b1) tmpReg[i] = ~tmpReg[i];
641
    end
642
end
643
CorruptDataPid = tmpReg;
644
end
645
endfunction
646
 
647
 
648
function [7:0] CorruptToken;
649
input [7:0]    funToken;
650
integer        i;
651
reg   [7:0]    tmpReg;
652
begin
653
tmpReg = funToken;
654
if (GenTokenErr == TRUE) begin
655
    for ( i = 0; i < 8; i = i + 1) begin
656
        if (TokenErrMask[i] == 1'b1) tmpReg[i] = ~tmpReg[i];
657
    end
658
end
659
CorruptToken = tmpReg;
660
end
661
endfunction
662
 
663
 
664
////////////////////////////////////////////////////////////////////////////////
665
//
666
//   WriteResults : writes out the results to the file pointed to by ResultsFp
667
//
668
////////////////////////////////////////////////////////////////////////////////
669
task WriteResults;
670
 
671
begin
672
 
673
if (ResultsFile == "") disable WriteResults;
674
 
675
if (ResultsFp != 0) $fclose(ResultsFp);
676
 
677
ResultsFp = $fopen(ResultsFile);
678
 
679
$fdisplay(ResultsFp, "\n");
680
$fdisplay(ResultsFp, "--------------------------------------------------------------------------------");
681
$fdisplay(ResultsFp, "-------------------- Transfer Statistics for the HOST model --------------------");
682
$fdisplay(ResultsFp, "--------------------------------------------------------------------------------");
683
$fdisplay(ResultsFp, "\n");
684
 
685
 
686
$fdisplay(ResultsFp,
687
                 "     Simulation Start Time ------------------------------ : 0",);
688
$fdisplay(ResultsFp,
689
                 "     Number of Bulk In transactions --------------------- : %0d",
690
                 NumBulkInTrans);
691
$fdisplay(ResultsFp,
692
                 "     Number of Successful Bulk In transactions ---------- : %0d",
693
                 NumSucBulkInTrans);
694
$fdisplay(ResultsFp,
695
                 "     Number of Bulk Out transactions -------------------- : %0d",
696
                 NumBulkOutTrans);
697
$fdisplay(ResultsFp,
698
                 "     Number of Successful Bulk Out transactions --------- : %0d",
699
                 NumSucBulkOutTrans);
700
$fdisplay(ResultsFp,
701
                 "     Number of Iso In transactions ---------------------- : %0d",
702
                 NumIsoInTrans);
703
$fdisplay(ResultsFp,
704
                 "     Number of Successful Iso In transactions ----------- : %0d",
705
                 NumSucIsoInTrans);
706
$fdisplay(ResultsFp,
707
                 "     Number of Iso Out transactions --------------------- : %0d",
708
                 NumIsoOutTrans);
709
$fdisplay(ResultsFp,
710
                 "     Number of Interrupt transactions ------------------- : %0d",
711
                 NumIntrptTrans);
712
$fdisplay(ResultsFp,
713
                 "     Number of Successful Interrupt transactions -------- : %0d",
714
                 NumSucIntrptTrans);
715
$fdisplay(ResultsFp,
716
                 "     Number of resets ----------------------------------- : %0d",
717
                 NumResets);
718
$fdisplay(ResultsFp,
719
                 "     Number of SOF's sent ------------------------------- : %0d",
720
                 NumSOF);
721
$fdisplay(ResultsFp,
722
                 "     Number of Control Read transactions ---------------- : %0d",
723
                 NumCntrlRdTrans);
724
$fdisplay(ResultsFp,
725
                 "     Number of Successful Control Read transactions ----- : %0d",
726
                 NumSucCntrlRdTrans);
727
$fdisplay(ResultsFp,
728
                 "     Number of Control Write transactions --------------- : %0d",
729
                 NumCntrlWrTrans);
730
$fdisplay(ResultsFp,
731
                 "     Number of Successful Control Write transactions ---- : %0d",
732
                 NumSucCntrlWrTrans);
733
$fdisplay(ResultsFp,
734
                 "     Simulation End Time -------------------------------- : %0t",
735
                 $time);
736
$fdisplay(ResultsFp, "\n");
737
 
738
end
739
endtask
740
 
741
 
742
////////////////////////////////////////////////////////////////////////////////
743
//
744
//  CorruptCrc16 : Corrupts the crc16 value passed on to it according to the
745
//                 present crc16 error generation status
746
//
747
////////////////////////////////////////////////////////////////////////////////
748
function [15:0] CorruptCrc16;
749
input    [15:0] funCrc16;
750
reg      [5:0]  i;
751
begin
752
if (GenCrc16Err == TRUE) begin
753
    for (i = 0; i < 16; i = i + 1) begin
754
        if (Crc16ErrMask[i] == 1'b1) funCrc16[i] = ~funCrc16[i];
755
    end
756
end
757
CorruptCrc16 = funCrc16;
758
end
759
endfunction
760
 
761
 
762
////////////////////////////////////////////////////////////////////////////////
763
//
764
//  CorruptCrc5 : Corrupts the crc5 value passed on to it according to the
765
//                present crc5 error generation status
766
//
767
////////////////////////////////////////////////////////////////////////////////
768
function [4:0] CorruptCrc5;
769
input    [4:0] funCrc5;
770
reg      [5:0] i;
771
begin
772
if (GenCrc5Err == TRUE) begin
773
    for (i = 0; i < 5; i = i + 1) begin
774
        if (Crc5ErrMask[i] == 1'b1) funCrc5[i] = ~funCrc5[i];
775
    end
776
end
777
CorruptCrc5 = funCrc5;
778
end
779
endfunction
780
 
781
 
782
////////////////////////////////////////////////////////////////////////////////
783
//
784
//  modify_device_speed : modifies the device speed
785
//
786
////////////////////////////////////////////////////////////////////////////////
787
task modify_device_speed;
788
input tskDeviceSpeed;
789
begin
790
DeviceSpeed = (tskDeviceSpeed == LOW_SPEED) ? LOW_SPEED:HIGH_SPEED;
791
end
792
endtask
793
 
794
 
795
////////////////////////////////////////////////////////////////////////////////
796
//
797
// CorruptSyncField : corrupts the sync field according to SyncFieldMask
798
//
799
////////////////////////////////////////////////////////////////////////////////
800
function [7:0] CorruptSyncField;
801
input [7:0] funSyncField;
802
reg   [7:0] tmpReg;
803
reg   [4:0] i;
804
begin
805
tmpReg = funSyncField;
806
if ((SyncField == TRUE) & (SyncLevel == SetSyncLevel)) begin
807
    for (i = 0; i < 8; i = i + 1) begin
808
        if (SyncFieldMask[i] == 1'b1) tmpReg[i] = ~tmpReg[i];
809
    end
810
end
811
CorruptSyncField = tmpReg;
812
end
813
endfunction
814
 
815
 
816
////////////////////////////////////////////////////////////////////////////////
817
//
818
// SendData : serialises and puts out the data in in_out_buf onto DPLS(D+)
819
//            and DMNS(D-)
820
//
821
////////////////////////////////////////////////////////////////////////////////
822
task SendData;
823
integer        i;
824
reg     [31:0] SE0Counter; // Single Ended Zero Counter
825
reg     [31:0] SE0Terminate;
826
event          SE0Event;
827
begin
828
i = 0;
829
SE0Counter = 2'b00;
830
if (in_out_buf_ptr > 0) begin
831
    @(posedge clk);
832
    @(posedge clk) begin // synchronise to positive edge of clock
833
        enc_enbl = 1'b1; // active high
834
        enc_reset_n = 1'b1; // active low
835
        enc_last_byte = 1'b0;
836
        enc_data_in = CorruptSyncField(8'h80);
837
    end
838
    fork
839
        forever @(posedge clk) begin
840
            if (GenByteBoundary == TRUE) begin
841
                if ((i == in_out_buf_ptr) & (enc_bit_count_out == 6)) begin
842
                    enc_enbl = 1'b0;
843
                    enc_reset_n = 1'b0;
844
                    in_out_buf_ptr = 0;
845
                    -> SE0Event;
846
                end
847
            end
848
        end
849
 
850
        forever @(posedge clk) begin
851
           if (GenByteBoundaryPos == TRUE) begin
852
              in_out_buf[in_out_buf_ptr + 1] = {BoundaryBitVal, BoundaryBitVal, BoundaryBitVal, BoundaryBitVal, BoundaryBitVal, BoundaryBitVal, BoundaryBitVal, BoundaryBitVal};
853
              if ((i == (in_out_buf_ptr + 1)) & (enc_bit_count_out == 0)) begin
854
                 enc_enbl = 1'b0;
855
                 enc_reset_n = 1'b0;
856
                 in_out_buf_ptr = 0;
857
                 -> SE0Event;
858
              end
859
           end
860
        end
861
 
862
        forever @(negedge enc_count_out) begin
863
            if ((i == in_out_buf_ptr) & (GenByteBoundaryPos == FALSE)) begin
864
                //@(posedge clk);
865
                enc_enbl = 1'b0; // active high
866
                enc_reset_n = 1'b0; // active low
867
                in_out_buf_ptr = 0; // reset output buffer pointer
868
                -> SE0Event;
869
            end
870
            else begin
871
                enc_data_in = in_out_buf[i];
872
                if (i == in_out_buf_ptr - 1) enc_last_byte = 1'b1;
873
                else enc_last_byte = 1'b0;
874
                //if (Debug) $display("in_out_buf[%h] = %h at time %0t",i, in_out_buf[i], $time);
875
                i = i + 1;
876
            end
877
        end
878
 
879
        forever @(SE0Event) begin // drive a SE0 for 2 bit times
880
            SE0Terminate = ((GenSE0Error == TRUE) & (SE0ErrorLevel == SetSyncLevel)) ? (SE0BitTimes) : 2;
881
            if (ModifyGran < -8) ModifyGran = -8;
882
            // SE0Terminate = (SE0Terminate * 4) + ModifyGran;
883
            // @(posedge clk);
884
            // forever @(posedge clk4x) begin
885
            forever @(posedge clk) begin
886
                if (SE0Counter >= SE0Terminate) begin
887
                    zDPLS = #1 1'bZ;
888
                    zDMNS =  1'bZ;
889
                    @(posedge clk); // wait for one idle state after pulls
890
                    disable SendData;
891
                end
892
                if (i >= in_out_buf_ptr) begin
893
                    zDPLS = #1 1'b0;
894
                    zDMNS =  1'b0;
895
                    SE0Counter = SE0Counter + 1;
896
                end
897
            end
898
        end
899
    join
900
end
901
 
902
end
903
endtask
904
 
905
////////////////////////////////////////////////////////////////////////////////
906
//
907
// WaitForResp : collects the data from DPLS(D+) and DMNS(D-) and fills in_out_buf
908
//
909
////////////////////////////////////////////////////////////////////////////////
910
task WaitForResp;
911
 
912
output  [31:0]  recv_bit_count;
913
 
914
reg     [31:0]  recv_bit_count;
915
integer         EopDetect;
916
reg     [4:0]   ClkCount;
917
reg     [3:0]   DplsCount;
918
reg             FltrSyncFld;
919
integer         tmpTimeOutCounter;
920
reg             tmpTimeOut;
921
reg             OnlyOnce;
922
reg             SyncDetect;
923
time            SyncPulseT1;
924
time            SyncPulseT2;
925
time            SyncPulseDuration;
926
 
927
begin
928
if (Debug) $display("In %0s --> In task wait for response at time %0t", SelfName, $time);
929
EopDetect         = 0;
930
in_out_buf_ptr    = 0;
931
DplsCount         = 0;
932
ClkCount          = 0;
933
FltrSyncFld       = 1'b1;
934
tmpTimeOutCounter = 0;
935
tmpTimeOut        = TRUE;
936
recv_bit_count    = 0;
937
OnlyOnce          = TRUE;
938
SyncDetect        = FALSE;
939
 
940
// dec_enbl = 1'b1;              // active high
941
// dec_reset_n = 1'b1;           // active low
942
begin : TimeOutBlock
943
    forever @(posedge dpll_clk) begin
944
    //if (Debug) $display("In %0s --> waiting for event in WaitForResp %0t", SelfName, $time);
945
        if (TimeOut == TRUE) begin
946
            if (tmpTimeOutCounter == TimeOutVal) begin
947
                if (Debug) $display("In %0s --> Time out at time %0t", SelfName, $time);
948
                disable WaitForResp;
949
            end
950
            tmpTimeOutCounter = tmpTimeOutCounter + 1;
951
        end
952
        //if (Debug) $display("In %0s --> DeviceSpeed = %b at time %0t", SelfName, DeviceSpeed, $time);
953
        //if (DPLS === 1'b0) begin
954
        if (DPLS === ~DeviceSpeed) begin
955
           if (Debug) $display("In %0s --> DPLS = %b , DeviceSpeed = %b at time %0t", SelfName, DPLS, DeviceSpeed, $time);
956
           if (DMNS === DeviceSpeed) begin   // differential data
957
 
958
               @DPLS
959
               StartTime = $time;
960
               SyncPulseT1 = $time;
961
               @DPLS
962
               SyncPulseT2 = $time;
963
               @DPLS
964
               SyncPulseDuration = SyncPulseT2 - SyncPulseT1;
965
               @DPLS
966
               SyncPulseT1 = $time;
967
               @DPLS
968
               SyncPulseT2 = $time;
969
               @DPLS
970
               #SyncPulseDuration
971
               #SyncPulseDuration
972
               #SyncPulseDuration
973
 
974
               dec_enbl = 1'b1;              // active high
975
               dec_reset_n = 1'b1;           // active low
976
               // StartTime = $time;   this time should be start of syncpulse
977
               disable TimeOutBlock;
978
           end
979
           else if ((DMNS === 1'b0) & (DPLS === 1'b0)) begin
980
               EopDetect = 1;
981
               disable TimeOutBlock;
982
           end
983
        end
984
    end
985
end // TimeOutBlock
986
 
987
if (Debug) $display("In %0s --> Decoder enabled at time %0t in host", SelfName, $time);
988
fork
989
    begin : DataSink
990
    forever @(posedge dec_par_data_rdy) begin
991
        if (FltrSyncFld == 1'b1) begin  // filter out the sync field
992
            in_out_buf[in_out_buf_ptr] = dec_par_data_out;
993
            in_out_buf_ptr = in_out_buf_ptr + 1;
994
        end
995
        if (dec_par_data_out == {~PREAMBLE, PREAMBLE} &
996
            in_out_buf_ptr == 1) begin
997
            dec_enbl = 1'b0;
998
            dec_reset_n = 1'b0;
999
            StopTime = $time;
1000
            disable WaitForResp;
1001
        end
1002
        if (Debug) $display("In %0s --> receive data = %h", SelfName, dec_par_data_out);
1003
        if (FltrSyncFld == 1'b0) begin
1004
/*
1005
            if (dec_par_data_out != 8'h80) begin
1006
                if (Debug) $display("In %0s --> Incorrect sync field %0h received at time %0t, ...discarding packet", SelfName, dec_par_data_out, $time);
1007
                in_out_buf_ptr = 0; // equivalent to a time out
1008
                dec_enbl = 1'b0;
1009
                dec_reset_n = 1'b0;
1010
                wait(1==0); // wait while the other block detects a EOP and disables task
1011
            end
1012
*/
1013
        end
1014
        FltrSyncFld = 1'b1;
1015
    end
1016
    end
1017
 
1018
    forever @(posedge dpll_clk) begin
1019
        if (dec_bit_stuff_err == 1'b1) begin
1020
            if (OnlyOnce == TRUE) begin
1021
                DispErrMsg(0, 0, 27);
1022
                OnlyOnce = FALSE;
1023
                in_out_buf_ptr = 0;  // reset data pointer
1024
            end
1025
            disable DataSink;
1026
        end
1027
        if((DPLS == DMNS) & (DPLS == 1'b0)) begin
1028
            EopDetect = EopDetect + 1;
1029
            recv_bit_count = dec_recv_bit_count - 1;
1030
            if (StopTime == 0) StopTime = $time;
1031
            if (SE0StartTime == 0) SE0StartTime = $time;
1032
            if (Debug) $display("In %0s --> StopTime = %0d, SE0StartTime = %0d", SelfName, StopTime, SE0StartTime);
1033
        end
1034
        if (EopDetect == 1) begin
1035
            if (DPLS == ~DMNS) begin // SE0 seen for only 1 bit time
1036
                if (Debug) $display("In %0s --> EOP asserted for 1 bit time at time %0t", SelfName, $time);
1037
                dec_enbl = 1'b0; // disable the decoder
1038
                dec_reset_n = 1'b0; // reset the decoder
1039
                SE0StopTime = $time;
1040
                disable WaitForResp; // incorrect EOP was received
1041
            end
1042
        end
1043
        if (EopDetect == 2) begin
1044
            dec_enbl = 1'b0; // disable the decoder
1045
            dec_reset_n = 1'b0; // reset the decoder
1046
            if (DPLS == ~DMNS) begin
1047
                if (Debug) $display("In %0s --> EOP asserted for 2 bit time at time %0t", SelfName, $time);
1048
                dec_enbl = 1'b0; // disable the decoder
1049
                dec_reset_n = 1'b0; // reset the decoder
1050
                SE0StopTime = $time;
1051
                disable WaitForResp; // correct EOP was received
1052
            end
1053
        end
1054
        if ((EopDetect > 2) & (EopDetect < 32)) begin // incorrect EOP received
1055
            if (DPLS == ~DMNS) begin
1056
                if (Debug) $display("In %0s --> EOP asserted for %h bit times at time ", SelfName, EopDetect, $time);
1057
                SE0StopTime = $time;
1058
                disable WaitForResp;
1059
            end
1060
        end
1061
        if (EopDetect >= 32) begin
1062
            if (DPLS == ~DMNS) begin
1063
                if (Debug) $display("In %0s --> Reset at time ", SelfName, $time);
1064
                SE0StopTime = $time;
1065
                in_out_buf_ptr = 0;
1066
                disable WaitForResp;
1067
            end
1068
        end
1069
    end
1070
join
1071
 
1072
 
1073
end
1074
endtask
1075
 
1076
 
1077
////////////////////////////////////////////////////////////////////////////////
1078
//
1079
//  SendReset : asserts a SE0 on the USB for the number of bit times specified
1080
//              by ResetTime.
1081
//  Input     : ResetTime, number of bit times for which to drive a reset on
1082
//              the USB
1083
//
1084
////////////////////////////////////////////////////////////////////////////////
1085
 
1086
task SendReset;
1087
 
1088
input [7:0] ResetTime;
1089
reg [7:0] tskResetTime;
1090
reg [7:0] tskResetTimeCounter;
1091
 
1092
begin
1093
    tskResetTime = ResetTime;
1094
    //if (tskResetTime <= 32) tskResetTime = 7'b0100000;
1095
    //if (tskResetTime >= 64) tskResetTime = 7'b1000000;
1096
    tskResetTimeCounter = 7'b0000000;
1097
    forever @(posedge clk) begin
1098
        zDPLS = 1'b0;
1099
        zDMNS = 1'b0;
1100
        tskResetTimeCounter = tskResetTimeCounter + 1'b1;
1101
        if (tskResetTimeCounter > tskResetTime) begin
1102
            zDPLS = 1'bz;
1103
            zDMNS = 1'bz;
1104
            @(posedge clk);
1105
            @(posedge clk);
1106
            disable SendReset;
1107
        end
1108
    end
1109
end
1110
endtask
1111
 
1112
 
1113
 
1114
 
1115
 
1116
parameter M16 = 16'h8005; //mask value to calculate 16 bit crc
1117
parameter M05 = 8'h05;    //mask value to calculate 5 bit crc
1118
 
1119
function [15:0] crc16;
1120
input    [7:0]  DataByte;
1121
input    [15:0] PrevCrc;
1122
 
1123
reg      [15:0] TempPrevCrc;
1124
integer         i;
1125
 
1126
begin
1127
    TempPrevCrc = PrevCrc;
1128
    for (i = 0; i < 8; i = i + 1)
1129
    begin
1130
        if (DataByte[i] ^ TempPrevCrc[15] )
1131
            TempPrevCrc = {TempPrevCrc[14:0],1'b0} ^ M16;
1132
        else
1133
            TempPrevCrc = {TempPrevCrc[14:0], 1'b0};
1134
    end
1135
    crc16 = TempPrevCrc;
1136
end
1137
 
1138
endfunction
1139
 
1140
 
1141
////////////////////////////////////////////////////////////////////////////////
1142
//function crc5 calculates a 5 bit crc
1143
//inputs :
1144
//         PrevCrc : 5 bit value, initially set to zero by the
1145
//                   calling module, from the next call onwards
1146
//                   it is the previous CRC value returned by
1147
//                   the function.
1148
//
1149
//         DataByte : 8 bit value for which crc is to calculated
1150
//
1151
////////////////////////////////////////////////////////////////////////////////
1152
 
1153
function [4:0] crc5;
1154
input    [10:0] DataByte;
1155
input    [4:0] PrevCrc;
1156
 
1157
reg      [4:0] TempPrevCrc;
1158
integer        i;
1159
begin
1160
    TempPrevCrc = PrevCrc;
1161
    for (i = 0; i < 11; i = i + 1)
1162
    begin
1163
        if (DataByte[i] ^ TempPrevCrc[4] )
1164
            TempPrevCrc = {TempPrevCrc[3:0],1'b0} ^ M05;
1165
        else
1166
            TempPrevCrc = {TempPrevCrc[3:0], 1'b0};
1167
    end
1168
    crc5 = TempPrevCrc[4:0];
1169
end
1170
endfunction
1171
 
1172
 
1173
 
1174
 
1175
///////////////////////////////////////////////////////////////////////////////
1176
//
1177
//  FillCrc5 : fills with crc5 given a 11 bit value
1178
//  input    : InVal, in value for which crc5 has to be appended
1179
//             this is a 11 bit value for which the 7 LSB bits are address and 
1180
//             4 MSB bits are end point number
1181
//  returns  : 16 bit value for which is InVal with crc5 appended to it.
1182
//
1183
///////////////////////////////////////////////////////////////////////////////
1184
function [15:0] FillCrc5;
1185
input  [10:0] InVal;
1186
reg    [15:0] tmpReg;
1187
begin
1188
tmpReg[10:0] =  InVal;     // put address and EndPt into consecutive bits
1189
tmpReg[15:11] = crc5(InVal, 5'b11111); // calculate crc5 for the first 8 bits
1190
 
1191
tmpReg[15:11] ={tmpReg[11], tmpReg[12], tmpReg[13], tmpReg[14], tmpReg[15]};
1192
tmpReg[6:0] = InVal[6:0];   // address
1193
tmpReg[10:7] = InVal[10:7]; // End Point
1194
if (GenCrc5Err == FALSE) tmpReg[15:11] = ~tmpReg[15:11];
1195
                                               // invert the bits in the crc
1196
tmpReg[15:11] = CorruptCrc5(tmpReg[15:11]); // crc5 corruption
1197
FillCrc5 = tmpReg;
1198
end
1199
endfunction
1200
 
1201
 
1202
 
1203
////////////////////////////////////////////////////////////////////////////////
1204
//
1205
//  FillCrc16 : Calculates the crc16 value from in_out_buf
1206
//  input   : StartAddr : start address of in_out_buf, 32 bits
1207
//            StopAddr  : stop address of in_out_buf, 32 bits
1208
//  returns : 16 bit value which is the crc16 for this segment of memory
1209
//
1210
////////////////////////////////////////////////////////////////////////////////
1211
function [16:0] FillCrc16;
1212
 
1213
input    [31:0] StartAddr;
1214
input    [31:0] StopAddr;
1215
 
1216
reg      [16:0] tmpCrc;
1217
integer         i;
1218
 
1219
begin
1220
tmpCrc = 16'hffff;
1221
for (i = StartAddr; i <= StopAddr; i = i + 1) begin
1222
    tmpCrc = crc16(in_out_buf[i], tmpCrc);
1223
end
1224
FillCrc16 = tmpCrc;
1225
end
1226
endfunction
1227
 
1228
 
1229
 
1230
////////////////////////////////////////////////////////////////////////////////
1231
//
1232
//   SendAck : sends an ack 
1233
//
1234
////////////////////////////////////////////////////////////////////////////////
1235
task SendAck;
1236
 
1237
begin
1238
task_in_progress = TRUE;
1239
in_out_buf[0] = CorruptHshk({~ACK, ACK});
1240
in_out_buf_ptr = 1;
1241
SetSyncLevel = 2;
1242
usb_idle(ResponseLatency - 3);
1243
task_in_progress = TRUE;
1244
SendData;
1245
task_in_progress = FALSE;
1246
end
1247
endtask
1248
 
1249
 
1250
 
1251
////////////////////////////////////////////////////////////////////////////////
1252
//
1253
//   reset : performs a reset on the USB bus by driving SE0 
1254
//
1255
//   input : Reset Time in bit times
1256
//
1257
////////////////////////////////////////////////////////////////////////////////
1258
task usb_reset;
1259
 
1260
input [7:0] tskResetTime;
1261
 
1262
begin
1263
task_in_progress = TRUE;
1264
NumResets = NumResets + 1;
1265
SendReset(tskResetTime);
1266
WriteResults;
1267
task_in_progress = FALSE;
1268
end
1269
endtask
1270
 
1271
 
1272
 
1273
//////////////////////////////////////////////////////////////////////////////////
1274
//  usb_idle : idles the USB.
1275
//  input    : IdleTime, which is the number of bit times for which to idle the
1276
//             bus.
1277
//
1278
////////////////////////////////////////////////////////////////////////////////
1279
task usb_idle;
1280
input [31:0] IdleTime;
1281
reg   [31:0] tskIdleTime;
1282
 
1283
begin : usb_idle
1284
task_in_progress = TRUE;
1285
tskIdleTime = 0;
1286
forever @(posedge clk) begin
1287
   if (tskIdleTime >= IdleTime) begin
1288
       task_in_progress = FALSE;
1289
       disable usb_idle;
1290
   end
1291
   tskIdleTime = tskIdleTime + 1;
1292
end
1293
task_in_progress = FALSE;
1294
end
1295
endtask
1296
 
1297
 
1298
///////////////////////////////////////////////////////////////////////////////
1299
//
1300
//  task usb_idle_nolock : same as usb_idle except that there is no lock
1301
//                         that is there is no assertion of the task_in_progress
1302
//                         flag
1303
//
1304
///////////////////////////////////////////////////////////////////////////////
1305
task usb_idle_nolock;
1306
input [31:0] IdleTime;
1307
reg   [31:0] tskIdleTime;
1308
begin : usb_idle_nolock
1309
tskIdleTime = 0;
1310
forever @(posedge clk) begin
1311
   if (tskIdleTime >= IdleTime) begin
1312
       task_in_progress = FALSE;
1313
       disable usb_idle_nolock;
1314
   end
1315
   tskIdleTime = tskIdleTime + 1;
1316
end
1317
end
1318
endtask
1319
 
1320
 
1321
////////////////////////////////////////////////////////////////////////////////
1322
//
1323
//  setup : issues a setup token with the corresponding data
1324
//  inputs  : address : address of the device, 7 bits
1325
//            EndPt   : end point number, 4 bits
1326
//  outputs : Status  : returns the status of the transaction, 4 bits
1327
//
1328
////////////////////////////////////////////////////////////////////////////////
1329
task setup;
1330
 
1331
input   [6:0]  address;
1332
input   [3:0]  EndPt;
1333
 
1334
output  [3:0]  Status; // 0 : ack received
1335
                       // 3 : no response
1336
                       // 4 : invalid response
1337
                       // 6 : another control transaction in progress
1338
                       // 8 : invalid control data
1339
reg     [3:0]  Status;
1340
reg     [15:0] tmpCrc;
1341
reg     [15:0] tmpReg;
1342
integer        i;
1343
integer        CntrlNum; // number of the control transaction
1344
reg     [31:0] recv_bit_count;
1345
reg            Match;
1346
reg     [31:0] tmpPulseWidth;
1347
 
1348
// eight bytes of setup data is assumed to be in Xmitbuffer
1349
begin : setup
1350
task_in_progress = TRUE;
1351
tmpPulseWidth = PulseWidth;
1352
Match = FALSE;
1353
for (i = 1; i <= MAX_CNTRL_INTERLEAVE; i = i + 1) begin
1354
   if ((address == CntrlTransAddr[i]) & (EndPt == CntrlTransEndP[i])) begin
1355
       Status = 4'b0110;
1356
       disable setup;
1357
   end
1358
end
1359
for (i = 1; i <= MAX_CNTRL_INTERLEAVE; i = i + 1) begin
1360
    if (CntrlTransType[i] == 2'b00) begin
1361
        Match = TRUE;
1362
        CntrlTransAddr[i] = address;
1363
        CntrlTransEndP[i] = EndPt;
1364
        CntrlTransDlen[i] = {XmitBuffer[7], XmitBuffer[6]};
1365
        CntrlNum = i;
1366
        i = MAX_CNTRL_INTERLEAVE + 1;
1367
    end
1368
end
1369
    if (Match == FALSE) begin
1370
        Status = 6; // only one control transaction in progress
1371
        clk_swtch = HIGH_SPEED;
1372
        task_in_progress = FALSE;
1373
        disable setup;
1374
    end
1375
 
1376
usb_idle(ResponseLatency - 3);  // #27
1377
if ((SendPreamble == TRUE) & (DeviceSpeed == HIGH_SPEED)) begin
1378
    send_preamble; // a high speed preamble is sent only when a high speed
1379
                   // hub is connected to the host model so in this case
1380
                   // switch clock speeds
1381
    task_in_progress = TRUE;
1382
    usb_idle(4);  // idle for 4 high speed clock times after a preamble
1383
    task_in_progress = TRUE;
1384
    // PulseWidth = PulseWidth * 8; // decrease the clock frequency
1385
    clk_swtch = LOW_SPEED;
1386
end
1387
 
1388
in_out_buf[0] = CorruptToken({~SETUP_TOKEN, SETUP_TOKEN});
1389
 
1390
tmpReg = FillCrc5({EndPt, address});
1391
in_out_buf[1] = tmpReg[7:0];
1392
in_out_buf[2] = tmpReg[15:8];
1393
in_out_buf_ptr = 3;
1394
SetSyncLevel = 0;
1395
// usb_idle(ResponseLatency - 3);  #27
1396
task_in_progress = TRUE;
1397
 
1398
SendData;
1399
 
1400
usb_idle(ResponseLatency - 3);  //  #27
1401
 
1402
send_high_speed_preamble;
1403
task_in_progress = TRUE;
1404
in_out_buf[0] = CorruptDataPid({~DATA0, DATA0});
1405
tmpCrc = 16'hffff;
1406
for (i = 1; i <= SetupDataLen; i = i + 1) begin
1407
    in_out_buf[i] = XmitBuffer[i - 1];
1408
    tmpCrc = crc16(in_out_buf[i], tmpCrc);
1409
end
1410
//if (Debug) $display("In %0s raw crc is %h at time %0t", SelfName, tmpCrc, $time);
1411
tmpCrc = CorruptCrc16(~{swap8(tmpCrc[15:8]), swap8(tmpCrc[7:0])});
1412
in_out_buf[9] = tmpCrc[15:8];
1413
in_out_buf[10] = tmpCrc[7:0];
1414
//if (Debug) $display("In %0s bus crc is %h at time %0t", SelfName, {in_out_buf[9], in_out_buf[10]}, $time);
1415
in_out_buf_ptr = SetupDataLen + 3;
1416
SetSyncLevel = 1;
1417
// usb_idle(ResponseLatency - 3);   #27
1418
task_in_progress = TRUE;
1419
SendData;
1420
tmpReg[7:0] = XmitBuffer[0];
1421
//if (Debug) $display("In %0s --> tmpReg = %b at time %0t", SelfName, tmpReg[7:0], $time);
1422
case(tmpReg[7])
1423
1'b1 : CntrlTransType[CntrlNum] = READ;
1424
1'b0 : CntrlTransType[CntrlNum] = WRITE;
1425
default : begin
1426
    Status = 8; // invalid control data
1427
    in_out_buf_ptr = 0;
1428
    clk_swtch = HIGH_SPEED;
1429
    task_in_progress = FALSE;
1430
    disable setup;
1431
end
1432
endcase
1433
 
1434
if (tmpReg[7] == 1'b1) NumCntrlRdTrans = NumCntrlRdTrans + 1;
1435
else NumCntrlWrTrans = NumCntrlWrTrans + 1;
1436
 
1437
if (Debug) $display("CntrlTransType = %b", CntrlTransType[CntrlNum]);
1438
 
1439
 
1440
WaitForResp(recv_bit_count);
1441
if (Debug) $display("In %0s --> in_out_buf[0] = %b, in_out_buf_ptr = %d", SelfName, in_out_buf[0], in_out_buf_ptr);
1442
case (in_out_buf_ptr)
1443
 
1444
    if (dec_bit_stuff_err == TRUE) begin
1445
        usb_idle(RespTimeOutVal);
1446
        task_in_progress = TRUE;
1447
    end
1448
    Status = 3;
1449
    CntrlTransType[CntrlNum] = 2'b00; // clear the transaction in progress flag
1450
    CntrlTransAddr[CntrlNum] = 7'b1111111;
1451
    CntrlTransEndP[CntrlNum] = 4'b1111;
1452
    CntrlTransDlen[CntrlNum] = 0;
1453
end
1454
1 : begin
1455
    if (in_out_buf[0] == {~ACK, ACK}) begin
1456
        Status = 0; //setup initiated successfully
1457
        SetDataToggle(address, EndPt, 2'b11);
1458
    end
1459
    else begin
1460
        Status = 4; // invalid response
1461
        CntrlTransType[CntrlNum] = 2'b00;
1462
                            // clear the transaction in progress flag
1463
        CntrlTransAddr[CntrlNum] = 7'b1111111;
1464
        CntrlTransEndP[CntrlNum] = 4'b1111;
1465
        CntrlTransDlen[CntrlNum] = 0;
1466
    end
1467
end
1468
default : begin
1469
    Status = 4; // invalid response
1470
    CntrlTransType[CntrlNum] = 2'b00;
1471
                             // clear the transaction in progress flag
1472
    CntrlTransAddr[CntrlNum] = 7'b1111111;
1473
    CntrlTransEndP[CntrlNum] = 4'b1111;
1474
    CntrlTransDlen[CntrlNum] = 0;
1475
end
1476
endcase
1477
WriteResults;
1478
clk_swtch = HIGH_SPEED;
1479
task_in_progress = FALSE;
1480
end
1481
endtask
1482
 
1483
 
1484
////////////////////////////////////////////////////////////////////////////////
1485
//
1486
//  control_IN : does the data phase in a control transaction initiated by
1487
//               a call to setup
1488
//  output     : ByteCount : number of bytes received during this control_in
1489
//  Status     : Exit Status of this task
1490
//
1491
////////////////////////////////////////////////////////////////////////////////
1492
 
1493
task control_IN;
1494
input   [6:0]     address;
1495
input   [3:0]     EndPt;
1496
output  [31:0]    ByteCount;
1497
output  [3:0]     Status;
1498
 
1499
reg     [3:0]     Status;
1500
reg     [31:0]    tskByteCount;
1501
reg     [31:0]    recv_bit_count;
1502
reg     [15:0]    tmpReg;
1503
reg     [15:0]    tmpCrc;
1504
integer           i;
1505
integer           CntrlNum;
1506
reg               tmpDataToggle;
1507
reg     [31:0]    tmpPulseWidth;
1508
 
1509
begin : control_IN
1510
task_in_progress = TRUE;
1511
ByteCount = 0;
1512
tmpPulseWidth = PulseWidth;
1513
CntrlNum = 0;
1514
for (i = 1; i <= MAX_CNTRL_INTERLEAVE; i = i + 1) begin
1515
    if ((CntrlTransType[i] != 2'b00) & (CntrlTransAddr[i] == address) & (CntrlTransEndP[i] == EndPt)) begin
1516
        CntrlNum = i;
1517
        i = MAX_CNTRL_INTERLEAVE + 1;
1518
    end
1519
end
1520
if (Debug) $display("CntrlTransType = %b", CntrlTransType[CntrlNum]);
1521
if (CntrlNum == 0) begin
1522
    DispErrMsg(0, 0, 21);
1523
    Status = 7;
1524
    clk_swtch = HIGH_SPEED;
1525
    task_in_progress = FALSE;
1526
    disable control_IN;
1527
end
1528
if (CntrlTransType[CntrlNum] == 2'b00) begin  // redundant ??
1529
    DispErrMsg(0, 0, 21);
1530
    Status = 7; // no setup transaction in progress to do a control_in xfer
1531
    clk_swtch = HIGH_SPEED;
1532
    task_in_progress = FALSE;
1533
    disable control_IN;
1534
end
1535
 
1536
if (CntrlTransType[CntrlNum] != READ) begin
1537
    DispErrMsg(0, 0, 22);
1538
    Status = 9; // wrong type of control transaction
1539
    clk_swtch = HIGH_SPEED;
1540
    task_in_progress = FALSE;
1541
    disable control_IN;
1542
end
1543
 
1544
 
1545
if ((SendPreamble == TRUE) & (DeviceSpeed == HIGH_SPEED)) begin
1546
    clk_swtch = LOW_SPEED;         // #27
1547
    usb_idle(ResponseLatency - 3); // #27
1548
    clk_swtch = HIGH_SPEED;        // #27
1549
    send_preamble; // a high speed preamble is sent only when a high speed
1550
                   // hub is connected to the host model so in this case
1551
                   // switch clock speeds
1552
    task_in_progress = TRUE;
1553
    usb_idle(4);  // idle for 4 high speed clock times after a preamble
1554
    task_in_progress = TRUE;
1555
    // PulseWidth = PulseWidth * 8;
1556
    clk_swtch = LOW_SPEED;
1557
end
1558
 
1559
in_out_buf[0] = CorruptToken({~IN_TOKEN, IN_TOKEN});
1560
in_out_buf_ptr = 1;
1561
 
1562
tmpReg[15:0] = FillCrc5({EndPt, address});
1563
 
1564
in_out_buf[1] = tmpReg[7:0];
1565
in_out_buf[2] = tmpReg[15:8];
1566
in_out_buf_ptr = 3;
1567
SetSyncLevel = 0;
1568
// usb_idle(ResponseLatency - 3); #27
1569
task_in_progress = TRUE;
1570
SendData;   //serialises, encodes and sends the data in in_out_buf,
1571
 
1572
WaitForResp(recv_bit_count);
1573
@(posedge dpll_clk); // 10/10/97
1574
case(in_out_buf_ptr)
1575
 
1576
    Status = 3;
1577
    if (Debug) $display("In %0s --> time out for control_in transaction at time %0t", SelfName, $time);
1578
end
1579
1 : begin
1580
    tmpReg[7:0] = in_out_buf[0]; //should contain the pid
1581
    if (tmpReg[7:4] != (~tmpReg[3:0])) begin
1582
        DispErrMsg(address, EndPt, 5);
1583
    end
1584
    if (tmpReg[3:0] == NAK) begin
1585
        DispErrMsg(address, EndPt, 11);
1586
        Status = 1; //NAK received from end point
1587
    end
1588
    if (tmpReg[3:0] == STALL) begin
1589
        DispErrMsg(address, EndPt, 12);
1590
        Status = 2; //STALL received from end point
1591
    end
1592
end
1593
2 : begin
1594
    DispErrMsg(address, EndPt, 6); // invalid number of data bytes received
1595
    Status = 4; //invalid response
1596
end
1597
default : begin
1598
    tmpReg[7:0] = in_out_buf[0]; //should contain the pid
1599
    if (tmpReg[7:4] != (~tmpReg[3:0])) begin
1600
        DispErrMsg(address, EndPt, 5);
1601
    end
1602
    if (Debug) $display("In %0s --> Data toggle recevied is %0b at time %0t", SelfName, tmpReg[7:0], $time);
1603
    ByteCount = 0;
1604
    tmpCrc = 16'hffff;
1605
    //if (Debug) $display("In %0s --> calculating crc for in_out_buf[%0d] = %0h", SelfName, i, in_out_buf[i]);
1606
    for (i = 1; i < (in_out_buf_ptr - 2); i = i + 1) begin
1607
        tmpCrc = crc16(in_out_buf[i], tmpCrc);
1608
        RecvBuffer[i - 1] = in_out_buf[i];
1609
        ByteCount = ByteCount + 1;
1610
        if (Debug) $display("In %0s --> received byte[%0d] = %b", SelfName, i, in_out_buf[i]);
1611
    end
1612
    if (Debug) $display("In %0s --> calculated crc is %0h at time %0t.", SelfName, tmpCrc, $time);
1613
    if (Debug) $display("In %0s --> received raw crc is %0h at time %0t.", SelfName, {swap8(~in_out_buf[in_out_buf_ptr - 2]), swap8(~in_out_buf[in_out_buf_ptr - 1])}, $time);
1614
    tmpCrc = CorruptCrc16(~{swap8(tmpCrc[15:8]), swap8(tmpCrc[7:0])});
1615
    if (Debug) $display("In %0s --> received crc is %0h at time %0t.", SelfName, {in_out_buf[in_out_buf_ptr - 2], in_out_buf[in_out_buf_ptr - 1]}, $time);
1616
 
1617
    //ByteCount = ByteCount + 1;
1618
    if (Debug) $display("In %0s --> tmpCrc %0h, at time %0t", SelfName, tmpCrc, $time);
1619
    if (tmpCrc != {in_out_buf[in_out_buf_ptr - 2], in_out_buf[in_out_buf_ptr - 1]}) begin
1620
        DispErrMsg(address, EndPt, 8); //CRC Error, send no response
1621
        Status = 5;
1622
        usb_idle(RespTimeOutVal);
1623
        task_in_progress = TRUE;
1624
    end
1625
    else begin
1626
        case (tmpReg[3:0]) //check the token
1627
        DATA0 : begin
1628
            if(CheckDataToggleIN(address, EndPt) != 0) begin
1629
                DispErrMsg(address, EndPt, 10);
1630
                ByteCount = 0; // discard data
1631
            end
1632
            SetDataToggle(address, EndPt, 2'b11);
1633
            //usb_idle(ResponseLatency - 3);   // #27
1634
            send_high_speed_preamble;
1635
            task_in_progress = TRUE;
1636
            SendAck;
1637
            task_in_progress = TRUE;
1638
            Status = 0;
1639
            if (Debug) $display("In %0s --> sending ACK at time %0t", SelfName, $time);
1640
        end
1641
        DATA1 : begin
1642
            if(CheckDataToggleIN(address, EndPt) != 1) begin
1643
                DispErrMsg(address, EndPt, 10);
1644
                ByteCount = 0; // discard data
1645
            end
1646
            SetDataToggle(address, EndPt, 2'b00);
1647
                //usb_idle(ResponseLatency - 3);
1648
                send_high_speed_preamble;
1649
                task_in_progress = TRUE;
1650
                SendAck;
1651
                task_in_progress = TRUE;
1652
                Status = 0;
1653
                if (Debug) $display("In %0s --> sending ACK at time %0t", SelfName, $time);
1654
        end
1655
        default : begin
1656
            Status = 4;
1657
            ByteCount = 0; // discard data
1658
            DispErrMsg(address, EndPt, 9); //incorrect token
1659
        end
1660
        endcase
1661
    end //if (tmpCrc ...
1662
end  // default :
1663
endcase
1664
 
1665
if (ByteCount > CntrlTransDlen[CntrlNum]) begin
1666
    CntrlTransDlen[CntrlNum] = 0;
1667
    DispErrMsg(address, EndPt, 20);
1668
end
1669
if (Status == 0) CntrlTransDlen[CntrlNum] = CntrlTransDlen[CntrlNum] - ByteCount;
1670
WriteResults;
1671
// PulseWidth = tmpPulseWidth;
1672
clk_swtch = HIGH_SPEED;
1673
task_in_progress = FALSE;
1674
end
1675
endtask
1676
 
1677
 
1678
 
1679
////////////////////////////////////////////////////////////////////////////////
1680
//
1681
// control_OUT : does the data phase in control transaction intiated by a setup
1682
// input       : ByteCount, number of bytes from XmitBuffer to send
1683
// Status      : exit status
1684
//
1685
////////////////////////////////////////////////////////////////////////////////
1686
task control_OUT;
1687
input   [6:0]     address;
1688
input   [3:0]     EndPt;
1689
input   [31:0]    ByteCount;
1690
output  [3:0]     Status;
1691
 
1692
reg     [3:0]     Status;
1693
reg     [31:0]    tskByteCount;
1694
reg     [31:0]    recv_bit_count;
1695
reg     [15:0]    tmpReg;
1696
reg     [15:0]    tmpCrc;
1697
integer           i;
1698
integer           CntrlNum;
1699
reg               tmpDataToggle;
1700
reg     [31:0]    tmpPulseWidth;
1701
 
1702
begin : control_OUT
1703
task_in_progress = TRUE;
1704
tmpPulseWidth = PulseWidth;
1705
CntrlNum = 0;
1706
for (i = 1; i <= MAX_CNTRL_INTERLEAVE; i = i + 1) begin
1707
    if ((CntrlTransType[i] != 2'b00) & (CntrlTransAddr[i] == address) & (CntrlTransEndP[i] == EndPt)) begin
1708
        CntrlNum = i;
1709
        i = MAX_CNTRL_INTERLEAVE + 1;
1710
    end
1711
end
1712
if (CntrlNum == 0) begin
1713
    DispErrMsg(0, 0, 21);
1714
    Status = 7;
1715
    clk_swtch = HIGH_SPEED;
1716
    task_in_progress = FALSE;
1717
    disable control_OUT;
1718
end
1719
 
1720
if (CntrlTransType[CntrlNum] == 2'b00) begin
1721
    DispErrMsg(0, 0, 21);
1722
    Status = 7; // no setup transaction in progress to do a control_in xfer
1723
    clk_swtch = HIGH_SPEED;
1724
    task_in_progress = FALSE;
1725
    disable control_OUT;
1726
end
1727
 
1728
if (CntrlTransType[CntrlNum] != WRITE) begin
1729
    DispErrMsg(0, 0, 22);
1730
    Status = 9; // wrong type of control transaction
1731
    clk_swtch = HIGH_SPEED;
1732
    task_in_progress = FALSE;
1733
    disable control_OUT;
1734
end
1735
 
1736
if (CntrlTransDlen[CntrlNum] == 0) begin
1737
    DispErrMsg(0, 0, 23);
1738
    Status = 10; // doing a control transaction when wLength is 0
1739
    clk_swtch = HIGH_SPEED;
1740
    task_in_progress = FALSE;
1741
    disable control_OUT;
1742
end
1743
// no setup transaction in progress so start a control_in transaction
1744
 
1745
usb_idle(ResponseLatency - 3);
1746
 
1747
if ((DeviceSpeed == HIGH_SPEED) & (SendPreamble == TRUE)) begin
1748
    clk_swtch = LOW_SPEED;           // #27
1749
    usb_idle(ResponseLatency - 3);   // #27
1750
    clk_swtch = HIGH_SPEED;          // #27
1751
    send_preamble; // a high speed preamble is sent only when a high speed
1752
                   // hub is connected to the host model so in this case
1753
                   // switch clock speeds
1754
    task_in_progress = TRUE;
1755
    // PulseWidth = PulseWidth * 8;
1756
    clk_swtch = LOW_SPEED;
1757
end
1758
 
1759
 
1760
tskByteCount = ByteCount;
1761
if (tskByteCount > CntrlTransDlen[CntrlNum]) begin
1762
    if (Debug) $display("In %0s --> more data is being requested than specified by wLength, ignoring the extra bytes at time %0t", SelfName, $time);
1763
    tskByteCount = CntrlTransDlen[CntrlNum];
1764
end
1765
// else CntrlTransDlen[CntrlNum] = CntrlTransDlen[CntrlNum] - tskByteCount;
1766
                                                        // decrement data count
1767
 
1768
in_out_buf[0] = CorruptToken({~OUT_TOKEN, OUT_TOKEN});
1769
in_out_buf_ptr = 1;
1770
 
1771
tmpReg[15:0] = FillCrc5({EndPt, address});
1772
 
1773
in_out_buf[1] = tmpReg[7:0];
1774
in_out_buf[2] = tmpReg[15:8];
1775
in_out_buf_ptr = 3;
1776
if (Debug) $display("In  host --> address = %h, EndPt = %h, crc5 = %h, tmpReg = %h", address, EndPt, tmpReg[15:11], tmpReg);
1777
 
1778
SetSyncLevel = 0;
1779
task_in_progress = TRUE;
1780
SendData;     //serialises, encodes and sends the data in in_out_buf
1781
 
1782
task_in_progress = TRUE;
1783
tmpDataToggle = CheckDataToggleIN(address, EndPt);
1784
if (Debug) $display("In %0s --> DataToggle is %0h", SelfName, tmpDataToggle);
1785
 
1786
case (tmpDataToggle)
1787
 
1788
1 : in_out_buf[0] = CorruptDataPid({~DATA1, DATA1});
1789
default : in_out_buf[0] = CorruptDataPid({~DATA0, DATA0});
1790
endcase
1791
in_out_buf_ptr = 1;
1792
if (Debug) $display("In %0s --> DataToggle is %0h at time %0t.", SelfName, in_out_buf[0], $time);
1793
 
1794
tmpCrc = 16'hffff;
1795
for (i = 1; i <= ByteCount; i = i + 1) begin
1796
    in_out_buf[i] = XmitBuffer[i - 1];
1797
    tmpCrc = crc16(in_out_buf[i], tmpCrc);
1798
    in_out_buf_ptr = in_out_buf_ptr + 1;
1799
    if (Debug) $display("In %0s --> sending byte[%0d] = %b", SelfName, i, in_out_buf[i]);
1800
end
1801
if (Debug) $display("In %0s --> raw crc is %0h at time", SelfName, tmpCrc, $time);
1802
tmpCrc = CorruptCrc16(~{swap8(tmpCrc[15:8]), swap8(tmpCrc[7:0])});
1803
if (Debug) $display("In %0s --> sent crc is %0h at time", SelfName, tmpCrc, $time);
1804
in_out_buf[ByteCount + 2] = tmpCrc[7:0];
1805
in_out_buf[ByteCount + 1] = tmpCrc[15:8];
1806
in_out_buf_ptr = in_out_buf_ptr + 2;
1807
SetSyncLevel = 1;
1808
usb_idle(ResponseLatency - 3);
1809
task_in_progress = TRUE;
1810
send_high_speed_preamble;
1811
task_in_progress = TRUE;
1812
SendData; //send the contents of in_out_buf
1813
 
1814
WaitForResp(recv_bit_count);  //wait for a response for this transfer
1815
if (Debug) $display("In %0s --> bits received are %0h", SelfName, recv_bit_count);
1816
 
1817
case (in_out_buf_ptr)
1818
 
1819
    if (dec_bit_stuff_err == TRUE) begin
1820
        usb_idle(RespTimeOutVal);
1821
        task_in_progress = TRUE;
1822
    end
1823
    Status = 3;
1824
    DispErrMsg(address, EndPt, 4);
1825
end
1826
1 : begin
1827
    tmpReg[7:0] = in_out_buf[0];
1828
    case (tmpReg[3:0])
1829
    ACK   : begin
1830
        case (tmpDataToggle)   //change the data toggle
1831
 
1832
        1 : SetDataToggle(address, EndPt, 2'b00);
1833
        default : SetDataToggle(address, EndPt, 0);
1834
        endcase
1835
        Status = 0;
1836
        if (Debug) $display("In %0s --> ACK received at time %0t.", SelfName, $time);
1837
    end
1838
    NAK   : begin
1839
        DispErrMsg(address, EndPt, 11);
1840
        Status = 1; // nak received
1841
    end
1842
    STALL : begin
1843
        DispErrMsg(address, EndPt, 12);
1844
        Status = 2; // stall received
1845
    end
1846
    default : begin
1847
        DispErrMsg(address, EndPt, 13);
1848
        Status = 4; // invalid response
1849
    end
1850
    endcase
1851
end
1852
default : DispErrMsg(address, EndPt, 14);
1853
endcase
1854
if (Status == 0) CntrlTransDlen[CntrlNum] = CntrlTransDlen[CntrlNum] - tskByteCount;
1855
WriteResults;
1856
// PulseWidth = tmpPulseWidth;
1857
clk_swtch = HIGH_SPEED;
1858
task_in_progress = FALSE;
1859
end
1860
endtask   //control_out
1861
 
1862
 
1863
 
1864
////////////////////////////////////////////////////////////////////////////////
1865
//
1866
//  status_in : does the status phase in a control transaction
1867
//  output    : Status : exit status of the transaction
1868
//
1869
////////////////////////////////////////////////////////////////////////////////
1870
task status_IN;
1871
input   [6:0]     address;
1872
input   [3:0]     EndPt;
1873
output            Status;
1874
reg     [3:0]     Status;
1875
reg     [31:0]    recv_bit_count;
1876
reg     [15:0]    tmpReg;
1877
integer           i;
1878
reg               tmpDataToggle;
1879
integer           CntrlNum;
1880
reg     [31:0]    tmpPulseWidth;
1881
 
1882
begin : status_IN
1883
task_in_progress = TRUE;
1884
tmpPulseWidth = PulseWidth;
1885
CntrlNum = 0;
1886
$display("Input Address:%x, EndPt:%x",address,EndPt);
1887
for (i = 1; i <= MAX_CNTRL_INTERLEAVE; i = i + 1) begin
1888
    $display("i :%d, CntrlTransType:%x; CntrlTransAddr:%x;CntrlTransEndP:%x ",
1889
            i,CntrlTransType[i],CntrlTransAddr[i],CntrlTransEndP[i]);
1890
    if ((CntrlTransType[i] != 2'b00) & (CntrlTransAddr[i] == address) & (CntrlTransEndP[i] == EndPt)) begin
1891
        CntrlNum = i;
1892
        i = MAX_CNTRL_INTERLEAVE + 1;
1893
    end
1894
end
1895
if (CntrlNum == 0) begin
1896
    DispErrMsg(0, 0, 21);
1897
    Status = 7;
1898
    clk_swtch = HIGH_SPEED;
1899
    task_in_progress = FALSE;
1900
    disable status_IN;
1901
end
1902
if (CntrlTransType[CntrlNum] == 2'b00) begin
1903
    DispErrMsg(0, 0, 24);
1904
    Status = 7; // no setup transaction in progress to do a control_in xfer
1905
    clk_swtch = HIGH_SPEED;
1906
    task_in_progress = FALSE;
1907
    disable status_IN;
1908
end
1909
if (Debug) $display("In %0s CntrlTransType = %b, WRITE = %b", SelfName, CntrlTransType[CntrlNum], WRITE);
1910
if (CntrlTransType[CntrlNum] != WRITE) begin
1911
    DispErrMsg(0, 0, 22);
1912
    Status = 9; // wrong type of control transaction
1913
    clk_swtch = HIGH_SPEED;
1914
    task_in_progress = FALSE;
1915
    disable status_IN;
1916
end
1917
 
1918
usb_idle(ResponseLatency - 3);
1919
task_in_progress = TRUE;
1920
if ((DeviceSpeed == HIGH_SPEED) & (SendPreamble == TRUE)) begin
1921
    clk_swtch = LOW_SPEED;           // #27
1922
    usb_idle(ResponseLatency - 3);   // #27
1923
    clk_swtch = HIGH_SPEED;          // #27
1924
    send_preamble; // a high speed preamble is sent only when a high speed
1925
                   // hub is connected to the host model so in this case
1926
                   // switch clock speeds
1927
    task_in_progress = TRUE;
1928
    // PulseWidth = PulseWidth * 8;
1929
    clk_swtch = LOW_SPEED;
1930
end
1931
in_out_buf[0] = CorruptToken({~IN_TOKEN, IN_TOKEN});
1932
in_out_buf_ptr = 1;
1933
 
1934
tmpReg[15:0] = FillCrc5({EndPt, address});
1935
 
1936
in_out_buf[1] = tmpReg[7:0];
1937
in_out_buf[2] = tmpReg[15:8];
1938
in_out_buf_ptr = 3;
1939
SetSyncLevel = 0;
1940
SendData;   //serialises, encodes and sends the data in in_out_buf,
1941
 
1942
WaitForResp(recv_bit_count);
1943
case (in_out_buf_ptr)
1944
 
1945
    if (dec_bit_stuff_err == TRUE) begin
1946
        usb_idle(RespTimeOutVal);
1947
        task_in_progress = TRUE;
1948
    end
1949
    Status = 3;
1950
end
1951
1 : begin
1952
    tmpReg[7:0] = in_out_buf[0]; //should contain the pid
1953
    if (tmpReg[7:4] != (~tmpReg[3:0])) begin
1954
        DispErrMsg(address, EndPt, 5);
1955
    end
1956
    if (tmpReg[3:0] == NAK) begin
1957
        DispErrMsg(address, EndPt, 11);
1958
        Status = 1; //NAK received from end point
1959
    end
1960
    else if (tmpReg[3:0] == STALL) begin
1961
        DispErrMsg(address, EndPt, 12);
1962
        Status = 2; //STALL received from end point
1963
    end
1964
    else begin
1965
        Status = 4; // invalid response
1966
    end
1967
end
1968
    3 : begin
1969
        tmpReg[7:0] = in_out_buf[0]; //should contain the pid
1970
        if (tmpReg[7:4] != (~tmpReg[3:0])) begin
1971
            DispErrMsg(address, EndPt, 5);
1972
        end
1973
        if ({in_out_buf[1], in_out_buf[2]} != 16'h0000) begin
1974
            DispErrMsg(address, EndPt, 8);
1975
            usb_idle(RespTimeOutVal);
1976
            task_in_progress = TRUE;
1977
            Status = 5;
1978
        end
1979
        else begin
1980
            if (tmpReg[3:0] == DATA1) begin
1981
                NumSucCntrlWrTrans = NumSucCntrlWrTrans + 1;
1982
                //usb_idle(ResponseLatency - 3);   // #27
1983
                send_high_speed_preamble;
1984
                task_in_progress = TRUE;
1985
                SendAck;
1986
                task_in_progress = TRUE;
1987
                Status = 0;
1988
            end
1989
            else begin
1990
                DispErrMsg(address, EndPt, 25);
1991
                usb_idle(RespTimeOutVal);
1992
                task_in_progress = TRUE;
1993
            end
1994
        end
1995
    end
1996
    default : begin
1997
        Status = 4; // invalid response
1998
    end
1999
endcase
2000
 
2001
//reset control transaction flags
2002
if (Status != 1) begin
2003
    CntrlTransEndP[CntrlNum] = 4'b1111;
2004
    CntrlTransAddr[CntrlNum] = 7'b1111111;
2005
    CntrlTransDlen[CntrlNum] = 0;
2006
    CntrlTransType[CntrlNum] = 0;
2007
end
2008
WriteResults;
2009
// PulseWidth = tmpPulseWidth;
2010
clk_swtch = HIGH_SPEED;
2011
task_in_progress = FALSE;
2012
end
2013
endtask
2014
 
2015
 
2016
////////////////////////////////////////////////////////////////////////////////
2017
//
2018
//  status_out : does the status phase of a control transaction
2019
//  output     : Status : Exit Status
2020
//
2021
////////////////////////////////////////////////////////////////////////////////
2022
task status_OUT;
2023
input   [6:0]     address;
2024
input   [3:0]     EndPt;
2025
output            Status;
2026
reg     [3:0]     Status;
2027
reg     [31:0]    recv_bit_count;
2028
reg     [15:0]    tmpReg;
2029
integer           i;
2030
reg               tmpDataToggle;
2031
integer           CntrlNum;
2032
reg     [31:0]    tmpPulseWidth;
2033
 
2034
begin : status_OUT
2035
task_in_progress = TRUE;
2036
tmpPulseWidth = PulseWidth;
2037
CntrlNum = 0;
2038
for (i = 1; i <= MAX_CNTRL_INTERLEAVE; i = i + 1) begin
2039
    if ((CntrlTransType[i] != 2'b00) & (CntrlTransAddr[i] == address) & (CntrlTransEndP[i] == EndPt)) begin
2040
        CntrlNum = i;
2041
        i = MAX_CNTRL_INTERLEAVE + 1;
2042
    end
2043
end
2044
if (CntrlNum == 0) begin
2045
    DispErrMsg(0, 0, 21);
2046
    Status = 7;
2047
    clk_swtch = HIGH_SPEED;
2048
    task_in_progress = FALSE;
2049
    disable status_OUT;
2050
end
2051
if (CntrlTransType [CntrlNum]== 2'b00) begin
2052
    DispErrMsg(0, 0, 24);
2053
    Status = 7; // no setup transaction in progress to do a control_in xfer
2054
    clk_swtch = HIGH_SPEED;
2055
    task_in_progress = FALSE;
2056
    disable status_OUT;
2057
end
2058
 
2059
if (CntrlTransType[CntrlNum] != READ) begin
2060
    DispErrMsg(0, 0, 22);
2061
    Status = 9; // wrong type of control transaction
2062
    clk_swtch = HIGH_SPEED;
2063
    task_in_progress = FALSE;
2064
    disable status_OUT;
2065
end
2066
 
2067
usb_idle(ResponseLatency - 3);
2068
task_in_progress = TRUE;
2069
if ((DeviceSpeed == HIGH_SPEED) & (SendPreamble == TRUE)) begin
2070
    clk_swtch = LOW_SPEED;           // #27
2071
    usb_idle(ResponseLatency - 3);   // #27
2072
    clk_swtch = HIGH_SPEED;          // #27
2073
    send_preamble; // a high speed preamble is sent only when a high speed
2074
                   // hub is connected to the host model so in this case
2075
                   // switch clock speeds
2076
    task_in_progress = TRUE;
2077
    usb_idle(4);  // idle for 4 high speed clock times after a preamble
2078
    task_in_progress = TRUE;
2079
    // PulseWidth = PulseWidth * 8;
2080
    clk_swtch = LOW_SPEED;
2081
end
2082
in_out_buf[0] = CorruptToken({~OUT_TOKEN, OUT_TOKEN});
2083
in_out_buf_ptr = 1;
2084
 
2085
tmpReg[15:0] = FillCrc5({EndPt, address});
2086
 
2087
in_out_buf[1] = tmpReg[7:0];
2088
in_out_buf[2] = tmpReg[15:8];
2089
in_out_buf_ptr = 3;
2090
SetSyncLevel = 0;
2091
SendData;
2092
 
2093
usb_idle(ResponseLatency - 3);
2094
task_in_progress = TRUE;
2095
send_high_speed_preamble;
2096
task_in_progress = TRUE;
2097
in_out_buf[0] = CorruptDataPid({~DATA1, DATA1});
2098
in_out_buf[1] = 0;
2099
in_out_buf[2] = 0;
2100
in_out_buf_ptr = 3;
2101
SetSyncLevel = 1;
2102
SendData;
2103
 
2104
WaitForResp(recv_bit_count);
2105
 
2106
case (in_out_buf_ptr)
2107
 
2108
    if (dec_bit_stuff_err == TRUE) begin
2109
        usb_idle(RespTimeOutVal);
2110
        task_in_progress = TRUE;
2111
    end
2112
    Status = 3; // time out
2113
end
2114
1 : begin
2115
    tmpReg[7:0] = in_out_buf[0]; //should contain the pid
2116
    if (tmpReg[7:4] != (~tmpReg[3:0])) begin
2117
        DispErrMsg(address, EndPt, 5);
2118
    end
2119
    if (tmpReg[3:0] == NAK) begin
2120
        DispErrMsg(address, EndPt, 11);
2121
        Status = 1; //NAK received from end point
2122
    end
2123
    else if (tmpReg[3:0] == STALL) begin
2124
        DispErrMsg(address, EndPt, 12);
2125
        Status = 2; //STALL received from end point
2126
    end
2127
    else if (tmpReg[3:0] == ACK) begin
2128
        NumSucCntrlRdTrans = NumSucCntrlRdTrans + 1;
2129
        Status = 0;
2130
    end
2131
    else begin
2132
        Status = 4; // invalid response
2133
    end
2134
end
2135
    default : begin
2136
        Status = 4; // invalid response
2137
    end
2138
endcase
2139
 
2140
//reset control transaction flags
2141
if (Status != 1) begin
2142
    CntrlTransEndP[CntrlNum] = 0;
2143
    CntrlTransAddr[CntrlNum] = 7'b1111111;
2144
    CntrlTransDlen[CntrlNum] = 4'b1111;
2145
    CntrlTransType[CntrlNum] = 0;
2146
end
2147
// PulseWidth = tmpPulseWidth;
2148
clk_swtch = HIGH_SPEED;
2149
WriteResults;
2150
task_in_progress = FALSE;
2151
end
2152
endtask
2153
 
2154
 
2155
////////////////////////////////////////////////////////////////////////////////
2156
//
2157
//  usb_resume : drives a K state on the bus for ResumeTime number of bit times
2158
//
2159
////////////////////////////////////////////////////////////////////////////////
2160
task usb_resume;
2161
input [31:0] ResumeTime;
2162
reg   [31:0] tskResumeTime;
2163
 
2164
begin : usb_resume
2165
task_in_progress = TRUE;
2166
tskResumeTime = 0;
2167
forever @(posedge clk) begin
2168
   if (tskResumeTime >= ResumeTime) begin
2169
       zDPLS = 1'b0;
2170
       zDMNS = 1'b0;
2171
       if (DeviceSpeed == HIGH_SPEED) begin // wait for two low speed bit times
2172
           #667;
2173
           #667;
2174
       end
2175
       else begin
2176
           @(posedge clk);
2177
           @(posedge clk);
2178
       end
2179
       zDPLS = 1'bZ;
2180
       zDMNS = 1'bZ;
2181
       task_in_progress = FALSE;
2182
       disable usb_resume;
2183
   end
2184
   if (DeviceSpeed == HIGH_SPEED) begin
2185
       zDPLS = 1'b0;
2186
       zDMNS = 1'b1;
2187
   end
2188
   else begin
2189
       zDPLS = 1'b1;
2190
       zDMNS = 1'b0;
2191
   end
2192
   tskResumeTime = tskResumeTime + 1;
2193
end
2194
task_in_progress = FALSE;
2195
end
2196
endtask
2197
 
2198
 
2199
 
2200
////////////////////////////////////////////////////////////////////////////////
2201
//
2202
//  send_preamble : sends a Preamble token and idles the bus for the required
2203
//                 4 bit times which is the hub setup time for low speed devices
2204
//
2205
////////////////////////////////////////////////////////////////////////////////
2206
task send_preamble;
2207
 
2208
reg         tskGenSE0Error;
2209
reg [31:0]  tskSE0BitTimes;
2210
reg [31:0]  tskSE0ErrorLevel;
2211
 
2212
begin
2213
task_in_progress = TRUE;
2214
// SE0 should not be generated after sending a preamble 10/03/1996
2215
// modify SE0 error generation logic
2216
tskGenSE0Error = GenSE0Error;
2217
tskSE0BitTimes = SE0BitTimes;
2218
tskSE0ErrorLevel = SE0ErrorLevel;
2219
 
2220
GenSE0Error = TRUE;
2221
SE0BitTimes = 0;
2222
SE0ErrorLevel = SetSyncLevel;
2223
 
2224
in_out_buf[0] = {~PREAMBLE, PREAMBLE};
2225
in_out_buf_ptr = 1;
2226
SendData;
2227
 
2228
// restore SE0 error generation logic 10/03/1996
2229
GenSE0Error = tskGenSE0Error;
2230
SE0BitTimes = tskSE0BitTimes;
2231
SE0ErrorLevel = tskSE0ErrorLevel;
2232
 
2233
usb_idle(4);  // hub setup time
2234
task_in_progress = FALSE;
2235
end
2236
endtask
2237
 
2238
 
2239
////////////////////////////////////////////////////////////////////////////////
2240
//
2241
//  transfer_buf : transfers whatever data from the xmit buffer with a sync
2242
//                 field in the front
2243
//  input : ByteCount : number of bytes to be transferred from buffer, 32 bits
2244
//          FromFile  : TRUE/FALSE, if TRUE data is taken from host_usb_recv.dat
2245
//
2246
////////////////////////////////////////////////////////////////////////////////
2247
task transfer_buf;
2248
 
2249
input [31:0]   ByteCount;
2250
input          FromFile;
2251
input [160:1]  FileName;
2252
reg   [3:0]    Status;
2253
integer        i;
2254
 
2255
begin : transfer_buf
2256
task_in_progress = TRUE;
2257
    for (i = 0; i < ByteCount; i = i + 1) begin
2258
        in_out_buf[i] = XmitBuffer[i];    // addition 5/29/1996
2259
    end
2260
in_out_buf_ptr = ByteCount;
2261
SendData;
2262
task_in_progress = FALSE;
2263
end
2264
endtask
2265
 
2266
 
2267
////////////////////////////////////////////////////////////////////////////////
2268
//
2269
//  receive_buf : receives the data from the bus and puts in RecvBuf
2270
//  input  : DumpToFile : if true data is dumped to a file
2271
//  output : ByteCount : number of bytes received
2272
//
2273
////////////////////////////////////////////////////////////////////////////////
2274
task receive_buf;
2275
 
2276
input          DumpToFile;
2277
output [31:0]  ByteCount;
2278
reg    [31:0]  recv_bit_count;
2279
integer        i;
2280
 
2281
begin
2282
task_in_progress = TRUE;
2283
WaitForResp(recv_bit_count);
2284
for (i = 0; i < in_out_buf_ptr; i = i + 1) begin
2285
    RecvBuffer[i] = in_out_buf[i];
2286
end
2287
ByteCount = in_out_buf_ptr;
2288
if (DumpToFile == TRUE && ByteCount > 0) DumpData(7'b1111111, 4'b1111, DATA0, ByteCount-1);
2289
task_in_progress = FALSE;
2290
end
2291
 
2292
endtask
2293
 
2294
 
2295
///////////////////////////////////////////////////////////////////////////////
2296
//
2297
//  task send_high_speed_preamble : sends a preamble by switching clock
2298
//                                  during a low speed transaction
2299
//
2300
////////////////////////////////////////////////////////////////////////////////
2301
task send_high_speed_preamble;
2302
begin
2303
task_in_progress = TRUE;
2304
if ((SendPreamble == TRUE) & (DeviceSpeed == HIGH_SPEED)) begin
2305
     // PulseWidth = PulseWidth / 8;
2306
     clk_swtch = HIGH_SPEED;
2307
     send_preamble;
2308
     task_in_progress = TRUE;
2309
         // a high speed preamble is sent only when a high speed
2310
         // hub is connected to the host model so in this case
2311
         // switch clock speeds
2312
     usb_idle(4);
2313
     task_in_progress = TRUE;
2314
         // idle for 4 high speed clock times after a preamble
2315
     // PulseWidth = PulseWidth * 8;
2316
     clk_swtch = LOW_SPEED;
2317
end
2318
task_in_progress = FALSE;
2319
end
2320
endtask
2321
 
2322
 
2323
 
2324
initial begin // initilaise the input and output buffers
2325
    for(tmpCounter = 0; tmpCounter <= 2048; tmpCounter = tmpCounter + 1) begin
2326
        XmitBuffer[tmpCounter] = 8'b00000000;
2327
    end
2328
    for(tmpCounter = 0; tmpCounter <= RECV_BUF_SIZE; tmpCounter = tmpCounter + 1) begin
2329
        RecvBuffer[tmpCounter] = 8'b00000000;
2330
    end
2331
    for (tmpCounter = 0; tmpCounter < IN_OUT_BUF_SIZE; tmpCounter = tmpCounter + 1) begin
2332
        in_out_buf[tmpCounter] = 0;
2333
    end
2334
    //for (tmpCounter = 0; tmpCounter < OUT_BUF_SIZE; tmpCounter = tmpCounter + 1) begin
2335
        //out_buf[tmpCounter] = 0;
2336
    //end
2337
    for (tmpCounter = 0; tmpCounter < 128; tmpCounter = tmpCounter + 1)
2338
    begin
2339
        InDataToggle[tmpCounter]  = 16'h0000;
2340
        OutDataToggle[tmpCounter] = 16'h0000;
2341
    end
2342
 
2343
    TimeOut        = TRUE;
2344
    TimeOutVal     = 16;     // timeout after 16 bit times
2345
    RespTimeOutVal = 16;
2346
 
2347
    ResponseLatency = 3;
2348
 
2349
    GenCrc16Err    = FALSE;
2350
    Crc16ErrMask   = 16'hffff;
2351
 
2352
    GenCrc5Err     = FALSE;
2353
    Crc5ErrMask    = 5'b00000;
2354
 
2355
    ReportResults  = TRUE; // default : turned on
2356
    ResultsFile    = "host_usb_res.log"; // default file name
2357
    ResultsFp      = 0; // initially log file pointer is 0
2358
 
2359
    PulseWidth     = 42;
2360
 
2361
    SyncField      = FALSE; // default : sync field corruption is turned off
2362
    SyncFieldMask  = 8'hf0; // default no sync field corruption specified
2363
    SyncLevel      = 0;
2364
    SetSyncLevel   = 0;
2365
 
2366
    GenSE0Error    = FALSE;
2367
    SE0BitTimes    = 2;     // default conforms to the spec
2368
    SE0ErrorLevel  = 0;
2369
 
2370
    HshkPidIntegrity = FALSE; // no corruption
2371
    HshkPidIntegrityMask = 8'hf0; // corruption mask for ACK's
2372
 
2373
    BitStuffErr = FALSE; // changed TRUE to FALSE 02/18/97
2374
 
2375
    for (tmpCounter = 1; tmpCounter <= MAX_CNTRL_INTERLEAVE; tmpCounter = tmpCounter + 1) begin
2376
        CntrlTransType[tmpCounter] = 2'b00;
2377
                                   // no control transaction in progress
2378
        CntrlTransAddr[tmpCounter] = 7'b1111111;
2379
                                   // address of a control transaction
2380
        CntrlTransEndP[tmpCounter] = 4'b1111;
2381
                                   // endpoint number of a control transaction
2382
        CntrlTransDlen[tmpCounter] = 16'h0000;
2383
                                   // data length for this control transaction
2384
    end
2385
 
2386
    SendDataFileName = "host_usb_xmit.dat";
2387
    RecvDataFileName = "host_usb_recv.dat";
2388
    RecvDataFp = 0;
2389
    ReportErrors = TRUE;
2390
    ErrorFileName = "host_usb_err.log";
2391
    ErrorFileFp = 0;
2392
 
2393
    for ( tmpCounter = 1; tmpCounter <= NUM_ENDPT_FILES; tmpCounter = tmpCounter + 1) begin
2394
        EndPtFileName[tmpCounter] = "";
2395
        EndPtFileMode[tmpCounter] = 2'b00; // no mode is assigned to it
2396
        EndPtFileInfo[tmpCounter] = 11'b00000000000;
2397
        EndPtFp[tmpCounter] = 0;
2398
        EndPtFileOfst[tmpCounter] = 0;
2399
    end
2400
 
2401
    SendDataOfst = 0;
2402
 
2403
    Debug = FALSE;
2404
 
2405
    GenDataPidErr = FALSE;
2406
    DataPidErrMask = 8'hff;
2407
    GenTokenErr = FALSE;
2408
    TokenErrMask = 8'hff;
2409
 
2410
    //DeviceSpeed = LOW_SPEED;
2411
    DeviceSpeed = HIGH_SPEED;
2412
    GenByteBoundary = FALSE;
2413
 
2414
    SendPreamble = FALSE;   // assumes a low speed device is connected to the
2415
                            // host
2416
 
2417
    FrameNumber = 0;
2418
 
2419
    NumBulkInTrans = 0;       // number of bulk in transactions
2420
    NumSucBulkInTrans = 0;    // number of successful bulk in transctions
2421
    NumBulkOutTrans = 0;      // number of bulk out transactions
2422
    NumSucBulkOutTrans = 0;   // number of successful bulk out transactions
2423
    NumIsoInTrans = 0;        // number of iso in transactions
2424
    NumSucIsoInTrans = 0;     // number of successful iso in transactions
2425
    NumIsoOutTrans = 0;       // number of iso out transactions
2426
    NumSOF = 0;               // number of SOF's sent
2427
    NumCntrlRdTrans = 0;      // number of control reads
2428
    NumSucCntrlRdTrans = 0;   // number of successful control reads
2429
    NumCntrlWrTrans = 0;      // number of control writes
2430
    NumSucCntrlWrTrans = 0;   // number of successful control writes
2431
    NumIntrptTrans = 0;       // number of interrupts
2432
    NumSucIntrptTrans = 0;    // number of successful interrupts
2433
    NumIntrOutTrans = 0;      // number of interrupt out transactions
2434
    NumSucIntrOutTrans = 0;   // number of successful interrupt out transactions
2435
    NumResets = 0;            // number of resets
2436
 
2437
    // intialize Jitter registers
2438
    HighJitterTime   = 0;
2439
    LowJitterTime    = 0;
2440
    JitterPeriod     = 0;
2441
    JitterCount      = 0;
2442
    JitterOnOff      = FALSE;  // Jitter generation is off by default;
2443
 
2444
    task_in_progress = FALSE;
2445
 
2446
    clk_swtch = HIGH_SPEED;
2447
 
2448
    SetupDataLen = 8;
2449
 
2450
    GenByteBoundaryPos = FALSE;
2451
    BoundaryBitVal = 1'b0;
2452
 
2453
    ModifyGran = 0;
2454
 
2455
end
2456
 
2457
 
2458
assign clk = (clk_swtch == LOW_SPEED) ? ls_clk : hs_clk;
2459
assign clk4x = (clk_swtch == LOW_SPEED) ? clk6 : clk48;
2460
 
2461
 
2462
 
2463
 
2464
///////////////////////////////////////////////////////////////////////////////
2465
//
2466
//   task in_token : sends an in token on to the bus.
2467
//   inputs : address : 7 bits : endpoint address
2468
//            EndPt   : 4 bits : endpoint number
2469
//
2470
///////////////////////////////////////////////////////////////////////////////
2471
task in_token;
2472
input     [6:0]    address;
2473
input     [3:0]    EndPt;
2474
reg       [15:0]   tmpReg;
2475
begin
2476
    in_out_buf[0]  = CorruptToken({~IN_TOKEN, IN_TOKEN});
2477
    tmpReg[15:0]   = FillCrc5({EndPt, address});
2478
    in_out_buf[1]  = tmpReg[7:0];
2479
    in_out_buf[2]  = tmpReg[15:8];
2480
    in_out_buf_ptr = 3;
2481
    SendData;
2482
end
2483
endtask
2484
 
2485
 
2486
///////////////////////////////////////////////////////////////////////////////
2487
//
2488
//    task out_token : sends an out token on to the bus.
2489
//    inputs : address : 7 bits : endpoint address
2490
//             EndPt   : 4 bits : endpoint number
2491
//
2492
///////////////////////////////////////////////////////////////////////////////
2493
task out_token;
2494
input     [6:0]    address;
2495
input     [3:0]    EndPt;
2496
reg       [15:0]   tmpReg;
2497
begin
2498
    in_out_buf[0]  = CorruptToken({~OUT_TOKEN, OUT_TOKEN});
2499
    tmpReg[15:0]   = FillCrc5({EndPt, address});
2500
    in_out_buf[1]  = tmpReg[7:0];
2501
    in_out_buf[2]  = tmpReg[15:8];
2502
    in_out_buf_ptr = 3;
2503
    SendData;
2504
end
2505
endtask
2506
 
2507
 
2508
///////////////////////////////////////////////////////////////////////////////
2509
//
2510
//     task setup_token : sends an setup token on to the bus
2511
//     inputs : address : 7 bits : endpoint address
2512
//              EndPt   : 4 bits : endpoint number
2513
//
2514
///////////////////////////////////////////////////////////////////////////////
2515
task setup_token;
2516
input     [6:0]    address;
2517
input     [3:0]    EndPt;
2518
reg       [15:0]   tmpReg;
2519
begin
2520
    in_out_buf[0]  = CorruptToken({~SETUP_TOKEN, SETUP_TOKEN});
2521
    tmpReg[15:0]   = FillCrc5({EndPt, address});
2522
    in_out_buf[1]  = tmpReg[7:0];
2523
    in_out_buf[2]  = tmpReg[15:8];
2524
    in_out_buf_ptr = 3;
2525
    SendData;
2526
end
2527
endtask
2528
 
2529
 
2530
 
2531
///////////////////////////////////////////////////////////////////////////////
2532
//
2533
//     task send_ack : sends an ACK on to the bus
2534
//
2535
///////////////////////////////////////////////////////////////////////////////
2536
task send_ack;
2537
begin
2538
    in_out_buf[0] = CorruptHshk({~ACK, ACK});
2539
    in_out_buf_ptr = 1;
2540
    SendData;
2541
end
2542
endtask
2543
 
2544
 
2545
///////////////////////////////////////////////////////////////////////////////
2546
//
2547
//     task send_nak : sends a NAK on the bus (though an host is not supposed
2548
//                     to send a NAK)
2549
//
2550
///////////////////////////////////////////////////////////////////////////////
2551
task send_nak;
2552
begin
2553
    in_out_buf[0] = CorruptHshk({~NAK, NAK});
2554
    in_out_buf_ptr = 1;
2555
    SendData;
2556
end
2557
endtask
2558
 
2559
 
2560
///////////////////////////////////////////////////////////////////////////////
2561
//
2562
//     task send_stall : sends a STALL on to the bus (though an host is not
2563
//                       supposed to send a STALL)
2564
//
2565
///////////////////////////////////////////////////////////////////////////////
2566
task send_stall;
2567
begin
2568
    in_out_buf[0] = CorruptHshk({~STALL, STALL});
2569
    in_out_buf_ptr = 1;
2570
    SendData;
2571
end
2572
endtask
2573
 
2574
 
2575
///////////////////////////////////////////////////////////////////////////////
2576
//
2577
//     task wait_for_data : waits for a response on the bus and decodes the
2578
//                          data packet and returns a status indicating what
2579
//                          type of packet was received.
2580
//     Output : PackType  : 4'b0010 : ACK
2581
//                          4'b1010 : NAK
2582
//                          4'b1110 : STALL
2583
//                          4'b0011 : DATA0
2584
//                          4'b1011 : DATA1
2585
//                          4'b1111 : Unknown
2586
//              ByteCount : indicates the number of bytes of data present if
2587
//                          PackType is of DATA0 or DATA1
2588
//              Status    : 0  : command executed successfully.
2589
//                          3  : time out, no response.
2590
//                          4  : invalid response, unknown packet type
2591
//                          5  : CRC error on received data
2592
//                          11 : corrupted ACK/NAK/STALL
2593
//                          12 : corrupted DATA0/DATA1 pid, CRC correct
2594
//                          13 : corrupted DATA0/DATA1 pid, CRC incorrect
2595
//             
2596
//
2597
///////////////////////////////////////////////////////////////////////////////
2598
task wait_for_data;
2599
output    [31:0]     ByteCount;
2600
output    [3:0]      PackType;
2601
output    [3:0]      Status;
2602
reg       [15:0]     tmpReg;
2603
reg       [15:0]     tmpCrc;
2604
reg       [31:0]     recv_bit_count;
2605
integer   i;
2606
begin
2607
WaitForResp(recv_bit_count);
2608
PackType = 4'b1111;
2609
Status   = 0;
2610
case (in_out_buf_ptr)
2611
 
2612
    Status = 3; // timeout
2613
    if (dec_bit_stuff_err == TRUE) usb_idle(RespTimeOutVal);
2614
end
2615
1 : begin
2616
    tmpReg[7:0] = in_out_buf[0];
2617
    case (tmpReg[3:0])
2618
    ACK     : PackType = ACK;
2619
    NAK     : PackType = NAK;
2620
    STALL   : PackType = STALL;
2621
    default : PackType = 4'b1111;
2622
    endcase
2623
    if (((tmpReg == ACK) | (tmpReg == NAK) | (tmpReg == STALL)) & (~tmpReg[7:4] != tmpReg[3:0])) Status = 11;
2624
end
2625
2 : begin
2626
    Status = 4;
2627
    PackType = 4'b1111;
2628
end
2629
default : begin   // since the number of bytes received is greater than 2 this
2630
                  // obviously should be a data packet
2631
    tmpReg[7:0] = in_out_buf[0];
2632
    ByteCount = 0;
2633
    tmpCrc = 16'hffff;
2634
    if ((tmpReg[3:0] == DATA0) | (tmpReg[3:0] == DATA1)) begin
2635
        for ( i = 1; i < (in_out_buf_ptr - 2); i = i + 1) begin
2636
            tmpCrc = crc16(in_out_buf[i], tmpCrc);
2637
            RecvBuffer[i - 1] = in_out_buf[i];
2638
            ByteCount = ByteCount + 1;
2639
        end
2640
        tmpCrc = ~{swap8(tmpCrc[15:8]), swap8(tmpCrc[7:0])};
2641
        if (tmpCrc != {in_out_buf[in_out_buf_ptr - 2], in_out_buf[in_out_buf_ptr - 1]}) Status = 5;
2642
        if (~tmpReg[7:4] != tmpReg[3:0]) begin
2643
            if (Status == 5) Status = 13;
2644
            else Status = 12;
2645
        end
2646
        PackType = tmpReg[3:0];
2647
    end
2648
    else PackType = 4'b1111;
2649
end
2650
endcase
2651
 
2652
end
2653
endtask
2654
 
2655
 
2656
 
2657
 
2658
parameter  MYACK   = 4'b0000,
2659
           MYNAK   = 4'b0001,
2660
           MYSTALL = 4'b0010,
2661
           MYTOUT  = 4'b0011,
2662
           MYIVRES = 4'b0100,
2663
           MYCRCER = 4'b0101;
2664
 
2665
 
2666
 
2667
parameter  OUT = 2'b00,
2668
           IN  = 2'b10,
2669
           SOF = 2'b01,
2670
           SETUP=2'b11;
2671
 
2672
 
2673
// Control Packet format;
2674
 
2675
reg [24:0]  ControlPkt;
2676
reg  [3:0] Status;
2677
integer     ByteCount;
2678
 
2679
 
2680
task printstatus;
2681
   input [3:0] RecvdStatus;
2682
   input [3:0] ExpStatus;
2683
begin
2684
  $display("");
2685
  $display("    #######################################################");
2686
  if(RecvdStatus !== ExpStatus ) begin
2687
     $display("    ERROR: Expected Status and Observed Status didn't match at %0d", $time);
2688
     if(ExpStatus==4'b0000)
2689
        $display("    Expected Status is ACK at %0d", $time);
2690
     else if(ExpStatus==4'b0001)
2691
        $display("    Expected Status is NACK at %0d", $time);
2692
     else if(ExpStatus==4'b0010)
2693
        $display("    Expected Status is STALL at %0d", $time);
2694
     else if(ExpStatus==4'b0011)
2695
        $display("    Expected Status is TIMEOUT at %0d", $time);
2696
     else if(ExpStatus==4'b0100)
2697
        $display("    Expected Status is INVALID RESPONSE at %0d", $time);
2698
     else if(ExpStatus==4'b0101)
2699
        $display("    Expected Status is CRC ERROR at %0d", $time);
2700
  end
2701
 
2702
  if(RecvdStatus==4'b0000)
2703
     $display("    Received Status is ACK at %0d", $time);
2704
  else if(RecvdStatus==4'b0001)
2705
     $display("    Received Status is NACK at %0d", $time);
2706
  else if(RecvdStatus==4'b0010)
2707
     $display("    Received Status is STALL at %0d", $time);
2708
  else if(RecvdStatus==4'b011)
2709
     $display("    Received Status is TIMEOUT at %0d", $time);
2710
  else if(RecvdStatus==4'b0100)
2711
     $display("    Received Status is INVALID RESPONSE at %0d", $time);
2712
  else if(RecvdStatus==4'b0101)
2713
     $display("    Received Status is CRC ERROR at %0d", $time);
2714
  $display("    #######################################################");
2715
  $display("");
2716
end
2717
endtask
2718
 
2719
 
2720
 
2721
 
2722
task dump_recv_buffer;
2723
 
2724
  input [31:0] NumBytes;
2725
  integer i;
2726
begin
2727
 
2728
 
2729
  for(i=0; i < NumBytes; i=i+1)
2730
    $display("RecvBuffer[%0d]  = %b  : %0d", i, RecvBuffer[i], RecvBuffer[i]);
2731
end
2732
endtask
2733
 
2734
 
2735
 
2736
task send_token;
2737
   input [1:0] tkn;
2738
   input [6:0] adr;
2739
   input [3:0] ep;
2740
 
2741
   reg [2:0]   Status;
2742
   reg [15:0]  tmpreg;
2743
begin
2744
 
2745
   XmitBuffer[0] = {~tkn,2'b10, tkn, 2'b01};
2746
   tmpreg = FillCrc5({ep, adr});
2747
   XmitBuffer[1] = tmpreg[7:0];
2748
   XmitBuffer[2] = tmpreg[15:8];
2749
   transfer_buf(3, 0, Status);
2750
end
2751
endtask
2752
 
2753
task send_datapkt;
2754
   input        datatgl;
2755
   input [10:0] numbytes;
2756
 
2757
   integer      i;
2758
   reg   [15:0] tmpcrc;
2759
   reg   [2:0]  Status;
2760
begin
2761
 
2762
   // Shifting the XmitBuffer Values to put the DataTkn in Byte0.
2763
   for(i=numbytes; i > 0; i=i-1) begin
2764
      XmitBuffer[i] = XmitBuffer[i-1];
2765
   end
2766
 
2767
   XmitBuffer[0] = {!datatgl, 3'b100, datatgl, 3'b011};
2768
 
2769
   tmpcrc = crc16(XmitBuffer[1], 16'hffff);
2770
   for(i=1; i < numbytes; i=i+1) begin
2771
      tmpcrc = crc16(XmitBuffer[i+1], tmpcrc);
2772
   end
2773
 
2774
   if(numbytes > 0) begin
2775
      XmitBuffer[numbytes+1] = ~swap8(tmpcrc[15:8]);
2776
      XmitBuffer[numbytes+2] = ~swap8(tmpcrc[7:0]);
2777
   end
2778
   else begin
2779
      XmitBuffer[numbytes+1] = 8'b0000_0000;
2780
      XmitBuffer[numbytes+2] = 8'b0000_0000;
2781
   end
2782
 
2783
   transfer_buf(numbytes+3, 0, Status);
2784
 
2785
end
2786
endtask
2787
 
2788
 
2789
task SetAddress;
2790
  input [6:0] address;
2791
begin
2792
    XmitBuffer[0] = 8'b0000_0000;
2793
    XmitBuffer[1] = 8'b0000_0101; // SetAddress
2794
    XmitBuffer[2] = {1'b0, address};
2795
    XmitBuffer[3] = 8'b0000_0000;
2796
    XmitBuffer[4] = 8'b0000_0000;
2797
    XmitBuffer[5] = 8'b0000_0000;
2798
    XmitBuffer[6] = 8'b0000_0000;
2799
    XmitBuffer[7] = 8'b0000_0000;
2800
end
2801
endtask
2802
 
2803
 
2804
task GetConfiguration;
2805
begin
2806
    XmitBuffer[0] = 8'b1000_0000;
2807
    XmitBuffer[1] = 8'b0000_1000; // get config.
2808
    XmitBuffer[2] = 8'b0000_0000;
2809
    XmitBuffer[3] = 8'b0000_0000;
2810
    XmitBuffer[4] = 8'b0000_0000;
2811
    XmitBuffer[5] = 8'b0000_0000;
2812
    XmitBuffer[6] = 8'b0000_0001;
2813
    XmitBuffer[7] = 8'b0000_0000;
2814
end
2815
endtask
2816
 
2817
 
2818
task SetConfiguration;
2819
  input [1:0] cfg_val;
2820
begin
2821
    XmitBuffer[0] = 8'b0000_0000;
2822
    XmitBuffer[1] = 8'b0000_1001; // Set Configuration
2823
    XmitBuffer[2] = {6'b000_000, cfg_val};
2824
    XmitBuffer[3] = 8'b0000_0000;
2825
    XmitBuffer[4] = 8'b0000_0000;
2826
    XmitBuffer[5] = 8'b0000_0000;
2827
    XmitBuffer[6] = 8'b0000_0000;
2828
    XmitBuffer[7] = 8'b0000_0000;
2829
end
2830
endtask
2831
 
2832
task GetDescriptor;
2833
  input [2:0] des_type_new;
2834
  input [2:0] des_index;
2835
  input [15:0] des_size;
2836
begin
2837
   XmitBuffer[0] = 8'b1000_0000;
2838
   XmitBuffer[1] = 8'b0000_0110;
2839
   XmitBuffer[2] = {5'b00000, des_index};
2840
   XmitBuffer[3] = {5'b00000, des_type_new};
2841
   XmitBuffer[4] = 8'b0000_0000;
2842
   XmitBuffer[5] = 8'b0000_0000;
2843
   XmitBuffer[6] = des_size[7:0];
2844
   XmitBuffer[7] = des_size[15:8];
2845
end
2846
endtask
2847
 
2848
task SetDescriptor;
2849
  input [2:0] des_type_new;
2850
  input [2:0] des_index;
2851
  input [15:0] des_size;
2852
begin
2853
   XmitBuffer[0] = 8'b0000_0000;
2854
   XmitBuffer[1] = 8'b0000_0111;
2855
   XmitBuffer[2] = {5'b00000, des_index};
2856
   XmitBuffer[3] = {5'b00000, des_type_new};
2857
   XmitBuffer[4] = 8'b0000_0000;
2858
   XmitBuffer[5] = 8'b0000_0000;
2859
   XmitBuffer[6] = des_size[7:0];
2860
   XmitBuffer[7] = des_size[15:8];
2861
end
2862
endtask
2863
 
2864
task SynchFrame;
2865
begin
2866
   XmitBuffer[0] = 8'b1000_0010;
2867
   XmitBuffer[1] = 8'b0000_1100;
2868
   XmitBuffer[2] = 8'b0000_0000;
2869
   XmitBuffer[3] = 8'b0000_0000;
2870
   XmitBuffer[4] = 8'b0000_0000;
2871
   XmitBuffer[5] = 8'b0000_0000;
2872
   XmitBuffer[6] = 8'b0000_0000;
2873
   XmitBuffer[7] = 8'b0000_0000;
2874
end
2875
endtask
2876
 
2877
 
2878
task VenRegWordWr;
2879
  input [6:0] address;
2880
  input [31:0] reg_address;
2881
  input [31:0] dataword;
2882
begin
2883
   XmitBuffer[0] = 8'b0100_0000;
2884
   XmitBuffer[1] = 8'b0001_0000;
2885
   XmitBuffer[2] = reg_address[31:24];
2886
   XmitBuffer[3] = reg_address[23:16];
2887
   XmitBuffer[4] = reg_address[15:8];
2888
   XmitBuffer[5] = reg_address[7:0];
2889
   XmitBuffer[6] = 8'b0000_0100;
2890
   XmitBuffer[7] = 8'b0000_0000;
2891
 
2892
   setup (address, 4'h0, Status);
2893
 
2894
   XmitBuffer[0] = dataword[31:24];
2895
   XmitBuffer[1] = dataword[23:16];
2896
   XmitBuffer[2] = dataword[15:8];
2897
   XmitBuffer[3] = dataword[7:0];
2898
 
2899
  control_OUT(address, 4'h0, 4, Status);
2900
  status_IN (address, 4'h0, Status);
2901
end
2902
endtask
2903
 
2904
task VenRegWordRd;
2905
  input [6:0] address;
2906
  input [31:0] reg_address;
2907
  output [31:0] dataword;
2908
  reg  [31:0] ByteCount;
2909
begin
2910
   XmitBuffer[0] = 8'b1100_0000;
2911
   XmitBuffer[1] = 8'b0001_0001;
2912
   XmitBuffer[2] = reg_address[31:24];
2913
   XmitBuffer[3] = reg_address[23:16];
2914
   XmitBuffer[4] = reg_address[15:8];
2915
   XmitBuffer[5] = reg_address[7:0];
2916
   XmitBuffer[6] = 8'b0000_0100;
2917
   XmitBuffer[7] = 8'b0000_0000;
2918
 
2919
   setup (address, 4'h0, Status);
2920
   control_IN(address, 4'h0, ByteCount, Status);
2921
   if (Status != MYACK)
2922
         control_IN(address, 4'h0, ByteCount, Status);
2923
   if (Status != MYACK)
2924
         control_IN(address, 4'h0, ByteCount, Status);
2925
    dataword[7:0]      = RecvBuffer[3];
2926
    dataword[15:8]     = RecvBuffer[2];
2927
    dataword[23:16]    = RecvBuffer[1];
2928
    dataword[31:24]    = RecvBuffer[0];
2929
    dump_recv_buffer(ByteCount);
2930
 
2931
   status_OUT (address, 4'h0, Status);
2932
end
2933
endtask
2934
 
2935
task VenRegWordRdCmp;
2936
  input [6:0] address;
2937
  input [31:0] reg_address;
2938
  input [31:0] dataword;
2939
  output [31:0] ByteCount;
2940
begin
2941
   XmitBuffer[0] = 8'b1100_0000;
2942
   XmitBuffer[1] = 8'b0001_0001;
2943
   XmitBuffer[2] = reg_address[31:24];
2944
   XmitBuffer[3] = reg_address[23:16];
2945
   XmitBuffer[4] = reg_address[15:8];
2946
   XmitBuffer[5] = reg_address[7:0];
2947
   XmitBuffer[6] = 8'b0000_0100;
2948
   XmitBuffer[7] = 8'b0000_0000;
2949
 
2950
   setup (address, 4'h0, Status);
2951
   control_IN(address, 4'h0, ByteCount, Status);
2952
   if (Status != MYACK)
2953
         control_IN(address, 4'h0, ByteCount, Status);
2954
   if (Status != MYACK)
2955
         control_IN(address, 4'h0, ByteCount, Status);
2956
   if ((RecvBuffer[3] !== dataword[7:0]) || (RecvBuffer[2] !== dataword[15:8])
2957
         || (RecvBuffer[1] !== dataword[23:16]) || (RecvBuffer[0] !== dataword[31:24]))
2958
    begin
2959
      -> tb.test_control.error_detected;
2960
       $display( "usb_agent check: Register Read Byte Mismatch !!! Exp: %x ; Rxd: %x",dataword[31:0], {RecvBuffer[0],RecvBuffer[1], RecvBuffer[2],RecvBuffer[3]} );
2961
       dump_recv_buffer(ByteCount);
2962
    end
2963
 
2964
   status_OUT (address, 4'h0, Status);
2965
end
2966
endtask
2967
task VenRegHalfWordRd;
2968
  input [6:0] address;
2969
  input [21:0] reg_address;
2970
  input [15:0] dataword;
2971
  output [31:0] ByteCount;
2972
begin
2973
   XmitBuffer[0] = 8'b1100_0000;
2974
   XmitBuffer[1] = {2'b00,reg_address[21:16]};
2975
   XmitBuffer[2] = reg_address[7:0];
2976
   XmitBuffer[3] = reg_address[15:8];
2977
   XmitBuffer[4] = 8'b0000_0000;
2978
   XmitBuffer[5] = 8'b0000_0000;
2979
   XmitBuffer[6] = 8'b0000_0010;
2980
   XmitBuffer[7] = 8'b0000_0000;
2981
 
2982
   setup (address, 4'h0, Status);
2983
   control_IN(address, 4'h0, ByteCount, Status);
2984
   if (Status != MYACK)
2985
         control_IN(address, 4'h0, ByteCount, Status);
2986
   if (Status != MYACK)
2987
         control_IN(address, 4'h0, ByteCount, Status);
2988
   if ((RecvBuffer[0] !== dataword[7:0]) || (RecvBuffer[1] !== dataword[15:8]))
2989
    begin
2990
       -> tb.test_control.error_detected;
2991
       $display( "usb_agent check: Register Read Byte Mismatch !!!");
2992
       dump_recv_buffer(ByteCount);
2993
    end
2994
   status_OUT (address, 4'h0, Status);
2995
end
2996
endtask
2997
 
2998
task VenRegByteRd;
2999
  input [6:0] address;
3000
  input [21:0] reg_address;
3001
  input [7:0] dataword;
3002
  output [31:0] ByteCount;
3003
begin
3004
   XmitBuffer[0] = 8'b1100_0000;
3005
   XmitBuffer[1] = {2'b00,reg_address[21:16]};
3006
   XmitBuffer[2] = reg_address[7:0];
3007
   XmitBuffer[3] = reg_address[15:8];
3008
   XmitBuffer[4] = 8'b0000_0000;
3009
   XmitBuffer[5] = 8'b0000_0000;
3010
   XmitBuffer[6] = 8'b0000_0001;
3011
   XmitBuffer[7] = 8'b0000_0000;
3012
 
3013
   setup (address, 4'h0, Status);
3014
   control_IN(address, 4'h0, ByteCount, Status);
3015
   if (Status != MYACK)
3016
         control_IN(address, 4'h0, ByteCount, Status);
3017
   if (Status != MYACK)
3018
         control_IN(address, 4'h0, ByteCount, Status);
3019
   if ((RecvBuffer[0] !== dataword[7:0]))
3020
    begin
3021
       -> tb.test_control.error_detected;
3022
       $display( "usb_agent check: Register Read Byte Mismatch !!!");
3023
       dump_recv_buffer(ByteCount);
3024
    end
3025
   status_OUT (address, 4'h0, Status);
3026
end
3027
endtask
3028
 
3029
task VenRegWr;
3030
  input [21:0] reg_address;
3031
  input [2:0]  length;
3032
begin
3033
   XmitBuffer[0] = 8'b0100_0000;
3034
   XmitBuffer[1] = {2'b00,reg_address[21:16]};
3035
   XmitBuffer[2] = reg_address[7:0];
3036
   XmitBuffer[3] = reg_address[15:8];
3037
   XmitBuffer[4] = 8'b0000_0000;
3038
   XmitBuffer[5] = 8'b0000_0000;
3039
   XmitBuffer[6] = {5'b0000_0,length};
3040
   XmitBuffer[7] = 8'b0000_0000;
3041
 
3042
end
3043
endtask
3044
 
3045
task VenRegRd;
3046
  input [21:0] reg_address;
3047
  input [2:0]  length;
3048
begin
3049
   XmitBuffer[0] = 8'b1100_0000;
3050
   XmitBuffer[1] = {2'b00,reg_address[21:16]};
3051
   XmitBuffer[2] = reg_address[7:0];
3052
   XmitBuffer[3] = reg_address[15:8];
3053
   XmitBuffer[4] = 8'b0000_0000;
3054
   XmitBuffer[5] = 8'b0000_0000;
3055
   XmitBuffer[6] = {5'b0000_0,length};
3056
   XmitBuffer[7] = 8'b0000_0000;
3057
end
3058
endtask
3059
 
3060
task VenRegWrWordData;
3061
  input [7:0] Byte0;
3062
  input [7:0] Byte1;
3063
  input [7:0] Byte2;
3064
  input [7:0] Byte3;
3065
begin
3066
   XmitBuffer[0] = Byte0;
3067
   XmitBuffer[1] = Byte1;
3068
   XmitBuffer[2] = Byte2;
3069
   XmitBuffer[3] = Byte3;
3070
end
3071
endtask
3072
 
3073
task VenRegWrHWordData;
3074
  input [7:0] Byte0;
3075
  input [7:0] Byte1;
3076
begin
3077
   XmitBuffer[0] = Byte0;
3078
   XmitBuffer[1] = Byte1;
3079
end
3080
endtask
3081
 
3082
task VenRegWrByteData;
3083
  input [7:0] Byte0;
3084
begin
3085
   XmitBuffer[0] = Byte0;
3086
end
3087
endtask
3088
 
3089
 
3090
/*****************************************/
3091
 
3092
    assign DPLS = zDPLS;
3093
    assign DMNS = zDMNS;
3094
 
3095
    //instantiate the encoder
3096
    usb_bfm_encoder u_usb_enc
3097
               (
3098
                 .enable_in         (enc_enbl),
3099
                 .reset_n           (enc_reset_n),
3100
                 .clk               (clk),
3101
                 .bit_count_out     (enc_bit_count_out),
3102
                 .count_out         (enc_count_out),
3103
                 .data_out_valid    (enc_data_out_valid),
3104
                 .gen_bit_stuff_err (BitStuffErr),
3105
                 .last_byte         (enc_last_byte),
3106
                 .start_bit         (DeviceSpeed),
3107
                 .data_in           (enc_data_in),
3108
                 .data_out          (DPLS),
3109
                 .data_out_n        (DMNS)
3110
               );
3111
 
3112
    //instantiate the decoder
3113
    usb_bfm_decoder u_usb_dec
3114
               (
3115
                 .enable_in         (dec_enbl),
3116
                 .ser_data_rdy      (dec_ser_data_rdy),
3117
                 .par_data_rdy      (dec_par_data_rdy),
3118
                 .reset_n           (dec_reset_n),
3119
                 .clk               (dpll_clk),
3120
                 .start_bit         (DeviceSpeed), // 1'b1),
3121
                 .data_in           (DPLS),
3122
                 .data_in_n         (DMNS),
3123
                 .recv_bit_count    (dec_recv_bit_count),
3124
                 .bit_stuff_err     (dec_bit_stuff_err),
3125
                 .ser_data_out      (),
3126
                 .par_data_out      (dec_par_data_out)
3127
               );
3128
 
3129
    usb_bfm_dpll dpll_inst
3130
               (
3131
                 .clk48             (clk4x),
3132
                 .clk6              (clk4x),
3133
                 .switch            (~DeviceSpeed),
3134
                 .reset_n           (dpll_reset_n),
3135
                 .data_in           (DPLS),
3136
                 .rec_clk           (dpll_clk),
3137
                 .data_out          ()
3138
               );
3139
 
3140
 
3141
    always begin
3142
        if (JitterOnOff == TRUE) begin
3143
            if (tmpJitterCount > 0) begin
3144
                #(PulseWidth - LowJitterTime) hs_clk = 1'b1;
3145
                #(PulseWidth - HighJitterTime)  hs_clk = 1'b0;
3146
                tmpJitterCount = tmpJitterCount - 1;
3147
                if (tmpJitterCount == 0) begin
3148
                    tmpJitterPeriod = JitterPeriod;
3149
                end
3150
            end
3151
            else begin
3152
                #PulseWidth hs_clk = 1'b1;
3153
                #PulseWidth hs_clk = 1'b0;
3154
                 if (tmpJitterPeriod == 0) begin
3155
                    tmpJitterCount = JitterCount;
3156
                 end
3157
                 tmpJitterPeriod = tmpJitterPeriod - 1;
3158
            end
3159
        end
3160
        else begin
3161
            #PulseWidth hs_clk = 1'b1;
3162
            #PulseWidth hs_clk = 1'b0;
3163
        end
3164
    end
3165
 
3166
    always begin
3167
        if (JitterOnOff == TRUE) begin
3168
            if (tmpJitterCount > 0) begin
3169
                #((PulseWidth * 8) - LowJitterTime)   ls_clk = 1'b1;
3170
                #((PulseWidth * 8) - HighJitterTime)  ls_clk = 1'b0;
3171
                tmpJitterCount = tmpJitterCount - 1;
3172
                if (tmpJitterCount == 0) begin
3173
                    tmpJitterPeriod = JitterPeriod;
3174
                end
3175
            end
3176
            else begin
3177
                #(PulseWidth * 8) ls_clk = 1'b1;
3178
                #(PulseWidth * 8) ls_clk = 1'b0;
3179
                 if (tmpJitterPeriod == 0) begin
3180
                    tmpJitterCount = JitterCount;
3181
                 end
3182
                 tmpJitterPeriod = tmpJitterPeriod - 1;
3183
            end
3184
        end
3185
        else begin
3186
            #(PulseWidth * 8) ls_clk = 1'b1;
3187
            #(PulseWidth * 8) ls_clk = 1'b0;
3188
        end
3189
    end
3190
 
3191
    initial  // intialise pll clock signals
3192
    begin
3193
        tmpJitterPeriod = 0;
3194
        tmpJitterCount  = 0;
3195
        dpll_reset_n    = 1'b0;
3196
        #1 dpll_reset_n = 1'b1;
3197
    end
3198
 
3199
    initial  // drive 6 MHz clock
3200
    begin
3201
        clk6 = 1'b0;
3202
        forever #(PulseWidth * 2) clk6 = ~clk6;
3203
    end
3204
 
3205
    initial  // drive 48 MHz clock
3206
    begin
3207
        clk48 = 1'b0;
3208
        HSClkComp = 1'b0;
3209
        HSClkCompToggle = 1'b0;
3210
        case ((PulseWidth) % 4)
3211
 
3212
        1 : HSClkComp = 1'b0;
3213
        2 : HSClkComp = 1'b1;
3214
        3 : HSClkComp = 1'b1;
3215
        default : HSClkComp = 1'b0;
3216
        endcase
3217
        forever begin
3218
            #((PulseWidth / 4) + HSClkComp) clk48 = 1'b1;
3219
            case ((PulseWidth) % 4)
3220
            0, 2 : begin
3221
                      #(PulseWidth / 4) clk48 = 1'b0;
3222
                      HSClkComp = ((PulseWidth % 4) == 0) ? 1'b0 : 1'b1;
3223
                   end
3224
            1, 3 : begin
3225
                       if (HSClkCompToggle == 1'b0) begin
3226
                           #(PulseWidth / 4) clk48 = 1'b0;
3227
                           HSClkCompToggle = 1'b1;
3228
                       end
3229
                       else begin
3230
                           #((PulseWidth / 4) + HSClkCompToggle) clk48 = 1'b0;
3231
                           HSClkCompToggle = 1'b0;
3232
                       end
3233
                       HSClkComp = ((PulseWidth % 4) == 1) ? 1'b0 : 1'b1;
3234
                   end
3235
            default : clk48 = 1'b1;
3236
            endcase
3237
        end
3238
    end
3239
 
3240
    always @(dpll_clk) rec_clk = dpll_clk;
3241
 
3242
    //initialise the encoder signals
3243
    initial
3244
    begin
3245
        hs_clk      = 1'b1;
3246
        ls_clk      = 1'b1;
3247
        enc_enbl    = 1'b0;        // active high
3248
        enc_reset_n = 1'b0;        // active low
3249
        enc_data_in = 8'bZZZZZZZZ;
3250
        zDPLS       = 1'bZ;
3251
        zDMNS       = 1'bZ;
3252
        dec_enbl    = 1'b0;        // active high
3253
        dec_reset_n = 1'b0;        // active low
3254
        // dec_cnt;
3255
      // user_commands;             // Invoking the User Commands.
3256
    end
3257
 
3258
initial
3259
begin
3260
`ifdef USBF_DEBUG
3261
   Debug = TRUE ;
3262
`else
3263
   Debug = FALSE ;
3264
`endif
3265
sofOnFlag        = FALSE ;
3266
//sofPeriod        = 1_000_000 ;
3267
sofPeriod        = 100_000 ;
3268
interruptOnFlag  = FALSE ;
3269
interruptRequest = FALSE ;
3270
interruptTimer   = 0 ;
3271
interruptPeriod  = 0 ;
3272
controlRequest   = FALSE ;
3273
controlGrant     = FALSE ;
3274
bulkInOnFlag      = FALSE ;
3275
bulkOutOnFlag    = FALSE ;
3276
end
3277
 
3278
 
3279
endmodule
3280
 
3281
 
3282
module usb_bfm_decoder(
3283
                enable_in,
3284
                ser_data_rdy,
3285
                par_data_rdy,
3286
                reset_n,
3287
                clk,
3288
                start_bit,
3289
                data_in,
3290
                data_in_n,
3291
                recv_bit_count,
3292
                bit_stuff_err,
3293
                ser_data_out,
3294
                par_data_out
3295
              );
3296
 
3297
input         enable_in;
3298
output        ser_data_rdy;
3299
output        par_data_rdy;
3300
input         clk;
3301
input         start_bit;
3302
input         data_in;
3303
input         data_in_n;
3304 8 dinesha
output [31:0] recv_bit_count;
3305 3 dinesha
output        bit_stuff_err;
3306
output        ser_data_out;
3307
output [7:0]  par_data_out;
3308
input         reset_n;
3309
 
3310
reg           enable_out;
3311
reg    [7:0]  par_data_out;
3312
reg           ser_data_out;
3313
reg           prev_bit;
3314
reg           prev_bit1;
3315
reg           tmpDataOut1;
3316
reg    [7:0]  tmpDataOut;
3317
reg    [31:0] recv_bit_count;
3318
reg           bit_stuff_err;
3319
reg           ser_data_rdy;
3320
reg           par_data_rdy;
3321
reg           JustEnabled;
3322
 
3323
reg    [3:0]  bit_count;
3324
reg    [3:0]  count;
3325
reg           SyncDetect;
3326
 
3327
initial begin
3328
    enable_out     = 1;
3329
    ser_data_out   = 1'bz;
3330
    ser_data_rdy   = 1'b0;
3331
    par_data_out   = 8'b0000_0000;
3332
    bit_count      = 0;
3333
    count          = 0;
3334
    tmpDataOut     = 8'b00000000;
3335
    tmpDataOut1    = 0;
3336
    JustEnabled    = 1;
3337
    par_data_rdy   = 1'b0;
3338
    recv_bit_count = 32'h0000_0000;
3339
    bit_stuff_err  = 1'b0;
3340
end
3341
 
3342
 
3343
 
3344
always @(posedge clk) #1 prev_bit1 <= data_in;
3345
 
3346
always @(posedge clk) begin
3347
 
3348
    if (!reset_n) begin
3349
        count <= 0;
3350
        recv_bit_count <= 1'b0;
3351
        bit_count <= 0;
3352
        par_data_out  <= 8'b0000_0000;
3353
    end
3354
 
3355
    if (enable_in) begin
3356
        if (count == 7 && !(bit_count==5 & (tmpDataOut1!=prev_bit))) begin
3357
            par_data_rdy <= 1'b1;
3358
        end
3359
        if (bit_count < 5) begin
3360
            if (count == 7) count <= 0;
3361
            else count <= count + 1;
3362
            par_data_out[count] <= tmpDataOut1;
3363
            recv_bit_count <= recv_bit_count + 1;
3364
            ser_data_rdy <= 1'b1;
3365
            ser_data_out <= tmpDataOut1;
3366
        end
3367
        else begin
3368
            if (tmpDataOut1 != 1'b0) begin
3369
                bit_stuff_err <= 1'b1;
3370
            end
3371
            ser_data_rdy <= 1'b0;
3372
        end
3373
    end
3374
    else begin
3375
        bit_stuff_err <= 1'b0;
3376
        par_data_rdy  <= 1'b0;
3377
    end
3378
 
3379
    prev_bit <= tmpDataOut1;
3380
 
3381
    if ((tmpDataOut1 == prev_bit) & (tmpDataOut1 == 1'b1)) begin
3382
        bit_count <= bit_count + 1;
3383
    end
3384
    else begin
3385
        bit_count <= 0;
3386
    end
3387
 
3388
    if (bit_count == 5) bit_count <= 0;
3389
 
3390
    if (prev_bit1 == data_in) tmpDataOut1 <= 1'b1;
3391
    else tmpDataOut1 <= 1'b0;
3392
 
3393
    if (par_data_rdy == 1'b1) par_data_rdy <= 1'b0;
3394
 
3395
end
3396
 
3397
 
3398
endmodule
3399
 
3400
module usb_bfm_encoder( enable_in,
3401
                reset_n,
3402
                clk,
3403
                bit_count_out,
3404
                count_out,
3405
                data_out_valid,
3406
                gen_bit_stuff_err,
3407
                last_byte,
3408
                start_bit,
3409
                data_in,
3410
                data_out,
3411
                data_out_n
3412
              );
3413
 
3414
//enable_in       : 0 disables the block
3415
//                  1 enables the block
3416
//data_in         : 8 bit wide register containing the parallel data
3417
//clk             : Clock !!
3418
//not used//data_in_valid   : the data in data_in is a valid next block of data
3419
//count_out       : count[2]
3420
//data_out        : serial data out
3421
//data_out_n      : invert of data_out
3422
//data_out_valid  : the data on data_out is valid and can be sampled
3423
//reset_n         : synchronous reset of the block
3424
 
3425
input        enable_in;
3426
input        clk;
3427
input        gen_bit_stuff_err;
3428
input  [7:0] data_in;
3429
input        reset_n;
3430
input        last_byte;
3431
input        start_bit;
3432
 
3433
output [3:0] bit_count_out;
3434
output       count_out;
3435
output       data_out;
3436
output       data_out_n;
3437
output       data_out_valid;
3438
 
3439
reg    [3:0] bit_count_out;
3440
reg          count_out;
3441
reg          data_out;
3442
reg          data_out_n;
3443
reg          data_out_valid;
3444
reg          tmpDataOut1;
3445
reg          tmpDataOut2;
3446
reg          prev_bit;
3447
reg          tmpDataOut;
3448
 
3449
reg    [3:0] count;
3450
reg    [3:0] bit_count;
3451
reg    [7:0] tmpDataIn;
3452
 
3453
initial begin
3454
    data_out       = 1'bZ;
3455
    data_out_n     = 1'bZ;
3456
    count          = 0;
3457
    bit_count      = 0;
3458
    bit_count_out  = 0;
3459
    count_out      = 0;
3460
    data_out_valid = 0;
3461
    tmpDataOut1    = start_bit;
3462
    tmpDataOut     = 0;
3463
    prev_bit       = 0;
3464
end
3465
 
3466
always @(posedge clk) begin
3467
    if (enable_in) begin
3468
        if (count == 0) tmpDataIn = data_in;
3469
        if (count < 8) begin
3470
            tmpDataOut = tmpDataIn[count];
3471
            if ((tmpDataOut) & (prev_bit)) begin
3472
                bit_count = bit_count + 1;
3473
            end
3474
            else begin
3475
                if (tmpDataOut) bit_count = 1;
3476
                else begin
3477
                    if (bit_count == 6) bit_count = 7;
3478
                    else bit_count = 0;
3479
                end
3480
            end
3481
            if (bit_count == 7)  begin
3482
                if (gen_bit_stuff_err == 1'b0) begin
3483
 
3484
                    tmpDataOut1 = ~tmpDataOut1;
3485
                    prev_bit = 1'b0;
3486
                end
3487
                else begin
3488
                    tmpDataOut1 = tmpDataOut1;
3489
                    prev_bit = 1'b1;
3490
                end
3491
                bit_count = 0;
3492
            end
3493
            else begin
3494
                if (tmpDataIn[count] == 0) tmpDataOut1 = ~tmpDataOut1;
3495
                count = count + 1;
3496
                prev_bit = tmpDataOut;
3497
            end
3498
            data_out = #1 tmpDataOut1;
3499
            data_out_n = ~tmpDataOut1;
3500
            data_out_valid = 1;
3501
        end
3502
        if (count == 8) count = 0;
3503
        if (bit_count != 6) count_out = count[2];
3504
        bit_count_out = count;
3505
    end
3506
    else begin
3507
        data_out = #1 1'bz;
3508
        data_out_n = 1'bz;
3509
        data_out_valid = 0;
3510
    end
3511
 
3512
    if (!reset_n) begin
3513
        count          = 0;
3514
        count_out      = 0;
3515
        bit_count      = 0;
3516
        data_out_valid = 0;
3517
        tmpDataIn      = 8'h00;
3518
        tmpDataOut1    = start_bit;
3519
        tmpDataOut     = 0;
3520
        prev_bit       = 0;
3521
        data_out       = #1 1'bz;
3522
        data_out_n     = 1'bz;
3523
    end
3524
end
3525
 
3526
endmodule
3527
 
3528
module usb_bfm_dpll (clk48, clk6, switch, reset_n, data_in, rec_clk, data_out);
3529
 
3530
  input clk48, clk6, switch, reset_n, data_in;
3531
 
3532
  output rec_clk, data_out;
3533
 
3534
  wire rec_clk;
3535
  wire data_out;
3536
  wire nrz;
3537
  wire dpll_clk;
3538
 
3539
  assign data_out = nrz;
3540
 
3541
  wire diff_pulse;
3542
 
3543
// Instance of the clock switch
3544
  usb_bfm_clk_switch clk_switch     (.clk1    (clk48),
3545
                             .clk2    (clk6),
3546
                             .switch  (switch),
3547
                             .reset_n (reset_n),
3548
                             .clk_out (dpll_clk));
3549
 
3550
// Instance of NRZI to NRZ converter                             
3551
  usb_bfm_nrzi2nrz nrzi2nrz_inst    (.nrzi    (data_in),
3552
                             .rec_clk (rec_clk),
3553
                             .reset_n (reset_n),
3554
                             .nrz     (nrz));
3555
 
3556
// Instance of the phase detect 
3557
  usb_bfm_ph_detect ph_detect       (.dpll_clk   (dpll_clk),
3558
                             .rst_n      (reset_n),
3559
                             .data_in    (data_in),
3560
                             .rec_clk    (rec_clk),
3561
                             .diff_pulse (diff_pulse));
3562
 
3563
// Instance of the pulse puller state machine
3564
  usb_bfm_pulse_puller pulse_puller (.clk        (dpll_clk),
3565
                             .diff_pulse (diff_pulse),
3566
                             .rst_n      (reset_n),
3567
                             .rec_clk    (rec_clk));
3568
 
3569
  endmodule
3570
 
3571
 
3572
// The clock switch module for selecting a low/high speed PLL
3573
 
3574
  module usb_bfm_clk_switch (clk1, clk2, switch, reset_n, clk_out);
3575
 
3576
  input  clk1, clk2, switch, reset_n;
3577
  output clk_out;
3578
 
3579
  wire ff1set, ff1clr, ff3clr, clk_out;
3580
  reg  ff1out, ff2out_bar, ff3out, ff3out_bar, ff4out_bar;
3581
 
3582
  assign ff1set  = ff4out_bar;
3583
  assign ff1clr  = reset_n;
3584
  assign ff3clr  = ff2out_bar;
3585
  assign clk_out = ((ff1out | clk1) & (ff3out_bar | clk2));
3586
 
3587
  parameter LOW  = 1'b0;
3588
  parameter HIGH = 1'b1;
3589
 
3590
//Filp Flop # 1
3591
 
3592
  always @ (posedge clk1 or negedge ff1set or negedge ff1clr) begin
3593
 
3594
    if (ff1clr === LOW) begin
3595
       ff1out = LOW;
3596
    end
3597
    else if (ff1set === LOW) begin
3598
       ff1out = HIGH;
3599
    end
3600
    else
3601
       ff1out <= switch;
3602
  end
3603
 
3604
//Flip Flop # 2
3605
 
3606
  always @ (posedge clk2) begin
3607
    ff2out_bar <= (ff1out);
3608
  end
3609
 
3610
//Flip Flop #3
3611
 
3612
  always @ (posedge clk2 or negedge ff3clr) begin
3613
 
3614
    if (ff3clr === LOW) begin
3615
       ff3out     <= LOW;
3616
       ff3out_bar <= HIGH;
3617
    end
3618
    else begin
3619
       ff3out     <= switch;
3620
       ff3out_bar <= !switch;
3621
    end
3622
  end
3623
 
3624
//Flip Flop #4
3625
 
3626
  always @ (posedge clk1) begin
3627
    ff4out_bar <= ! (ff3out);
3628
  end
3629
 
3630
  endmodule
3631
 
3632
// The NRZI to NRZ converter
3633
 
3634
  module usb_bfm_nrzi2nrz (nrzi, rec_clk, reset_n, nrz);
3635
 
3636
  input nrzi, rec_clk, reset_n;
3637
  output nrz;
3638
 
3639
  wire nrz;
3640
 
3641
  wire D1, D2, D0;
3642
  reg  Q1, Q2, Q0;
3643
  reg del_rec_clk;
3644
 
3645
  assign D0   = nrzi;
3646
  assign D1   = Q0;
3647
  assign D2   = !(Q0^Q1);
3648
  assign nrz = Q2;
3649
 
3650
//NRZI to NRZ converter
3651
 
3652
  always @ (reset_n) begin
3653
    if (!reset_n) begin
3654
      Q0 <= 1'b0;
3655
      Q1 <= 1'b0;
3656
      Q2 <= 1'b0;
3657
    end
3658
  end
3659
 
3660
  always @ (rec_clk) begin
3661
     del_rec_clk <= #21 rec_clk;
3662
  end
3663
 
3664
  always @(posedge del_rec_clk) begin
3665
    Q0 <= D0;
3666
    Q1 <= D1;
3667
    Q2 <= D2;
3668
  end
3669
 
3670
  endmodule
3671
 
3672
// The Phase detector
3673
 
3674
  module usb_bfm_ph_detect  (dpll_clk, rst_n, data_in, rec_clk, diff_pulse);
3675
 
3676
  input  dpll_clk, rst_n, data_in, rec_clk;
3677
  output diff_pulse;
3678
 
3679
  wire diff_pulse;
3680
 
3681
  reg Q0;
3682
  reg rec_clk_neg_edge;
3683
  reg gate_control;
3684
 
3685
  assign diff_pulse = (Q0 ^ data_in) & gate_control;
3686
 
3687
  always @ (posedge dpll_clk or negedge rst_n) begin
3688
    if (rst_n) begin
3689
       if ((Q0 ^ data_in) & rec_clk_neg_edge) begin
3690
         gate_control     <= 1'b0;
3691
         rec_clk_neg_edge <= 1'b0;
3692
       end
3693
    end
3694
    else begin
3695
       gate_control     <= 1'b1;
3696
       rec_clk_neg_edge <= 1'b0;
3697
    end
3698
    rec_clk_neg_edge <= 1'b0;
3699
  end
3700
 
3701
  always @ (negedge rec_clk or negedge rst_n) begin
3702
    if (rst_n) begin
3703
      Q0               <= data_in;
3704
      rec_clk_neg_edge <= 1'b1;
3705
      gate_control     <= 1'b1;
3706
    end
3707
    else begin
3708
       Q0 <= 1'b0;
3709
    end
3710
  end
3711
  endmodule
3712
 
3713
// The State m/c which does the Phase Correction
3714
 
3715
  module usb_bfm_pulse_puller (clk, diff_pulse, rst_n, rec_clk);
3716
 
3717
  input clk, rst_n, diff_pulse;
3718
  output rec_clk;
3719
 
3720
  reg rec_clk;
3721
 
3722
  reg [3:0] State;
3723
 
3724
  reg correct_pulse;
3725
 
3726
  reg Q0;
3727
 
3728
  parameter HIGH = 1'b1;
3729
  parameter LOW  = 1'b0;
3730
 
3731
  parameter  S0 = 3'b000;
3732
  parameter  S1 = 3'b001;
3733
  parameter  S2 = 3'b010;
3734
  parameter  S3 = 3'b011;
3735
  parameter  S4 = 3'b100;
3736
 
3737
// Generation of the correcting pulse from the Phase difference between the
3738
// data transition and negative edge of recovered clock
3739
 
3740
  always @ (posedge clk) begin
3741
    Q0 <= diff_pulse;
3742
    correct_pulse <= Q0 & diff_pulse;
3743
  end
3744
 
3745
// The pulse_puller state machine
3746
 
3747
  always @ (posedge clk or negedge rst_n) begin
3748
 
3749
  if (!rst_n) begin
3750
    State   <= S0;
3751
    rec_clk <= LOW;
3752
  end
3753
  else begin
3754
 
3755
    case (State)
3756
 
3757
    S0  :  begin
3758
             State   <= S1;
3759
             rec_clk <= ~rec_clk;
3760
           end
3761
 
3762
    S1  :  if (correct_pulse) begin
3763
              rec_clk <= ~rec_clk;
3764
              State   <= S3;
3765
           end
3766
           else begin
3767
              rec_clk <= rec_clk;
3768
              State   <= S2;
3769
           end
3770
 
3771
    S2  :  begin
3772
             if (correct_pulse) begin
3773
                State   <= S4;
3774
             end
3775
             else begin
3776
                State   <= S3;
3777
             end
3778
             rec_clk <= ~rec_clk;
3779
           end
3780
 
3781
    S3  :  if (correct_pulse) begin
3782
              State   <= S1;
3783
              rec_clk <= ~rec_clk;
3784
           end
3785
           else begin
3786
              rec_clk <= rec_clk;
3787
              State   <= S4;
3788
           end
3789
 
3790
    S4  :  begin
3791
             if (correct_pulse) begin
3792
               State <= S2;
3793
             end
3794
             else begin
3795
               State <= S1;
3796
             end
3797
             rec_clk <= ~rec_clk;
3798
           end
3799
 
3800
    default  :
3801
$display ("Illegal State at ",$time);
3802
 
3803
    endcase
3804
  end
3805
  end
3806
 
3807
  endmodule
3808
 
3809
 

powered by: WebSVN 2.1.0

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