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/] [fattree_route.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
*   fattree rout function
5
*
6
***************************************/
7
 
8
// ============================================================
9
//  FATTREE: Nearest Common Ancestor w/ Random  Routing Up
10
// ============================================================
11
 
12
module fattree_nca_random_up_routing  #(
13
   parameter K   = 2, // number of last level individual router`s endpoints.
14
   parameter L   = 2 // Fattree layer number (The height of FT)
15
 
16
)
17
(
18
    reset,
19
    clk,
20
    current_addr_encoded,    // connected to current router x address
21
    current_level,    //connected to current router y address
22
    dest_addr_encoded,        // destination address
23
    destport_encoded    // router output port
24
 
25
);
26
 
27
 
28
    function integer log2;
29
      input integer number; begin
30
         log2=(number <=1) ? 1: 0;
31
         while(2**log2<number) begin
32
            log2=log2+1;
33
         end
34
      end
35
    endfunction // log2 
36
 
37
 
38
    localparam
39
        Kw = log2(K),
40
        LKw= L*Kw,
41
        Lw = log2(L);
42
 
43
 
44
 
45
    input reset,clk;
46
    input  [LKw-1 :0]    current_addr_encoded;
47
    input  [Lw-1  :0]    current_level;
48
    input  [LKw-1 :0]    dest_addr_encoded;
49
    output [K :0]    destport_encoded;
50
    /******************
51
        destport_encoded format in fat tree. K+1 bit
52
        destport[K]
53
            1'b0  : go down
54
            1'b1  : go up
55
        destport[K-1: 0]:
56
            onehot coded. asserted bit show the output port locatation
57
    *******************/
58
 
59
 
60
 
61
    wire  [Kw-1 :0]  current_addr [L-1 : 0];
62
    wire  [Kw-1 :0]  parrent_dest_addr [L-1 : 0];
63
    wire  [Kw-1 :0]  dest_addr [L-1 : 0];
64
    wire  [Kw-1 :0]  current_node_dest_port;
65
 
66
    wire [L-1 : 0] parrents_node_missmatch;
67
 
68
    reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
69
 
70
`ifdef SYNC_RESET_MODE
71
    always @ (posedge clk )begin
72
`else
73
    always @ (posedge clk or posedge reset)begin
74
`endif
75
        if(reset) begin
76
            counter <= 1;
77
        end
78
        else begin
79
            counter <= {counter[0],counter[K-1:1]};
80
        end
81
    end
82
 
83
    assign current_addr [0]={Kw{1'b0}};
84
    assign parrent_dest_addr [0]={Kw{1'b0}};
85
 
86
    genvar i;
87
    generate
88
    for(i=1; i<L; i=i+1)begin : caddr
89
        /* verilator lint_off WIDTH */
90
        assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
91
        assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
92
        /* verilator lint_on WIDTH */
93
    end
94
 
95
 
96
    for(i=0; i<L; i=i+1) begin : daddr
97
       // assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
98
 
99
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
100
        assign parrents_node_missmatch[i]=  current_addr [i] !=  parrent_dest_addr [i];
101
    end//for
102
    endgenerate
103
 
104
   assign current_node_dest_port = dest_addr[current_level];
105
   wire [K-1:0] current_node_dest_port_one_hot;
106
 
107
   bin_to_one_hot #(
108
    .BIN_WIDTH(Kw),
109
    .ONE_HOT_WIDTH(K)
110
   )
111
   conv
112
   (
113
    .bin_code(current_node_dest_port),
114
    .one_hot_code(current_node_dest_port_one_hot)
115
   );
116
 
117
    assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,counter} :  /*go down*/{1'b0,current_node_dest_port_one_hot};
118
 
119
endmodule
120
 
121
 
122
 
123
// ============================================================
124
//  FATTREE: Nearest Common Ancestor w/ destination port Up. 
125
//  The up port is selected based on destination connected port num
126
// ============================================================
127
 
128
module fattree_nca_destp_up_routing  #(
129
   parameter K   = 2, // number of last level individual router`s endpoints.
130
   parameter L   = 2 // Fattree layer number (The height of FT)
131
 
132
)
133
(
134
    reset,
135
    clk,
136
    current_addr_encoded,    // connected to current router x address
137
    current_level,    //connected to current router y address
138
    dest_addr_encoded,        // destination address
139
    destport_encoded    // router output port
140
 
141
);
142
 
143
 
144
    function integer log2;
145
      input integer number; begin
146
         log2=(number <=1) ? 1: 0;
147
         while(2**log2<number) begin
148
            log2=log2+1;
