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/] [perl_gui/] [lib/] [perl/] [mpsoc_verilog_gen.pl] - Blame information for rev 16

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

Line No. Rev Author Line
1 16 alirezamon
 
2
 
3
use strict;
4
use warnings;
5
use mpsoc;
6
use soc;
7
use ip;
8
use ip_gen;
9
use Cwd;
10
use rvp;
11
 
12
 
13
 
14
sub mpsoc_generate_verilog{
15
        my $mpsoc=shift;
16
        my $mpsoc_name=$mpsoc->mpsoc_get_mpsoc_name();
17
        my $io_v="\tclk,\n\treset";
18
        my $io_def_v="
19
//IO
20
\tinput\tclk,reset;\n";
21
        my $param_as_in_v;
22
 
23
        #generate socs_parameter
24
        my $socs_param= gen_socs_param($mpsoc);
25
 
26
        #generate noc_parameter
27
        my $noc_param=gen_noc_param_v($mpsoc);
28
 
29
        #generate the noc
30
        my $noc_v=gen_noc_v();
31
 
32
        #generate socs
33
        my $socs_v=gen_socs_v($mpsoc,\$io_v,\$io_def_v);
34
 
35
        #functions
36
        my $functions=get_functions();
37
 
38
        my $mpsoc_v = (defined $param_as_in_v )? "module $mpsoc_name #(\n $param_as_in_v\n)(\n$io_v\n);\n": "module $mpsoc_name (\n$io_v\n);\n";
39
        add_text_to_string (\$mpsoc_v,$functions);
40
        add_text_to_string (\$mpsoc_v,$socs_param);
41
        add_text_to_string (\$mpsoc_v,$noc_param);
42
        add_text_to_string (\$mpsoc_v,$io_def_v);
43
        add_text_to_string (\$mpsoc_v,$noc_v);
44
        add_text_to_string (\$mpsoc_v,$socs_v);
45
        add_text_to_string (\$mpsoc_v,"\nendmodule\n");
46
 
47
 
48
        return $mpsoc_v;
49
}
50
 
51
sub get_functions{
52
        my $p='
53
//functions
54
        function integer log2;
55
                input integer number; begin
56
                        log2=0;
57
                        while(2**log2<number) begin
58
                                log2=log2+1;
59
                        end
60
        end
61
        endfunction // log2
62
 
63
        function integer CORE_NUM;
64
                input integer x,y;
65
                begin
66
                        CORE_NUM = ((y * NX) +  x);
67
                end
68
        endfunction
69
 
70
 
71
 
72
        localparam      Fw      =   2+V+Fpay,
73
                                NC      =   NX*NY,  //flit width;
74
                                Xw      =   log2(NX),
75
                                Yw      =   log2(NY) ,
76
                                Cw      =   (C>1)? log2(C): 1,
77
                                NCw     =   log2(NC),
78
                                NCV     =   NC  * V,
79
                                NCFw    =   NC  * Fw;
80
        ';
81
 
82
        return $p;
83
 
84
 
85
 
86
}
87
 
88
 
89
sub  gen_socs_param{
90
        my $mpsoc=shift;
91
        my $socs_param="
92
//SOC parameters\n";
93
        my $nx= $mpsoc->mpsoc_get_param("NX");
94
    my $ny= $mpsoc->mpsoc_get_param("NY");
95
    my $processors_en=0;
96
    for (my $y=0;$y<$ny;$y++){
97
                for (my $x=0; $x<$nx;$x++){
98
                        my $tile=($nx*$y)+ $x;
99
                        my ($soc_name,$n,$soc_num)=$mpsoc->mpsoc_get_tile_soc_name($tile);
100
                        if(defined $soc_name) {
101
                                my $param=      gen_soc_param($mpsoc,$soc_name,$soc_num,$tile);
102
                                add_text_to_string(\$socs_param,$param);
103
                        }
104
        }}#x&y
105
        $socs_param="$socs_param \n";
106
        return $socs_param;
107
 
108
}
109
 
110
 
