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

powered by: WebSVN 2.1.0

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