149
         end
150
      end
151
    endfunction // log2 
152
 
153
 
154
    localparam
155
        Kw = log2(K),
156
        LKw= L*Kw,
157
        Lw = log2(L);
158
 
159
 
160
 
161
    input reset,clk;
162
    input  [LKw-1 :0]    current_addr_encoded;
163
    input  [Lw-1  :0]    current_level;
164
    input  [LKw-1 :0]    dest_addr_encoded;
165
    output [K :0]    destport_encoded;
166
    /******************
167
        destport_encoded format in fat tree. K+1 bit
168
        destport[K]
169
            1'b0  : go down
170
            1'b1  : go up
171
        destport[K-1: 0]:
172
            onehot coded. asserted bit show the output port locatation
173
    *******************/
174
 
175
 
176
 
177
    wire  [Kw-1 :0]  current_addr [L-1 : 0];
178
    wire  [Kw-1 :0]  parrent_dest_addr [L-1 : 0];
179
    wire  [Kw-1 :0]  dest_addr [L-1 : 0];
180
    wire  [Kw-1 :0]  current_node_dest_port;
181
 
182
    wire [L-1 : 0] parrents_node_missmatch;
183
 
184
    reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
185
 
186
`ifdef SYNC_RESET_MODE
187
    always @ (posedge clk )begin
188
`else
189
    always @ (posedge clk or posedge reset)begin
190
`endif
191
        if(reset) begin
192
            counter <= 1;
193
        end
194
        else begin
195
            counter <= {counter[0],counter[K-1:1]};
196
        end
197
    end
198
 
199
    assign current_addr [0]={Kw{1'b0}};
200
    assign parrent_dest_addr [0]={Kw{1'b0}};
201
 
202
    genvar i;
203
    generate
204
    for(i=1; i<L; i=i+1) begin : caddr
205
        assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
206
        assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
207
    end
208
 
209
 
210
    for(i=0; i<L; i=i+1) begin : daddr
211
       // assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
212
 
213
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
214
        assign parrents_node_missmatch[i]=  current_addr [i] !=  parrent_dest_addr [i];
215
    end//for
216
    endgenerate
217
 
218
   assign current_node_dest_port = dest_addr[current_level];
219
   wire [K-1:0] current_node_dest_port_one_hot;
220
 
221
   bin_to_one_hot #(
222
    .BIN_WIDTH(Kw),
223
    .ONE_HOT_WIDTH(K)
224
   )
225
   conv
226
   (
227
    .bin_code(current_node_dest_port),
228
    .one_hot_code(current_node_dest_port_one_hot)
229
   );
230
 
231
    assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,current_node_dest_port_one_hot} :  /*go down*/{1'b0,current_node_dest_port_one_hot};
232
 
233
endmodule
234
 
235
 
236
// ============================================================
237
//  FATTREE: Nearest Common Ancestor w/ straight port Up. 
238
//  The up port is in the same column as reciver port
239
// ============================================================
240
 
241
module fattree_nca_straight_up_routing  #(
242
   parameter K   = 2, // number of last level individual router`s endpoints.
243
   parameter L   = 2 // Fattree layer number (The height of FT)
244
 
245
)
246
(
247
    reset,
248
    clk,
249
    current_addr_encoded,    // connected to current router x address
250
    current_level,    //connected to current router y address
251
    dest_addr_encoded,        // destination address
252
    destport_encoded    // router output port
253
 
254
);
255
 
256
 
257
 
258
 
259
    function integer log2;
260
      input integer number; begin
261
         log2=(number <=1) ? 1: 0;
262
         while(2**log2<number) begin
263
            log2=log2+1;
264
         end
265
      end
266
    endfunction // log2 
267
 
268
 
269
    localparam
270
        Kw = log2(K),
271
        LKw= L*Kw,
272
        Lw = log2(L);
273
 
274
 
275
 
276
    input reset,clk;
277
 
278
    input  [LKw-1 :0]    current_addr_encoded;
279
    input  [Lw-1  :0]    current_level;
280
    input  [LKw-1 :0]    dest_addr_encoded;
281
    output [K :0]    destport_encoded;
282
 
283
    /******************
284
        destport_encoded format in fat tree. K+1 bit
285
        destport[K]
286
            1'b0  : go down
287
            1'b1  : go up
288
        destport[K-1: 0]:
289
            onehot coded. asserted bit show the output port locatation
290
    *******************/
291
 
292
 
293
 
294
    wire  [Kw-1 :0]  current_addr [L-1 : 0];
295
    wire  [Kw-1 :0]  parrent_dest_addr [L-1 : 0];
