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 56

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

powered by: WebSVN 2.1.0

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