OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_noc/] [congestion_analyzer.v] - Blame information for rev 48

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
`timescale      1ns/1ps
2
/**********************************************************************
3
**      File:  congestion_analyzer.v
4
**
5
**      Copyright (C) 2014-2017  Alireza Monemi
6
**
7
**      This file is part of ProNoC
8
**
9
**      ProNoC ( stands for Prototype Network-on-chip)  is free software:
10
**      you can redistribute it and/or modify it under the terms of the GNU
11
**      Lesser General Public License as published by the Free Software Foundation,
12
**      either version 2 of the License, or (at your option) any later version.
13
**
14
**      ProNoC is distributed in the hope that it will be useful, but WITHOUT
15
**      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
**      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
17
**      Public License for more details.
18
**
19
**      You should have received a copy of the GNU Lesser General Public
20
**      License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
21
**
22
**
23
**      Description:
24
**      This file includes all files for getting congestion information and
25
**      Port selection modules for supporting adaptive routing
26
**
27
**************************************************************/
28
 
29
 
30
 
31
 
32
                                    /*****************************
33
 
34
                                                port_presel
35
 
36
                                    *****************************/
37
 
38
 
39
 
40
/***************************************
41
 
42
     port_presel_based_dst_ports_vc
43
          CONGESTION_INDEX==0
44
***************************************/
45
 
46
 
47
//congestion analyzer based on number of occupied VCs
48
module   port_presel_based_dst_ports_vc #(
49
    parameter PPSw=4,
50
    parameter P   =   5,
51
    parameter V   =   4
52
    )
53
    (
54
        ovc_status,
55
        port_pre_sel
56
     );
57
 
58
 
59
    function integer log2;
60
      input integer number; begin
61
         log2=(number <=1) ? 1: 0;
62
         while(2**log2<number) begin
63
            log2=log2+1;
64
         end
65
      end
66
    endfunction // log2 
67
 
68
    localparam  P_1     =       P-1,
69
                P_1V    =       P_1*V,
70
                CNTw    =       log2(V+1);
71
 
72
    input   [P_1V-1     :   0]  ovc_status;
73
    output  [PPSw-1      :   0]  port_pre_sel;
74
    wire    [P_1-1      :   0]  conjestion_cmp;
75
    //VC counter on all ports exept the local    
76
    wire    [V-1        :   0]  ovc_status_per_port [P-1-1  :   0];
77
    wire    [CNTw -1    :   0]  vc_counter          [P_1-1  :   0];
78
 
79
    genvar i;
80
    generate
81
        for( i= 0;i<P_1;i=i+1) begin : p_loop
82
                //seperate all credit counters 
83
 
84
                assign ovc_status_per_port[i]   = ovc_status[(i+1)*V-1       :   i*V];
85
                //count number of busy OVCs
86
                accumulator #(
87
                        .INw(V),
88
                        .OUTw(CNTw),
89
                        .NUM(V)
90
                )
91
                counter
92
                (
93
                        .in_all(ovc_status_per_port[i]),
94
                        .out(vc_counter[i])
95
                );
96
 
97
 
98
                /*
99
                parallel_counter #(
100
                    .IN_WIDTH(V)
101
                )counter
102
                (
103
                    .in    (ovc_status_per_port[i]),
104
                    .out   (vc_counter[i])
105
                );
106
                */
107
 
108
 
109
       end//for
110
    endgenerate
111
/*******************
112
pre-sel[xy]
113
    y
114
1   |   3
115
    |
116
 -------x
117
 
118
    |
119
 
120
 
121
pre_sel
122
             0: xdir is preferable
123
             1: ydir is preferable
124
*******************/
125
 
126
 
127
 
128
    //location in counter  
129
    localparam X_PLUS   =   0,//EAST
130
               Y_PLUS   =   1,//NORTH
131
               X_MINUS  =   2,//WEST
132
               Y_MINUS  =   3;//SOUTH
133
 
134
    //location in port-pre-select           
135
    localparam X_PLUS_Y_PLUS  = 3,
136
               X_MINUS_Y_PLUS = 1,
137
               X_PLUS_Y_MINUS = 2,
138
               X_MINUS_Y_MINUS= 0;
139
 
140
    assign conjestion_cmp[X_PLUS_Y_PLUS]  = (vc_counter[X_PLUS]   >  vc_counter[Y_PLUS]);
141
    assign conjestion_cmp[X_MINUS_Y_PLUS] = (vc_counter[X_MINUS]  >  vc_counter[Y_PLUS]);
142
    assign conjestion_cmp[X_PLUS_Y_MINUS] = (vc_counter[X_PLUS]   >  vc_counter[Y_MINUS]);
143
    assign conjestion_cmp[X_MINUS_Y_MINUS]= (vc_counter[X_MINUS]  >  vc_counter[Y_MINUS]);
144
 
145
    //assign port_pre_sel = conjestion_cmp;
146
 
147
 
148
    assign port_pre_sel = conjestion_cmp;
149
 
150
 
151
 
152
 
153
 
154
 endmodule
155
 
156
/*************************************
157
*
158
*    port_presel_based_dst_ports_credit
159
*           CONGESTION_INDEX==1
160
*************************************/
161
 
162
 
163
//congestion analyzer based on number of total available credit of a port
164
module  port_presel_based_dst_ports_credit #(
165
    parameter PPSw=4,
166
    parameter P =   5,
167
    parameter V =   4,
168
    parameter B =   4
169
)
170
(
171
    credit_decreased_all,
172
    credit_increased_all,
173
    port_pre_sel,
174
    clk,
175
    reset
176
);
177
 
178
 
179
    function integer log2;
180
      input integer number; begin
181
         log2=(number <=1) ? 1: 0;
182
         while(2**log2<number) begin
183
            log2=log2+1;
184
         end
185
      end
186
    endfunction // log2 
187
 
188
    localparam  P_1     =       P-1,
189
                P_1V    =       (P_1)*V,
190
                BV      =       B*V,
191
                BV_1    =       BV-1,
192
                BVw     =       log2(BV);
193
 
194
   localparam [BVw-1    :   0] C_INT    =  BV_1 [BVw-1    :   0];
195
 
196
 
197
   input    [P_1V-1 :   0]  credit_decreased_all;
198
   input    [P_1V-1 :   0]  credit_increased_all;
199
   input                    reset,clk;
200
   output   [PPSw-1  :   0]  port_pre_sel;
201
 
202
 
203
 
204
    reg     [BVw-1  :   0]  credit_per_port_next    [P_1-1    :   0];
205
    reg     [BVw-1  :   0]  credit_per_port         [P_1-1    :   0];
206
    wire    [P_1-1  :   0]  credit_increased_per_port;
207
    wire    [P_1-1  :   0]  credit_decreased_per_port;
208
    wire    [P_1-1  :   0]  conjestion_cmp;
209
 
210
 
211
    genvar i;
212
    generate
213
        for(i=0;   i<P_1; i=i+1) begin :sep
214
           assign  credit_increased_per_port[i]=|credit_increased_all[((i+1)*V)-1   : i*V];
215
           assign  credit_decreased_per_port[i]=|credit_decreased_all[((i+1)*V)-1   : i*V];
216
        end//for
217
 
218
 
219
        for(i=0;   i<P; i=i+1'b1) begin :blk1
220
     always @(*) begin
221
            credit_per_port_next[i]  =   credit_per_port[i];
222
            if(credit_increased_per_port[i]  & ~credit_decreased_per_port[i]) begin
223
                credit_per_port_next[i]  = credit_per_port[i]+1'b1;
224
            end else if (~credit_increased_per_port[i]   & credit_decreased_per_port[i])begin
225
                credit_per_port_next[i]  = credit_per_port[i]-1'b1;
226
            end
227
        end//for
228
    end//always
229
 
230
  for(i=0;    i<P_1; i=i+1'b1) begin :blk2
231
`ifdef SYNC_RESET_MODE
232
    always @ (posedge clk )begin
