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 55

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

powered by: WebSVN 2.1.0

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