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/] [compile.pl] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
#!/usr/bin/perl -w
2
use constant::boolean;
3 34 alirezamon
use strict;
4
use warnings;
5 43 alirezamon
 
6
use FindBin;
7
use lib $FindBin::Bin;
8
 
9 34 alirezamon
use soc;
10
 
11 43 alirezamon
 
12 34 alirezamon
use File::Path;
13
use File::Find::Rule;
14
use File::Copy;
15
use File::Copy::Recursive qw(dircopy);
16
use Cwd 'abs_path';
17
use Verilog::EditFiles;
18
 
19
 
20 48 alirezamon
 
21 34 alirezamon
use List::MoreUtils qw( minmax );
22
 
23
 
24
 
25
################
26 48 alirezamon
#       Compile
27 34 alirezamon
#################
28
 
29
 
30
 
31
sub is_capital_sensitive()
32
{
33
  my ($cell_layout, $cell, $tree_model, $iter, $data) = @_;
34
  my $sensitive = !$tree_model->iter_has_child($iter);
35
  $cell->set('sensitive', $sensitive);
36
}
37
 
38
 
39
 
40
sub get_range {
41
        my ($board,$self,$porttype,$assignname,$portrange,$portname) =@_;
42
        my $box= def_hbox(FALSE,0);
43
        my @range=$board->board_get_pin_range($porttype,$assignname);
44
 
45
 
46
        if ($range[0] ne '*undefine*'){
47
                my $content = join(",", @range);
48
                my ($min, $max) = minmax @range;
49
                if  (length($portrange)!=0){
50
                        my $range_hsb=gen_combobox_object($self,'compile_pin_range_hsb',$portname,$content,$max,undef,undef);
51
                        $box->pack_start( $range_hsb, FALSE, FALSE, 0);
52
                        $box->pack_start(gen_label_in_center(':'),, FALSE, FALSE, 0);
53
                }
54
 
55
                my $range_lsb=gen_combobox_object($self,'compile_pin_range_lsb',$portname,$content,$min,undef,undef);
56
                $box->pack_start( $range_lsb, FALSE, FALSE, 0);
57
 
58
        }
59
        return $box;
60
 
61
}
62
 
63
 
64 38 alirezamon
sub read_top_v_file{
65
        my $top_v=shift;
66 34 alirezamon
        my $board = soc->board_new();
67 38 alirezamon
        my $vdb=read_verilog_file($top_v);
68
        my @modules=sort $vdb->get_modules($top_v);
69
        my %Ptypes=get_ports_type($vdb,$modules[0]);
70
        my %Pranges=get_ports_rang($vdb,$modules[0]);
71
        foreach my $p (sort keys %Ptypes){
72
                my $Ptype=$Ptypes{$p};
73
                my $Prange=$Pranges{$p};
74
                my $type=($Ptype eq "input")? "Input" : ($Ptype eq "output")? 'Output' : 'Bidir';
75
                if (  $Prange ne ''){
76
                        my @r=split(":",$Prange);
77
                        my $a=($r[0]<$r[1])? $r[0] : $r[1];
78
                        my $b=($r[0]<$r[1])? $r[1] : $r[0];
79
                        for (my $i=$a; $i<=$b; $i++){
80
                                $board->board_add_pin ($type,"$p\[$i\]");
81
 
82
                        }
83 34 alirezamon
                }
84 38 alirezamon
                else {$board->board_add_pin ($type,$p);}
85
        }
86 34 alirezamon
        return $board;
87
}
88
 
89
 
90
 
91
 
92
sub gen_top_v{
93
        my ($self,$board,$name,$top)=@_;
94
 
95
        my $top_v=get_license_header("Top.v");
96
        #read port list 
97
        my $vdb=read_verilog_file($top);
98
        my %port_type=get_ports_type($vdb,"${name}_top");
99
        my %port_range=get_ports_rang($vdb,"${name}_top");
100
 
101
 
102
        my $io='';
103
        my $io_def='';
104
        my $io_assign='';
105
        my %board_io;
106
        my $first=1;
107
        foreach my $p (sort keys %port_type){
108
                my $porttype=$port_type{$p};
109
                my $portrange=$port_range{$p};
110
                my $assign_type = $self->object_get_attribute('compile_assign_type',$p);
111
                my $assign_name = $self->object_get_attribute('compile_pin',$p);
112
                my $range_hsb   = $self->object_get_attribute('compile_pin_range_hsb',$p);
113
                my $range_lsb   = $self->object_get_attribute('compile_pin_range_lsb',$p);
114
                my $assign="\t";
115
                if (defined $assign_name){
116
                        if($assign_name eq '*VCC'){
117
                                $assign= (length($portrange)!=0)? '{32{1\'b1}}' : '1\'b1';
118
                        } elsif ($assign_name eq '*GND'){
119
                                $assign= (length($portrange)!=0)? '{32{1\'b0}}' : '1\'b0';
120
                        }elsif ($assign_name eq '*NOCONNECT'){
121
                                $assign="\t";
122
 
123
                        }else{
124
 
125
                                $board_io{$assign_name}=$porttype;
126
 
127
 
128
                                my $range = (defined $range_hsb) ? "[$range_hsb : $range_lsb]" :
129
                                            (defined $range_lsb) ?  "[ $range_lsb]" : " ";
130
                                my $l=(defined $assign_type)?
131
                                        ($assign_type eq 'Direct') ? '' : '~' : '';
132
                                $assign="$l $assign_name $range";
133
 
134
 
135
                        }
136
                }
137
                $io_assign= ($first)? "$io_assign \t  .$p($assign)":"$io_assign,\n \t  .$p($assign)";
138
                $first=0;
139
        }
140
        $first=1;
141
        foreach my $p (sort keys %board_io){
142
                        $io=($first)? "\t$p" : "$io,\n\t$p";
143
                        my $dir=$board_io{$p};
144
                        my $range;
145
                        my $type= ($dir eq  'input') ? 'Input' :
146
                                  ($dir eq  'output')? 'Output' : 'Bidir';
147
                        my @r= $board->board_get_pin_range($type,$p);
148
                        if ($r[0] eq '*undefine*'){
149
                                $range="\t\t\t";
150
                        } else {
151
                                my ($min, $max) = minmax @r;
152
                                $range="\t[$max : $min]\t";
153
                        }
154
                        $io_def = "$io_def \t $dir $range $p;\n";
155
                        $first=0;
156
 
157
        }
158
        $top_v="$top_v
159
module Top (
160
$io
161
);
162
$io_def
163
 
164
        ${name}_top uut(
165
$io_assign
166
        );
167
 
168
 
169
endmodule
170
";
171
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
172
        my $board_top_file= "$fpath/Top.v";
173
        save_file($board_top_file,$top_v);
174
}
175
 
176
 
177
 
178
 
