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 56

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

powered by: WebSVN 2.1.0

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