233
`else
234
    always @ (posedge clk or posedge reset)begin
235
`endif
236
 
237
            if(reset) begin
238
                credit_per_port[i]   <=  C_INT;
239
            end else begin
240
                credit_per_port[i]   <=  credit_per_port_next[i];
241
            end
242
        end//for
243
    end
244
 
245
 endgenerate//always
246
 
247
    /*******************
248
pre-sel[xy]
249
    y
250
1   |   3
251
    |
252
 -------x
253
 
254
    |
255
 
256
 
257
pre_sel
258
             0: xdir
259
             1: ydir
260
*******************/
261
 
262
    //location in counter  
263
    localparam X_PLUS   =   0,//EAST
264
               Y_PLUS   =   1,//NORTH
265
               X_MINUS  =   2,//WEST
266
               Y_MINUS  =   3;//SOUTH
267
 
268
    //location in port-pre-select           
269
    localparam X_PLUS_Y_PLUS  = 3,
270
               X_MINUS_Y_PLUS = 1,
271
               X_PLUS_Y_MINUS = 2,
272
               X_MINUS_Y_MINUS= 0;
273
 
274
    assign conjestion_cmp[X_PLUS_Y_PLUS]  = (credit_per_port[X_PLUS]   <  credit_per_port[Y_PLUS]);
275
    assign conjestion_cmp[X_MINUS_Y_PLUS] = (credit_per_port[X_MINUS]  <  credit_per_port[Y_PLUS]);
276
    assign conjestion_cmp[X_PLUS_Y_MINUS] = (credit_per_port[X_PLUS]   <  credit_per_port[Y_MINUS]);
277
    assign conjestion_cmp[X_MINUS_Y_MINUS]= (credit_per_port[X_MINUS]  <  credit_per_port[Y_MINUS]);
278
 
279
  // assign port_pre_sel = conjestion_cmp;
280
 
281
 
282
 
283
     assign port_pre_sel = conjestion_cmp;
284
 
285
 
286
 
287
 endmodule
288
 
289
 
290
/*********************************
291
 
292
port_presel_based_dst_routers_ovc
293
    CONGESTION_INDEX==2,3,4,5,6,7,9
294
********************************/
295
 
296
 
297
module mesh_torus_port_presel_based_dst_routers_vc #(
298
    parameter PPSw=4,
299
    parameter P=5,
300
    parameter CONGw=2 //congestion width per port
301
)
302
(
303
    port_pre_sel,
304
    congestion_in_all,
305
    reset,clk
306
);
307
 
308
 
309
    localparam  CONG_ALw=       CONGw* P;   //  congestion width per router;
310
 
311
    localparam XDIR =1'b0;
312
    localparam YDIR =1'b1;
313
 
314
//location in port-pre-select           
315
    localparam X_PLUS_Y_PLUS  = 3,
316
               X_MINUS_Y_PLUS = 1,
317
               X_PLUS_Y_MINUS = 2,
318
               X_MINUS_Y_MINUS= 0;
319
 
320
 
321
 
322
    input   [CONG_ALw-1 :   0]  congestion_in_all;
323
    output  [PPSw-1      :   0]  port_pre_sel;
324
    input reset,clk;
325
 
326
    wire    [CONGw-1    :   0]  congestion_x_plus,congestion_y_plus,congestion_x_min,congestion_y_min;
327
    wire    [PPSw-1      :   0]  conjestion_cmp;
328
 
329
 
330
    assign {congestion_y_min,congestion_x_min,congestion_y_plus,congestion_x_plus} = congestion_in_all[(CONGw*5)-1   : CONGw];
331
 
332
/****************
333
    congestion:
334
             0: list congested
335
             3: most congested
336
    pre_sel
337
             0: xdir
338
             1: ydir
339
*******************/
340
    assign conjestion_cmp[X_PLUS_Y_PLUS]  = (congestion_x_plus  >  congestion_y_plus)? YDIR : XDIR;
341
    assign conjestion_cmp[X_MINUS_Y_PLUS] = (congestion_x_min   >  congestion_y_plus)? YDIR : XDIR;
342
    assign conjestion_cmp[X_PLUS_Y_MINUS] = (congestion_x_plus  >  congestion_y_min)?  YDIR : XDIR;
343
    assign conjestion_cmp[X_MINUS_Y_MINUS]= (congestion_x_min   >  congestion_y_min)?  YDIR : XDIR;
344
 
345
 
346
 
347
 
348
   // assign port_pre_sel = conjestion_cmp;
349
   register #(.W(PPSw)) reg1 (.in(conjestion_cmp ), .reset(reset), .clk(clk), .out(port_pre_sel));
350
 
351
 
352
endmodule
353
 
354
 
355
/*********************************
356
 
357
port_presel_based_dst_routers_ovc
358
    CONGESTION_INDEX==8,10
359
********************************/
360
 
361
 
362
module port_presel_based_dst_routers_ovc #(
363
    parameter PPSw=4,
364
    parameter P=5,
365
    parameter V=4,
366
    parameter CONGw=2 //congestion width per port
367
)
368
(
369
    port_pre_sel,
370
    congestion_in_all
371
);
372
 
373
 
374
    localparam  P_1     =       P-1,
375
                CONG_ALw=       CONGw* P;   //  congestion width per router;
376
 
377
 
378
    input   [CONG_ALw-1 :   0]  congestion_in_all;
379
    output  [PPSw-1      :   0]  port_pre_sel;
380
 
381
 
382
 
383
 
384
   /*************
385
        N
386
     Q1 | Q3
387
   w--------E
388
     Q0 | Q2
389
        S
390
   ***************/
391
 
392
    localparam Q3   = 3,
393
               Q1   = 1,
394
               Q2   = 2,
395
               Q0   = 0;
396
 
397
    localparam EAST =   0,
398
               NORTH=   1,
399
               WEST =   2,
400
               SOUTH=   3;
401
 
402
    localparam XDIR =1'b0,
403
               YDIR =1'b1;
404
 
405
    wire [CONGw-1   :   0] congestion_in [P_1-1 :   0];
406
    assign {congestion_in[SOUTH],congestion_in[WEST],congestion_in[NORTH],congestion_in[EAST]} = congestion_in_all[CONG_ALw-1   : CONGw];
407
 
408
    wire [(CONGw/2)-1   :   0]cong_from_west_Q1   , cong_from_west_Q0;
