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/] [mesh_torus_routting.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
/************************************
4
 
5
     mesh_torus_look_ahead_routing
6
 
7
*************************************/
8
 
9
module mesh_torus_look_ahead_routing #(
10
    parameter NX        =4,
11
    parameter NY        =4,
12
    parameter SW_LOC    =0,
13
    parameter TOPOLOGY  ="MESH",//"MESH","TORUS"
14
    parameter ROUTE_NAME="XY",// 
15
    parameter ROUTE_TYPE="DETERMINISTIC"// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE"
16
)
17
(
18
    current_x,  //current router x address
19
    current_y,  //current router y address
20
    dest_x,  // destination router x address          
21
    dest_y,  // destination router y address                  
22
    destport_encoded,   // current router destination port number       
23
    lkdestport_encoded, // look ahead destination port number
24
    reset,
25
    clk
26
);
27
 
28
     /* verilator lint_off WIDTH */
29
    localparam  P = (TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS")?  5:3;
30
     /* verilator lint_on WIDTH */
31
 
32
    function integer log2;
33
      input integer number; begin
34
         log2=(number <=1) ? 1: 0;
35
         while(2**log2<number) begin
36
            log2=log2+1;
37
         end
38
      end
39
    endfunction // log2 
40
 
41
    localparam  P_1     =   P-1,
42
                Xw      =   log2(NX),   // number of node in x axis
43
                Yw      =   log2(NY);    // number of node in y axis
44
 
45
    input   [Xw-1   :   0]  current_x;
46
    input   [Yw-1   :   0]  current_y;
47
    input   [Xw-1   :   0]  dest_x;
48
    input   [Yw-1   :   0]  dest_y;
49
    input   [P_1-1  :   0]  destport_encoded;
50
    output  [P_1-1  :   0]  lkdestport_encoded;
51
    input                   reset,clk;
52
 
53
    reg     [Xw-1   :   0]  destx_delayed;
54
    reg     [Yw-1   :   0]  desty_delayed;
55
    reg     [P_1-1  :   0]  destport_delayed;
56
 
57
 
58
    // routing algorithm
59
    generate
60
    /* verilator lint_off WIDTH */
61
    if(ROUTE_TYPE=="DETERMINISTIC") begin :dtrmst
62
    /* verilator lint_on WIDTH */
63
         mesh_torus_deterministic_look_ahead_routing #(
64
             .P(P),
65
             .NX(NX),
66
             .NY(NY),
67
             .SW_LOC(SW_LOC),
68
             .TOPOLOGY(TOPOLOGY),
69
             .ROUTE_NAME(ROUTE_NAME)
70
         )
71
         deterministic_look_ahead(
72
             .current_x(current_x),
73
             .current_y(current_y),
74
             .dest_x(destx_delayed),
75
             .dest_y(desty_delayed),
76
             .destport(destport_delayed),
77
             .lkdestport(lkdestport_encoded)
78
         );
79
 
80
    end else begin :adapt
81
        mesh_torus_adaptive_look_ahead_routing #(
82
            .P(P),
83
            .NX(NX),
84
            .NY(NY),
85
            .TOPOLOGY(TOPOLOGY),
86
            .ROUTE_NAME(ROUTE_NAME),
87
            .ROUTE_TYPE(ROUTE_TYPE)
88
         )
89
         adaptive_look_ahead
90
         (
91
            .current_x(current_x),
92
            .current_y(current_y),
93
            .dest_x(destx_delayed),
94
            .dest_y(desty_delayed),
95
            .destport_encoded(destport_delayed),
96
            .lkdestport_encoded(lkdestport_encoded)
97
         );
98
 
99
 
100
    end
101
    endgenerate
102
 
103
 
104
 `ifdef SYNC_RESET_MODE
105
    always @ (posedge clk )begin
106
`else
107
    always @ (posedge clk or posedge reset)begin
