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 56

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

powered by: WebSVN 2.1.0

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