409
    wire [(CONGw/2)-1   :   0]cong_from_south_Q0  , cong_from_south_Q2;
410
    wire [(CONGw/2)-1   :   0]cong_from_east_Q2   , cong_from_east_Q3;
411
    wire [(CONGw/2)-1   :   0]cong_from_north_Q3  , cong_from_north_Q1;
412
 
413
 
414
 
415
    assign {cong_from_west_Q1   ,cong_from_west_Q0  }=congestion_in[WEST];
416
    assign {cong_from_south_Q0  ,cong_from_south_Q2 }=congestion_in[SOUTH];
417
    assign {cong_from_east_Q2   ,cong_from_east_Q3  }=congestion_in[EAST];
418
    assign {cong_from_north_Q3  ,cong_from_north_Q1 }=congestion_in[NORTH];
419
 
420
    /****************
421
    congestion:
422
             0: list congested
423
             3: most congested
424
    pre_sel
425
             0: xdir
426
             1: ydir
427
    *******************/
428
     wire    [P_1-1      :   0]  conjestion_cmp;
429
 
430
 
431
 
432
    assign conjestion_cmp[Q3]  =  (cong_from_east_Q3  >  cong_from_north_Q3)? YDIR :XDIR;
433
    assign conjestion_cmp[Q2]  =  (cong_from_east_Q2  >  cong_from_south_Q2)? YDIR :XDIR;
434
    assign conjestion_cmp[Q1]  =  (cong_from_west_Q1  >  cong_from_north_Q1)? YDIR :XDIR;
435
    assign conjestion_cmp[Q0]  =  (cong_from_west_Q0  >  cong_from_south_Q0)? YDIR :XDIR;
436
 
437
 
438
 
439
 
440
 
441
 
442
        assign port_pre_sel = conjestion_cmp;
443
 
444
 
445
 
446
 
447
 
448
endmodule
449
 
450
/***********************
451
 
452
    port_pre_sel_gen
453
 
454
 
455
************************/
456
 
457
 
458
 
459
module port_pre_sel_gen #(
460
    parameter PPSw=4,
461
    parameter P=5,
462
    parameter V=4,
463
    parameter B=4,
464
    parameter CONGESTION_INDEX=2,
465
    parameter CONGw=2,
466
    parameter ROUTE_TYPE="ADAPTIVE",
467
    parameter [V-1  :   0] ESCAP_VC_MASK= 4'b0001
468
 
469
)(
470
    port_pre_sel,
471
    ovc_status,
472
    ovc_avalable_all,
473
    congestion_in_all,
474
    credit_decreased_all,
475
    credit_increased_all,
476
    reset,
477
    clk
478
 
479
);
480
 
481
    localparam P_1      =   P-1,
482
               PV       =   P   *   V,
483
               CONG_ALw =   CONGw * P;
484
 
485
    output [PPSw-1      :   0]  port_pre_sel;
486
    input  [PV-1        :   0]  ovc_status;
487
    input  [PV-1        :   0]  ovc_avalable_all;
488
    input  [PV-1        :   0]  credit_decreased_all;
489
    input  [PV-1        :   0]  credit_increased_all;
490
    input  [CONG_ALw-1 :    0]  congestion_in_all;
491
    input  reset,clk;
492
 
493
 
494
generate
495
    /* verilator lint_off WIDTH */
496
    if(ROUTE_TYPE    ==   "DETERMINISTIC") begin : detrministic
497
    /* verilator lint_on WIDTH */
498
       assign port_pre_sel = {PPSw{1'b0}};
499
 
500
    end else begin : adaptive
501
        if(CONGESTION_INDEX==0) begin:indx0
502
 
503
                port_presel_based_dst_ports_vc #(
504
                    .PPSw(PPSw),
505
                    .P(P),
506
                    .V(V)
507
 
508
                )
509
                port_presel_gen
510
                (
511
                    .ovc_status (ovc_status [PV-1   :   V]),
512
                    .port_pre_sel(port_pre_sel)
513
 
514
 
515
                );
516
 
517
        end else if(CONGESTION_INDEX==1) begin :indx1
518
 
519
                port_presel_based_dst_ports_credit #(
520
                    .PPSw(PPSw),
521
                    .P(P),
522
                    .V(V),
523
                    .B(B)
524
                )
525
                port_presel_gen
526
                (
527
                    .credit_decreased_all   (credit_decreased_all   [PV-1  :   V]),//remove local port signals
528
                    .credit_increased_all   (credit_increased_all   [PV-1  :   V]),
529
                    .port_pre_sel           (port_pre_sel),
530
                    .clk                    (clk),
531
                    .reset                  (reset)
532
                );
533
        end else if (   (CONGESTION_INDEX==2) || (CONGESTION_INDEX==3) ||
534
                        (CONGESTION_INDEX==4) || (CONGESTION_INDEX==5) ||
535
                        (CONGESTION_INDEX==6) || (CONGESTION_INDEX==7) ||
536
                        (CONGESTION_INDEX==9) ||
537
                        (CONGESTION_INDEX==11)|| (CONGESTION_INDEX==12))      begin :dst_vc
538
 
539
                mesh_torus_port_presel_based_dst_routers_vc #(
540
                    .PPSw(PPSw),
541
                    .P(P),
542
                    .CONGw(CONGw)
543
                )
544
                port_presel_gen
545
                (
546
                    .congestion_in_all(congestion_in_all),
547
                    .port_pre_sel(port_pre_sel),
548
                    .reset(reset),
549
                    .clk(clk)
550
                );
551
          end else if((CONGESTION_INDEX==8) || (CONGESTION_INDEX==10) )begin :dst_ovc
552
 
553
            port_presel_based_dst_routers_ovc #(
554
                .PPSw(PPSw),
555
                .P(P),
556
                .V(V),
557
                .CONGw(CONGw)
558
            )
559
             port_presel_gen
560
            (
561
                .port_pre_sel(port_pre_sel),
562
                .congestion_in_all(congestion_in_all)
563
            );
564
 
565
 
566
        end
567
    end
568
    endgenerate
569
endmodule
570
 
571
 
572
 
573
                                                    /*********************************
574
 
575
                                                            congestion_out_gen
576
 
577
                                                    ********************************/
578
 
579
 
580
 
581
 
582
 
583
 /*******************************
584
 
585
       congestion based on number of active ivc
586
            CONGESTION_INDEX==2  CONGw   =   2
587
            CONGESTION_INDEX==3  CONGw   =   3
588
 ********************************/
589
 module congestion_out_based_ivc_req #(
590
    parameter P=5,
591
    parameter V=4,
592
    parameter CONGw   =   2 //congestion width per port
593
 
594
 )
595
 (
596
    ivc_request_all,
597
    congestion_out_all
598
 
599
 );
600
 
601
 
602
    localparam  PV      =   (V     *  P),
603
                CONG_ALw=   (CONGw* P);   //  congestion width per router;
604
 
605
 
606
 
607
 
608
    input       [PV-1       :   0]  ivc_request_all;
609
    output      [CONG_ALw-1 :   0]  congestion_out_all;
610
 
611
 
612
    wire    [CONGw-1    :   0]  congestion_out ;
