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 48

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

Line No. Rev Author Line
1 48 alirezamon
`timescale     1ns/1ps
2
/**********************************************************************
3
**      File:  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
    parameter P         =5,
270
    parameter T1= 8,
271
    parameter T2= 8,
272
    parameter T3= 8,
273
    parameter T4= 8,
274
    parameter RAw = 3,
275
    parameter EAw = 3,
276
    parameter DSTPw=P-1,
277
    parameter SW_LOC    =0,
278
    parameter TOPOLOGY  ="MESH",//"MESH","TORUS"
279
    parameter ROUTE_NAME="XY",// 
280
    parameter ROUTE_TYPE="DETERMINISTIC"// "DETERMINISTIC", "FULL_ADAPTIVE", "PAR_ADAPTIVE"
281
)
282
(
283
    current_r_addr,  //current router  address
284
    neighbors_r_addr,
285
    dest_e_addr,  // destination endpoint address   
286
    src_e_addr, //   source endpoint address. Only needed for custom topology 
287
    destport_encoded,   // current router destination port number       
288
    lkdestport_encoded, // look ahead destination port number
289
    reset,
290
    clk
291
);
292
 
293
    function integer log2;
294
    input integer number; begin
295
       log2=(number <=1) ? 1: 0;
296
       while(2**log2<number) begin
297
          log2=log2+1;
298
       end
299
    end
300
    endfunction // log2 
301
 
302
    localparam
303
        PRAw= P * RAw;
304
    localparam
305
        //K= T1,
306
        //L=T2,
307
            Kw = log2(T1),
308
            Lw = log2(T2),
309
            LKw= T2 * Kw,
310
            PLw = P * Lw,
311
            PLKw = P * LKw;
312
 
313
    input   [PRAw-1:  0]  neighbors_r_addr;
314
    input   [RAw-1   :   0]  current_r_addr;
315
    input   [EAw-1   :   0]  dest_e_addr;
316
    input   [EAw-1   :   0]  src_e_addr;
317
    input   [DSTPw-1  :   0]  destport_encoded;
318
    output  [DSTPw-1  :   0]  lkdestport_encoded;
319
    input                   reset,clk;
320
 
321
    genvar i;
322
    generate
323
    /* verilator lint_off WIDTH */
324
    if(TOPOLOGY == "MESH" || TOPOLOGY == "FMESH" || TOPOLOGY == "TORUS"  || TOPOLOGY ==  "RING" || TOPOLOGY ==  "LINE")begin :mesh_torus
325
    /* verilator lint_on WIDTH */
326
 
327
       localparam
328
        NX = T1,
329
        NY = T2,
330
        RXw = log2(NX),
331
        RYw = log2(NY),
332
        EXw = RXw,
333
        EYw = RYw;
334
 
335
        wire   [RXw-1   :   0]  current_rx;
336
        wire   [RYw-1   :   0]  current_ry;
337
        wire   [EXw-1   :   0]  dest_ex;
338
        wire   [EYw-1   :   0]  dest_ey;
339
 
340
        localparam SL_SW_LOC = ( SW_LOC > P-T3) ? 0 : SW_LOC; //single_local   
341
 
342
        mesh_tori_router_addr_decode #(
343
            .TOPOLOGY(TOPOLOGY),
344
            .T1(T1),
345
            .T2(T2),
346
            .T3(T3),
347
            .RAw(RAw)
348
        )
349
        router_addr_decode
350
        (
351
            .r_addr(current_r_addr),
352
            .rx(current_rx),
353
            .ry(current_ry),
354
            .valid( )
355
        );
356
         /* verilator lint_off WIDTH */
357
        if(TOPOLOGY == "FMESH") begin :fmesh
358
         /* verilator lint_on WIDTH */
359
             fmesh_endp_addr_decode #(
360
                .T1(T1),
361
                .T2(T2),
362
                .T3(T3),
363
                .EAw(EAw)
364
            )
365
            end_addr_decode
366
            (
367
                .e_addr(dest_e_addr),
368
                .ex(dest_ex),
369
                .ey(dest_ey),
370
                .ep( ),
371
                .valid()
372
            );
373
        end else begin :mesh
374
            mesh_tori_endp_addr_decode #(
375
                .TOPOLOGY(TOPOLOGY),
376
                .T1(T1),
377
                .T2(T2),
378
                .T3(T3),
379
                .EAw(EAw)
380
            )
381
            end_addr_decode
382
            (
383
                .e_addr(dest_e_addr),
384
                .ex(dest_ex),
385
                .ey(dest_ey),
386
                .el( ),
387
                .valid()
388
            );
389
 
390
 
391
        end
392
 
393
        mesh_torus_look_ahead_routing #(
394
                .NX(T1),
395
                .NY(T2),
396
                .SW_LOC(SL_SW_LOC),
397
                .TOPOLOGY(TOPOLOGY),
398
                .ROUTE_NAME(ROUTE_NAME),
399
                .ROUTE_TYPE(ROUTE_TYPE)
400
        )
401
        look_ahead_route
402
        (
403
                .current_x(current_rx),
404
                .current_y(current_ry),
405
                .dest_x(dest_ex),
406
                .dest_y(dest_ey),
407
                .destport_encoded(destport_encoded),
408
                .lkdestport_encoded(lkdestport_encoded),
409
                .reset(reset),
410
                .clk(clk)
411
        );
412
    /* verilator lint_off WIDTH */
413
    end else if (TOPOLOGY == "FATTREE") begin: fat
414
    /* verilator lint_on WIDTH */
415
 
416
        wire  [PLKw-1 : 0]  neighbors_rx;
417
        wire  [PLw-1 : 0]  neighbors_ry;
418
 
419
        for (i=0; i<P; i=i+1) begin : port
420
            assign neighbors_rx[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
421
            assign neighbors_ry[(i+1)*Lw-1 : i*Lw]  = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
422
        end//port        
423
 
424
        fattree_look_ahead_routing #(
425
                .ROUTE_NAME(ROUTE_NAME),
426
                .P(P),
427
                .K(T1),
428
                .L(T2)
429
        )
430
        look_ahead_route
431
        (
432
                .destport_encoded(destport_encoded),
433
                .dest_addr_encoded(dest_e_addr),
434
                .neighbors_rx(neighbors_rx),
435
                .neighbors_ry(neighbors_ry),
436
                .lkdestport_encoded(lkdestport_encoded),
437
                .reset(reset),
438
                .clk(clk)
439
        );
440
 
441
    /* verilator lint_off WIDTH */
442
    end else if (TOPOLOGY == "TREE") begin: tree
443
    /* verilator lint_on WIDTH */
444
 
445
        wire  [PLKw-1 : 0]  neighbors_rx_tree;
446
        wire  [PLw-1 : 0]  neighbors_ry_tree;
447
 
448
        for (i=0; i<P; i=i+1) begin : port
449
            assign neighbors_rx_tree[(i+1)*LKw-1: i*LKw] = neighbors_r_addr[(i*RAw)+LKw-1 : i*RAw];
450
            assign neighbors_ry_tree[(i+1)*Lw-1 : i*Lw]  = neighbors_r_addr[(i+1)*RAw-1: (i*RAw)+LKw];
451
        end//port        
452
 
453
 
454
        tree_look_ahead_routing #(
455
                .ROUTE_NAME(ROUTE_NAME),
456
                .P(P),
457
                .L(T2),
458
                .K(T1)
459
        )
460
        look_ahead_routing
461
        (
462
                .destport_encoded(destport_encoded),
463
                .dest_addr_encoded(dest_e_addr),
464
                .neighbors_rx(neighbors_rx_tree),
465
                .neighbors_ry(neighbors_ry_tree),
466
                .lkdestport_encoded(lkdestport_encoded),
467
                .reset(reset),
468
                .clk(clk)
469
        );
470
 
471
      /* verilator lint_off WIDTH */
472
    end else if (TOPOLOGY == "STAR") begin : star
473
    /* verilator lint_on WIDTH */
474
     //look-ahead routing is not needed in star topology as there is only one router
475
        assign  lkdestport_encoded={DSTPw{1'b0}};
476
 
477
     end else begin : custom
478
 
479
        custom_lkh_routing  #(
480
            .TOPOLOGY(TOPOLOGY),
481
            .ROUTE_NAME(ROUTE_NAME),
482
            .ROUTE_TYPE(ROUTE_TYPE),
483
            .RAw(RAw),
484
            .EAw(EAw),
485
            .DSTPw(DSTPw)
486
        )
487
        look_ahead_routing
488
        (
489
            .current_r_addr(current_r_addr),
490
            .dest_e_addr(dest_e_addr),
491
            .src_e_addr(src_e_addr),
492
            .destport(lkdestport_encoded),
493
            .reset(reset),
494
            .clk(clk)
495
        );
496
 
497
    end
498
    endgenerate
499
endmodule
500
 
501
/********************************************************
502
 
503
                    next_router_addr_selector
504
 
505
Determine the next router address based on the packet destination port
506
 
507
********************************************************/
508
 
509
 
510
module next_router_addr_selector_onehot #(
511
    parameter P = 5,
512
    parameter RXw = 3,  // The router's x dimension adress width in bits
513
    parameter RYw = 3  // The router's y dimension adress width in bits
514
    )
515
    (
516
    destport_onehot,
517
    neighbors_rx,
518
    neighbors_ry,
519
    next_rx,
520
    next_ry
521
    );
522
 
523
    localparam
524
        PRXw = P * RXw,
525
        PRYw = P * RYw;
526
 
527
    input [P-1   :  0]  destport_onehot;
528
    input [PRXw-1:  0]  neighbors_rx;
529
    input [PRYw-1:  0]  neighbors_ry;
530
    output[RXw-1  :    0]  next_rx;
531
    output[RYw-1  :    0]  next_ry;
532
 
533
    onehot_mux_1D #(
534
        .W(RXw),
535
        .N(P)
536
    )
537
    next_x_mux
538
    (
539
        .in(neighbors_rx),
540
        .out(next_rx),
541
        .sel(destport_onehot)
542
    );
543
 
544
    onehot_mux_1D #(
545
        .W(RYw),
546
        .N(P)
547
    )
548
    next_y_mux
549
    (
550
        .in(neighbors_ry),
551
        .out(next_ry),
552
        .sel(destport_onehot)
553
    );
554
 
555
endmodule
556
 
557
 
558
 
559
 
560
 
561
module next_router_addr_selector_bin #(
562
    parameter P = 5,
563
    parameter RXw = 3,  // The router's x dimension adress width in bits
564
    parameter RYw = 3  // The router's y dimension adress width in bits
565
    )
566
    (
567
    destport_bin,
568
    neighbors_rx,
569
    neighbors_ry,
570
    next_rx,
571
    next_ry
572
 
573
    );
574
 
575
    function integer log2;
576
      input integer number; begin
577
         log2=(number <=1) ? 1: 0;
578
         while(2**log2<number) begin
579
            log2=log2+1;
580
         end
581
      end
582
    endfunction // log2 
583
 
584
    localparam
585
        Pw = log2(P),
586
        PRXw = P * RXw,
587
        PRYw = P * RYw;
588
 
589
    input [Pw-1   :  0]  destport_bin;
590
    input [PRXw-1:  0]  neighbors_rx;
591
    input [PRYw-1:  0]  neighbors_ry;
592
    output[RXw-1  :    0]  next_rx;
593
    output[RYw-1  :    0]  next_ry;
594
 
595
    binary_mux #(
596
        .IN_WIDTH(PRXw),
597
        .OUT_WIDTH(RXw)
598
    )
599
    next_x_mux
600
    (
601
        .mux_in(neighbors_rx),
602
        .mux_out(next_rx),
603
        .sel(destport_bin)
604
    );
605
 
606
    binary_mux  #(
607
        .IN_WIDTH(PRYw),
608
        .OUT_WIDTH(RYw)
609
    )
610
    next_y_mux
611
    (
612
        .mux_in(neighbors_ry),
613
        .mux_out(next_ry),
614
        .sel(destport_bin)
615
    );
616
 
617
endmodule
618
 
619
 
620
 
621
 

powered by: WebSVN 2.1.0

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