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

powered by: WebSVN 2.1.0

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