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

Subversion Repositories openhmc

[/] [openhmc/] [trunk/] [openHMC/] [sim/] [UVC/] [hmc/] [sv/] [hmc_driver_base.sv] - Blame information for rev 15

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 juko
/*
2
 *                              .--------------. .----------------. .------------.
3
 *                             | .------------. | .--------------. | .----------. |
4
 *                             | | ____  ____ | | | ____    ____ | | |   ______ | |
5
 *                             | ||_   ||   _|| | ||_   \  /   _|| | | .' ___  || |
6
 *       ___  _ __   ___ _ __  | |  | |__| |  | | |  |   \/   |  | | |/ .'   \_|| |
7
 *      / _ \| '_ \ / _ \ '_ \ | |  |  __  |  | | |  | |\  /| |  | | || |       | |
8
 *       (_) | |_) |  __/ | | || | _| |  | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
9
 *      \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
10
 *           | |               | |            | | |              | | |          | |
11
 *           |_|               | '------------' | '--------------' | '----------' |
12
 *                              '--------------' '----------------' '------------'
13
 *
14
 *  openHMC - An Open Source Hybrid Memory Cube Controller
15
 *  (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
16
 *  www.ziti.uni-heidelberg.de
17
 *  B6, 26
18
 *  68159 Mannheim
19
 *  Germany
20
 *
21
 *  Contact: openhmc@ziti.uni-heidelberg.de
22
 *  http://ra.ziti.uni-heidelberg.de/openhmc
23
 *
24
 *   This source file is free software: you can redistribute it and/or modify
25
 *   it under the terms of the GNU Lesser General Public License as published by
26
 *   the Free Software Foundation, either version 3 of the License, or
27
 *   (at your option) any later version.
28
 *
29
 *   This source file is distributed in the hope that it will be useful,
30
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
 *   GNU Lesser General Public License for more details.
33
 *
34
 *   You should have received a copy of the GNU Lesser General Public License
35
 *   along with this source file.  If not, see .
36
 *
37
 *
38
 */
39
`ifndef HMC_DRIVER_BASE_SV
40
`define HMC_DRIVER_BASE_SV
41
 
42
class hmc_driver_base#(parameter NUM_LANES = 16) extends uvm_driver #(hmc_packet);
43
 
44
 
