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/] [wrra.v] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
`timescale 1ns / 1ps
2
 
3
/**********************************************************************
4
**  File:  wrra.v
5
**  Date:2017-07-11
6
**
7
**  Copyright (C) 2014-2017  Alireza Monemi
8
**
9
**  This file is part of ProNoC
10
**
11
**  ProNoC ( stands for Prototype Network-on-chip)  is free software:
12
**  you can redistribute it and/or modify it under the terms of the GNU
13
**  Lesser General Public License as published by the Free Software Foundation,
14
**  either version 2 of the License, or (at your option) any later version.
15
**
16
**  ProNoC is distributed in the hope that it will be useful, but WITHOUT
17
**  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18
**  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
19
**  Public License for more details.
20
**
21
**  You should have received a copy of the GNU Lesser General Public
22
**  License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
23
**
24
**
25
**  Description:
26
**  Weighted round robin arbiter support for QoS support in NoC:
27
**  Packets are injected with initial weights. The defualt value is 1.
28
**  Weights are assigned to each input ports according to contention degree.
29
**  The contention degree is calculated based on the accumulation of input ports
30
**  weight sending packet to the same output ports.
31
**  Swich allocator's output arbters' priority is lucked until the winner's
32
**  input weight is not consumed. A weight is consumed when a packet is sent.
33
**
34
**      PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 );
35
**      PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 );
36
**      PROPOGATE_NEQ1 = (WRRA_CONFIG_INDEX==2 );
37
**      PROPOGATE_NEQ2 = (WRRA_CONFIG_INDEX==3 );
38
*****************************************************************/
39
 
40 54 alirezamon
`include "pronoc_def.v"
41
 
42 48 alirezamon
module  wrra #(
43
    parameter ARBITER_WIDTH = 8,
44
    parameter WEIGHTw = 4, // maximum weight size in bits
45
    parameter EXT_P_EN = 1
46
 
47
)
48
(
49
 
50
   ext_pr_en_i,
51
   clk,
52
   reset,
53
   request,
54
   grant,
55
   any_grant,
56
   weight_array,
57
   winner_weight_consumed
58
);
59
 
60
    localparam WEIGHT_ARRAYw= WEIGHTw * ARBITER_WIDTH;
61
 
62
    input                                  ext_pr_en_i;
63
    input     [ARBITER_WIDTH-1  :    0]    request;
64
    output    [ARBITER_WIDTH-1  :    0]    grant;
65
    output                                 any_grant;
66
    input                                  clk;
67
    input                                  reset;
68
    input    [WEIGHT_ARRAYw-1   :   0]     weight_array;
69
    output                                 winner_weight_consumed;
70
 
71
 
72
    wire [WEIGHTw-1 :   0] weight [ARBITER_WIDTH-1  :   0];
73
    wire [ARBITER_WIDTH-1:  0] weight_counter_is_reset;
74
 
75
    genvar i;
76
    generate
77
    for (i=0; i<ARBITER_WIDTH; i=i+1) begin : wcount
78
        // seperate wieghts
79
        assign weight [i] = weight_array [ ((i+1)*WEIGHTw)-1    :   i*WEIGHTw];
80
 
81
        weight_counter #(
82
            .WEIGHTw(WEIGHTw)
83
        )
84
        w_counter
85
        (
86
            .load_i(1'b0),
87
            .weight_i(weight [i]),
88
            .reset(reset),
89
            .clk(clk),
90
            .decr(grant[i]),
91
            .out(weight_counter_is_reset[i])
92
        );
93
 
94
    end
95
    endgenerate
96
 
97
 
98
 
99
    // one hot mux
100
 
101
    onehot_mux_1D #(
102
        .W(1),
103
        .N(ARBITER_WIDTH)
104
    )
105
    mux
106
    (
107
        .in(weight_counter_is_reset),
108
        .out(winner_weight_consumed),
109
        .sel(grant)
110
    );
111
 
112
    wire priority_en = (EXT_P_EN == 1) ? ext_pr_en_i & winner_weight_consumed : winner_weight_consumed;
113
 
114
    //round robin arbiter with external priority
115
 
116
     arbiter_priority_en #(
117
        .ARBITER_WIDTH(ARBITER_WIDTH)
118
    )
119
    rra
120
    (
121
        .request(request),
122
        .grant(grant),
123
        .any_grant(any_grant),
124
        .clk(clk),
125
        .reset(reset),
126
        .priority_en(priority_en)
127
    );
128
 
129
endmodule
130
 
131
 
132
 
133
 
134
 
135
 
136
module  rra_priority_lock #(
137
    parameter    ARBITER_WIDTH    =8
138
)
139
(
140
 
141
   ext_pr_en_i,
142
   winner_weight_consumed,
143
   pr_en_array_i,
144
 
145
   clk,
146
   reset,
147
 
148
   request,
149
   grant,
150
   any_grant
151
);
152
 
153
 
154
    input     [ARBITER_WIDTH-1:     0]     pr_en_array_i;
