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_modelsim/] [multicast_injector.sv] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 56 alirezamon
`include "pronoc_def.v"
2
 
3 54 alirezamon
/****************************
4
 * This module can inject and eject packets from the NoC.
5
 * It can be used in simulation for injecting real application traces to the NoC
6
 * *************************/
7
 
8
 
9 56 alirezamon
module multicast_injector #(
10
        parameter NOC_ID=0
11
)(
12
        //general
13
        current_e_addr,
14
        reset,
15
        clk,
16
        //noc port
17
        chan_in,
18
        chan_out,
19
        //control interafce
20
        pck_injct_in,
21
        pck_injct_out
22
);
23 54 alirezamon
 
24 56 alirezamon
        `NOC_CONF
25
 
26 54 alirezamon
        //general
27
        input reset,clk;
28
        input [EAw-1 :0 ] current_e_addr;
29
 
30
        // the destination endpoint address
31
        //NoC interface
32
        input   smartflit_chanel_t      chan_in;
33
        output  smartflit_chanel_t      chan_out;
34
        //control interafce
35
 
36
        input   pck_injct_t pck_injct_in;
37
        output  pck_injct_t pck_injct_out;
38
 
39
 
40
        wire  [RAw-1 :0 ] current_r_addr;
41
 
42
        wire  [DSTPw-1 : 0 ] destport;
43 56 alirezamon
        reg flit_wr;
44 54 alirezamon
 
45 56 alirezamon
        assign current_r_addr = chan_in.ctrl_chanel.neighbors_r_addr;
46 54 alirezamon
 
47
        /*
48
        conventional_routing #(
49 56 alirezamon
                .NOC_ID(NOC_ID),
50 54 alirezamon
                .TOPOLOGY(TOPOLOGY),
51
                .ROUTE_NAME(ROUTE_NAME),
52
                .ROUTE_TYPE(ROUTE_TYPE),
53
                .T1(T1),
54
                .T2(T2),
55
                .T3(T3),
56
                .RAw(RAw),
57
                .EAw(EAw),
58
                .DSTPw(DSTPw),
59
                .LOCATED_IN_NI(1)
60
        )
61
        routing_module
62
        (
63
                .reset(reset),
64
                .clk(clk),
65
                .current_r_addr(current_r_addr),
66
                .dest_e_addr(pck_injct_in.endp_addr),
67
                .src_e_addr(current_e_addr),
68
                .destport(destport)
69
        );
70
 
71
*/
72
 
73 56 alirezamon
        assign destport = 7;
74 54 alirezamon
 
75
        localparam
76
                HDR_BYTE_NUM =  HDR_MAX_DATw / 8, // = HDR_MAX_DATw / (8 - HDR_MAX_DATw %8)
77
                HDR_DATA_w_tmp   =  HDR_BYTE_NUM * 8,
78
                HDR_DATA_w = (PCK_INJ_Dw < HDR_DATA_w_tmp)? PCK_INJ_Dw : HDR_DATA_w_tmp;
79
 
80
        wire [HDR_DATA_w-1 : 0] hdr_data_in = pck_injct_in.data [HDR_DATA_w-1 : 0];
81
        wire [Fw-1 : 0] hdr_flit_out;
82
 
83
        header_flit_generator #(
84 56 alirezamon
                .NOC_ID(NOC_ID),
85 54 alirezamon
                .DATA_w(HDR_DATA_w)