296
    wire  [Kw-1 :0]  dest_addr [L-1 : 0];
297
    wire  [Kw-1 :0]  current_node_dest_port;
298
 
299
    wire [L-1 : 0] parrents_node_missmatch;
300
 
301
    reg [K-1 : 0] counter; // a one hot counter. The value of the counter is used as a random destination port number when going to the up ports
302
 
303
`ifdef SYNC_RESET_MODE
304
    always @ (posedge clk )begin
305
`else
306
    always @ (posedge clk or posedge reset)begin
307
`endif
308
        if(reset) begin
309
            counter <= 1;
310
        end
311
        else begin
312
            counter <= {counter[0],counter[K-1:1]};
313
        end
314
    end
315
 
316
    assign current_addr [0]={Kw{1'b0}};
317
    assign parrent_dest_addr [0]={Kw{1'b0}};
318
 
319
    genvar i;
320
    generate
321
    for(i=1; i<L; i=i+1)begin : caddr
322
        assign current_addr [i] = (current_level <i)? current_addr_encoded[i*Kw-1 : (i-1)*Kw] : {Kw{1'b0}};
323
        assign parrent_dest_addr [i] = (current_level<i)? dest_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
324
    end
325
 
326
 
327
    for(i=0; i<L; i=i+1)begin : daddr
328
       // assign current_addr [i] = (current_level >=i)? current_addr_encoded[(i+1)*Kw-1 : i*Kw] : {Kw{1'b0}};
329
 
330
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
331
        assign parrents_node_missmatch[i]=  current_addr [i] !=  parrent_dest_addr [i];
332
    end//for
333
    endgenerate
334
 
335
   assign current_node_dest_port = dest_addr[current_level];
336
   wire [K-1:0] current_node_dest_port_one_hot;
337
 
338
   bin_to_one_hot #(
339
    .BIN_WIDTH(Kw),
340
    .ONE_HOT_WIDTH(K)
341
   )
342
   conv
343
   (
344
    .bin_code(current_node_dest_port),
345
    .one_hot_code(current_node_dest_port_one_hot)
346
   );
347
 
348
    // if going up the destination port num is statis straigh. It will be filled at reciver port of the next router so leave it empty
349
    assign destport_encoded = (parrents_node_missmatch != {L{1'b0}}) ? /*go up*/{1'b1,{K{1'b0}}} :  /*go down*/{1'b0,current_node_dest_port_one_hot};
350
 
351
endmodule
352
 
353
 
354
module    fattree_destport_up_select #(
355
      parameter   K=3,
356
      parameter   SW_LOC=0
357
)(
358
        destport_in,
359
        destport_o
360
);
361
 
362
    input  [K :0]    destport_in;
363
    output [K :0]    destport_o;
364
 
365
    localparam [K-1 : 0] SW_LOC_ONHOT = 1<< SW_LOC;
366
 
367
 
368
    wire going_up = destport_in[K];
369
    assign destport_o = (going_up)?  {1'b1,SW_LOC_ONHOT[K-1 : 0]} : destport_in;
370
 
371
endmodule
372
 
373
 
374
 
375
/*************************
376
 *  fattree_conventional_routing
377
 * **********************/
378
 
379
 
380
module fattree_conventional_routing #(
381
    parameter ROUTE_NAME = "NCA_RND_UP",
382
    parameter K   = 2, // number of last level individual router`s endpoints.
383
    parameter L   = 2 // Fattree layer number (The height of FT)
384
 )
385
(
386
    reset,
387
    clk,
388
    current_addr_encoded,    // connected to current router x address
389
    current_level,    //connected to current router y address
390
    dest_addr_encoded,        // destination address
391
    destport_encoded    // router output port
392
 
393
);
394
 
395
 
396
    function integer log2;
397
      input integer number; begin
398
         log2=(number <=1) ? 1: 0;
399
         while(2**log2<number) begin
400
            log2=log2+1;
401
         end
402
      end
403
    endfunction // log2 
404
 
405
 
406
    localparam
407
        Kw = log2(K),
408
        LKw= L*Kw,
409
        Lw = log2(L);
410
 
411
 
412
 
413
    input reset,clk;
414
    input  [LKw-1 :0]    current_addr_encoded;
415
    input  [Lw-1  :0]    current_level;
416
    input  [LKw-1 :0]    dest_addr_encoded;
417
    output [K :0]    destport_encoded;
418
 
419
 
420
    generate
421
    /* verilator lint_off WIDTH */
422
    if( ROUTE_NAME == "NCA_RND_UP")begin :nca_rnd
