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 54

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

powered by: WebSVN 2.1.0

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