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/] [router_bypass.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 48 alirezamon
 
3
/**************************************
4
* Module: router_bypass
5
* Date:2020-11-24
6
* Author: alireza
7
*
8
* Description:
9
*   This file contains HDL modules that can be added
10 54 alirezamon
*   to a 2-stage NoC router and provides router bypassing
11 48 alirezamon
***************************************/
12
 
13
/**************************
14
 * SMART_flags_gen:
15
 * generate SMART flags based on NoC parameter, current router's port and address,
16
 * and destination router address
17
 * located in router output port (port number:SPB_OPORT_NUM)
18
 * smart_flag_o indicates how many more router in direct line can be bypassed
19
 * if SPB_OPORT_NUM  is also one of the possible output port in
20
 * lk-ahead routing, The packet can by-pass the next router once the bypassing condition are met
21
 ***************************/
22
 
23 54 alirezamon
`include "pronoc_def.v"
24 48 alirezamon
 
25
 
26
module reduction_or #(
27
        parameter W = 5,//out width
28
        parameter N = 4 //array lenght
29
)(
30
        in,
31
        out
32
);
33
    input  [W-1 : 0] in [N-1 : 0];
34
    output reg [W-1 : 0] out;
35
 
36
    // assign out = in.or(); //it is not synthesizable able by some compiler
37
        always_comb begin
38
                out = {W{1'b0}};
39
                for (int i = 0; i < N; i++)
40
                        out |=   in[i];
41
        end
42
 
43
 
44
endmodule
45
 
46
module onehot_mux_2D #(
47
                parameter W = 5,//out width
48
                parameter N = 4 //sel width
49
                )(
50
                in,
51
                sel,
52
                out
53
                );
54
 
55
        input  [W-1 : 0] in [N-1 : 0];
56
        input  [N-1 : 0] sel;
57
        output reg [W-1 : 0] out;
58
 
59
 
60
        always_comb begin
61
                out = {W{1'b0}};
62
                for (int i = 0; i < N; i++)
63
                        out |= (sel[i]) ?  in[i] :  {W{1'b0}};
64
        end
65
 
66
 
67
endmodule
68
 
69
module onehot_mux_1D #(
70
                parameter W = 5,//out width
71
                parameter N = 4 //sel width
72
        )(
73
                input  [W*N-1 : 0] in,
74
                input  [N-1 : 0] sel,
75
                output [W-1 : 0] out
76
        );
77
 
78
wire  [W-1 : 0] in_array [N-1 : 0];
79
 
80
genvar i;
81
generate
82
for (i=0;i
83
        assign in_array[i] = in[(i+1)*W-1 : i*W];
84
end
85
endgenerate
86
 
87
 
88
        onehot_mux_2D #(
89
                .W    (W   ),
90
                .N    (N   )
91
                ) onehot_mux_2D (
92
                .in   (in_array  ),
93
                .sel  (sel ),
94
                .out  (out ));
95
 
96
 
97
endmodule
98
 
99
 
100 54 alirezamon
module onehot_mux_1D_reverse #(
101
                parameter W = 5,//out width  p
102
                parameter N = 4 //sel width  v
103
                )(
104
                input  [W*N-1 : 0] in,
105
                input  [N-1 : 0] sel,
106
                output [W-1 : 0] out
107
                );
108 48 alirezamon
 
109 54 alirezamon
        wire  [N-1 : 0] in_array [W-1 : 0];
110
        wire  [W-1 : 0] in_array2[N-1 : 0];
111 48 alirezamon
 
112 54 alirezamon
        genvar i,j;
113
        generate
114
                for (i=0;i
115
                        assign in_array[i] = in[(i+1)*N-1 : i*N];
116
                        for (j=0;j
117
                                assign in_array2[j][i] = in_array[i][j];
118
                        end
119
                end
120
        endgenerate
121
 
122
 
123
        onehot_mux_2D #(
124
                        .W    (N   ),
125
                        .N    (W   )
126
                ) onehot_mux_2D (
127
                        .in   (in_array2  ),
128
                        .sel  (sel ),
129
                        .out  (out ));
130
 
131
 
132
endmodule
133
 
134
 
135
 
136
 
137
 
138
 
139 48 alirezamon
module header_flit_info
140
        import pronoc_pkg::*;
141
#(
142
        parameter DATA_w = 0
143
)(
144
        flit,
145
        hdr_flit,
146
        data_o
147
);
148
        localparam
149
        Dw = (DATA_w==0)? 1 : DATA_w;
150
 
151
        input flit_t flit;
152
        output hdr_flit_t hdr_flit;
153
        output [Dw-1 : 0] data_o;
154
 
155
 
156
        localparam
157
                DATA_LSB= MSB_BE+1,               DATA_MSB= (DATA_LSB + DATA_w)
158
                OFFSETw = DATA_MSB - DATA_LSB +1;
159
 
160
        wire [OFFSETw-1 : 0 ] offset;
161
 
162
        assign hdr_flit.src_e_addr  = flit.payload [E_SRC_MSB : E_SRC_LSB];
163
        assign hdr_flit.dest_e_addr = flit.payload [E_DST_MSB : E_DST_LSB];
164
        assign hdr_flit.destport    = flit.payload [DST_P_MSB : DST_P_LSB];
165
 
166
 
167
        generate
168
                if(C>1)begin : have_class
169
                        assign hdr_flit.message_class = flit.payload [CLASS_MSB : CLASS_LSB];
170
                end else begin : no_class
171
                        assign hdr_flit.message_class = {Cw{1'b0}};
172
                end
173
 
174
                /* verilator lint_off WIDTH */
175
                if(SWA_ARBITER_TYPE != "RRA")begin  : wrra_b
176
                /* verilator lint_on WIDTH */
177
                        assign hdr_flit.weight =  flit.payload [WEIGHT_MSB : WEIGHT_LSB];
178
                end else begin : rra_b
179
                        assign hdr_flit.weight = {WEIGHTw{1'bX}};
180
                end
181
 
182
                if( BYTE_EN ) begin : be_1
183
                        assign hdr_flit.be = flit.payload [BE_MSB : BE_LSB];
184
                end else begin : be_0
185
                        assign hdr_flit.be = {BEw{1'bX}};
186
                end
187
 
188
 
189
                assign offset = flit.payload [DATA_MSB : DATA_LSB];
190
 
191
 
192
                if(Dw > OFFSETw) begin : if1
193
                        assign data_o={{(Dw-OFFSETw){1'b0}},offset};
194
                end else begin : if2
195
                        assign data_o=offset[Dw-1 : 0];
196
                end
197
 
198
        endgenerate
199
 
200
 
201
 
202
endmodule
203
 
204
//synthesis translate_off
205
//synopsys  translate_off
206
 
207
module smart_chanel_check
208
                import pronoc_pkg::*;
209
        (
210
                flit_chanel,
211
                smart_chanel,
212
                reset,
213
                clk
214
        );
215
 
216
        input flit_chanel_t  flit_chanel;
217
        input smart_chanel_t   smart_chanel;
218
        input reset,clk;
219
 
220
        smart_chanel_t   smart_chanel_delay;
221
        always @(posedge clk) smart_chanel_delay<=smart_chanel;
222
 
223
        hdr_flit_t hdr_flit;
224
        header_flit_info extract(
225
                        .flit(flit_chanel.flit),
226
                        .hdr_flit(hdr_flit),
227
                        .data_o()
228
                );
229
 
230
        always @(posedge clk) begin
231
                if(flit_chanel.flit_wr) begin
232
                        if(smart_chanel_delay.ovc!=flit_chanel.flit.vc) begin
233
                                $display("%t: ERROR: smart ovc %d is not equal with flit ovc %d. %m",$time,smart_chanel_delay.ovc,flit_chanel.flit.vc );
234
                                $finish;
235
                        end
236
                        if(flit_chanel.flit.hdr_flag==1'b1 &&   hdr_flit.dest_e_addr != smart_chanel_delay.dest_e_addr) begin
237
                                $display("%t: ERROR: smart dest_e_addr %d is not equal with flit dest_e_addr %d. %m",$time,smart_chanel_delay.dest_e_addr,hdr_flit.dest_e_addr );
238
                                $finish;
239
                        end
240
                        if(flit_chanel.flit.hdr_flag!=smart_chanel_delay.hdr_flit) begin
241
                                $display("%t: ERROR: smart and current hdr flag (%d!=%d) miss-match. %m",$time, smart_chanel_delay.hdr_flit, flit_chanel.flit.hdr_flag);
242
                                $finish;
243
                        end
244
 
245
                end
246
 
247
        end
248
endmodule
249
 
250
//synopsys  translate_on
251
//synthesis translate_on
252
 
253
 
254
 
255
 
256
 
257
module smart_forward_ivc_info
258
        import pronoc_pkg::*;
259
        #(
260
        parameter P=5
261
)(
262
                ivc_info,
263
                iport_info,
264
                oport_info,
265
                smart_chanel,
266
                ovc_locally_requested,
267
                reset,clk
268
);
269
 
270
 
271
 
272
        //ivc info
273
        input reset,clk;
274
        input  ivc_info_t       ivc_info    [P-1 : 0][V-1 : 0];
275
        input  iport_info_t iport_info  [P-1 : 0];
276
        input  oport_info_t oport_info  [P-1 : 0];
277
        output smart_chanel_t smart_chanel  [P-1 : 0];
278
        output [V-1 : 0] ovc_locally_requested [P-1 : 0];
279
 
280
        smart_ivc_info_t  smart_ivc_info [P-1 : 0][V-1 : 0];
281
        smart_ivc_info_t  smart_ivc_mux  [P-1 : 0];
282
 
283
        smart_ivc_info_t  smart_ivc_info_all_port [P-1 : 0] [P-1 : 0];
284
        smart_ivc_info_t  smart_vc_info_o [P-1 : 0];
285
 
286
        wire [V-1 : 0] assigned_ovc [P-1:0];
287
        wire [V-1 : 0] non_assigned_vc_req [P-1:0];
288
        wire [P-1 : 0] mask_gen  [P-1 : 0][V-1 :0];
289
        wire [V-1 : 0] ovc_locally_requested_next [P-1 : 0];
290
 
291
        /*
292
                                                P  V                   P                P  V   p
293
        non_assigned_vc_req[i][j] destport_one_hot[z]-->   [z][ j][i]
294
        non_assigned_vc_req[0][0] destport_one_hot[3]--> | [3][0] [0]
295
        non_assigned_vc_req[1][0] destport_one_hot[3]--> | [3][0] [1]
296
        non_assigned_vc_req[2][0] destport_one_hot[3]--> | [3][0] [2]
297
        */
298
 
299
        smart_chanel_t smart_chanel_next  [P-1 : 0];
300
 
301
 
302
        genvar i,j,z;
303
        generate
304
        for (i=0;i
305
 
306
                for (j=0; j < V; j=j+1) begin : ivc
307
                        assign smart_ivc_info[i][j].dest_e_addr = ivc_info[i][j].dest_e_addr;
308
                        assign smart_ivc_info[i][j].ovc_is_assigned= ivc_info[i][j].ovc_is_assigned;
309
                        assign smart_ivc_info[i][j].assigned_ovc_bin=ivc_info[i][j].assigned_ovc_bin;
310
                        assign non_assigned_vc_req[i][j] = ~ivc_info[i][j].ovc_is_assigned & ivc_info[i][j].ivc_req;
311
                        for (z=0; z < P; z=z+1) begin : port
312
                                assign mask_gen[z][j][i] = non_assigned_vc_req[i][j] & ivc_info[i][j].destport_one_hot[z];
313
                        end
314
                        assign ovc_locally_requested_next[i][j]=|mask_gen[i][j];
315
                end//V
316
 
317 54 alirezamon
                pronoc_register #(.W(V)) reg1 (.in(ovc_locally_requested_next[i] ), .reset(reset), .clk(clk), .out(ovc_locally_requested[i]));
318 48 alirezamon
 
319
 
320
 
321
 
322
                onehot_mux_2D   #(.W(SMART_IVC_w),.N(V)) mux1 ( .in(smart_ivc_info[i]), .sel(iport_info[i].swa_first_level_grant), .out(smart_ivc_mux[i]));
323
                //demux
324
                for (j=0;j
325
                        assign smart_ivc_info_all_port[j][i] = (iport_info[i].granted_oport_one_hot[j]==1'b1)? smart_ivc_mux[i] : {SMART_IVC_w{1'b0}};
326
                end
327
 
328
                //assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].or; not synthesizable
329
                // assign smart_vc_info_o[i] = smart_ivc_info_all_port[i].[0] | smart_ivc_info_all_port[i].[1] | smart_ivc_info_all_port[i].[2]  ... | smart_ivc_info_all_port[i].[p-1];
330
                reduction_or #(
331
                        .W    (SMART_IVC_w   ),
332
                        .N    (P   )
333
                ) _or (
334
                        .in   (smart_ivc_info_all_port[i]  ),
335
                        .out  (smart_vc_info_o[i] )
336
                );
337
                /*
338
                always_comb begin
339
                        smart_vc_info_o[i] = {SMART_IVC_w{1'b0}};
340
                        for (int ii = 0; ii < P; ii++)
341
                                smart_vc_info_o[i] |= smart_ivc_info_all_port[i][ii];
342
                end
343
                */
344
 
345
 
346
                bin_to_one_hot #(
347
                        .BIN_WIDTH      (Vw),
348
                        .ONE_HOT_WIDTH  (V )
349
                ) conv (
350
                        .bin_code       (smart_vc_info_o[i].assigned_ovc_bin ),
351
                        .one_hot_code   (assigned_ovc[i]  )
352
                );
353
 
354
 
355
 
356
                assign smart_chanel_next[i].dest_e_addr= smart_vc_info_o[i].dest_e_addr;
357
                assign smart_chanel_next[i].ovc= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
358
                assign smart_chanel_next[i].hdr_flit=~smart_vc_info_o[i].ovc_is_assigned;
359 54 alirezamon
                assign smart_chanel_next[i].requests = (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
360
                assign smart_chanel_next[i].bypassed_num = {BYPASSw{1'b0}} ;
361 48 alirezamon
 
362 54 alirezamon
 
363 48 alirezamon
                if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
364 54 alirezamon
                        pronoc_register #(
365 48 alirezamon
                                .W      ( SMART_CHANEL_w     )
366
                                ) register (
367
                                .in     (smart_chanel_next[i]   ),
368
                                .reset  (reset ),
369
                                .clk    (clk   ),
370
                                .out    (smart_chanel[i]   ));
371
 
372
                end else begin :no_link_reg
373
                                assign smart_chanel[i] = smart_chanel_next[i];
374
                end
375
                /*
376
 
377 54 alirezamon
                        always @ (`pronoc_clk_reset_edge )begin