423
    /* verilator lint_on WIDTH */
424
        fattree_nca_random_up_routing #(
425
            .K(K),
426
            .L(L)
427
        )
428
        nca_random_up
429
        (
430
            .reset(reset),
431
            .clk(clk),
432
            .current_addr_encoded(current_addr_encoded),
433
            .current_level(current_level),
434
            .dest_addr_encoded(dest_addr_encoded),
435
            .destport_encoded(destport_encoded)
436
        );
437
     /* verilator lint_off WIDTH */
438
    end else if ( ROUTE_NAME == "NCA_DST_UP")begin :nca_dst
439
    /* verilator lint_on WIDTH */
440
        fattree_nca_destp_up_routing #(
441
            .K(K),
442
            .L(L)
443
        )
444
        nca_random_up
445
        (
446
            .reset(reset),
447
            .clk(clk),
448
            .current_addr_encoded(current_addr_encoded),
449
            .current_level(current_level),
450
            .dest_addr_encoded(dest_addr_encoded),
451
            .destport_encoded(destport_encoded)
452
        );
453
   /* verilator lint_off WIDTH */
454
   end else if ( ROUTE_NAME == "NCA_STRAIGHT_UP")begin :nca_straight
455
    /* verilator lint_on WIDTH */
456
        fattree_nca_straight_up_routing #(
457
            .K(K),
458
            .L(L)
459
        )
460
        nca_straight_up
461
        (
462
            .reset(reset),
463
            .clk(clk),
464
            .current_addr_encoded(current_addr_encoded),
465
            .current_level(current_level),
466
            .dest_addr_encoded(dest_addr_encoded),
467
            .destport_encoded(destport_encoded)
468
        );
469
    end else begin
470
        // synthesis translate_off
471
        initial begin
472
            $display( "\t ERROR: %s is an undefined routing algorithm for FATTREE topology",ROUTE_NAME);
473
            $finish;
474
        end
475
        // synthesis translate_on
476
    end
477
    endgenerate
478
 
479
endmodule
480
 
481
 
482
/************************************
483
 
484
     fattree_look_ahead_routing
485
 
486
*************************************/
487
 
488
module fattree_look_ahead_routing #(
489
    parameter ROUTE_NAME = "NCA_RND_UP",
490
    parameter P = 4,
491
    parameter L = 2,
492
    parameter K = 2
493
 
494
)
495
(
496
    reset,
497
    clk,
498
    destport_encoded,// current router destination port 
499
    dest_addr_encoded,
500
    neighbors_rx,
501
    neighbors_ry,
502
    lkdestport_encoded // look ahead destination port     
503
);
504
 
505
   function integer log2;
506
      input integer number; begin
507
         log2=(number <=1) ? 1: 0;
508
         while(2**log2<number) begin
509
            log2=log2+1;
510
         end
511
      end
512
    endfunction // log2 
513
 
514
 
515
    localparam
516
        Kw = log2(K),
517
        LKw= L*Kw,
518
        Lw = log2(L),
519
        PLw = P * Lw,
520
        PLKw = P * LKw;
521
 
522
    input  [K :0]    destport_encoded;
523
    input  [LKw-1 :0]    dest_addr_encoded;
524
    input  [PLKw-1 : 0]  neighbors_rx;
525
    input  [PLw-1 : 0]  neighbors_ry;
526
    output [K: 0]    lkdestport_encoded;
527
    input                   reset,clk;
528
 
529
    reg  [K :0]    destport_encoded_delayed;
530
    reg  [LKw-1 :0]    dest_addr_encoded_delayed;
531
 
532
     fattree_deterministic_look_ahead_routing #(
533
        .P(P),
534
        .ROUTE_NAME(ROUTE_NAME),
535
        .K(K),
536
        .L(L)
537
     )
538
     look_ahead_routing
539
     (
540
        .reset(reset),
541
        .clk(clk),
542
        .destport_encoded(destport_encoded_delayed),
543
        .dest_addr_encoded(dest_addr_encoded_delayed),
544
        .neighbors_rx(neighbors_rx),
545
        .neighbors_ry(neighbors_ry),
546
        .lkdestport_encoded(lkdestport_encoded)
547
     );
548
 
549
 
550
`ifdef SYNC_RESET_MODE
551
    always @ (posedge clk )begin
552
`else
553
    always @ (posedge clk or posedge reset)begin
