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 48

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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