155
    input                                  ext_pr_en_i;
156
    output                                 winner_weight_consumed;
157
    input     [ARBITER_WIDTH-1  :    0]    request;
158
    output    [ARBITER_WIDTH-1  :    0]    grant;
159
    output                                 any_grant;
160
    input                                  clk;
161
    input                                  reset;
162
 
163
 
164
    // one hot mux
165
 
166
    onehot_mux_1D #(
167
        .W(1),
168
        .N(ARBITER_WIDTH)
169
    )
170
    mux
171
    (
172
        .in(pr_en_array_i),
173
        .out(winner_weight_consumed),
174
        .sel(grant)
175
    );
176
 
177
    wire priority_en = ext_pr_en_i & winner_weight_consumed;
178
 
179
    //round robin arbiter with external priority
180
 
181
     arbiter_priority_en #(
182
        .ARBITER_WIDTH(ARBITER_WIDTH)
183
    )
184
    rra
185
    (
186
        .request(request),
187
        .grant(grant),
188
        .any_grant(any_grant),
189
        .clk(clk),
190
        .reset(reset),
191
        .priority_en(priority_en)
192
    );
193
 
194
endmodule
195
 
196
 
197
 
198
 
199
 
200
/**************
201
*   weight_counter
202
*
203
***************/
204
 
205
 
206
module weight_counter #(
207
    parameter WEIGHTw=4
208
)(
209
 
210
    weight_i,
211
    decr,
212
    load_i,
213
    out,
214
    reset,
215
    clk
216
 
217
);
218
 
219
    input [WEIGHTw-1    :   0]  weight_i;
220
    input reset,clk,decr,load_i;
221
    output  out;
222
    wire [WEIGHTw-1    :   0]  weight;
223
 
224 54 alirezamon
    reg  [WEIGHTw-1    :   0] counter_next;
225
    wire [WEIGHTw-1    :   0] counter;
226 48 alirezamon
    wire couner_zero, load;
227
 