554
`endif
555
        if(reset)begin
556
            destport_encoded_delayed <= {(K+1){1'b0}};
557
            dest_addr_encoded_delayed<= {LKw{1'b0}};
558
        end else begin
559
            destport_encoded_delayed<=destport_encoded;
560
            dest_addr_encoded_delayed<=dest_addr_encoded;
561
        end//else reset
562
    end//always
563
 
564
endmodule
565
 
566
 
567
 
568
 
569
 
570
 
571
 
572
/************************************************
573
 
574
        deterministic_look_ahead_routing
575
**********************************************/
576
 
577
 
578
module  fattree_deterministic_look_ahead_routing #(
579
    parameter P=4,
580
    parameter ROUTE_NAME = "NCA_RND_UP",
581
    parameter K   = 2, // number of last level individual router`s endpoints.
582
    parameter L   = 2 // Fattree layer number (The height of FT)
583
 
584
  )
585
  (
586
    reset,
587
    clk,
588
    destport_encoded,// current router destination port 
589
    dest_addr_encoded,
590
    neighbors_rx,
591
    neighbors_ry,
592
    lkdestport_encoded // look ahead destination port     
593
 );
594
 
595
 
596
   function integer log2;
597
      input integer number; begin
598
         log2=(number <=1) ? 1: 0;
599
         while(2**log2<number) begin
600
            log2=log2+1;
601
         end
602
      end
603
    endfunction // log2 
604
 
605
 
606
    localparam
607
        Kw = log2(K),
608
        LKw= L*Kw,
609
        Lw = log2(L),
610
        PLw = P * Lw,
611
        PLKw = P * LKw;
612
 
613
    input reset,clk;
614
    input  [K :0]    destport_encoded;
615
    input  [LKw-1 :0]    dest_addr_encoded;
616
    input  [PLKw-1 : 0]  neighbors_rx;
617
    input  [PLw-1 : 0]  neighbors_ry;
618
    output [K: 0]    lkdestport_encoded;
619
 
620
 
621
    wire  [LKw-1 :0]    next_addr_encoded;
622
    wire  [Lw-1  :0]    next_level;
623
    wire  [K : 0] lkdestport_encoded;
624
    wire  [2*K-1 : 0] destport_decoded;
625
 
626
    fattree_destport_decoder #(
627
        .K(K)
628
    )
629
    fattree_destport_decoder(
630
        .destport_encoded_i(destport_encoded),
631
        .destport_decoded_o(destport_decoded)
632
    );
633
 
634
 
635
    next_router_addr_selector_onehot #(
636
         .P(P),
637
         .RXw(LKw),
638
         .RYw(Lw)
639
    )
640
    addr_predictor
641
    (
642
        .destport_onehot(destport_decoded[P-1 : 0]),
643
        .neighbors_rx(neighbors_rx),
644
        .neighbors_ry(neighbors_ry),
645
        .next_rx(next_addr_encoded),
646
        .next_ry(next_level)
647
    );
648
 
649
 
650
    fattree_conventional_routing #(
651
        .ROUTE_NAME(ROUTE_NAME),
652
        .K(K),
653
        .L(L)
654
    )
655
    conv_routing
656
    (
657
        .reset(reset),
658
        .clk(clk),
659
        .current_addr_encoded(next_addr_encoded),
660
        .current_level(next_level),
661
        .dest_addr_encoded(dest_addr_encoded),
662
        .destport_encoded(lkdestport_encoded)
663
    );
664
 
665
 endmodule
666
 
667
 module fattree_destport_decoder #(
668
     parameter K=2
669
 
670
 )(
671
    destport_decoded_o,
672
    destport_encoded_i
673
 );
674
 
675
    input [K:0] destport_encoded_i;
676
    output [2*K-1 : 0] destport_decoded_o;
677
 