86 56 alirezamon
        ) the_header_flit_generator (
87 54 alirezamon
                .flit_out                       (hdr_flit_out),
88
                .vc_num_in                      (pck_injct_in.vc),
89
                .class_in                       (pck_injct_in.class_num),
90
                .dest_e_addr_in         (pck_injct_in.endp_addr),
91
                .src_e_addr_in          (current_e_addr),
92
                .weight_in                      (pck_injct_in.init_weight),
93
                .destport_in            (destport),
94
                .data_in                        (hdr_data_in),
95
                .be_in({BEw{1'b1}} )// Be is not used in simulation as we dont sent real data
96
        );
97
 
98
 
99
        localparam
100
                REMAIN_DATw =  PCK_INJ_Dw - HDR_DATA_w,
101
                REMAIN_DAT_FLIT_I = (REMAIN_DATw / Fpay),
102
                REMAIN_DAT_FLIT_F = (REMAIN_DATw % Fpay == 0)? 0 : 1,
103
                REMAIN_DAT_FLIT   = REMAIN_DAT_FLIT_I + REMAIN_DAT_FLIT_F,
104
                CNTw = log2(REMAIN_DAT_FLIT),
105
                MIN_PCK_SIZ = REMAIN_DAT_FLIT +1;
106
 
107
 
108
        reg [PCK_SIZw-1             :   0]  counter, counter_next;
109
        reg [CNTw-1                 :   0]  counter2,counter2_next;
110
        reg tail,head;
111
 
112
        wire [Fpay -1 : 0]  remain_dat [REMAIN_DAT_FLIT -1 : 0];
113
        wire [Fpay-1 : 0] dataIn =  remain_dat[counter2];
114
        enum {HEADER, BODY,TAIL} flit_type,flit_type_next;
115
 
116
 
117
 
118
        wire [V-1 : 0]   wr_vc_send = (flit_wr)?   pck_injct_in.vc : {V{1'b0}};
119
        wire [V-1 : 0]   vc_fifo_full;
120
 
121
 
122
        wire noc_ready;
123
 
124
        localparam
125
                LAST_TMP =PCK_INJ_Dw -  (Fpay*REMAIN_DAT_FLIT_I)-HDR_DATA_w,
126
                LASTw=(LAST_TMP==0)? Fpay : LAST_TMP;
127
        genvar i;
128
        generate
129
                for(i=0; i
130
                        assign remain_dat [i] = pck_injct_in.data [Fpay*(i+1)+HDR_DATA_w-1   : (Fpay*i)+HDR_DATA_w];
131
                end
132
                if(REMAIN_DAT_FLIT_F ) begin
133
 
134
                        assign remain_dat [REMAIN_DAT_FLIT_I][LASTw-1 : 0] = pck_injct_in.data [PCK_INJ_Dw-1   : (Fpay*REMAIN_DAT_FLIT_I)+HDR_DATA_w];
135
                end
136
        endgenerate
137
 
138
 
139
 
140
 
141
 
142
                one_hot_mux #(
143
                        .IN_WIDTH   (V ),
144
                        .SEL_WIDTH  (V ),
145
                        .OUT_WIDTH  (1 )
146
                        ) one_hot_mux1 (
147
                        .mux_in     (~ vc_fifo_full    ),
148
                        .mux_out    (noc_ready   ),
149
                        .sel        (pck_injct_in.vc       ));
150
 
151
 
152
 
153
 
154
                always @ (*) begin
155
                        counter_next = counter;
156
                        counter2_next =counter2;
157
                        flit_type_next =flit_type;
158
                        tail=1'b0;
159
                        head=1'b0;
160
                        flit_wr=0;
161
                        if(noc_ready)begin
162
                                case(flit_type)
163
                                        HEADER:begin
164
                                                if(pck_injct_in.pck_wr)begin
165
                                                        flit_wr=1;
166
                                                        counter_next = pck_injct_in.size-1;
167
                                                        counter2_next=0;
168
                                                        head=1'b1;
169
                                                        if(pck_injct_in.size == 1)begin
170
                                                                tail=1'b1;
171
                                                        end else if (pck_injct_in.size == 2) begin
172
                                                                flit_type_next = TAIL;
173
                                                        end else begin
174
                                                                flit_type_next = BODY;
175
                                                        end
176
                                                end
177
                                        end
178
                                        BODY: begin
179
                                                flit_wr=1;
180
                                                counter_next = counter -1'b1;
181
                                                counter2_next =counter2 +1'b1;
182
                                                if(counter == 2) begin
183
                                                        flit_type_next = TAIL;
184
                                                end
185
                                        end
186
                                        TAIL: begin
187
                                                flit_type_next = HEADER;
188
                                                flit_wr=1;
189
                                                tail=1'b1;
190
                                        end
191
                                endcase
192
 
193
                        end
194
                end
195
                reg [V-1 : 0] credit_o;
196
 
197
                always @ (posedge clk) begin
198 56 alirezamon
                        if(`pronoc_reset) begin
199 54 alirezamon
                                flit_type<=HEADER;
200
                                counter<=0;
201
                                counter2<=0;
202
                                credit_o<={V{1'b0}};
203
                        end else begin
204
                                flit_type<=flit_type_next;
205
                                counter<=counter_next;
206
                                counter2<=counter2_next;
207
                                if (chan_in.flit_chanel.flit_wr) credit_o<=  chan_in.flit_chanel.flit.vc;
208
                                else credit_o<={V{1'b0}};
209
                        end
210
                end
211
 
212
 
213
 
214
 
215
 
216 56 alirezamon
        multi_cast_injector_ovc_status #(
217 54 alirezamon
                .V(V),
218
                .B(LB),
219
                .CRDTw(CRDTw)
220
        )
221
        the_ovc_status
222
        (
223
                .credit_init_val_in ( chan_in.ctrl_chanel.credit_init_val),
224
                .wr_in(wr_vc_send),
225
                .credit_in(chan_in.flit_chanel.credit),
226
                .full_vc(vc_fifo_full),
227
                .nearly_full_vc( ),
228
                .empty_vc( ),
229
                .clk(clk),
230
                .reset(reset)
231 56 alirezamon
        );
232 54 alirezamon
 
233
 
234
        wire [HDR_DATA_w-1 : 0] hdr_data_o;
235
        hdr_flit_t hdr_flit_i;
236
 
237
        header_flit_info
238
        #(
239 56 alirezamon
                .NOC_ID (NOC_ID),
240
                .DATA_w (HDR_DATA_w)
241 54 alirezamon
        ) extractor (
242
                .flit(chan_in.flit_chanel.flit),
243
                .hdr_flit(hdr_flit_i),
244
                .data_o(hdr_data_o)
245
        );
246
 
247
        wire [PCK_INJ_Dw-1 : 0]  pck_data_o [V-1 : 0];
248
        reg  [Fpay-1 : 0] pck_data_o_gen [V-1 : 0][REMAIN_DAT_FLIT : 0];
249
 
250
        genvar k;
251
 
252
        reg [PCK_SIZw-1 : 0] rsv_counter [V-1 : 0];
253
        reg [EAw-1 : 0] sender_endp_addr_reg [V-1 : 0];
254
        logic [15:0] h2t_counter [V-1 : 0];
255
        logic [15:0] h2t_counter_next [V-1 : 0];
256
 
257
 
258
 
259
        //synthesis translate_off
260
        wire [NEw-1 : 0] current_id;
261
        wire [NEw-1 : 0] sendor_id;
262
        endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw),  .NE(NE)) encode1 ( .id(current_id), .code(current_e_addr));
263
        endp_addr_decoder #( .TOPOLOGY(TOPOLOGY), .T1(T1), .T2(T2), .T3(T3), .EAw(EAw),  .NE(NE)) encode2 ( .id(sendor_id), .code(pck_injct_out.endp_addr[EAw-1 : 0]));
264
        //synthesis translate_on
265
 
266
 
267
        generate
268
                for(i=0; i
269
                        always@(*) begin
270
                                h2t_counter_next[i]=h2t_counter[i]+1'b1;
271
                                if(chan_in.flit_chanel.flit.vc[i] & chan_in.flit_chanel.flit_wr & chan_in.flit_chanel.flit.hdr_flag)begin
272
                                                        h2t_counter_next[i]= 16'd0; // reset once header flit is received
273
                                end//hdr flit wr
274
                        end//always
275
 
276
 
277
 
278
 
279 56 alirezamon
                        always_ff @(`pronoc_clk_reset_edge) begin
280
                                if (`pronoc_reset)  begin
281 54 alirezamon
                                        rsv_counter[i]<= {PCK_SIZw{1'b0}};
282
                                        h2t_counter[i]<= 16'd0;
283
                                        sender_endp_addr_reg [i]<= {EAw{1'b0}};
284
                                end else begin
285
                                        h2t_counter[i]<=h2t_counter_next[i];
286
                                        if(chan_in.flit_chanel.flit.vc[i] & chan_in.flit_chanel.flit_wr ) begin
287
                                                if(chan_in.flit_chanel.flit.hdr_flag)begin
288
                                                        rsv_counter[i]<= {{(PCK_SIZw-1){1'b0}}, 1'b1};
289
                                                        sender_endp_addr_reg [i]<= hdr_flit_i.src_e_addr;
290
                                                        //synthesis translate_off
291
                                                        if(hdr_flit_i.dest_e_addr != current_e_addr) begin
292
                                                                $display("%t: ERROR: packet destination address %d does not match reciver endp address %d. %m",$time,hdr_flit_i.dest_e_addr , current_e_addr );
293
                                                                $finish;
294
                                                        end//if hdr_flit_i
295
                                                        //synthesis translate_on
296
                                                end //if hdr_flag
297
                                                else rsv_counter[i]<= rsv_counter[i]+1'b1;
298
                                        end//flit wr
299
                                end//reset
300
                        end//always
301
 
302
 
303
 
304
 
305
                        for (k=0;k< REMAIN_DAT_FLIT+1;k++)begin : K_
306
 
307 56 alirezamon
                                always_ff @(`pronoc_clk_reset_edge) begin
308
                                        if (`pronoc_reset)  begin
309 54 alirezamon
                                                pck_data_o_gen [i][k] <= {Fpay{1'b0}};
310
 
311
                                        end else begin
312
                                                if(chan_in.flit_chanel.flit.vc[i] & chan_in.flit_chanel.flit_wr ) begin
313
                                                        if (chan_in.flit_chanel.flit.hdr_flag )begin
314
                                                                if ( k ==0 ) pck_data_o_gen [i][k][HDR_DATA_w-1 : 0] <= hdr_data_o;
315
                                                        end
316
                                                        else begin
317
                                                                if (rsv_counter[i] == k ) pck_data_o_gen [i][k] <= chan_in.flit_chanel.flit.payload;
318
 
319
                                                        end // else
320
                                                end //if
321
                                        end //else
322
                                end// always
323
 
324
                                        if   (k == 0 ) assign pck_data_o [i][HDR_DATA_w-1 : 0] = pck_data_o_gen [i][0][HDR_DATA_w-1 : 0];
325
                                        else if (k == REMAIN_DAT_FLIT) assign pck_data_o [i][PCK_INJ_Dw-1 :    (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k][LASTw-1: 0];
326
                                        else assign pck_data_o [i][(k)*Fpay+HDR_DATA_w -1 : (k-1)*Fpay+ HDR_DATA_w] = pck_data_o_gen [i][k];
327
 
328
                        end //for k
329
 
330
 
331
                        //synthesis translate_off
332
                        always @(posedge clk) begin
333
                                if((pck_injct_out.ready[i] == 1'b0 ) & pck_injct_in.vc[i] & pck_injct_in.pck_wr )begin
334
                                        $display("%t: ERROR: a packet injection request is recived in core(%d), vc (%d) while packet injectore was not ready. %m",$time,current_id,i);
335
                                        $finish;
336
                                end
337
 
338
                        end
339
                        //synthesis translate_on
340
 
341
 
342
 
343
 
344
                end//for i
345
        endgenerate
346
 
347
        wire [V-1 : 0] vc_reg;
348
        wire tail_flag_reg, hdr_flag_reg;
349
 
350
 
351
        pronoc_register #(.W(V))   register1 (.in(chan_in.flit_chanel.flit.vc),        .reset  (reset ), .clk (clk),.out(vc_reg));
352
        pronoc_register #(.W(1))   register2 (.in(chan_in.flit_chanel.flit.hdr_flag),   .reset  (reset ), .clk (clk),.out(hdr_flag_reg));
353
        pronoc_register #(.W(1))   register3 (.in(chan_in.flit_chanel.flit.tail_flag & chan_in.flit_chanel.flit_wr ),.reset  (reset ), .clk (clk),.out(tail_flag_reg));
354
 
355
        wire [Vw-1 : 0] vc_bin;
356
 
357
        one_hot_to_bin #(
358
                .ONE_HOT_WIDTH  (V),
359
                .BIN_WIDTH      (Vw )
360
        ) one_hot_to_bin (
361
                .one_hot_code   (vc_reg  ),
362
                .bin_code       (vc_bin      )
363
        );
364
 
365
 
366
        assign pck_injct_out.data  =  pck_data_o[vc_bin];
367
        assign pck_injct_out.size  =  rsv_counter[vc_bin];
368
        assign pck_injct_out.h2t_delay = h2t_counter[vc_bin];
369
        assign pck_injct_out.ready = (flit_type == HEADER)?  ~vc_fifo_full : {V{1'b0}};
370
        assign pck_injct_out.endp_addr =  sender_endp_addr_reg[vc_bin];
371
        assign pck_injct_out.vc = vc_reg;
372
        assign pck_injct_out.pck_wr = tail_flag_reg;
373
 
374
        assign chan_out.flit_chanel.flit.hdr_flag =head;
375
        assign chan_out.flit_chanel.flit.tail_flag=tail;
376
        assign chan_out.flit_chanel.flit.vc=pck_injct_in.vc;
377
        assign chan_out.flit_chanel.flit_wr=flit_wr;
378
 
379
        assign chan_out.flit_chanel.flit.payload = (flit_type== HEADER)? hdr_flit_out[Fpay-1 : 0] : dataIn;
380
        assign chan_out.smart_chanel = {SMART_CHANEL_w{1'b0}};
381
        assign chan_out.flit_chanel.congestion = {CONGw{1'b0}};
382
        assign chan_out.flit_chanel.credit= credit_o;
383
        assign chan_out.ctrl_chanel.credit_init_val= LB;
384
        assign chan_out.ctrl_chanel.endp_port =1'b1;
385
 
386
 
387
        distance_gen #(
388
                        .TOPOLOGY(TOPOLOGY),
389
                        .T1(T1),
390
                        .T2(T2),
391
                        .T3(T3),
392
                        .EAw(EAw),
393
                        .DISTw(DISTw)
394
                )
395
                the_distance_gen
396
                (
397
                        .src_e_addr(sender_endp_addr_reg[vc_bin]),
398
                        .dest_e_addr(current_e_addr),
399
                        .distance(pck_injct_out.distance)
400
                );
401
 
402
 
403
 
404
 
405
 
406
 
407
        //synthesis translate_off
408
        //`define MONITOR_RSV_DAT
409
 
410
 
411
 
412
        always @(posedge clk) begin
413
                if((pck_injct_in.vc == {V{1'b0}} ) & pck_injct_in.pck_wr )begin
414
                        $display("%t: ERROR: a packet injection request is recived while vc is not set. %m",$time);
415
                        $finish;
416
                end
417
                if(pck_injct_in.pck_wr && (pck_injct_in.size
418
                        $display("%t: ERROR: requested %d flit packet size is smaller than minimum %d flits to send %d bits of data. %m",$time,pck_injct_in.size,MIN_PCK_SIZ, PCK_INJ_Dw );
419
                        $finish;
420
                end
421
 
422
                `ifdef MONITOR_RSV_DAT
423
 
424
 
425
                if(pck_injct_in.pck_wr) begin
426
                        $display ("pck_inj(%d) send a packet:  size=%d, data=%h, v=%h",current_id,
427
                                        pck_injct_in.size, pck_injct_in.data,pck_injct_in.vc);
428
                end
429
 
430
                if(pck_injct_out.pck_wr) begin
431
                        $display ("pck_inj(%d) got a packet: source=%d, size=%d, data=%h",current_id,
432
                                        sendor_id,pck_injct_out.size,pck_injct_out.data);
433
                end
434
 
435
 
436
                `endif
437
 
438
        end
439
 
440
 
441
        //synthesis translate_on
442
 
443
 
444
 
445
 
446
 
447
endmodule
448
 
449
 
450
 
451
 
452
/******************
453
 *   ovc_status
454
 *******************/
455
 
456 56 alirezamon
module multi_cast_injector_ovc_status #(
457 54 alirezamon
                parameter V     =   4,
458
                parameter B =   16,
459
                parameter CRDTw =4
460
                )
461
                (
462
 
463
                input   [V-1 : 0] [CRDTw-1 : 0 ] credit_init_val_in,
464
                input   [V-1            :0] wr_in,
465
                input   [V-1            :0] credit_in,
466
                output  [V-1            :0] full_vc,
467
                output  [V-1            :0] nearly_full_vc,
468
                output  [V-1            :0] empty_vc,
469
                input                       clk,
470
                input                       reset
471
                );
472
 
473
 
474
        function integer log2;
475
                input integer number; begin
476
                        log2=(number <=1) ? 1: 0;
477
                        while(2**log2
478
                                log2=log2+1;
479
                        end
480
                end
481
        endfunction // log2
482
 
483
 
484
        localparam  DEPTH_WIDTH =   log2(B+1);
485
 
486
 
487
        reg  [DEPTH_WIDTH-1 : 0] credit    [V-1 : 0];
488
        wire  [V-1 : 0] cand_vc_next;
489
 
490
 
491
        genvar i;
492
        generate
493 56 alirezamon
    for(i=0;i
494
        always @ (`pronoc_clk_reset_edge)begin
495
            if(`pronoc_reset)begin
496
                credit[i]<= credit_init_val_in[i][DEPTH_WIDTH-1:0];
497
            end else begin
498
                if(  wr_in[i]  && ~credit_in[i])   credit[i] <= credit[i]-1'b1;
499
                if( ~wr_in[i]  &&  credit_in[i])   credit[i] <= credit[i]+1'b1;
500
            end //reset
501
        end//always
502 54 alirezamon
 
503 56 alirezamon
        assign  full_vc[i]   = (credit[i] == {DEPTH_WIDTH{1'b0}});
504
        assign  nearly_full_vc[i]=  (credit[i] == 1) |  full_vc[i];
505
        assign  empty_vc[i]  = (credit[i] == credit_init_val_in[i][DEPTH_WIDTH-1:0]);
506
    end//for
507
    endgenerate
508 54 alirezamon
endmodule

powered by: WebSVN 2.1.0

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