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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 54 alirezamon
`include "pronoc_def.v"
2 48 alirezamon
/************************
3
 *      fmesh
4
 *
5
 * **********************/
6
 
7
 
8
 
9
 
10
module  fmesh_addr_encoder #(
11
                parameter   NX=2,
12
                parameter   NY=2,
13
                parameter   NL=2,
14
                parameter   NE=16,
15
                parameter   EAw=4
16
                )(
17
                id,
18
                code
19
                );
20
 
21
        function integer log2;
22
                input integer number; begin
23
                        log2=(number <=1) ? 1: 0;
24
                        while(2**log2
25
                                log2=log2+1;
26
                        end
27
                end
28
        endfunction // log2
29
 
30
        localparam  LOCAL   =   0,
31
                EAST    =   1,
32
                NORTH   =   2,
33
                WEST    =   3,
34
                SOUTH   =   4;
35
 
36
 
37
 
38
        function integer addrencode;
39
                input integer in,nx,nxw,nl,nyw,ny;
40
                integer  y, x, l,p, diff,mul;begin
41
                        mul  = nx*ny*nl;
42
                        if(in < mul) begin
43
                                y = ((in/nl) / nx );
44
                                x = ((in/nl) % nx );
45
                                l = (in % nl);
46
                                p = (l==0)? LOCAL : 4+l;
47
                        end else begin
48
                                diff = in -  mul ;
49
                                if( diff <  nx) begin //top mesh edge
50
                                        y = 0;
51
                                        x = diff;
52
                                        p = NORTH;
53
                                end else if  ( diff < 2* nx) begin //bottom mesh edge
54
                                        y = ny-1;
55
                                        x = diff-nx;
56
                                        p = SOUTH;
57
                                end else if  ( diff < (2* nx)+ny ) begin //left mesh edge
58
                                        y = diff - (2* nx);
59
                                        x = 0;
60
                                        p = WEST;
61
                                end else begin //right mesh edge
62
                                        y = diff - (2* nx) -ny;
63
                                        x = nx-1;
64
                                        p = EAST;
65
                                end
66
                        end//else
67
                        addrencode = ( p<<(nxw+nyw) | (y<
68
                end
69
        endfunction // addrencode
70
 
71
 
72
 
73
        localparam
74
                NXw= log2(NX),
75
                NYw= log2(NY),
76
                NEw = log2(NE);
77
 
78
 
79
        input  [NEw-1 :0] id;
80
        output [EAw-1 : 0] code;
81
 
82
        wire [EAw-1 : 0 ] codes [NE-1 : 0];
83
        genvar i;
84
        generate
85
                for(i=0; i< NE; i=i+1) begin : endpoints
86
                        //Endpoint decoded address
87
                        /* verilator lint_off WIDTH */
88
                        localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw,NY);
89
                        /* verilator lint_on WIDTH */
90
                        assign codes[i] = ENDP;
91
                end
92
        endgenerate
93
 
94
        assign code = codes[id];
95
endmodule
96
 
97
 
98
module  fmesh_addr_coder #(
99
                parameter   NX=2,
100
                parameter   NY=2,
101
                parameter   NL=2,
102
                parameter   NE=16,
103
                parameter   EAw=4
104
                )(
105
                id,
106
                code
107
                );
108
 
109
        function integer log2;
110
                input integer number; begin
111
                        log2=(number <=1) ? 1: 0;
112
                        while(2**log2
113
                                log2=log2+1;
114
                        end
115
                end
116
        endfunction // log2
117
 
118
        localparam  LOCAL   =   0,
119
                EAST    =   1,
120
                NORTH   =   2,
121
                WEST    =   3,
122
                SOUTH   =   4;
123
 
124
 
125
        function integer addrencode;
126
                input integer in,nx,nxw,nl,nyw,ny;
127
                integer  y, x, l,p, diff,mul;begin
128
                        mul  = nx*ny*nl;
129
                        if(in < mul) begin
130
                                y = ((in/nl) / nx );
131
                                x = ((in/nl) % nx );
132
                                l = (in % nl);
133
                                p = (l==0)? LOCAL : 4+l;
134
                        end else begin
135
                                diff = in -  mul ;
136
                                if( diff <  nx) begin //top mesh edge
137
                                        y = 0;
138
                                        x = diff;
139
                                        p = NORTH;
140
                                end else if  ( diff < 2* nx) begin //bottom mesh edge
141
                                        y = ny-1;
142
                                        x = diff-nx;
143
                                        p = SOUTH;
144
                                end else if  ( diff < (2* nx)+ny ) begin //left mesh edge
145
                                        y = diff - (2* nx);
146
                                        x = 0;
147
                                        p = WEST;
148
                                end else begin //right mesh edge
149
                                        y = diff - (2* nx) -ny;
150
                                        x = nx-1;
151
                                        p = EAST;
152
                                end
153
                        end//else
154
                        addrencode = ( p<<(nxw+nyw) | (y<
155
                end
156
        endfunction // addrencode
157
 
158
 
159
        localparam
160
                NXw= log2(NX),
161
                NYw= log2(NY),
162
                NEw = log2(NE);
163
 
164
 
165
        output [NEw-1 :0] id;
166
        input [EAw-1 : 0] code;
167
 
168
        wire   [NEw-1 : 0]  codes   [(2**EAw)-1 : 0 ];
169
        genvar i;
170
        generate
171
                for(i=0; i< NE; i=i+1) begin : endpoints
172
                        //Endpoint decoded address
173
                        /* verilator lint_off WIDTH */
174
                        localparam [EAw-1 : 0] ENDP= addrencode(i,NX,NXw,NL,NYw,NY);
175
                        /* verilator lint_on WIDTH */
176
                        assign codes[ENDP] = i;
177
                end
178
        endgenerate
179
 
180
        assign id = codes[code];
181
endmodule
182
 
183
 
184
 
185
 
186
module fmesh_endp_addr_decode #(
187
                parameter T1=4,
188
                parameter T2=4,
189
                parameter T3=4,
190
                parameter EAw=9
191
                )(
192
                e_addr,
193
                ex,
194
                ey,
195
                ep,
196
                valid
197
                );
198
 
199
        function integer log2;
200
                input integer number; begin
201
                        log2=(number <=1) ? 1: 0;
202
                        while(2**log2
203
                                log2=log2+1;
204
                        end
205
                end
206
        endfunction // log2
207
 
208
        localparam
209
                NX = T1,
210
                NY = T2,
211
                NL = T3,
212
                EXw = log2(NX),
213
                EYw = log2(NY),
214
                EPw = EAw - EXw - EYw,
215
                P   = 5 + NL -1;
216
 
217
        /* verilator lint_off WIDTH */
218
        localparam [EXw-1 : 0]    MAXX = (NX-1);
219
        localparam [EYw-1 : 0]    MAXY = (NY-1);
220
        localparam [EPw-1 : 0]    MAXP = (P-1);
221
        /* verilator lint_on WIDTH */
222
 
223
 
224
        input  [EAw-1 : 0] e_addr;
225
        output [EXw-1 : 0] ex;
226
        output [EYw-1 : 0] ey;
227
        output [EPw-1 : 0] ep;
228
        output valid;
229
 
230
        assign {ep,ey,ex} = e_addr;
231
        /* verilator lint_off CMPCONST */
232
        assign valid = ( (ex<= MAXX) & (ey <= MAXY) & (ep<= MAXP) );
233
        /* verilator lint_on CMPCONST */
234
 
235
 
236
endmodule
237
 
238
 
239
module fmesh_destp_generator #(
240
                parameter ROUTE_NAME = "XY",
241
                parameter ROUTE_TYPE = "DETERMINISTIC",
242
                parameter P=5,
243
                parameter DSTPw=4,
244
                parameter NL=1,
245
                parameter PLw=1,
246
                parameter PPSw=4,
247
                parameter SW_LOC=0,
248
                parameter SELF_LOOP_EN="NO"
249
                )(
250
                dest_port_out,
251
                dest_port_coded,
252
                endp_localp_num,
253
                swap_port_presel,
254
                port_pre_sel,
255
                odd_column
256
                );
257
        localparam P_1 =  ( SELF_LOOP_EN=="NO")?  P-1 : P;
258
 
259
        input  [DSTPw-1 : 0] dest_port_coded;
260
        input  [PLw-1 : 0] endp_localp_num;
261
        output [P_1-1 : 0] dest_port_out;
262
        input           swap_port_presel;
263
        input  [PPSw-1 : 0] port_pre_sel;
264
        input odd_column;
265
 
266
        wire [P_1-1 : 0] dest_port_in;
267
 
268
        fmesh_destp_decoder #(
269
                .ROUTE_TYPE(ROUTE_TYPE),
270
                .P(P),
271
                .DSTPw(DSTPw),
272
                .NL(NL),
273
                .PLw(PLw),
274
                .PPSw(PPSw),
275
                .SW_LOC(SW_LOC),
276
                .SELF_LOOP_EN(SELF_LOOP_EN)
277
        )
278
        decoder
279
        (
280
                .dest_port_coded(dest_port_coded),
281
                .dest_port_out(dest_port_in),
282
                .endp_localp_num(endp_localp_num),
283
                .swap_port_presel(swap_port_presel),
284
                .port_pre_sel(port_pre_sel)
285
                );
286
 
287
        assign dest_port_out = dest_port_in;
288
 
289
endmodule
290
 
291
 
292
 
293
 
294
 
295
 
296
 
297
 
298
 
299
 
300
 
301
 
302
 
303
module fmesh_destp_decoder #(
304
                parameter ROUTE_TYPE="DETERMINISTIC",
305
                parameter P=6,
306
                parameter DSTPw=4,
307
                parameter NL=2,
308
                parameter PLw=1,
309
                parameter PPSw=4,
310
                parameter SW_LOC=0,
311
                parameter SELF_LOOP_EN="NO"
312
                )(
313
                dest_port_coded,
314
                endp_localp_num,
315
                dest_port_out,
316
                swap_port_presel,
317
                port_pre_sel
318
                );
319
 
320
        localparam P_1 = ( SELF_LOOP_EN=="NO")?  P-1 : P;
321
 
322
        input  [DSTPw-1 : 0] dest_port_coded;
323
        input  [PLw-1 : 0] endp_localp_num;
324
        output [P_1-1 : 0] dest_port_out;
325
        input           swap_port_presel;
326
        input  [PPSw-1 : 0] port_pre_sel;
327
 
328
        wire [P-1 : 0] endp_localp_onehot;
329
 
330
        reg [4:0] portout;
331
 
332
        generate
333
                if( ROUTE_TYPE == "DETERMINISTIC") begin :dtrmn
334
 
335
 
336
                        wire x,y,a,b;
337
                        assign {x,y,a,b} = dest_port_coded;
338
 
339
                        always @(*)begin
340
                                case({a,b})
341
                                        2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
342
                                        2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
343
                                        2'b00 : portout =  5'b00001;
344
                                        2'b11 : portout = {~y,1'b0,y,1'b0,1'b0}; //invalid condition in determinstic routing
345
                                endcase
346
                        end //always
347
 
348
                end else begin : adpv
349
 
350
                        wire x,y,a,b;
351
                        assign {x,y,a,b} = dest_port_coded;
352
                        wire [PPSw-1:0] port_pre_sel_final;
353
                        assign port_pre_sel_final= (swap_port_presel)? ~port_pre_sel: port_pre_sel;
354
 
355
                        always @(*)begin
356
                                case({a,b})
357
                                        2'b10 : portout = {1'b0,~x,1'b0,x,1'b0};
358
                                        2'b01 : portout = {~y,1'b0,y,1'b0,1'b0};
359
                                        2'b11 : portout = (port_pre_sel_final[{x,y}])?  {~y,1'b0,y,1'b0,1'b0} : {1'b0,~x,1'b0,x,1'b0};
360
                                        2'b00 : portout =  5'b00001;
361
                                endcase
362
                        end //always
363
                end //adaptive
364
 
365
                wire [P-1 : 0] destport_onehot;
366
 
367
                bin_to_one_hot #(
368
                        .BIN_WIDTH(PLw),
369
                        .ONE_HOT_WIDTH(P)
370
                )
371
                conv
372
                (
373
                        .bin_code(endp_localp_num),
374
                        .one_hot_code(endp_localp_onehot)
375
                );
376
                if(NL>1) begin :multi
377
                        assign destport_onehot =(portout[0])? endp_localp_onehot : /*select local destination*/
378
                                { {(NL-1){1'b0}} ,portout};
379
                end else begin
380
                        assign destport_onehot =(portout[0])? endp_localp_onehot : /*select local destination*/
381
                                portout;
382
                end
383
 
384
                if(SELF_LOOP_EN == "NO") begin :nslp
385
                        remove_sw_loc_one_hot #(
386
                                        .P(P),
387
                                        .SW_LOC(SW_LOC)
388
                                )
389
                                remove_sw_loc
390
                                (
391
                                        .destport_in(destport_onehot),
392
                                        .destport_out(dest_port_out)
393
                                );
394
                end else begin: slp
395
                                assign dest_port_out = destport_onehot;
396
                end
397
 
398
                endgenerate
399
endmodule
400
 
401
 
402
 
403
/********************
404
 
405
    distance_gen
406
 
407
 ********************/
408
 
409
module fmesh_distance_gen #(
410
                parameter T1= 4,    // number of router in x axis
411
                parameter T2= 4,    // number of router in y axis
412
                parameter T3= 4,
413
                parameter EAw=4,
414
                parameter DISTw=4
415
)(
416
                src_e_addr,
417
                dest_e_addr,
418
                distance
419
);
420
 
421
        function integer log2;
422
                input integer number; begin
423
                        log2=(number <=1) ? 1: 0;
424
                        while(2**log2
425
                                log2=log2+1;
426
                        end
427
                end
428
        endfunction // log2
429
 
430
 
431
        localparam
432
                Xw  =   log2(T1),   // number of node in x axis
433
                Yw  =   log2(T2);    // number of node in y axis
434
        localparam [Xw : 0] NX  = T1;
435
        localparam [Yw : 0] NY  = T2;
436
 
437
 
438
        input [EAw-1 : 0] src_e_addr;
439
        input [EAw-1 : 0] dest_e_addr;
440
        output[DISTw-1:   0]distance;
441
 
442
        wire [Xw-1 :   0]src_x,dest_x;
443
        wire [Yw-1 :   0]src_y,dest_y;
444
 
445
        fmesh_endp_addr_decode #(
446
                .T1(T1),
447
                .T2(T2),
448
                .T3(T3),
449
                .EAw(EAw)
450
        )
451
        src_addr_decode
452
        (
453
                .e_addr(src_e_addr),
454
                .ex(src_x),
455
                .ey(src_y),
456
                .ep(),
457
                .valid()
458
        );
459
 
460
        fmesh_endp_addr_decode #(
461
                .T1(T1),
462
                .T2(T2),
463
                .T3(T3),
464
                .EAw(EAw)
465
        )
466
        dest_addr_decode
467
        (
468
                .e_addr(dest_e_addr),
469
                .ex(dest_x),
470
                .ey(dest_y),
471
                .ep(),
472
                .valid()
473
        );
474
 
475
        reg [Xw-1  :   0] x_offset;
476
        reg [Yw-1  :   0] y_offset;
477
 
478
        always @(*) begin
479
                        x_offset     = (src_x> dest_x)? src_x - dest_x : dest_x - src_x;
480
                        y_offset     = (src_y> dest_y)? src_y - dest_y : dest_y - src_y;
481
        end
482
 
483
 
484
        /* verilator lint_off WIDTH */
485
        assign distance =  x_offset + y_offset +1'b1;
486
        /* verilator lint_on WIDTH */
487
endmodule
488
 
489
 

powered by: WebSVN 2.1.0

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