613
 
614
    parallel_count_normalize #(
615
        .INw    (PV),
616
        .OUTw   (CONGw)
617
    )
618
    ivc_req_counter
619
    (
620
        .in     (ivc_request_all),
621
        .out    (congestion_out)
622
 
623
    );
624
 
625
 
626
 
627
    assign  congestion_out_all = {P{congestion_out}};
628
 
629
endmodule
630
 
631
 
632
 
633
 
634
/*******************************
635
 
636
       congestion based on number of
637
 active ivc requests that are not granted
638
            CONGESTION_INDEX==4  CONGw   =   2
639
            CONGESTION_INDEX==5  CONGw   =   3
640
 ********************************/
641
 module congestion_out_based_ivc_notgrant #(
642
    parameter P=5,
643
    parameter V=4,
644
    parameter CONGw=2 //congestion width per port
645
 
646
 )
647
 (
648
    ivc_request_all,
649
    congestion_out_all,
650
    ivc_num_getting_sw_grant,
651
    clk,
652
    reset
653
 
654
 );
655
 
656
    function integer log2;
657
      input integer number; begin
658
         log2=(number <=1) ? 1: 0;
659
         while(2**log2<number) begin
660
            log2=log2+1;
661
         end
662
      end
663
    endfunction // log2 
664
 
665
    localparam  PV      =   (V     *  P),
666
                CONG_ALw=   CONGw* P,   //  congestion width per router;
667
                IVC_CNTw=   log2(PV+1);
668
 
669
 
670
 
671
 
672
    input       [PV-1       :   0]  ivc_request_all,ivc_num_getting_sw_grant;
673
    output      [CONG_ALw-1 :   0]  congestion_out_all;
674
    input                           clk,reset;
675
 
676
    wire    [IVC_CNTw-1 :   0]  ivc_req_num;
677
    reg     [CONGw-1    :   0]  congestion_out ;
678
    reg     [PV-1       :   0]  ivc_request_not_granted;
679
 
680
`ifdef SYNC_RESET_MODE
681
    always @ (posedge clk )begin
682
`else
683
    always @ (posedge clk or posedge reset)begin
