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 48

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

powered by: WebSVN 2.1.0

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