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/] [routing.v] - Blame information for rev 54

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

Line No. Rev Author Line
1 48 alirezamon
`timescale     1ns/1ps
2
/**********************************************************************
3
**      File:  routing.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
**      look-ahead and conventional routing algorithms for Mesh and Torus NoC
25
**
26
**
27
**************************************************************/
28
 
29
 
30
module conventional_routing #(
31
    parameter TOPOLOGY          = "MESH",
32
    parameter ROUTE_NAME        = "XY",
33
    parameter ROUTE_TYPE        = "DETERMINISTIC",
34
    parameter T1                = 4,
35
    parameter T2                = 4,
36
    parameter T3                = 4,
37
    parameter RAw               = 3,
38
    parameter EAw               = 3,
39
    parameter DSTPw             = 4,
40
    parameter LOCATED_IN_NI     = 1 // only needed for mesh and odd-even routing
41
)
42
(
43
    reset,
44
    clk,
45
    current_r_addr,
46
    src_e_addr,
47
    dest_e_addr,
48
    destport
49
);
50
 
51
    function integer log2;
52
    input integer number; begin
53
       log2=(number <=1) ? 1: 0;
54
       while(2**log2<number) begin
55
          log2=log2+1;
56
       end
57
    end
58
    endfunction // log2 
59
 
60
    input  reset,clk;
61
    input   [RAw-1   :0] current_r_addr;
62
    input   [EAw-1   :0] src_e_addr;
63
    input   [EAw-1   :0] dest_e_addr;
64
    output  [DSTPw-1 :0] destport;
65
 
66
 generate
67
    /* verilator lint_off WIDTH */
68
    if(TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS"  || TOPOLOGY ==  "RING" || TOPOLOGY ==  "LINE") begin :mesh_torus
69
    /* verilator lint_on WIDTH */
70
 
71
    localparam
72
        NX = T1,
73
        NY = T2,
74
        RXw = log2(NX),
75
        RYw = log2(NY),
76
        EXw = RXw,
77
        EYw = RYw;
78
 
79
        wire   [RXw-1   :   0]  current_rx;
80
        wire   [RYw-1   :   0]  current_ry;
81
        wire   [EXw-1   :   0]  dest_ex;
82
        wire   [EYw-1   :   0]  dest_ey;
83
 
84
 
85
        mesh_tori_router_addr_decode #(
86
                .TOPOLOGY(TOPOLOGY),
87
            .T1(T1),
88
            .T2(T2),
89
            .T3(T3),
90
                .RAw(RAw)
91
        )
92
        router_addr_decode
93
        (
94
                .r_addr(current_r_addr),
95
                .rx(current_rx),
96
                .ry(current_ry),
97
                .valid( )
98
        );
99
 
100
       /* verilator lint_off WIDTH */
101
        if(TOPOLOGY == "FMESH") begin :fmesh
102
         /* verilator lint_on WIDTH */
103
            fmesh_endp_addr_decode #(
104
                .T1(T1),
105
                .T2(T2),
106
                .T3(T3),
107
                .EAw(EAw)
108
            )
109
            end_addr_decode
110
            (
111
                .e_addr(dest_e_addr),
112
                .ex(dest_ex),
113
                .ey(dest_ey),
114
                .ep( ),
115
                .valid()
116
            );
117
 
118
 
119
 
120
        end else begin : mesh
121
            mesh_tori_endp_addr_decode #(
122
                .TOPOLOGY(TOPOLOGY),
123
                .T1(T1),
124
                .T2(T2),
125
                .T3(T3),
126
                .EAw(EAw)
127
            )
128
            end_addr_decode
129
            (
130
                .e_addr(dest_e_addr),
131
                .ex(dest_ex),
132
                .ey(dest_ey),
133
                .el( ),
134
                .valid()
135
            );
136
        end//mesh
137
 
138
            mesh_torus_conventional_routing #(
139
                .TOPOLOGY(TOPOLOGY),
140
                .ROUTE_NAME(ROUTE_NAME),
141
                .ROUTE_TYPE(ROUTE_TYPE),
142
                .NX(T1),
143
                .NY(T2),
144
                .LOCATED_IN_NI(LOCATED_IN_NI)
145
            )
146
            the_conventional_routing
147
            (
148
                .current_x(current_rx),
149
                .current_y(current_ry),
150
                .dest_x(dest_ex),
151
                .dest_y(dest_ey),
152
                .destport(destport)
153
            );
154
 
155
    /* verilator lint_off WIDTH */
156
    end else if(TOPOLOGY == "FATTREE" || TOPOLOGY == "TREE" ) begin :tree_based
157
    /* verilator lint_on WIDTH */
158
 
159
        localparam
160
            K=T1,
161
            L=T2,
162
            Kw = log2(K),
163
            LKw= L*Kw,
164
            Lw = log2(L);
165
 
166
        wire [LKw-1 :0]    current_rx;
167
        wire [Lw-1  :0]    current_rl;
168
 
169
        fattree_router_addr_decode #(
170
            .K(T1),
171
            .L(T2)
172
        )
173
        router_addr_decode
174
        (
175
            .r_addr(current_r_addr),
176
            .rx(current_rx),
177
            .rl(current_rl)
178
        );
179
 
180
        /* verilator lint_off WIDTH */
181
        if(TOPOLOGY == "FATTREE" )begin : fattree
182
        /* verilator lint_on WIDTH */
183
 
184
            fattree_conventional_routing #(
185
                .ROUTE_NAME(ROUTE_NAME),
186
                .K(T1),
187
                .L(T2)
188
            )
189
            the_conventional_routing
190
            (
191
                .reset(reset),
192
                .clk(clk),
193
                .current_addr_encoded(current_rx),
194
                .current_level(current_rl),
195
                .dest_addr_encoded(dest_e_addr),
196
                .destport_encoded(destport)
197
            );
198
        /* verilator lint_off WIDTH */
199
        end else  if(TOPOLOGY == "TREE" )begin : tree
200
        /* verilator lint_on WIDTH */
201
            tree_conventional_routing #(
202
                .ROUTE_NAME(ROUTE_NAME),
203
                .K(T1),
204
                .L(T2)
205
            )
206
            the_conventional_routing
207
            (
208
 
209
                .current_addr_encoded(current_rx),
210
                .current_level(current_rl),
211
                .dest_addr_encoded(dest_e_addr),
212
                .destport_encoded(destport)
213
            );
214
        end // tree 
215
 
216
    /* verilator lint_off WIDTH */
217
    end else if (TOPOLOGY == "STAR") begin : star
218
    /* verilator lint_on WIDTH */
219
        star_conventional_routing #(
220
            .NE(T1)
221
        )
222
        the_conventional_routing
223
        (
224
            .dest_e_addr(dest_e_addr),
225
            .destport(destport)
226
        );
227
 
228
 
229
 
230
 
231
    end else begin :custom
232
 
233
        custom_ni_routing  #(
234
            .TOPOLOGY(TOPOLOGY),
235
            .ROUTE_NAME(ROUTE_NAME),
236
            .ROUTE_TYPE(ROUTE_TYPE),
237
            .RAw(RAw),
238
            .EAw(EAw),
239
            .DSTPw(DSTPw)
240
        )
241
        the_conventional_routing
242
        (
243
            .dest_e_addr(dest_e_addr),
244
            .src_e_addr(src_e_addr),
245
            .destport(destport)
246
        );
247
 
248
    end //custom
249
    endgenerate
250
 
251
endmodule
252
 
253
 
254
 
255
 
256
 
257
 
258
 
259
 
260
 
261
 
262
/************************************
263
 
264
     look_ahead_routing
265
 
266
*************************************/
267
 
268
module look_ahead_routing #(
269 54 alirezamon
    parameter P = 5,
270 48 alirezamon
    parameter T1= 8,
271
    parameter T2= 8,
272
    parameter T3= 8,
273
    parameter T4= 8,
274
    parameter RAw = 3,
275 54 alirezamon
    parameter EAw = 3,
276
    parameter DAw = 3,
277 48 alirezamon
    parameter DSTPw=P-1,
278
    parameter SW_LOC    =0,
279
    parameter TOPOLOGY  ="MESH",//"MESH","TORUS"
280
    parameter ROUTE_NAME="XY",// 
281
    parameter ROUTE_TYPE="DETERMINISTIC"// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE"
282
)
283
(
284
    current_r_addr,  //current router  address
285
    neighbors_r_addr,
286
    dest_e_addr,  // destination endpoint address   
287
    src_e_addr, //   source endpoint address. Only needed for custom topology 
288
    destport_encoded,   // current router destination port number       
289
    lkdestport_encoded, // look ahead destination port number
290
    reset,
291
    clk
292
);
293
 
294
    function integer log2;
295
    input integer number; begin
296
       log2=(number <=1) ? 1: 0;
297
       while(2**log2<number) begin
298
          log2=log2+1;
299
       end
300
    end
301
    endfunction // log2 
302
 
303
    localparam
304
        PRAw= P * RAw;
305
    localparam
306
        //K= T1,
307
        //L=T2,
308
            Kw = log2(T1),
309
            Lw = log2(T2),
310
            LKw= T2 * Kw,
311
            PLw = P * Lw,
312
            PLKw = P * LKw;
313
 
314
    input   [PRAw-1:  0]  neighbors_r_addr;
315
    input   [RAw-1   :   0]  current_r_addr;
316 54 alirezamon
    input   [DAw-1   :   0]  dest_e_addr;
317 48 alirezamon
    input   [EAw-1   :   0]  src_e_addr;
318
    input   [DSTPw-1  :   0]  destport_encoded;
319
    output  [DSTPw-1  :   0]  lkdestport_encoded;
320
    input                   reset,clk;
321
 
322
    genvar i;
323
    generate
324
    /* verilator lint_off WIDTH */
325
    if(TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS"  || TOPOLOGY ==  "RING" || TOPOLOGY ==  "LINE")begin :mesh_torus
326
    /* verilator lint_on WIDTH */
327
 
328
       localparam
329
        NX = T1,
330
        NY = T2,
331
        RXw = log2(NX),
332
        RYw = log2(NY),
333
        EXw = RXw,
334
        EYw = RYw;
335
 
336
        wire   [RXw-1   :   0]  current_rx;
337
        wire   [RYw-1   :   0]  current_ry;
338
        wire   [EXw-1   :   0]  dest_ex;
339
        wire   [EYw-1   :   0]  dest_ey;
340
 
341
        localparam SL_SW_LOC = ( SW_LOC > P-T3) ? 0 : SW_LOC; //single_local   
342
 
343
        mesh_tori_router_addr_decode #(
344
            .TOPOLOGY(TOPOLOGY),
345
            .T1(T1),
346
            .T2(T2),
347
            .T3(T3),
348
            .RAw(RAw)
349
        )
350
        router_addr_decode
351
        (
352
            .r_addr(current_r_addr),
353
            .rx(current_rx),
354
            .ry(current_ry),
355
            .valid( )
356
        );
357
         /* verilator lint_off WIDTH */
358
        if(TOPOLOGY == "FMESH") begin :fmesh
359
         /* verilator lint_on WIDTH */
360
             fmesh_endp_addr_decode #(
361
                .T1(T1),
362
                .T2(T2),
363
                .T3(T3),
364
                .EAw(EAw)
365
            )
366
            end_addr_decode
367
            (
368
                .e_addr(dest_e_addr),
369
                .ex(dest_ex),
370
                .ey(dest_ey),
371
                .ep( ),
372
                .valid()
373
            );
374
        end else begin :mesh
375
            mesh_tori_endp_addr_decode #(
376
                .TOPOLOGY(TOPOLOGY),
377
                .T1(T1),
378
                .T2(T2),
379
                .T3(T3),
380
                .EAw(EAw)
381
            )
382
            end_addr_decode
383
            (
384
                .e_addr(dest_e_addr),
385
                .ex(dest_ex),
386
                .ey(dest_ey),
387
                .el( ),
388
                .valid()
389
            );
390
 
391
 
392
        end
393
 
394
        mesh_torus_look_ahead_routing #(
395
                .NX(T1),
396
                .NY(T2),
397
                .SW_LOC(SL_SW_LOC),
398
                .TOPOLOGY(TOPOLOGY),
399
                .ROUTE_NAME(ROUTE_NAME),
400
                .ROUTE_TYPE(ROUTE_TYPE)
401
        )
402
        look_ahead_route
403
        (
404
                .current_x(current_rx),
405
                .current_y(current_ry),
406
                .dest_x(dest_ex),
407
                .dest_y(dest_ey),
408
                .destport_encoded(destport_encoded),
409
                .lkdestport_encoded(lkdestport_encoded),
410
                .reset(reset),
411
                .clk(clk)
412
        );
413
    /* verilator lint_off WIDTH */
414
    end else if (TOPOLOGY == "FATTREE") begin: fat
415
    /* verilator lint_on WIDTH */
416
 
417
        wire  [PLKw-1 : 0]  neighbors_rx;
418
        wire  [PLw-1 : 0]  neighbors_ry;
419
 
420
        for (i=0; i<P; i=i+1) begin : port
421
            assign neighbors_rx[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
422
            assign neighbors_ry[(i+1)*Lw-1 : i*Lw]  = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
423
        end//port        
424
 
425
        fattree_look_ahead_routing #(
426
                .ROUTE_NAME(ROUTE_NAME),
427
                .P(P),
428
                .K(T1),
429
                .L(T2)
430
        )
431
        look_ahead_route
432
        (
433
                .destport_encoded(destport_encoded),
434
                .dest_addr_encoded(dest_e_addr),
435
                .neighbors_rx(neighbors_rx),
436
                .neighbors_ry(neighbors_ry),
437
                .lkdestport_encoded(lkdestport_encoded),
438
                .reset(reset),
439
                .clk(clk)
440
        );
441
 
442
    /* verilator lint_off WIDTH */
443
    end else if (TOPOLOGY == "TREE") begin: tree
444
    /* verilator lint_on WIDTH */
445
 
446
        wire  [PLKw-1 : 0]  neighbors_rx_tree;
447
        wire  [PLw-1 : 0]  neighbors_ry_tree;
448
 
449
        for (i=0; i<P; i=i+1) begin : port
450
            assign neighbors_rx_tree[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
451
            assign neighbors_ry_tree[(i+1)*Lw-1 : i*Lw]  = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
452
        end//port        
453
 
454
 
455
        tree_look_ahead_routing #(
456
                .ROUTE_NAME(ROUTE_NAME),
457
                .P(P),
458
                .L(T2),
459
                .K(T1)
460
        )
461
        look_ahead_routing
462
        (
463
                .destport_encoded(destport_encoded),
464
                .dest_addr_encoded(dest_e_addr),
465
                .neighbors_rx(neighbors_rx_tree),
466
                .neighbors_ry(neighbors_ry_tree),
467
                .lkdestport_encoded(lkdestport_encoded),
468
                .reset(reset),
469
                .clk(clk)
470
        );
471
 
472
      /* verilator lint_off WIDTH */
473
    end else if (TOPOLOGY == "STAR") begin : star
474
    /* verilator lint_on WIDTH */
475
     //look-ahead routing is not needed in star topology as there is only one router
476
        assign  lkdestport_encoded={DSTPw{1'b0}};
477
 
478
     end else begin : custom
479
 
480
        custom_lkh_routing  #(
481
            .TOPOLOGY(TOPOLOGY),
482
            .ROUTE_NAME(ROUTE_NAME),
483
            .ROUTE_TYPE(ROUTE_TYPE),
484
            .RAw(RAw),
485
            .EAw(EAw),
486
            .DSTPw(DSTPw)
487
        )
488
        look_ahead_routing
489
        (
490
            .current_r_addr(current_r_addr),
491
            .dest_e_addr(dest_e_addr),
492
            .src_e_addr(src_e_addr),
493
            .destport(lkdestport_encoded),
494
            .reset(reset),
495
            .clk(clk)
496
        );
497
 
498
    end
499
    endgenerate
500
endmodule
501
 
502
/********************************************************
503
 
504
                    next_router_addr_selector
505
 
506
Determine the next router address based on the packet destination port
507
 
508
********************************************************/
509
 
510
 
511
module next_router_addr_selector_onehot #(
512
    parameter P = 5,
513
    parameter RXw = 3,  // The router's x dimension adress width in bits
514
    parameter RYw = 3  // The router's y dimension adress width in bits
515
    )
516
    (
517
    destport_onehot,
518
    neighbors_rx,
519
    neighbors_ry,
520
    next_rx,
521
    next_ry
522
    );
523
 
524
    localparam
525
        PRXw = P * RXw,
526
        PRYw = P * RYw;
527
 
528
    input [P-1   :  0]  destport_onehot;
529
    input [PRXw-1:  0]  neighbors_rx;
530
    input [PRYw-1:  0]  neighbors_ry;
531
    output[RXw-1  :    0]  next_rx;
532
    output[RYw-1  :    0]  next_ry;
533
 
534
    onehot_mux_1D #(
535
        .W(RXw),
536
        .N(P)
537
    )
538
    next_x_mux
539
    (
540
        .in(neighbors_rx),
541
        .out(next_rx),
542
        .sel(destport_onehot)
543
    );
544
 
545
    onehot_mux_1D #(
546
        .W(RYw),
547
        .N(P)
548
    )
549
    next_y_mux
550
    (
551
        .in(neighbors_ry),
552
        .out(next_ry),
553
        .sel(destport_onehot)
554
    );
555
 
556
endmodule
557
 
558
 
559
 
560
 
561
 
562
module next_router_addr_selector_bin #(
563
    parameter P = 5,
564
    parameter RXw = 3,  // The router's x dimension adress width in bits
565
    parameter RYw = 3  // The router's y dimension adress width in bits
566
    )
567
    (
568
    destport_bin,
569
    neighbors_rx,
570
    neighbors_ry,
571
    next_rx,
572
    next_ry
573
 
574
    );
575
 
576
    function integer log2;
577
      input integer number; begin
578
         log2=(number <=1) ? 1: 0;
579
         while(2**log2<number) begin
580
            log2=log2+1;
581
         end
582
      end
583
    endfunction // log2 
584
 
585
    localparam
586
        Pw = log2(P),
587
        PRXw = P * RXw,
588
        PRYw = P * RYw;
589
 
590
    input [Pw-1   :  0]  destport_bin;
591
    input [PRXw-1:  0]  neighbors_rx;
592
    input [PRYw-1:  0]  neighbors_ry;
593
    output[RXw-1  :    0]  next_rx;
594
    output[RYw-1  :    0]  next_ry;
595
 
596
    binary_mux #(
597
        .IN_WIDTH(PRXw),
598
        .OUT_WIDTH(RXw)
599
    )
600
    next_x_mux
601
    (
602
        .mux_in(neighbors_rx),
603
        .mux_out(next_rx),
604
        .sel(destport_bin)
605
    );
606
 
607
    binary_mux  #(
608
        .IN_WIDTH(PRYw),
609
        .OUT_WIDTH(RYw)
610
    )
611
    next_y_mux
612
    (
613
        .mux_in(neighbors_ry),
614
        .mux_out(next_ry),
615
        .sel(destport_bin)
616
    );
617
 
618
endmodule
619
 
620
 
621
 
622
 

powered by: WebSVN 2.1.0

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