111
sub  gen_soc_param {
112
        my ($mpsoc,$soc_name,$soc_num,$tile)=@_;
113
        my $top=$mpsoc->mpsoc_get_soc($soc_name);
114
        my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
115
        my %params;
116
        if ($setting eq 'Custom'){
117
                 %params= $top->top_get_custom_soc_param($tile);
118
        }else{
119
                 %params=$top->top_get_default_soc_param();
120
        }
121
        my $params="\n\t //Parameter setting for $soc_name  located in tile: $tile \n";
122
        foreach my $p (sort keys %params){
123
                        $params="$params\t localparam ${soc_name}_${soc_num}_$p=$params{$p};\n";
124
        }
125
 
126
 
127
 
128
        return $params;
129
}
130
 
131
 
132
sub gen_noc_param_v{
133
        my $mpsoc=shift;
134
        my $param_v="\n\n//NoC parameters\n";
135
        my @params=$mpsoc->mpsoc_get_param_order();
136
        foreach my $p (@params){
137
                my $val=$mpsoc->mpsoc_get_param($p);
138
                add_text_to_string (\$param_v,"\tlocalparam $p=$val;\n");
139
                #print "$p\n";
140
 
141
        }
142
        my $class=$mpsoc->mpsoc_get_param("C");
143
        my $str;
144
        if( $class > 1){
145
                $str="CLASS_SETTING={";
146
                for (my $i=$class-1; $i>=0;$i--){
147
                        $str=($i==0)?  "${str}Cn_0};\n " : "${str}Cn_$i,";
148
                }
149
        }else {
150
                $str="CLASS_SETTING={V{1\'b1}};\n";
151
        }
152
        add_text_to_string (\$param_v,"\tlocalparam $str");
153
        my $v=$mpsoc->mpsoc_get_param("V")-1;
154
        my $escape=$mpsoc->mpsoc_get_param("ESCAP_VC_MASK");
155
        add_text_to_string (\$param_v,"\tlocalparam [$v :0] ESCAP_VC_MASK=1;\n") if (! defined $escape);
156
        add_text_to_string (\$param_v," \tlocalparam  CVw=(C==0)? V : C * V;\n");
157
 
158
 
159
 
160
        return $param_v;
161
 
162
 
163
 
164
}
165
 
166
 
167
 
168
 