684
`endif
685
        if(reset) begin
686
            ivc_request_not_granted <= 0;
687
        end else begin
688
            ivc_request_not_granted <= ivc_request_all & ~(ivc_num_getting_sw_grant);
689
        end//reset
690
    end //always
691
 
692
 
693
    accumulator #(
694
        .INw(PV),
695
        .OUTw(IVC_CNTw),
696
        .NUM(PV)
697
    )
698
    ivc_req_counter
699
    (
700
        .in_all(ivc_request_not_granted),
701
        .out(ivc_req_num)
702
    );
703
 
704
    /*
705
    parallel_counter #(
706
        .IN_WIDTH(PV)
707
    )
708
    ivc_req_counter
709
    (
710
        .in(ivc_request_not_granted),
711
        .out(ivc_req_num)
712
    );
713
    */
714
 
715
 
716
    generate
717
    if(CONGw==2)begin :w2
718
        always @(*)begin
719
            if      (ivc_req_num <= (PV/10) )   congestion_out=2'd0;    //0~10
720
            else if (ivc_req_num <= (PV/5)  )   congestion_out=2'd1;    //10~20
721
            else if (ivc_req_num <= (PV/2)  )   congestion_out=2'd2;    //20~50
722
            else                                congestion_out=2'd3;    //50~100
723
        end
724
    end else begin :w3 // CONGw==3
725
        always @(*)begin
726
            if      (ivc_req_num < ((PV*1)/8) )   congestion_out=3'd0;
727
            else if (ivc_req_num < ((PV*2)/8) )   congestion_out=3'd1;
728
            else if (ivc_req_num < ((PV*3)/8) )   congestion_out=3'd2;
729
            else if (ivc_req_num < ((PV*4)/8) )   congestion_out=3'd3;
730
            else if (ivc_req_num < ((PV*5)/8) )   congestion_out=3'd4;
731
            else if (ivc_req_num < ((PV*6)/8) )   congestion_out=3'd5;
732
            else if (ivc_req_num < ((PV*7)/8) )   congestion_out=3'd6;
733
            else                                  congestion_out=3'd7;
734
        end
735
    end
736
    endgenerate
737
    assign  congestion_out_all = {P{congestion_out}};
738
 
739
endmodule
740
 
741
 
742
 
743
 
744
 
745
 
746
/*******************************
747
 
748
     congestion based on number of
749
 availabe ovc in all 3ports of next router
750
            CONGESTION_INDEX==6 CONGw=2
751
            CONGESTION_INDEX==7 CONGw=3
752
 ********************************/
753
 module congestion_out_based_3port_avb_ovc #(
754
    parameter P=5,
755
    parameter V=4,
756
    parameter CONGw=2 //congestion width per port
757
 
758
 )
759
 (
760
    ovc_avalable_all,
761
    congestion_out_all
762
 
763
 );
764
 
765
 
766
    localparam  P_1     =   P-1,
767
                PV      =   (V     *  P),
768
                CONG_ALw=   CONGw* P;
769
 
770
 
771
   localparam EAST      =0,
772
              NORTH     =1,
773
              WEST      =2,
774
              SOUTH     =3;
775
 
776
    localparam  CNT_Iw = 3*V;
777
 
778
    input       [PV-1       :   0]  ovc_avalable_all;
779
    output      [CONG_ALw-1 :   0]  congestion_out_all;
780
 
781
 
782
 
783
    wire    [V-1        :   0] ovc_not_avb [P_1-1  :   0];
784
    wire    [CNT_Iw-1   :   0] counter_in   [P_1-1  :   0];
785
    wire    [CONGw-1    :   0] congestion_out[P_1-1  :   0];
786
 
787
    assign  {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH],  ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1     :   V];
788
    assign  counter_in[EAST]    ={ovc_not_avb[NORTH],ovc_not_avb[WEST]  ,ovc_not_avb[SOUTH]};
789
    assign  counter_in[NORTH]   ={ovc_not_avb[EAST] ,ovc_not_avb[WEST]  ,ovc_not_avb[SOUTH]};
790
    assign  counter_in[WEST]    ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[SOUTH]};
791
    assign  counter_in[SOUTH]   ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[WEST]};
792
 
793
 
794
 
795
    genvar i;
796
    generate
797
    for (i=0;i<4;i=i+1) begin :lp
798
 
799
        parallel_count_normalize #(
800
            .INw(CNT_Iw),
801
            .OUTw(CONGw)
802
        )
803
        ovc_avb_east
804
        (
805
            .in(counter_in[i]),
806
            .out(congestion_out[i])
807
        );
808
 
809
 
810
    end
811
    endgenerate
812
 
813
 
814
 
815
    assign  congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
816
 
817
endmodule
818
 
819
 
820
 
821
 
822
 
823
 
824
 
825
/*******************************
826
 
827
     congestion based on number of
828
 availabe ovc in destination router
829
            CONGESTION_INDEX==8  CONGw=2
830
 ********************************/
831
 
832
 
833
 module congestion_out_based_avb_ovc_w2 #(
834
    parameter P=5,
835
    parameter V=4
836
 
837
 
838
 )
839
 (
840
    ovc_avalable_all,
841
    congestion_out_all
842
 
843
 );
844
   localparam CONGw=2; //congestion width per port
845
 
846
    localparam  P_1     =   P-1,
847
                PV      =   (V     *  P),
848
                CONG_ALw=   CONGw* P,
849
                CNT_Iw = 2*V;
850
 
851
 
852
 
853
 
854
 
855
    input       [PV-1       :   0]  ovc_avalable_all;
856
    output      [CONG_ALw-1 :   0]  congestion_out_all;
857
 
858
   /*************
859
        N
860
     Q1 | Q3
861
   w--------E
862
     Q0 | Q2
863
        S
864
   ***************/
865
 
866
    localparam Q3   = 3,
867
               Q1   = 1,
868
               Q2   = 2,
869
               Q0   = 0;
870
 
871
    localparam EAST =   0,
872
               NORTH=   1,
873
               WEST =   2,
874
               SOUTH=   3;
875
 
876
 
877
 
878
 
879
 
880
 
881
    wire    [V-1        :   0] ovc_not_avb      [P_1-1  :   0];
882
    wire    [CNT_Iw-1   :   0] counter_in       [P_1-1  :   0];
883
    wire    [CONGw-1    :   0] congestion_out   [P_1-1  :   0];
884
    wire    [P_1-1      :   0] threshold;
885
 
886
 
887
    assign  {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH],  ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1     :   V];
888
 
889
    assign  counter_in[Q3]    ={ovc_not_avb[EAST ],ovc_not_avb[NORTH]};
890
    assign  counter_in[Q1]    ={ovc_not_avb[NORTH],ovc_not_avb[WEST ]};
891
    assign  counter_in[Q2]    ={ovc_not_avb[SOUTH],ovc_not_avb[EAST ]};
892
    assign  counter_in[Q0]    ={ovc_not_avb[WEST ],ovc_not_avb[SOUTH]};
893
 
894
    genvar i;
895
    generate
896
    for (i=0;i<4;i=i+1) begin :lp
897
 
898
        parallel_count_normalize #(
899
            .INw(CNT_Iw),
900
            .OUTw(1)
901
        )
902
        ovc_not_avb_cnt
903
        (
904
            .in(counter_in[i]),
905
            .out(threshold[i])
906
        );
907
 
908
 
909
    end
910
    endgenerate
911
 
912
 
913
 
914
 
915
 
916
 
917
    assign congestion_out[EAST]     = {threshold[Q1],threshold[Q0]};
918
    assign congestion_out[NORTH]    = {threshold[Q0],threshold[Q2]};
919
    assign congestion_out[WEST]     = {threshold[Q2],threshold[Q3]};
920
    assign congestion_out[SOUTH]    = {threshold[Q3],threshold[Q1]};
921
 
922
    assign  congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
923
 
924
endmodule
925
 
926
 
927
 
928
 
929
 
930
 
931
/*******************************
932
 
933
     congestion based on number of
934
 availabe ovc in destination router
935
            CONGESTION_INDEX==9  CONGw=3
936
 ********************************/
937
 
938
 module congestion_out_based_avb_ovc_w3 #(
939
    parameter P=5,
940
    parameter V=4
941
 
942
 
943
 )
944
 (
945
    ovc_avalable_all,
946
    congestion_out_all
947
 
948
 );
949
   localparam CONGw=3; //congestion width per port
950
 
951
    localparam  P_1     =   P-1,
952
                PV      =   (V     *  P),
953
                CONG_ALw=   CONGw* P;
954
 
955
 
956
   localparam EAST      =0,
957
              NORTH     =1,
958
              WEST      =2,
959
              SOUTH     =3;
960
 
961
 
962
 
963
    input       [PV-1       :   0]  ovc_avalable_all;
964
    output      [CONG_ALw-1 :   0]  congestion_out_all;
965
 
966
 
967
 
968
    wire    [V-1        :   0] ovc_not_avb [P_1-1  :   0];
969
    wire    [CONGw-1    :   0] congestion_out[P_1-1  :   0];
970
 
971
    wire [P_1-1  :   0] threshold;
972
 
973
    assign  {ovc_not_avb[SOUTH],  ovc_not_avb[WEST], ovc_not_avb[NORTH],   ovc_not_avb[EAST]}=~ovc_avalable_all[PV-1     :   V];
974
 
975
 
976
 
977
 
978
    genvar i;
979
    generate
980
 
981
 
982
    for (i=0;i<4;i=i+1) begin :lp
983
 
984
        parallel_count_normalize #(
985
            .INw(V),
986
            .OUTw(1)
987
        )
988
        ovc_avb_east
989
        (
990
            .in(ovc_not_avb[i]),
991
            .out(threshold[i])
992
        );
993
 
994
 
995
    end
996
    endgenerate
997
 
998
    assign congestion_out[EAST]     = {threshold[NORTH],threshold[WEST ],threshold[SOUTH]};
999
    assign congestion_out[NORTH]    = {threshold[WEST ],threshold[SOUTH],threshold[EAST ]};
1000
    assign congestion_out[WEST]     = {threshold[SOUTH],threshold[EAST ],threshold[NORTH]};
1001
    assign congestion_out[SOUTH]    = {threshold[EAST ],threshold[NORTH],threshold[WEST ]};
1002
 
1003
    assign  congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
1004
 
1005
endmodule
1006
 
1007
 
1008
/*******************************
1009
 
1010
     congestion based on number of
1011
 availabe ovc in destination router
1012
            CONGESTION_INDEX==10  CONGw=4
1013
 ********************************/
1014
 module congestion_out_based_avb_ovc_w4 #(
1015
    parameter P=5,
1016
    parameter V=4
1017
 
1018
 
1019
 )
1020
 (
1021
    ovc_avalable_all,
1022
    congestion_out_all
1023
 
1024
 );
1025
   localparam CONGw=4; //congestion width per port
1026
 
1027
    localparam  P_1     =   P-1,
1028
                PV      =   (V     *  P),
1029
                CONG_ALw=   CONGw* P,
1030
                CNT_Iw = 2*V;
1031
 
1032
 
1033
 
1034
 
1035
    input       [PV-1       :   0]  ovc_avalable_all;
1036
    output      [CONG_ALw-1 :   0]  congestion_out_all;
1037
 
1038
 
1039
 
1040
 
1041
    /*************
1042
        N
1043
     Q1 | Q3
1044
   w--------E
1045
     Q0 | Q2
1046
        S
1047
   ***************/
1048
 
1049
    localparam Q3   = 3,
1050
               Q1   = 1,
1051
               Q2   = 2,
1052
               Q0   = 0;
1053
 
1054
    localparam EAST =   0,
1055
               NORTH=   1,
1056
               WEST =   2,
1057
               SOUTH=   3;
1058
 
1059
 
1060
 
1061
 
1062
 
1063
    wire    [V-1        :   0] ovc_not_avb      [P_1-1  :   0];
1064
    wire    [CNT_Iw-1   :   0] counter_in       [P_1-1  :   0];
1065
    wire    [CONGw-1    :   0] congestion_out   [P_1-1  :   0];
1066
    wire    [1          :   0] threshold        [P_1-1  :   0];
1067
 
1068
 
1069
    assign  {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH],  ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1     :   V];
1070
 
1071
    assign  counter_in[Q3]    ={ovc_not_avb[EAST ],ovc_not_avb[NORTH]};
1072
    assign  counter_in[Q1]    ={ovc_not_avb[NORTH],ovc_not_avb[WEST ]};
1073
    assign  counter_in[Q2]    ={ovc_not_avb[SOUTH],ovc_not_avb[EAST ]};
1074
    assign  counter_in[Q0]    ={ovc_not_avb[WEST ],ovc_not_avb[SOUTH]};
1075
 
1076
 
1077
    genvar i;
1078
    generate
1079
    for (i=0;i<4;i=i+1) begin :lp
1080
 
1081
        parallel_count_normalize #(
1082
            .INw(CNT_Iw),
1083
            .OUTw(2)
1084
        )
1085
        ovc_not_avb_cnt
1086
        (
1087
            .in(counter_in[i]),
1088
            .out(threshold[i])
1089
        );
1090
 
1091
 
1092
    end
1093
    endgenerate
1094
 
1095
 
1096
 
1097
 
1098
 
1099
 
1100
    assign congestion_out[EAST]     = {threshold[Q1],threshold[Q0]};
1101
    assign congestion_out[NORTH]    = {threshold[Q0],threshold[Q2]};
1102
    assign congestion_out[WEST]     = {threshold[Q2],threshold[Q3]};
1103
    assign congestion_out[SOUTH]    = {threshold[Q3],threshold[Q1]};
1104
 
1105
    assign  congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
1106
 
1107
endmodule
1108
 
1109
 
1110
 
1111
 
1112
/*******************************
1113
 
1114
    congestion based on number of
1115
    availabe ovc and not granted
1116
        ivc in next router
1117
    CONGESTION_INDEX==11 CONGw=2
1118
    CONGESTION_INDEX==12 CONGw=3
1119
 
1120
 
1121
 ********************************/
1122
 module congestion_out_based_avb_ovc_not_granted_ivc #(
1123
    parameter P=5,
1124
    parameter V=4,
1125
    parameter CONGw=3 //congestion width per port
1126
 
1127
 )
1128
 (
1129
    ovc_avalable_all,
1130
    ivc_request_all,
1131
    ivc_num_getting_sw_grant,
1132
    clk,
1133
    reset,
1134
    congestion_out_all
1135
 
1136
 );
1137
 
1138
 
1139
    function integer log2;
1140
      input integer number; begin
1141
         log2=(number <=1) ? 1: 0;
1142
         while(2**log2<number) begin
1143
            log2=log2+1;
1144
         end
1145
      end
1146
    endfunction // log2 
1147
 
1148
 
1149
 
1150
 
1151
    localparam  P_1         =   P-1,
1152
                PV          =   (V     *  P),
1153
                CONG_ALw    =   CONGw* P,
1154
                CNT_Iw      =   3*V,
1155
                CNT_Ow      =   log2((3*V)+1),
1156
                CNG_w       =   log2((6*V)+1),
1157
                CNT_Vw      =   log2(V+1),
1158
                EAST        =   0,
1159
                NORTH       =   1,
1160
                WEST        =   2,
1161
                SOUTH       =   3;
1162
 
1163
 
1164
 
1165
    input       [PV-1       :   0]  ovc_avalable_all;
1166
    output      [CONG_ALw-1 :   0]  congestion_out_all;
1167
    input       [PV-1       :   0]  ivc_request_all,ivc_num_getting_sw_grant;
1168
 
1169
    input                           reset,clk;
1170
 
1171
    // counting not available ovc            
1172
    wire    [V-1        :   0] ovc_not_avb  [P_1-1  :   0];
1173
    wire    [CNT_Iw-1   :   0] counter_in   [P_1-1  :   0];
1174
    wire    [CNT_Ow-1   :   0] counter_o    [P_1-1  :   0];
1175
    wire    [CONGw-1    :   0] congestion_out[P_1-1  :   0];
1176
 
1177
    assign  {ovc_not_avb[SOUTH], ovc_not_avb[WEST], ovc_not_avb[NORTH],  ovc_not_avb[EAST]}= ~ovc_avalable_all[PV-1     :   V];
1178
    assign  counter_in[EAST]    ={ovc_not_avb[NORTH],ovc_not_avb[WEST]  ,ovc_not_avb[SOUTH]};
1179
    assign  counter_in[NORTH]   ={ovc_not_avb[EAST] ,ovc_not_avb[WEST]  ,ovc_not_avb[SOUTH]};
1180
    assign  counter_in[WEST]    ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[SOUTH]};
1181
    assign  counter_in[SOUTH]   ={ovc_not_avb[EAST] ,ovc_not_avb[NORTH] ,ovc_not_avb[WEST]};
1182
 
1183
    // counting not granted requests
1184
    reg     [PV-1       :   0]  ivc_request_not_granted;
1185
    wire    [V-1        :   0]  ivc_not_grnt  [P_1-1  :   0];
1186
    wire    [CNT_Vw-1   :   0]  ivc_not_grnt_num [P_1-1  :   0];
1187
 
1188
`ifdef SYNC_RESET_MODE
1189
    always @ (posedge clk )begin