378
                                if(`pronoc_reset) begin
379 48 alirezamon
                                        smart_chanel[i].dest_e_addr<= {EAw{1'b0}};
380
                                        smart_chanel[i].ovc<= {V{1'b0}};
381
                                        smart_chanel[i].hdr_flit<=1'b0;
382
                                end else begin
383
                                        smart_chanel[i].dest_e_addr<= smart_vc_info_o[i].dest_e_addr;
384
                                        smart_chanel[i].ovc<= (smart_vc_info_o[i].ovc_is_assigned)? assigned_ovc[i] : oport_info[i].non_smart_ovc_is_allocated;
385
                                        smart_chanel[i].hdr_flit<=~smart_vc_info_o[i].ovc_is_assigned;
386
                                        smart_chanel[i].requests <= (oport_info[i].any_ovc_granted)? {SMART_NUM{1'b1}}:{SMART_NUM{1'b0}} ;
387
                                end
388
                        end
389
 
390
                */
391
 
392
 
393
 
394
 
395
 
396
                end//port_
397
                endgenerate
398
 
399
//      generate for (i=0; i < P; i=i+1) begin : port
400
//                      assign smart_ivc_info_o[i] = (granted_dest_port[i]==1'b1)? ivc_info_mux : {SMART_IVC_w{1'b0}};
401
//              end endgenerate
402
 
403
 
404
endmodule
405
 
406
 
407
 
408
 
409
module smart_bypass_chanels
410
        import pronoc_pkg::*;
411
#(
412
        parameter P=5
413
)(
414
        ivc_info,
415
        iport_info,
416
        oport_info,
417
        smart_chanel_new,
418
        smart_chanel_in,
419
        smart_chanel_out,
420
        smart_req,
421
        reset,
422
        clk
423
 
424
);
425
 
426
        input reset,clk;
427
        input smart_chanel_t smart_chanel_new  [P-1 : 0];
428
        input smart_chanel_t smart_chanel_in   [P-1 : 0];
429
        input ivc_info_t   ivc_info    [P-1 : 0][V-1 : 0];
430
        input iport_info_t iport_info  [P-1 : 0];
431
        input oport_info_t oport_info  [P-1 : 0];
432
 
433
        output [P-1 : 0] smart_req;
434
        output smart_chanel_t smart_chanel_out   [P-1 : 0];
435
 
436
 
437
        smart_chanel_t smart_chanel_shifted  [P-1 : 0];
438
        localparam DISABLE = P;
439
 
440
        wire [V-1 : 0 ] ivc_forwardable [P-1 : 0];
441
        wire [P-1 :0] smart_forwardable;
442
        logic [P-1 :0] outport_is_granted;
443
        reg [P-1 : 0] rq;
444
        genvar i;
445
        generate
446
        for (i=0;i
447
                /* verilator lint_off WIDTH */
448
                assign ivc_forwardable[i] =  (PCK_TYPE == "SINGLE_FLIT")?  1'b1 :~iport_info[i].ivc_req;
449
                /* verilator lint_on WIDTH */
450
 
451
 
452
                if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
453
                always @( posedge clk)begin
454
                    outport_is_granted[i] <= oport_info[i].any_ovc_granted;
455
                end
456
                end else begin
457
                        assign outport_is_granted[i] = oport_info[i].any_ovc_granted;
458
                end
459
 
460
                localparam SS_PORT = strieght_port (P,i); // the straight port number
461
                if(SS_PORT != DISABLE) begin: ssp
462
 
463
                        //smart_chanel_shifter
464
                        assign smart_forwardable[i] = |  (ivc_forwardable[i] & smart_chanel_in[i].ovc);
465
                        always @(*) begin
466
                                smart_chanel_shifted[i] = smart_chanel_in [i];
467
                                {smart_chanel_shifted[i].requests,rq[i]} =(smart_forwardable[i])? {1'b0,smart_chanel_in[i].requests}:{{SMART_NUM{1'b0}},smart_chanel_in[i].requests[0]};
468 54 alirezamon
                                smart_chanel_shifted[i].bypassed_num =   smart_chanel_in [i].bypassed_num +1'b1;
469 48 alirezamon
                        end
470
                        assign smart_req[i]=rq[i];
471
                        // mux out smart chanel
472
                        assign smart_chanel_out[i] = (outport_is_granted[i])? smart_chanel_new[i] : smart_chanel_shifted[SS_PORT];
473
 
474
 
475
 
476
 
477
                end else begin
478
                        assign {smart_chanel_shifted[i].requests,smart_req[i]} = {(SMART_NUM+1){1'b0}};
479
                        assign smart_chanel_out[i] = {SMART_CHANEL_w{1'b0}};
480
                end
481
 
482
        end
483
        endgenerate
484
 
485
 
486
endmodule
487
 
488
 
489
 
490
 
491
 
492
 
493
module check_straight_oport #(
494
                parameter TOPOLOGY          =   "MESH",
495
                parameter ROUTE_NAME        =   "XY",
496
                parameter ROUTE_TYPE        =   "DETERMINISTIC",
497
                parameter DSTPw             =   4,
498
                parameter SS_PORT_LOC     =   1
499
                )(
500
                destport_coded_i,
501
                goes_straight_o
502
                );
503
 
504
        input   [DSTPw-1 : 0] destport_coded_i;
505
        output  goes_straight_o;
506
 
507
        generate
508
        /* verilator lint_off WIDTH */
509 54 alirezamon
                if(TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY =="FMESH" ) begin :twoD
510 48 alirezamon
                        /* verilator lint_on WIDTH */
511
                        if (SS_PORT_LOC == 0 || SS_PORT_LOC > 4) begin : local_ports
512
                                assign goes_straight_o = 1'b0; // There is not a next router in this case at all
513
                        end
514
                        else begin :non_local
515
 
516
                                wire [4 : 0 ] destport_one_hot;
517
                                mesh_tori_decode_dstport decoder(
518
                                                .dstport_encoded(destport_coded_i),
519
                                                .dstport_one_hot(destport_one_hot)
520
                                        );
521
 
522
                                assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
523
                        end//else
524
                end//mesh_tori
525
                /* verilator lint_off WIDTH */
526
                else if(TOPOLOGY ==  "RING" || TOPOLOGY ==  "LINE"  ) begin :oneD
527
                        /* verilator lint_on WIDTH */
528
                        if (SS_PORT_LOC == 0 || SS_PORT_LOC > 2) begin : local_ports
529
                                assign goes_straight_o = 1'b0; // There is not a next router in this case at all
530
                        end
531
                        else begin :non_local
532
 
533
                                wire [2: 0 ] destport_one_hot;
534
 
535
                                line_ring_decode_dstport decoder(
536
                                                .dstport_encoded(destport_coded_i),
537
                                                .dstport_one_hot(destport_one_hot)
538
 
539
                                        );
540
                                assign goes_straight_o = destport_one_hot [SS_PORT_LOC];
541
 
542
                        end     //non_local
543
                end// oneD
544
 
545
                //TODO Add fattree & custom
546
 
547
        endgenerate
548
 
549
endmodule
550
 
551
 
552
 
553
 
554
module smart_validity_check_per_ivc
555
        import pronoc_pkg::*;
556
#(
557
        parameter IVC_NUM = 0
558
)(
559
        reset                  ,
560
        clk                    ,
561
        //smart channel
562
        goes_straight              ,
563
        smart_requests_i         ,
564
        smart_ivc_i              ,
565
        smart_hdr_flit             ,
566
        //flit
567
        flit_hdr_flag_i        ,
568
        flit_tail_flag_i       ,
569
        flit_wr_i              ,
570
        //router ivc status
571
        ovc_locally_requested     ,
572
        assigned_to_ss_ovc          ,
573
        assigned_ovc_not_full       ,
574
        ovc_is_assigned             ,
575
        ivc_request                 ,
576
        //ss port status
577
        ss_ovc_avalable_in_ss_port  ,
578
        ss_port_link_reg_flit_wr    ,
579
        ss_ovc_crossbar_wr          ,
580
        //output
581
        smart_single_flit_pck_o         ,
582
        smart_ivc_smart_en_o            ,
583
        smart_credit_o                  ,
584
        smart_buff_space_decreased_o  ,
585
        smart_ss_ovc_is_allocated_o   ,
586
        smart_ss_ovc_is_released_o    ,
587
        smart_mask_available_ss_ovc_o ,
588
        smart_ivc_num_getting_ovc_grant_o,
589
        smart_ivc_reset_o,
590
        smart_ivc_granted_ovc_num_o
591
);
592
 
593
input reset, clk;
594
//smart channel
595
input goes_straight                ,
596
        smart_requests_i         ,
597
        smart_ivc_i              ,
598
        smart_hdr_flit             ,
599
        //flit
600
        flit_hdr_flag_i        ,
601
        flit_tail_flag_i       ,
602
        flit_wr_i              ,
603
        //router ivc status
604
        ovc_locally_requested       ,
605
        assigned_to_ss_ovc          ,
606
        assigned_ovc_not_full       ,
607
        ovc_is_assigned             ,
608
        ivc_request                 ,
609
        //ss port status
610
        ss_ovc_avalable_in_ss_port  ,
611
        ss_ovc_crossbar_wr,
612
        ss_port_link_reg_flit_wr    ;
613
//output
614
output
615
        smart_single_flit_pck_o                 ,
616
        smart_ivc_smart_en_o         ,
617
        smart_credit_o                  ,
618
        smart_buff_space_decreased_o  ,
619
        smart_ss_ovc_is_allocated_o   ,
620
        smart_ss_ovc_is_released_o    ,
621
        smart_ivc_num_getting_ovc_grant_o,
622
        smart_ivc_reset_o,
623
        smart_mask_available_ss_ovc_o;
624
 
625
output reg [V-1 : 0] smart_ivc_granted_ovc_num_o;
626
 
627
always @(*) begin
628
        smart_ivc_granted_ovc_num_o={V{1'b0}};
629
        smart_ivc_granted_ovc_num_o[IVC_NUM]=smart_ivc_num_getting_ovc_grant_o;
630
end
631
 
632
 
633
 
634
wire  smart_req_valid_next  = smart_requests_i &  smart_ivc_i & goes_straight;
635
logic smart_req_valid;
636
wire  smart_hdr_flit_req_next = smart_req_valid_next  & smart_hdr_flit;
637
logic smart_hdr_flit_req;
638
 
639 54 alirezamon
pronoc_register #(.W(1)) req1 (.in(smart_req_valid_next), .reset(reset), .clk(clk), .out(smart_req_valid));
640
pronoc_register #(.W(1)) req2 (.in(smart_hdr_flit_req_next), .reset(reset), .clk(clk), .out(smart_hdr_flit_req));
641 48 alirezamon
 
642
 
643
 
644
 
645
// condition1: new smart vc allocation condition
646
wire hdr_flit_condition    = ~ovc_locally_requested & ss_ovc_avalable_in_ss_port;
647
wire nonhdr_flit_condition = assigned_to_ss_ovc & assigned_ovc_not_full;
648
wire condition1 =
649
        /* verilator lint_off WIDTH */
650
        (PCK_TYPE == "SINGLE_FLIT")?  hdr_flit_condition :
651
        /* verilator lint_on WIDTH */
652
        (ovc_is_assigned)? nonhdr_flit_condition : hdr_flit_condition;
653
wire condition2;
654
generate
655
 
656
/* verilator lint_off WIDTH */
657
wire non_empty_ivc_condition =(PCK_TYPE == "SINGLE_FLIT")?  1'b0 :ivc_request;
658
/* verilator lint_on WIDTH */
659
 
660
 
661
if( ADD_PIPREG_AFTER_CROSSBAR == 1 ) begin :link_reg
662
        assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr| ss_ovc_crossbar_wr);
663
end else begin : no_link_reg
664
        assign condition2= ~(non_empty_ivc_condition | ss_port_link_reg_flit_wr); // ss_port_link_reg_flit_wr are identical with ss_ovc_crossbar_wr when there is no link reg
665
end
666
 
667
endgenerate
668
wire conditions_met = condition1 & condition2;
669
assign smart_ivc_smart_en_o = conditions_met & smart_req_valid;
670
 
671
 
672
 
673
assign smart_single_flit_pck_o     =
674
        /* verilator lint_off WIDTH */
675
        (PCK_TYPE == "SINGLE_FLIT")? 1'b1 :
676
        /* verilator lint_on WIDTH */
677
        (MIN_PCK_SIZE==1)?  flit_tail_flag_i & flit_hdr_flag_i : 1'b0;
678
 
679
assign smart_buff_space_decreased_o =  smart_ivc_smart_en_o & flit_wr_i ;
680
assign smart_ivc_num_getting_ovc_grant_o  =  smart_buff_space_decreased_o & !ovc_is_assigned  & flit_hdr_flag_i;
681
assign smart_ivc_reset_o   =  smart_buff_space_decreased_o & flit_tail_flag_i;
682
assign smart_ss_ovc_is_released_o = smart_ivc_reset_o & ~smart_single_flit_pck_o;
683
assign smart_ss_ovc_is_allocated_o = smart_ivc_num_getting_ovc_grant_o & ~smart_single_flit_pck_o;
684
 
685
 
686
 
687
 
688
//mask the available SS OVC for local requests allocation if the following conditions met
689
assign smart_mask_available_ss_ovc_o = smart_hdr_flit_req & ~ovc_locally_requested & condition2;
690
 
691
 
692 54 alirezamon
pronoc_register #(.W(1)) credit(.in(smart_buff_space_decreased_o), .reset(reset), .clk(clk), .out(smart_credit_o));
693 48 alirezamon
 
694
endmodule
695
 
696
 
697
 
698
module smart_allocator_per_iport
699
        import pronoc_pkg::*;
700
#(
701
        parameter P=5,
702
        parameter SW_LOC=0,
703
        parameter SS_PORT_LOC=1
704
        )(
705
        //general
706
        clk,
707
        reset,
708
        current_r_addr_i,
709
        neighbors_r_addr_i,
710
        //smart_chanel & flit in
711
        smart_chanel_i,
712
        flit_chanel_i,
713
        //router status signals
714
        ivc_info,
715
        ss_ovc_info,
716
        ovc_locally_requested,//make sure no conflict is existed between local & SMART VC allocation
717
        ss_port_link_reg_flit_wr,
718
        ss_smart_chanel_new,
719
        //output
720
        smart_destport_o,
721
        smart_lk_destport_o,
722
        smart_ivc_smart_en_o,
723
        smart_credit_o,
724
        smart_buff_space_decreased_o,
725
        smart_ss_ovc_is_allocated_o,
726
        smart_ss_ovc_is_released_o,
727
        smart_ivc_num_getting_ovc_grant_o,
728
        smart_ivc_reset_o,
729
        smart_mask_available_ss_ovc_o,
730
        smart_hdr_flit_req_o,
731
        smart_ivc_granted_ovc_num_o,
732
        smart_ivc_single_flit_pck_o,
733
        smart_ovc_single_flit_pck_o
734
);
735
        //general
736
        input clk, reset;
737
        input [RAw-1   :0]  current_r_addr_i;
738
        input [RAw-1:  0]  neighbors_r_addr_i [P-1 : 0];
739
        //channels
740
        input smart_chanel_t smart_chanel_i;
741
        input flit_chanel_t flit_chanel_i;
742
        //ivc
743
        input ivc_info_t ivc_info [V-1 : 0];
744
        input [V-1 : 0] ovc_locally_requested;
745
        //ss port
746
        input ovc_info_t   ss_ovc_info [V-1 : 0];
747
        input ss_port_link_reg_flit_wr;
748
        input smart_chanel_t ss_smart_chanel_new;
749
        //output
750
        output [DSTPw-1 : 0] smart_destport_o,smart_lk_destport_o;
751
        output smart_hdr_flit_req_o;
752
        output [V-1 : 0]
753
                smart_ivc_smart_en_o,
754
                smart_credit_o,
755
                smart_buff_space_decreased_o,
756
                smart_ss_ovc_is_allocated_o,
757
                smart_ss_ovc_is_released_o,
758
                smart_mask_available_ss_ovc_o,
759
                smart_ivc_num_getting_ovc_grant_o,
760
                smart_ivc_reset_o,
761
                smart_ivc_single_flit_pck_o,
762
                smart_ovc_single_flit_pck_o;
763
        output [V*V-1 : 0] smart_ivc_granted_ovc_num_o;
764
 
765
        assign smart_ovc_single_flit_pck_o = smart_ivc_single_flit_pck_o;
766
        wire  [DSTPw-1  :   0]  destport,lkdestport;
767
        wire  goes_straight;
768
 
769
 
770
 
771
        /* verilator lint_off WIDTH */
772
        localparam  LOCATED_IN_NI=
773
                (TOPOLOGY=="RING" || TOPOLOGY=="LINE") ? (SW_LOC == 0 || SW_LOC>2) :
774 54 alirezamon
                (TOPOLOGY =="MESH" || TOPOLOGY=="TORUS" || TOPOLOGY == "FMESH")? (SW_LOC == 0 || SW_LOC>4) : 0;
775 48 alirezamon
        /* verilator lint_on WIDTH */
776
 
777
        // does the route computation for the current router
778
        conventional_routing #(
779
                .TOPOLOGY        (TOPOLOGY       ),
780
                .ROUTE_NAME      (ROUTE_NAME     ),
781
                .ROUTE_TYPE      (ROUTE_TYPE     ),
782
                .T1              (T1             ),
783
                .T2              (T2             ),
784
                .T3              (T3             ),
785
                .RAw             (RAw            ),
786
                .EAw             (EAw            ),
787
                .DSTPw           (DSTPw          ),
788
                .LOCATED_IN_NI   (LOCATED_IN_NI  )
789
        ) routing (
790
                .reset           (reset          ),
791
                .clk             (clk            ),
792
                .current_r_addr  (current_r_addr_i ),
793
                .src_e_addr      (                           ),// needed only for custom routing
794
                .dest_e_addr     (smart_chanel_i.dest_e_addr    ),
795
                .destport        (destport)
796
        );
797
 
798 54 alirezamon
        pronoc_register #(.W(DSTPw)) reg1 (.in(destport), .reset(reset), .clk(clk), .out(smart_destport_o));
799 48 alirezamon
 
800
        check_straight_oport #(
801
                .TOPOLOGY      ( TOPOLOGY     ),
802
                .ROUTE_NAME    ( ROUTE_NAME   ),
803
                .ROUTE_TYPE    ( ROUTE_TYPE   ),
804
                .DSTPw         ( DSTPw        ),
805
                .SS_PORT_LOC   ( SS_PORT_LOC)
806
        ) check_straight (
807
                .destport_coded_i (destport),
808
                .goes_straight_o  (goes_straight)
809
        );
810
 
811
        //look ahead routing. take straight next router address as input
812
        conventional_routing #(
813
                        .TOPOLOGY        (TOPOLOGY       ),
814
                        .ROUTE_NAME      (ROUTE_NAME     ),
815
                        .ROUTE_TYPE      (ROUTE_TYPE     ),
816
                        .T1              (T1             ),
817
                        .T2              (T2             ),
818
                        .T3              (T3             ),
819
                        .RAw             (RAw            ),
820
                        .EAw             (EAw            ),
821
                        .DSTPw           (DSTPw          ),
822
                        .LOCATED_IN_NI   (LOCATED_IN_NI  )
823
                ) lkrouting (
824
                        .reset           (reset          ),
825
                        .clk             (clk            ),
826
                        .current_r_addr  (neighbors_r_addr_i[SS_PORT_LOC] ),
827
                        .src_e_addr      (                           ),// needed only for custom routing
828
                        .dest_e_addr     (smart_chanel_i.dest_e_addr    ),
829
                        .destport        (lkdestport)
830
                );
831
 
832 54 alirezamon
        pronoc_register #(.W(DSTPw)) reg2 (.in(lkdestport), .reset(reset), .clk(clk), .out(smart_lk_destport_o));
833 48 alirezamon
 
834
        wire [V-1 : 0] ss_ovc_crossbar_wr;//If asserted, a flit will be injected to ovc at next clk cycle
835
        assign ss_ovc_crossbar_wr = (ss_smart_chanel_new.requests[0] ) ? ss_smart_chanel_new.ovc : {V{1'b0}};
836
 
837
 
838
 
839
        //assign smart_ivc_num_getting_ovc_grant_o = smart_ss_ovc_is_allocated_o;
840
        //assign smart_ivc_reset_o = smart_ss_ovc_is_released_o;
841
 
842
        genvar i,j;
843
        generate
844
        for (i=0;i
845
                smart_validity_check_per_ivc #(
846
                                .IVC_NUM(i)
847
                )       validity_check (
848
                        .reset                       (reset                             ),
849
                        .clk                         (clk                               ),
850
                        .goes_straight                           (goes_straight),
851
                        .smart_requests_i              (smart_chanel_i.requests[0]              ),
852
                        .smart_ivc_i                   (smart_chanel_i.ovc  [i]                 ),
853
                        .smart_hdr_flit                          (smart_chanel_i.hdr_flit     ),
854
 
855
                        .flit_hdr_flag_i                (flit_chanel_i.flit.hdr_flag            ),
856
                        .flit_tail_flag_i               (flit_chanel_i.flit.tail_flag       ),
857
                        .flit_wr_i                      (flit_chanel_i.flit_wr         ),
858
 
859
                        .ovc_locally_requested      (ovc_locally_requested[i]   ),
860
 
861
                        .assigned_to_ss_ovc          (ivc_info[i].assigned_ovc_num[i]),
862
                        .assigned_ovc_not_full       (~ss_ovc_info[i].full),
863
                        .ovc_is_assigned             (ivc_info[i].ovc_is_assigned),
864
                        .ivc_request                 (ivc_info[i].ivc_req       ),
865
 
866
                        .ss_ovc_avalable_in_ss_port  (ss_ovc_info[i].avalable),
867
                        .ss_port_link_reg_flit_wr    (ss_port_link_reg_flit_wr     ),
868
                        .ss_ovc_crossbar_wr          (ss_ovc_crossbar_wr[i]),
869
 
870
                        .smart_single_flit_pck_o       (smart_ivc_single_flit_pck_o[i]  ),
871
                        .smart_ivc_smart_en_o                    (smart_ivc_smart_en_o[i]       ),
872
                        .smart_credit_o                  (smart_credit_o[i]     ),
873
                        .smart_buff_space_decreased_o  (smart_buff_space_decreased_o[i]),
874
                        .smart_ss_ovc_is_allocated_o   (smart_ss_ovc_is_allocated_o[i] ),
875
                        .smart_ss_ovc_is_released_o    (smart_ss_ovc_is_released_o[i]  ),
876
                        .smart_mask_available_ss_ovc_o (smart_mask_available_ss_ovc_o[i] ),
877
                        .smart_ivc_num_getting_ovc_grant_o(smart_ivc_num_getting_ovc_grant_o[i]),
878
                        .smart_ivc_reset_o                       (smart_ivc_reset_o[i]),
879
                        .smart_ivc_granted_ovc_num_o   (smart_ivc_granted_ovc_num_o[(i+1)*V-1 : i*V])
880
                );
881
 
882
 
883
 
884
 
885
 
886
        end//for
887
        endgenerate
888
 
889
 
890 54 alirezamon
        pronoc_register #(.W(1)) reg3 (.in(smart_chanel_i.hdr_flit), .reset(reset), .clk(clk), .out(smart_hdr_flit_req_o));
891 48 alirezamon
 
892
endmodule
893
 
894
//
895
module smart_credit_manage #(
896
        parameter V=4,
897
        parameter B=2
898
        )(
899
                credit_in,
900
                smart_credit_in,
901
                credit_out,
902
                reset,
903
                clk
904
        );
905
        localparam Bw=$clog2(B);
906
 
907
        input [V-1 : 0]  credit_in, smart_credit_in;
908
        input reset,    clk;
909
        output [V-1 : 0]  credit_out;
910
        genvar i;
911
        generate
912
        for (i=0;i
913
                smart_credit_manage_per_vc #(
914
                        .Bw(Bw)
915
                        )credit(
916
                                .credit_in(credit_in[i]),
917
                                .smart_credit_in(smart_credit_in[i]),
918
                                .credit_out(credit_out[i]),
919
                                .reset(reset),
920
                                .clk(clk)
921
                        );
922
        end
923
        endgenerate
924
endmodule
925
 
926
module smart_credit_manage_per_vc #(
927
                parameter Bw=2
928
)(
929
        credit_in,
930
        smart_credit_in,
931
        credit_out,
932
        reset,
933
        clk
934
);
935
 
936
        input credit_in, smart_credit_in,       reset,  clk;
937
        output credit_out;
938
 
939
        logic [Bw : 0] counter, counter_next;
940
 
941
        always @(*) begin
942
                counter_next=counter;
943
                if(credit_in & 	smart_credit_in ) counter_next = counter +1'b1;
944
                else if(credit_in |     smart_credit_in ) counter_next=counter;
945
                else if(counter > 0) counter_next = counter -1'b1;
946
        end
947
 
948
        assign credit_out = credit_in |         smart_credit_in | (counter > 0);
949
 
950 54 alirezamon
        pronoc_register #(.W(Bw+1)) reg1 (.in(counter_next), .reset(reset), .clk(clk), .out(counter));
951 48 alirezamon
 
952
 
953
endmodule
954
 
955
 
956
 
957
 
958
 
959
 
960
 
961
 
962
 
963
 
964
 
965
 
966
 
967
 
968
 
969
 
970
 
971
 

powered by: WebSVN 2.1.0

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