45
        `uvm_analysis_imp_decl(_hmc_frp)
46
        uvm_analysis_imp_hmc_frp #(hmc_packet, hmc_driver_base#(.NUM_LANES(NUM_LANES))) hmc_frp_port;
47
 
48
        init_state_t next_state = RESET;
49
        init_state_t state = RESET;
50
        init_state_t last_state = LINK_UP;
51
 
52
        virtual interface hmc_sr_if #(.NUM_LANES(NUM_LANES)) vif;
53
 
54
        hmc_token_handler token_handler;
55
        hmc_retry_buffer  retry_buffer;
56
        hmc_link_status   remote_status;
57
 
58
        //-- The parameters for this link
59
        hmc_link_config link_config;
60
 
61
        //-- The parameters for this driver
62
        hmc_local_link_config local_config;
63
 
64
        //-- Packets to send
65
        hmc_packet packet_queue[$];
66
 
67
        typedef bit lane_queue [$];
68
        lane_queue lane_queues [NUM_LANES];
69
 
70
        event driver_clk;
71
 
72
        uvm_event start_clear_retry_event;
73
 
74
        // Timestamps for debugging
75
        int reset_timestamp = 0;
76
        int prbs_timestamp = 0;
77
        int null_timestamp = 0;
78
        int req_ts1_timestamp = 0;
79
        int ts1_timestamp = 0;
80
 
81
        // Timestamps for controlling packet flow
82
        int last_packet_timestamp = 0;
83
        int start_retry_timestamp = 0;
84
        //-- error propability
85
        int next_poisoned = 0;
86
        int     lng_error_prob = 0;
87
        int     seq_error_prob = 0;
88
        int     crc_error_prob = 0;
89
 
90
        bit recover_from_power_down = 0;
91
 
92
        // Count retry attempts signalled by the responder (from here)
93
        int retry_attempts = 0;
94
 
95
        // Count retry attempts from the requester
96
        int remote_retries_signalled = 0;
97
        int remote_retries_cleared = 0;
98
        int local_retries_signalled = 0;
99
        int local_retries_cleared = 0;
100
 
101
        // Internal state for scramblers
102
        bit [14:0] lfsr[NUM_LANES-1:0];
103
 
104
        // Internal state for packets
105
        bit [2:0] seq_num = 1;
106
 
107
        // State for tokens and frp
108
        bit [7:0] frp_queue [$];
109
        bit [7:0] last_frp = 0;
110
        bit [7:0] last_rrp;
111
 
112
        int tokens_to_send = 0;
113
 
114
        int used_tokens = 0;
115
        int sent_tokens = 0;
116
 
117
        bit [14:0] lfsr_seed[0:15] = {
118
                                        15'h4D56,
119
                                        15'h47FF,
120
                                        15'h75B8,
121
                                        15'h1E18,
122
                                        15'h2E10,
123
                                        15'h3EB2,
124
                                        15'h4302,
125
                                        15'h1380,
126
                                        15'h3EB3,
127
                                        15'h2769,
128
                                        15'h4580,
129
                                        15'h5665,
130
                                        15'h6318,
131
                                        15'h6014,
132
                                        15'h077B,
133
                                        15'h261F
134
                        };
135
 
136
        bit [15:8]      ts1_high                = 8'hF0;
137
        bit [7:4]       ts1_top_lane    = 4'hC;
138
        bit [7:4]       ts1_bottom_lane = 4'h3;
139
        bit [7:4]       ts1_middle_lane = 4'h5;
140
 
141
        // Configuration parameters
142
        bit init_continue;
143
        bit can_continue;
144
 
145
        `uvm_component_param_utils(hmc_driver_base #(.NUM_LANES(NUM_LANES)))
146
 
147
        function new(string name="hmc_driver_base", uvm_component parent);
148
                super.new(name,parent);
149
        endfunction : new
150
 
151
        function void build_phase(uvm_phase phase);
152
                super.build_phase(phase);
153
 
154
                vif_found : assert (uvm_config_db#(virtual interface hmc_sr_if#(.NUM_LANES(NUM_LANES)))::get(this, "", "vif",this.vif));
155
                config_found : assert (uvm_config_db#(hmc_link_config)::get(this, "", "link_config",link_config));
156
        endfunction : build_phase
157
 
158
        virtual task run_phase(uvm_phase phase);
159
                super.run_phase(phase);
160
        endtask : run_phase
161
 
162
        task reset();
163
 
164
                vif.TXP = {$size(vif.TXP) {1'bz}};
165
                vif.TXN = {$size(vif.TXN) {1'bz}};
166
                vif.TXPS = 1'bz;
167
 
168
                seq_num = 1;
169
                last_rrp = 0;
170
                init_continue = 0;
171
                can_continue = 0;
172
                retry_buffer.reset();
173
 
174
                //-- wait for reset signal
175
                @(posedge vif.P_RST_N);
176
                reset_timestamp = $time;
177
 
178
                next_state = INIT;
179
        endtask : reset
180
 
181
        task clk_gen();
182
                @(posedge vif.REFCLKP);
183
                forever begin
184
                        #link_config.bit_time -> driver_clk;
185
                end
186
        endtask : clk_gen
187
 
188
        task send_ts1(int ts1_fits);
189
                bit [4:0] ts1_seq_num;
190
                bit [NUM_LANES-1:0] fit_val;
191
                bit [15:0] ts1_values [NUM_LANES-1:0];
192
 
193
                ts1_values[0]           = {ts1_high, ts1_bottom_lane, 4'h0};
194
                for (int lane=1; lane < local_config.width-1; lane++)
195
                        ts1_values[lane]        = {ts1_high, ts1_middle_lane, 4'h0};
196
                ts1_values[local_config.width-1]        = {ts1_high, ts1_top_lane, 4'h0};
197
 
198
                //Send some (possibly incomplete) TS1 flits
199
                while (ts1_fits > 0) begin
200
                        // Cycle through all the sequence numbers
201
                        for (ts1_seq_num=0; ts1_seq_num < 16 && ts1_fits > 0; ts1_seq_num++) begin
202
                                // Add the sequence number to the ts1_values
203
                                for (int i=0; i < local_config.width; i++) begin
204
                                        ts1_values[i][3:0] = ts1_seq_num;
205
                                end
206
                                // Send the fits of the ts1 values
207
                                for (int fit=0; fit < 16; fit++) begin
208
                                        for (int lane=0; lane < local_config.width; lane++) begin
209
                                                fit_val[lane] = ts1_values[lane][fit];
210
                                        end
211
                                        if (ts1_fits > 0) begin
212
                                                drive_fit(fit_val);
213
                                        end else begin
214
                                                drive_fit({NUM_LANES{1'b0}});
215
                                        end
216
                                        ts1_fits = ts1_fits - 1;
217
                                end
218
                        end
219
                end
220
        endtask : send_ts1
221
 
222
        task initial_trets();
223
                hmc_packet tret = new();
224
                //send TRET FLITs
225
                while (tokens_to_send > 0) begin
226
                        init_tret_randomization : assert (tret.randomize() with {
227
                                command == HMC_TRET;
228
                                poisoned == 0;
229
                                crc_error == 0;
230
                                packet_length == 1;
231
                                duplicate_length == 1;
232
                                return_token_count <= tokens_to_send && return_token_count > 0;
233
                                });
234
                        send_packet(tret);
235
                        tokens_to_send = tokens_to_send - tret.return_token_count;
236
                end
237
                next_state = LINK_UP;
238
        endtask : initial_trets
239
 
240
        task link_up();
241
                hmc_packet packet;
242
 
243
                get_packets();
244
 
245
                if (packet_queue.size() > 0 && token_handler.tokens_available(packet_queue[0].packet_length) && (250- retry_buffer.get_buffer_used()) > packet_queue[0].packet_length ) begin
246
                        packet = packet_queue.pop_front();      //-- send the first packet in the queue
247
                        if ((next_poisoned < local_config.poisoned_probability))
248
                                send_poisoned(packet);
249
                        else
250
                                send_packet(packet);
251
 
252
                        poisoned_propability_randomisation : assert (std::randomize(next_poisoned) with {next_poisoned > 0 && next_poisoned < 1000;});
253
 
254
                end else if ($time-last_packet_timestamp > local_config.send_pret_time && frp_queue.size() > 0) begin
255
                        `uvm_info(get_type_name(),$psprintf("sending pret, frp_queue size = %0d", frp_queue.size()), UVM_HIGH)
256
                        send_pret();
257
                end else if ($time-last_packet_timestamp > local_config.send_tret_time && (used_tokens - sent_tokens) > 0 &&(250- retry_buffer.get_buffer_used()) >1) begin
258
                        `uvm_info(get_type_name(),$psprintf("sending tret, (<%0d)", used_tokens-sent_tokens), UVM_HIGH)
259
                        send_tret();
260
                end else begin
261
                        drive_flit(128'h0);
262
                end
263
 
264
                // From here on, there are no packets being driven.  This is just logic to decide the next state.
265
 
266
                //-- Handle error_abort_mode on remote link
267
                if (remote_status.get_error_abort_mode() && $time() - start_retry_timestamp > link_config.retry_timeout_period  ) begin
268
                        next_state = START_RETRY_INIT;
269
                end
270
        endtask : link_up
271
 
272
        task start_retry_init();        //-- send start retry IRTRYs
273
 
274
                start_retry_timestamp = $time;
275
                local_retries_signalled = local_retries_signalled + 1;
276
                `uvm_info(get_type_name(),$psprintf("sending start retry packets"), UVM_MEDIUM)
277
 
278
                //send IRTRY FLITs
279
                for (int i=0; i < local_config.irtry_flit_count_to_send; i++)
280
                        send_irtry_start();
281
 
282
                next_state = LINK_UP;
283
        endtask : start_retry_init
284
 
285
        task clear_retry(); //-- send clear error abort mode IRTRYs
286
 
287
                local_retries_cleared = local_retries_cleared + 1;
288
                //send IRTRY FLITs
289
                for (int i=0; i < local_config.irtry_flit_count_to_send; i++)
290
                        send_irtry_clear();
291
                next_state = SEND_RETRY_PACKETS;
292
        endtask : clear_retry
293
 
294
        task send_retry_packets();
295
                hmc_packet packet;
296
                int spacer_flits;
297
 
298
                packet = retry_buffer.get_retry_packet();
299
                while (packet != null) begin
300
                        spacer_flits_randomization_succeeds : assert (std::randomize(spacer_flits) with {spacer_flits >= 0 && spacer_flits < 10;});
301
                        for (int i=0; i
302
                                drive_flit(128'h0);
303
                        end
304
                        retry_send_packet(packet);
305
                        packet = retry_buffer.get_retry_packet();
306
                end
307
                next_state = LINK_UP;
308
        endtask : send_retry_packets
309
 
310
        task get_packets();
311
                hmc_packet packet;
312
 
313
                if( seq_item_port.has_do_available() ) begin
314
                        if( packet_queue.size() == 0) begin
315
                                seq_item_port.get_next_item(packet);
316
                                packet_queue.push_back(packet);
317
                                seq_item_port.item_done();
318
                        end
319
                end
320
        endtask : get_packets
321
 
322
        task send_irtry_start();
323
                send_irtry(1,0);
324
        endtask : send_irtry_start
325
 
326
        task send_irtry_clear();
327
                send_irtry(0,1);
328
        endtask : send_irtry_clear
329
 
330
        task send_irtry(input bit start, input bit clear);
331
                hmc_packet irtry = new();
332
 
333
                irtry_randomization: assert (irtry.randomize() with {
334
                        command == HMC_IRTRY;
335
                        packet_length == 1;
336
                        duplicate_length == 1;
337
                        start_retry == start;
338
                        clear_error_abort == clear;
339
                });
340
 
341
                send_packet(irtry);
342
        endtask : send_irtry
343
 
344
        task send_tret();
345
 
346
                hmc_packet tret = new();
347
 
348
                tret_randomization: assert (tret.randomize() with {
349
                        command == HMC_TRET;
350
                        packet_length == 1;
351
                        duplicate_length == 1;
352
                });
353
 
354
                send_packet(tret);
355
 
356
        endtask : send_tret
357
 
358
        task send_pret();
359
 
360
                hmc_packet pret = new();
361
 
362
                pret_randomization: assert (pret.randomize() with {
363
                        command == HMC_PRET;
364
                        packet_length == 1;
365
                        duplicate_length == 1;
366
                });
367
 
368
                send_packet(pret);
369
 
370
        endtask : send_pret
371
 
372
        task send_poisoned(input hmc_packet pkt);
373
                hmc_packet poisoned = new pkt; //-- copy the pkt into a new one
374
 
375
                `uvm_info(get_type_name(),$psprintf("Poisoning Packet with command %s and tag %d", poisoned.command.name(), poisoned.tag),UVM_NONE)
376
 
377
                poisoned.poisoned = 1;
378
                send_packet(poisoned);
379
 
380
                packet_queue.push_back(pkt);//-- resent the packet later
381
 
382
        endtask : send_poisoned
383
 
384
        task send_packet(input hmc_packet pkt);
385
                int packet_frp;
386
                bit [31:0] crc;
387
                int bit_pos;
388
                int tok_cnt;
389
                // Save packet in Retry buffer if not IRTRY, NULL, or PRET
390
                // Tokens and Sequence numbers are saved in the retry buffer.
391
 
392
                if (pkt.command == HMC_IRTRY ||
393
                        pkt.command == HMC_NULL ||
394
                        pkt.command == HMC_PRET) begin
395
                        packet_frp = 0;
396
                        pkt.sequence_number = 0;
397
                        retry_send_packet(pkt);
398
                end else begin
399
                        pkt.sequence_number = seq_num;
400
                        if (state != INITIAL_TRETS) begin
401
                                if (used_tokens - sent_tokens > 0) begin
402
                                        // Always send tokens with TRETs
403
                                        if (pkt.command == HMC_TRET)
404
                                                tok_cnd_tret_randomization : assert (std::randomize(tok_cnt) with {(pkt.command == HMC_TRET && tok_cnt > 0)  && tok_cnt < 32 && tok_cnt <= (used_tokens - sent_tokens);});
405
                                        else
406
                                                tok_cnt_randomization_succeeds : assert (std::randomize(tok_cnt) with {(tok_cnt >= 0) && tok_cnt < 32 && tok_cnt <= (used_tokens - sent_tokens);});
407
                                        pkt.return_token_count = tok_cnt;
408
                                end else begin
409
                                        pkt.return_token_count = 0;
410
                                end
411
                        end
412
                        packet_frp = retry_buffer.add_packet(pkt);
413
                        if(packet_frp != -1)begin
414
                                seq_num++;
415
                                if (state != INITIAL_TRETS) begin
416
                                        sent_tokens += pkt.return_token_count;
417
                                end
418
                                // From now on, it's equivalent to retry
419
                                `uvm_info(get_type_name(), $psprintf("Sending CDM  %s with TRETS %d", pkt.command.name(), pkt.return_token_count), UVM_HIGH)
420
                                retry_send_packet(pkt);
421
                        end
422
                end
423
        endtask : send_packet
424
 
425
        task retry_send_packet(input hmc_packet pkt);
426
                bit [31:0] crc;
427
                int bit_pos;
428
                int bit_error;
429
                int error_type;
430
                int rrp_to_send;
431
 
432
 
433
                int pkt_lng;
434
                bit [2:0]seq_number;
435
 
436
 
437
                // Don't change the stored packet (except to clear the CRC error flag)
438
                hmc_packet copy = new pkt;
439
 
440
                // Return retry pointers are not saved.
441
                // Skip some retry pointers
442
                rrp_to_send_randomization_succeeds : assert (std::randomize(rrp_to_send) with {rrp_to_send >= 0 && rrp_to_send <= frp_queue.size();});
443
                if (rrp_to_send == 0) begin
444
                        copy.return_retry_pointer = last_rrp;
445
                end else begin
446
                        for (int i=0;i
447
                                copy.return_retry_pointer = frp_queue.pop_front();
448
                                `uvm_info(get_type_name(),$psprintf("popped %0d for frp in %s", copy.return_retry_pointer, copy.command.name()),UVM_HIGH)
449
                        end
450
                end
451
                last_rrp = copy.return_retry_pointer;
452
 
453
                //-- ERROR INJECTION
454
 
455
                //-- adding sequence error
456
                error_type_seq_error_randomization : assert (std::randomize(seq_error_prob) with {seq_error_prob > 0 && seq_error_prob < 1000;});
457
                if (seq_error_prob < local_config.seq_error_probability) begin
458
                                randcase
459
                                        1:      copy.sequence_number = copy.sequence_number + 1;
460
                                        1:      copy.sequence_number = copy.sequence_number - 1;
461
                                        1:      begin
462
                                                        random_SEQ_succeeds : assert(
463
                                                                        std::randomize(seq_number) with { seq_number !=copy.sequence_number;});
464
                                                        copy.sequence_number = seq_number;
465
                                                end
466
                                endcase
467
                                `uvm_info(get_type_name(),$psprintf("injecting SEQ error in CMD %s and FRP %d",copy.command.name(), copy.forward_retry_pointer), UVM_NONE)
468
                end
469
 
470
 
471
                //-- inserting Length Error
472
                error_type_lng_error_randomization : assert (std::randomize(lng_error_prob) with {lng_error_prob > 0 && lng_error_prob < 1000;});
473
                if (lng_error_prob < local_config.lng_error_probability) begin
474
                        randcase
475
                                1:      copy.packet_length = copy.packet_length + 1;
476
                                1:      copy.packet_length = copy.packet_length - 1;
477
                                1:      copy.duplicate_length = copy.duplicate_length + 1;
478
                                1:      copy.duplicate_length = copy.duplicate_length - 1;
479
                                1:      begin   random_LNG_succeeds : assert(
480
                                                                std::randomize(pkt_lng) with {pkt_lng >= 0 && pkt_lng < 16  && pkt_lng !=copy.packet_length;});
481
                                                        copy.packet_length = pkt_lng;
482
                                        end
483
                                1:      begin   random_DLN_succeeds : assert(
484
                                                                std::randomize(pkt_lng) with {pkt_lng >= 0 && pkt_lng < 16  && pkt_lng !=copy.duplicate_length;});
485
                                                        copy.duplicate_length = pkt_lng;
486
                                        end
487
                        endcase
488
                end
489
 
490
                crc = copy.calculate_crc(); //-- calculate crc for packet with valid tail
491
 
492
 
493
                //-- poisoning packets
494
                if (copy.poisoned) begin
495
                        `uvm_info(get_type_name(),$psprintf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX poisoning packet with CRC %0x and CMD %s and TAG %d", ~crc, copy.command.name(), copy.tag),UVM_LOW)
496
                        crc = ~crc;
497
                end
498
 
499
 
500
                //-- inserting CRC error
501
                error_type_crc_error_randomization : assert (std::randomize(crc_error_prob) with {crc_error_prob > 0 && crc_error_prob < 1000;});
502
                if (crc_error_prob < local_config.crc_error_probability * copy.packet_length) begin //-- increase the crc error probability for longer packets
503
                        int clear_crc_error;
504
                        crc_bit_error_randomization_succeeds : assert (std::randomize(bit_pos) with {bit_pos >= 0 && bit_pos < 32;});
505
                        `uvm_info(get_type_name(),$psprintf("inserting crc error at %0x", bit_pos),UVM_LOW)
506
                        crc[bit_pos] = !crc[bit_pos];
507
                        clear_crc_error_randomization_succeeds : assert (std::randomize(clear_crc_error) with {clear_crc_error >= 0 && clear_crc_error < 3;});
508
                        if (clear_crc_error == 1)
509
                                pkt.crc_error = 0;
510
                end
511
                copy.packet_crc = crc;
512
                drive_tx_packet(copy);
513
 
514
        endtask : retry_send_packet
515
 
516
        task drive_fit(input bit[NUM_LANES-1:0] new_value);
517
                if (link_config.scramblers_enabled) begin
518
                        drive_lanes(get_scrambler_value()^new_value);
519
                end else begin
520
                        drive_lanes(new_value);
521
                end
522
                @driver_clk;
523
                step_scramblers();
524
        endtask : drive_fit
525
 
526
        task drive_flit(input bit [127:0] flit);
527
                int i;
528
                bit [15:0] fits [16];
529
 
530
                for (int i=0; i<128; i++)
531
                        fits[i/local_config.width][i%local_config.width] = flit[i];
532
 
533
                for (int i=0; i<128/local_config.width;i++) begin
534
                        drive_fit(fits[i]);
535
                end
536
 
537
        endtask : drive_flit
538
 
539
        task drive_tx_packet(input hmc_packet pkt);
540
                bit bitstream[];
541
                bit [127:0] flits [9]; // Max packet size is 9 flits
542
                bit [127:0] curr_flit;
543
                int i;
544
                int bitcount;
545
                bitcount = pkt.pack(bitstream);
546
 
547
                for (int i=0; i
548
                        flits[i/128][i%128] = bitstream[i];
549
                for (int i=0; i
550
                        drive_flit(flits[i]);
551
                end
552
 
553
                last_packet_timestamp = $time;
554
 
555
        endtask : drive_tx_packet
556
 
557
        virtual function void drive_lanes(input bit[NUM_LANES-1:0] new_value);
558
                `uvm_info(get_type_name(),$psprintf("called virtual function drive_lanes!"), UVM_HIGH)
559
        endfunction : drive_lanes
560
 
561
        function void reset_lfsr();
562
                int i;
563
 
564
                for (i = 0; i < NUM_LANES; i= i+1) begin
565
                        if (local_config.reverse_lanes == 1)
566
                                lfsr[i] = lfsr_seed[NUM_LANES-1-i];
567
                        else
568
                                lfsr[i] = lfsr_seed[i];
569
                end
570
        endfunction : reset_lfsr
571
 
572
        function void step_scramblers();
573
                int i;
574
 
575
                if (link_config.scramblers_enabled) begin
576
                        for (i = 0; i < NUM_LANES; i= i+1) begin
577
                                lfsr[i] = {lfsr[i][1]^lfsr[i][0], lfsr[i][14:1]};
578
                        end
579
                end
580
        endfunction : step_scramblers
581
 
582
        function bit[NUM_LANES-1:0] get_scrambler_value();
583
                int i;
584
 
585
                if (link_config.scramblers_enabled) begin
586
                        for (i = 0; i < NUM_LANES; i= i+1) begin
587
                                get_scrambler_value[i] = lfsr[i][0];
588
                        end
589
                end else begin
590
                        for (i = 0; i < NUM_LANES; i= i+1) begin
591
                                get_scrambler_value = {NUM_LANES {1'b0}};
592
                        end
593
                end
594
        endfunction : get_scrambler_value
595
 
596
        // I2C or JTAG would configure the HMC during reset
597
        function void set_init_continue();
598
                tb_respects_tINIT : assert (can_continue);
599
                init_continue = 1;
600
        endfunction : set_init_continue
601
 
602
        virtual function void write_hmc_frp(input hmc_packet pkt);
603
 
604
                bit [7:0] frp;
605
                int random_wait;
606
 
607
                `uvm_info(get_type_name(),$psprintf("hmc_frp: %s with FRP %0d & size %0d",pkt.command.name(), pkt.forward_retry_pointer, pkt.packet_length),UVM_HIGH)
608
 
609
                // IRTRY and PRET do not have valid frp fields
610
                if (pkt.command != HMC_IRTRY && pkt.command != HMC_PRET) begin
611
                        frp = pkt.forward_retry_pointer;
612
                        if (frp != last_frp) begin
613
                                frp_queue.push_back(frp);
614
                                last_frp = frp;
615
                        end
616
                end
617
 
618
                if (pkt.get_command_type != HMC_FLOW_TYPE && !pkt.poisoned ) begin
619
                        used_tokens_does_not_overflow : assert ( used_tokens < used_tokens + pkt.packet_length);
620
                        used_tokens = used_tokens + pkt.packet_length;
621
                end
622
 
623
        endfunction : write_hmc_frp
624
 
625
endclass : hmc_driver_base
626
 
627
`endif // HMC_DRIVER_BASE_SV
628
 

powered by: WebSVN 2.1.0

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