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/] [output_ports.sv] - Blame information for rev 54

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

Line No. Rev Author Line
1 54 alirezamon
`include "pronoc_def.v"
2 48 alirezamon
/**********************************************************************
3
**      File:  output_ports.sv
4
**
5
**      Copyright (C) 2014-2017  Alireza Monemi
6
**
7
**      This file is part of ProNoC
8
**
9
**      ProNoC ( stands for Prototype Network-on-chip)  is free software:
10
**      you can redistribute it and/or modify it under the terms of the GNU
11
**      Lesser General Public License as published by the Free Software Foundation,
12
**      either version 2 of the License, or (at your option) any later version.
13
**
14
**      ProNoC is distributed in the hope that it will be useful, but WITHOUT
15
**      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
**      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
17
**      Public License for more details.
18
**
19
**      You should have received a copy of the GNU Lesser General Public
20
**      License along with ProNoC. If not, see .
21
**
22
**
23
**      Description:
24
**      output_ports module: contain output VC (OVC) status registers and credit counters,
25
**
26
**************************************************************/
27
 
28
 
29
module output_ports
30
    import pronoc_pkg::*;
31
 #(
32
    parameter P = 5 // router port num
33
)(
34
    vsa_ovc_allocated_all,
35
    flit_is_tail_all,
36 54 alirezamon
 
37 48 alirezamon
    dest_port_all,
38
    nonspec_granted_dest_port_all,
39
    credit_in_all,
40
    nonspec_first_arbiter_granted_ivc_all,
41
    ivc_num_getting_sw_grant,
42
    ovc_avalable_all,
43
    assigned_ovc_not_full_all,
44
    port_pre_sel,
45
    congestion_in_all,
46
    granted_dst_is_from_a_single_flit_pck,
47
    granted_ovc_num_all,
48
    reset,
49
    clk,
50
    any_ovc_granted_in_outport_all,
51
    vsa_credit_decreased_all,
52
    vsa_ovc_released_all,
53
    crossbar_flit_out_wr_all,
54
    oport_info,
55 54 alirezamon
    ovc_info,
56
    ivc_info,
57 48 alirezamon
    vsa_ctrl_in,
58
    ssa_ctrl_in,
59
    smart_ctrl_in,
60
    credit_init_val_in
61
);
62
 
63
 
64
 
65
 
66
    function integer log2;
67
      input integer number; begin
68
         log2=(number <=1) ? 1: 0;
69
         while(2**log2
70
            log2=log2+1;
71
         end
72
      end
73
    endfunction // log2
74
 
75
    localparam      PV      =    V        *    P,
76
                    VV      =   V       *  V,
77
                    PVV     =    PV        *  V,
78
                    P_1     =   ( SELF_LOOP_EN=="NO")?  P-1 : P,
79
                    VP_1    =    V        *     P_1,
80
                    PP_1    =    P_1    *    P,
81
                    PVP_1    =    PV        *    P_1;
82
 
83
 
84
    localparam  NORTH  =       2,
85
                SOUTH  =       4;
86
    localparam [V-1     :   0] ADAPTIVE_VC_MASK = ~ ESCAP_VC_MASK;
87
    localparam  CONG_ALw=   CONGw * P;   //  congestion width per router;
88
 
89
    input  [PV-1       :    0] vsa_ovc_allocated_all;
90 54 alirezamon
    input  [PV-1       :    0] flit_is_tail_all;
91 48 alirezamon
    input  [PVP_1-1    :    0] dest_port_all;
92
    input  [PP_1-1     :    0] nonspec_granted_dest_port_all;
93
    input  [PV-1       :    0] credit_in_all;
94
    input  [PV-1       :    0] nonspec_first_arbiter_granted_ivc_all;
95
    input  [PV-1       :    0] ivc_num_getting_sw_grant;
96
    output [PV-1       :    0] ovc_avalable_all;
97
    output [PV-1       :    0] assigned_ovc_not_full_all;
98
    input                      reset,clk;
99
    output [PPSw-1     :    0] port_pre_sel;
100
    input  [CONG_ALw-1 :    0] congestion_in_all;
101
    input  [PVV-1 : 0] granted_ovc_num_all;
102
    input  [P-1 : 0] granted_dst_is_from_a_single_flit_pck;
103
    input  [P-1 : 0] crossbar_flit_out_wr_all;
104
    input  [P-1 : 0] any_ovc_granted_in_outport_all;
105
    output [PV-1    :    0]  vsa_ovc_released_all;
106
    output [PV-1    :    0]  vsa_credit_decreased_all;
107
    output oport_info_t oport_info [P-1:0];
108 54 alirezamon
    output ovc_info_t   ovc_info   [P-1 : 0][V-1 : 0];
109
    input   ivc_info_t ivc_info [P-1 : 0][V-1 : 0];
110
    input   vsa_ctrl_t vsa_ctrl_in [P-1: 0];
111
    input   ssa_ctrl_t ssa_ctrl_in [P-1: 0];
112 48 alirezamon
    input   smart_ctrl_t  smart_ctrl_in [P-1: 0];
113
    input   [CRDTw-1 : 0 ] credit_init_val_in  [P-1 : 0][V-1 : 0];
114
 
115 54 alirezamon
    logic  [PV-1    :    0]    ovc_status;
116
    logic  [PV-1    :    0]    ovc_status_next;
117 48 alirezamon
    wire   [PV-1    :    0]    assigned_ovc_is_full_all;
118 54 alirezamon
    wire   [VP_1-1  :    0]    credit_decreased        [P-1        :    0];
119
    wire   [P_1-1   :    0]    credit_decreased_gen    [PV-1        :    0];
120 48 alirezamon
 
121
    wire   [PV-1    :    0]  credit_increased_all;
122
    wire   [VP_1-1    :    0]    ovc_released            [P-1        :    0];
123
    wire   [P_1-1    :    0]    ovc_released_gen        [PV-1        :    0];
124
 
125
    wire   [VP_1-1    :   0]  credit_in_perport        [P-1        :    0];
126
    wire   [VP_1-1    :    0]  full_perport              [P-1        :    0];
127
    wire   [VP_1-1    :    0]  nearly_full_perport    [P-1        :    0];
128
 
129
    wire   [PV-1    :    0]    full_all,nearly_full_all, empty_all;
130
    wire   [PV-1    :    0]    full_all_next,nearly_full_all_next,empty_all_next;
131
 
132
 
133
    wire [PV-1  :   0] credit_decreased_all;
134
    wire [PV-1  :   0] ovc_released_all;
135
    wire [PV-1  :   0] ovc_allocated_all;
136
    wire [CREDITw-1   :    0] credit_counter [PV-1  :   0];
137
 
138 54 alirezamon
    wire  [PVV-1      :    0] assigned_ovc_num_all;
139
    wire  [PV-1       :    0] ovc_is_assigned_all;
140 48 alirezamon
 
141
 
142 54 alirezamon
    pronoc_register #(.W(PV)) reg_1 ( .in(full_all_next), .reset(reset), .clk(clk), .out(full_all));
143
    pronoc_register #(.W(PV)) reg_2 ( .in(nearly_full_all_next), .reset(reset), .clk(clk), .out(nearly_full_all));
144
    pronoc_register #(.W(PV)) reg_3 ( .in(empty_all_next), .reset(reset), .clk(clk), .out(empty_all));
145 48 alirezamon
 
146
 
147 54 alirezamon
 
148 48 alirezamon
    integer k;
149
    genvar i,j;
150
    generate
151
        /* verilator lint_off WIDTH */
152
        if(VC_REALLOCATION_TYPE=="ATOMIC") begin :atomic
153
        /* verilator lint_on WIDTH */
154
            // in atomic architecture an OVC is available if its not allocated and its empty
155
            assign ovc_avalable_all                 = ~ovc_status & empty_all;
156
 
157
        end else begin :nonatomic //NONATOMIC
158
            /* verilator lint_off WIDTH */
159
            if(ROUTE_TYPE  == "FULL_ADAPTIVE") begin :full_adpt
160
            /* verilator lint_on WIDTH */
161
 
162
                reg [PV-1       :   0] full_adaptive_ovc_mask,full_adaptive_ovc_mask_next;
163
 
164
                always @(*) begin
165
                    for(k=0;    k
166
                     //in full adaptive routing, adaptive VCs located in y axies can not be reallocated non-atomicly
167
                        if( AVC_ATOMIC_EN== 0) begin :avc_atomic
168
                            if((((k/V) == NORTH ) || ((k/V) == SOUTH )) && (  ADAPTIVE_VC_MASK[k%V]))
169
                                    full_adaptive_ovc_mask_next[k]  =   empty_all_next[k];
170
                            else    full_adaptive_ovc_mask_next[k] = (OVC_ALLOC_MODE)? ~full_all_next[k] : ~nearly_full_all_next[k];
171
                        end else begin :avc_nonatomic
172
                            if(  ADAPTIVE_VC_MASK[k%V])
173
                                    full_adaptive_ovc_mask_next[k]  =   empty_all_next[k];
174
                            else    full_adaptive_ovc_mask_next[k] = (OVC_ALLOC_MODE)? ~full_all_next[k] :~nearly_full_all_next[k];
175
 
176
                        end
177
                     end // for
178
                end//always
179
 
180 54 alirezamon
                pronoc_register #(.W(PV)) reg2 ( .in(full_adaptive_ovc_mask_next), .reset(reset), .clk(clk), .out(full_adaptive_ovc_mask));
181 48 alirezamon
 
182
                assign ovc_avalable_all              = ~ovc_status & full_adaptive_ovc_mask;
183
 
184
            end else begin : par_adpt//par adaptive
185
                assign ovc_avalable_all = (OVC_ALLOC_MODE)? ~(ovc_status | full_all) :  ~(ovc_status | nearly_full_all);
186
 
187
           end
188
        end //NONATOMIC
189
    endgenerate
190
 
191
 
192
    assign credit_increased_all         = credit_in_all;
193
    assign assigned_ovc_not_full_all    =    ~ assigned_ovc_is_full_all;
194
 
195
  //  wire [PV-1 : 0] non_smart_ovc_allocated_all =    ssa_ovc_allocated_all| vsa_ovc_allocated_all;
196
    wire [PV-1 : 0] non_smart_ovc_allocated_all;
197
    generate
198
    for(i=0;i
199
 
200
        assign credit_decreased_all [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].buff_space_decreased |   ssa_ctrl_in[i].buff_space_decreased | smart_ctrl_in[i].buff_space_decreased;
201
        assign ovc_released_all         [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_released  | ssa_ctrl_in[i].ovc_is_released  | smart_ctrl_in[i].ovc_is_released;
202
        assign ovc_allocated_all        [(i+1)*V-1 : i*V] = vsa_ctrl_in[i].ovc_is_allocated | ssa_ctrl_in[i].ovc_is_allocated | smart_ctrl_in[i].ovc_is_allocated;
203
        //assign non_smart_ovc_allocated_all [(i+1)*V-1 : i*V] = ssa_ctrl_in[i].ovc_is_allocated | vsa_ctrl_in[i].ovc_is_allocated;
204
 
205
        assign non_smart_ovc_allocated_all [(i+1)*V-1 : i*V] =  vsa_ctrl_in[i].ovc_is_allocated;
206
 
207
 
208
        assign oport_info[i].non_smart_ovc_is_allocated =  non_smart_ovc_allocated_all [(i+1)*V-1        :i*V];
209
        assign oport_info[i].any_ovc_granted =  any_ovc_granted_in_outport_all [i];
210
 
211
 
212
        oport_ovc_sig_gen #(
213
            .V    (V), // vc_num_per_port
214
            .P    (P), // router port num
215
            .SELF_LOOP_EN(SELF_LOOP_EN)
216
        )the_oport_ovc_sig_gen
217
        (
218
            .flit_is_tail                    (flit_is_tail_all                        [(i+1)*V-1        :i*V]),
219
            .assigned_ovc_num                (assigned_ovc_num_all                [(i+1)*VV-1        :i*VV]),
220
            .ovc_is_assigned                 (ovc_is_assigned_all                    [(i+1)*V-1        :i*V]),
221
            .granted_dest_port               (nonspec_granted_dest_port_all                [(i+1)*P_1-1    :i*P_1]),
222
            .first_arbiter_granted_ivc       (nonspec_first_arbiter_granted_ivc_all    [(i+1)*V-1        :i*V]),
223
            .credit_decreased                (credit_decreased                        [i]),
224
            .ovc_released                    (ovc_released                            [i])
225
 
226
        );
227
 
228
        for(j=0; j
229
                assign  ovc_info[i][j].avalable= ovc_avalable_all [i*V+j];
230
                assign  ovc_info[i][j].status =ovc_status [i*V+j]; //1 : is allocated 0 : not_allocated
231
                assign  ovc_info[i][j].credit = credit_counter[i*V+j];//available credit in OVC
232
                assign  ovc_info[i][j].full =full_all[i*V+j];
233
                assign  ovc_info[i][j].nearly_full=nearly_full_all[i*V+j];
234
                assign  ovc_info[i][j].empty=empty_all[i*V+j];
235
        end
236
 
237
    end//for
238
 
239
 
240
    for(i=0;i< PV;i=i+1) begin :total_vc_loop2
241
        for(j=0;j
242
                if ( SELF_LOOP_EN=="NO") begin : nslp
243
                    if((i/V)
244
                        assign ovc_released_gen        [i][j-1]    = ovc_released[j][i];
245
                        assign credit_decreased_gen[i][j-1]    = credit_decreased [j][i];
246
                    end else if((i/V)>j) begin: hh
247
                        assign ovc_released_gen        [i][j]    = ovc_released[j][i-V];
248
                        assign credit_decreased_gen[i][j]    = credit_decreased[j][i-V];
249
                    end
250
                end else begin :slp
251
                        assign ovc_released_gen        [i][j]    = ovc_released[j][i];
252
                    assign credit_decreased_gen[i][j]    = credit_decreased [j][i];
253
                end
254
        end//j
255
        assign vsa_ovc_released_all      [i] = |ovc_released_gen[i];
256
        assign vsa_credit_decreased_all [i] = (|credit_decreased_gen[i])|vsa_ovc_allocated_all[i];
257
    end//i
258
 
259
 
260
 
261
    if ( SELF_LOOP_EN=="NO") begin : nslp
262
            //remove source port from the list
263
            for(i=0;i< P;i=i+1) begin :port_loop
264
                if(i==0)        begin :i0
265
                    assign credit_in_perport    [i]=credit_in_all     [PV-1                :    V];
266
                    assign full_perport             [i]=full_all              [PV-1                :    V];
267
                    assign nearly_full_perport    [i]=nearly_full_all    [PV-1                :    V];
268
                end else if(i==(P-1)) begin :ip_1
269
                    assign credit_in_perport    [i]=credit_in_all     [PV-V-1            :    0];
270
                    assign full_perport             [i]=full_all              [PV-V-1            :    0];
271
                    assign nearly_full_perport    [i]=nearly_full_all    [PV-V-1            :    0];
272
                end else begin : els
273
                    assign credit_in_perport    [i]={credit_in_all     [PV-1    :    (i+1)*V],credit_in_all     [(i*V)-1    :    0]};
274
                    assign full_perport             [i]={full_all          [PV-1    :    (i+1)*V],full_all         [(i*V)-1    :    0]};
275
                    assign nearly_full_perport    [i]={nearly_full_all [PV-1    :    (i+1)*V],nearly_full_all[(i*V)-1    :    0]};
276
                end
277
            end//for
278
    end else begin:  slp
279
        for(i=0;i< P;i=i+1) begin :port_loop
280
                assign credit_in_perport    [i]=credit_in_all;
281
                    assign full_perport         [i]=full_all;
282
                    assign nearly_full_perport  [i]=nearly_full_all;
283
            end
284
    end
285
 
286
 
287
    for(i=0; i
288
 
289 54 alirezamon
        assign assigned_ovc_num_all[(i+1)*V-1 : i*V] = ivc_info[i/V][i%V].assigned_ovc_num;
290
        assign ovc_is_assigned_all[i]=ivc_info[i/V][i%V].ovc_is_assigned;
291
 
292
 
293
 
294 48 alirezamon
        credit_monitor_per_ovc  #(
295
                        .SW_LOC(i/V)
296
                )
297
                credit_monitor
298
                (
299
                        .credit_init_val_i(credit_init_val_in[i/V][i%V]),
300
                        .credit_counter_o (credit_counter[i]),
301
                        .credit_increased (credit_increased_all[i]),
302
                        .credit_decreased(credit_decreased_all[i]),
303
                        .empty_all_next(empty_all_next[i]),
304
                        .full_all_next(full_all_next[i]),
305
                        .nearly_full_all_next(nearly_full_all_next[i]),
306
                        .reset(reset),
307
                        .clk(clk)
308
                );
309
 
310
 
311
 
312 54 alirezamon
        full_ovc_predictor #(
313 48 alirezamon
                .OVC_ALLOC_MODE(OVC_ALLOC_MODE),
314
                .PCK_TYPE(PCK_TYPE),
315
                .V (V), // vc_num_per_port
316
            .P (P), // router port num
317
            .SELF_LOOP_EN (SELF_LOOP_EN)
318
 
319
        )
320
        sw_mask
321
        (
322
                .granted_ovc_num(granted_ovc_num_all[(i+1)*V-1        :i*V]),
323
                .ovc_is_assigned(ovc_is_assigned_all[i]),
324
                .assigned_ovc_num (assigned_ovc_num_all[(i+1)*V-1        :i*V]),
325
            .dest_port (dest_port_all  [(i+1)*P_1-1    :i*P_1]),
326
            .full  (full_perport [i/V]),
327
            .credit_increased (credit_in_perport [i/V]),
328
            .nearly_full (nearly_full_perport    [i/V]),
329
            .ivc_getting_sw_grant  (ivc_num_getting_sw_grant[i]),
330
            .assigned_ovc_is_full  (assigned_ovc_is_full_all[i]),
331
            .clk (clk),
332
            .reset  (reset)
333
        );
334
    end//for
335
 
336 54 alirezamon
 
337
 
338
 
339
 
340
 
341 48 alirezamon
    for(i=0;    i
342 54 alirezamon
        always @ (*)begin
343
            ovc_status_next[i]   =  ovc_status[i];
344
            /* verilator lint_off WIDTH */
345
                if(PCK_TYPE == "SINGLE_FLIT")  ovc_status_next[i]=1'b0; // donot change VC status for single flit packet
346
                /* verilator lint_on WIDTH */
347
                else begin
348
                if(ovc_released_all[i])        ovc_status_next[i] =1'b0;
349
                //if(ovc_allocated_all[i] & ~granted_dst_is_from_a_single_flit_pck[i/V])    ovc_status_next[i]=1'b1; // donot change VC status for single flit packet
350
                if((vsa_ctrl_in[i/V].ovc_is_allocated[i%V] & ~granted_dst_is_from_a_single_flit_pck[i/V]) |
351 48 alirezamon
                           (ssa_ctrl_in[i/V].ovc_is_allocated[i%V] & ~ssa_ctrl_in[i/V].ovc_single_flit_pck[i%V])|
352
                           (smart_ctrl_in[i/V].ovc_is_allocated[i%V] & ~smart_ctrl_in[i/V].ovc_single_flit_pck[i%V]))
353 54 alirezamon
                           ovc_status_next[i]=1'b1; // donot change VC status for single flit packet
354 48 alirezamon
 
355 54 alirezamon
                end
356 48 alirezamon
        end//always
357
    end//for
358
    endgenerate
359
 
360 54 alirezamon
    pronoc_register #(.W(PV)) reg2 (.in(ovc_status_next ), .out(ovc_status), .reset(reset), .clk(clk));
361 48 alirezamon
 
362
    port_pre_sel_gen #(
363
        .PPSw(PPSw),
364
        .P(P),
365
        .V(V),
366
        .B(B),
367
        .CONGESTION_INDEX(CONGESTION_INDEX),
368
        .CONGw(CONGw),
369
        .ROUTE_TYPE(ROUTE_TYPE),
370
        .ESCAP_VC_MASK(ESCAP_VC_MASK)
371
 
372
    )
373
     port_pre_sel_top
374
    (
375
        .port_pre_sel(port_pre_sel),
376
        .ovc_status(ovc_status),
377
        .ovc_avalable_all(ovc_avalable_all),
378
        .credit_decreased_all(credit_decreased_all),
379
        .credit_increased_all(credit_increased_all),
380
        .congestion_in_all(congestion_in_all),
381
        .reset(reset),
382
        .clk(clk)
383
 
384
    );
385
 
386
 
387
    //synthesis translate_off
388
    //synopsys  translate_off
389
generate
390
if(DEBUG_EN) begin: debug
391
 
392 54 alirezamon
 
393 48 alirezamon
    always @ (posedge clk )begin
394
        for(k=0;    k
395
            if(empty_all[k] & credit_increased_all[k]) begin
396
                $display("%t: ERROR: unexpected credit recived for empty ovc[%d]: %m",$time,k);
397
                                $finish;
398
                        end
399
            if(full_all[k] & credit_decreased_all[k]) begin
400
                $display("%t: ERROR: Attempt to send flit to full ovc[%d]: %m",$time,k);
401
                                $finish;
402
                        end
403
            if(ovc_released_all[k] & ovc_allocated_all[k]) begin
404
                $display("%t: ERROR: simultaneous allocation and release for an OVC[%d]: %m",$time,k);
405
                                $finish;
406
                        end
407
            if(ovc_released_all[k]==1'b1 && ovc_status[k]==1'b0) begin
408
                $display("%t: ERROR: Attempt to release an unallocated OVC[%d]: %m",$time,k);
409
                                $finish;
410
                        end
411
                        if(ovc_allocated_all[k] & ovc_status[k]) begin
412
                $display("%t: ERROR: Attempt to allocate an allocated OVC[%d]: %m",$time,k);
413
                                $finish;
414
                        end
415
        end//for
416 54 alirezamon
 
417 48 alirezamon
    end//always
418
 
419
 
420 54 alirezamon
    /* verilator lint_off WIDTH */
421
    if(CAST_TYPE== "UNICAST") begin : unicast
422
    /* verilator lint_on WIDTH */
423
 
424
            localparam NUM_WIDTH = log2(PV+1);
425
            wire [NUM_WIDTH-1        :    0] num1,num2;
426 48 alirezamon
 
427 54 alirezamon
            accumulator #(
428
                .INw(PV),
429
                .OUTw(NUM_WIDTH),
430
                .NUM(PV)
431
                )
432
                cnt1
433
                (
434
                        .in_all(ovc_status),
435
                .out(num1)
436
            );
437
 
438
            accumulator #(
439
                .INw(PV),
440
                .OUTw(NUM_WIDTH),
441
                .NUM(PV)
442
            )
443
            cnt2
444
            (
445
                .in_all(ovc_is_assigned_all),
446
                .out(num2)
447
            );
448
 
449
 
450
 
451
 
452 48 alirezamon
    always @(posedge clk) begin
453
        if(num1    != num2 )begin
454
                $display("%t: ERROR: number of assigned IVC %d mismatch the number of occupied OVC %d: %m",$time,num1,num2);
455
                $finish;
456
        end
457
    end
458 54 alirezamon
    end //unicast
459 48 alirezamon
    check_ovc #(
460
        .V(V) , // vc_num_per_port
461
        .P(P), // router port num
462
        .SELF_LOOP_EN(SELF_LOOP_EN)
463
 
464
    )test
465
    (
466
    .ovc_status(ovc_status),
467
    .assigned_ovc_num_all(assigned_ovc_num_all),
468
    .ovc_is_assigned_all(ovc_is_assigned_all),
469
    .dest_port_all(dest_port_all),
470
    .clk(clk),
471
    .reset(reset)
472
    );
473
 
474
end// DEBUG
475
endgenerate
476
    //synopsys  translate_on
477
    //synthesis translate_on
478
endmodule
479
 
480
 
481
/*********************
482
 *      credit_monitor_per_ovc
483
 ********************/
484
 
485
module   credit_monitor_per_ovc
486
        import pronoc_pkg::*;
487
        #(
488
        parameter SW_LOC=0
489
        )(
490
                credit_init_val_i,
491
                credit_increased,
492
                credit_decreased,
493
                credit_counter_o,
494
                empty_all_next,
495
                full_all_next,
496
                nearly_full_all_next,
497
                reset,
498
                clk
499
        );
500
 
501
 
502
        localparam
503
        PORT_B = port_buffer_size(SW_LOC),
504
        DEPTHw = log2(PORT_B+1);
505
 
506
        localparam [DEPTHw-1    :    0] Bint    =    PORT_B [DEPTHw-1    :    0];
507
 
508
        input  [CRDTw-1 : 0] credit_init_val_i;
509
        input   credit_increased;
510
        input   credit_decreased;
511
        output  reg [CREDITw-1   :    0]    credit_counter_o ;
512
        output empty_all_next;
513
        output full_all_next;
514
        output nearly_full_all_next;
515
        input reset,clk;
516
 
517
        reg    [DEPTHw-1    :    0]    credit_counter_next;
518
        reg    [DEPTHw-1    :    0]    credit_counter;
519
 
520
        always @(*) begin
521
                credit_counter_next    =    credit_counter;
522
                if(credit_increased    &   ~credit_decreased) begin
523
                        credit_counter_next =   credit_counter+1'b1;
524
                end else if (~credit_increased  &  credit_decreased)begin
525
                        credit_counter_next =  credit_counter-1'b1;
526
                end
527
                credit_counter_o = {CREDITw{1'b0}};
528
                credit_counter_o  [DEPTHw-1 :  0] = credit_counter;
529
        end
530
 
531
 
532
        assign  empty_all_next       =  (credit_counter_next  == Bint);
533
        assign  full_all_next        =  (credit_counter_next  == {DEPTHw{1'b0}});
534
        assign  nearly_full_all_next =  (credit_counter_next  <= 1);
535
 
536 54 alirezamon
 
537
        pronoc_register_reset_init #(
538
                        .W(DEPTHw)
539
                )reg1(
540
                        .in(credit_counter_next),
541
                        .reset(reset),
542
                        .clk(clk),
543
                        .out(credit_counter),
544
                        .reset_to(credit_init_val_i [DEPTHw-1    :    0]) // Bint;
545
                );
546
 
547
 
548 48 alirezamon
endmodule
549
 
550
 
551
/************************************
552
        oport_ovc_sig_gen
553
*************************************/
554
module oport_ovc_sig_gen #(
555
    parameter V = 4, // vc_num_per_port
556
    parameter P = 5, // router port num
557
    parameter SELF_LOOP_EN = "NO"
558
)(
559
    flit_is_tail,
560
    assigned_ovc_num,
561
    ovc_is_assigned,
562
    granted_dest_port,
563
    first_arbiter_granted_ivc,
564
    credit_decreased,
565
    ovc_released
566
 
567
);
568
 
569
    localparam      VV      =    V        *    V,
570
                    P_1     =    ( SELF_LOOP_EN=="NO")?  P-1 : P,
571
                    VP_1    =    V        *     P_1;
572
 
573
 
574
    input   [V-1         :    0]    flit_is_tail;
575
    input   [VV-1        :    0]    assigned_ovc_num;
576
    input   [V-1         :    0]    ovc_is_assigned;
577
    input   [P_1-1       :    0]    granted_dest_port;
578
    input   [V-1         :    0]    first_arbiter_granted_ivc;
579
    output  [VP_1-1      :    0]    credit_decreased;
580
    output  [VP_1-1      :    0]    ovc_released;
581
 
582
 
583
 
584
    wire [V-1      :    0] muxout1;
585
    wire                   muxout2;
586
 
587
    wire   [VV-1   :    0] assigned_ovc_num_masked;
588
    genvar i;
589
    generate
590
        for (i=0;i
591
            assign    assigned_ovc_num_masked[(i+1)*V-1    :    i*V] = ovc_is_assigned[i]? assigned_ovc_num [(i+1)*V-1    :    i*V] : {V{1'b0}};
592
        end
593
    endgenerate
594
 
595
 
596
 
597
    // assigned ovc mux
598
    onehot_mux_1D #(
599
        .W  (V),
600
        .N  (V)
601
    )assigned_ovc_mux
602
    (
603
        .in  (assigned_ovc_num_masked),
604
        .out (muxout1),
605
        .sel (first_arbiter_granted_ivc)
606
    );
607
 
608
    // tail mux
609
        onehot_mux_1D #(
610
        .W  (1),
611
        .N  (V)
612
    )tail_mux
613
    (
614
        .in        (flit_is_tail),
615
        .out       (muxout2),
616
        .sel       (first_arbiter_granted_ivc)
617
    );
618
 
619
 
620
    one_hot_demux    #(
621
        .IN_WIDTH    (V),
622
        .SEL_WIDTH    (P_1)
623
 
624
    ) demux
625
    (
626
        .demux_sel    (granted_dest_port),//selectore
627
        .demux_in    (muxout1),//repeated
628
        .demux_out    (credit_decreased)
629
    );
630
 
631
    assign ovc_released = (muxout2)? credit_decreased : {VP_1{1'b0}};
632
 
633
 
634
endmodule
635
 
636
 
637
/**********************************
638
 
639 54 alirezamon
    full_ovc_predictor
640 48 alirezamon
 
641
*********************************/
642
 
643 54 alirezamon
module full_ovc_predictor #(
644 48 alirezamon
    parameter PCK_TYPE = "MULTI_FLIT",
645
        parameter V = 4, // vc_num_per_port
646
    parameter P = 5, // router port num
647
    parameter OVC_ALLOC_MODE=1'b0,
648
    parameter SELF_LOOP_EN = "NO"
649
 
650
)(
651
        granted_ovc_num,
652
        ovc_is_assigned,
653
        assigned_ovc_num,
654
    dest_port,
655
    full,
656
    credit_increased,
657
    nearly_full,
658
    ivc_getting_sw_grant,
659
    assigned_ovc_is_full,
660
    clk,
661
    reset
662
);
663
    localparam      P_1   =  ( SELF_LOOP_EN=="NO")?  P-1 : P,
664
                    VP_1    =    V        *     P_1;
665
    input       clk,reset;
666
    input       ovc_is_assigned;
667
    input       [V-1           :    0]  assigned_ovc_num,granted_ovc_num;
668
    input       [P_1-1         :    0]  dest_port;
669
    input       [VP_1-1        :    0]  full;
670
    input       [VP_1-1        :    0]  credit_increased;
671
    input       [VP_1-1        :    0]  nearly_full;
672
    input       ivc_getting_sw_grant;
673
    output      assigned_ovc_is_full;
674
 
675
 
676
    wire        [VP_1-1        :    0]    full_muxin1,nearly_full_muxin1;
677
    wire         [V-1            :    0]    full_muxout1,nearly_full_muxout1;
678
    wire                                full_muxout2,nearly_full_muxout2;
679 54 alirezamon
    wire   full_reg1,full_reg2;
680 48 alirezamon
    wire   full_reg1_next,full_reg2_next;
681
 
682
 
683
    assign full_muxin1             = full & (~credit_increased);
684
    assign nearly_full_muxin1     = nearly_full & (~credit_increased);
685
 
686
 
687
    // destport mux
688
    onehot_mux_1D #(
689
        .W  (V),
690
        .N  (P_1)
691
    )full_mux1
692
    (
693
        .in     (full_muxin1),
694
        .out    (full_muxout1),
695
        .sel    (dest_port)
696
    );
697
 
698
    onehot_mux_1D #(
699
        .W  (V),
700
        .N  (P_1)
701
    )nearly_full_mux1
702
    (
703
        .in        (nearly_full_muxin1),
704
        .out       (nearly_full_muxout1),
705
        .sel       (dest_port)
706
    );
707
 
708
    // assigned ovc mux
709
    onehot_mux_1D #(
710
        .W (1),
711
        .N (V)
712
    )full_mux2
713
    (
714
        .in  (full_muxout1),
715
        .out (full_muxout2),
716
        .sel (assigned_ovc_num)
717
    );
718
 
719
   wire [V-1 : 0]  nearlyfull_sel = (ovc_is_assigned | ~OVC_ALLOC_MODE)? assigned_ovc_num : granted_ovc_num;
720
 
721
    onehot_mux_1D #(
722
        .W  (1),
723
        .N  (V)
724
    )nearlfull_mux2
725
    (
726
        .in  (nearly_full_muxout1),
727
        .out (nearly_full_muxout2),
728
        .sel (nearlyfull_sel)
729
    );
730
 
731
   assign full_reg1_next    =    full_muxout2;
732
   assign full_reg2_next    =    nearly_full_muxout2 & ivc_getting_sw_grant;
733 54 alirezamon
   assign assigned_ovc_is_full    = (PCK_TYPE == "MULTI_FLIT")? full_reg1 | full_reg2: 1'b0;
734 48 alirezamon
 
735 54 alirezamon
   pronoc_register #(.W(1)) reg1 (.in(full_reg1_next ), .out(full_reg1), .reset(reset), .clk(clk));
736
   pronoc_register #(.W(1)) reg2 (.in(full_reg2_next ), .out(full_reg2), .reset(reset), .clk(clk));
737
 
738
 
739
 
740 48 alirezamon
 
741
endmodule
742
 
743
 
744
//synthesis translate_off
745
//synopsys  translate_off
746
module check_ovc #(
747
    parameter V = 4, // vc_num_per_port
748
    parameter P    = 5, // router port num
749
    parameter SELF_LOOP_EN="NO"
750
 
751
)(
752
    ovc_status,
753
    assigned_ovc_num_all,
754
    ovc_is_assigned_all,
755
    dest_port_all,
756
    clk,
757
    reset
758
);
759
 
760
    localparam      PV        =    V        *    P,
761
                    PVV     =    PV        *  V,
762
                    P_1        =   ( SELF_LOOP_EN=="NO")?  P-1 : P,
763
                    PVP_1    =    PV        *    P_1;
764
 
765
 
766
    input    [PV-1        :    0]    ovc_status;
767
    input [PVV-1    :    0]    assigned_ovc_num_all;
768
    input [PV-1        :    0]    ovc_is_assigned_all;
769
    input    [PVP_1-1    :    0]    dest_port_all;
770
    input clk,reset;
771
 
772
    wire [V-1        :    0] assigned_ovc_num    [PV-1        :    0];
773
    wire [P_1-1        :    0]    destport_sel        [PV-1        :    0];
774
    wire [P-1        :    0]    destport_num        [PV-1        :    0];
775
 
776
    wire [PV-1        :    0] ovc_num                [PV-1        :    0];
777
    genvar i;
778
    generate
779
    for(i=0; i
780
        assign assigned_ovc_num [i]= (ovc_is_assigned_all[i])? assigned_ovc_num_all[(i+1)*V-1    :    i*V]: 0;
781
        assign destport_sel        [i]= dest_port_all[(i+1)*P_1-1    :    i*P_1];
782
 
783
        if(SELF_LOOP_EN=="NO") begin : nslp
784
                add_sw_loc_one_hot #(
785
                    .P(P),
786
                    .SW_LOC(i/V)
787
                )
788
                add_sw_loc
789
                (
790
                    .destport_in(destport_sel[i]),
791
                    .destport_out(destport_num[i])
792
                );
793
        end else begin :slp
794
                assign destport_num[i] = destport_sel[i];
795
        end
796
 
797
 
798
 
799
 
800
        one_hot_demux    #(
801
            .IN_WIDTH    (V),
802
            .SEL_WIDTH    (P)
803
 
804
        ) demux
805
        (
806
            .demux_sel    (destport_num[i]),//selectore
807
            .demux_in    (assigned_ovc_num[i]),//repeated
808
            .demux_out    (ovc_num[i])
809
        );
810
    always @(posedge clk)begin
811
        if(ovc_status >0 && ovc_num[i] >0 && (ovc_num[i] & ovc_status)==0) $display ("%t    :Error: OVC status%d missmatch:%b & %b, %m  ",$time,i,ovc_num[i] , ovc_status);
812
    end
813
 
814
 
815
    end//for
816
    endgenerate
817
 
818
 
819
 
820
 
821
endmodule
822
//synopsys  translate_on
823
//synthesis translate_on
824
 

powered by: WebSVN 2.1.0

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