678
    assign destport_decoded_o =   (destport_encoded_i[K])? /*go up*/    {destport_encoded_i[K-1:0],{K{1'b0}}}:
679
                                                           /*go down*/   {{K{1'b0}},destport_encoded_i[K-1:0]};
680
 
681
endmodule
682
 
683
 
684
 
685
 
686
/**********
687
 *  fattree_mask_non_assignable_destport
688
 * ********/
689
 
690
module fattree_mask_non_assignable_destport #(
691
    parameter K=4,
692
    parameter P=2*K,
693
    parameter SW_LOC = 0
694
)
695
(
696
    destport_in,
697
    destport_out
698
);
699
 
700
    input [2*K-1 : 0] destport_in;
701
    output [2*K-1 : 0] destport_out;
702
 
703
    generate
704
    if(P<=K)begin :root //This is a root node there is conectivety between all ports
705
        assign destport_out = destport_in;
706
    end else begin: leaf
707
        if(SW_LOC < K) begin: down // This port located in lower side of the router. It can send packet to any destport 
708
            assign destport_out = destport_in;
709
        end else begin : up // // This port located in upper side of the router. It cannot send packet to upper port anymore
710
            assign destport_out[2*K-1 : K] = {K{1'b0}};
711
            assign destport_out[K-1 : 0] = destport_in [K-1 : 0];
712
        end
713
    end
714
    endgenerate
715
endmodule
716
 
717
/********************
718
 
719
    distance_gen
720
 
721
********************/
722
 
723
module fattree_distance_gen #(
724
    parameter K= 4,
725
    parameter L= 4
726
)(
727
    src_addr_encoded,
728
    dest_addr_encoded,
729
    distance
730
 
731
);
732
 
733
    function integer log2;
734
      input integer number; begin
735
         log2=(number <=1) ? 1: 0;
736
         while(2**log2<number) begin
737
            log2=log2+1;
738
         end
739
      end
740
    endfunction // log2 
741
 
742
     localparam
743
        Kw = log2(K),
744
        LKw= L*Kw,
745
        DISTw= log2(2*L+1);
746
 
747
     input  [LKw-1 :0]    src_addr_encoded;
748
     input  [LKw-1 :0]    dest_addr_encoded;
749
     output reg [DISTw-1 : 0] distance;
750
 
751
 
752
 
753
     wire  [Kw-1 :0]  dest_addr [L-1 : 0];
754
     wire  [Kw-1 :0]  src_addr [L-1 : 0];
755
     wire  [L-1 : 0] diffrent;
756
 
757
 
758
    genvar i;
759
    generate
760
    for(i=0; i<L; i=i+1)begin : daddr
761
        assign dest_addr [i] =  dest_addr_encoded[(i+1)*Kw-1 : i*Kw];
762
        assign src_addr [i] =  src_addr_encoded[(i+1)*Kw-1 : i*Kw];
763
        assign diffrent[i] = dest_addr [i] != src_addr [i];
764
    end//for
765
    endgenerate
766
 
767
    wire [11:0] tmp;
768
    assign tmp= {{(12-L){1'b0}},diffrent};
769
    /* verilator lint_off WIDTH */
770
    always @(*)begin
771
        if (tmp[10]) distance =21;
772
        else if (tmp[9]) distance =19;
773
        else if (tmp[8]) distance =17;
774
        else if (tmp[7]) distance =15;
775
        else if (tmp[6]) distance =13;
776
        else if (tmp[5]) distance =11;
777
        else if (tmp[4]) distance =9;
778
        else if (tmp[3]) distance =7;
779
        else if (tmp[2]) distance =5;
780
        else if (tmp[1]) distance =3;
781
        else distance =1;
782
    end
783
    /* verilator lint_on WIDTH */
784
 
785
 
786
 
787
 
788
endmodule
789
 
790
/**************
791
    fattree_addr_encoder
792
    most probably it is only needed for simulation purposes
793
***************/
794
 
795
module  fattree_addr_encoder #(
796
    parameter   K=2,
797
    parameter   L=2
798
 
799
)(
800
    id,
801
    code
802
);
803
 
804
    function integer log2;
805
      input integer number; begin
806
         log2=(number <=1) ? 1: 0;
807
         while(2**log2<number) begin
808
            log2=log2+1;
809
         end
810
      end
811
    endfunction // log2 
812
 
813
    function integer powi;
814
        input integer x,y;
815
        integer i;begin //compute x to the y
816
        powi=1;
817
        for (i = 0; i <y; i=i+1 ) begin
818
            powi=powi * x;
819
        end
820
        end
821
    endfunction // log2 
822
 
823
    function integer addrencode;
824
        input integer pos,k,n,kw;
825
        integer pow,i,tmp;begin
826
        addrencode=0;
827
        pow=1;
828
        for (i = 0; i <n; i=i+1 ) begin
829
            tmp=(pos/pow);
830
            tmp=tmp%k;
831
            tmp=tmp<<i*kw;
832
            addrencode=addrencode | tmp;
833
            pow=pow * k;
834
        end
835
        end
836
    endfunction // log2 
837
 
838
 
839
    localparam
840
        NE = powi( K,L ),  //total number of endpoints
841
        NEw = log2(NE),
842
        Kw=log2(K),
843
        LKw=L*Kw;
844
 
845
 
846
     input [NEw-1 :0] id;
847
     output [LKw-1 : 0] code;
848
 
849
    wire [LKw-1 : 0 ] codes [NE-1 : 0];
850
    genvar i;
851
    generate
852
    for(i=0; i< NE; i=i+1) begin : endpoints
853
        //Endpoint decoded address
854
        localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
855
        assign codes[i] = ENDPX;
856
    end
857
    endgenerate
858
 
859
    assign code = codes[id];
860
endmodule
861
 
862
 
863
 
864
/**************
865
    fattree_addr_decoder
866
    most probably it is only needed for simulation
867
***************/
868
 
869
module  fattree_addr_decoder #(
870
    parameter   K=2,
871
    parameter   L=2
872
 
873
)(
874
    id,
875
    code
876
);
877
 
878
    function integer log2;
879
      input integer number; begin
880
         log2=(number <=1) ? 1: 0;
881
         while(2**log2<number) begin
882
            log2=log2+1;
883
         end
884
      end
885
    endfunction // log2 
886
 
887
    function integer powi;
888
        input integer x,y;
889
        integer i;begin //compute x to the y
890
        powi=1;
891
        for (i = 0; i <y; i=i+1 ) begin
892
            powi=powi * x;
893
        end
894
        end
895
    endfunction // log2 
896
 
897
    function integer addrencode;
898
        input integer pos,k,n,kw;
899
        integer pow,i,tmp;begin
900
        addrencode=0;
901
        pow=1;
902
        for (i = 0; i <n; i=i+1 ) begin
903
            tmp=(pos/pow);
904
            tmp=tmp%k;
905
            tmp=tmp<<i*kw;
906
            addrencode=addrencode | tmp;
907
            pow=pow * k;
908
        end
909
        end
910
    endfunction // log2 
911
 
912
 
913
    localparam
914
        NE = powi( K,L ),  //total number of endpoints
915
        NEw = log2(NE),
916
        Kw=log2(K),
917
        LKw=L*Kw;
918
 
919
 
920
     output [NEw-1 :0] id;
921
     input  [LKw-1 : 0] code;
922
 
923
    wire  [NEw-1 : 0] codes  [2**LKw-1 : 0 ];
924
    genvar i;
925
    generate
926
    for(i=0; i< NE; i=i+1) begin : endpoints
927
        //Endpoint decoded address
928
        /* verilator lint_off WIDTH */
929
        localparam [LKw-1 : 0] ENDPX= addrencode(i,K,L,Kw);
930
        /* verilator lint_on WIDTH */
931
        assign codes[ENDPX] = i;
932
    end
933
    endgenerate
934
 
935
    assign id = codes[code];
936
endmodule
937
 
938
/**************
939
 * mesh_torus_ssa_check_destport_conflict
940
 * check if the incomming flit goes to SS port
941
 * ************/
942
 
943
module fattree_ssa_check_destport #(
944
    parameter DSTPw = 5,
945
    parameter SS_PORT=0
946
)
947
(
948
    destport_encoded, //exsited packet dest port
949
    destport_in_encoded, // incomming packet dest port
950
    ss_port_hdr_flit, // asserted if the header incomming flit goes to ss port
951
    ss_port_nonhdr_flit // asserted if the body or tail incomming flit goes to ss port
952
 );
953
 
954
    localparam K= DSTPw-1;
955
    localparam SS_LOC = (SS_PORT < K)? SS_PORT : SS_PORT-K;
956
 
957
    input [DSTPw-1 : 0] destport_encoded, destport_in_encoded;
958
    output ss_port_hdr_flit, ss_port_nonhdr_flit;
959
 
960
 
961
/******************
962
        destport_encoded format in fat tree. K+1 bit
963
        destport[K]
964
            1'b0  : go down
965
            1'b1  : go up
966
        destport[K-1: 0]:
967
            onehot coded. asserted bit show the output port locatation
968
*******************/
969
 
970
    wire up_flg = destport_encoded[DSTPw-1];
971
    wire up_flg_in = destport_in_encoded[DSTPw-1];
972
    wire down_flg = ~destport_encoded[DSTPw-1];
973
    wire down_flg_in = ~destport_in_encoded[DSTPw-1];
974
 
975
 
976
    generate
977
    if(SS_PORT < K) begin :SS_DOWN // the ssa port is located in down router side
978
        assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & down_flg_in;
979
        assign ss_port_nonhdr_flit =  destport_encoded[SS_LOC] & down_flg;
980
    end else begin : SS_UP
981
        assign ss_port_hdr_flit = destport_in_encoded [SS_LOC] & up_flg_in;
982
        assign ss_port_nonhdr_flit =  destport_encoded[SS_LOC] & up_flg;
983
    end
984
    endgenerate
985
 
986
endmodule
987
 
988
/*
989
module fattree_add_ss_port #(
990
    parameter SW_LOC=1,
991
    parameter P=5
992
)(
993
    destport_in,
994
    destport_out
995
);
996
    localparam
997
        P_1     =   P-1,
998
        DISABLED   =    P;
999
 
1000
    localparam  SS_PORT_FATTREE_EVEN =  (SW_LOC < (P/2) )? (P/2)+ SW_LOC-1 : SW_LOC - (P/2);
1001
    localparam  SS_PORT_FATTREE_ODD  =  (SW_LOC == (P-1)/2)?   DISABLED:
1002
                                        (SW_LOC < ((P+1)/2) )? ((P+1)/2)+ SW_LOC-1 : SW_LOC - ((P+1)/2);
1003
 
1004
    localparam  SS_PORT_FATTREE = (P[0]==1'b0) ? SS_PORT_FATTREE_EVEN : SS_PORT_FATTREE_ODD;
1005
 
1006
    localparam  SS_PORT      =   SS_PORT_FATTREE;
1007
 
1008
 
1009
 
1010
 
1011
    input       [P_1-1  :   0] destport_in;
1012
    output reg  [P_1-1  :   0] destport_out;
1013
 
1014
 
1015
 
1016
    always @(*)begin
1017
        destport_out=destport_in;
1018
        if( SS_PORT != DISABLED ) begin
1019
            if(destport_in=={P_1{1'b0}}) destport_out[SS_PORT]= 1'b1;
1020
        end
1021
    end
1022
 
1023
 
1024
endmodule
1025
 */
1026
module fattree_router_addr_decode #(
1027
    parameter K=4,
1028
    parameter L=4
1029
)(
1030
    r_addr,
1031
    rx,
1032
    rl
1033
    //valid
1034
);
1035
 
1036
    function integer log2;
1037
      input integer number; begin
1038
         log2=(number <=1) ? 1: 0;
1039
         while(2**log2<number) begin
1040
            log2=log2+1;
1041
         end
1042
      end
1043
    endfunction // log2 
1044
 
1045
 
1046
    localparam
1047
        Kw = log2(K),
1048
        LKw= L*Kw,
1049
        Lw = log2(L),
1050
        RAw= LKw + Lw;
1051
 
1052
    input   [RAw-1 : 0]   r_addr;
1053
    output  [LKw-1 :0]    rx;
1054
    output  [Lw-1  :0]    rl;
1055
 
1056
    assign {rl,rx} = r_addr;
1057
 
1058
endmodule
1059
 
1060
 
1061
//decode and mask destport  
1062
module  fattree_destp_generator #(
1063
    parameter K=2,
1064
    parameter P=2*K,
1065
    parameter SW_LOC=0,
1066
    parameter DSTPw=4,
1067
    parameter SELF_LOOP_EN = "NO"
1068
)(
1069
    dest_port_in_encoded,
1070
    dest_port_out
1071
);
1072
 
1073
    localparam P_1 = (SELF_LOOP_EN == "NO")? P-1 : P;
1074
    input  [DSTPw-1:0] dest_port_in_encoded;
1075
    output [P_1-1 : 0] dest_port_out;
1076
 
1077
 
1078
    wire [2*K-1 : 0] destport_decoded;
1079
    wire [2*K-1 : 0] destport_masked;
1080
 
1081
 
1082
        fattree_destport_decoder #(
1083
            .K(K)
1084
        )
1085
        destport_decoder
1086
        (
1087
            .destport_encoded_i(dest_port_in_encoded),
1088
            .destport_decoded_o(destport_decoded)
1089
        );
1090
 
1091
        fattree_mask_non_assignable_destport #(
1092
            .K(K),
1093
            .P(P),
1094
            .SW_LOC(SW_LOC)
1095
        )
1096
        mask
1097
        (
1098
            .destport_in(destport_decoded),
1099
            .destport_out(destport_masked)
1100
        );
1101
 
1102
        generate
1103
        if(SELF_LOOP_EN == "NO") begin : nslp
1104
            remove_sw_loc_one_hot #(
1105
                .P(P),
1106
                .SW_LOC(SW_LOC)
1107
            )
1108
            conv
1109
            (
1110
                .destport_in(destport_masked[P-1 : 0]),
1111
                .destport_out(dest_port_out[P_1-1  :   0 ])
1112
            );
1113
        end else begin : slp
1114
            assign dest_port_out= destport_masked [P_1-1  :   0 ];
1115
        end
1116
        endgenerate
1117
 endmodule

powered by: WebSVN 2.1.0

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