108
`endif
109
        if(reset)begin
110
            destx_delayed               <= {Xw{1'b0}};
111
            desty_delayed               <= {Yw{1'b0}};
112
            destport_delayed            <= {P_1{1'b0}};
113
        end else begin
114
            destx_delayed                <= dest_x;
115
            desty_delayed                <= dest_y;
116
            destport_delayed             <= destport_encoded;
117
        end//else reset
118
    end//always
119
 
120
endmodule
121
 
122
 
123
 
124
/************************************************
125
 
126
 
127
        deterministic_look_ahead_routing
128
 
129
 
130
**********************************************/
131
 
132
 
133
module  mesh_torus_deterministic_look_ahead_routing #(
134
    parameter P         =5,
135
    parameter NX        =4,
136
    parameter NY        =4,
137
    parameter SW_LOC    =0,
138
    parameter TOPOLOGY  ="MESH",//"MESH","TORUS"
139
    parameter ROUTE_NAME="XY"// "XY", "TRANC_XY"
140
  )
141
  (
142
        current_x,  //current router x address
143
        current_y,  //current router y address
144
        dest_x,  // destination router x address          
145
        dest_y,  // destination router y address                  
146
        destport,   // current router destination port number       
147
        lkdestport // look ahead destination port number
148
 
149
 );
150
 
151
 
152
    function integer log2;
153
      input integer number; begin
154
         log2=(number <=1) ? 1: 0;
155
         while(2**log2<number) begin
156
            log2=log2+1;
157
         end
158
      end
159
    endfunction // log2 
160
 
161
 
162
    localparam  P_1     =   P-1,
163
                Xw      =   log2(NX),   // number of node in x axis
164
                Yw      =   log2(NY);    // number of node in y axis
165
 
166
 
167
    input   [Xw-1   :   0]  current_x;
168
    input   [Yw-1   :   0]  current_y;
169
    input   [Xw-1   :   0]  dest_x;
170
    input   [Yw-1   :   0]  dest_y;
171
    input   [P_1-1  :   0]  destport;
172
    output  [P_1-1  :   0]  lkdestport;
173
 
174
 
175
 
176
    wire    [Xw-1   :   0]  next_x;
177
    wire    [Yw-1   :   0]  next_y;
178
 
179
  wire     [P-1    :   0]  destport_one_hot;
180
 
181
 generate
182
  /* verilator lint_off WIDTH */
183
 if (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "FMESH" ) begin: twoD
184
   /* verilator lint_on WIDTH */
185
    mesh_tori_decode_dstport decoder(
186
        .dstport_encoded(destport),
187
        .dstport_one_hot(destport_one_hot)
188
    );
189
 
190
 
191
   end else begin :oneD
192
    line_ring_decode_dstport decoder(
193
        .dstport_encoded(destport),
194
        .dstport_one_hot(destport_one_hot)
195
    );
196
 
197
 
198
   end
199
   endgenerate
200
 
201
 
202
    mesh_torus_next_router_addr_predictor #(
203
        .P(P),
204
        .TOPOLOGY(TOPOLOGY),
205
        .NX(NX),
206
        .NY(NY)
207
    )
208
    addr_predictor
209
    (
210
        .destport(destport_one_hot),
211
        .current_x(current_x),
212
        .current_y(current_y),
213
        .next_x(next_x),
214
        .next_y(next_y)
215
    );
216
 
217
 
218
   wire [P_1-1  :   0] lkdestport_encoded;
219
 
220
    mesh_torus_conventional_routing #(
221
        .TOPOLOGY(TOPOLOGY),
222
        .ROUTE_NAME(ROUTE_NAME),
223
        .ROUTE_TYPE("DETERMINISTIC"),
224
        .NX(NX),
225
        .NY(NY),
226
        .LOCATED_IN_NI(0)
227
    )
228
    conv_routing
229
    (
230
        .current_x(next_x),
231
        .current_y(next_y),
232
        .dest_x(dest_x),
233
        .dest_y(dest_y),
234
        .destport(lkdestport_encoded)
235
 
236
    );
237
 
238
    //take the value of a&b only.  x&y can be obtained from destport in the router
239
    assign lkdestport = lkdestport_encoded;//[1:0];
240
 
241
 
242
 
243
 endmodule
244
 
245
 
246
 
247
/************************************************
248
 
249
 
250
        adaptive_look_ahead_routing
251
 
252
 
253
**********************************************/
254
 
255
 
256
module  mesh_torus_adaptive_look_ahead_routing #(
257
    parameter P         =5,
258
    parameter NX        =4,
259
    parameter NY        =4,
260
    parameter TOPOLOGY  ="MESH",//"MESH","TORUS"
261
    parameter ROUTE_NAME="WEST_FIRST",
262
    parameter ROUTE_TYPE="DETERMINISTIC"
263
  )
264
  (
265
        current_x,  //current router x address
266
        current_y,  //current router y address
267
        dest_x,  // destination router x address          
268
        dest_y,  // destination router y address                  
269
        destport_encoded,   // current router destination port      
270
        lkdestport_encoded // look ahead destination port 
271
 
272
 );
273
 
274
 
275
    function integer log2;
276
      input integer number; begin
277
         log2=(number <=1) ? 1: 0;
278
         while(2**log2<number) begin
279
            log2=log2+1;
280
         end
281
      end
282
    endfunction // log2 
283
 
284
 
285
    localparam  P_1     =   P-1,
286
                Xw      =   log2(NX),   // number of node in x axis
287
                Yw      =   log2(NY);    // number of node in y axis
288
 
289
 
290
    input   [Xw-1   :   0]  current_x;
291
    input   [Yw-1   :   0]  current_y;
292
    input   [Xw-1   :   0]  dest_x;
293
    input   [Yw-1   :   0]  dest_y;
294
    input   [P_1-1  :   0]  destport_encoded;
295
    output  [P_1-1  :   0]  lkdestport_encoded;
296
 
297
 /*
298
 destination-port coded
299
            x:  1 EAST, 0 WEST
300
            y:  1 NORTH, 0 SOUTH
301
            ab: 00 : LOCAL, 10: xdir, 01: ydir, 11 x&y dir
302
 
303
*/
304
 
305
 
306
 
307
    wire x,y,a,b;
308
    wire    [Xw-1   :   0]  next_x;
309
    wire    [Yw-1   :   0]  next_y;
310
    wire    [P_1-1  :   0]  lkdestport_x,lkdestport_y;
311
    reg     [P-1    :   0]  destport_x, destport_y;
312
 
313
    assign {x,y,a,b} = destport_encoded;
314
 
315
   always @(*)begin
316
        destport_x = 5'd0;
317
        destport_y = 5'd0;
318
        case({a,b})
319
            2'b10 : destport_x = {1'b0,~x,1'b0,x,1'b0};
320
            2'b01 : destport_y = {~y,1'b0,y,1'b0,1'b0};
321
            2'b11 : begin destport_x = {1'b0,~x,1'b0,x,1'b0}; destport_y = {~y,1'b0,y,1'b0,1'b0}; end
322
            2'b00 : begin destport_x =  5'b00001;destport_y =  5'b00001; end
323
         endcase
324
   end //always
325
 
326
    mesh_torus_next_router_addr_predictor #(
327
        .P(P),
328
        .TOPOLOGY(TOPOLOGY),
329
        .NX(NX),
330
        .NY(NY)
331
    )
332
    addr_predictor_x
333
    (
334
        .destport(destport_x),
335
        .current_x(current_x),
336
        .current_y(current_y),
337
        .next_x(next_x),
338
        .next_y()
339
    );
340
 
341
 
342
     mesh_torus_next_router_addr_predictor #(
343
        .P(P),
344
        .TOPOLOGY(TOPOLOGY),
345
        .NX(NX),
346
        .NY(NY)
347
    )
348
    addr_predictor_y
349
    (
350
        .destport(destport_y),
351
        .current_x(current_x),
352
        .current_y(current_y),
353
        .next_x(),
354
        .next_y(next_y)
355
    );
356
 
357
 
358
 
359
    mesh_torus_conventional_routing #(
360
        .TOPOLOGY(TOPOLOGY),
361
        .ROUTE_NAME(ROUTE_NAME),
362
        .ROUTE_TYPE(ROUTE_TYPE),
363
        .NX(NX),
364
        .NY(NY),
365
        .LOCATED_IN_NI(0)
366
    )
367
    conv_route_x
368
    (
369
        .current_x(next_x),
370
        .current_y(current_y),
371
        .dest_x(dest_x),
372
        .dest_y(dest_y),
373
        .destport(lkdestport_x)
374
    );
375
 
376
    mesh_torus_conventional_routing #(
377
        .TOPOLOGY(TOPOLOGY),
378
        .ROUTE_NAME(ROUTE_NAME),
379
        .ROUTE_TYPE(ROUTE_TYPE),
380
        .NX(NX),
381
        .NY(NY),
382
        .LOCATED_IN_NI(0)
383
    )
384
    conv_route_y
385
    (
386
        .current_x(current_x),
387
        .current_y(next_y),
388
        .dest_x(dest_x),
389
        .dest_y(dest_y),
390
        .destport(lkdestport_y)
391
    );
392
 //take the value of a&b only.  x&y can be obtained from destport in the router
393
 assign lkdestport_encoded = {lkdestport_x[1:0],lkdestport_y[1:0]};
394
 
395
 
396
 endmodule
397
 
398
 
399
 
400
 
401
/********************************************************
402
 
403
                    next_router_addr_predictor
404
 
405
Determine the next router address based on the packet destination port
406
 
407
********************************************************/
408
 
409
module mesh_torus_next_router_addr_predictor #(
410
    parameter P     =   5,
411
    parameter TOPOLOGY  ="MESH",
412
    parameter NX    =   4,//toutal number of router in x direction 
413
    parameter NY    =   4//toutal number of router in y direction 
414
    )
415
    (
416
    destport,
417
    current_x,
418
    current_y,
419
    next_x,
420
    next_y
421
 
422
    );
423
 
424
    function integer log2;
425
      input integer number; begin
426
         log2=(number <=1) ? 1: 0;
427
         while(2**log2<number) begin
428
            log2=log2+1;
429
         end
430
      end
431
    endfunction // log2 
432
 
433
    localparam  Xw          =   log2(NX),
434
                Yw          =   log2(NY);
435
    // mesh torus            
436
    localparam  EAST   =       3'd1,
437
                NORTH  =       3'd2,
438
                WEST   =       3'd3,
439
                SOUTH  =       3'd4;
440
    //ring line            
441
    localparam  FORWARD =  2'd1,
442
                BACKWARD=  2'd2;
443
 
444
    localparam [Xw-1  :   0] LAST_X_ADDR  =(NX[Xw-1 :   0]-1'b1);
445
    localparam [Yw-1  :   0] LAST_Y_ADDR  =(NY[Yw-1 :   0]-1'b1);
446
 
447
    input       [P-1   :    0]  destport;
448
    input       [Xw-1  :    0]  current_x;
449
    input       [Yw-1  :    0]  current_y;
450
    output reg  [Xw-1  :    0]  next_x;
451
    output reg  [Yw-1  :    0]  next_y;
452
 
453
    generate
454
    /* verilator lint_off WIDTH */
455
    if(TOPOLOGY=="MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "FMESH" ) begin : mesh
456
    /* verilator lint_on WIDTH */
457
        always @(*) begin
458
             //default values 
459
            next_x= current_x;
460
            next_y= current_y;
461
            if(destport[EAST]) begin
462
                next_x= (current_x==LAST_X_ADDR ) ? {Xw{1'b0}} : current_x+1'b1;
463
                next_y=  current_y;
464
            end
465
            else if(destport[NORTH])  begin
466
                next_x= current_x;
467
                next_y= (current_y==0)? LAST_Y_ADDR  : current_y-1'b1;
468
            end
469
            else  if(destport[WEST])       begin
470
                next_x= (current_x==0) ? LAST_X_ADDR  : current_x-1'b1;
471
                next_y=  current_y;
472
             end
473
            else  if(destport[SOUTH])  begin
474
                next_x= current_x;
475
                next_y= (current_y== LAST_Y_ADDR ) ? {Yw{1'b0}}: current_y+1'b1;
476
            end
477
        end//always
478
    /* verilator lint_off WIDTH */
479
    end else  if(TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin : ring
480
    /* verilator lint_on WIDTH */
481
 
482
        always @(*) begin
483
             //default values 
484
            next_x= current_x;
485
            next_y= 1'b0;
486
            if(destport[FORWARD]) begin
487
                next_x= (current_x==LAST_X_ADDR ) ? {Xw{1'b0}} : current_x+1'b1;
488
 
489
            end
490
            else if(destport[BACKWARD])  begin
491
                next_x= (current_x=={Xw{1'b0}} ) ? LAST_X_ADDR  : current_x-1'b1;
492
 
493
            end
494
 
495
        end//always
496
 
497
 
498
    end
499
    //synthesis translate_off
500
    //synopsys  translate_off
501
    else begin : wrong_topology initial $display("Error: next router inport is not predicted for %s   topology",TOPOLOGY); end
502
    //synopsys  translate_on
503
    //synthesis translate_on
504
 
505
 
506
 
507
     endgenerate
508
endmodule
509
 
510
/*******************************************************
511
 
512
            next_router_inport_predictor
513
 
514
 
515
********************************************************/
516
 
517
module mesh_torus_next_router_inport_predictor #(
518
    parameter TOPOLOGY  ="MESH",
519
    parameter P =5
520
)(
521
    destport,
522
    receive_port
523
 
524
);
525
 
526
 
527
 
528
    input   [P-1    :   0] destport;
529
    output  [P-1    :   0] receive_port;
530
 
531
    localparam  LOCAL   =       3'd0,
532
                EAST    =       3'd1,
533
                NORTH   =       3'd2,
534
                WEST    =       3'd3,
535
                SOUTH   =       3'd4;
536
    generate
537
    /* verilator lint_off WIDTH */
538
    if(TOPOLOGY=="MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "FMESH") begin : mesh
539
    /* verilator lint_on WIDTH */
540
 
541
        assign  receive_port[LOCAL]   = destport[LOCAL];
542
        assign  receive_port[WEST]    = destport[EAST];
543
        assign  receive_port[EAST]    = destport[WEST];
544
        assign  receive_port[NORTH]   = destport[SOUTH];
545
        assign  receive_port[SOUTH]   = destport[NORTH];
546
    /* verilator lint_off WIDTH */
547
    end else  if(TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin : ring
548
    /* verilator lint_on WIDTH */
549
        assign  receive_port[0] = destport[0];
550
        assign  receive_port[1] = destport[2];
551
        assign  receive_port[2] = destport[1];
552
    end
553
    //synthesis translate_off
554
    //synopsys  translate_off
555
            else begin : wrong_topology initial $display("Error: next router inport is not predicted for %s   topology",TOPOLOGY); end
556
    //synopsys  translate_on
557
    //synthesis translate_on
558
 
559
 
560
 
561
 
562
    endgenerate
563
 
564
endmodule
565
 
566
/***********************************
567
 
568
            remove_sw_loc_one_hot
569
remove port number that is holdind the packet
570
 
571
************************************/
572
 
573
module remove_sw_loc_one_hot #(
574
    parameter P              =   5,
575
    parameter SW_LOC     = 0
576
 
577
)
578
(
579
    destport_in,
580
    destport_out
581
);
582
 
583
    localparam P_1 = P-1;
584
 
585
    input   [P-1         :   0] destport_in;
586
    output  [P_1-1       :   0] destport_out;
587
 
588
 
589
    generate
590
 
591
    if(SW_LOC==0)begin :local_p
592
        assign destport_out= destport_in[P-1    :   1];
593
 
594
    end else if (SW_LOC==P_1)begin :last_p
595
        assign destport_out= destport_in[P_1-1  :   0];
596
 
597
    end else begin :midle_p
598
        assign destport_out= {destport_in[P-1   :   SW_LOC+1],destport_in[SW_LOC-1  :   0]};
599
 
600
    end
601
    endgenerate
602
 
603
endmodule
604
 
605
 
606
/***********************************
607
 
608
     remove_receive_port_one_hot
609
 
610
 
611
************************************/
612
 
613
 
614
module remove_receive_port_one_hot #(
615
    parameter P              =   5
616
)
617
(
618
    receiver_port,
619
    destport_in,
620
    destport_out
621
);
622
 
623
 
624
 
625
    function integer log2;
626
      input integer number; begin
627
         log2=(number <=1) ? 1: 0;
628
         while(2**log2<number) begin
629
            log2=log2+1;
630
         end
631
      end
632
    endfunction // log2 
633
 
634
    localparam P_1  =   P-1,
635
               Pw   =   log2(P),
636
               P_1w =   log2(P_1);
637
 
638
    input  [P-1        :   0]  destport_in;
639
    input  [P-1        :   0]  receiver_port;
640
    output [P_1-1      :   0]  destport_out;
641
 
642
    wire        [Pw-1       :   0]  receiver_port_bin,destport_in_bin;
643
    wire        [P_1w-1     :   0]  destport_out_bin;
644
 
645
 
646
    one_hot_to_bin #(
647
        .ONE_HOT_WIDTH(P),
648
        .BIN_WIDTH(Pw)
649
    )
650
    convert1(
651
        .one_hot_code(receiver_port),
652
        .bin_code(receiver_port_bin)
653
    );
654
 
655
     one_hot_to_bin #(
656
        .ONE_HOT_WIDTH(P),
657
        .BIN_WIDTH(Pw)
658
    )
659
    convert2(
660
        .one_hot_code(destport_in),
661
        .bin_code(destport_in_bin)
662
    );
663
 
664
 
665
    wire [Pw-1      :   0] temp;
666
    assign temp = (receiver_port_bin > destport_in_bin ) ? destport_in_bin   : destport_in_bin  -1'b1;
667
    assign destport_out_bin=temp[P_1w-1     :0];
668
 
669
    bin_to_one_hot #(
670
        .BIN_WIDTH(P_1w),
671
        .ONE_HOT_WIDTH(P_1)
672
    )
673
    convert3(
674
        .bin_code(destport_out_bin),
675
        .one_hot_code(destport_out)
676
    );
677
 
678
 
679
 
680
endmodule
681
 
682
/**************************************
683
 
684
        add_sw_loc_one_hot
685
 
686
 
687
****************************************/
688
 
689
module add_sw_loc_one_hot #(
690
    parameter P          =   5,
691
    parameter SW_LOC     = 1
692
 
693
)
694
(
695
    destport_in,
696
    destport_out
697
);
698
 
699
    localparam P_1 = P-1;
700
 
701
    input       [P_1-1     :   0] destport_in;
702
    output reg  [P-1       :   0] destport_out;
703
 
704
    integer i;
705
    always @(*)begin
706
        for(i=0;i<P;i=i+1)begin :port_loop
707
            if      (i>SW_LOC)      destport_out[i]      =   destport_in[i-1];
708
            else if (i==SW_LOC)     destport_out[i]      =   1'b0;
709
            else                    destport_out[i]      =   destport_in[i];
710
        end//for 
711
    end
712
 
713
 
714
 
715
 endmodule
716
 
717
 
718
module add_sw_loc_one_hot_val #(
719
    parameter P          =   5,
720
    parameter SW_LOC     = 1
721
 
722
)
723
(
724
    sw_loc_val,
725
    destport_in,
726
    destport_out
727
);
728
 
729
    localparam P_1 = P-1;
730
    input sw_loc_val;
731
    input       [P_1-1     :   0] destport_in;
732
    output reg  [P-1       :   0] destport_out;
733
 
734
    integer i;
735
    always @(*)begin
736
        for(i=0;i<P;i=i+1)begin :port_loop
737
            if      (i>SW_LOC)      destport_out[i]      =   destport_in[i-1];
738
            else if (i==SW_LOC)     destport_out[i]      =   sw_loc_val;
739
            else                    destport_out[i]      =   destport_in[i];
740
        end//for 
741
    end
742
 
743
 
744
 
745
 endmodule
746
 
747
 
748
/***************************************************
749
 
750
                    conventional routing
751
 
752
***************************************************/
753
 
754
module mesh_torus_conventional_routing #(
755
    parameter TOPOLOGY          =   "MESH",
756
    parameter ROUTE_NAME        =   "XY",
757
    parameter ROUTE_TYPE        =   "DETERMINISTIC",
758
    parameter NX                =   4,
759
    parameter NY                =   4,
760
    parameter LOCATED_IN_NI     =   0//use for add even only
761
 
762
    )
763
    (
764
    current_x,
765
    current_y,
766
    dest_x,
767
    dest_y,
768
    destport
769
 
770
    );
771
 
772
 
773
    function integer log2;
774
      input integer number; begin
775
         log2=(number <=1) ? 1: 0;
776
         while(2**log2<number) begin
777
            log2=log2+1;
778
         end
779
      end
780
    endfunction // log2 
781
   /* verilator lint_off WIDTH */
782
   localparam P =  (TOPOLOGY=="RING" || TOPOLOGY=="LINE" )? 3 : 5,
783
   /* verilator lint_on WIDTH */
784
              P_1   =   P-1,
785
              Xw    =   log2(NX),
786
              Yw    =   log2(NY);
787
 
788
    localparam DSTw     =    P_1;
789
 
790
    input   [Xw-1         :0] current_x;
791
    input   [Yw-1         :0] current_y;
792
    input   [Xw-1         :0] dest_x;
793
    input   [Yw-1         :0] dest_y;
794
 
795
    output  [DSTw-1       :0] destport;
796
 
797
 
798
    generate
799
        /* verilator lint_off WIDTH */
800
        if (TOPOLOGY == "MESH" || TOPOLOGY == "FMESH")begin :mesh
801
            if(ROUTE_NAME ==  "XY") begin : xy_routing_blk
802
        /* verilator lint_on WIDTH */
803
 
804
                xy_mesh_routing #(
805
                    .NX(NX),
806
                    .NY(NY)
807
                )
808
                 xy_routing
809
                (
810
                    .current_x(current_x),
811
                    .current_y(current_y),
812
                    .dest_x(dest_x),
813
                    .dest_y(dest_y),
814
                    .dstport_encoded(destport)
815
                 );
816
 
817
 
818
            end //"XY"
819
            /* verilator lint_off WIDTH */
820
            else if(ROUTE_NAME    ==  "WEST_FIRST") begin : west_first_routing_blk
821
            /* verilator lint_on WIDTH */
822
                west_first_routing #(
823
                    .NX         (NX),
824
                    .NY         (NY)
825
                )
826
                west_first
827
                (
828
                    .current_x          (current_x),
829
                    .current_y          (current_y),
830
                    .dest_x             (dest_x),
831
                    .dest_y             (dest_y),
832
                    .destport           (destport)
833
 
834
                );
835
            end // WEST_FIRST
836
            /* verilator lint_off WIDTH */
837
            else if(ROUTE_NAME    ==  "NORTH_LAST") begin : north_last_routing_blk
838
            /* verilator lint_on WIDTH */
839
                north_last_routing #(
840
                    .NX         (NX),
841
                    .NY         (NY)
842
                )
843
                north_last
844
                (
845
                    .current_x          (current_x),
846
                    .current_y          (current_y),
847
                    .dest_x             (dest_x),
848
                    .dest_y             (dest_y),
849
                    .destport           (destport)
850
 
851
                );
852
 
853
            end // NORTH_LAST
854
            /* verilator lint_off WIDTH */
855
            else if(ROUTE_NAME    ==  "NEGETIVE_FIRST") begin : negetive_first_routing_blk
856
            /* verilator lint_on WIDTH */
857
                negetive_first_routing #(
858
                    .NX         (NX),
859
                    .NY         (NY)
860
                )
861
                negetive_first
862
                (
863
                    .current_x          (current_x),
864
                    .current_y          (current_y),
865
                    .dest_x             (dest_x),
866
                    .dest_y             (dest_y),
867
                    .destport           (destport)
868
 
869
                );
870
 
871
            end // NEGETIVE_FIRST           
872
            /* verilator lint_off WIDTH */
873
            else if(ROUTE_NAME    ==  "ODD_EVEN") begin : odd_even_routing_blk
874
            /* verilator lint_on WIDTH */
875
                odd_even_routing #(
876
                    .NX         (NX),
877
                    .NY         (NY),
878
                    .LOCATED_IN_NI      (LOCATED_IN_NI)
879
 
880
                ) odd_even
881
                (
882
                    .current_x          (current_x),
883
                    .current_y          (current_y),
884
                    .dest_x             (dest_x),
885
                    .dest_y             (dest_y),
886
                    .destport           (destport)
887
                );
888
 
889
            end //ODD_EVEN
890
            /* verilator lint_off WIDTH */
891
            else if(ROUTE_NAME    ==  "DUATO") begin : duato_routing_blk
892
            /* verilator lint_on WIDTH */
893
                duato_mesh_routing #(
894
                    .NX         (NX),
895
                    .NY         (NY)
896
                )
897
                duato_full_adaptive
898
                (
899
                    .current_x          (current_x),
900
                    .current_y          (current_y),
901
                    .dest_x             (dest_x),
902
                    .dest_y             (dest_y),
903
                    .destport           (destport)
904
 
905
 
906
                );
907
            end //DUATO
908
        //synthesis translate_off
909
        //synopsys  translate_off
910
            else begin : not_supported initial $display ("Error: %s is an unsupported routing algorithm for %s topology \n",ROUTE_NAME,TOPOLOGY); end
911
        //synopsys  translate_on
912
        //synthesis translate_on
913
        /* verilator lint_off WIDTH */
914
        end else if (TOPOLOGY == "TORUS" ) begin :torus
915
            if(ROUTE_NAME ==  "TRANC_XY") begin : tranc_routing_blk
916
        /* verilator lint_on WIDTH */
917
                tranc_xy_routing #(
918
                    .NX (NX),
919
                    .NY (NY)
920
                )
921
                tranc_xy
922
                (
923
                    .current_x          (current_x),
924
                    .current_y          (current_y),
925
                    .dest_x             (dest_x),
926
                    .dest_y             (dest_y),
927
                    .destport_encoded   (destport)
928
 
929
 
930
                );
931
 
932
            end //"TRANC_XY"
933
            /* verilator lint_off WIDTH */
934
            else if(ROUTE_NAME    ==  "TRANC_WEST_FIRST") begin : tranc_west_first_routing_blk
935
            /* verilator lint_on WIDTH */
936
                tranc_west_first_routing #(
937
                    .NX         (NX),
938
                    .NY         (NY)
939
                )
940
                tranc_west_first
941
                (
942
                    .current_x          (current_x),
943
                    .current_y          (current_y),
944
                    .dest_x             (dest_x),
945
                    .dest_y             (dest_y),
946
                    .destport           (destport)
947
 
948
                );
949
             end // TRANC_WEST_FIRST
950
             /* verilator lint_off WIDTH */
951
             else if(ROUTE_NAME    ==  "TRANC_NORTH_LAST") begin : tranc_north_last_routing_blk
952
             /* verilator lint_on WIDTH */
953
                tranc_north_last_routing #(
954
                    .NX         (NX),
955
                    .NY         (NY)
956
                )
957
                tranc_north_last
958
                (
959
                    .current_x          (current_x),
960
                    .current_y          (current_y),
961
                    .dest_x             (dest_x),
962
                    .dest_y             (dest_y),
963
                    .destport           (destport)
964
 
965
                );
966
             end // TRANC_NORTH_LAST
967
             /* verilator lint_off WIDTH */
968
             else if(ROUTE_NAME    ==  "TRANC_NEGETIVE_FIRST") begin : tranc_negetive_first_routing_blk
969
             /* verilator lint_on WIDTH */
970
                tranc_negetive_first_routing #(
971
                    .NX         (NX),
972
                    .NY         (NY)
973
                )
974
                tranc_negetive_first
975
                (
976
                    .current_x          (current_x),
977
                    .current_y          (current_y),
978
                    .dest_x             (dest_x),
979
                    .dest_y             (dest_y),
980
                    .destport           (destport)
981
 
982
                );
983
             end // TRANC_NEGETIVE_FIRST
984
            /* verilator lint_off WIDTH */
985
            else if(ROUTE_NAME    ==  "TRANC_DUATO") begin : tranc_duato_routing_blk
986
            /* verilator lint_on WIDTH */
987
                tranc_duato_routing #(
988
                    .NX         (NX),
989
                    .NY         (NY)
990
                )
991
                duato_full_adaptive
992
                (
993
                    .current_x          (current_x),
994
                    .current_y          (current_y),
995
                    .dest_x             (dest_x),
996
                    .dest_y             (dest_y),
997
                    .destport           (destport)
998
 
999
                );
1000
            end //TRANC_DUATO
1001
        //synthesis translate_off
1002
        //synopsys  translate_off
1003
            else begin : not_supported2 initial $display("Error: %s is an unsupported routing algorithm for %s topology",ROUTE_NAME,TOPOLOGY); end
1004
        //synopsys  translate_on
1005
        //synthesis translate_on
1006
        end //TORUS
1007
 
1008
        /* verilator lint_off WIDTH */
1009
        else if (TOPOLOGY == "RING" ) begin :ring
1010
            if(ROUTE_NAME == "TRANC_XY") begin : tranc_ring_blk
1011
        /* verilator lint_on WIDTH */
1012
                tranc_ring_routing #(
1013
                    .NX(NX)
1014
                )
1015
                tranc_ring
1016
                (
1017
                    .current_x(current_x),
1018
                    .dest_x(dest_x),
1019
                    .destport(destport)
1020
                );
1021
            end // "TRANC"
1022
    //synthesis translate_off
1023
        //synopsys  translate_off
1024
        else begin : not_supported2 initial $display("Error: %s is an unsupported routing algorithm for %s topology",ROUTE_NAME,TOPOLOGY); end
1025
    //synopsys  translate_on
1026
        //synthesis translate_on     
1027
        end //"RING" 
1028
 
1029
        /* verilator lint_off WIDTH */
1030
        else if (TOPOLOGY == "LINE" ) begin :ring
1031
            if(ROUTE_NAME == "XY") begin : tranc_ring_blk
1032
        /* verilator lint_on WIDTH */
1033
                xy_line_routing #(
1034
                    .NX(NX)
1035
                )
1036
                 xy_routing
1037
                (
1038
                    .current_x(current_x),
1039
                    .dest_x(dest_x),
1040
                    .destport(destport)
1041
                 );
1042
            end // "XY"
1043
    //synthesis translate_off
1044
        //synopsys  translate_off
1045
        else begin : not_supported2 initial $display("Error: %s is an unsupported routing algorithm for %s topology",ROUTE_NAME,TOPOLOGY); end
1046
    //synopsys  translate_on
1047
        //synthesis translate_on           
1048
        end //"LINE" 
1049
 
1050
 
1051
 
1052
    //synthesis translate_off
1053
    //synopsys  translate_off
1054
            else begin : wrong_topology initial $display("Error: %s is an unsupported topology",TOPOLOGY); end
1055
    //synopsys  translate_on
1056
    //synthesis translate_on
1057
 
1058
    endgenerate
1059
 
1060
    //force modelsim to add route_mesh & turos files
1061
 
1062
 
1063
 
1064
endmodule
1065
 
1066
 
1067
 
1068
 
1069
 
1070
/********************************************
1071
                        TRANC_ring
1072
*********************************************/
1073
 
1074
module tranc_ring_routing #(
1075
    parameter NX   =    4
1076
)
1077
(
1078
    current_x,
1079
    dest_x,
1080
    destport
1081
 
1082
);
1083
 
1084
 
1085
    function integer log2;
1086
      input integer number; begin
1087
         log2=(number <=1) ? 1: 0;
1088
         while(2**log2<number) begin
1089
            log2=log2+1;
1090
         end
1091
      end
1092
    endfunction // log2 
1093
 
1094
 
1095
    localparam  P           =   3,
1096
                Xw          =   log2(NX),
1097
                DSTw        =   P-1;
1098
 
1099
 
1100
    input   [Xw-1       :   0] current_x;
1101
    input   [Xw-1       :   0] dest_x;
1102
    output  [DSTw -1    :   0] destport;
1103
 
1104
    localparam      LOCAL   =    3'b001,
1105
                    PLUS    =    3'b010,
1106
                    MINUS   =    3'b100;
1107
 
1108
    reg [P-1            :0] destport_one_hot;
1109
 
1110
 
1111
 
1112
    reg tranc_x_plus;
1113
    reg tranc_x_min;
1114
    wire same_x;
1115
 
1116
 
1117
 
1118
    localparam SIGNED_X_WIDTH   =  (Xw<3) ? 4 : Xw+1;
1119
 
1120
 
1121
    wire signed [SIGNED_X_WIDTH-1       :0] xc;//current 
1122
    wire signed [SIGNED_X_WIDTH-1       :0] xd;//destination
1123
    wire signed [SIGNED_X_WIDTH-1       :0] xdiff;
1124
 
1125
 
1126
    assign  xd  ={{(SIGNED_X_WIDTH-Xw){1'b0}}, dest_x};
1127
    assign  xc  ={{(SIGNED_X_WIDTH-Xw){1'b0}}, current_x [Xw-1      :0]};
1128
    assign  xdiff   = xd-xc;
1129
 
1130
 
1131
    always@ (*)begin
1132
        tranc_x_plus    =1'b0;
1133
        tranc_x_min     =1'b0;
1134
        if(xdiff!=0)begin
1135
            if ((xdiff ==1) ||
1136
                 (xdiff == (-NX+1)) ||
1137
                 ((xc == (NX-4)) && (xd == (NX-2))) ||
1138
                 ((xc >= (NX-2)) && (xd <= (NX-4))) ||
1139
                 ((xdiff> 0) && (xd<= (NX-3))))
1140
                    tranc_x_plus    = 1'b1;
1141
            else    tranc_x_min     = 1'b1;
1142
        end
1143
 
1144
    end//always
1145
 
1146
    assign same_x = (xdiff == 0);
1147
 
1148
 
1149
 
1150
 
1151
    always@(*)begin
1152
        if (same_x ) destport_one_hot= LOCAL;
1153
        else    begin
1154
            if          (tranc_x_plus)  destport_one_hot= PLUS;
1155
            else if     (tranc_x_min)   destport_one_hot= MINUS;
1156
         end
1157
    end
1158
 
1159
 line_ring_encode_dstport encode(
1160
        .dstport_one_hot(destport_one_hot),
1161
        .dstport_encoded(destport)
1162
    );
1163
 
1164
 
1165
endmodule
1166
 
1167
 
1168
 
1169
/********************************************
1170
                        xy_line
1171
*********************************************/
1172
 
1173
module xy_line_routing #(
1174
    parameter NX   =    8
1175
)
1176
(
1177
    current_x,
1178
    dest_x,
1179
    destport
1180
 
1181
);
1182
 
1183
 
1184
    function integer log2;
1185
      input integer number; begin
1186
         log2=(number <=1) ? 1: 0;
1187
         while(2**log2<number) begin
1188
            log2=log2+1;
1189
         end
1190
      end
1191
    endfunction // log2 
1192
 
1193
 
1194
    localparam  OUT_BIN     =   0,
1195
                P           =   3,
1196
                Xw          =   log2(NX);
1197
 
1198
 
1199
 
1200
    input   [Xw-1       :   0] current_x;
1201
    input   [Xw-1       :   0] dest_x;
1202
    output  [1       :   0] destport;
1203
 
1204
    localparam      LOCAL   =   (OUT_BIN)?  3'd0    : 3'b001,
1205
                    PLUS    =   (OUT_BIN)?  3'd1    : 3'b010,
1206
                    MINUS   =   (OUT_BIN)?  3'd2    : 3'b100;
1207
 
1208
 
1209
 
1210
    reg [P-1            :0] destport_one_hot;
1211
 
1212
 
1213
    always@(*)begin
1214
            destport_one_hot    = LOCAL [2    :0];
1215
            if           (dest_x    > current_x)        destport_one_hot    = PLUS  [2    :0];
1216
            else if      (dest_x    < current_x)        destport_one_hot    = MINUS [2    :0];
1217
    end
1218
 
1219
 
1220
    line_ring_encode_dstport encode(
1221
        .dstport_one_hot(destport_one_hot),
1222
        .dstport_encoded(destport)
1223
    );
1224
 
1225
 
1226
endmodule
1227
 
1228
 
1229
module line_ring_encode_dstport (
1230
    dstport_one_hot,
1231
    dstport_encoded
1232
);
1233
 
1234
    input  [2 : 0] dstport_one_hot;
1235
    output [1 : 0] dstport_encoded;
1236
 
1237
 
1238
 
1239
     localparam  FORWARD =  2'd1,
1240
                 BACKWARD=  2'd2;
1241
 
1242
    /************************
1243
 
1244
        destination-port_in
1245
            2'b11 : FORWARD or BACKWARD // can be sent to any of them
1246
            2'b10 : BACKWARD
1247
            2'b01 : FORWARD
1248
            2'b00 : LOCAL
1249
    *******************/
1250
// code the destination port
1251
    assign dstport_encoded = {dstport_one_hot[BACKWARD], dstport_one_hot[FORWARD]};
1252
 
1253
endmodule
1254
 
1255
 
1256
module line_ring_decode_dstport (
1257
    dstport_one_hot,
1258
    dstport_encoded
1259
);
1260
 
1261
    output  reg [2 : 0] dstport_one_hot;
1262
    input   [1 : 0] dstport_encoded;
1263
 
1264
         /************************
1265
      localparam  FORWARD =  2'd1,
1266
                 BACKWARD=  2'd2;
1267
        destination-port_in
1268
            2'b11 : FORWARD or BACKWARD // can be sey to any of them
1269
            2'b10 : BACKWARD
1270
            2'b01 : FORWARD
1271
            2'b00 : LOCAL
1272
    *******************/
1273
// code the destination port
1274
    //assign dstport_encoded = {dstport_one_hot[BACKWARD], dstport_one_hot[FORWARD]};
1275
 
1276
 
1277
 
1278
        always @(*)begin
1279
            dstport_one_hot = 3'b000;
1280
            case(dstport_encoded)
1281
                2'b10 : dstport_one_hot=3'b100;
1282
                2'b01 : dstport_one_hot=3'b010;
1283
                2'b00 : dstport_one_hot=3'b001;
1284
                2'b11 : dstport_one_hot=3'b110; //invalid condition in determinstic routing
1285
            endcase
1286
        end //always
1287
endmodule
1288
 
1289
 
1290
 
1291
module mesh_tori_decode_dstport (
1292
    dstport_encoded,
1293
    dstport_one_hot
1294
 
1295
);
1296
 
1297
 
1298
    input   [3 : 0] dstport_encoded;
1299
    output  reg [4 : 0] dstport_one_hot;
1300
 
1301
    wire x,y,a,b;
1302
 
1303
 
1304
    assign {x,y,a,b} = dstport_encoded;
1305
 
1306
   always @(*)begin
1307
        dstport_one_hot = 5'd0;
1308
        case({a,b})
1309
            2'b10 : dstport_one_hot = {1'b0,~x,1'b0,x,1'b0};
1310
            2'b01 : dstport_one_hot = {~y,1'b0,y,1'b0,1'b0};
1311
            2'b11 : dstport_one_hot = {1'b0,~x,1'b0,x,1'b0}; //illegal
1312
            2'b00 : dstport_one_hot =  5'b00001;
1313
         endcase
1314
   end //always
1315
 
1316
endmodule

powered by: WebSVN 2.1.0

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