169
sub gen_noc_v{
170
 
171
 
172
        my $noc =  read_file("../src_noc/noc.v");
173
        my @noc_param=$noc->get_modules_parameters_not_local_order('noc');
174
 
175
 
176
        my $noc_v='
177
 
178
//NoC ports
179
        wire [Fw-1      :   0]  ni_flit_out                 [NC-1           :0];
180
        wire [NC-1      :   0]  ni_flit_out_wr;
181
        wire [V-1       :   0]  ni_credit_in                [NC-1           :0];
182
        wire [Fw-1      :   0]  ni_flit_in                  [NC-1           :0];
183
        wire [NC-1      :   0]  ni_flit_in_wr;
184
        wire [V-1       :   0]  ni_credit_out               [NC-1           :0];
185
        wire [NCFw-1    :   0]  flit_out_all;
186
        wire [NC-1      :   0]  flit_out_wr_all;
187
        wire [NCV-1     :   0]  credit_in_all;
188
        wire [NCFw-1    :   0]  flit_in_all;
189
        wire [NC-1      :   0]  flit_in_wr_all;
190
        wire [NCV-1     :   0]  credit_out_all;
191
        wire                                    noc_clk,noc_reset;
192
 
193
    ';
194
 
195
 
196
 
197
        $noc_v="$noc_v
198
//NoC\n \tnoc #(\n";
199
        my $i=0;
200
        foreach my $p (@noc_param){
201
                my $param=($i==0)?  "\t\t.$p($p)":",\n\t\t.$p($p)";
202
                $i=1;
203
                add_text_to_string(\$noc_v,$param);
204
        }
205
        add_text_to_string(\$noc_v,"\n\t)\n\tthe_noc\n\t(\n");
206
 
207
        my @ports= $noc->get_module_ports_order('noc');
208
        $i=0;
209
        foreach my $p (@ports){
210
                my $port;
211
                if($p eq 'reset' ){
212
                        $port=($i==0)?  "\t\t.$p(noc_reset)":",\n\t\t.$p(noc_reset)";
213
                }elsif( $p eq 'clk'){
214
                        $port=($i==0)?  "\t\t.$p(noc_clk)":",\n\t\t.$p(noc_clk)";
215
                }else {
216
                        $port=($i==0)?  "\t\t.$p($p)":",\n\t\t.$p($p)";
217
                }
218
                $i=1;
219
                add_text_to_string(\$noc_v,$port);
220
        }
221
        add_text_to_string(\$noc_v,"\n\t);\n\n");
222
 
223
add_text_to_string(\$noc_v,'
224
        clk_source  src         (
225
                .clk_in(clk),
226
                .clk_out(noc_clk),
227
                .reset_in(reset),
228
                .reset_out(noc_reset)
229
        );
230
');
231
 
232
 
233
 
234
 
235
add_text_to_string(\$noc_v,'
236
 
237
//NoC port assignment
238
  genvar x,y;
239
  generate
240
    for (x=0;   x<NX; x=x+1) begin :x_loop1
241
        for (y=0;   y<NY;   y=y+1) begin: y_loop1
242
                localparam IP_NUM   =   ((y * NX) +  x);
243
 
244
 
245
            assign  ni_flit_in      [IP_NUM] =   flit_out_all    [(IP_NUM+1)*Fw-1    : IP_NUM*Fw];
246
            assign  ni_flit_in_wr   [IP_NUM] =   flit_out_wr_all [IP_NUM];
247
            assign  credit_in_all   [(IP_NUM+1)*V-1 : IP_NUM*V]     =   ni_credit_out   [IP_NUM];
248
            assign  flit_in_all     [(IP_NUM+1)*Fw-1    : IP_NUM*Fw]    =   ni_flit_out     [IP_NUM];
249
            assign  flit_in_wr_all  [IP_NUM] =   ni_flit_out_wr  [IP_NUM];
250
            assign  ni_credit_in    [IP_NUM] =   credit_out_all  [(IP_NUM+1)*V-1 : IP_NUM*V];
251
 
252
 
253
 
254
 
255
 
256
        end
257
    end
258
endgenerate
259
 
260
'
261
);
262
 
263
 
264
 
265
 
266
 
267
 
268
 
269
 
270
 
271
 
272
 
273
 
274
 
275
 
276
 
277
 
278
 
279
 
280
 
281
 
282
        return $noc_v;
283
 
284
}
285
 
286
 
287
 
288
 
289
sub gen_socs_v{
290
        my ($mpsoc,$io_v_ref,$io_def_v)=@_;
291
        #generate loop
292
 
293
#       my $socs_v='
294
#       genvar x,y;    
295
#    
296
#    generate 
297
#    for (x=0;   x<NX; x=x+1) begin :x_loop1
298
#        for (y=0;   y<NY;   y=y+1) begin: y_loop1
299
#                localparam IP_NUM   =   CORE_NUM(x,y);'  ;     
300
 
301
 
302
 
303
#       my @socs= $mpsoc->mpsoc_get_soc_list();
304
#       foreach my $soc (@socs){
305
 
306
#       #tile num condition
307
#               my @tiles= $mpsoc->mpsoc_get_soc_tiles_num($soc);
308
#       if(scalar @tiles>0){
309
#               my $condition="\n\t\tif(";
310
#               my $s=compress_nums( @tiles);
311
#               my @sep=split(',',$s);
312
#                       my $i=0;
313
#                       foreach my $p (@sep){
314
#                               my @range=split(':',$p);
315
#                               my $tt;
316
#                               if($i==0){
317
#                                       $tt= (scalar @range>1)? "(IP_NUM>=$range[0] && IP_NUM<=$range[1])":"(IP_NUM==$range[0])" ;
318
#                               }else{
319
#                               }
320
#                               add_text_to_string(\$condition,$tt);
321
#                               $i=1;
322
#                       }
323
#                       add_text_to_string(\$condition,") begin :${soc}_if\n ");        
324
#                       #soc instance
325
#                       my $soc_v= gen_soc_v($mpsoc,$soc);
326
#         
327
#                       add_text_to_string(\$socs_v,$condition );
328
#                       add_text_to_string(\$socs_v,$soc_v);
329
#                       add_text_to_string(\$socs_v,"\t\tend // ${soc}_if \n");
330
#               }#scalar @tile  
331
# }     #froeach soc
332
 
333
 
334
 
335
 my $socs_v;
336
 
337
   my $nx= $mpsoc->mpsoc_get_param("NX");
338
   my $ny= $mpsoc->mpsoc_get_param("NY");
339
   my $processors_en=0;
340
   for (my $y=0;$y<$ny;$y++){
341
                for (my $x=0; $x<$nx;$x++){
342
                        my $tile_num=($nx*$y)+ $x;
343
 
344
                        my ($soc_name,$n,$soc_num)=$mpsoc->mpsoc_get_tile_soc_name($tile_num);
345
 
346
                        if(defined $soc_name) {
347
                                my ($soc_v,$en)= gen_soc_v($mpsoc,$soc_name,$tile_num,$x,$y,$soc_num,$io_v_ref,$io_def_v);
348
                                add_text_to_string(\$socs_v,$soc_v);
349
                                $processors_en|=$en;
350
                        }else{
351
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
352
                                my $soc_v="\n\n // Tile:$tile_num (x=$x,y=$y)   is not assigned to any ip\n";
353
                                $soc_v="$soc_v
354
 
355
        assign ni_credit_out[$tile_num]={V{1'b0}};
356
        assign ni_flit_out[$tile_num]={Fw{1'b0}};
357
        assign ni_flit_out_wr[$tile_num]=1'b0;
358
        ";
359
                add_text_to_string(\$socs_v,$soc_v);
360
 
361
                        }
362
 
363
        }}
364
 
365
    if($processors_en){
366
        add_text_to_string($io_v_ref,",\n\tprocessors_en");
367
        add_text_to_string($io_def_v,"\t input processors_en;");
368
 
369
    }
370
 
371
 
372
        return $socs_v;
373
 
374
}
375
 
376
##############
377
#       gen_soc_v
378
##############
379
 
380
 
381
 
382
sub   gen_soc_v{
383
        my ($mpsoc,$soc_name,$tile_num,$x,$y,$soc_num,$io_v_ref,$io_def_v)=@_;
384
        my $soc_v;
385
        my $processor_en=0;
386
        my $xw= log2($mpsoc->mpsoc_get_param("NX"));
387
        my $yw= log2($mpsoc->mpsoc_get_param("NY"));
388
        $soc_v="\n\n // Tile:$tile_num (x=$x,y=$y)\n   \t$soc_name #(\n";
389
 
390
        # core id
391
        add_text_to_string(\$soc_v,"\t\t.CORE_ID($tile_num)");
392
 
393
        # ni parameter
394
        my $top=$mpsoc->mpsoc_get_soc($soc_name);
395
        my @noc_param=$top->top_get_parameter_list('ni0');
396
        my $inst_name=$top->top_get_def_of_instance('ni0','instance');
397
 
398
        #other parameters
399
        my %params=$top->top_get_default_soc_param();
400
 
401
        foreach my $p (@noc_param){
402
                my $parm_next = $p;
403
                $parm_next =~ s/${inst_name}_//;
404
                my $param=  ",\n\t\t.$p($parm_next)";
405
                add_text_to_string(\$soc_v,$param);
406
        }
407
        foreach my $p (sort keys %params){
408
                my $parm_next= "${soc_name}_${soc_num}_$p";
409
                my $param=  ",\n\t\t.$p($parm_next)";
410
                add_text_to_string(\$soc_v,$param);
411
 
412
        }
413
 
414
        add_text_to_string(\$soc_v,"\n\t)the_${soc_name}_$soc_num(\n");
415
 
416
        my @intfcs=$top->top_get_intfc_list();
417
 
418
        my $i=0;
419
        foreach my $intfc (@intfcs){
420
 
421
                # ni intfc      
422
                if( $intfc eq 'socket:ni[0]'){
423
                        my @ports=$top->top_get_intfc_ports_list($intfc);
424
 
425
                        foreach my $p (@ports){
426
                                my($inst,$range,$type,$intfc_name,$intfc_port)= $top->top_get_port($p);
427
                                my $q=($intfc_port eq "current_x")? "$xw\'d$x" :
428
                                                                  ($intfc_port eq "current_y")? "$yw\'d$y" :"ni_$intfc_port\[$tile_num\]";
429
                                add_text_to_string(\$soc_v,',') if ($i);
430
                                add_text_to_string(\$soc_v,"\n\t\t.$p($q)");
431
                                $i=1;
432
 
433
 
434
                        }
435
                }
436
                # clk source
437
                elsif( $intfc eq 'plug:clk[0]'){
438
                        my @ports=$top->top_get_intfc_ports_list($intfc);
439
                        foreach my $p (@ports){
440
                                my($inst,$range,$type,$intfc_name,$intfc_port)= $top->top_get_port($p);
441
                                add_text_to_string(\$soc_v,',') if ($i);
442
                            add_text_to_string(\$soc_v,"\n\t\t.$p(clk)");
443
                            $i=1;
444
 
445
                        }
446
                }
447
                #reset
448
                elsif( $intfc eq 'plug:reset[0]'){
449
                        my @ports=$top->top_get_intfc_ports_list($intfc);
450
                        foreach my $p (@ports){
451
                                my($inst,$range,$type,$intfc_name,$intfc_port)= $top->top_get_port($p);
452
                                add_text_to_string(\$soc_v,',') if ($i);
453
                            add_text_to_string(\$soc_v,"\n\t\t.$p(reset)");
454
                            $i=1;
455
 
456
                        }
457
 
458
 
459
 
460
                }
461
                elsif( $intfc eq 'plug:enable[0]'){
462
                        my @ports=$top->top_get_intfc_ports_list($intfc);
463
                        foreach my $p (@ports){
464
                                my($inst,$range,$type,$intfc_name,$intfc_port)= $top->top_get_port($p);
465
                                add_text_to_string(\$soc_v,',') if ($i);
466
                            add_text_to_string(\$soc_v,"\n\t\t.$p(processors_en)");
467
                            $processor_en=1;
468
                            $i=1;
469
 
470
                        }
471
 
472
 
473
                }
474
                else {
475
                #other interface
476
                        my @ports=$top->top_get_intfc_ports_list($intfc);
477
                        foreach my $p (@ports){
478
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $top->top_get_port($p);
479
                        my $io_port="${soc_name}_${soc_num}_${p}";
480
                        #io name 
481
                        add_text_to_string($io_v_ref,",\n\t$io_port");
482
                        #io definition
483
                        my $new_range = add_instantc_name_to_parameters(\%params,"${soc_name}_$soc_num",$range);
484
                        #my $new_range=$range;
485
                        my $port_def=(length ($range)>1 )?      "\t$type\t [ $new_range    ] $io_port;\n": "\t$type\t\t\t$io_port;\n";
486
 
487
 
488
                        add_text_to_string($io_def_v,"$port_def");
489
                        add_text_to_string(\$soc_v,',') if ($i);
490
                        add_text_to_string(\$soc_v,"\n\t\t.$p($io_port)");
491
                        $i=1;
492
 
493
                        }
494
 
495
 
496
                }
497
 
498
 
499
        }
500
 
501
        add_text_to_string(\$soc_v,"\n\t);\n");
502
 
503
 
504
 
505
 
506
 
507
 
508
 
509
 
510
 
511
 
512
        return ($soc_v,$processor_en);
513
 
514
}
515
 
516
 
517
sub log2{
518
        my $num=shift;
519
        my $log=0;
520
        while( (1<<$log)  < $num) {
521
                                $log++;
522
        }
523
        return  $log;
524
}
525
 
526
 
527
1

powered by: WebSVN 2.1.0

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