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 56

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

powered by: WebSVN 2.1.0

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