1190
`else
1191
    always @ (posedge clk or posedge reset)begin
1192
`endif
1193
        if(reset) begin
1194
            ivc_request_not_granted <= 0;
1195
        end else begin
1196
            ivc_request_not_granted <= ivc_request_all & ~(ivc_num_getting_sw_grant);
1197
        end//reset
1198
    end //always
1199
 
1200
 
1201
     assign  {ivc_not_grnt[SOUTH], ivc_not_grnt[WEST], ivc_not_grnt[NORTH],ivc_not_grnt[EAST]}= ivc_request_not_granted[PV-1     :   V];
1202
 
1203
 
1204
 
1205
    genvar i;
1206
    generate
1207
    for (i=0;i<4;i=i+1) begin :lp
1208
 
1209
   /*
1210
        parallel_counter #(
1211
            .IN_WIDTH(CNT_Iw)
1212
        )
1213
        ovc_counter
1214
        (
1215
            .in(counter_in[i]),
1216
            .out(counter_o[i])
1217
        );
1218
   */
1219
 
1220
       accumulator #(
1221
        .INw(CNT_Iw),
1222
        .OUTw(CNT_Ow),
1223
        .NUM(CNT_Iw)
1224
       )
1225
       ovc_counter
1226
       (
1227
        .in_all(counter_in[i]),
1228
        .out(counter_o[i])
1229
       );
1230
 
1231
 
1232
 
1233
     /*
1234
        parallel_counter #(
1235
            .IN_WIDTH(V)
1236
 
1237
        )
1238
        ivc_counter
1239
        (
1240
            .in(ivc_not_grnt[i]),
1241
            .out(ivc_not_grnt_num[i])
1242
        );
1243
  */
1244
 
1245
 
1246
       accumulator #(
1247
        .INw(V),
1248
        .OUTw(CNT_Vw),
1249
        .NUM(V)
