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

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

Line No. Rev Author Line
1 54 alirezamon
`include "pronoc_def.v"
2
 
3
/**************************************
4
 * Module: router_bypass
5
 * Date:2021-11-14
6
 * Author: alireza
7
 *
8
 * Description:
9
 *   This file contains HDL modules that can be added
10
 *   to NoC router to provide multicasting
11
 ***************************************/
12
 
13
 
14
 
15
 
16
 
17
/************************************
18
 
19
     look_ahead_routing
20
 
21
 *************************************/
22
 
23
module multicast_routing
24
                import pronoc_pkg::*;
25
        #(
26
                parameter P = 5,
27
                parameter SW_LOC = 0
28
                )
29
                (
30
                        current_r_addr,  //current router  address
31
                        dest_e_addr,  // destination endpoint address
32
                        destport
33
                );
34
 
35
        input   [RAw-1   :   0]  current_r_addr;
36
        input   [DAw-1   :   0]  dest_e_addr;
37
        output  [DSTPw-1  :   0] destport;
38
 
39
        generate
40
        /* verilator lint_off WIDTH */
41
        if(TOPOLOGY=="MESH") begin: mesh
42
        /* verilator lint_on WIDTH */
43
                multicast_routing_mesh
44
                #(
45
                        .P(P) ,
46
                        .SW_LOC(SW_LOC)
47
                )
48
                routing
49
                (
50
                        .current_r_addr(current_r_addr),  //current router  address
51
                        .dest_e_addr(dest_e_addr),  // destination endpoint address
52
                        .destport(destport)
53
                );
54
        /* verilator lint_off WIDTH */
55
        end else if (TOPOLOGY == "FMESH") begin : fmesh
56
        /* verilator lint_on WIDTH */
57
                multicast_routing_fmesh
58
                #(
59
                        .P(P) ,
60
                        .SW_LOC(SW_LOC)
61
                )
62
                routing
63
                (
64
                        .current_r_addr(current_r_addr),  //current router  address
65
                        .dest_e_addr(dest_e_addr),  // destination endpoint address
66
                        .destport(destport)
67
                );
68
 
69
        end else begin
70
                initial begin
71
                        $display ("ERROR: Multicast/Broadcast is not yet supported for %s Topology",TOPOLOGY);
72
                        $finish;
73
                end
74
        end
75
        endgenerate
76
 
77
 
78
 
79
endmodule
80
 
81
module multicast_routing_mesh
82
        import pronoc_pkg::*;
83
        #(
84
                parameter P = 5,
85
                parameter SW_LOC = 0
86
        )
87
        (
88
                current_r_addr,  //current router  address
89
                dest_e_addr,  // destination endpoint address
90
                destport
91
        );
92
 
93
 
94
 
95
        input   [RAw-1   :   0]  current_r_addr;
96
        input   [DAw-1   :   0]  dest_e_addr;
97
        output  [DSTPw-1  :   0] destport;
98
 
99
 
100
        localparam
101
                NX = T1,
102
                NY = T2,
103
                RXw = log2(NX),
104
                RYw = log2(NY),
105
                EXw = RXw,
106
                EYw = RYw;
107
 
108
 
109
        //mask gen. x_plus: all rows larger than current router x address are asserted.
110
        wire [NX-1 : 0] x_plus,x_minus;
111
        //mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
112
        wire [NE-1 : 0] y_plus,y_min;
113
        //Only one-bit is asserted for each local_p[i]
114
        wire [NE-1 : 0] local_p [NL-1 : 0];
115
 
116
        wire   [RXw-1   :   0]  current_rx;
117
        wire   [RYw-1   :   0]  current_ry;
118
 
119
        mesh_tori_router_addr_decode #(
120
                        .TOPOLOGY(TOPOLOGY),
121
                        .T1(T1),
122
                        .T2(T2),
123
                        .T3(T3),
124
                        .RAw(RAw)
125
                )
126
                router_addr_decode
127
                (
128
                        .r_addr(current_r_addr),
129
                        .rx(current_rx),
130
                        .ry(current_ry),
131
                        .valid( )
132
                );
133
 
134
 
135
 
136
                wire [NX-1 : 0] row_has_any_dest;
137
                wire [NE-1 : 0] dest_mcast_all_endp;
138
 
139
                mcast_dest_list_decode decode (
140
                        .dest_e_addr(dest_e_addr),
141
                        .dest_o(dest_mcast_all_endp),
142
                        .row_has_any_dest(row_has_any_dest),
143
                        .is_unicast()
144
                );
145
 
146
                genvar i,j;
147
                generate
148
 
149
                        for(i=0; i< NX; i=i+1) begin : X_
150
                                assign x_plus[i]  = (current_rx >       i);
151
                                /* verilator lint_off UNSIGNED */
152
                                assign x_minus[i] = (current_rx <        i);
153
                                /* verilator lint_on UNSIGNED */
154
                        end
155
 
156
                        //get all endp addresses located in the same x
157
                        for(i=0; i< NE; i=i+1) begin : endpoints
158
                        //Endpoint decoded address
159
 
160
                                        localparam
161
                                                Y_LOC = ((i/NL) / NX ),
162
                                                X_LOC = ((i/NL) % NX ),
163
                                                LL = (i % NL);
164
                                        localparam [RYw-1   :   0] YY = Y_LOC [RYw-1   :   0];
165
                                        localparam [RXw-1   :   0] XX = X_LOC [RXw-1   :   0];
166
 
167
                                        /* verilator lint_off CMPCONST */
168
                                        assign y_plus[i]  = (current_rx ==      XX) && (current_ry >  YY);
169
                                        /* verilator lint_on CMPCONST */
170
 
171
                                        /* verilator lint_off UNSIGNED */
172
                                        assign y_min[i]   = (current_rx ==      XX) && (current_ry <  YY);
173
                                        /* verilator lint_on UNSIGNED */
174
                                        for(j=0;j
175
                                                assign local_p[j][i] = (current_rx      ==      XX) && (current_ry == YY) && (LL == j);
176
                                        end
177
 
178
                        end //i
179
 
180
 
181
                        wire goto_north = |(y_plus  & dest_mcast_all_endp);
182
                        wire goto_south = |(y_min   & dest_mcast_all_endp);
183
                        wire goto_east  = |(x_minus & row_has_any_dest);
184
                        wire goto_west  = |(x_plus  & row_has_any_dest);
185
 
186
 
187
                        wire [NL-1 : 0] goto_local;
188
                        for(i=0; i< NL; i=i+1) begin : endps
189
                                assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
190
                        end//for
191
 
192
 
193
 
194
                        reg [4  :   0] destport_tmp;
195
 
196
                        always @(*) begin
197
                                destport_tmp = {5{1'b0}};
198
                                destport_tmp[LOCAL]=goto_local[LOCAL];
199
                                if     (SW_LOC == SOUTH) destport_tmp [NORTH] = goto_north;
200
                                else if(SW_LOC == NORTH) destport_tmp [SOUTH] = goto_south;
201
                                else if(SW_LOC == WEST)begin
202
                                        destport_tmp [NORTH] = goto_north;
203
                                        destport_tmp [SOUTH] = goto_south;
204
                                        destport_tmp [EAST ] = goto_east;
205
                                end
206
                                else if(SW_LOC == EAST) begin
207
                                        destport_tmp [NORTH] = goto_north;
208
                                        destport_tmp [SOUTH] = goto_south;
209
                                        destport_tmp [WEST ] = goto_west;
210
                                end
211
                                else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
212
                                        destport_tmp [NORTH] = goto_north;
213
                                        destport_tmp [SOUTH] = goto_south;
214
                                        destport_tmp [EAST]  = goto_east;
215
                                        destport_tmp [WEST]  = goto_west;
216
                                end
217
                        end
218
 
219
                        localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
220
 
221
                        assign destport [MSB_DSTP : 0] =destport_tmp;
222
                        for(i=1;i
223
                                assign destport[MSB_DSTP+i]=goto_local[i];
224
                        end
225
        endgenerate
226
 
227
endmodule
228
 
229
 
230
 
231
 
232
 
233
 
234
module multicast_routing_fmesh
235
        import pronoc_pkg::*;
236
        #(
237
        parameter P = 5,
238
        parameter SW_LOC = 0
239
        )
240
        (
241
        current_r_addr,  //current router  address
242
        dest_e_addr,  // destination endpoint address
243
        destport
244
        );
245
 
246
        input   [RAw-1   :   0]  current_r_addr;
247
        input   [DAw-1   :   0]  dest_e_addr;
248
        output  [DSTPw-1 :   0]  destport;
249
 
250
        localparam Pw = log2(MAX_P_FMESH);
251
 
252
        localparam
253
                NX = T1,
254
                NY = T2,
255
                RXw = log2(NX),
256
                RYw = log2(NY),
257
                EXw = RXw,
258
                EYw = RYw;
259
 
260
        wire   [RXw-1   :   0]  current_rx;
261
        wire   [RYw-1   :   0]  current_ry;
262
 
263
 
264
        //mask gen. x_plus: all rows larger than current router x address are asserted.
265
        wire [NX-1 : 0] x_plus,x_minus;
266
        //mask generation. Only the corresponding bits to destination located in current column are asserted in each mask
267
        wire [NE-1 : 0] y_plus,y_min;
268
        //Only one-bit is asserted for each local_p[i]
269
        wire [NE-1 : 0] local_p [MAX_P_FMESH-1 : 0];
270
 
271
        mesh_tori_router_addr_decode #(
272
                .TOPOLOGY(TOPOLOGY),
273
                .T1(T1),
274
                .T2(T2),
275
                .T3(T3),
276
                .RAw(RAw)
277
        )
278
        router_addr_decode
279
        (
280
                .r_addr(current_r_addr),
281
                .rx(current_rx),
282
                .ry(current_ry),
283
                .valid( )
284
        );
285
 
286
 
287
        wire [NX-1 : 0] row_has_any_dest;
288
        wire [NE-1 : 0] dest_mcast_all_endp;
289
 
290
        mcast_dest_list_decode decode (
291
                        .dest_e_addr(dest_e_addr),
292
                        .dest_o(dest_mcast_all_endp),
293
                        .row_has_any_dest(row_has_any_dest),
294
                        .is_unicast()
295
                );
296
 
297
 
298
        genvar i,j;
299
        generate
300
 
301
        for(i=0; i< NX; i=i+1) begin : X_
302
                assign x_plus[i]  = (current_rx >       i);
303
                /* verilator lint_off UNSIGNED */
304
                assign x_minus[i] = (current_rx <        i);
305
                /* verilator lint_on UNSIGNED */
306
        end
307
 
308
        //get all endp addresses located in the same x
309
        for(i=0; i< NE; i=i+1) begin : endpoints
310
                //Endpoint decoded address
311
                localparam
312
                        ADR = fmesh_addrencode(i),
313
                        XX = ADR [NXw -1 : 0],
314
                        YY = ADR [NXw+NYw-1 : NXw],
315
                        PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
316
 
317
 
318
                /* verilator lint_off CMPCONST */
319
                assign y_plus[i]  = (current_rx ==      XX) && (current_ry >  YY);
320
                /* verilator lint_on CMPCONST */
321
 
322
                /* verilator lint_off UNSIGNED */
323
                assign y_min[i]   = (current_rx ==      XX) && (current_ry <  YY);
324
                /* verilator lint_on UNSIGNED */
325
 
326
                for(j=0;j
327
                        assign local_p[j][i] = (current_rx      ==      XX) && (current_ry == YY) && (PP == j);
328
                end
329
 
330
 
331
 
332
        end//for ne
333
 
334
        wire [MAX_P_FMESH-1 : 0] goto_local;
335
        for(i=0; i
336
                assign goto_local[i] = |(local_p[i] & dest_mcast_all_endp);// will be synthesized as single bit assign
337
        end//for
338
 
339
 
340
        wire goto_north = (|(y_plus  & dest_mcast_all_endp)) | goto_local[NORTH];
341
        wire goto_south = (|(y_min   & dest_mcast_all_endp)) | goto_local[SOUTH];
342
        wire goto_east  = (|(x_minus & row_has_any_dest))    | goto_local[EAST];
343
        wire goto_west  = (|(x_plus  & row_has_any_dest))    | goto_local[WEST];
344
 
345
 
346
 
347
 
348
 
349
                reg [4  :   0] destport_tmp;
350
 
351
                always @(*) begin
352
                        destport_tmp = {DSTPw{1'b0}};
353
                        destport_tmp[LOCAL]=goto_local[LOCAL];
354
                        if     (SW_LOC == SOUTH)begin
355
                                destport_tmp [NORTH] = goto_north ;
356
                                destport_tmp [EAST]  = goto_east;
357
                                destport_tmp [WEST]  = goto_west;
358
                        end
359
                        else if(SW_LOC == NORTH) begin
360
                                destport_tmp [SOUTH] = goto_south ;
361
                                destport_tmp [EAST]  = goto_east;
362
                                destport_tmp [WEST]  = goto_west;
363
                        end
364
                        else if(SW_LOC == WEST)begin
365
                                destport_tmp [NORTH] = goto_north ;
366
                                destport_tmp [SOUTH] = goto_south;
367
                                destport_tmp [EAST ] = goto_east;
368
                        end
369
                        else if(SW_LOC == EAST) begin
370
                                destport_tmp [NORTH] = goto_north;
371
                                destport_tmp [SOUTH] = goto_south;
372
                                destport_tmp [WEST ] = goto_west;
373
                        end
374
                        else if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin
375
                                destport_tmp [NORTH] = goto_north;
376
                                destport_tmp [SOUTH] = goto_south;
377
                                destport_tmp [EAST]  = goto_east;
378
                                destport_tmp [WEST]  = goto_west;
379
                        end
380
                end
381
 
382
                localparam MSB_DSTP = (DSTPw-1 < SOUTH)? DSTPw-1: SOUTH;
383
 
384
                assign destport [MSB_DSTP : 0] =destport_tmp;
385
                for(i=1;i
386
                        assign destport[MSB_DSTP+i]=goto_local[i];
387
                end
388
 
389
 
390
 
391
        endgenerate
392
 
393
endmodule
394
 
395
 
396
module mcast_dest_list_decode
397
                import pronoc_pkg::*;
398
                (
399
                dest_e_addr,
400
                dest_o,
401
                row_has_any_dest,
402
                is_unicast
403
                );
404
 
405
 
406
        input  [DAw-1 :0]  dest_e_addr;
407
        output [NE-1 : 0]  dest_o;
408
        output [NX-1 : 0] row_has_any_dest;
409
        output is_unicast;
410
 
411
        wire   [MCASTw-1 : 0] mcast_dst_coded;
412
 
413
 
414
 
415
        assign {row_has_any_dest,mcast_dst_coded}=dest_e_addr;
416
 
417
 
418
 
419
        genvar i;
420
        generate
421
        /* verilator lint_off WIDTH */
422
        if(CAST_TYPE == "MULTICAST_FULL") begin : full
423
        /* verilator lint_on WIDTH */
424
                assign dest_o = mcast_dst_coded;
425
                assign is_unicast = 1'b0;
426
        /* verilator lint_off WIDTH */
427
        end else if (CAST_TYPE == "MULTICAST_PARTIAL") begin : partial
428
        /* verilator lint_on WIDTH */
429
                wire not_in_cast_list ;
430
                wire [EAw-1 : 0] unicast_code;
431
                assign {unicast_code,not_in_cast_list} = mcast_dst_coded  [EAw : 0];
432
                wire [NE-1 : 0]  dest_o_multi;
433
                reg  [NE-1 : 0]  dest_o_uni;
434
                wire [NEw-1 : 0] unicast_id;
435
                assign is_unicast = not_in_cast_list;
436
 
437
                endp_addr_decoder  #(
438
                        .TOPOLOGY (TOPOLOGY),
439
                        .T1(T1),
440
                        .T2(T2),
441
                        .T3(T3),
442
                        .EAw(EAw),
443
                        .NE(NE)
444
                        )
445
                        decoder
446
                        (
447
                                .code(unicast_code),
448
                                .id(unicast_id)
449
                        );
450
 
451
                always @(*)begin
452
                        dest_o_uni = {NE{1'b0}};
453
                        dest_o_uni[unicast_id]=1'b1;
454
                end
455
 
456
                for(i=0; i< NE; i=i+1) begin : endpoints
457
                        localparam MCAST_ID = endp_id_to_mcast_id(i);
458
                        assign dest_o_multi [i] = (MCAST_ENDP_LIST[i]==1'b1)? mcast_dst_coded[MCAST_ID+1] : 1'b0;
459
                end
460
 
461
                assign dest_o = (not_in_cast_list)? dest_o_uni : dest_o_multi;
462
        /* verilator lint_off WIDTH */
463
        end else if (CAST_TYPE == "BROADCAST_FULL") begin : bcast_full
464
        /* verilator lint_on WIDTH */
465
                wire not_broad_casted;
466
                wire [EAw-1 : 0] unicast_code;
467
                assign {unicast_code,not_broad_casted} = mcast_dst_coded;
468
                assign is_unicast =not_broad_casted;
469
                wire [NE-1 : 0]  dest_o_multi;
470
                reg  [NE-1 : 0]  dest_o_uni;
471
                wire [NEw-1 : 0] unicast_id;
472
 
473
                endp_addr_decoder  #(
474
                                .TOPOLOGY (TOPOLOGY),
475
                                .T1(T1),
476
                                .T2(T2),
477
                                .T3(T3),
478
                                .EAw(EAw),
479
                                .NE(NE)
480
                        )
481
                        decoder
482
                        (
483
                                .code(unicast_code),
484
                                .id(unicast_id)
485
                        );
486
 
487
                always @(*)begin
488
                        dest_o_uni = {NE{1'b0}};
489
                        dest_o_uni[unicast_id]=1'b1;
490
                end
491
 
492
                assign dest_o = (not_broad_casted)? dest_o_uni : {NE{1'b1}};
493
 
494
        end else begin //BCAST_PARTIAL
495
                wire not_broad_casted;
496
                wire [EAw-1 : 0] unicast_code;
497
                assign {unicast_code,not_broad_casted} = mcast_dst_coded;
498
                assign is_unicast =not_broad_casted;
499
                wire [NE-1 : 0]  dest_o_multi;
500
                reg  [NE-1 : 0]  dest_o_uni;
501
                wire [NEw-1 : 0] unicast_id;
502
 
503
                endp_addr_decoder  #(
504
                                .TOPOLOGY (TOPOLOGY),
505
                                .T1(T1),
506
                                .T2(T2),
507
                                .T3(T3),
508
                                .EAw(EAw),
509
                                .NE(NE)
510
                        )
511
                        decoder
512
                        (
513
                                .code(unicast_code),
514
                                .id(unicast_id)
515
                        );
516
 
517
                always @(*)begin
518
                        dest_o_uni = {NE{1'b0}};
519
                        dest_o_uni[unicast_id]=1'b1;
520
                end
521
 
522
                assign dest_o = (not_broad_casted)? dest_o_uni : MCAST_ENDP_LIST;
523
 
524
 
525
 
526
        end
527
 
528
        endgenerate
529
 
530
 
531
endmodule
532
 
533
 
534
 
535
 
536
module multicast_chan_in_process
537
                import pronoc_pkg::*;
538
        #(
539
                parameter P = 5,
540
                parameter SW_LOC = 0
541
 
542
        )
543
        (
544
                endp_port,
545
                current_r_addr,
546
                chan_in,
547
                chan_out,
548
                clk
549
        );
550
 
551
        input endp_port;
552
        input   [RAw-1   :   0]  current_r_addr;
553
        input   flit_chanel_t chan_in;
554
        input   clk;
555
        output  flit_chanel_t chan_out;
556
 
557
 
558
        wire  [MCASTw-1   :   0]  mcast_dst_coded;
559
        wire  [NE-1 : 0] dest_mcast_all_endp;
560
        wire [NX-1 : 0] row_has_any_dest,row_has_any_dest_in;
561
        wire  [DSTPw-1  :   0] destport,destport_o;
562
 
563
 
564
 
565
        hdr_flit_t hdr_flit;
566
        header_flit_info extract(
567
                        .flit(chan_in.flit),
568
                        .hdr_flit(hdr_flit),
569
                        .data_o()
570
                );
571
 
572
        mcast_dest_list_decode decoder
573
        (
574
                .dest_e_addr(hdr_flit.dest_e_addr),
575
                .dest_o(dest_mcast_all_endp),
576
                .row_has_any_dest(row_has_any_dest_in),
577
                .is_unicast()
578
        );
579
 
580
        localparam MCASTw_= (MCASTw < DAw ) ? MCASTw : DAw;
581
 
582
        assign mcast_dst_coded = hdr_flit.dest_e_addr[MCASTw_-1:0];
583
 
584
 
585
        genvar i;
586
        generate
587
        if(TOPOLOGY == "MESH") begin : mesh_
588
                if(SW_LOC == LOCAL || SW_LOC > SOUTH) begin :endp
589
 
590
                        wire [NE/NX-1   :   0] endp_mask [NX-1 : 0];
591
                        for(i=0; i< NE; i=i+1) begin : endpoints
592
                                //Endpoint decoded address
593
                                localparam
594
                                        MCAST_ID = endp_id_to_mcast_id(i),
595
                                        YY = ((i/NL) / NX ),
596
                                        XX = ((i/NL) % NX ),
597
                                        LL = (i % NL),
598
                                        PP = YY*NL + LL;
599
                                assign endp_mask [XX] [PP] = dest_mcast_all_endp [i];
600
                        end
601
 
602
                        for(i=0;i
603
                                assign row_has_any_dest[i] =| endp_mask[i];
604
                        end
605
 
606
                        reg   [DSTPw-1  :   0] destport_tmp;
607
                        always @(*) begin
608
                                destport_tmp = destport;
609
                                if(SELF_LOOP_EN   == "NO") destport_tmp [ SW_LOC ] = 1'b0;
610
                        end
611
                        assign destport_o = destport_tmp;
612
 
613
                end else begin : no_endp
614
                        assign  row_has_any_dest =       row_has_any_dest_in;
615
                        assign  destport_o = destport;
616
                end
617
        end //mesh
618
 
619
        /* verilator lint_off WIDTH */
620
        else if (TOPOLOGY == "FMESH" ) begin :fmesh_
621
        /* verilator lint_on WIDTH */
622
 
623
 
624
 
625
                localparam MAX_ENDP_NUM_IN_SAME_ROW = NY * NL + NY + 2;
626
                localparam ENDP_NUM_IN_MIDLE_ROW = NY * NL + 2;
627
                localparam Pw = log2(MAX_P_FMESH);
628
 
629
                wire [NX-1 : 0] row_has_any_dest_endp_port;
630
                wire [NY*NL-1   :   0] endp_mask [NX-1 : 0];
631
 
632
                for(i=0; i< NE; i=i+1) begin : endpoints
633
                        //Endpoint decoded address
634
                        localparam
635
                                ADR = fmesh_addrencode(i),
636
                                XX = ADR [NXw -1 : 0],
637
                                YY = ADR [NXw+NYw-1 : NXw],
638
                                PP = ADR [NXw+NYw+Pw-1 : NXw+NYw];
639
                                if(PP == LOCAL || PP > SOUTH) begin
640
                                        localparam MM = (PP==LOCAL) ? YY*NL : (YY*NL) + PP - SOUTH;
641
                                        assign endp_mask [XX] [MM] = dest_mcast_all_endp [i];
642
                                end
643
                end
644
 
645
                wire [NX-1 : 0] north_endps;
646
                wire [NY-1 : 0] west_endps;
647
                wire [NX-1 : 0] south_endps;
648
                wire [NY-1 : 0] east_endps;
649
 
650
                assign {    east_endps,    west_endps ,south_endps ,north_endps}  = dest_mcast_all_endp [NE-1 :   NY*NL*NX];
651
 
652
 
653
                for(i=0;i
654
                        if(i==0) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |west_endps)  | north_endps[i] | south_endps[i];
655
                        else if (i==NX-1) assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) | ( |east_endps)  | north_endps[i] | south_endps[i];
656
                        else assign row_has_any_dest_endp_port[i] =(| endp_mask[i]) |  north_endps[i] | south_endps[i];
657
                end
658
 
659
                reg   [DSTPw-1  :   0] destport_tmp;
660
                always @(*) begin
661
                        destport_tmp = destport;
662
                        if(SELF_LOOP_EN   == "NO") destport_tmp [ SW_LOC ] = 1'b0;
663
                end
664
 
665
 
666
                assign  destport_o = (endp_port) ?    destport :  destport_tmp ;
667
                assign  row_has_any_dest = (endp_port) ? row_has_any_dest_endp_port : row_has_any_dest_in;
668
 
669
 
670
        end
671
 
672
 
673
 
674
 
675
                wire [DAw-1 : 0] dest_e_addr = {row_has_any_dest,mcast_dst_coded};
676
 
677
 
678
                multicast_routing
679
                #(
680
                        .P(P) ,
681
                        .SW_LOC(SW_LOC)
682
                )
683
                routing
684
                (
685
                        .current_r_addr(current_r_addr),  //current router  address
686
                        .dest_e_addr(dest_e_addr),  // destination endpoint address
687
                        .destport(destport)
688
                );
689
 
690
 
691
 
692
 
693
                always @(*) begin
694
                        chan_out=chan_in;
695
                        if(chan_in.flit.hdr_flag == 1'b1) begin
696
                                chan_out.flit [E_DST_MSB : E_DST_LSB] = dest_e_addr;
697
                                chan_out.flit [DST_P_MSB : DST_P_LSB] = destport_o;
698
                        end
699
                end
700
 
701
 
702
 
703
 
704
 
705
 
706
        //synthesis translate_off
707
        if(DEBUG_EN) begin :debg
708
                always @(posedge clk) begin
709
                        /* verilator lint_off WIDTH */
710
                        if(CAST_TYPE == "MULTICAST_FULL" || CAST_TYPE == "MULTICAST_PARTIAL")
711
                        /* verilator lint_on WIDTH */
712
                        if(chan_in.flit_wr  == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && mcast_dst_coded == {MCASTw{1'b0}}) begin
713
                                $display ("%t: ERROR: A multicast packet is injected to the NoC with zero mcast_dst_coded filed %m ",$time);
714
                                $finish;
715
                        end
716
 
717
                        if(chan_in.flit_wr  == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && dest_mcast_all_endp == {NE{1'b0}}) begin
718
                                $display ("%t: ERROR: A multicast packet is injected to the NoC without any set destination %m ",$time);
719
                                $finish;
720
                        end
721
 
722
                        if(chan_in.flit_wr  == 1'b1 && chan_in.flit.hdr_flag == 1'b1 && destport_o == {DSTPw{1'b0}}) begin
723
                                $display ("%t: ERROR: Routing module did not set any destination port for an injected multicast packet %m ",$time);
724
                                $finish;
725
                        end
726
 
727
                end
728
        end//debug
729
        //synthesis translate_on
730
 
731
        endgenerate
732
endmodule
733
 
734
 
735
 
736
 
737
 
738
module multicast_dst_sel
739
                import pronoc_pkg::*;
740
        (
741
 
742
                destport_in,
743
                destport_out
744
        );
745
 
746
        input  [DSTPw-1 : 0] destport_in;
747
        output [DSTPw-1 : 0] destport_out;
748
 
749
 
750
        wire  [DSTPw-1 : 0] arb_in, arb_out;
751
 
752
        function integer mesh_tori_pririty_order;
753
                input integer x;
754
                begin
755
                        case(x)
756
 
757
                                1 : mesh_tori_pririty_order = WEST;
758
                                2 : mesh_tori_pririty_order = NORTH;
759
                                3 : mesh_tori_pririty_order = SOUTH;
760
                                4 : mesh_tori_pririty_order = LOCAL;
761
                                default : mesh_tori_pririty_order =x;
762
                        endcase
763
                end
764
        endfunction // pririty_order
765
 
766
        function integer ring_lin_pririty_order;
767
                input integer x;
768
                begin
769
                        case(x)
770
 
771
                                1 : ring_lin_pririty_order = BACKWARD;
772
                                2 : ring_lin_pririty_order = LOCAL;
773
                                default : ring_lin_pririty_order =x;
774
                        endcase
775
                end
776
        endfunction // pririty_order
777
 
778
 
779
 
780
 
781
 
782
        genvar i;
783
        generate
784
                for (i=0; i
785
                        localparam PR =
786
                                /* verilator lint_off WIDTH */
787
                                (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "FMESH"  )?  mesh_tori_pririty_order(i):
788
                                (TOPOLOGY == "RING" || TOPOLOGY == "LINE") ? ring_lin_pririty_order(i) : i;
789
                                /* verilator lint_on WIDTH */
790
                        assign arb_in[i] = destport_in[PR];
791
                        assign destport_out [PR] = arb_out[i];
792
                end
793
        endgenerate
794
 
795
 
796
        fixed_priority_arbiter #(
797
                        .ARBITER_WIDTH     (DSTPw),
798
                        .HIGH_PRORITY_BIT  ("LSB")
799
                ) fixed_priority_arbiter (
800
                        .request           (arb_in),
801
                        .grant             (arb_out),
802
                        .any_grant         (   )
803
                );
804
 
805
 
806
 
807
 
808
endmodule
809
 
810
 

powered by: WebSVN 2.1.0

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