228
    assign couner_zero = counter == {WEIGHTw{1'b0}};
229
    assign load =  (counter > weight_i) | load_i;
230
    assign out = couner_zero;
231
    assign weight= (weight_i == {WEIGHTw{1'b0}} )? 1 : weight_i; // minimum weight is 1;
232
    always @(*)begin
233
        counter_next = counter;
234
        if(load) counter_next  = weight- 1'b1 ;
235
        if(decr) counter_next  = (couner_zero)? weight-1'b1  : counter - 1'b1; // if the couner has zero value then the load is active not decrese
236
 
237
    end
238
 
239 54 alirezamon
    pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
240 48 alirezamon
 
241 54 alirezamon
 
242 48 alirezamon
 
243
 
244
endmodule
245
 
246
 
247
/**************
248
*   weight_counter
249
*
250
***************/
251
 
252
 
253
module classic_weight_counter #(
254
    parameter WEIGHTw=4
255
)(
256
 
257
    weight_i,
258
    decr,
259
    load_i,
260
    out,
261
    reset,
262
    clk
263
 
264
);
265
 
266
    input [WEIGHTw-1    :   0]  weight_i;
267
    input reset,clk,decr,load_i;
268
    output  out;
269
    wire [WEIGHTw-1    :   0]  weight;
270
 
271 54 alirezamon
    reg  [WEIGHTw-1    :   0] counter_next;
272
    wire [WEIGHTw-1    :   0] counter;
273 48 alirezamon
    wire couner_zero, load;
274
 
275
    assign couner_zero = counter == {WEIGHTw{1'b0}};
276
    assign load =  (counter > weight_i) | load_i;
277
    assign out = couner_zero;
278
    assign weight= (weight_i == {WEIGHTw{1'b0}} )? 1 : weight_i; // minimum weight is 1;
279
    always @(*)begin
280
        counter_next = counter;
281
        if(load) counter_next  = weight- 1'b1 ;
282
        if(decr && !couner_zero) counter_next  = counter - 1'b1; // if the couner has zero value then the load is active not decrese
283
 
284
    end
285
 
286 54 alirezamon
    pronoc_register #(.W(WEIGHTw)) reg2 (.in(counter_next ), .out(counter), .reset(reset), .clk(clk));
287 48 alirezamon
 
288
 
289
endmodule
290
 
291
 
292
 
293
/***************
294
*   weight_control
295
***************/
296
 
297
 
298
module  weight_control #(
299
    parameter ARBITER_TYPE="WRRA",
300
    parameter SW_LOC=0,
301
    parameter WEIGHTw= 4,
302
    parameter WRRA_CONFIG_INDEX=0,
303
    parameter P=5,
304
    parameter SELF_LOOP_EN = "NO"
305
)
306
(
307
 
308
    sw_is_granted,
309
    flit_is_tail,
310
    iport_weight,
311
    granted_dest_port,
312
    weight_is_consumed_o,
313
    oports_weight,
314
    refresh_w_counter,
315
    clk,
316
    reset
317
);
318
 
319
    localparam
320
        W = WEIGHTw,
321
        WP = W * P,
322
        P_1 = (SELF_LOOP_EN=="NO") ?  P-1 : P;
323
 
324
    localparam [W-1 : 0] INIT_WEIGHT = 1;
325
    localparam [W-1 : 0] MAX_WEIGHT = {W{1'b1}}-1'b1;
326
 
327
    localparam  PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 ),
328
                PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 ),
329
                PROPOGATE_NEQ1 = (WRRA_CONFIG_INDEX==2 ),
330
                PROPOGATE_NEQ2 = (WRRA_CONFIG_INDEX==3 );
331
 
332
    input  sw_is_granted , flit_is_tail;
333
    input  [WEIGHTw-1 : 0] iport_weight;
334
    input  clk,reset;
335
    output weight_is_consumed_o;
336
    input  [P_1-1 : 0] granted_dest_port;
337
    output [WP-1 : 0] oports_weight;
338
    input refresh_w_counter;
339
 
340
    // wire ivc_empty = ~ivc_not_empty;    
341
    wire counter_is_reset;
342
    wire weight_dcrease_en = sw_is_granted & flit_is_tail;
343
    wire [P-1 : 0] dest_port;
344
    reg  [W-1 : 0] oport_weight_counter [P-1 : 0];
345
    reg  [W-1 : 0] oport_weight [P-1 : 0];
346
 
347
    generate
348
    if(SELF_LOOP_EN == "NO") begin : nslp
349
        add_sw_loc_one_hot #(
350
            .P(P),
351
            .SW_LOC(SW_LOC)
352
        )
353
        add_sw_loc
354
        (
355
            .destport_in(granted_dest_port),
356
            .destport_out(dest_port)
357
        );
358
    end else begin : slp
359
        assign dest_port = granted_dest_port;
360
    end
361
    endgenerate
362
 
363
    assign oports_weight [W-1 : 0] = {W{1'b0}};
364
 
365
    genvar i;
366
    generate
367
 
368
 
369
    if(PROPOGATE_EQUALL | PROPOGATE_LIMITED )begin : eq
370
 
371
         for (i=1;i<P;i=i+1)begin : port
372
             if(i==SW_LOC) begin : if1
373
                assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
374
             end else begin :else1
375
                assign oports_weight[(i+1)*W-1 : i*W]  = iport_weight;
376
            end
377
         end //for
378
 
379
    end else if (PROPOGATE_NEQ1) begin :neq1
380
 
381
        always @(*)begin
382
               oport_weight_counter[0]= {W{1'b0}};// the output port weight of local port is useless. hence fix it as zero.
383
               oport_weight[0]= {W{1'b0}};
384
        end
385
 
386
 
387
        for (i=1;i<P;i=i+1)begin : port
388
             if(i==SW_LOC) begin : if1
389
 
390
                always @(*) begin
391
                    oport_weight_counter[i]= {W{1'b0}};// The loopback injection is forbiden hence it will be always as zero.
392
                    oport_weight[i]= {W{1'b0}};
393
                end
394
                assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
395
             end else begin :else1
396
 
397 54 alirezamon
 
398
                always @ (`pronoc_clk_reset_edge )begin
399
                    if(`pronoc_reset) begin
400 48 alirezamon
                        oport_weight_counter[i]<=INIT_WEIGHT;
401
                    end else begin
402
                        if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
403
                        else if (weight_dcrease_en && dest_port[i] && oport_weight_counter[i] != {W{1'b1}} )oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
404
                    end
405
                end //always
406
 
407 54 alirezamon
                always @ (`pronoc_clk_reset_edge )begin
408
                    if(`pronoc_reset) begin
409 48 alirezamon
                        oport_weight[i]<={W{1'b0}};
410
                    end else begin
411
                        if (weight_dcrease_en && counter_is_reset) oport_weight[i]<= oport_weight_counter[i];  //capture oweight counters                    
412
                    end
413
                end //always
414
                assign oports_weight [(i+1)*W-1 : i*W] = oport_weight[i];
415
             end  //else 
416
 
417
 
418
 
419
        end //for
420
 
421
 
422
    end else begin : neq2 //if (PROPOGATE_NEQ1) :neq1 
423
 
424
 
425
 
426
    for (i=0;i<P;i=i+1)begin : port
427
        if(i==0) begin : local_p
428
            always @ (posedge clk)begin
429
                        oport_weight_counter[i]<= {W{1'b0}};// the output port weight of local port is useless. hence fix it as zero.
430
                        oport_weight[i]<= {W{1'b0}};
431
            end//always
432
        end//local_p
433
 
434
             else if(i==SW_LOC) begin : if1
435
 
436
               always @ (posedge clk)begin
437
                    oport_weight_counter[i]<= {W{1'b0}};// The loopback injection is forbiden hence it will be always as zero.
438
                    oport_weight[i]<= {W{1'b0}};
439
                end
440
                assign oports_weight [(i+1)*W-1 : i*W] = {W{1'b0}};
441
             end else begin :else1
442
 
443 54 alirezamon
                always @ (`pronoc_clk_reset_edge )begin
444
                    if(`pronoc_reset) begin
445 48 alirezamon
                        oport_weight_counter[i]<= INIT_WEIGHT;
446
                    end else begin
447
                        if (weight_dcrease_en && counter_is_reset) oport_weight_counter[i]<= INIT_WEIGHT;
448
                        else if (weight_dcrease_en && dest_port[i] && oport_weight_counter[i] <MAX_WEIGHT )oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
449
                    end
450
                end //always
451
 
452 54 alirezamon
                always @ (`pronoc_clk_reset_edge )begin
453
                    if(`pronoc_reset) begin
454 48 alirezamon
                        oport_weight[i]<={W{1'b0}};
455
                    end else begin
456 54 alirezamon
                        if(oport_weight[i]>iport_weight) oport_weight[i]<=iport_weight;// weight counter should always be smaller than iport weight
457 48 alirezamon
                        else if (weight_dcrease_en)begin
458 54 alirezamon
                            if( counter_is_reset ) begin
459
                                oport_weight[i]<= (oport_weight_counter[i]>0)? oport_weight_counter[i]: 1;
460
                            end//counter_reset
461
                            else begin
462
                                if (oport_weight_counter[i]>0 && oport_weight[i] < oport_weight_counter[i]) oport_weight[i]<= oport_weight_counter[i];
463
                            end
464
                        end//weight_dcr                          
465 48 alirezamon
                    end//else reset
466
                end //always
467 54 alirezamon
 
468 48 alirezamon
                assign oports_weight [(i+1)*W-1 : i*W] = oport_weight[i];
469 54 alirezamon
             end  //else            
470 48 alirezamon
 
471 54 alirezamon
        end //for    
472 48 alirezamon
 
473
    end
474
 
475
 
476
 
477
 
478
    /* verilator lint_off WIDTH */
479
    if(ARBITER_TYPE == "WRRA_CLASSIC") begin : wrra_classic
480
    /* verilator lint_on WIDTH */
481
        // use classic WRRA. only for compasrion with propsoed wrra 
482
 
483
        classic_weight_counter #(
484
            .WEIGHTw(WEIGHTw)
485
        )
486
           iport_weight_counter
487
        (
488
            .load_i(refresh_w_counter),
489
            .weight_i(iport_weight),
490
            .reset(reset),
491
            .clk(clk),
492
            .decr(weight_dcrease_en),
493
            .out(counter_is_reset)
494
        );
495
 
496
    end else begin : wrra_mine
497
        // weight counters   
498
        weight_counter #(
499
            .WEIGHTw(WEIGHTw)
500
        )
501
        iport_weight_counter
502
        (
503
            .load_i(refresh_w_counter),
504
            .weight_i(iport_weight),
505
            .reset(reset),
506
            .clk(clk),
507
            .decr(weight_dcrease_en),
508
            .out(counter_is_reset)
509
        );
510
 
511
 
512
    end
513
 
514
    endgenerate
515
 
516
 
517
 
518
 
519
 
520
 
521
 
522
    assign weight_is_consumed_o = counter_is_reset; //  & flit_is_tail ;
523
 
524
endmodule
525
 
526
 
527
 
528
 
529
/***************
530
*       wrra_contention_gen
531
* generate contention based on number of request to
532
* the same output port
533
***************/
534
 
535
 
536
module  wrra_contention_gen #(
537
    parameter V=4,
538
    parameter P=5,
539
    parameter WRRA_CONFIG_INDEX=0,
540
    parameter WEIGHTw = 4, // WRRA width
541
    parameter SELF_LOOP_EN ="NO"
542
)(
543
    ovc_is_assigned_all,
544
    ivc_request_all,
545
    dest_port_all,
546
    iport_weight_all,
547
    oports_weight_all,
548
    contention_all,
549
    limited_oport_weight_all
550
);
551
 
552
    function integer log2;
553
      input integer number; begin
554
         log2=(number <=1) ? 1: 0;
555
         while(2**log2<number) begin
556
            log2=log2+1;
557
         end
558
      end
559
    endfunction // log2 
560
 
561
    localparam
562
        P_1 = (SELF_LOOP_EN == "NO") ?  P-1 : P,
563
        PV = P * V,
564
        VP_1= V * P_1,
565
        PVP_1 = PV * P_1,
566
        Pw= log2(P),
567
        PwP= Pw *P,
568
        W= WEIGHTw,
569
        WP= W * P,
570
        WPP = WP * P;
571
 
572
        localparam
573
            VALID_IF_HAS_FLIT  = 1, //1: has flit 0: VC-Assigned
574
            PROPOGATE_EQUALL = (WRRA_CONFIG_INDEX==0 ),
575
            PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 );
576
 
577
 
578
    input  [PVP_1-1 :  0] dest_port_all;
579
    input  [PV-1 : 0] ovc_is_assigned_all;
580
    input  [PV-1 : 0] ivc_request_all;
581
    input  [WP-1 : 0] iport_weight_all;
582
    output [WP-1 : 0] contention_all;
583
    input  [WPP-1 : 0] oports_weight_all;
584
    input  [WP-1 : 0] limited_oport_weight_all;
585
 
586
 
587
    wire [P-1 : 0] destport_sum [P-1 : 0];//destport_sum[inport-num][out-num]=  out-port is requested by inport-num
588
    wire [P-1 : 0] contention_one_hot [P-1  :   0];  //contention_one_hot[outport-num][inport-num]=  inport- is requesting this outport
589
 
590
    wire [W-1 : 0] iport_weight [P-1  :   0];
591
    wire [W-1 : 0] weight_sum [P-1  :   0];
592
    wire [W-1 : 0] contention [P-1  :   0];
593
    wire [WP-1 : 0] weight_array_per_outport [P-1  :   0];
594
    wire [WP-1: 0] oports_weight [P-1  :   0];
595
    // weight_array_per_outport[outport-num][inport-num]= weight-inport-num if  inport- is requesting this outport
596
 
597
 
598
   wire [PV-1 : 0] weight_is_valid = (VALID_IF_HAS_FLIT)? ivc_request_all : ovc_is_assigned_all ;
599
 
600
    genvar j,i;
601
    generate
602
    for (i=0;i<P; i=i+1) begin : port_lp
603
        assign iport_weight[i]= iport_weight_all[(i+1)*W-1  : i*W];
604
        assign oports_weight[i]= oports_weight_all [(i+1)*WP-1  : i*WP];
605
 
606
         //get the lis of all destination ports requested by each port
607
         wrra_inputport_destports_sum #(
608
            .V(V),
609
            .P(P),
610
            .SW_LOC(i),
611
            .SELF_LOOP_EN(SELF_LOOP_EN)
612
         )
613
         destports_sum
614
         (
615
            .weight_is_valid(weight_is_valid[(i+1)*V-1  : i*V]),
616
            .dest_ports(dest_port_all [(i+1)*VP_1-1  : i*VP_1]),
617
            .destports_sum(destport_sum[i])
618
         );
619
 
620
 
621
 
622
 
623
         for (j=0;j<P;j=j+1) begin : outlp1
624
            assign  contention_one_hot[j][i] =  destport_sum[i][j];
625
            if(PROPOGATE_EQUALL | PROPOGATE_LIMITED ) begin : peq
626
               assign  weight_array_per_outport[j][(i+1)*W-1  : i*W] = (contention_one_hot[j][i])? iport_weight[i] : {W{1'b0}};
627
            end
628
            else begin : pneq
629
               assign  weight_array_per_outport[j][(i+1)*W-1  : i*W] = (contention_one_hot[j][i])? oports_weight[i][(j+1)*W-1 : j*W] : {W{1'b0}};
630
            end
631
         end//for
632
 
633
 
634
         //contention is the sum of all inputports weights requesting this outputport
635
         accumulator #(
636
            .INw(WP),
637
            .OUTw(W),
638
            .NUM(P)
639
 
640
         )
641
         accum
642
         (
643
            .in_all(weight_array_per_outport[i]),
644
            .out(weight_sum[i])
645
         );
646
 
647
 
648
         if(PROPOGATE_LIMITED) begin : limted
649
 
650
            wire [W-1 : 0] limited_oport_weight [P-1 : 0];
651
            for (j=0;j<P;j=j+1) begin : outlp1
652
                assign  limited_oport_weight [j] = limited_oport_weight_all [(j+1)*W-1 : j*W];
653
                assign contention[j] = (limited_oport_weight [j] > weight_sum [j]) ? weight_sum [j] : limited_oport_weight [j];
654
 
655
            end
656
 
657
 
658
         end else begin : eq_or_actual
659
            for (j=0;j<P;j=j+1) begin : outlp1
660
                assign contention[j] = weight_sum [j];
661
            end
662
         end
663
 
664
 
665
 
666
 
667
 
668
         assign contention_all[(i+1)*W-1 : i*W] =  contention[i];
669
 
670
    end
671
    endgenerate
672
 
673
endmodule
674
 
675
 
676
module  wrra_inputport_destports_sum #(
677
    parameter V=4,
678
    parameter P=5,
679
    parameter SW_LOC=0,
680
    parameter SELF_LOOP_EN = "NO"
681
)(
682
    weight_is_valid,
683
    dest_ports,
684
    destports_sum
685
 
686
);
687
 
688
    localparam
689
        P_1 = (SELF_LOOP_EN== "NO")? P - 1 : P,
690
        VP_1 = V * P_1;
691
 
692
    input [V-1 : 0] weight_is_valid;
693
    input [VP_1-1 : 0] dest_ports;
694
    output [P-1 : 0] destports_sum;
695
 
696
    wire [VP_1-1 : 0] dest_ports_masked;
697
 
698
 
699
    wire  [P_1-1    :   0] sum;
700
 
701
    genvar i;
702
    generate
703
    for (i=0;i<V; i=i+1) begin : port_lp
704
        assign  dest_ports_masked [(i+1)*P_1-1  : i*P_1] =  (weight_is_valid[i]) ? dest_ports [(i+1)*P_1-1  : i*P_1] : {P_1{1'b0}};
705
    end
706
 
707
 
708
    custom_or #(
709
        .IN_NUM(V),
710
        .OUT_WIDTH(P_1)
711
    )
712
    custom_or(
713
        .or_in(dest_ports_masked),
714
        .or_out(sum)
715
    );
716
 
717
 
718
    if(SELF_LOOP_EN=="NO") begin : nslp
719
        add_sw_loc_one_hot #(
720
            .P(P),
721
            .SW_LOC(SW_LOC)
722
        )
723
        add_sw_loc
724
        (
725
            .destport_in(sum),
726
            .destport_out(destports_sum)
727
        );
728
    end else begin : slp
729
        assign destports_sum = sum;
730
    end
731
    endgenerate
732
endmodule
733
 
734
/***************
735
*   weights_update
736
*
737
***************/
738
 
739
module weights_update # (
740 56 alirezamon
    parameter NOC_ID=0,
741 48 alirezamon
    parameter ARBITER_TYPE="WRRA",
742
    parameter V=4,
743
    parameter P=5,
744
    parameter Fw = 36,    //flit width;  
745
    parameter WEIGHTw=4,
746
    parameter C = 4,
747
    parameter WRRA_CONFIG_INDEX=0,
748
    parameter TOPOLOGY =    "MESH",//"MESH","TORUS","RING" 
749
    parameter EAw = 3,
750
    parameter DSTPw=P-1,
751
    parameter ADD_PIPREG_AFTER_CROSSBAR=0
752
 
753
 
754
)(
755
    limited_oports_weight,
756
    contention_all,
757
    flit_in_all,
758
    flit_out_all,
759
    flit_out_wr_all,
760
    iport_weight_all,
761
    refresh_w_counter,
762
    clk,
763
    reset
764
);
765
 
766
    function integer log2;
767
    input integer number; begin
768
        log2=(number <=1) ? 1: 0;
769
        while(2**log2<number) begin
770
            log2=log2+1;
771
        end
772
    end
773
    endfunction // log2  
774
 
775
 
776
    localparam
777
        PFw = P * Fw,
778
        W= WEIGHTw,
779
        WP= W * P,
780
        ALL_WEIGHTw=log2(WP);
781
 
782
    localparam  PROPOGATE_LIMITED = (WRRA_CONFIG_INDEX==1 ),
783
                INIT_WEIGHT = 1;
784
 
785
 
786
    input [WP-1 : 0] contention_all;
787
    input [PFw-1 :  0]  flit_in_all;
788
    output[PFw-1 :  0]  flit_out_all;
789
    input [P-1 :  0]  flit_out_wr_all;
790
    input [WP-1: 0] iport_weight_all;
791
    output[WP-1 : 0] limited_oports_weight;
792
    output refresh_w_counter;
793
    input clk,reset;
794
 
795
    //assign refresh_w_counter = 1'b0;   
796
 
797
    genvar i;
798
    generate
799
    //nonlocal port
800
    for (i=1; i<P; i=i+1) begin : non_local_port
801
 
802
        weight_update_per_port #(
803 56 alirezamon
            .NOC_ID(NOC_ID),
804 48 alirezamon
            .V(V),
805
            .C(C),
806
            .P(P),
807
            .Fw(Fw),
808
            .EAw(EAw),
809
            .DSTPw(DSTPw),
810
            .TOPOLOGY(TOPOLOGY),
811
            .WEIGHTw(WEIGHTw),
812
            .WRRA_CONFIG_INDEX(WRRA_CONFIG_INDEX),
813
            .ADD_PIPREG_AFTER_CROSSBAR(ADD_PIPREG_AFTER_CROSSBAR)
814
        )
815
        update_per_port
816
        (
817
            .contention_in(contention_all[(i+1)*W-1  :   i*W]),
818
            .flit_in(flit_in_all[ (i+1)*Fw-1 : i*Fw]),
819
            .flit_out(flit_out_all[(i+1)*Fw-1 : i*Fw]),
820
            .flit_out_wr(flit_out_wr_all[i]),
821
            .clk(clk),
822
            .reset(reset)
823
        );
824
 
825
    end
826
 
827
 
828
    if(PROPOGATE_LIMITED) begin : limited
829
 
830
        wire [ALL_WEIGHTw-1 :   0] iweight_sum;
831
        wire [P-1   :   0] flit_out_is_tail,tail_flit_is_sent;
832
        wire any_tail_is_sent;
833
 
834
        wire capture_o_weights;
835
        reg  [W-1 : 0] oport_weight_counter [P-1 : 0];
836
        reg  [W-1 : 0] limited_oport_weight [P-1 : 0];
837
 
838
        assign tail_flit_is_sent = (flit_out_wr_all & flit_out_is_tail);
839
        assign any_tail_is_sent = | tail_flit_is_sent;
840
        for (i=0; i<P; i=i+1) begin : lp
841
            assign flit_out_is_tail[i] = flit_out_all[(i+1)*Fw-2];
842
 
843 54 alirezamon
                always @ (`pronoc_clk_reset_edge )begin
844
                    if(`pronoc_reset) begin
845 48 alirezamon
                        oport_weight_counter[i]<=INIT_WEIGHT;
846
                    end else begin
847
                        if (any_tail_is_sent && capture_o_weights) oport_weight_counter[i]<= INIT_WEIGHT;
848
                        else if (any_tail_is_sent && tail_flit_is_sent[i] && oport_weight_counter[i] != {W{1'b1}})oport_weight_counter[i]<= oport_weight_counter[i] +1'b1;
849
                    end
850
                end //always
851
 
852 54 alirezamon
                always @ (`pronoc_clk_reset_edge )begin
853
                    if(`pronoc_reset) begin
854 48 alirezamon
                        limited_oport_weight[i]<={W{1'b0}};
855
                    end else begin
856
                        if (any_tail_is_sent && capture_o_weights) limited_oport_weight[i]<= oport_weight_counter[i];  //capture oweight counters                    
857
                    end
858
                end //always
859 54 alirezamon
 
860 48 alirezamon
                assign limited_oports_weight [(i+1)*W-1 : i*W] = limited_oport_weight[i];
861
 
862
 
863
        end
864
        //all input wights summation
865
         accumulator #(
866
            .INw(WP),
867
            .OUTw(ALL_WEIGHTw),
868
            .NUM(P)
869
 
870
         )
871
         accum
872
         (
873
            .in_all(iport_weight_all),
874
            .out(iweight_sum)
875
         );
876
 
877
 
878
 
879
         weight_counter #(
880
            .WEIGHTw(ALL_WEIGHTw)
881
         )
882
         weight_counter
883
         (
884
            .weight_i(iweight_sum),
885
            .reset(reset),
886
            .clk(clk),
887
            .decr(any_tail_is_sent),
888
            .load_i(1'b0),
889
            .out(capture_o_weights )
890
         // .out(refresh_w_counter)
891
         );
892
 
893
 
894
 
895
 
896
 
897
 
898
    end else begin :dontcare
899
        assign limited_oports_weight = {WP{1'bX}};
900
    end
901
 
902
 
903
    /* verilator lint_off WIDTH */
904
    if(ARBITER_TYPE == "WRRA")begin  : wrra
905
    /* verilator lint_on WIDTH */
906
 
907
         assign refresh_w_counter=1'b0;
908
 
909
 
910
    end else begin  :wrra_classic
911
 
912
 
913
 
914
        wire [ALL_WEIGHTw-1 :   0] iweight_sum;
915
        wire any_tail_is_sent;
916
        wire [P-1   :   0] flit_out_is_tail,tail_flit_is_sent;
917
        for (i=0; i<P; i=i+1) begin : lp2
918
            assign flit_out_is_tail[i] = flit_out_all[(i+1)*Fw-2];
919
        end
920
 
921
 
922
        assign tail_flit_is_sent = (flit_out_wr_all & flit_out_is_tail);
923
        assign any_tail_is_sent = | tail_flit_is_sent;
924
 
925
 
926
 
927
         //all input wights summation
928
         accumulator #(
929
            .INw(WP),
930
            .OUTw(ALL_WEIGHTw),
931
            .NUM(P)
932
 
933
         )
934
         accum
935
         (
936
            .in_all(iport_weight_all),
937
            .out(iweight_sum)
938
         );
939
 
940
 
941
 
942
         weight_counter #(
943
            .WEIGHTw(ALL_WEIGHTw)
944
         )
945
         weight_counter
946
         (
947
            .weight_i(iweight_sum-1),
948
            .reset(reset),
949
            .clk(clk),
950
            .decr(any_tail_is_sent),
951
            .load_i(1'b0),
952
            .out(refresh_w_counter)
953
         );
954
 
955
    end
956
 
957
    endgenerate
958
 
959
 
960
 
961
 
962
    // localport 
963
    assign flit_out_all[Fw-1 : 0] = flit_in_all [Fw-1 : 0];
964
 
965
 
966
 
967
endmodule
968
 
969
 
970
 
971
module weight_update_per_port # (
972 56 alirezamon
    parameter NOC_ID=0,
973 48 alirezamon
    parameter V=4,
974
    parameter C=2,
975
    parameter P=5,
976
    parameter Fw =36,
977
    parameter WEIGHTw=4,
978
    parameter EAw=3,
979
    parameter DSTPw=P-1,
980
    parameter TOPOLOGY =    "MESH",//"MESH","TORUS","RING"   
981
    parameter WRRA_CONFIG_INDEX=0,
982
    parameter ADD_PIPREG_AFTER_CROSSBAR=0
983
 
984
)(
985
    contention_in,
986
    flit_in,
987
    flit_out,
988
    flit_out_wr,
989
    clk,
990
    reset
991 56 alirezamon
);
992 48 alirezamon
 
993
    localparam
994 56 alirezamon
        W=WEIGHTw,
995
        WEIGHT_LATCHED = 0;  //(WRRA_CONFIG_INDEX==0 || WRRA_CONFIG_INDEX==1 || WRRA_CONFIG_INDEX==2 || WRRA_CONFIG_INDEX==3 ); //1: no latched  0: latched
996 48 alirezamon
 
997
 
998
    input [W-1 : 0] contention_in;
999
    input [Fw-1 :  0]  flit_in;
1000
    output[Fw-1 :  0]  flit_out;
1001
    input flit_out_wr;
1002
    input clk,reset;
1003
 
1004
 
1005
    wire flit_is_hdr = flit_in[Fw-1];
1006
    reg [W-1 : 0]  contention;
1007
 
1008
    generate
1009
    if(WEIGHT_LATCHED == 1) begin : add_latch
1010
 
1011
        wire update = flit_out_wr & flit_is_hdr;
1012
        wire [W-1 : 0] contention_out;
1013
        output_weight_latch #(
1014
            .WEIGHTw (WEIGHTw)
1015
        )
1016
        out_weight_latch
1017
        (
1018
            .weight_in(contention_in),
1019
            .weight_out(contention_out),
1020
            .clk(clk),
1021
            .reset(reset),
1022
            .update( update )
1023
        );
1024
        always @ (*) begin
1025
           contention= contention_out;
1026
        end
1027
 
1028
     end else  if(ADD_PIPREG_AFTER_CROSSBAR==1)begin : add_reg
1029 54 alirezamon
 
1030
        always @ (`pronoc_clk_reset_edge )begin
1031
            if(`pronoc_reset) begin
1032 48 alirezamon
                contention<={W{1'b0}};
1033
            end else begin
1034
                 contention<= contention_in;
1035
            end
1036 54 alirezamon
        end//always
1037
 
1038
 
1039 48 alirezamon
     end else begin : no_reg
1040
        always @ (*) begin
1041
           contention= contention_in;
1042
        end
1043
    end
1044
    endgenerate
1045
 
1046
    wire [Fw-1 : 0] hdr_flit_new;
1047
 
1048 56 alirezamon
    hdr_flit_weight_update #(
1049
        .NOC_ID(NOC_ID)
1050
    ) updater (
1051 48 alirezamon
        .new_weight(contention),
1052
        .flit_in(flit_in),
1053
        .flit_out(hdr_flit_new)
1054
    );
1055
 
1056
 
1057
   // assign flit_out = (flit_is_hdr) ? {flit_in[Fw-1 : WEIGHT_LSB+WEIGHTw ] ,contention, flit_in[WEIGHT_LSB-1 : 0] }   : flit_in;
1058
    assign flit_out = (flit_is_hdr) ? hdr_flit_new  : flit_in;
1059
 
1060
 
1061
endmodule
1062
 
1063
 
1064
 
1065
 
1066
module output_weight_latch #(
1067
    parameter WEIGHTw =4
1068
)(
1069
    weight_in,
1070
    weight_out,
1071
    clk,
1072
    reset,
1073
    update
1074
);
1075
 
1076 54 alirezamon
    localparam W=WEIGHTw;
1077 48 alirezamon
 
1078 54 alirezamon
     input [W-1 : 0] weight_in;
1079
     output reg [W-1 : 0] weight_out;
1080
     input clk, reset, update;
1081
 
1082
     reg  [W-1 : 0] counter,counter_next,weight_out_next;
1083
 
1084
     wire less =  weight_in <  weight_out;
1085
     wire counter_is_zero = counter == {W{1'b0}};
1086 48 alirezamon
 
1087 54 alirezamon
     always @ (*)begin
1088
        counter_next = counter;
1089
        weight_out_next = weight_out;
1090
        if(update)begin
1091
            if (less ) begin // input weight is smaller than the captured one before
1092
               if(counter_is_zero) begin // 
1093
                   weight_out_next = weight_in;
1094
               end else begin
1095
                 counter_next =   counter - 1'b1;
1096
               end
1097
            end
1098
            else begin
1099
                counter_next = (weight_in[W-1] != 1'b1) ?  {weight_in[W-2:0],1'b0} : {W{1'b1}};
1100
                weight_out_next = weight_in;
1101
            end
1102
        end
1103
     end
1104 48 alirezamon
 
1105
 
1106 54 alirezamon
    always @ (`pronoc_clk_reset_edge )begin
1107
        if(`pronoc_reset) begin
1108
            counter = {WEIGHTw{1'b0}};
1109
            weight_out = {WEIGHTw{1'b0}};
1110
        end else begin
1111
            counter = counter_next;
1112
            weight_out = weight_out_next;
1113
        end
1114
    end//always
1115 48 alirezamon
 
1116
endmodule
1117
 
1118
 
1119
 
1120
 
1121
 

powered by: WebSVN 2.1.0

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