1250
       )
1251
        ivc_counter
1252
        (
1253
        .in_all(ivc_not_grnt[i]),
1254
        .out(ivc_not_grnt_num[i])
1255
       );
1256
 
1257
 
1258
       wire [CNG_w-1 :   0] congestion_num  [P_1-1  :   0];
1259
 
1260
 
1261
       assign congestion_num [i]=  counter_o[i]+ ivc_not_grnt_num[i]+ {ivc_not_grnt_num[i],1'b0};
1262
 
1263
       normalizer #(
1264
            .MAX_IN(6*V),
1265
            .OUTw(CONGw)
1266
 
1267
        )norm
1268
        (
1269
            .in(congestion_num [i]),
1270
            .out(congestion_out[i])
1271
 
1272
         );
1273
 
1274
 
1275
    end//for
1276
    endgenerate
1277
 
1278
 
1279
 
1280
 
1281
    assign  congestion_out_all = {congestion_out[SOUTH],congestion_out[WEST],congestion_out[NORTH],congestion_out[EAST],{CONGw{1'b0}}};
1282
 
1283
endmodule
1284
 
1285
 
1286
 
1287
/**********************
1288
 
1289
    parallel_count_normalize
1290
 
1291
**********************/
1292
module parallel_count_normalize #(
1293
    parameter INw = 12,
1294
    parameter OUTw= 2
1295
 
1296
)(
1297
    in,
1298
    out
1299
 
1300
);
1301
 
1302
    function integer log2;
1303
      input integer number; begin
1304
         log2=(number <=1) ? 1: 0;
1305
         while(2**log2<number) begin
1306
            log2=log2+1;
1307
         end
1308
      end
1309
    endfunction // log2 
1310
 
1311
    input   [INw-1      :   0]  in;
1312
    output  [OUTw-1     :   0]  out;
1313
 
1314
    localparam CNTw = log2(INw+1);
1315
    wire    [CNTw-1     :    0] counter;
1316
/*
1317
    parallel_counter #(
1318
        .IN_WIDTH(INw)
1319
    )
1320
    ovc_avb_cnt
1321
    (
1322
        .in(in),
1323
        .out(counter)
1324
    );
1325
  */
1326
 
1327
      accumulator #(
1328
        .INw(INw),
1329
        .OUTw(CNTw),
1330
        .NUM(INw)
1331
      )
1332
      ovc_avb_cnt
1333
      (
1334
        .in_all(in),
1335
        .out(counter)
1336
      );
1337
 
1338
 
1339
    normalizer #(
1340
        .MAX_IN(INw),
1341
        .OUTw(OUTw)
1342
 
1343
    )norm
1344
    (
1345
        .in(counter),
1346
        .out(out)
1347
     );
1348
 
1349
 
1350
 endmodule
1351
 
1352
   /**************
1353
 
1354
   normalizer
1355
 
1356
   ***************/
1357
 
1358
 module normalizer #(
1359
    parameter MAX_IN= 10,
1360
    parameter OUTw= 2
1361
 
1362
 )(
1363
    in,
1364
    out
1365
 
1366
 );
1367
 
1368
 
1369
    function integer log2;
1370
      input integer number; begin
1371
         log2=(number <=1) ? 1: 0;
1372
         while(2**log2<number) begin
1373
            log2=log2+1;
1374
         end
1375
      end
1376
    endfunction // log2 
1377
 
1378
    localparam INw= log2(MAX_IN+1),
1379
               OUT_ON_HOT_NUM = 2**OUTw;
1380
 
1381
 
1382
    input   [INw-1   :   0]  in;
1383
    output  [OUTw-1  :   0]  out;
1384
 
1385
    wire [OUT_ON_HOT_NUM-1   :   0]  one_hot_out;
1386
 
1387
 
1388
 
1389
    genvar i;
1390
    generate
1391
    for(i=0;i< OUT_ON_HOT_NUM;i=i+1)begin :lp
1392
        /* verilator lint_off WIDTH */
1393
       if(i==0) begin : i0 assign one_hot_out[i]= (in<= (MAX_IN /OUT_ON_HOT_NUM)); end
1394
       else begin :ib0   assign one_hot_out[i]= ((in> ((MAX_IN *i)/OUT_ON_HOT_NUM)) &&  (in<= ((MAX_IN *(i+1))/OUT_ON_HOT_NUM))); end
1395
        /* verilator lint_on WIDTH */
1396
    end//for
1397
    endgenerate
1398
 
1399
 
1400
 
1401
    one_hot_to_bin#(
1402
        .ONE_HOT_WIDTH(OUT_ON_HOT_NUM)
1403
    )
1404
    conv
1405
    (
1406
        .one_hot_code(one_hot_out),
1407
        .bin_code(out)
1408
    );
1409
 
1410
 
1411
 endmodule
1412
 
1413
 
1414
 
1415
 
1416
 
1417
 
1418
 
1419
 
1420
 
1421
 
1422
 
1423
 
1424
 
1425
 
1426
/**************************
1427
 
1428
 
1429
        congestion_out_gen
1430
 
1431
 
1432
**************************/
1433
 
1434
 
1435
 
1436
 
1437
module congestion_out_gen #(
1438
    parameter P=5,
1439
    parameter V=4,
1440
    parameter ROUTE_TYPE ="ADAPTIVE",
1441
    parameter CONGESTION_INDEX=2,
1442
    parameter CONGw=2
1443
 
1444
)
1445
(
1446
   ivc_request_all,
1447
   ivc_num_getting_sw_grant,
1448
   ovc_avalable_all,
1449
   congestion_out_all,
1450
   clk,
1451
   reset
1452
);
1453
 
1454
localparam PV       = P*V,
1455
           CONG_ALw = CONGw* P;   //  congestion width per router;;
1456
 
1457
 input    [PV-1       :   0]  ovc_avalable_all;
1458
 input    [PV-1       :   0]  ivc_request_all;
1459
 input    [PV-1       :   0]  ivc_num_getting_sw_grant;
1460
 output  reg [CONG_ALw-1 :   0]  congestion_out_all;
1461
 input                        clk,reset;
1462
 
1463
  wire [CONG_ALw-1 :   0]  congestion_out_all_next;
1464
generate
1465
if(ROUTE_TYPE  !=  "DETERMINISTIC") begin :adpt
1466
        if((CONGESTION_INDEX==2) || (CONGESTION_INDEX==3)) begin :based_ivc
1467
           congestion_out_based_ivc_req #(
1468
               .P(P),
1469
               .V(V),
1470
               .CONGw(CONGw)
1471
           )
1472
           the_congestion_out_gen
1473
           (
1474
               .ivc_request_all(ivc_request_all),
1475
               .congestion_out_all(congestion_out_all_next)
1476
           );
1477
        end else if((CONGESTION_INDEX==4) || (CONGESTION_INDEX==5)) begin :based_ng_ivc
1478
 
1479
           congestion_out_based_ivc_notgrant #(
1480
               .P(P),
1481
               .V(V),
1482
               .CONGw(CONGw)
1483
           )
1484
           the_congestion_out_gen
