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 48

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

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

powered by: WebSVN 2.1.0

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