179
sub select_compiler {
180 38 alirezamon
        my ($self,$name,$top,$target_dir,$end_func)=@_;
181 34 alirezamon
        my $window = def_popwin_size(40,40,"Step 1: Select Compiler",'percent');
182 48 alirezamon
 
183 34 alirezamon
        my $table = def_table(2, 2, FALSE);
184
        my $col=0;
185
        my $row=0;
186
 
187 48 alirezamon
        my $compilers=$self->object_get_attribute('compile','compilers');#"QuartusII,Vivado,Verilator,Modelsim"
188 38 alirezamon
 
189
        my $compiler=gen_combobox_object ($self,'compile','type',$compilers,"QuartusII",undef,undef);
190 34 alirezamon
        $table->attach(gen_label_in_center("Compiler tool"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
191
        $table->attach($compiler,$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
192
        $row++;$col=0;
193
 
194 48 alirezamon
        my $old_board_name=$self->object_get_attribute('compile','board');
195
        my $old_compiler=$self->object_get_attribute('compile','type');
196
        my $vendor= ($old_compiler eq "QuartusII")? 'Altera' : 'Xilinx';
197 34 alirezamon
 
198 48 alirezamon
        #get the list of boards located in "boards/*" folder
199
        my @dirs = grep {-d} glob("../boards/$vendor/*");
200
        my ($fpgas,$init);
201
        foreach my $dir (@dirs) {
202
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
203
                $init=$name;
204
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
205
        }
206
 
207 34 alirezamon
 
208 48 alirezamon
        my $compiler_options =
209
                ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir,$vendor):
210
                ($old_compiler eq "Vivado"   )? select_board  ($self,$name,$top,$target_dir,$vendor):
211
                ($old_compiler eq "Modelsim" )? select_model_path  ($self,$name,$top,$target_dir):
212
                ($old_compiler eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
213
                gen_label_in_center(" ");
214
 
215 34 alirezamon
        $table->attach($compiler_options,$col,$col+2,$row,$row+1,'fill','shrink',2,2); $row++;
216
 
217
        $col=1;
218
        my $i;
219
        for ($i=$row; $i<5; $i++){
220
 
221
                my $temp=gen_label_in_center(" ");
222
                $table->attach_defaults ($temp, 0, 1 , $i, $i+1);
223
        }
224
        $row=$i;
225
 
226
 
227
        $window->add ($table);
228
        $window->show_all();
229 48 alirezamon
        my $next=def_image_button('icons/right.png','_Next',FALSE,1);
230 34 alirezamon
        $table->attach($next,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++;
231
        $next-> signal_connect("clicked" => sub{
232 48 alirezamon
                my $compiler_type=$self->object_get_attribute('compile','type');
233
                if($compiler_type eq "QuartusII" || $compiler_type eq "Vivado"){
234
                        $vendor= ($compiler_type eq "QuartusII")? 'Altera' : 'Xilinx';
235 34 alirezamon
                        my $new_board_name=$self->object_get_attribute('compile','board');
236
                        if(defined $old_board_name) {
237 38 alirezamon
                                if ($old_board_name ne $new_board_name){
238
                                        remove_pin_assignment($self);
239
                                        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
240
                                        #delete jtag_intfc.sh file
241
                                        unlink "${fpath}../sw/jtag_intfc.sh";
242
                                        #program_device.sh file  
243
                                        unlink "${fpath}../program_device.sh";
244
                                }
245
 
246 34 alirezamon
                                my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
247
                                my $board_top_file= "$fpath/Top.v";
248
                                unlink $board_top_file if ($old_board_name ne $new_board_name);
249
 
250
 
251
                        }
252 48 alirezamon
                        if($new_board_name eq "Add New Board") {add_new_fpga_board($self,$name,$top,$target_dir,$end_func,$vendor);}
253
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func,$vendor);}
254
                }
255
 
256
 
257
 
258
 
259
 
260
 
261
                elsif($compiler_type eq "Modelsim"){
262
                        modelsim_compilation($self,$name,$top,$target_dir,$vendor);
263 34 alirezamon
 
264
                }else{#verilator
265 48 alirezamon
                        verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
266 34 alirezamon
 
267
                }
268
 
269
                $window->destroy;
270
 
271
        });
272
 
273
        $compiler->signal_connect("changed" => sub{
274
                $compiler_options->destroy;
275
                my $new_board_name=$self->object_get_attribute('compile','type');
276 48 alirezamon
                $compiler_options =
277
                        ($new_board_name eq "QuartusII")? select_board  ($self,$name,$top,$target_dir,"Altera"):
278
                        ($new_board_name eq "Vivado")? select_board  ($self,$name,$top,$target_dir,"Xilinx"):
279
                        ($new_board_name eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
280
                        ($new_board_name eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
281
                        gen_label_in_center(" ");
282 34 alirezamon
                $table->attach($compiler_options,0,2,1,2,'fill','shrink',2,2);
283
                $table->show_all;
284
 
285
        });
286 48 alirezamon
 
287 34 alirezamon
}
288
 
289
 
290
 
291
 
292
 
293 48 alirezamon
 
294 34 alirezamon
sub select_board {
295 48 alirezamon
        my ($self,$name,$top,$target_dir,$vendor)=@_;
296 34 alirezamon
 
297
        #get the list of boards located in "boards/*" folder
298 48 alirezamon
        my @dirs = grep {-d} glob("../boards/$vendor/*");
299 34 alirezamon
        my ($fpgas,$init);
300 38 alirezamon
        $fpgas="Add New Board";
301
 
302 34 alirezamon
        foreach my $dir (@dirs) {
303
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
304 38 alirezamon
 
305
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
306
                $init="$name";
307 34 alirezamon
        }
308
        my $table = def_table(2, 2, FALSE);
309
        my $col=0;
310
        my $row=0;
311 48 alirezamon
    my $compiler = ($vendor eq "Altera")? 'quartus' : 'vivado';
312
    my $bin_name = "$compiler bin";
313
    my $env = ($vendor eq "Altera")? "QUARTUS_BIN" : "VIVADO_BIN";
314
        my $Fpga_bin=   $ENV{$env};
315 34 alirezamon
 
316
        my $old_board_name=$self->object_get_attribute('compile','board');
317 48 alirezamon
        $table->attach(gen_label_help("The list of supported boards are obtained from \"mpsoc/boards/$vendor\" path. You can add your boards by adding its required files in aformentioned path. Note that currently Altera and Xilinx FPGAs are supported.",'Targeted Board:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
318 34 alirezamon
        $table->attach(gen_combobox_object ($self,'compile','board',$fpgas,$init,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
319 48 alirezamon
        my $bin =  $self->object_get_attribute('compile',$bin_name);
320 34 alirezamon
 
321
        $col=0;
322 48 alirezamon
        $self->object_add_attribute('compile',$bin_name,$Fpga_bin) if (!defined $bin && defined $Fpga_bin);
323
        $table->attach(gen_label_help("Path to $vendor/bin directory. You can set a default path as $env environment variable in ~/.bashrc file.
324
e.g:  export $env=/home/alireza/$compiler/bin","$env:"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
325
        $table->attach(get_dir_in_object ($self,'compile',$bin_name,undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
326 34 alirezamon
 
327 48 alirezamon
 
328
 
329
 
330
 
331 34 alirezamon
        return $table;
332
 
333
}
334
 
335 48 alirezamon
 
336
 
337
 
338 34 alirezamon
sub select_model_path {
339
        my ($self,$name,$top,$target_dir)=@_;
340
 
341
 
342
        my $table = def_table(2, 2, FALSE);
343
        my $col=0;
344
        my $row=0;
345
 
346
 
347
 
348
 
349
        my $bin = $self->object_get_attribute('compile','modelsim_bin');
350
        my $modelsim_bin=  $ENV{MODELSIM_BIN};
351
        $col=0;
352
        $self->object_add_attribute('compile','modelsim_bin',$modelsim_bin) if (!defined $bin && defined $modelsim_bin);
353 48 alirezamon
        $table->attach(gen_label_help("Path to modelsim/bin directory. You can set a default path as MODELSIM_BIN environment variable in ~/.bashrc file.
354 34 alirezamon
e.g.  export MODELSIM_BIN=/home/alireza/altera/modeltech/bin",'Modelsim  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
355
        $table->attach(get_dir_in_object ($self,'compile','modelsim_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
356
 
357
        return $table;
358
 
359
}
360
 
361 56 alirezamon
my $cpu_num;
362 48 alirezamon
sub select_parallel_process_num {
363
        my ($self,$name,$top,$target_dir)=@_;
364
        my $table = def_table(2, 2, FALSE);
365
        my $col=0;
366
        my $row=0;
367
 
368
        #get total number of processor in the system
369
        my $cmd = "nproc\n";
370 56 alirezamon
        if(!defined $cpu_num){
371
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
372
                if(length $stderr>1){
373
                        #nproc command has failed. set default 4 paralel processor
374
 
375
                }else {
376
                        my ($number ) = $stdout =~ /(\d+)/;
377
                        if (defined  $number ){
378
                                $cpu_num =$number if  ($number > 0 );
379
                        }
380
                }
381 48 alirezamon
        }
382
        ($row,$col)= add_param_widget ($self,"Paralle run:" , "cpu_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of processors the Verilator can use at once to run parallel compilations/simulations", $table,$row,$col,1, 'compile', undef,undef,'vertical');
383
        return $table;
384
}
385 56 alirezamon
 
386 48 alirezamon
sub select_parallel_thread_num {
387
        my ($self,$name,$top,$target_dir)=@_;
388
        my $table = def_table(2, 2, FALSE);
389
        my $col=0;
390
        my $row=0;
391
 
392
        #get total number of processor in the system
393
        my $cmd = "nproc\n";
394 56 alirezamon
        if(!defined $cpu_num){
395
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
396
                if(length $stderr>1){
397
                        #nproc command has failed. set default 4 paralel processor
398
 
399
                }else {
400
                        my ($number ) = $stdout =~ /(\d+)/;
401
                        if (defined  $number ){
402
                                $cpu_num =$number if  ($number > 0 );
403
                        }
404
                }
405 48 alirezamon
        }
406
        ($row,$col)= add_param_widget ($self,"Thread run:" , "thread_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of threads the Verilator can use at once in one simulation", $table,$row,$col,1, 'compile', undef,undef,'vertical');
407
        return $table;
408
}
409
 
410
 
411
 
412
 
413 34 alirezamon
sub remove_pin_assignment{
414
        my $self=shift;
415
        $self->object_remove_attribute('compile_pin_pos');
416
        $self->object_remove_attribute('compile_pin');
417
        $self->object_remove_attribute('compile_assign_type');
418
        $self->object_remove_attribute('compile_pin_range_hsb');
419
        $self->object_remove_attribute('compile_pin_range_lsb');
420
}
421
 
422
 
423 38 alirezamon
 
424
sub add_new_fpga_board{
425 48 alirezamon
 
426
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
427
 
428
        my $window = def_popwin_size(50,80,"Add New $vendor FPGA Board",'percent');
429 38 alirezamon
        my $table = def_table(2, 2, FALSE);
430 48 alirezamon
        my $scrolled_win=add_widget_to_scrolled_win($table);
431 38 alirezamon
 
432
 
433
        my $mtable = def_table(10, 10, FALSE);
434
 
435
        my $next=def_image_button('icons/plus.png','Add');
436 48 alirezamon
        my $back=def_image_button('icons/left.png','Previous');
437 38 alirezamon
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
438 48 alirezamon
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2) if (defined $name);
439 38 alirezamon
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
440
 
441
 
442 48 alirezamon
        my ($Twin,$tview)=create_txview();
443 38 alirezamon
 
444
 
445 48 alirezamon
        my $widgets=
446
                ($vendor eq 'Altera')? add_new_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor):
447
                add_new_xilinx_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor,$tview);
448 43 alirezamon
 
449 48 alirezamon
 
450 38 alirezamon
 
451
        my $v1=gen_vpaned($widgets,0.3,$Twin);
452
 
453
        $table->attach_defaults($v1,0,3,0,2);
454
        #$table->attach_defaults( $Twin,0,3,1,2);       
455
 
456
 
457
 
458
 
459
        $back-> signal_connect("clicked" => sub{
460
 
461
                $window->destroy;
462
                select_compiler($self,$name,$top,$target_dir,$end_func);
463
 
464
        });
465
 
466
        $next-> signal_connect("clicked" => sub{
467 48 alirezamon
                my $result = ($vendor eq 'Altera')?
468
                        add_new_altera_fpga_board_files($self,$vendor):
469
                        add_new_xilinx_fpga_board_files($self,$vendor);
470
 
471 38 alirezamon
                if(! defined $result ){
472 48 alirezamon
                        select_compiler($self,$name,$top,$target_dir,$end_func) if (defined $name);
473 38 alirezamon
                        $window->destroy;
474 48 alirezamon
                        message_dialog("The new board has been added successfully!");
475 38 alirezamon
                }else {
476 48 alirezamon
                        show_info($tview," ");
477
                        show_colored_info($tview,$result,'red');
478
                }
479 38 alirezamon
 
480
        });
481
 
482 48 alirezamon
 
483
 
484
        if($vendor eq 'Altera'){
485
            my $auto=def_image_button('icons/advance.png','Auto-fill');
486
            set_tip($auto, "Auto-fill JTAG configuration. The board must be powered on and be connected to the PC.");
487
                $mtable->attach($auto,5,6,9,10,'shrink','shrink',2,2);
488
                $auto-> signal_connect("clicked" => sub{
489
                        my $pid;
490
                        my $hw;
491
 
492
                        my $project_dir   = get_project_dir();
493
                        my $command=  "$project_dir/mpsoc/src_c/jtag/jtag_libusb/list_usb_dev";
494
                        add_info($tview,"$command\n");
495
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
496
                        if(length $stderr>1){
497
                                add_colored_info($tview,"$stderr\n",'red');
498
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
499
                        }else {
500
 
501
                                if($exit){
502
                                        add_colored_info($tview,"$stdout\n",'red');
503
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
504 38 alirezamon
                                }else{
505 48 alirezamon
                                        add_info($tview,"$stdout\n");
506
                                        my @a=split /vid=9fb/, $stdout;
507
                                        if(defined $a[1]){
508
                                                my @b=split /pid=/, $a[1];
509
                                                my @c=split /\n/, $b[1];
510
                                                $pid=$c[0];
511
                                                $self->object_add_attribute('compile','quartus_pid',$pid);
512
                                                add_colored_info($tview,"Detected PID: $pid\n",'blue');
513
 
514
                                        }else{
515
                                                add_colored_info($tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
516
                                                return;
517
                                        }
518 38 alirezamon
                                }
519
                        }
520 48 alirezamon
 
521
 
522
                        $command=  "$ENV{QUARTUS_BIN}/jtagconfig";
523
                        add_info($tview,"$command\n");
524
                        ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
525
                        if(length $stderr>1){
526
                                add_colored_info($tview,"$stderr\n",'red');
527
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
528
                        }else {
529
 
530
                                if($exit){
531
                                        add_colored_info($tview,"$stdout\n",'red');
532
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
533
                                }else{
534
                                        add_info($tview,"$stdout\n");
535
                                        my @a=split /1\)\s+/, $stdout;
536
                                        if(defined $a[1]){
537
                                                my @b=split /\s+/, $a[1];
538
                                                $hw=$b[0];
539
                                                $self->object_add_attribute('compile','quartus_hardware',$hw);
540
                                                add_colored_info($tview,"Detected Hardware: $hw\n",'blue');
541
                                                my $qsf=$self->object_get_attribute('compile','board_confg_file');
542
                                                if(!defined $qsf ){
543
                                                        add_colored_info ($tview,"Cannot detect device location in JTAG chin. Please enter the QSF file or fill in manually \n",'red');
544
 
545
                                                }else{
546
                                                        #search for device name in qsf file
547
                                                        $qsf=add_project_dir_to_addr($qsf);
548
                                                        if (!(-f $qsf)){
549
                                                                add_colored_info($tview, "Error Could not find $qsf file!\n");
550
                                                                return;
551
                                                        }
552
                                                        my $str=load_file($qsf);
553
                                                        my $dw= capture_string_between(' DEVICE ',$str,"\n");
554
                                                        if(defined $dw){
555
                                                        add_colored_info($tview,"Device name in qsf file is: $dw\n",'blue');
556
                                                        @b=split /\n/, $a[1];
557
 
558
                                                        #capture device name in JTAG chain
559
                                                                my @f=(0);
560
                                                                foreach my $c (@b){
561
                                                                        my @e=split /\s+/, $c;
562
                                                                        push(@f,$e[2]) if(defined $e[2]);
563
                                                                }
564
 
565
                                                                my $pos=find_the_most_similar_position($dw ,@f);
566
                                                                $self->object_add_attribute('compile','quartus_device',$pos);
567
                                                        add_colored_info($tview,"$dw has the most similarity with $f[$pos] in JTAG chain\n",'blue');
568 38 alirezamon
 
569 48 alirezamon
 
570
                                                    }else{
571
                                                        add_colored_info ($tview, "Could not find device name in the $qsf file!\n");
572
                                                    }
573
 
574 38 alirezamon
                                                }
575
 
576
 
577 48 alirezamon
                                        }else{
578
                                                #add_colored_info($tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
579
 
580 38 alirezamon
                                        }
581
 
582
                                }
583
                        }
584 48 alirezamon
                        $widgets->destroy();
585
                        $widgets= add_new_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor);
586
                        $v1-> pack1($widgets, TRUE, TRUE);
587
                        #$table->attach_defaults($widgets,0,3,0,1); 
588
                        $table->show_all();
589
                 #      my $cmd=" $ENV{'QUARTUS_BIN'}"
590 38 alirezamon
 
591 48 alirezamon
                });
592
 
593
 
594
        }
595
 
596
 
597
 
598 38 alirezamon
 
599
        $window->add ($mtable);
600
        $window->show_all();
601
 
602
}
603
 
604
 
605
 
606 48 alirezamon
sub add_new_xilinx_fpga_board_widgets{
607
        my ($self,$name,$top,$target_dir,$end_func,$vendor,$tview)=@_;
608
        my $table = def_table(2, 2, FALSE);
609
 
610
        my $col=0;
611
        my $row=0;
612
 
613
        my $help1="Your given FPGA Board name. Do not use any space in given name";
614
        my $help2="Path to FPGA board xdc file. In your Xilinx board installation CD or in the Internet, search for a xdc file containing your FPGA device pin assignment constrain).";
615
        my $help3="Path to FPGA_board_top.v file. A Verilog file containing all your FPGA device IO ports.";
616
        my $help4="Your Board name (Board PART) e.g. digilentinc.com:arty-z7-20:part0:1.0";
617
        my $help5="Your FPGA device name (PART) e.g. xc7z020clg400-1 ";
618
        my $help6="The order number of target device in jtag chain. Run jtag targets after \"connect\" command in xsct terminal to list all available targets.";
619
        my $help7="Path to Vivado board files repository. E.g download the repo from https://github.com/Digilent/vivado-boards and save in \$ProNoC_work/toolchain/board_files folder.";
620
        my $help8="Hardware device name e.g. xc7z020_1. To find it you can connect your FPGA board to your PC. In tcl terminal run
621
                open_hw
622
                connect_hw_server
623
                open_hw_target
624
                get_hw_devices
625
It supposed to show the list of your hardware devices in your FPGA. Select the name represent your FPGA device
626
                ";
627
 
628
 
629
        my $repo ="$ENV{PRONOC_WORK}/toolchain/board_files";
630
 
631
 
632
        $row++;
633
 
634
        my @info = (
635
        { label=>"FPGA board display name:",        param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
636
        { label=>"Set board repo:", param_name=>'fpga_board_repo',  type=>"DIR_path", default_val=>"$repo", content=>undef, info=>$help7, param_parent=>'compile',ref_delay=>undef},
637
        { label=>"FPGA board part name:", param_name=>'fpga_board_part', type=>"EntryCombo",default_val=>undef, content=>undef, info =>$help4, param_parent=>'compile', ref_delay=> undef},
638
        { label=>"FPGA part name:",       param_name=>'fpga_part', type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
639
    { label=>"FPGA Hardware device name:", param_name=>'fpga_hw_device', type=>"EntryCombo", default_val=>undef, content=>undef, info=>$help8, param_parent=>'compile', ref_delay=> undef},
640
        { label=>"Target device JTAG chain order number", param_name=>'fpga_board_order',  type=>"Spin-button", default_val=>1, content=>"0,256,1", info=>$help6, param_parent=>'compile',ref_delay=>undef},
641
        { label=>'FPGA board xdc file:',    param_name=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"xdc", info=>$help2, param_parent=>'compile', ref_delay=>undef},
642
        { label=>"FPGA board golden top Verilog file", param_name=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef},
643
                );
644
        my %widgets;
645
        my %rows;
646
        foreach my $d (@info) {
647
                $rows{$d->{param_name}} =$row;
648
                ($row,$col,$widgets{$d->{param_name}})=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,'vertical');
649
        }
650
 
651
        my $icon = 'icons/advance.png';
652
        my $search=def_image_button($icon,undef);
653
        my $search_board=def_image_button ($icon,undef);
654
        my $search_dev=def_image_button ($icon,undef);
655
        my $search_chain=def_image_button ($icon,undef);
656
 
657
        $table->attach($search,4,5,$rows{'fpga_board_part'},$rows{'fpga_board_part'}+1,'fill','shrink',2,2);
658
        $table->attach($search_board,4,5,$rows{'fpga_part'},$rows{'fpga_part'}+1,'fill','shrink',2,2);
659
        $table->attach($search_dev,4,5,$rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+1,'fill','shrink',2,2);
660
        $table->attach($search_chain,4,5,$rows{'fpga_board_order'},$rows{'fpga_board_order'}+1,'fill','shrink',2,2);
661
 
662
 
663
        $search->signal_connect("clicked" => sub{
664
                        my $load= show_gif("icons/load.gif");
665
                        $table->attach ($load,5, 6, $rows{'fpga_board_part'},$rows{'fpga_board_part'}+ 1,'shrink','shrink',0,0);
666
                        $table->show_all;
667
                        my $result=     set_xilinx_board_from_repo($self,$tview);
668
                        update_combo_entry_content($widgets{'fpga_board_part'}, $result);
669
                        $load->destroy;
670
                        $table->show_all;
671
                });
672
 
673
 
674
        $search_board->signal_connect("clicked" => sub{
675
                        my $load= show_gif("icons/load.gif");
676
                        $table->attach ($load,5, 6, $rows{'fpga_part'},$rows{'fpga_part'}+1, 'shrink','shrink',0,0);
677
                        $table->show_all;
678
                        my $result=     get_xilinx_board_part($self,$tview);
679
                        $widgets{'fpga_part'}->set_text($result);
680
                        #print "result = $result\n";
681
                        $load->destroy;
682
                        $table->show_all;
683
                });
684
        $search_dev->signal_connect("clicked" => sub{
685
                        my $load= show_gif("icons/load.gif");
686
                        $table->attach ($load,5, 6, $rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+ 1,'shrink','shrink',0,0);
687
                        $table->show_all;
688
                        my $result=     get_xilinx_device_names($self,$tview);
689
                        update_combo_entry_content($widgets{'fpga_hw_device'}, $result);
690
                        $load->destroy;
691
                        $table->show_all;
692
                });
693
        $search_chain->signal_connect("clicked" => sub{
694
                my $targets = show_all_xilinx_targets($self,$tview);
695
                if(!defined $targets){
696
                        add_info($tview,"Unable to find the FPGA board target list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
697
                        return;
698
                }
699
 
700
                my @lines=split(/\r?\n/,$targets);
701
                my @list1;
702
                my @list2;
703
                foreach my $p (@lines){
704
                        $p =~ s/^\s+//;#left trim
705
                        my @words=split(/\s+/,$p);
706
                        push (@list1,$words[0]);
707
                        push (@list2,$words[1]);
708
                }
709
                my $hw =  $self->object_get_attribute('compile','fpga_hw_device');
710
                if( !defined $hw){
711
                        add_colored_info($tview,"Please define the FPGA hardware device name first!\n",'red');
712
                        return;
713
                }
714
                my $pos = find_the_most_similar_position ($hw ,@list2);
715
                add_info($tview,"$hw matched with target $list1[$pos] $list2[$pos]  ");
716
                $widgets{'fpga_board_order'}->set_value($list1[$pos]);
717
        });
718
 
719
        return ($row, $col, $table);
720
}
721 38 alirezamon
 
722 48 alirezamon
 
723
 
724
sub set_xilinx_board_from_repo{
725
        my ($self,$tview)=@_;
726
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
727
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
728
        my $result;
729
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
730
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_boards.tcl -tclargs $repo";
731
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
732
 
733
        add_info($tview,"$command\n");
734
        my $stdout=run_cmd_textview_errors($command,$tview);
735
        return if (!defined $stdout);
736
        add_info($tview,"$stdout\n");
737
        my @boards=split(/\s+/,$stdout);
738
        my $r=0;
739
        foreach my $board (@boards){
740
                my @pp=split(':',$board);
741
                if(scalar @pp  == 4 && $pp[1] =~ /[a-zA-Z]+/) {
742
                        $r=1;
743
                        $result= (!defined $result)? "$board" : $result.",$board";
744
                }
745
        }
746
        add_colored_info($tview,"$stdout\n",'red') if($r==0);
747
        return $result;
748
}
749
 
750
 
751
sub get_xilinx_device_names{
752
        my ($self,$tview)=@_;
753
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
754
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
755
        my $result;
756
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
757
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_hw_device.tcl -tclargs";
758
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
759
 
760
        add_info($tview,"$command\n");
761
        my $stdout=run_cmd_textview_errors($command,$tview);
762
        if (!defined $stdout){
763
                add_info($tview,"Unable to find the FPGA board devices list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
764
                return;
765
        }
766
        add_info($tview,"$stdout\n");
767
        my $devices =  capture_string_between ('\n\*RESULT:',$stdout,"\n");
768
        my @D=split(/\s+/,$devices);
769
        return join ',', @D;
770
}
771
 
772
 
773
 
774
 
775
 
776
 
777
sub get_xilinx_board_part{
778
        my ($self,$tview)=@_;
779
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
780
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
781
        my $result;
782
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
783
        my $board_part= $self->object_get_attribute('compile' ,'fpga_board_part');
784
        if (!defined $board_part  ){
785
                add_colored_info($tview,"Please define the FPGA board part name first!\n",'red');
786
                return;
787
        }
788
 
789
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_part.tcl -tclargs $board_part $repo ";
790
 
791
 
792
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
793
 
794
        add_info($tview,"$command\n");
795
        my $stdout=run_cmd_textview_errors($command,$tview);
796
        return if (!defined $stdout);
797
        add_info($tview,"$stdout\n");
798
        return capture_string_between ('\n\*RESULT:',$stdout,"\n");
799
}
800
 
801
 
802
 
803
sub add_new_altera_fpga_board_widgets{
804
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
805 38 alirezamon
        my $table = def_table(2, 2, FALSE);
806
 
807
        my $help1="FPGA Board name. Do not use any space in given name";
808
        my $help2="Path to FPGA board qsf file. In your Altra board installation CD or in the Internet search for a QSF file containing your FPGA device name with other necessary global project setting including the pin assignments (e.g DE10_Nano_golden_top.qsf).";
809 48 alirezamon
        my $help3="Path to FPGA_board_top.v file. In your Altra board installation CD or in the Internet search for a Verilog file containing all your FPGA device IO ports (e.g DE10_Nano_golden_top.v).";
810
        my $help4="FPGA Board USB-Blaster product ID (PID). Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find PID. Optionally you can run mpsoc/
811 38 alirezamon
src_c/jtag/jtag_libusb/list_usb_dev to find your USB-Blaster PID. Search for PID of a device having 9fb (altera) Vendor ID (VID)";
812 48 alirezamon
        my $help5="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your hardware name. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your programming hardware name.
813 38 alirezamon
an example of output from the 'jtagconfig' command:
814
\t  1) ByteBlasterMV on LPT1
815
\t       090010DD   EPXA10
816
\t       049220DD   EPXA_ARM922
817
or
818
\t   1) DE-SoC [1-3]
819
\t       48A00477   SOCVHP5
820
\t       02D020DC   5CS(EBA6ES|XFC6c6ES)
821
ByteBlasterMV \& DE-SoC are the programming hardware name.";
822 48 alirezamon
my $help6="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your device location in jtag chain. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your target device location in jtag chain.";
823 38 alirezamon
 
824
 
825
 
826
 
827
        my @info = (
828 48 alirezamon
        { label=>"FPGA Board Name:",                   param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
829
        { label=>'FPGA Board Golden top QSF file:',    param_name=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"qsf", info=>$help2, param_parent=>'compile', ref_delay=>undef},
830
        { label=>"FPGA Board Golden top Verilog file", param_name=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef },
831 38 alirezamon
        );
832
 
833
        my @usb = (
834 48 alirezamon
        { label=>"FPGA Board USB Blaster PID:",        param_name=>'quartus_pid',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help4, param_parent=>'compile', ref_delay=> undef},
835
        { label=>"FPGA Board Programming Hardware Name:", param_name=>'quartus_hardware',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
836
        { label=>"FPGA Board Device location in JTAG chain:", param_name=>'quartus_device',   type=>"Spin-button",     default_val=>0, content=>"0,100,1", info=>$help6, param_parent=>'compile', ref_delay=> undef},
837 38 alirezamon
        );
838
 
839
 
840
        my $col=0;
841
        my $row=0;
842
        foreach my $d (@info) {
843
                ($row,$col)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,"vertical");
844
        }
845
 
846 48 alirezamon
        my $labl=def_pack_vbox(FALSE, 0,(gen_Hsep(),gen_label_in_center("FPGA Board JTAG Configuration"),gen_Hsep()));
847 38 alirezamon
 
848
        $table->attach( $labl,0,3,$row,$row+1,'fill','shrink',2,2); $row++; $col=0;
849
 
850
        foreach my $d (@usb) {
851
                ($row,$col)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,"vertical");
852
        }
853
 
854
 
855
        return ($row, $col, $table);
856
}
857
 
858
 
859 48 alirezamon
sub add_new_xilinx_fpga_board_files{
860
        my ($self,$vendor)=@_;
861
        #check the board name
862
        my $board_name=$self->object_get_attribute('compile','fpga_board');
863
        return "Please define the Board Name\n" if(! defined $board_name );
864
        return "Please define the Board Name\n" if(length($board_name) ==0 );
865
        my $r=check_verilog_identifier_syntax($board_name);
866
        return "Error in given Board Name: $r\n" if(defined $r );
867
 
868
        #check xdc file 
869
        my $xdc=$self->object_get_attribute('compile','board_confg_file');
870
        return "Please define the xdc file\n" if(!defined $xdc );
871
        $xdc=add_project_dir_to_addr($xdc);
872
 
873
        #check v file 
874
        my $top=$self->object_get_attribute('compile','fpga_board_v');
875
        return "Please define the verilog file file\n" if(!defined $top );
876
        $top=add_project_dir_to_addr($top);
877
 
878
        #check board part 
879
        my $part=$self->object_get_attribute('compile','fpga_part');
880
        my $board_part=$self->object_get_attribute('compile','fpga_board_part');
881
        return "Please define at least one of FPGA board part or FPGA part names"if(!defined $part && !defined $board_part  );
882
 
883
        #make board directory
884
        my $project_dir = get_project_dir();
885
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
886
        mkpath($path,1,01777);
887
        return "Error cannot make $path path" if ((-d $path)==0);
888
        copy( $xdc,"$path/$board_name.xdc");
889
        copy($top,"$path/$board_name.v");
890
 
891 38 alirezamon
 
892 48 alirezamon
 
893
        my $a=$self->object_get_attribute('compile','fpga_board_order');
894
        my $jtag_intfc="#!/bin/bash
895
JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_xilinx_xsct -a $a -b 36\"
896
#it works only for 32-bit jtag data width for 64 pass -b 68
897
";
898
        save_file ("$path/jtag_intfc.sh",$jtag_intfc);
899
 
900
 
901
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
902
    my $hw_dev=$self->object_get_attribute('compile',"fpga_hw_device");
903
    my $repo=  $self->object_get_attribute('compile','fpga_board_repo');
904
 
905
 
906
        my $tcl="proc set_project_properties { } {\n";
907
        if(-d $repo){
908
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [list \"$repo\"] [current_project]\n";
909
        }else {
910
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [get_property LOCAL_ROOT_DIR [xhub::get_xstores xilinx_board_store]] [current_project]\n" if(defined $board_part);
911
        }
912
        $tcl=$tcl."\tset_property \"part\" \"$part\" [current_project]\n" if(defined $part);
913
        $tcl=$tcl."\tset_property \"board_part\" \"$board_part\" [current_project]\n" if(defined $board_part);
914
        $tcl=$tcl."\tset_property \"default_lib\" \"xil_defaultlib\" [current_project]\n}\n";
915 38 alirezamon
 
916
 
917
 
918 48 alirezamon
        if (defined $hw_dev){
919
$tcl=$tcl."\n
920
proc program_board {bit_file} {
921
        open_hw
922
        connect_hw_server
923
        open_hw_target
924
        set_property PROGRAM.FILE \$bit_file [get_hw_devices $hw_dev]
925
        program_hw_devices [get_hw_devices $hw_dev]
926
        refresh_hw_device [get_hw_devices $hw_dev]
927
}
928
";
929
        }
930
        save_file ("$path/board_property.tcl",$tcl);
931
 
932
 
933
        $self->object_add_attribute('compile','board',$board_name);
934
        return undef;
935
 
936
 
937
}
938
 
939
 
940
sub add_new_altera_fpga_board_files{
941
        my ($self,$vendor)=@_;
942
 
943 38 alirezamon
        #check the board name
944 48 alirezamon
        my $board_name=$self->object_get_attribute('compile','fpga_board');
945 38 alirezamon
        return "Please define the Board Name\n" if(! defined $board_name );
946
        return "Please define the Board Name\n" if(length($board_name) ==0 );
947
        my $r=check_verilog_identifier_syntax($board_name);
948
        return "Error in given Board Name: $r\n" if(defined $r );
949
 
950
        #check qsf file 
951 48 alirezamon
        my $qsf=$self->object_get_attribute('compile','board_confg_file');
952 38 alirezamon
        return "Please define the QSF file\n" if(!defined $qsf );
953
 
954
        #check v file 
955 48 alirezamon
        my $top=$self->object_get_attribute('compile','fpga_board_v');
956 38 alirezamon
        return "Please define the verilog file file\n" if(!defined $top );
957
 
958
        #check PID
959
        my $pid=$self->object_get_attribute('compile','quartus_pid');
960
        return "Please define the PID\n" if(! defined $pid );
961
        return "Please define the PID\n" if(length($pid) ==0 );
962
 
963
        #check Hardware name
964
        my $hw=$self->object_get_attribute('compile','quartus_hardware');
965
        return "Please define the Hardware Name\n" if(! defined $hw );
966
        return "Please define the Hardware Name\n" if(length($hw) ==0 );
967
 
968
 
969
        #check Device name name
970
        my $dw=$self->object_get_attribute('compile','quartus_device');
971
        return "Please define targeted Device location in JTAG chain. The device location must be larger than zero.\n" if( $dw == 0 );
972
 
973
 
974
 
975
        #make board directory
976 48 alirezamon
        my $project_dir = get_project_dir();
977
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
978 38 alirezamon
        mkpath($path,1,01777);
979
        return "Error cannot make $path path" if ((-d $path)==0);
980
 
981
        #generate new qsf file
982
        $qsf=add_project_dir_to_addr($qsf);
983
        $top=add_project_dir_to_addr($top);
984
        open my $file, "<", $qsf or return "Error Could not open $qsf file in read mode!";
985
        open my $newqsf, ">", "$path/$board_name.qsf" or return "Error Could not create $path/$board_name.qsf file in write mode!";
986
 
987
        #remove the lines contain following strings
988
        my @p=("TOP_LEVEL_ENTITY","VERILOG_FILE","SYSTEMVERILOG_FILE","VHDL_FILE","AHDL_FILE","PROJECT_OUTPUT_DIRECTORY" );
989
        while (my $line = <$file>){
990
                if ($line =~ /\Q$p[0]\E/ || $line =~ /\Q$p[1]\E/ || $line =~ /\Q$p[2]\E/ ||  $line =~ /\Q$p[3]\E/ ||  $line =~ /\Q$p[4]\E/){#dont copy the line contain TOP_LEVEL_ENTITY
991
 
992
                }
993
 
994
                else{
995
                        print $newqsf $line;
996
                }
997
 
998
        }
999
        print $newqsf "\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files\n";
1000
 
1001
        close $newqsf;
1002
        close $file;
1003
        copy($top,"$path/$board_name.v");
1004
 
1005
        #generate jtag_intfc.sh
1006
        open $file, ">", "$path/jtag_intfc.sh" or return "Error: Could not create $path/jtag_intfc.sh file in write mode!";
1007
        my $jtag;
1008
        if($pid eq 6001 || $pid eq 6002 || $pid eq 6003){
1009
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_libusb -a \$PRODUCT_ID\"";
1010
 
1011
        }else{
1012
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_quartus_stp -a \$HARDWARE_NAME -b \$DEVICE_NAME\"";
1013
 
1014
        }
1015 45 alirezamon
        print $file "#!/bin/bash
1016 38 alirezamon
 
1017
PRODUCT_ID=\"0x$pid\"
1018
HARDWARE_NAME=\'$hw *\'
1019
DEVICE_NAME=\"\@$dw*\"
1020
 
1021
$jtag
1022
 
1023
        ";
1024
        close $file;
1025
 
1026
 
1027
        #generate program_device.sh
1028
        open $file, ">", "$path/program_device.sh" or return "Error: Could not create $path/program_device.sh file in write mode!";
1029
 
1030
 
1031 45 alirezamon
print $file "#!/bin/bash
1032 38 alirezamon
 
1033
#usage:
1034 45 alirezamon
#       bash program_device.sh  programming_file.sof
1035 38 alirezamon
 
1036
#programming file
1037
#given as an argument:  \$1
1038
 
1039
#Programming mode
1040
PROG_MODE=jtag
1041
 
1042
#cable name. Connect the board to ur PC and then run jtagconfig in terminal to find the cable name
1043
NAME=\"$hw\"
1044
 
1045
#device name
1046
DEVICE=\@$dw".'
1047
 
1048
 
1049
#programming command
1050
if [ -n "${QUARTUS_BIN+set}" ]; then
1051
  $QUARTUS_BIN/quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
1052
else
1053
  quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
1054
fi
1055
';
1056
 
1057
close $file;
1058
$self->object_add_attribute('compile','board',$board_name);
1059
 
1060
        return undef;
1061
}
1062
 
1063 48 alirezamon
 
1064
 
1065
 
1066
 
1067 34 alirezamon
sub  get_pin_assignment{
1068 48 alirezamon
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
1069 34 alirezamon
        my $window = def_popwin_size(80,80,"Step 2: Pin Assignment",'percent');
1070
 
1071
        my $table = def_table(2, 2, FALSE);
1072 48 alirezamon
        my $scrolled_win = add_widget_to_scrolled_win($table);
1073 34 alirezamon
 
1074 48 alirezamon
        my $mtable = def_table(10, 10, FALSE);
1075 34 alirezamon
        my $next=def_image_button('icons/right.png','Next');
1076
        my $back=def_image_button('icons/left.png','Previous');
1077
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
1078
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
1079
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
1080 38 alirezamon
 
1081
        my $board_name=$self->object_get_attribute('compile','board');
1082 42 alirezamon
 
1083 38 alirezamon
        #copy board jtag_intfc.sh file 
1084
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
1085 48 alirezamon
        copy("../boards/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
1086 43 alirezamon
        my $m= $self->object_get_attribute('mpsoc_name',undef);
1087
        if(defined $m){ # we are compiling a complete NoC-based mpsoc                                           
1088
                 my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
1089
         for (my $tile_num=0;$tile_num<$ne;$tile_num++){
1090
                    #print "$tile_num\n";
1091 42 alirezamon
                        my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
1092
                        next if(!defined $soc_name);
1093 48 alirezamon
                        copy("../boards/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
1094 43 alirezamon
                }
1095 42 alirezamon
 
1096
        }
1097
 
1098
 
1099 34 alirezamon
 
1100 38 alirezamon
        #copy board program_device.sh file 
1101 48 alirezamon
        copy("../boards/$vendor/$board_name/program_device.sh","${fpath}../program_device.sh");
1102 34 alirezamon
 
1103
        #get boards pin list
1104 48 alirezamon
        my $top_v= "../boards/$vendor/$board_name/$board_name.v";
1105
 
1106 38 alirezamon
        if(!-f $top_v){
1107 48 alirezamon
                message_dialog("Error: Could not load the board pin list. The $top_v does not exist!",'error');
1108 34 alirezamon
                $window->destroy;
1109
        }
1110 38 alirezamon
 
1111
        my $board=read_top_v_file($top_v);
1112 34 alirezamon
 
1113
        # Write object file
1114
        #open(FILE,  ">lib/soc/tttttttt") || die "Can not open: $!";
1115
        #print FILE Data::Dumper->Dump([\%$board],['board']);
1116
        #close(FILE) || die "Error closing file: $!";
1117
 
1118
        my @dirs = ('Input', 'Bidir', 'Output');
1119
        my %models;
1120
        foreach my $p (@dirs){
1121
                my %pins=$board->board_get_pin($p);
1122
                $models{$p}=gen_combo_model(\%pins);
1123
 
1124
        }
1125
 
1126
        my $row=0;
1127
        my $col=0;
1128 48 alirezamon
        my @labels= ('Port Direction','Port Range     ','Port name      ','Assignment Type','Board Port name ','Board Port Range');
1129
        foreach my $p (@labels){
1130 34 alirezamon
                my $l=gen_label_in_left($p);
1131
                $l->set_markup("<b>  $p    </b>");
1132
                $table->attach ($l, $col,$col+1, $row, $row+1,'fill','shrink',2,2);
1133
                $col++
1134
        }
1135
        $row++;
1136
 
1137
 
1138
        #read port list 
1139
        my $vdb=read_verilog_file($top);
1140
        my %port_type=get_ports_type($vdb,"${name}_top");
1141
        my %port_range=get_ports_rang($vdb,"${name}_top");
1142
        my %param = $vdb->get_modules_parameters("${name}_top");
1143
 
1144
        foreach my $p (sort keys %port_type){
1145
                my $porttype=$port_type{$p};
1146
                my $portrange=$port_range{$p};
1147
 
1148
                if  (length($portrange)!=0){
1149
                        #replace parameter with their values            
1150
                        my @a= split (/\b/,$portrange);
1151 42 alirezamon
 
1152 34 alirezamon
                        foreach my $l (@a){
1153
                                my $value=$param{$l};
1154
                                if(defined $value){
1155
                                        chomp $value;
1156
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
1157 42 alirezamon
                                #       print"($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l})\n";
1158 34 alirezamon
                                }
1159
                        }
1160 48 alirezamon
 
1161
                        my($s1,$s2)=split (":",$portrange);
1162
                        {
1163
                                no warnings 'numeric';
1164
                                $s1 = eval $s1;
1165
                                $s2 = eval $s2;
1166
                        }
1167
                        $portrange = "[ $portrange ]" ;
1168
                    if(defined $s1 && defined $s2 ){
1169
                        $portrange = "" if($s1 eq 0 && $s2 eq 0);                  #the upper and lower range are equal zero so remove it                         
1170
                        }
1171 34 alirezamon
                }
1172
 
1173
                my $label1= gen_label_in_left("  $porttype");
1174 48 alirezamon
                my $label2= gen_label_in_left("  $portrange");
1175 34 alirezamon
                my $label3= gen_label_in_left("  $p");
1176
 
1177
                $table->attach($label1, 0,1, $row, $row+1,'fill','shrink',2,2);
1178
                $table->attach($label2, 1,2, $row, $row+1,'fill','shrink',2,2);
1179
                $table->attach($label3, 2,3, $row, $row+1,'fill','shrink',2,2);
1180
 
1181
                my $assign_type= "Direct,Negate(~)";
1182
                if ($porttype eq  'input') {
1183
                        my $assign_combo=gen_combobox_object($self,'compile_assign_type',$p,$assign_type,'Direct',undef,undef);
1184
                        $table->attach( $assign_combo, 3,4, $row, $row+1,'fill','shrink',2,2);
1185
                }
1186
 
1187
                my $type= ($porttype eq  'input') ? 'Input' :
1188
                          ($porttype eq  'output')? 'Output' : 'Bidir';
1189
 
1190
                my $combo= gen_tree_combo($models{$type});
1191
                my $saved=$self->object_get_attribute('compile_pin_pos',$p);
1192
                my $box;
1193
                my $loc=$row;
1194
                if(defined $saved) {
1195
                          my @indices=@{$saved};
1196 48 alirezamon
                          my $path = TreePath_new_from_indices(@indices);
1197 34 alirezamon
                          my $iter = $models{$type}->get_iter($path);
1198
                          undef $path;
1199
                          $combo->set_active_iter($iter);
1200
                          $box->destroy if(defined $box);
1201
                          my $text=$self->object_get_attribute('compile_pin',$p);
1202
                          $box=get_range ($board,$self,$type,$text,$portrange,$p);
1203
                          $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
1204
                }
1205 43 alirezamon
 
1206 34 alirezamon
 
1207
                $combo->signal_connect("changed" => sub{
1208
 
1209
                        #get and saved new value
1210
                        my $treeiter=  $combo->get_active_iter();
1211
                        my $text = $models{$type}->get_value($treeiter, 0);
1212
                        $self->object_add_attribute('compile_pin',$p,$text);
1213
                        #get and saved value position in model
1214
                        my $treepath = $models{$type}->get_path ($treeiter);
1215
                        my @indices=   $treepath->get_indices();
1216
                        $self->object_add_attribute('compile_pin_pos',$p,\@indices);
1217
                        #update borad port range
1218
                        $box->destroy if(defined $box);
1219
                        $box=get_range ($board,$self,$type,$text,$portrange,$p);
1220
                        $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
1221
                        $table->show_all;
1222
 
1223
                });
1224
 
1225
                $table->attach($combo, 4,5, $row, $row+1,'fill','shrink',2,2);
1226
 
1227
                $row++;
1228
 
1229
        }
1230
        $next-> signal_connect("clicked" => sub{
1231
 
1232
                $window->destroy;
1233 48 alirezamon
                fpga_compilation($self,$board,$name,$top,$target_dir,$end_func,$vendor);
1234 34 alirezamon
 
1235
        });
1236
        $back-> signal_connect("clicked" => sub{
1237
 
1238
                $window->destroy;
1239 48 alirezamon
                select_compiler($self,$name,$top,$target_dir,$end_func,$vendor);
1240 34 alirezamon
 
1241
        });
1242
 
1243
 
1244
        $window->add ($mtable);
1245
        $window->show_all();
1246
}
1247
 
1248
 
1249
 
1250
 
1251
 
1252 48 alirezamon
sub fpga_compilation{
1253
        my ($self,$board,$name,$top,$target_dir,$end_func,$vendor)=@_;
1254 38 alirezamon
 
1255
        my $run=def_image_button('icons/gate.png','Compile');
1256 34 alirezamon
        my $back=def_image_button('icons/left.png','Previous');
1257 38 alirezamon
        my $regen=def_image_button('icons/refresh.png','Regenerate Top.v');
1258
        my $prog=def_image_button('icons/write.png','Program the board');
1259 34 alirezamon
 
1260
 
1261
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
1262
        my $board_top_file ="${fpath}Top.v";
1263
        unless (-e $board_top_file ){
1264
                gen_top_v($self,$board,$name,$top) ;
1265
        }
1266
 
1267
        my ($app,$table,$tview,$window) = software_main($fpath,'Top.v');
1268
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
1269
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
1270 43 alirezamon
        $table->attach ($run,6, 7, 1,2,'shrink','shrink',2,2);
1271 38 alirezamon
        $table->attach($prog,9,10,1,2,'shrink','shrink',2,2);
1272 34 alirezamon
 
1273
 
1274 38 alirezamon
 
1275 34 alirezamon
        $regen-> signal_connect("clicked" => sub{
1276 48 alirezamon
 
1277
                my $response =  yes_no_dialog("Are you sure you want to regenerate the Top.v file? Note that any changes you have made will be lost");
1278
                if ($response eq 'yes') {
1279
                        gen_top_v($self,$board,$name,$top);
1280
                        $app->refresh_source("$board_top_file");
1281
                }
1282 34 alirezamon
        });
1283
 
1284
 
1285
 
1286
        $back-> signal_connect("clicked" => sub{
1287
 
1288
                $window->destroy;
1289 48 alirezamon
                get_pin_assignment($self,$name,$top,$target_dir,$end_func,$vendor);
1290 34 alirezamon
 
1291
        });
1292
 
1293
 
1294
        #compile
1295 43 alirezamon
        $run-> signal_connect("clicked" => sub{
1296
                my $load= show_gif("icons/load.gif");
1297
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',2,2);
1298
                $load->show_all;
1299 48 alirezamon
 
1300 34 alirezamon
                set_gui_status($self,'save_project',1);
1301 48 alirezamon
                $app->ask_to_save_changes();
1302
 
1303
                quartus_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor) if($vendor eq 'Altera');
1304
                xilinx_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)  if($vendor eq 'Xilinx');
1305
 
1306
                $load->destroy;
1307
 
1308
        });
1309 34 alirezamon
 
1310
 
1311 48 alirezamon
        #Programe the board 
1312
        $prog-> signal_connect("clicked" => sub{
1313
                quartus_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Altera');
1314
                vivado_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Xilinx');
1315
        });
1316 34 alirezamon
 
1317 48 alirezamon
}
1318 34 alirezamon
 
1319 48 alirezamon
sub vivado_program_the_board {
1320
        my      ($self,$tview,$target_dir,$name,$vendor) =@_;
1321
 
1322
        my $bit_file="$target_dir/Vivado/xilinx_compile/${name}.runs/impl_1/Top.bit";
1323
 
1324
 
1325
 
1326
        unless (-f "$target_dir/Vivado/program_board.tcl"){
1327
        #create tcl file
1328
        my $xpr = "\$tcl_path/xilinx_compile/${name}.xpr";
1329
        my $tcl="
1330
#Get tcl shell path relative to current script
1331
set tcl_path    [file dirname [info script]]
1332
 
1333
set projectName $name
1334
 
1335
source \"\$tcl_path/board_property.tcl\"
1336
set projectXpr \"$xpr\"
1337
#Open project
1338
open_project   \$projectXpr
1339
program_board \"\$tcl_path/xilinx_compile/${name}.runs/impl_1/Top.bit\"
1340
close_project
1341
exit
1342
 
1343
        ";
1344
        save_file ("$target_dir/Vivado/program_board.tcl",$tcl);
1345
        add_info($tview,"File $target_dir/Vivado/program_board.tcl is created\n");
1346
        }
1347
 
1348
        #check bit file existance
1349
        unless (-f $bit_file){
1350
                add_colored_info($tview,"Could not find $bit_file. Click on project Compile button first and make sure it runs successfully.",'red');
1351
                return
1352
        }
1353
 
1354
 
1355
        #run vivado using program_board.tcl
1356
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/program_board.tcl");
1357
        add_colored_info($tview,"Board is programmed successfully!\n",'blue') if($error==0);
1358
 
1359
 
1360
}
1361
 
1362
 
1363
 
1364
 
1365
sub quartus_program_the_board{
1366
        my ($self,$tview,$target_dir,$name,$vendor)=@_;
1367
        my $error = 0;
1368
        my $sof_file="$target_dir/Quartus/output_files/${name}.sof";
1369
        my $bash_file="$target_dir/program_device.sh";
1370
 
1371
        add_info($tview,"Program the board using Quartus_pgm and $sof_file file\n");
1372
        #check if the programming file exists
1373
        unless (-f $sof_file) {
1374
                add_colored_info($tview,"\tThe $sof_file does not exists! Make sure you have compiled the code successfully.\n", 'red');
1375
                $error=1;
1376
        }
1377
        #check if the program_device.sh file exists
1378
        unless (-f $bash_file) {
1379
                add_colored_info($tview,"\tThe $bash_file does not exist! This file varies depending on your target board and must be available inside mpsoc/boards/$vendor/[board_name].\n", 'red');
1380
                $error=1;
1381
        }
1382
        return if($error);
1383
        my $command = "bash $bash_file $sof_file";
1384
        add_info($tview,"$command\n");
1385
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
1386
        if(length $stderr>1){
1387
                add_colored_info($tview,"$stderr\n",'red');
1388
                add_colored_info($tview,"Board was not programmed successfully!\n",'red');
1389
        }else {
1390
                if($exit){
1391
                        add_colored_info($tview,"$stdout\n",'red');
1392
                        add_colored_info($tview,"Board was not programmed successfully!\n",'red');
1393
                }else{
1394
                        add_info($tview,"$stdout\n");
1395
                        add_colored_info($tview,"Board is programmed successfully!\n",'blue');
1396 34 alirezamon
                }
1397 48 alirezamon
 
1398
        }
1399
}
1400 34 alirezamon
 
1401
 
1402 48 alirezamon
sub quartus_run_compile{
1403
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
1404
 
1405
        my $error = 0;
1406
        add_info($tview,"CREATE: start creating Quartus project in $target_dir/Quartus folder\n");
1407
 
1408
        mkpath("$target_dir/Quartus",1,01777);
1409
 
1410
        #get list of source file
1411
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
1412
        my @files = File::Find::Rule->file()
1413
                          ->name( '*.v','*.V','*.sv' )
1414
                          ->in( "$target_dir/src_verilog" );
1415
 
1416
        #make sure source files have key word 'module' 
1417
        my @sources;
1418
        foreach my $p (@files){
1419
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
1420
        }
1421
        foreach my $p (@files){
1422
                push (@sources,$p)      if(check_file_has_string($p,'module'));
1423
        }
1424
        my $files = join ("\n",@sources);
1425
        add_info($tview,"$files\n");
1426
 
1427
        #creat project qsf file
1428
        my $qsf_file="$target_dir/Quartus/${name}.qsf";
1429
        save_file ($qsf_file,"# Generated using ProNoC\n");
1430
 
1431
        #append global assignets to qsf file
1432
        my $board_name=$self->object_get_attribute('compile','board');
1433
        my @qsfs =   glob("../boards/$vendor/$board_name/*.qsf");
1434
        if(!defined $qsfs[0]){
1435
                message_dialog("Error: ../boards/$vendor/$board_name folder does not contain the qsf file.!",'error');
1436
                $window->destroy;
1437
        }
1438
 
1439
        my $assignment_file =  $qsfs[0];
1440 34 alirezamon
 
1441 48 alirezamon
        if(-f $assignment_file){
1442
                merg_files ($assignment_file,$qsf_file);
1443
        }
1444
 
1445
        my %paths;
1446
 
1447
        #add the list of source fils to qsf file
1448
        my $s="\n\n\n set_global_assignment -name TOP_LEVEL_ENTITY Top\n";
1449
        foreach my $p (@sources){
1450
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
1451
                $s="$s set_global_assignment -name VERILOG_FILE $p\n" if ($suffix eq ".v");
1452
                $s="$s set_global_assignment -name SYSTEMVERILOG_FILE $p\n" if ($suffix eq ".sv");
1453
                $paths{$path}=1;
1454
        }
1455
 
1456
 
1457
 
1458
 
1459
 
1460
 
1461
        foreach my $p (sort keys %paths){
1462
                $s="$s set_global_assignment -name SEARCH_PATH  $p\n";
1463
        }
1464
 
1465
        append_text_to_file($qsf_file,$s);
1466
        add_info($tview,"\n Qsf file has been created\n");
1467
 
1468
 
1469
 
1470
 
1471
        #start compilation
1472
        my $Quartus_bin= $self->object_get_attribute('compile','quartus bin');
1473
        my @qfiles = ("quartus_map","quartus_fit","quartus_asm","quartus_sta");
1474
        foreach my $f (@qfiles){
1475
                unless(-f "$Quartus_bin/$f" ){
1476
                        $error=1;
1477
                        add_colored_info($tview, "$Quartus_bin/$f No such file or directory\n",'red');
1478
                        last;
1479 34 alirezamon
                }
1480
 
1481 48 alirezamon
        }
1482
 
1483
        my $run_sh = "#!/bin/bash
1484
$Quartus_bin/quartus_map --64bit $name --read_settings_files=on
1485
$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on
1486
$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on
1487
$Quartus_bin/quartus_sta --64bit $name
1488
        ";
1489
 
1490
        save_file("$target_dir/Quartus/run.sh",  $run_sh);
1491
 
1492
        add_info($tview, "Start Quartus compilation.....\n");
1493
        my @compilation_command =(
1494
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
1495
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
1496
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
1497
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_sta --64bit $name; echo \$? > status; sleep 1 ' ");
1498
 
1499
                foreach my $cmd (@compilation_command){
1500
                        last if($error);
1501
                add_info($tview,"$cmd\n");
1502
                unlink "$target_dir/Quartus/status";
1503
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout( $cmd);
1504
                if($exit){
1505
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
1506
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
1507
                        $error=1;
1508
                        last;
1509
                }
1510
 
1511
                open(my $fh,  "<$target_dir/Quartus/status") || die "Can not open: $!";
1512
                read($fh,my $status,1);
1513
                close($fh);
1514
                if("$status" != "0"){
1515
                        ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/Quartus/output_files/\" \n grep -h \"Error (\" *");
1516
                        add_colored_info($tview,"$stderr\n",'red') if(defined $stderr);
1517
                        add_colored_info($tview,"$stdout\n",'red');
1518
                        $error=1;
1519
                        last;
1520
                }
1521
        }
1522
        add_colored_info($tview,"Quartus compilation failed !\n",'red') if($error==1);
1523
        add_colored_info($tview,"Quartus compilation is done successfully in $target_dir/Quartus!\n", 'blue') if($error==0);
1524
        if (defined $end_func){
1525
                if ($error==0){
1526
                        $end_func->($self);
1527
                        $window->destroy;
1528
                }else {
1529
                        message_dialog("Error in Quartus compilation!",'error');
1530 34 alirezamon
                }
1531 48 alirezamon
        }
1532
 
1533 34 alirezamon
 
1534 48 alirezamon
 
1535
}
1536
 
1537
 
1538
 
1539
 
1540
 
1541
 
1542
sub xilinx_run_compile{
1543
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
1544
 
1545
        add_info($tview,"CREATE: start creating Vivado project in $target_dir/Vivado\n");
1546
        #get list of source file
1547
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
1548
        my @files = File::Find::Rule->file()
1549
                          ->name( '*.v','*.V','*.sv' )
1550
                          ->in( "$target_dir/src_verilog" );
1551
 
1552
        #make sure source files have key word 'module' 
1553
        my @sources;
1554
        foreach my $p (@files){
1555
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
1556
        }
1557
        foreach my $p (@files){
1558
                push (@sources,$p)      if(check_file_has_string($p,'module'));
1559
        }
1560
 
1561
        my %paths;
1562
        foreach my $p (@files){
1563
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
1564
                #print "$path\n";
1565
                my $remove="$target_dir/";
1566
                $path =~ s/$remove//;
1567
                $paths{$path}=1;
1568
        }
1569
 
1570
 
1571
 
1572
 
1573
        my $incdir="set include_dir_list [list";
1574
        foreach my $p (sort keys %paths){
1575
                $incdir.=" \$Dir/$p";
1576
         }
1577
        $incdir.="]";
1578
 
1579
        my $files = join ("\n",@sources);
1580
 
1581
 
1582
 
1583
        #add mem initial file to sources
1584
        my $mem_files="";
1585
        my @initial_files = File::Find::Rule->file()
1586
                          ->name( '*.mem')
1587
                          ->in( "$target_dir/sw" );
1588
        mkpath("$target_dir/Vivado/xilinx_mem",1,01777) unless -f "$target_dir/Vivado/xilinx_mem";
1589
        foreach my $f   (@initial_files){
1590
                #       /home/alireza/work/hca_git/mpsoc_work/SOC/mor1k_soc/sw/RAM/ram0.mif  fpr soc
1591
                #   /home/alireza/work/hca_git/mpsoc_work/MPSOC/newAdder/sw/tile0/RAM/ram0.mif fpr mpsoc
1592
                my @m = split('\/sw\/',$f );
1593
                my $d = $m[-1];#take the last file path name after /sw/
1594
                $d=~ s/RAM//g; #remove RAM
1595
                $d=~ s/\///g; #remove /
1596
                $d = "tile0".$d unless($m[-1]=~/^tile/); #add tile0 to soc
1597
                copy($f,"$target_dir/Vivado/xilinx_mem/$d");
1598
                $mem_files="$mem_files \$tcl_path/xilinx_mem/$d";
1599
        }
1600
        add_info($tview,"HDL sources:\n$files\nMem sources:\n$mem_files\n");
1601
        #make tcl file
1602
        my $tcl="
1603
#Get tcl shell path relative to current script
1604
set tcl_path    [file dirname [info script]]
1605
set Dir \"\$tcl_path/..\"
1606
";
1607
 
1608
        $tcl=$tcl."set projectName $name";
1609
 
1610
        $tcl =$tcl."
1611
source \"\$tcl_path/board_property.tcl\"
1612
#Create output directory and clear contents
1613
set outputdir \"\$tcl_path/xilinx_compile\"";
1614
        $tcl =$tcl.'
1615
file mkdir $outputdir
1616
set files [glob -nocomplain "$outputdir/*"]
1617
if {[llength $files] != 0} {
1618
    puts "deleting contents of $outputdir"
1619
    file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
1620
} else {
1621
    puts "$outputdir is empty"
1622
}
1623
 
1624
#Create project
1625
create_project  $projectName $outputdir
1626
 
1627
set_project_properties
1628
 
1629
#add source files to Vivado project
1630
';
1631
 
1632
        #get top level port names
1633
        #get boards pin list
1634
        my $top_v= "$target_dir/src_verilog/Top.v";
1635
        if(!-f $top_v){
1636
                message_dialog("Error: Could not load the board pin list. The Top.v does not exist!",'error');
1637
                $window->destroy;
1638
        }
1639
 
1640
 
1641
        my @ports=verilog_file_get_ports_list(read_verilog_file($top_v),"Top");
1642
 
1643
        #get board tcl
1644
        my $board_name=$self->object_get_attribute('compile','board');
1645
        my @tcls= glob("../boards/$vendor/$board_name/*.tcl");
1646
        foreach my $f (@tcls){
1647
                copy($f,"$target_dir/Vivado");
1648
        }
1649
 
1650
        #get board xdc
1651
        my @xdcs= glob("../boards/$vendor/$board_name/*.xdc");
1652
        my $i=1;
1653 34 alirezamon
 
1654 48 alirezamon
        foreach my $f (@xdcs){
1655
                my $out="";
1656
                #capture file content
1657
                my $string= load_file($f);
1658
                my @lines=split('\n',$string);
1659
                #make sure lines describing the port name are not comment
1660
                foreach my $l (@lines){
1661
                        foreach my $p (@ports){
1662
 
1663
                                $l=~ s/^\s*#/ /g if($l =~ /^\s*#/   && $l =~  /\[\s*get_ports\s*[{\s]\s*$p[\s\[\]\}]/ );#             /\[get_ports\s*{\s*$p[\s\}\[]/);
1664
 
1665 38 alirezamon
                        }
1666 48 alirezamon
                        $out=$out."$l\n";
1667
                }
1668
                my ($fname,$fpath,$fsuffix) = fileparse("$f",qr"\..[^.]*$");
1669
                my $xdc_file = "$target_dir/Vivado/$fname.xdc";
1670
                #save new xdc file
1671
                save_file($xdc_file,$out);
1672
                #add xdc to tcl file
1673
                $tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/$fname.xdc\n";
1674
                $i++;
1675
        }
1676 34 alirezamon
 
1677 48 alirezamon
        #internal clock constrain
1678
        my $clk_xdc=get_clk_constrain_file($self);
1679
        #save_file ("$target_dir/clk.xdc",$clk_xdc);
1680
        #$tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/clk.xdc\n";
1681 34 alirezamon
 
1682
 
1683 48 alirezamon
 
1684
        $tcl =$tcl."add_files ";
1685
        #add hdl sources
1686
        foreach my $f (@sources){
1687
                my $p =cut_dir_path($f,'src_verilog');
1688
                $tcl =$tcl." \$Dir/src_verilog/$p ";
1689
        }
1690
        $tcl =$tcl."\n";
1691
 
1692
        $tcl =$tcl."#add memory initial files to Vivado project
1693
        add_files -norecurse $mem_files" if(length($mem_files)>3);
1694
 
1695
 
1696
        $tcl =$tcl."\n set_property \"top\"  \"Top\" [current_fileset]\n";
1697
        $tcl =$tcl."
1698
        update_compile_order -fileset sources_1
1699
        #launch synthesis
1700
 
1701
        # Make all reset syncron
1702
        set_property verilog_define {{SYNC_RESET_MODE}} [current_fileset]
1703
 
1704
        # include source dirs
1705
        $incdir
1706
        set_property include_dirs  \$include_dir_list [current_fileset]
1707
 
1708
        launch_runs synth_1
1709
        wait_on_run synth_1
1710
        #Run implementation and generate bitstream
1711
        set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]
1712
        launch_runs impl_1 -to_step write_bitstream
1713
        wait_on_run impl_1
1714
        puts \"Implementation done!\"
1715
        ";
1716
 
1717
 
1718
        $tcl =$tcl."\nexit";
1719
        #creat make_project tcl file
1720
        save_file ("$target_dir/Vivado/make_project.tcl",$tcl);
1721
 
1722
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/make_project.tcl");
1723
        add_colored_info($tview,"Vivado compilation is done successfully in $target_dir/Vivado!\n", 'blue') if($error==0);
1724
        if (defined $end_func){
1725
                if ($error==0){
1726
                        $end_func->($self);
1727
                        $window->destroy;
1728
                }else {
1729
                        message_dialog("Error in Vivado compilation!",'error');
1730 38 alirezamon
                }
1731 48 alirezamon
        }
1732
 
1733
 
1734
}
1735
 
1736
 
1737
sub run_vivado {
1738
        my ($self,$target_dir,$tview,$tcl)=@_;
1739
        my $error=0;
1740
        #start compilation
1741
        my $vivado_bin= $self->object_get_attribute('compile','vivado bin');
1742
        add_info($tview, "Start compilation using vivado.....\n");
1743
        my @compilation_command =(
1744
                "cd \"$target_dir/Vivado/\" \n xterm -e bash -c '$vivado_bin/vivado -mode tcl -source $tcl'"
1745
        );
1746
 
1747
        save_file("$target_dir/Vivado/run.sh",  "#!/bin/bash \n $vivado_bin/vivado -mode tcl -source $tcl");
1748
 
1749
 
1750
        my $log="$target_dir/Vivado/vivado.log";
1751
        #unlink $log;
1752
 
1753
        foreach my $cmd (@compilation_command){
1754
                add_info($tview,"$cmd\n");
1755
 
1756
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout( $cmd);
1757
                if($exit){
1758 38 alirezamon
                        $error=1;
1759 48 alirezamon
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
1760
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
1761 38 alirezamon
                }
1762 48 alirezamon
 
1763
        }
1764
 
1765
        #check vivado.log for error
1766
        my $r;
1767
        open my $fd, "<" , $log or $r=$!;
1768
        if(defined $r ) {
1769
                add_colored_info($tview, "could not open $log to check errors: $r\n",'red');
1770
                $error=1;
1771
        }
1772
        else{
1773
 
1774
                #check error
1775
                while (my $line = <$fd>) {
1776
                        chomp $line;
1777
                        if( $line =~ /ERROR:/){
1778
                                add_colored_info($tview, "$line\n",'red');
1779
                                $error=1;
1780 38 alirezamon
                        }
1781 48 alirezamon
                }
1782
 
1783
                #check warning
1784
                close($fd);
1785
                open $fd, "<" , $log;
1786
                #print  "$log\n";
1787
                if($error==0){
1788
                        while (my $line = <$fd>) {
1789
                                chomp $line;
1790
                                if( $line =~ /^\s*WARNING:/){
1791
                                        add_info($tview, "$line\n");
1792
 
1793
                                }
1794
                        }
1795
                }
1796
 
1797
                #check critical warning
1798
                close($fd);
1799
                open $fd, "<" , $log;
1800
                #print  "$log\n";
1801
                if($error==0){
1802
                        while (my $line = <$fd>) {
1803
                                chomp $line;
1804
                                if( $line =~ /^\s*CRITICAL WARNING:/){
1805
                                        add_colored_info($tview, "$line\n",'green');
1806
                                }
1807
                        }
1808
                }
1809
                close($fd);
1810
        }
1811
        return $error;
1812 34 alirezamon
}
1813
 
1814
 
1815
 
1816
 
1817
 
1818
sub modelsim_compilation{
1819 48 alirezamon
        my ($self,$name,$top,$target_dir,$vendor)=@_;
1820 34 alirezamon
        #my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
1821
 
1822
 
1823 48 alirezamon
        my $run=def_image_button('icons/run.png','_run',FALSE,1);
1824 34 alirezamon
        my $back=def_image_button('icons/left.png','Previous');
1825
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
1826 48 alirezamon
 
1827
 
1828
        #creat modelsim dir
1829
 
1830
        my $model="$target_dir/Modelsim";
1831
        unlink("$model/model.tcl");
1832
        rmtree("$target_dir/rtl_work");
1833
        mkpath("$model/rtl_work",1,01777);
1834
 
1835
        my ($app,$table,$tview,$window) = software_main("$target_dir/Modelsim",undef);
1836 34 alirezamon
        #create testbench.v
1837 48 alirezamon
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir,$tview) unless (-f "$target_dir/Modelsim/testbench.v");
1838
        $app->refresh_source("$target_dir/Modelsim/testbench.v");
1839 34 alirezamon
 
1840
 
1841 48 alirezamon
 
1842
        add_info($tview,"create Modelsim dir in $target_dir\n");
1843 34 alirezamon
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
1844
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
1845
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
1846
 
1847
 
1848
 
1849
        $regen-> signal_connect("clicked" => sub{
1850 48 alirezamon
                my $response =  yes_no_dialog("Are you sure you want to regenerate the testbench.v file? Note that any changes you have made will be lost");
1851
                if ($response eq 'yes') {
1852
                        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir,$tview);
1853
                        $app->refresh_source("$target_dir/Modelsim/testbench.v");
1854
                }
1855 34 alirezamon
        });
1856
 
1857
        $back-> signal_connect("clicked" => sub{
1858
 
1859
                $window->destroy;
1860
                select_compiler($self,$name,$top,$target_dir);
1861
 
1862
        });
1863
 
1864 48 alirezamon
        #Get the list of  all verilog files in src_verilog folder
1865
        add_info($tview,"Get the list of all Verilog files in src_verilog folder\n");
1866
        my @files = File::Find::Rule->file()
1867
                ->name( '*.v','*.V','*.sv' )
1868
                ->in( "$target_dir/src_verilog" );
1869
 
1870
        #get list of all verilog files in src_sim folder 
1871
    my @sim_files = File::Find::Rule->file()
1872
                ->name( '*.v','*.V','*.sv' )
1873
                ->in( "$target_dir/src_sim" );
1874
        push (@files, @sim_files);
1875
        #add testnemch.v
1876
        push (@files, "$target_dir/Modelsim/testbench.v");
1877 34 alirezamon
 
1878 48 alirezamon
        #create a file list
1879
        my $tt =create_file_list($target_dir,\@files,'modelsim');
1880
        save_file("$target_dir/Modelsim/file_list.f",  "$tt");
1881
 
1882
 
1883 34 alirezamon
        #create modelsim.tcl file
1884
my $tcl="#!/usr/bin/tclsh
1885
 
1886
 
1887
transcript on
1888
if {[file exists rtl_work]} {
1889
        vdel -lib rtl_work -all
1890
}
1891
vlib rtl_work
1892
vmap work rtl_work
1893
 
1894
 
1895 48 alirezamon
vlog  +acc=rn  -F $target_dir/Modelsim/file_list.f
1896
 
1897 34 alirezamon
vsim -t 1ps  -L rtl_work -L work -voptargs=\"+acc\"  testbench
1898
 
1899
add wave *
1900
view structure
1901
view signals
1902
run -all
1903
";
1904 48 alirezamon
        add_info($tview,"Create model.tcl, run.sh files\n");
1905
        save_file ("$model/model.tcl",$tcl);
1906
        my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
1907
        my $cmd="cd $target_dir/Modelsim; rm -Rf rtl_work; $modelsim_bin/vsim -do $model/model.tcl";
1908
        save_file ("$model/run.sh",'#!/bin/bash'."\n".$cmd);
1909
 
1910 34 alirezamon
        $run -> signal_connect("clicked" => sub{
1911
                set_gui_status($self,'save_project',1);
1912 48 alirezamon
                $app->ask_to_save_changes();
1913 42 alirezamon
 
1914 48 alirezamon
 
1915
                add_info($tview,"$cmd\n");
1916 34 alirezamon
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
1917 38 alirezamon
                if(length $stderr>1){
1918 48 alirezamon
                        add_colored_info($tview,"$stderr\n","red");
1919 38 alirezamon
 
1920 34 alirezamon
                }else {
1921 48 alirezamon
                        add_info($tview,"$stdout\n");
1922 34 alirezamon
                }
1923
 
1924
        });
1925
 
1926
        #$window->show_all();
1927
}
1928
 
1929
 
1930 38 alirezamon
# source files : $target_dir/src_verilog
1931
# work dir : $target_dir/src_verilog
1932 34 alirezamon
 
1933 48 alirezamon
 
1934
sub create_file_list {
1935
        my ($target_dir,$files_ref, $platform)=@_;
1936
        my @ff=@{$files_ref} if(defined $files_ref);
1937
        my $pakages="";
1938
        my $file_list="";
1939
        my $include="";
1940
 
1941
        my %paths;
1942
        my @files = File::Find::Rule->file()
1943
                ->name( '*.v','*.V','*.sv','*.vh')
1944
            ->in( @ff );
1945
 
1946
    @ff =uniq( @ff);
1947
 
1948
        foreach my $file (@files) {
1949
                my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
1950
                #print "$path\n";
1951
                my $remove="$target_dir/";
1952
                $path =~ s/$remove//;
1953
                $paths{$path}=1;
1954
 
1955
                #put packages at the top of the list 
1956
                if(check_file_has_string($file,'endpackage')){
1957
                        $pakages.="../${path}${name}$suffix\n" if($platform eq 'modelsim');
1958
                        $pakages.="./${name}$suffix\n" if($platform eq 'verilator');
1959
                } else{
1960
                        $file_list.= "../${path}${name}$suffix\n"if($platform eq 'modelsim');
1961
                        $file_list.= "./${name}$suffix\n"if($platform eq 'verilator');
1962
                }
1963
        }
1964
         foreach my $p (sort keys %paths){
1965
                $include.="+incdir+../$p\n";
1966
         }
1967
 
1968
        return "$include\n$pakages\n$file_list";
1969
}
1970
 
1971
 
1972 34 alirezamon
sub verilator_compilation {
1973 48 alirezamon
        my ($top_ref,$target_dir,$outtext,$cpu_num)=@_;
1974
        $cpu_num = 1 if (!defined $cpu_num);
1975 38 alirezamon
        my %tops = %{$top_ref};
1976 34 alirezamon
        #creat verilator dir
1977 48 alirezamon
        add_info($outtext,"create verilator dir in $target_dir\n");
1978 34 alirezamon
        my $verilator="$target_dir/verilator";
1979
 
1980 48 alirezamon
        rmtree("$verilator");
1981
        mkpath("$verilator",1,01777);
1982
 
1983 43 alirezamon
        my @ff = ("$target_dir/src_verilog");
1984
        push (@ff,"$target_dir/src_verilator") if (-d "$target_dir/src_verilator");
1985 48 alirezamon
        push (@ff,"$target_dir/src_sim") if (-d "$target_dir/src_sim");
1986 43 alirezamon
 
1987 48 alirezamon
        #create a file list
1988
        add_info($outtext,"make a file list containig all RTL modules\n");
1989
        my $tt =create_file_list($target_dir,\@ff,'verilator');
1990
        save_file("$verilator/file_list.f",  "$tt");
1991 34 alirezamon
 
1992 48 alirezamon
        #check if -Wno-TIMESCALEMOD flag is supported"
1993
    my $flag="";
1994
 #   my $cmd ="verilator --version | head -n1 | cut -d\" \" -f2";
1995
  #     my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
1996
 
1997
   #    my $current_v=$stdout;
1998
   #    $current_v =~ s/[^0-9.]//g;
1999
   #    if (defined $current_v){
2000
   #            $cmd = "printf \'%s\n\' \"4.0.0\" \"$current_v\" | sort -V | head -n1";
2001
   #            my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2002
   #            $stdout =~ s/[^0-9.]//g;
2003
   #            if ($stdout eq "4.0.0" ){
2004
   #                    add_info($outtext, "Verilator vesrion $current_v is Greater than or equal to 4.0.0. So compile with -Wno-TIMESCALEMOD flag\n");
2005
   #                    $flag.="-Wno-TIMESCALEMOD";
2006
   #            }else{
2007
   #                    add_info($outtext, "Verilator vesrion is $current_v\n");
2008
   #            }
2009
   #    }
2010
  my $pdir        = get_project_dir();
2011
  my $tmp = "$pdir/mpsoc/perl_gui/lib/verilog/tmp.v";
2012
  my $cmd = "verilator --lint-only $tmp  -Wno-TIMESCALEMOD";
2013
  my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2014
 
2015
  if(length $stderr>1){ #-Wno-TIMESCALEMOD not supported                
2016
                #add_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
2017
  }else {
2018
                #add_info($outtext,"compile verilator with -Wno-TIMESCALEMOD\n");
2019
                $flag.="-Wno-TIMESCALEMOD";
2020
  }
2021 42 alirezamon
 
2022 34 alirezamon
        #run verilator
2023 48 alirezamon
        my $jobs=0; #a counter to limit the number of paralle process 
2024
        my $make_lib="";
2025
        $cmd="cd \"$verilator\"; ";
2026
        my $vrun="#!/bin/bash
2027
cd \"$verilator\"
2028
";
2029 45 alirezamon
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e bash -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
2030 48 alirezamon
        my $length = scalar (keys %tops);
2031 38 alirezamon
        foreach my $top (sort keys %tops) {
2032 48 alirezamon
                add_colored_info($outtext,"Generate $top Verilator model from $tops{$top} file\n",'green');
2033
                $cmd.= "verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 & ";
2034
                $vrun.="verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 &\n";
2035
 
2036
                $make_lib.="make lib$jobs &\n";
2037
                $jobs++;
2038
 
2039
                if( $jobs % $cpu_num == 0 || $jobs == $length){
2040
                        $vrun.="wait\n"; $make_lib.="wait\n"; $cmd.="wait\n";
2041
                        add_info($outtext,"$cmd\n");
2042
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2043
                        if(length $stderr>1){
2044
                                add_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
2045
                        }else {
2046
                                add_info($outtext,"$stdout\n");
2047
                        }
2048
                        $cmd="cd \"$verilator\"; ";
2049 38 alirezamon
                }
2050
        }
2051
 
2052 34 alirezamon
 
2053 48 alirezamon
 
2054 34 alirezamon
        #check if verilator model has been generated 
2055 38 alirezamon
        foreach my $top (sort keys %tops) {
2056 48 alirezamon
 
2057
                $vrun.="
2058
if ! [ -f $verilator/obj_dir/$top.cpp ]; then
2059
        echo  \"Failed to generate: $verilator/obj_dir/$top.cpp \"
2060
        exit 1
2061
fi
2062
";
2063
 
2064
                if (-f "$verilator/obj_dir/$top.cpp"){#succsess
2065 38 alirezamon
 
2066 42 alirezamon
 
2067 38 alirezamon
                }else {
2068
                        return 0;
2069
                }
2070
        }
2071 42 alirezamon
        #generate makefile
2072 48 alirezamon
        gen_verilator_makefile($top_ref,"$verilator/obj_dir/Makefile");
2073
 
2074
$vrun.="        echo  \"Verilator modules are generated successfully\".
2075 38 alirezamon
 
2076 48 alirezamon
cd $verilator/obj_dir/
2077 38 alirezamon
 
2078 48 alirezamon
#run make file
2079
$make_lib
2080
 
2081
make sim
2082
#done
2083
";
2084 38 alirezamon
 
2085
 
2086 48 alirezamon
        save_file ("$verilator/verilate.sh",$vrun);
2087
        #copy topology connection header files
2088
        my $project_dir = get_project_dir();
2089
        $project_dir= "$project_dir/mpsoc";
2090
        my $src_verilator_dir="$project_dir/src_verilator";
2091
        my @files = File::Find::Rule->file()
2092
                ->name( '*.h')
2093
            ->in( "$src_verilator_dir" );
2094
        copy_file_and_folders (\@files,$project_dir,"$verilator/obj_dir/");
2095 38 alirezamon
 
2096 48 alirezamon
        return 1;
2097
}
2098 38 alirezamon
 
2099
 
2100
 
2101
 
2102 42 alirezamon
 
2103 38 alirezamon
sub verilator_compilation_win {
2104 48 alirezamon
        my ($self,$name,$top,$target_dir,$vendor)=@_;
2105 38 alirezamon
        my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
2106
        my $mtable = def_table(10, 10, FALSE);
2107 48 alirezamon
        my ($outbox,$outtext)= create_txview();
2108 43 alirezamon
 
2109
 
2110 38 alirezamon
        my $next=def_image_button('icons/run.png','Next');
2111
        my $back=def_image_button('icons/left.png','Previous');
2112 43 alirezamon
        my $load= show_gif("icons/load.gif");
2113
        $mtable->attach($load,8,9,9,10,'shrink','shrink',2,2);
2114 38 alirezamon
 
2115
        $mtable->attach_defaults ($outbox ,0, 10, 4,9);
2116
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
2117 43 alirezamon
 
2118 38 alirezamon
 
2119
 
2120
 
2121
        $back-> signal_connect("clicked" => sub{
2122
 
2123
                $window->destroy;
2124
                select_compiler($self,$name,$top,$target_dir);
2125
 
2126
        });
2127
        $next-> signal_connect("clicked" => sub{
2128
 
2129
                $window->destroy;
2130 48 alirezamon
                verilator_testbench($self,$name,$top,$target_dir,$vendor);
2131 38 alirezamon
 
2132
        });
2133 42 alirezamon
 
2134
        $window->add ($mtable);
2135
        $window->show_all();
2136
 
2137
 
2138
        my $result;
2139 48 alirezamon
        my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
2140 42 alirezamon
 
2141
        my $n= $self->object_get_attribute('soc_name',undef);
2142
        if(defined $n){ #we are compiling a single tile as SoC
2143 48 alirezamon
                my $sw_path     = "$target_dir/sw";
2144
                my %params = soc_get_all_parameters($self);
2145
                my $verilator = soc_generate_verilator ($self,$sw_path,"verilator_$n",\%params);
2146
        my %tops;
2147
                $tops{"Vtop"}= "--top-module verilator_$n";
2148
                my $target_verilator_dr ="$target_dir/src_verilator";
2149
        mkpath("$target_verilator_dr",1,01777);
2150
        save_file ("$target_verilator_dr/verilator_${n}.sv",$verilator);
2151
 
2152
 
2153
 
2154
 
2155
 
2156
                #$tops{"Vtop"}= "--top-module $name";
2157
                $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
2158 42 alirezamon
                $self->object_add_attribute('verilator','libs',\%tops);
2159
        }
2160
        else { # we are compiling a complete NoC-based mpsoc
2161 48 alirezamon
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext,$cpu_num);
2162 42 alirezamon
 
2163
 
2164
        }
2165
 
2166
 
2167 38 alirezamon
        #check if verilator model has been generated 
2168
        if ($result){
2169 48 alirezamon
                add_colored_info($outtext,"Veriator model has been generated successfully!",'blue');
2170 43 alirezamon
                $load->destroy();
2171
                $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
2172 34 alirezamon
        }else {
2173 48 alirezamon
                add_colored_info($outtext,"Verilator compilation failed!\n","red");
2174 43 alirezamon
                $load->destroy();
2175 34 alirezamon
                $next->destroy();
2176
        }
2177
}
2178
 
2179 38 alirezamon
 
2180
 
2181 42 alirezamon
 
2182
 
2183
sub  gen_mpsoc_verilator_model{
2184 48 alirezamon
        my ($self,$name,$top,$target_dir,$outtext,$cpu_num)=@_;
2185
 
2186
        my $project_dir = get_project_dir();
2187
        $project_dir= "$project_dir/mpsoc";
2188 42 alirezamon
        my $src_verilator_dir="$project_dir/src_verilator";
2189 43 alirezamon
        my $target_verilog_dr ="$target_dir/src_verilog";
2190
        my $target_verilator_dr ="$target_dir/src_verilator";
2191
 
2192 42 alirezamon
        my $sw_dir      = "$target_dir/sw";
2193 48 alirezamon
        my $src_noc_dir="$project_dir/rtl/src_noc";
2194 43 alirezamon
        mkpath("$target_verilator_dr",1,01777);
2195
 
2196 42 alirezamon
        #copy src_verilator files
2197 43 alirezamon
        my @files_list = File::Find::Rule->file()
2198
                            ->name( '*.v','*.V','*.sv' )
2199
                            ->in( "$src_verilator_dir" );
2200
 
2201
        #make sure source files have key word 'module' 
2202
        my @files;
2203
        foreach my $p (@files_list){
2204
                push (@files,$p)        if(check_file_has_string($p,'module'));
2205 42 alirezamon
        }
2206 43 alirezamon
        copy_file_and_folders (\@files,$project_dir,$target_verilator_dr);
2207 42 alirezamon
 
2208 43 alirezamon
 
2209
 
2210
        #copy src_noc files
2211
        #my @files2;
2212
        #push (@files2,$src_noc_dir);
2213
        #copy_file_and_folders (\@files2,$project_dir,$target_verilog_dr);
2214
 
2215
 
2216
        #create each tile top module    
2217 42 alirezamon
    my $processors_en=0;
2218 43 alirezamon
    my $mpsoc=$self;
2219 42 alirezamon
    my $lisence= get_license_header("verilator_tiles");
2220
        my $warning=autogen_warning();
2221
    my $verilator=$lisence.$warning;
2222
 
2223
 
2224
    # generate NoC parameter file
2225
        my ($noc_param,$pass_param)=gen_noc_param_v($self);
2226
 
2227
        my $noc_param_v= " \`ifdef     INCLUDE_PARAM \n \n
2228
        $noc_param
2229 43 alirezamon
 
2230 42 alirezamon
        //simulation parameter
2231
 
2232
\n \n \`endif" ;
2233 48 alirezamon
        #save_file("$target_verilator_dr/parameter.v",$noc_param_v);
2234 42 alirezamon
 
2235
 
2236 43 alirezamon
 
2237
 
2238
    my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
2239
    my %tops = %{$ref_tops};
2240
 
2241
    for (my $tile_num=0;$tile_num<$ne;$tile_num++){
2242
 
2243 42 alirezamon
                #print "$tile_num\n";
2244
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num);
2245 43 alirezamon
 
2246 42 alirezamon
                my $soc=eval_soc($mpsoc,$soc_name,$outtext);
2247
 
2248
 
2249
                my $top=$mpsoc->mpsoc_get_soc($soc_name);
2250 43 alirezamon
                my $soc_num= $tile_num;
2251 42 alirezamon
 
2252
 
2253
                #update core id
2254
                $soc->object_add_attribute('global_param','CORE_ID',$tile_num);
2255 43 alirezamon
 
2256 42 alirezamon
                #update NoC param
2257
                my $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
2258 43 alirezamon
                my ($NE, $NR, $RAw, $EAw, $Fw) = get_topology_info($mpsoc);
2259
                my %y=%{$nocparam};
2260
                $y{'EAw'} = $EAw;
2261
                $y{'RAw'} = $RAw;
2262
                $y{'Fw'}  = $Fw;
2263 42 alirezamon
                my @nis=get_NI_instance_list($top);
2264 43 alirezamon
                $soc->soc_add_instance_param($nis[0] ,\%y );
2265 48 alirezamon
                my %z;
2266 42 alirezamon
 
2267 48 alirezamon
                my %param_type=  $soc->soc_get_module_param_type($nis[0]);
2268
                foreach my $p (sort keys %y){
2269
                        $z{$p}=$param_type{$p}; #"Parameter";
2270
                }
2271
 
2272
 
2273
 
2274
 
2275
                $soc->soc_add_instance_param_type($nis[0] ,\%z );
2276
 
2277
 
2278 43 alirezamon
                my $tile=$tile_num;
2279 42 alirezamon
                my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
2280
                my %params;
2281 48 alirezamon
                #if ($setting eq 'Custom'){
2282 42 alirezamon
                         %params= $top->top_get_custom_soc_param($tile);
2283 48 alirezamon
                #}else{
2284
                #        %params=$top->top_get_default_soc_param();
2285
                #}
2286 42 alirezamon
 
2287
 
2288
                my $sw_path     = "$sw_dir/tile$tile_num";
2289 48 alirezamon
                $verilator = $verilator.soc_generate_verilator ($soc,$sw_path,"tile_$tile",\%params);
2290
                $tops{"Vtile$tile_num"}= "--top-module tile_$tile";
2291 42 alirezamon
 
2292
 
2293 43 alirezamon
        }
2294 42 alirezamon
 
2295 48 alirezamon
        save_file ("$target_verilator_dr/verilator_tiles.sv",$verilator);
2296
        my $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
2297 42 alirezamon
        $self->object_add_attribute('verilator','libs',\%tops);
2298
        return $result;
2299
 
2300
}
2301
 
2302
 
2303 34 alirezamon
sub gen_verilator_soc_testbench {
2304
        my ($self,$name,$top,$target_dir)=@_;
2305
        my $verilator="$target_dir/verilator";
2306
        my $dir="$verilator/";
2307
        my $soc_top= $self->soc_get_top ();
2308 42 alirezamon
 
2309 48 alirezamon
        my $include='#include <stdlib.h>
2310
#include <stdio.h>
2311
#include <unistd.h>
2312
#include <string.h>
2313
';
2314 34 alirezamon
        my @intfcs=$soc_top->top_get_intfc_list();
2315
        my %PP;
2316 48 alirezamon
        my %rxds;
2317 34 alirezamon
        my $top_port_info="IO type\t  port_size\t  port_name\n";
2318
        foreach my $intfc (@intfcs){
2319
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
2320
                         ( $intfc eq 'plug:reset[0]')? 'reset':
2321 48 alirezamon
                         ( $intfc eq 'plug:enable[0]')? 'en' :
2322
                         ( $intfc eq  'socket:RxD_sim[0]')? 'rxd':
2323
                         'other';
2324
 
2325
 
2326 34 alirezamon
                my $key1="${key}1";
2327
                my $key0="${key}0";
2328
 
2329
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
2330
                foreach my $p (@ports){
2331
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
2332
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} top->$p=1;\n" : "top->$p=1;\n";
2333
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} top->$p=0;\n" : "top->$p=0;\n";
2334
                        $top_port_info="$top_port_info $type  $range  top->$p \n";
2335
                }
2336 48 alirezamon
                if($key eq 'rxd'){
2337
                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
2338
                        foreach my $p (@ports){
2339
                                my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
2340
                                my @q =split  (/RxD_ready_si/,$p);
2341
                                $rxds{$id}{p}=$q[0]  if( defined $q[1]);
2342
                                $rxds{$id}{top}='top'  if( defined $q[1]);
2343
                        }
2344
                }
2345 34 alirezamon
 
2346
        }
2347 48 alirezamon
 
2348
 
2349
 my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
2350
 my $include2="";
2351
 $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
2352
 
2353
my $main_c=get_license_header("testbench.cpp");
2354
 
2355
 
2356
 
2357 34 alirezamon
$main_c="$main_c
2358 48 alirezamon
$include
2359
$include1
2360 34 alirezamon
#include <verilated.h>          // Defines common routines
2361
#include \"Vtop.h\"               // From Verilating \"$name.v\" file
2362
Vtop                    *top;
2363 48 alirezamon
$include2
2364 34 alirezamon
/*
2365
$top_port_info
2366
*/
2367
 
2368 48 alirezamon
 
2369
 
2370 34 alirezamon
int reset,clk;
2371
unsigned int main_time = 0; // Current simulation time
2372
 
2373
int main(int argc, char** argv) {
2374 48 alirezamon
        $rxd_info
2375 34 alirezamon
        Verilated::commandArgs(argc, argv);   // Remember args
2376
        top     = new Vtop;
2377
 
2378
        /********************
2379
        *       initialize input
2380
        *********************/
2381
 
2382
        $PP{reset1}
2383
        $PP{en1}
2384
        main_time=0;
2385
        printf(\"Start Simulation\\n\");
2386
        while (!Verilated::gotFinish()) {
2387 48 alirezamon
                $rxd_cap_cal
2388
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
2389 34 alirezamon
                if (main_time >= 10 ) {
2390
                        $PP{reset0}
2391
                }
2392
 
2393
 
2394
                if ((main_time & 1) == 0) {
2395
                        $PP{clk1}      // Toggle clock
2396
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
2397 48 alirezamon
                        $rxd_wr_cal
2398 34 alirezamon
 
2399
 
2400
                }//if
2401
                else
2402
                {
2403
                        $PP{clk0}
2404
 
2405
 
2406
 
2407
                }//else
2408
 
2409
 
2410
                main_time ++;
2411
                top->eval();
2412
                }
2413
        top->final();
2414
}
2415
 
2416
double sc_time_stamp () {       // Called by \$time in Verilog
2417
        return main_time;
2418
}
2419
";
2420
        save_file("$dir/testbench.cpp",$main_c);
2421 48 alirezamon
 
2422 34 alirezamon
 
2423
 
2424
}
2425
 
2426 42 alirezamon
sub eval_soc{
2427
        my ($mpsoc,$soc_name,$outtext)=@_;
2428
        my $path=$mpsoc->object_get_attribute('setting','soc_path');
2429
        $path=~ s/ /\\ /g;
2430
        my $p = "$path/$soc_name.SOC";
2431 43 alirezamon
        my ($soc,$r,$err) = regen_object($p);
2432
        if ($r){
2433 48 alirezamon
                show_info($outtext,"**Error reading  $p file: $err\n");
2434 42 alirezamon
               next;
2435
        }
2436
        return $soc;
2437
}
2438 34 alirezamon
 
2439 48 alirezamon
sub rxd_testbench_verilator_gen {
2440
my      ($rxds_ref,$dir)=@_;
2441 42 alirezamon
 
2442 48 alirezamon
my $rxd_info='';
2443
my $rxd_num=0;
2444
my $rxd_func='';
2445
my $rxd_wr_cal='';
2446
my $rxd_cap_cal='';
2447
my $include='';
2448
 
2449
my %rxds=%{$rxds_ref};
2450
 
2451
foreach my $rxd (sort keys %rxds){
2452
        my $n=$rxds{$rxd}{p};
2453
        my $top=$rxds{$rxd}{top};
2454
        $rxd_info.="\\t$rxd_num : ${top}_${n}RXD\\n";
2455
 
2456
        $rxd_func.="
2457
        // we have a character to send to interface $rxd_num
2458
        if (sent_table[$rxd_num]!=0 &&  $top->${n}RxD_ready_sim){
2459
                $top->${n}RxD_din_sim=sent_table[$rxd_num];
2460
        $top->${n}RxD_wr_sim=1;
2461
        sent_table[$rxd_num]=0;
2462
        }else {
2463
                $top->${n}RxD_wr_sim=0;
2464
        }
2465
";
2466
        $rxd_num++;
2467
}
2468
 
2469
 
2470
 
2471
if($rxd_num>0){
2472
$rxd_func="
2473
#ifndef RXD_SIM_H
2474
#define RXD_SIM_H
2475
        #define RXD_NUM  $rxd_num  // number of rxd input interfaces
2476
        char sent_table[RXD_NUM]={0};
2477
        unsigned char active_rxd_num=0;
2478
        void write_char_on_RXD( ) {
2479
                $rxd_func
2480
        }
2481
 
2482
        int kbhit(void) {
2483
          struct termios oldt, newt;
2484
          int ch;
2485
          int oldf;
2486
 
2487
          tcgetattr(STDIN_FILENO, &oldt);
2488
          newt = oldt;
2489
          newt.c_lflag &= ~(ICANON | ECHO);
2490
          tcsetattr(STDIN_FILENO, TCSANOW, &newt);
2491
          oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
2492
          fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
2493
 
2494
          ch = getchar();
2495
 
2496
          tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
2497
          fcntl(STDIN_FILENO, F_SETFL, oldf);
2498
 
2499
          if(ch != EOF)
2500
          {
2501
            ungetc(ch, stdin);
2502
            return 1;
2503
          }
2504
          return 0;
2505
        }
2506
 
2507
        void capture_char_on_RXD (){
2508
                char c;
2509
                if(kbhit()){
2510
                        c=getchar();
2511
                        if(c=='+'){
2512
                                active_rxd_num++;
2513
                                if(active_rxd_num>=$rxd_num) active_rxd_num=0;
2514
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
2515
                        }else if(c=='-'){
2516
                                active_rxd_num--;
2517
                                if(active_rxd_num>=$rxd_num) active_rxd_num=($rxd_num-1);
2518
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
2519
                        }else{
2520
                                sent_table[active_rxd_num]=c;
2521
                        }
2522
 
2523
                }
2524
        }
2525
#endif
2526
        ";
2527
 
2528
 
2529
        $include .='#include <termios.h>
2530
#include <fcntl.h>
2531
';
2532
        $rxd_wr_cal="write_char_on_RXD( );";
2533
        $rxd_cap_cal="capture_char_on_RXD( );";
2534
        $rxd_info="printf(\"There are total of $rxd_num RXD (UART) interface ports in the top module:\\n${rxd_info}The default interfce is 0. You can switch to different interfaces by pressing + or - key.\\n\");"
2535
}
2536
 
2537
        my $rxsim_c=get_license_header("RxDsim.h");
2538
        $rxsim_c.="$rxd_func";
2539
        save_file("$dir/RxDsim.h",$rxsim_c) if($rxd_num > 0);
2540
 
2541
        return ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include);
2542
 
2543
}
2544
 
2545
 
2546
 
2547 42 alirezamon
sub gen_verilator_mpsoc_testbench {
2548
        my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
2549
        my $verilator="$target_dir/verilator";
2550
        my $dir="$verilator/";
2551 43 alirezamon
        my $parameter_h=gen_noc_param_h($mpsoc);
2552 42 alirezamon
 
2553 48 alirezamon
 
2554 43 alirezamon
        my ($nr,$ne,$router_p,$ref_tops,$includ_h)= get_noc_verilator_top_modules_info($mpsoc);
2555 48 alirezamon
 
2556
        $parameter_h.="
2557
        #define NE  $ne
2558
        #define NR  $nr
2559
        ";
2560 43 alirezamon
        $parameter_h=$parameter_h.$includ_h;
2561
 
2562
 
2563 42 alirezamon
 
2564
        my $libh="";
2565
        my $inst= "";
2566
        my $newinst="";
2567
 
2568 43 alirezamon
        my $tile_addr="";
2569 42 alirezamon
        my $tile_flit_in="";
2570
        my $tile_flit_in_l="";
2571
        my $tile_credit="";
2572
        my $noc_credit="";
2573
        my $noc_flit_in="";
2574
        my $noc_flit_in_l="";
2575
        my $noc_flit_in_wr="";
2576
        my $noc_flit_in_wr_l="";
2577
        my $tile_flit_in_wr="";
2578
        my $tile_flit_in_wr_l="";
2579
        my $tile_eval="";
2580
        my $tile_final="";
2581
        my $tile_reset="";
2582
        my $tile_clk="";
2583
        my $tile_en="";
2584
        my $top_port_info="IO type\t  port_size\t  port_name\n";
2585
        my $no_connected='';
2586 48 alirezamon
        my %rxds;
2587 42 alirezamon
 
2588 48 alirezamon
        my $tile_chans="";
2589
        my $tmp_reg='';
2590 43 alirezamon
        for (my $endp=0; $endp<$ne;$endp++){
2591 48 alirezamon
 
2592 43 alirezamon
 
2593
                my $e_addr=endp_addr_encoder($mpsoc,$endp);
2594
                my $router_num = get_connected_router_id_to_endp($mpsoc,$endp);
2595
                my $r_addr=router_addr_encoder($mpsoc,$router_num);
2596
 
2597
 
2598
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($endp);
2599 42 alirezamon
                if(defined $soc_name) {#we have a conncted tile
2600
 
2601
                        #get ni instance name
2602
                        my $ni_name;
2603
                        my $soc=eval_soc($mpsoc,$soc_name,$tview);
2604
                        my $soc_top=$soc->object_get_attribute('top_ip',undef);
2605
                        my @intfcs=$soc_top->top_get_intfc_list();
2606
                        my @instances=$soc->soc_get_all_instances();
2607
                        foreach my $id (@instances){
2608
                                        my $category = $soc->soc_get_category($id);
2609
                                        if ($category eq 'NoC') {
2610
                                                 $ni_name=  $soc->soc_get_instance_name($id);
2611
                                        }
2612
                        }
2613
 
2614 48 alirezamon
                                $tile_chans.="\ttile_chan_out[$endp] = &tile$endp->ni_chan_out;\n\ttile_chan_in[$endp] = &tile$endp->ni_chan_in;\n";
2615 43 alirezamon
                                $libh=$libh."#include \"Vtile${endp}.h\"\n";
2616
                                $inst=$inst."Vtile${endp}\t*tile${endp};\t  // Instantiation of tile${endp}\n";
2617
                                $newinst = $newinst."\ttile${endp}\t=\tnew Vtile${endp};\n";
2618
                                $tile_flit_in = $tile_flit_in . "\ttile${endp}->${ni_name}_flit_in  = noc->ni_flit_out [${endp}];\n";
2619
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${endp}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${endp}][j];\n";
2620
                                $tile_credit= $tile_credit."\ttile${endp}->${ni_name}_credit_in= noc->ni_credit_out[${endp}];\n";
2621
                                $noc_credit= $noc_credit."\tnoc->ni_credit_in[${endp}] = tile${endp}->${ni_name}_credit_out;\n";
2622
                                $noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${endp}]  = tile${endp}->${ni_name}_flit_out;\n";
2623
                                $noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${endp}][j]  = tile${endp}->${ni_name}_flit_out[j];\n";
2624
                                $noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${endp}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${endp});\n";
2625
                                $tile_flit_in_wr=$tile_flit_in_wr."\ttile${endp}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${endp}) & 0x01);\n";
2626
                                $noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${endp}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${endp});\n";
2627
                                $tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${endp}->${ni_name}_flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,${endp})>0);\n";
2628
                                $tile_eval=$tile_eval."\ttile${endp}->eval();\n";
2629
                                $tile_final=$tile_final."\ttile${endp}->final();\n";
2630 42 alirezamon
 
2631
 
2632
                                foreach my $intfc (@intfcs){
2633
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
2634
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
2635 48 alirezamon
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
2636
                                                         ($intfc eq 'socket:RxD_sim[0]')? 'rxd':
2637 42 alirezamon
                                                         'other';
2638 48 alirezamon
 
2639 42 alirezamon
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
2640
                                        foreach my $p (@ports){
2641
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
2642 43 alirezamon
                                                $tile_reset=$tile_reset."\t\ttile${endp}->$p=reset;\n" if $key eq 'reset';
2643
                                                $tile_clk=$tile_clk."\t\ttile${endp}->$p=clk;\n" if $key eq 'clk';
2644
                                                $tile_en=$tile_en."\t\ttile${endp}->$p=enable;\n" if $key eq 'en';      ;
2645
                                                $top_port_info="$top_port_info $type  $range  tile${endp}->$p \n";
2646 42 alirezamon
                                        }#ports
2647 48 alirezamon
 
2648
                                        if($key eq 'rxd'){
2649
                                                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
2650
                                                foreach my $p (@ports){
2651
                                                        my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
2652
                                                        my @q =split  (/RxD_ready_si/,$p);
2653
                                                        $rxds{$endp.$id}{p}=$q[0]  if( defined $q[1]);
2654
                                                        $rxds{$endp.$id}{top}="tile$endp"  if( defined $q[1]);
2655
                                                }
2656
                                        }
2657
 
2658 42 alirezamon
 
2659
                                }#interface
2660
 
2661 43 alirezamon
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_r_addr=$r_addr; // noc->er_addr[${endp}];\n";
2662
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_e_addr=$e_addr;\n";
2663
 
2664 42 alirezamon
                        }else{
2665
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
2666 48 alirezamon
                                $tmp_reg.="\tunsigned char tmp1 [1024]={0};\n \tunsigned char tmp2 [1024]={0};";
2667
                                $tile_chans.="\n // Tile:$endp ($e_addr)   is not assigned to any ip. Connet coresponding chan to ground.\n";
2668
                                $tile_chans.="\ttile_chan_out[$endp] = tmp1;\n\ttile_chan_in[$endp] = tmp2;\n";
2669
 
2670 42 alirezamon
                        }
2671
 
2672
 
2673 43 alirezamon
        }
2674 48 alirezamon
 
2675
        my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
2676
        my $include2="";
2677
        $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
2678
 
2679 42 alirezamon
        my $main_c=get_license_header("testbench.cpp");
2680 43 alirezamon
 
2681 42 alirezamon
$main_c="$main_c
2682
#include <stdlib.h>
2683
#include <stdio.h>
2684
#include <unistd.h>
2685
#include <string.h>
2686 48 alirezamon
$include1
2687 42 alirezamon
#include <verilated.h>          // Defines common routines
2688 48 alirezamon
$tmp_reg
2689 42 alirezamon
 
2690 48 alirezamon
 
2691 42 alirezamon
$libh
2692
 
2693 48 alirezamon
 
2694 43 alirezamon
$inst
2695
int reset,clk,enable;
2696 42 alirezamon
 
2697 43 alirezamon
 
2698
#include \"parameter.h\"
2699 48 alirezamon
void * tile_chan_out[NE];
2700
void * tile_chan_in[NE];
2701 43 alirezamon
 
2702
 
2703 48 alirezamon
 
2704
#define CHAN_SIZE   sizeof(tile0->ni_chan_in)
2705
 
2706
#define conect_r2r(T1,r1,p1,T2,r2,p2)  \\
2707
        memcpy(&router##T1 [r1]->chan_in[p1] , &router##T2 [r2]->chan_out[p2], CHAN_SIZE )
2708
 
2709
#define connect_r2gnd(T,r,p)\\
2710
        memset(&router##T [r]->chan_in [p],0x00,CHAN_SIZE)
2711
 
2712
#define connect_r2e(T,r,p,e) \\
2713
        memcpy(&router##T [r]->chan_in[p], tile_chan_out[e], CHAN_SIZE );\\
2714
        memcpy(tile_chan_in[e], &router##T [r]->chan_out[p], CHAN_SIZE )
2715
 
2716
 
2717
 
2718
#include \"topology_top.h\"
2719
$include2
2720
 
2721 42 alirezamon
/*
2722
$top_port_info
2723
*/
2724
 
2725
 
2726
unsigned int main_time = 0; // Current simulation time
2727
 
2728
 
2729
 
2730 48 alirezamon
void connect_clk_reset_en_all(void){
2731
        //clk,reset,enable
2732
$tile_reset
2733
$tile_clk
2734
$tile_en
2735
        connect_routers_reset_clk();
2736
}
2737
 
2738
void sim_eval_all(void){
2739
        routers_eval();
2740
$tile_eval
2741
}
2742
 
2743
void sim_final_all(void ){
2744
        routers_final();
2745
$tile_final
2746
}
2747
 
2748
void clk_posedge_event(void) {
2749
 
2750
        clk = 1;       // Toggle clock
2751
        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
2752
        $rxd_wr_cal
2753
        connect_clk_reset_en_all();
2754
        sim_eval_all();
2755
}
2756
 
2757
 
2758
void clk_negedge_event(void){
2759
 
2760
        clk = 0;
2761
        topology_connect_all_nodes ();
2762
        connect_clk_reset_en_all();
2763
        sim_eval_all();
2764
}
2765
 
2766
 
2767 42 alirezamon
int main(int argc, char** argv) {
2768
        int i,j,x,y;
2769 48 alirezamon
        $rxd_info
2770 42 alirezamon
        Verilated::commandArgs(argc, argv);   // Remember args
2771 43 alirezamon
        Vrouter_new();             // Create instance
2772 48 alirezamon
 
2773 42 alirezamon
$newinst
2774
 
2775
        /********************
2776
        *       initialize input
2777
        *********************/
2778 48 alirezamon
        $tile_chans
2779 42 alirezamon
 
2780
        reset=1;
2781
        enable=1;
2782 48 alirezamon
        topology_init();
2783
 
2784 42 alirezamon
        $no_connected
2785 43 alirezamon
 
2786
$tile_addr
2787 42 alirezamon
 
2788 43 alirezamon
 
2789 42 alirezamon
        main_time=0;
2790
        printf(\"Start Simulation\\n\");
2791
        while (!Verilated::gotFinish()) {
2792 48 alirezamon
            $rxd_cap_cal
2793
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
2794
                if (main_time >= 10 )   reset=0;
2795 42 alirezamon
 
2796 48 alirezamon
                clk_posedge_event( );
2797
                //The valus of all registers and input ports valuse change @ posedge of the clock. Once clk is deasserted,  as multiple modules are connected inside the testbench we need several eval for propogating combinational logic values
2798
                //between modules when the clock .
2799
                for (i=0;i<2*(SMART_MAX+1);i++) clk_negedge_event( );
2800 42 alirezamon
 
2801
                main_time++;
2802
        }//while
2803
 
2804 43 alirezamon
        // Simulation is done
2805 48 alirezamon
        sim_final_all();
2806 42 alirezamon
}
2807
 
2808
double sc_time_stamp () {       // Called by \$time in Verilog
2809
        return main_time;
2810
}
2811 48 alirezamon
 
2812 42 alirezamon
 
2813
";
2814
 
2815 43 alirezamon
        save_file("$dir/parameter.h",$parameter_h);
2816 42 alirezamon
        save_file("$dir/testbench.cpp",$main_c);
2817
 
2818
}
2819
 
2820
 
2821
 
2822
sub soc_get_all_parameters {
2823
        my $soc=shift;
2824
        my @instances=$soc->soc_get_all_instances();
2825
 
2826
        my %all_param;
2827
        foreach my $id (@instances){
2828
 
2829
                my $module      =$soc->soc_get_module($id);
2830
                my $category    =$soc->soc_get_category($id);
2831
                my $inst        = $soc->soc_get_instance_name($id);
2832
                my %params      = $soc->soc_get_module_param($id);
2833 48 alirezamon
                my %params_type = $soc->soc_get_module_param_type($id);
2834 42 alirezamon
                my $ip = ip->lib_new ();
2835
                my @param_order=$soc->soc_get_instance_param_order($id);
2836
 
2837
                foreach my $p (sort keys %params){
2838
                        my $inst_param= "$inst\_$p";
2839
                        #add instance name to parameter value
2840
                        $params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
2841
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
2842 48 alirezamon
 
2843 42 alirezamon
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
2844 48 alirezamon
                        if ($vfile_param_type eq "Localparam"){
2845
                                my $type = $params_type{$p};
2846
                                $type = "Localparam" if (! defined $type);
2847
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
2848
                        }
2849
 
2850
                        #$vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
2851
                        #$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
2852 42 alirezamon
                        $all_param{ $inst_param} =      $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
2853 43 alirezamon
                        #print"$all_param{ $inst_param} =       $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
2854 42 alirezamon
                }
2855
        }
2856
        return %all_param;
2857
}
2858
 
2859
sub soc_get_all_parameters_order {
2860
        my $soc=shift;
2861
        my @instances=$soc->soc_get_all_instances();
2862
        my $ip = ip->lib_new ();
2863
        my @all_order;
2864
        foreach my $id (@instances){
2865
                my $module      =$soc->soc_get_module($id);
2866
                my $category    =$soc->soc_get_category($id);
2867
                my $inst        = $soc->soc_get_instance_name($id);
2868
                my @order       = $soc->soc_get_instance_param_order($id);
2869 48 alirezamon
                my %params_type = $soc->soc_get_module_param_type($id);
2870 42 alirezamon
                foreach my $p ( @order){
2871
                        my $inst_param= "$inst\_$p";
2872
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
2873
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
2874 48 alirezamon
                        if ($vfile_param_type eq "Localparam"){
2875
                                my $type = $params_type{$p};
2876
                                $type = "Localparam" if (! defined $type);
2877
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
2878
                        }
2879
                        #$vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
2880
                        #$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
2881 42 alirezamon
                        push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
2882
                }
2883
        }
2884
        return @all_order;
2885
}
2886
 
2887
 
2888
 
2889 34 alirezamon
sub gen_modelsim_soc_testbench {
2890 48 alirezamon
        my ($self,$name,$top,$target_dir,$tview)=@_;
2891
        my $dir="$target_dir/Modelsim";
2892 34 alirezamon
        my $soc_top= $self->object_get_attribute('top_ip',undef);
2893 48 alirezamon
 
2894 34 alirezamon
        my @intfcs=$soc_top->top_get_intfc_list();
2895
        my %PP;
2896
        my $top_port_def="// ${name}.v IO definition \n";
2897
        my $pin_assign;
2898
        my $rst_inputs='';
2899
 
2900
 
2901
 
2902 42 alirezamon
 
2903
        #add functions
2904 48 alirezamon
        my $project_dir   = get_project_dir();
2905
        open my $file1, "<", "$project_dir/mpsoc/perl_gui/lib/verilog/functions.v" or die;
2906 42 alirezamon
        my $functions_all='';
2907
        while (my $f1 = readline ($file1)) {
2908
                 $functions_all="$functions_all $f1 ";
2909
        }
2910
        close($file1);
2911
 
2912
        #get parameters
2913
        my $params_v="";
2914
        my $n= $self->object_get_attribute('soc_name',undef);
2915
 
2916
        if(defined $n){ #we are compiling a single tile as SoC
2917
                my $core_id= $self->object_get_attribute('global_param','CORE_ID');
2918
                my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
2919
 
2920
                        $params_v="\tlocalparam\tCORE_ID=$core_id;
2921
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
2922
                my %params=soc_get_all_parameters($self);
2923
                my @order= soc_get_all_parameters_order($self);
2924
                foreach my $p (@order){
2925
                        add_text_to_string(\$params_v,"\tlocalparam  $p = $params{$p};\n") if(defined $params{$p} );
2926
                }
2927
        }else{ # we are simulating a mpsoc
2928 48 alirezamon
                $params_v= gen_socs_param($self);
2929 42 alirezamon
 
2930
 
2931
        }
2932 34 alirezamon
 
2933
        foreach my $intfc (@intfcs){
2934
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
2935
                         ( $intfc eq 'plug:reset[0]')? 'reset':
2936
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
2937
                my $key1="${key}1";
2938
                my $key0="${key}0";
2939
 
2940
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
2941
                my $f=1;
2942
                foreach my $p (@ports){
2943
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
2944
 
2945
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
2946
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
2947
 
2948
 
2949
                        if  (length($range)!=0){
2950 42 alirezamon
#                               #replace parameter with their values            #
2951
#                               my @a= split (/\b/,$range);
2952
#                               print "a=@a\n";
2953
#                               foreach my $l (@a){
2954
#                                       my $value=$params{$l};
2955
#                                       if(defined $value){
2956
#                                               chomp $value;
2957
#                                               ($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l});
2958
#                                               print "($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l}); \n";
2959
#                                       }
2960
#                               }
2961 34 alirezamon
                                $range = "[ $range ]" ;
2962
                        }
2963
 
2964
 
2965
 
2966 42 alirezamon
 
2967
 
2968 34 alirezamon
                        if($type eq 'input'){
2969
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
2970
                        }else{
2971
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
2972
                        }
2973 48 alirezamon
 
2974
 
2975
 
2976
 
2977
 
2978
 
2979
 
2980
 
2981 34 alirezamon
                        $pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)":  "\t\t.$p($p)";
2982
                        $rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
2983
                }
2984
 
2985
 
2986
        }
2987 48 alirezamon
my $global_localparam=get_golal_param_v();
2988 34 alirezamon
my $test_v= get_license_header("testbench.v");
2989
 
2990 48 alirezamon
my $mpsoc_name=$self->object_get_attribute('mpsoc_name');
2991
#if(defined $mpsoc_name){
2992
        if(0){
2993
 
2994
 
2995
        my $top_ip=ip_gen->top_gen_new();
2996
        my $target_dir  = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name";
2997
    my $hw_dir     = "$target_dir/src_verilog";
2998
    my $sw_dir     = "$target_dir/sw";
2999
        my ($socs_v,$io_short,$io_full,$top_io_short,$top_io_full,$top_io_pass,$href)=gen_socs_v($self,$top_ip,$sw_dir,$tview);
3000
        my $socs_param= gen_socs_param($self);
3001
        my $global_localparam=get_golal_param_v();
3002
        my ($clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port)= get_top_clk_setting($self);
3003
 
3004
 
3005
$test_v.="
3006
 
3007
$clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port
3008
 
3009
`timescale       1ns/1ps
3010
 
3011
module testbench;
3012
 
3013
$functions_all
3014
 
3015
$global_localparam
3016
 
3017
$socs_param
3018
 
3019
$top_port_def
3020
 
3021
 
3022
\t${mpsoc_name} the_${mpsoc_name} (
3023
$top_io_pass
3024
 
3025
\t);
3026
/*****************************************************************/
3027
";
3028
 
3029
 
3030
}
3031
 
3032 34 alirezamon
$test_v ="$test_v
3033
 
3034
`timescale       1ns/1ps
3035
 
3036
module testbench;
3037
 
3038 42 alirezamon
$functions_all
3039
 
3040 48 alirezamon
$global_localparam
3041
 
3042 42 alirezamon
$params_v
3043
 
3044 34 alirezamon
$top_port_def
3045
 
3046
 
3047
        $name uut (
3048
$pin_assign
3049
        );
3050
 
3051
//clock defination
3052
initial begin
3053
        forever begin
3054
        #5 $PP{clk0}
3055
        #5 $PP{clk1}
3056
        end
3057
end
3058
 
3059
 
3060
 
3061
initial begin
3062
        // reset $name module at the start up
3063
        $PP{reset1}
3064
        $PP{en1}
3065
        $rst_inputs
3066
        // deasert the reset after 200 ns
3067
        #200
3068
        $PP{reset0}
3069
 
3070
        // write your testbench here
3071
 
3072
 
3073
 
3074
 
3075
end
3076
 
3077
endmodule
3078
";
3079
        save_file("$dir/testbench.v",$test_v);
3080
 
3081
 
3082
 
3083
}
3084
 
3085
sub verilator_testbench{
3086 48 alirezamon
        my ($self,$name,$top,$target_dir,$vendor)=@_;
3087 34 alirezamon
        my $verilator="$target_dir/verilator";
3088
        my $dir="$verilator";
3089 42 alirezamon
 
3090
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
3091
 
3092
        my $n= $self->object_get_attribute('soc_name',undef);
3093
        if(defined $n){ #we are compiling a single tile as SoC
3094
                gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
3095
        }
3096
        else { # we are compiling a complete NoC-based mpsoc
3097
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
3098
 
3099
        }
3100
 
3101 34 alirezamon
        #copy makefile
3102 48 alirezamon
        #copy("../script/verilator_soc_make", "$verilator/obj_dir/Makefile");
3103 34 alirezamon
 
3104
 
3105 42 alirezamon
 
3106 34 alirezamon
 
3107
 
3108
        my $make = def_image_button('icons/gen.png','Compile');
3109
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
3110
        my $run = def_image_button('icons/run.png','Run');
3111
        my $back=def_image_button('icons/left.png','Previous');
3112
 
3113 43 alirezamon
 
3114
 
3115 34 alirezamon
        $table->attach ($back,1,2,1,2,'shrink','shrink',0,0);
3116
        $table->attach ($regen,3,4,1,2,'shrink','shrink',0,0);
3117 43 alirezamon
        $table->attach ($make,6, 7, 1,2,'shrink','shrink',0,0);
3118 34 alirezamon
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
3119
 
3120
        $back-> signal_connect("clicked" => sub{
3121
 
3122
                $window->destroy;
3123 48 alirezamon
                verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
3124 34 alirezamon
 
3125
        });
3126
 
3127
        $regen-> signal_connect("clicked" => sub{
3128 48 alirezamon
                my $response = yes_no_dialog("Are you sure you want to regenerate the testbench.cpp file? Note that any changes you have made will be lost");
3129 34 alirezamon
                if ($response eq 'yes') {
3130 42 alirezamon
                        my $n= $self->object_get_attribute('soc_name',undef);
3131
                        if(defined $n){ #we are compiling a single tile as SoC
3132
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
3133
                        }
3134
                        else { # we are compiling a complete NoC-based mpsoc
3135
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
3136
 
3137
                        }
3138
 
3139 48 alirezamon
                        $app->refresh_source("$dir/testbench.cpp");
3140
                }
3141 34 alirezamon
        });
3142
 
3143
 
3144
        $make -> signal_connect("clicked" => sub{
3145 48 alirezamon
                $make->hide;
3146 43 alirezamon
                my $load= show_gif("icons/load.gif");
3147
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',0,0);
3148
                $table->show_all;
3149 48 alirezamon
                $app->ask_to_save_changes();
3150
                copy("$dir/testbench.cpp", "$verilator/obj_dir/testbench.cpp");
3151
                copy("$dir/parameter.h", "$verilator/obj_dir/parameter.h") if(-f "$dir/parameter.h");
3152
                copy("$dir/RxDsim.h", "$verilator/obj_dir/RxDsim.h") if(-f "$dir/RxDsim.h");
3153 42 alirezamon
 
3154
                my $tops_ref=$self->object_get_attribute('verilator','libs');
3155
                my %tops=%{$tops_ref};
3156
                my $lib_num=0;
3157 48 alirezamon
                my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
3158
                $cpu_num = 1 if (!defined $cpu_num);
3159
                add_colored_info($tview,"Makefie will use the maximum number of $cpu_num core(s) in parallel for compilation\n",'green');
3160
                my $length=scalar (keys %tops);
3161
                my $cmd="";
3162 42 alirezamon
                foreach my $top (sort keys %tops) {
3163 48 alirezamon
                        $cmd.= "lib$lib_num & ";
3164
                        $lib_num++;
3165
                        if( $lib_num % $cpu_num == 0 || $lib_num == $length){
3166
                                $cmd.="wait\n";
3167
                                run_make_file("$verilator/obj_dir/",$tview,$cmd);
3168
                                $cmd="";
3169
                        }else {
3170
                                $cmd.=" make ";
3171
                        }
3172 42 alirezamon
                }
3173 48 alirezamon
 
3174
 
3175
                #foreach my $top (sort keys %tops) {
3176
                #               run_make_file("$verilator/obj_dir/",$tview,"lib$lib_num");
3177
                #               $lib_num++;
3178
                #}
3179
 
3180
 
3181
 
3182
                run_make_file("$verilator/obj_dir/",$tview,"sim");
3183 43 alirezamon
                $load->destroy;
3184
                $make->show_all;
3185
 
3186 34 alirezamon
        });
3187
 
3188
        $run -> signal_connect("clicked" => sub{
3189 48 alirezamon
                my $bin="$verilator/obj_dir/testbench";
3190 34 alirezamon
                if (-f $bin){
3191 48 alirezamon
                        my $cmd= "cd \"$verilator/obj_dir/\" \n xterm -e bash -c \"$bin; sleep 5\"";
3192
                        add_info($tview,"$cmd\n");
3193 34 alirezamon
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
3194
                        if(length $stderr>1){
3195 48 alirezamon
                                add_colored_info($tview,"$stderr\n",'red');
3196 34 alirezamon
                        }else {
3197 48 alirezamon
                                add_info($tview,"$stdout\n");
3198 34 alirezamon
                        }
3199
 
3200
                }else{
3201 48 alirezamon
                        add_colored_info($tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
3202 34 alirezamon
                }
3203
 
3204
                });
3205
 
3206
 
3207
}
3208
 
3209
 
3210 48 alirezamon
 
3211 34 alirezamon
1;

powered by: WebSVN 2.1.0

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