1485
           (
1486
               .ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
1487
               .ivc_request_all(ivc_request_all),
1488
               .congestion_out_all(congestion_out_all_next),
1489
               .clk(clk),
1490
               .reset(reset)
1491
           );
1492
 
1493
        end else if  ((CONGESTION_INDEX==6) || (CONGESTION_INDEX==7)) begin :avb_ovc1
1494
 
1495
            congestion_out_based_3port_avb_ovc#(
1496
               .P(P),
1497
               .V(V),
1498
               .CONGw(CONGw)
1499
             )
1500
             the_congestion_out_gen
1501
             (
1502
                .ovc_avalable_all(ovc_avalable_all),
1503
                .congestion_out_all(congestion_out_all_next)
1504
              );
1505
 
1506
 
1507
       end  else if  (CONGESTION_INDEX==8) begin :indx8
1508
 
1509
 
1510
            congestion_out_based_avb_ovc_w2 #(
1511
                .P(P),
1512
                .V(V)
1513
            )
1514
            the_congestion_out_gen
1515
            (
1516
                .ovc_avalable_all(ovc_avalable_all),
1517
                .congestion_out_all(congestion_out_all_next)
1518
 
1519
            );
1520
         end  else if  (CONGESTION_INDEX==9) begin :indx9
1521
 
1522
            congestion_out_based_avb_ovc_w3 #(
1523
                .P(P),
1524
                .V(V)
1525
            )
1526
            the_congestion_out_gen
1527
            (
1528
                .ovc_avalable_all(ovc_avalable_all),
1529
                .congestion_out_all(congestion_out_all_next)
1530
 
1531
            );
1532
         end  else if  (CONGESTION_INDEX==10) begin :indx10
1533
 
1534
            congestion_out_based_avb_ovc_w4 #(
1535
                .P(P),
1536
                .V(V)
1537
            )
1538
            the_congestion_out_gen
1539
            (
1540
                .ovc_avalable_all(ovc_avalable_all),
1541
                .congestion_out_all(congestion_out_all_next)
1542
 
1543
            );
1544
 
1545
          end  else if  (CONGESTION_INDEX==11 || CONGESTION_INDEX==12) begin :indx11
1546
 
1547
            congestion_out_based_avb_ovc_not_granted_ivc #(
1548
                .P(P),
1549
                .V(V),
1550
                .CONGw(CONGw) //congestion width per port
1551
            )
1552
            the_congestion_out_gen
1553
            (
1554
                .ovc_avalable_all(ovc_avalable_all),
1555
                .ivc_request_all(ivc_request_all),
1556
                .ivc_num_getting_sw_grant(ivc_num_getting_sw_grant),
1557
                .clk(clk),
1558
                .reset(reset),
1559
                .congestion_out_all(congestion_out_all_next)
1560
            );
1561
 
1562
 
1563
        end  else begin :nocong assign  congestion_out_all_next = {CONG_ALw{1'bx}};   end
1564
 
1565
 
1566
    end else begin :dtrmn
1567
           assign  congestion_out_all_next = {CONG_ALw{1'bx}};
1568
 
1569
    end
1570
 
1571
endgenerate
1572
 
1573
`ifdef SYNC_RESET_MODE
1574
    always @ (posedge clk )begin
1575
`else
1576
    always @ (posedge clk or posedge reset)begin
1577
`endif
1578
                if(reset)begin
1579
                        congestion_out_all <= {CONG_ALw{1'b0}};
1580
                end else begin
1581
                        congestion_out_all <= congestion_out_all_next;
1582
 
1583
                end
1584
        end //always
1585
 
1586
 
1587
endmodule
1588
 
1589
 
1590
/*************************
1591
 
1592
    deadlock_detector
1593
 
1594
**************************/
1595
 
1596
module  deadlock_detector #(
1597
    parameter P=5,
1598
    parameter V=4,
1599
    parameter MAX_CLK = 16
1600
 
1601
)(
1602
    ivc_num_getting_sw_grant,
1603
    ivc_request_all,
1604
    reset,
1605
    clk,
1606
    detect
1607
 
1608
);
1609
 
1610
 
1611
    function integer log2;
1612
      input integer number; begin
1613
         log2=(number <=1) ? 1: 0;
1614
         while(2**log2<number) begin
1615
            log2=log2+1;
1616
         end
1617
      end
1618
    endfunction // log2 
1619
 
1620
 
1621
 
1622
 
1623
    localparam  PV      =  P*V,
1624
                CNTw    = log2(MAX_CLK);
1625
 
1626
 
1627
  input [PV-1   :   0]  ivc_num_getting_sw_grant, ivc_request_all;
1628
  input             reset,clk;
1629
  output            detect;
1630
 
1631
  reg   [CNTw-1 :   0]  counter         [V-1   :   0];
1632
  wire  [P-1    :   0]  counter_rst_gen [V-1   :   0];
1633
  wire  [P-1    :   0]  counter_en_gen  [V-1   :   0];
1634
  wire  [V-1    :   0]  counter_rst,counter_en,detect_gen;
1635
  reg   [PV-1   :   0]  ivc_num_getting_sw_grant_reg;
1636
 
1637
`ifdef SYNC_RESET_MODE
1638
    always @ (posedge clk )begin
1639
`else
1640
    always @ (posedge clk or posedge reset)begin
1641
`endif
1642
 
1643
    if(reset) begin
1644
          ivc_num_getting_sw_grant_reg  <= {PV{1'b0}};
1645
    end else begin
1646
          ivc_num_getting_sw_grant_reg  <= ivc_num_getting_sw_grant;
1647
    end
1648
  end
1649
 
1650
 //seperate all same virtual chanels requests
1651
 genvar i,j;
1652
 generate
1653
 for (i=0;i<V;i=i+1)begin:v_loop
1654
     for (j=0;j<P;j=j+1)begin :p_loop
1655
        assign counter_rst_gen[i][j]=ivc_num_getting_sw_grant_reg[j*V+i];
1656
        assign counter_en_gen [i][j]=ivc_request_all[j*V+i];
1657
    end//j
1658
    //sum all signals belong to the same VC
1659
    assign counter_rst[i]   =|counter_rst_gen[i];
1660
    assign counter_en[i]    =|counter_en_gen [i];
1661
    // generate the counter
1662
`ifdef SYNC_RESET_MODE
1663
    always @ (posedge clk )begin
1664
`else
1665
    always @ (posedge clk or posedge reset)begin
1666
`endif
1667
        if(reset) begin
1668
            counter[i]<={CNTw{1'b0}};
1669
        end else begin
1670
            if(counter_rst[i])      counter[i]<={CNTw{1'b0}};
1671
            else if(counter_en[i])  counter[i]<=counter[i]+1'b1;
1672
        end//reset
1673
    end//always
1674
    // check counters value to detect deadlock
1675
    assign detect_gen[i]=     (counter[i]== MAX_CLK-1);
1676
 
1677
 end//i
1678
 
1679
 assign detect=|detect_gen;
1680
 
1681
 
1682
 
1683
 endgenerate
1684
 
1685
 
1686
 
1687
 
1688
endmodule
1689
 
1690
 
1691
 
1692
 
1693
 
1694
 

powered by: WebSVN 2.1.0

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