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 42

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

Line No. Rev Author Line
1 34 alirezamon
#! /usr/bin/perl -w
2
use Glib qw/TRUE FALSE/;
3
use strict;
4
use warnings;
5
use soc;
6
#use ip;
7
#use interface;
8
#use POSIX 'strtol';
9
 
10
use File::Path;
11
use File::Find::Rule;
12
use File::Copy;
13
use File::Copy::Recursive qw(dircopy);
14
use Cwd 'abs_path';
15
use Verilog::EditFiles;
16
 
17
use Gtk2;
18
#use Gtk2::Pango;
19
 
20
use List::MoreUtils qw( minmax );
21
 
22
 
23
 
24
################
25
#       Comile
26
#################
27
 
28
 
29
 
30
sub is_capital_sensitive()
31
{
32
  my ($cell_layout, $cell, $tree_model, $iter, $data) = @_;
33
  my $sensitive = !$tree_model->iter_has_child($iter);
34
  $cell->set('sensitive', $sensitive);
35
}
36
 
37
sub gen_combo_model{
38
        my $ref=shift;
39
        my %inputs=%{$ref};
40
        my $store = Gtk2::TreeStore->new('Glib::String');
41
         for my $i (sort { $a cmp $b} keys %inputs ) {
42
                my $iter = $store->append(undef);
43
 
44
                $store->set($iter, 0, $i);
45
                for my $capital (sort { $a cmp $b} keys %{$inputs{$i}}) {
46
                        my $iter2 = $store->append($iter);
47
                        $store->set($iter2, 0, $capital);
48
                }
49
        }
50
        return $store;
51
 
52
}
53
 
54
sub gen_tree_combo{
55
        my $model=shift;
56
        my $combo = Gtk2::ComboBox->new_with_model($model);
57
        my $renderer = Gtk2::CellRendererText->new();
58
        $combo->pack_start($renderer, TRUE);
59
        $combo->set_attributes($renderer, "text", 0);
60
        $combo->set_cell_data_func($renderer, \&is_capital_sensitive);
61
        return $combo;
62
 
63
}
64
 
65
sub get_range {
66
        my ($board,$self,$porttype,$assignname,$portrange,$portname) =@_;
67
        my $box= def_hbox(FALSE,0);
68
        my @range=$board->board_get_pin_range($porttype,$assignname);
69
 
70
 
71
        if ($range[0] ne '*undefine*'){
72
                my $content = join(",", @range);
73
                my ($min, $max) = minmax @range;
74
                if  (length($portrange)!=0){
75
                        my $range_hsb=gen_combobox_object($self,'compile_pin_range_hsb',$portname,$content,$max,undef,undef);
76
                        $box->pack_start( $range_hsb, FALSE, FALSE, 0);
77
                        $box->pack_start(gen_label_in_center(':'),, FALSE, FALSE, 0);
78
                }
79
 
80
                my $range_lsb=gen_combobox_object($self,'compile_pin_range_lsb',$portname,$content,$min,undef,undef);
81
                $box->pack_start( $range_lsb, FALSE, FALSE, 0);
82
 
83
        }
84
        return $box;
85
 
86
}
87
 
88
 
89 38 alirezamon
sub read_top_v_file{
90
        my $top_v=shift;
91 34 alirezamon
        my $board = soc->board_new();
92 38 alirezamon
        my $vdb=read_verilog_file($top_v);
93
        my @modules=sort $vdb->get_modules($top_v);
94
        my %Ptypes=get_ports_type($vdb,$modules[0]);
95
        my %Pranges=get_ports_rang($vdb,$modules[0]);
96
        foreach my $p (sort keys %Ptypes){
97
                my $Ptype=$Ptypes{$p};
98
                my $Prange=$Pranges{$p};
99
                my $type=($Ptype eq "input")? "Input" : ($Ptype eq "output")? 'Output' : 'Bidir';
100
                if (  $Prange ne ''){
101
                        my @r=split(":",$Prange);
102
                        my $a=($r[0]<$r[1])? $r[0] : $r[1];
103
                        my $b=($r[0]<$r[1])? $r[1] : $r[0];
104
                        for (my $i=$a; $i<=$b; $i++){
105
                                $board->board_add_pin ($type,"$p\[$i\]");
106
 
107
                        }
108 34 alirezamon
                }
109 38 alirezamon
                else {$board->board_add_pin ($type,$p);}
110
        }
111 34 alirezamon
        return $board;
112
}
113
 
114
 
115
 
116
 
117
sub gen_top_v{
118
        my ($self,$board,$name,$top)=@_;
119
 
120
        my $top_v=get_license_header("Top.v");
121
        #read port list 
122
        my $vdb=read_verilog_file($top);
123
        my %port_type=get_ports_type($vdb,"${name}_top");
124
        my %port_range=get_ports_rang($vdb,"${name}_top");
125
 
126
 
127
        my $io='';
128
        my $io_def='';
129
        my $io_assign='';
130
        my %board_io;
131
        my $first=1;
132
        foreach my $p (sort keys %port_type){
133
                my $porttype=$port_type{$p};
134
                my $portrange=$port_range{$p};
135
                my $assign_type = $self->object_get_attribute('compile_assign_type',$p);
136
                my $assign_name = $self->object_get_attribute('compile_pin',$p);
137
                my $range_hsb   = $self->object_get_attribute('compile_pin_range_hsb',$p);
138
                my $range_lsb   = $self->object_get_attribute('compile_pin_range_lsb',$p);
139
                my $assign="\t";
140
                if (defined $assign_name){
141
                        if($assign_name eq '*VCC'){
142
                                $assign= (length($portrange)!=0)? '{32{1\'b1}}' : '1\'b1';
143
                        } elsif ($assign_name eq '*GND'){
144
                                $assign= (length($portrange)!=0)? '{32{1\'b0}}' : '1\'b0';
145
                        }elsif ($assign_name eq '*NOCONNECT'){
146
                                $assign="\t";
147
 
148
                        }else{
149
 
150
                                $board_io{$assign_name}=$porttype;
151
 
152
 
153
                                my $range = (defined $range_hsb) ? "[$range_hsb : $range_lsb]" :
154
                                            (defined $range_lsb) ?  "[ $range_lsb]" : " ";
155
                                my $l=(defined $assign_type)?
156
                                        ($assign_type eq 'Direct') ? '' : '~' : '';
157
                                $assign="$l $assign_name $range";
158
 
159
 
160
                        }
161
                }
162
                $io_assign= ($first)? "$io_assign \t  .$p($assign)":"$io_assign,\n \t  .$p($assign)";
163
                $first=0;
164
        }
165
        $first=1;
166
        foreach my $p (sort keys %board_io){
167
                        $io=($first)? "\t$p" : "$io,\n\t$p";
168
                        my $dir=$board_io{$p};
169
                        my $range;
170
                        my $type= ($dir eq  'input') ? 'Input' :
171
                                  ($dir eq  'output')? 'Output' : 'Bidir';
172
                        my @r= $board->board_get_pin_range($type,$p);
173
                        if ($r[0] eq '*undefine*'){
174
                                $range="\t\t\t";
175
                        } else {
176
                                my ($min, $max) = minmax @r;
177
                                $range="\t[$max : $min]\t";
178
                        }
179
                        $io_def = "$io_def \t $dir $range $p;\n";
180
                        $first=0;
181
 
182
        }
183
        $top_v="$top_v
184
module Top (
185
$io
186
);
187
$io_def
188
 
189
        ${name}_top uut(
190
$io_assign
191
        );
192
 
193
 
194
endmodule
195
";
196
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
197
        my $board_top_file= "$fpath/Top.v";
198
        save_file($board_top_file,$top_v);
199
}
200
 
201
 
202
 
203
 
204
 
205
 
206
 
207
 
208
 
209
 
210
sub select_compiler {
211 38 alirezamon
        my ($self,$name,$top,$target_dir,$end_func)=@_;
212 34 alirezamon
        my $window = def_popwin_size(40,40,"Step 1: Select Compiler",'percent');
213
        #get the list of boards located in "boards/*" folder
214 38 alirezamon
        my @dirs = grep {-d} glob("../boards/*");
215 34 alirezamon
        my ($fpgas,$init);
216
        foreach my $dir (@dirs) {
217
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
218
                $init=$name;
219
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
220
        }
221
        my $table = def_table(2, 2, FALSE);
222
        my $col=0;
223
        my $row=0;
224
 
225 38 alirezamon
        my $compilers=$self->object_get_attribute('compile','compilers');#"QuartusII,Verilator,Modelsim"
226
 
227
        my $compiler=gen_combobox_object ($self,'compile','type',$compilers,"QuartusII",undef,undef);
228 34 alirezamon
        $table->attach(gen_label_in_center("Compiler tool"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
229
        $table->attach($compiler,$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
230
        $row++;$col=0;
231
 
232
 
233
 
234
        my $old_board_name=$self->object_get_attribute('compile','board');
235
        my $old_compiler=$self->object_get_attribute('compile','type');
236
        my $compiler_options = ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir):
237
                               ($old_compiler eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
238
                                                                gen_label_in_center(" ");
239
        $table->attach($compiler_options,$col,$col+2,$row,$row+1,'fill','shrink',2,2); $row++;
240
 
241
        $col=1;
242
        my $i;
243
        for ($i=$row; $i<5; $i++){
244
 
245
                my $temp=gen_label_in_center(" ");
246
                $table->attach_defaults ($temp, 0, 1 , $i, $i+1);
247
        }
248
        $row=$i;
249
 
250
 
251
        $window->add ($table);
252
        $window->show_all();
253
        my $next=def_image_button('icons/right.png','Next');
254
        $table->attach($next,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++;
255
        $next-> signal_connect("clicked" => sub{
256
                my $compiler_type=$self->object_get_attribute('compile','type');
257
                if($compiler_type eq "QuartusII"){
258
                        my $new_board_name=$self->object_get_attribute('compile','board');
259
                        if(defined $old_board_name) {
260 38 alirezamon
                                if ($old_board_name ne $new_board_name){
261
                                        remove_pin_assignment($self);
262
                                        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
263
                                        #delete jtag_intfc.sh file
264
                                        unlink "${fpath}../sw/jtag_intfc.sh";
265
                                        #program_device.sh file  
266
                                        unlink "${fpath}../program_device.sh";
267
                                }
268
 
269 34 alirezamon
                                my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
270
                                my $board_top_file= "$fpath/Top.v";
271
                                unlink $board_top_file if ($old_board_name ne $new_board_name);
272
 
273
 
274
                        }
275 38 alirezamon
                        if($new_board_name eq "Add New Board") {add_new_fpga_board($self,$name,$top,$target_dir,$end_func);}
276
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func);}
277 34 alirezamon
                }elsif($compiler_type eq "Modelsim"){
278
                        modelsim_compilation($self,$name,$top,$target_dir);
279
 
280
                }else{#verilator
281 38 alirezamon
                        verilator_compilation_win($self,$name,$top,$target_dir);
282 34 alirezamon
 
283
                }
284
 
285
                $window->destroy;
286
 
287
        });
288
 
289
        $compiler->signal_connect("changed" => sub{
290
                $compiler_options->destroy;
291
                my $new_board_name=$self->object_get_attribute('compile','type');
292
                $compiler_options = ($new_board_name eq "QuartusII")? select_board  ($self,$name,$top,$target_dir):
293
                                    ($new_board_name eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
294
                                 gen_label_in_center(" ");
295
                $table->attach($compiler_options,0,2,1,2,'fill','shrink',2,2);
296
                $table->show_all;
297
 
298
        });
299
 
300
}
301
 
302
 
303
 
304
 
305
 
306
sub select_board {
307
        my ($self,$name,$top,$target_dir)=@_;
308
 
309
        #get the list of boards located in "boards/*" folder
310 38 alirezamon
        my @dirs = grep {-d} glob("../boards/*");
311 34 alirezamon
        my ($fpgas,$init);
312 38 alirezamon
        $fpgas="Add New Board";
313
 
314 34 alirezamon
        foreach my $dir (@dirs) {
315
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
316 38 alirezamon
 
317
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
318
                $init="$name";
319 34 alirezamon
        }
320
        my $table = def_table(2, 2, FALSE);
321
        my $col=0;
322
        my $row=0;
323
 
324
 
325
        my $old_board_name=$self->object_get_attribute('compile','board');
326 38 alirezamon
        $table->attach(gen_label_help("The list of supported boards are obtained from \"mpsoc/boards/\" path. You can add your boards by adding its required files in aformentioned path. Note that currently only Altera FPGAs are supported. For boards from other vendors, you need to directly use their own compiler and call $name.v file in your top level module.",'Targeted Board:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
327 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++;
328
 
329
        my $bin = $self->object_get_attribute('compile','quartus_bin');
330
        my $Quartus_bin=  $ENV{QUARTUS_BIN};
331
        $col=0;
332
        $self->object_add_attribute('compile','quartus_bin',$ENV{QUARTUS_BIN}) if (!defined $bin && defined $Quartus_bin);
333
        $table->attach(gen_label_help("Path to quartus/bin directory. You can set a default path as QUARTUS_BIN envirement variable in ~/.bashrc file.
334
e.g:  export QUARTUS_BIN=/home/alireza/altera/13.0sp1/quartus/bin",'Quartus  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
335
        $table->attach(get_dir_in_object ($self,'compile','quartus_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
336
 
337
        return $table;
338
 
339
}
340
 
341
sub select_model_path {
342
        my ($self,$name,$top,$target_dir)=@_;
343
 
344
 
345
        my $table = def_table(2, 2, FALSE);
346
        my $col=0;
347
        my $row=0;
348
 
349
 
350
 
351
 
352
        my $bin = $self->object_get_attribute('compile','modelsim_bin');
353
        my $modelsim_bin=  $ENV{MODELSIM_BIN};
354
        $col=0;
355
        $self->object_add_attribute('compile','modelsim_bin',$modelsim_bin) if (!defined $bin && defined $modelsim_bin);
356
        $table->attach(gen_label_help("Path to modelsim/bin directory. You can set a default path as MODELSIM_BIN envirement variable in ~/.bashrc file.
357
e.g.  export MODELSIM_BIN=/home/alireza/altera/modeltech/bin",'Modelsim  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
358
        $table->attach(get_dir_in_object ($self,'compile','modelsim_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
359
 
360
        return $table;
361
 
362
}
363
 
364
 
365
sub remove_pin_assignment{
366
        my $self=shift;
367
        $self->object_remove_attribute('compile_pin_pos');
368
        $self->object_remove_attribute('compile_pin');
369
        $self->object_remove_attribute('compile_assign_type');
370
        $self->object_remove_attribute('compile_pin_range_hsb');
371
        $self->object_remove_attribute('compile_pin_range_lsb');
372
}
373
 
374
 
375 38 alirezamon
 
376
 
377
 
378
sub add_new_fpga_board{
379
        my ($self,$name,$top,$target_dir,$end_func)=@_;
380
        my $window = def_popwin_size(50,80,"Add New FPGA Board",'percent');
381
        my $table = def_table(2, 2, FALSE);
382
        my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
383
        $scrolled_win->set_policy( "automatic", "automatic" );
384
        $scrolled_win->add_with_viewport($table);
385
 
386
 
387
        my $mtable = def_table(10, 10, FALSE);
388
 
389
        my $next=def_image_button('icons/plus.png','Add');
390
        my $back=def_image_button('icons/left.png','Previous');
391
    my $auto=def_image_button('icons/advance.png','Auto-fill');
392
 
393
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
394
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
395
        $mtable->attach($auto,5,6,9,10,'shrink','shrink',2,2);
396
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
397
 
398
        set_tip($auto, "Auto-fill JTAG configuration. The board must be powered on and be connecred to the PC.");
399
 
400
 
401
 
402
        my $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
403
        my ($Twin,$tview)=create_text();
404
        add_colors_to_textview($tview);
405
 
406
        my $v1=gen_vpaned($widgets,0.3,$Twin);
407
 
408
        $table->attach_defaults($v1,0,3,0,2);
409
        #$table->attach_defaults( $Twin,0,3,1,2);       
410
 
411
 
412
 
413
 
414
        $back-> signal_connect("clicked" => sub{
415
 
416
                $window->destroy;
417
                select_compiler($self,$name,$top,$target_dir,$end_func);
418
 
419
        });
420
 
421
        $next-> signal_connect("clicked" => sub{
422
                my $result = add_new_fpga_board_files($self);
423
                if(! defined $result ){
424
                        select_compiler($self,$name,$top,$target_dir,$end_func);
425
                        message_dialog("The new board has been added successfully!");
426
 
427
                        $window->destroy;
428
 
429
                }else {
430
                        show_info(\$tview," ");
431
                        show_colored_info(\$tview,$result,'red');
432
 
433
                }
434
 
435
 
436
 
437
        });
438
 
439
        $auto-> signal_connect("clicked" => sub{
440
                my $pid;
441
                my $hw;
442
                my $dir = Cwd::getcwd();
443
                my $project_dir   = abs_path("$dir/../../"); #mpsoc directory address           
444
                my $command=  "$project_dir/mpsoc/src_c/jtag/jtag_libusb/list_usb_dev";
445
                add_info(\$tview,"$command\n");
446
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
447
                if(length $stderr>1){
448
                        add_colored_info(\$tview,"$stderr\n",'red');
449
                        add_colored_info(\$tview,"$command was not run successfully!\n",'red');
450
                }else {
451
 
452
                        if($exit){
453
                                add_colored_info(\$tview,"$stdout\n",'red');
454
                                add_colored_info(\$tview,"$command was not run successfully!\n",'red');
455
                        }else{
456
                                add_info(\$tview,"$stdout\n");
457
                                my @a=split /vid=9fb/, $stdout;
458
                                if(defined $a[1]){
459
                                        my @b=split /pid=/, $a[1];
460
                                        my @c=split /\n/, $b[1];
461
                                        $pid=$c[0];
462
                                        $self->object_add_attribute('compile','quartus_pid',$pid);
463
                                        add_colored_info(\$tview,"Detected PID: $pid\n",'blue');
464
 
465
                                }else{
466
                                        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');
467
                                        return;
468
                                }
469
                        }
470
                }
471
 
472
 
473
                $command=  "$ENV{QUARTUS_BIN}/jtagconfig";
474
                add_info(\$tview,"$command\n");
475
                ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
476
                if(length $stderr>1){
477
                        add_colored_info(\$tview,"$stderr\n",'red');
478
                        add_colored_info(\$tview,"$command was not run successfully!\n",'red');
479
                }else {
480
 
481
                        if($exit){
482
                                add_colored_info(\$tview,"$stdout\n",'red');
483
                                add_colored_info(\$tview,"$command was not run successfully!\n",'red');
484
                        }else{
485
                                add_info(\$tview,"$stdout\n");
486
                                my @a=split /1\)\s+/, $stdout;
487
                                if(defined $a[1]){
488
                                        my @b=split /\s+/, $a[1];
489
                                        $hw=$b[0];
490
                                        $self->object_add_attribute('compile','quartus_hardware',$hw);
491
                                        add_colored_info(\$tview,"Detected Hardware: $hw\n",'blue');
492
                                        my $qsf=$self->object_get_attribute('compile','quartus_qsf');
493
                                        if(!defined $qsf ){
494
                                                add_colored_info (\$tview,"Cannot detect devce location in JTAG chin. Please enter the QSF file or fill in manually \n",'red');
495
 
496
                                        }else{
497
                                                #search for device nam ein qsf file
498
                                                $qsf=add_project_dir_to_addr($qsf);
499
                                                if (!(-f $qsf)){
500
                                                        add_colored_info (\$tview, "Error Could not find $qsf file!\n");
501
                                                        return;
502
                                                }
503
                                                my $str=load_file($qsf);
504
                                                my $dw= capture_string_between(' DEVICE ',$str,"\n");
505
                                                if(defined $dw){
506
                                                add_colored_info(\$tview,"Device name in qsf file is: $dw\n",'blue');
507
                                                @b=split /\n/, $a[1];
508
 
509
                                                #capture device name in JTAG chain
510
                                                        my @f=(0);
511
                                                        foreach my $c (@b){
512
                                                                my @e=split /\s+/, $c;
513
                                                                push(@f,$e[2]) if(defined $e[2]);
514
                                                        }
515
 
516
                                                        my $pos=find_the_most_similar_position($dw ,@f);
517
                                                        $self->object_add_attribute('compile','quartus_device',$pos);
518
                                                add_colored_info(\$tview,"$dw has the most similarity with $f[$pos] in JTAG chain\n",'blue');
519
 
520
 
521
                                            }else{
522
                                                add_colored_info (\$tview, "Could not find device name in the $qsf file!\n");
523
                                            }
524
 
525
                                        }
526
 
527
 
528
                                }else{
529
                                        #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');
530
 
531
                                }
532
 
533
                        }
534
                }
535
                $widgets->destroy();
536
                $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
537
                $v1-> pack1($widgets, TRUE, TRUE);
538
                #$table->attach_defaults($widgets,0,3,0,1); 
539
                $table->show_all();
540
         #      my $cmd=" $ENV{'QUARTUS_BIN'}"
541
 
542
        });
543
 
544
 
545
 
546
        $window->add ($mtable);
547
        $window->show_all();
548
 
549
}
550
 
551
 
552
 
553
 
554
 
555
 
556
 
557
 
558
 
559
 
560
sub add_new_fpga_board_widgets{
561
        my ($self,$name,$top,$target_dir,$end_func)=@_;
562
        my $table = def_table(2, 2, FALSE);
563
 
564
        my $help1="FPGA Board name. Do not use any space in given name";
565
        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).";
566
        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).";
567
        my $help4="FPGA Borad USB-Blaster product ID (PID). Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find PID. Optinally you can run mpsoc/
568
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)";
569
        my $help5="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your hardware name. Optinally you can run \$QUARTUS_BIN/jtagconfig to find your programming hardware name.
570
an example of output from the 'jtagconfig' command:
571
\t  1) ByteBlasterMV on LPT1
572
\t       090010DD   EPXA10
573
\t       049220DD   EPXA_ARM922
574
or
575
\t   1) DE-SoC [1-3]
576
\t       48A00477   SOCVHP5
577
\t       02D020DC   5CS(EBA6ES|XFC6c6ES)
578
ByteBlasterMV \& DE-SoC are the programming hardware name.";
579
my $help6="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your devive location in jtag chain. Optinally you can run \$QUARTUS_BIN/jtagconfig to find your target device location in jtag chain.";
580
 
581
 
582
 
583
 
584
        my @info = (
585
        { label=>"FPGA Borad name:",                   param_name=>'quartus_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
586
        { label=>'FPGA board golden top QSF file:',    param_name=>'quartus_qsf',   type=>"FILE_path", default_val=>undef, content=>"qsf", info=>$help2, param_parent=>'compile', ref_delay=>undef},
587
        { label=>"FPGA board golden top verilog file", param_name=>'quartus_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef },
588
        );
589
 
590
        my @usb = (
591
        { label=>"FPGA Borad USB Blaster PID:",        param_name=>'quartus_pid',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help4, param_parent=>'compile', ref_delay=> undef},
592
        { label=>"FPGA Borad Programming Hardware Name:", param_name=>'quartus_hardware',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
593
        { label=>"FPGA Borad 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},
594
        );
595
 
596
 
597
        my $col=0;
598
        my $row=0;
599
        foreach my $d (@info) {
600
                ($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");
601
        }
602
 
603
        my $labl=def_pack_vbox(FALSE, 0,(Gtk2::HSeparator->new,gen_label_in_center("FPGA Board JTAG Configuration"),Gtk2::HSeparator->new));
604
 
605
        $table->attach( $labl,0,3,$row,$row+1,'fill','shrink',2,2); $row++; $col=0;
606
 
607
        foreach my $d (@usb) {
608
                ($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");
609
        }
610
 
611
 
612
        return ($row, $col, $table);
613
}
614
 
615
 
616
 
617
 
618
 
619
sub add_new_fpga_board_files{
620
        my $self=shift;
621
 
622
        #check the board name
623
        my $board_name=$self->object_get_attribute('compile','quartus_board');
624
        return "Please define the Board Name\n" if(! defined $board_name );
625
        return "Please define the Board Name\n" if(length($board_name) ==0 );
626
        my $r=check_verilog_identifier_syntax($board_name);
627
        return "Error in given Board Name: $r\n" if(defined $r );
628
 
629
        #check qsf file 
630
        my $qsf=$self->object_get_attribute('compile','quartus_qsf');
631
        return "Please define the QSF file\n" if(!defined $qsf );
632
 
633
        #check v file 
634
        my $top=$self->object_get_attribute('compile','quartus_v');
635
        return "Please define the verilog file file\n" if(!defined $top );
636
 
637
        #check PID
638
        my $pid=$self->object_get_attribute('compile','quartus_pid');
639
        return "Please define the PID\n" if(! defined $pid );
640
        return "Please define the PID\n" if(length($pid) ==0 );
641
 
642
        #check Hardware name
643
        my $hw=$self->object_get_attribute('compile','quartus_hardware');
644
        return "Please define the Hardware Name\n" if(! defined $hw );
645
        return "Please define the Hardware Name\n" if(length($hw) ==0 );
646
 
647
 
648
        #check Device name name
649
        my $dw=$self->object_get_attribute('compile','quartus_device');
650
        return "Please define targeted Device location in JTAG chain. The device location must be larger than zero.\n" if( $dw == 0 );
651
 
652
 
653
 
654
        #make board directory
655
        my $dir = Cwd::getcwd();
656
        my $path="$dir/../boards/$board_name";
657
        mkpath($path,1,01777);
658
        return "Error cannot make $path path" if ((-d $path)==0);
659
 
660
        #generate new qsf file
661
        $qsf=add_project_dir_to_addr($qsf);
662
        $top=add_project_dir_to_addr($top);
663
        open my $file, "<", $qsf or return "Error Could not open $qsf file in read mode!";
664
        open my $newqsf, ">", "$path/$board_name.qsf" or return "Error Could not create $path/$board_name.qsf file in write mode!";
665
 
666
        #remove the lines contain following strings
667
        my @p=("TOP_LEVEL_ENTITY","VERILOG_FILE","SYSTEMVERILOG_FILE","VHDL_FILE","AHDL_FILE","PROJECT_OUTPUT_DIRECTORY" );
668
        while (my $line = <$file>){
669
                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
670
 
671
                }
672
 
673
                else{
674
                        print $newqsf $line;
675
                }
676
 
677
        }
678
        print $newqsf "\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files\n";
679
 
680
        close $newqsf;
681
        close $file;
682
        copy($top,"$path/$board_name.v");
683
 
684
        #generate jtag_intfc.sh
685
        open $file, ">", "$path/jtag_intfc.sh" or return "Error: Could not create $path/jtag_intfc.sh file in write mode!";
686
        my $jtag;
687
        if($pid eq 6001 || $pid eq 6002 || $pid eq 6003){
688
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_libusb -a \$PRODUCT_ID\"";
689
 
690
        }else{
691
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_quartus_stp -a \$HARDWARE_NAME -b \$DEVICE_NAME\"";
692
 
693
        }
694
        print $file "#!/bin/sh
695
 
696
PRODUCT_ID=\"0x$pid\"
697
HARDWARE_NAME=\'$hw *\'
698
DEVICE_NAME=\"\@$dw*\"
699
 
700
$jtag
701
 
702
        ";
703
        close $file;
704
 
705
 
706
        #generate program_device.sh
707
        open $file, ">", "$path/program_device.sh" or return "Error: Could not create $path/program_device.sh file in write mode!";
708
 
709
 
710
print $file "#!/bin/sh
711
 
712
#usage:
713
#       sh program_device.sh  programming_file.sof
714
 
715
#programming file
716
#given as an argument:  \$1
717
 
718
#Programming mode
719
PROG_MODE=jtag
720
 
721
#cable name. Connect the board to ur PC and then run jtagconfig in terminal to find the cable name
722
NAME=\"$hw\"
723
 
724
#device name
725
DEVICE=\@$dw".'
726
 
727
 
728
#programming command
729
if [ -n "${QUARTUS_BIN+set}" ]; then
730
  $QUARTUS_BIN/quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
731
else
732
  quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
733
fi
734
';
735
 
736
close $file;
737
$self->object_add_attribute('compile','board',$board_name);
738
 
739
        return undef;
740
}
741
 
742 34 alirezamon
sub  get_pin_assignment{
743 38 alirezamon
        my ($self,$name,$top,$target_dir,$end_func)=@_;
744 34 alirezamon
        my $window = def_popwin_size(80,80,"Step 2: Pin Assignment",'percent');
745
 
746
        my $table = def_table(2, 2, FALSE);
747
        my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
748
        $scrolled_win->set_policy( "automatic", "automatic" );
749
        $scrolled_win->add_with_viewport($table);
750
 
751
 
752
        my $mtable = def_table(10, 10, FALSE);
753
 
754
        my $next=def_image_button('icons/right.png','Next');
755
        my $back=def_image_button('icons/left.png','Previous');
756
 
757
 
758
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
759
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
760
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
761
 
762 38 alirezamon
 
763 34 alirezamon
 
764 38 alirezamon
 
765 34 alirezamon
 
766 38 alirezamon
        my $board_name=$self->object_get_attribute('compile','board');
767 42 alirezamon
 
768 38 alirezamon
        #copy board jtag_intfc.sh file 
769
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
770 42 alirezamon
        copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
771
        my $n= $self->object_get_attribute('soc_name',undef);
772
        if(!defined $n){        # we are compiling a complete NoC-based mpsoc                                           
773
                my $nx= $self->object_get_attribute('noc_param',"NX");
774
                my $ny= $self->object_get_attribute('noc_param',"NY");
775
                for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
776
                        my $tile_num= $y*$nx+$x;
777
                        #print "$tile_num\n";
778
                        my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
779
                        next if(!defined $soc_name);
780
                        copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
781
                }}
782
 
783
        }
784
 
785
 
786 34 alirezamon
 
787 38 alirezamon
        #copy board program_device.sh file 
788
        copy("../boards/$board_name/program_device.sh","${fpath}../program_device.sh");
789 34 alirezamon
 
790
        #get boards pin list
791 38 alirezamon
        my $top_v= "../boards/$board_name/$board_name.v";
792
        if(!-f $top_v){
793
                message_dialog("Error: Could not load the board pin list. The $top_v does not exist!");
794 34 alirezamon
                $window->destroy;
795
        }
796 38 alirezamon
 
797
        my $board=read_top_v_file($top_v);
798 34 alirezamon
 
799
        # Write object file
800
        #open(FILE,  ">lib/soc/tttttttt") || die "Can not open: $!";
801
        #print FILE Data::Dumper->Dump([\%$board],['board']);
802
        #close(FILE) || die "Error closing file: $!";
803
 
804
        my @dirs = ('Input', 'Bidir', 'Output');
805
        my %models;
806
        foreach my $p (@dirs){
807
                my %pins=$board->board_get_pin($p);
808
                $models{$p}=gen_combo_model(\%pins);
809
 
810
        }
811
 
812
        my $row=0;
813
        my $col=0;
814
        my @lables= ('Port Direction','Port Range     ','Port name      ','Assigment Type','Board Port name ','Board Port Range');
815
        foreach my $p (@lables){
816
                my $l=gen_label_in_left($p);
817
                $l->set_markup("<b>  $p    </b>");
818
                $table->attach ($l, $col,$col+1, $row, $row+1,'fill','shrink',2,2);
819
                $col++
820
        }
821
        $row++;
822
 
823
 
824
        #read port list 
825
        my $vdb=read_verilog_file($top);
826
        my %port_type=get_ports_type($vdb,"${name}_top");
827
        my %port_range=get_ports_rang($vdb,"${name}_top");
828
        my %param = $vdb->get_modules_parameters("${name}_top");
829
 
830
        foreach my $p (sort keys %port_type){
831
                my $porttype=$port_type{$p};
832
                my $portrange=$port_range{$p};
833
 
834
                if  (length($portrange)!=0){
835
                        #replace parameter with their values            
836
                        my @a= split (/\b/,$portrange);
837 42 alirezamon
 
838 34 alirezamon
                        foreach my $l (@a){
839
                                my $value=$param{$l};
840
                                if(defined $value){
841
                                        chomp $value;
842
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
843 42 alirezamon
                                #       print"($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l})\n";
844 34 alirezamon
                                }
845
                        }
846
                        $portrange = "[ $portrange ]" ;
847
                }
848
 
849
                my $label1= gen_label_in_left("  $porttype");
850
                my $label2= gen_label_in_left("  $portrange");
851
                my $label3= gen_label_in_left("  $p");
852
 
853
                $table->attach($label1, 0,1, $row, $row+1,'fill','shrink',2,2);
854
                $table->attach($label2, 1,2, $row, $row+1,'fill','shrink',2,2);
855
                $table->attach($label3, 2,3, $row, $row+1,'fill','shrink',2,2);
856
 
857
                my $assign_type= "Direct,Negate(~)";
858
                if ($porttype eq  'input') {
859
                        my $assign_combo=gen_combobox_object($self,'compile_assign_type',$p,$assign_type,'Direct',undef,undef);
860
                        $table->attach( $assign_combo, 3,4, $row, $row+1,'fill','shrink',2,2);
861
                }
862
 
863
                my $type= ($porttype eq  'input') ? 'Input' :
864
                          ($porttype eq  'output')? 'Output' : 'Bidir';
865
 
866
                my $combo= gen_tree_combo($models{$type});
867
                my $saved=$self->object_get_attribute('compile_pin_pos',$p);
868
                my $box;
869
                my $loc=$row;
870
                if(defined $saved) {
871
                          my @indices=@{$saved};
872
                          my $path = Gtk2::TreePath->new_from_indices(@indices);
873
                          my $iter = $models{$type}->get_iter($path);
874
                          undef $path;
875
                          $combo->set_active_iter($iter);
876
                          $box->destroy if(defined $box);
877
                          my $text=$self->object_get_attribute('compile_pin',$p);
878
                          $box=get_range ($board,$self,$type,$text,$portrange,$p);
879
                          $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
880
                }
881
 
882
 
883
 
884
 
885
                $combo->signal_connect("changed" => sub{
886
 
887
                        #get and saved new value
888
                        my $treeiter=  $combo->get_active_iter();
889
                        my $text = $models{$type}->get_value($treeiter, 0);
890
                        $self->object_add_attribute('compile_pin',$p,$text);
891
                        #get and saved value position in model
892
                        my $treepath = $models{$type}->get_path ($treeiter);
893
                        my @indices=   $treepath->get_indices();
894
                        $self->object_add_attribute('compile_pin_pos',$p,\@indices);
895
                        #update borad port range
896
                        $box->destroy if(defined $box);
897
                        $box=get_range ($board,$self,$type,$text,$portrange,$p);
898
                        $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
899
                        $table->show_all;
900
 
901
                });
902
 
903
                $table->attach($combo, 4,5, $row, $row+1,'fill','shrink',2,2);
904
 
905
 
906
 
907
 
908
 
909
 
910
 
911
                $row++;
912
 
913
        }
914
        $next-> signal_connect("clicked" => sub{
915
 
916
                $window->destroy;
917 38 alirezamon
                quartus_compilation($self,$board,$name,$top,$target_dir,$end_func);
918 34 alirezamon
 
919
        });
920
        $back-> signal_connect("clicked" => sub{
921
 
922
                $window->destroy;
923 38 alirezamon
                select_compiler($self,$name,$top,$target_dir,$end_func);
924 34 alirezamon
 
925
        });
926
 
927
 
928
        $window->add ($mtable);
929
        $window->show_all();
930
}
931
 
932
 
933
 
934
 
935
 
936
sub quartus_compilation{
937 38 alirezamon
        my ($self,$board,$name,$top,$target_dir,$end_func)=@_;
938
 
939
        my $run=def_image_button('icons/gate.png','Compile');
940 34 alirezamon
        my $back=def_image_button('icons/left.png','Previous');
941 38 alirezamon
        my $regen=def_image_button('icons/refresh.png','Regenerate Top.v');
942
        my $prog=def_image_button('icons/write.png','Program the board');
943 34 alirezamon
 
944
 
945
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
946
        my $board_top_file ="${fpath}Top.v";
947
        unless (-e $board_top_file ){
948
                gen_top_v($self,$board,$name,$top) ;
949
        }
950
 
951
        my ($app,$table,$tview,$window) = software_main($fpath,'Top.v');
952
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
953
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
954 38 alirezamon
        $table->attach ($run,7, 8, 1,2,'shrink','shrink',2,2);
955
        $table->attach($prog,9,10,1,2,'shrink','shrink',2,2);
956 34 alirezamon
 
957
 
958 38 alirezamon
 
959 34 alirezamon
        $regen-> signal_connect("clicked" => sub{
960
                my $dialog = Gtk2::MessageDialog->new (my $window,
961
                                      'destroy-with-parent',
962
                                      'question', # message type
963
                                      'yes-no', # which set of buttons?
964
                                      "Are you sure you want to regenaret the Top.v file? Note that any changes you have made will be lost");
965
                my $response = $dialog->run;
966
                if ($response eq 'yes') {
967
                        gen_top_v($self,$board,$name,$top);
968
                        $app->load_source("$board_top_file");
969
                }
970
                $dialog->destroy;
971
 
972
        });
973
 
974
 
975
 
976
        $back-> signal_connect("clicked" => sub{
977
 
978
                $window->destroy;
979
                get_pin_assignment($self,$name,$top,$target_dir);
980
 
981
        });
982
 
983
 
984
        #compile
985
        $run-> signal_connect("clicked" => sub{
986
                set_gui_status($self,'save_project',1);
987
                $app->do_save();
988
                my $error = 0;
989
                add_info(\$tview,"CREATE: start creating Quartus project in $target_dir\n");
990
 
991
                #get list of source file
992
                add_info(\$tview,"        Read the list of all source files $target_dir/src_verilog\n");
993
                my @files = File::Find::Rule->file()
994
                            ->name( '*.v','*.V','*.sv' )
995
                            ->in( "$target_dir/src_verilog" );
996
 
997
                #make sure source files have key word 'module' 
998
                my @sources;
999
                foreach my $p (@files){
1000
                        push (@sources,$p)      if(check_file_has_string($p,'module'));
1001
                }
1002
                my $files = join ("\n",@sources);
1003
                add_info(\$tview,"$files\n");
1004
 
1005
                #creat project qsf file
1006
                my $qsf_file="$target_dir/${name}.qsf";
1007
                save_file ($qsf_file,"# Generated using ProNoC\n");
1008
 
1009
                #append global assignets to qsf file
1010
                my $board_name=$self->object_get_attribute('compile','board');
1011 38 alirezamon
                my @qsfs =   glob("../boards/$board_name/*.qsf");
1012 34 alirezamon
                if(!defined $qsfs[0]){
1013 38 alirezamon
                        message_dialog("Error: ../boards/$board_name folder does not contain the qsf file.!");
1014 34 alirezamon
                        $window->destroy;
1015
                }
1016
 
1017
 
1018
                my $assignment_file =  $qsfs[0];
1019
 
1020
                if(-f $assignment_file){
1021
                        merg_files ($assignment_file,$qsf_file);
1022
                }
1023
 
1024
 
1025
                #add the list of source fils to qsf file
1026
                my $s="\n\n\n set_global_assignment -name TOP_LEVEL_ENTITY Top\n";
1027
                foreach my $p (@sources){
1028
                        my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
1029
                        $s="$s set_global_assignment -name VERILOG_FILE $p\n" if ($suffix eq ".v");
1030
                        $s="$s set_global_assignment -name SYSTEMVERILOG_FILE $p\n" if ($suffix eq ".sv");
1031
 
1032
                }
1033
                append_text_to_file($qsf_file,$s);
1034
                add_info(\$tview,"\n Qsf file has been created\n");
1035
 
1036
                #start compilation
1037
                my $Quartus_bin= $self->object_get_attribute('compile','quartus_bin');;
1038
                add_info(\$tview, "Start Quartus compilation.....\n");
1039
                my @compilation_command =(
1040
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status' ",
1041
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status' ",
1042
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status' ",
1043
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_sta --64bit $name;echo \$? > status' ");
1044
 
1045
                foreach my $cmd (@compilation_command){
1046
                        add_info(\$tview,"$cmd\n");
1047
                        unlink "$target_dir/status";
1048
                        my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout( $cmd);
1049
                        open(my $fh,  "<$target_dir/status") || die "Can not open: $!";
1050
                        read($fh,my $status,1);
1051
                        close($fh);
1052
                        if("$status" != "0"){
1053
                                ($stdout,$exit)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/output_files/\" \n grep -h \"Error (\" *");
1054
                                add_colored_info(\$tview,"$stdout\n Quartus compilation failed !\n",'red');
1055
                                $error=1;
1056
                                last;
1057
                        }
1058
                }
1059
                add_colored_info(\$tview,"Quartus compilation is done successfully in $target_dir!\n", 'blue') if($error==0);
1060 38 alirezamon
                if (defined $end_func){
1061
                        if ($error==0){
1062
                                $end_func->($self);
1063
                                $window->destroy;
1064
                        }else {
1065
                                message_dialog("Error in Quartus compilation!",'error');
1066
                        }
1067
                }
1068 34 alirezamon
 
1069
        });
1070
 
1071
 
1072 38 alirezamon
        #Programe the board 
1073
        $prog-> signal_connect("clicked" => sub{
1074
                my $error = 0;
1075
                my $sof_file="$target_dir/output_files/${name}.sof";
1076
                my $bash_file="$target_dir/program_device.sh";
1077 34 alirezamon
 
1078 38 alirezamon
                add_info(\$tview,"Programe the board using quartus_pgm and $sof_file file\n");
1079
                #check if the programming file exists
1080
                unless (-f $sof_file) {
1081
                        add_colored_info(\$tview,"\tThe $sof_file does not exists! Make sure you have compiled the code successfully.\n", 'red');
1082
                        $error=1;
1083
                }
1084
                #check if the program_device.sh file exists
1085
                unless (-f $bash_file) {
1086
                        add_colored_info(\$tview,"\tThe $bash_file does not exists! This file veries depend on your target board and must be available inside mpsoc/boards/[board_name].\n", 'red');
1087
                        $error=1;
1088
                }
1089
                return if($error);
1090
                my $command = "sh $bash_file $sof_file";
1091
                add_info(\$tview,"$command\n");
1092
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
1093
                if(length $stderr>1){
1094
                        add_colored_info(\$tview,"$stderr\n",'red');
1095
                        add_colored_info(\$tview,"Board was not programed successfully!\n",'red');
1096
                }else {
1097 34 alirezamon
 
1098 38 alirezamon
                        if($exit){
1099
                                add_colored_info(\$tview,"$stdout\n",'red');
1100
                                add_colored_info(\$tview,"Board was not programed successfully!\n",'red');
1101
                        }else{
1102
                                add_info(\$tview,"$stdout\n");
1103
                                add_colored_info(\$tview,"Board is programed successfully!\n",'blue');
1104 34 alirezamon
 
1105 38 alirezamon
                        }
1106
 
1107
                }
1108
        });
1109 34 alirezamon
 
1110
 
1111
}
1112
 
1113
 
1114
 
1115
 
1116
 
1117
 
1118
sub modelsim_compilation{
1119
        my ($self,$name,$top,$target_dir)=@_;
1120
        #my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
1121
 
1122
 
1123
        my $run=def_image_button('icons/run.png','run');
1124
        my $back=def_image_button('icons/left.png','Previous');
1125
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
1126
        #create testbench.v
1127
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir) if ((-f "$target_dir/src_verilog/testbench.v")==0);
1128
 
1129
 
1130
 
1131
        my ($app,$table,$tview,$window) = software_main("$target_dir/src_verilog",'testbench.v');
1132
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
1133
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
1134
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
1135
 
1136
 
1137
 
1138
        $regen-> signal_connect("clicked" => sub{
1139
                my $dialog = Gtk2::MessageDialog->new (my $window,
1140
                                      'destroy-with-parent',
1141
                                      'question', # message type
1142
                                      'yes-no', # which set of buttons?
1143
                                      "Are you sure you want to regenaret the testbench.v file? Note that any changes you have made will be lost");
1144
                my $response = $dialog->run;
1145
                if ($response eq 'yes') {
1146
                        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir);
1147
                        $app->load_source("$target_dir/src_verilog/testbench.v");
1148
                }
1149
                $dialog->destroy;
1150
 
1151
        });
1152
 
1153
 
1154
 
1155
 
1156
 
1157
 
1158
        $back-> signal_connect("clicked" => sub{
1159
 
1160
                $window->destroy;
1161
                select_compiler($self,$name,$top,$target_dir);
1162
 
1163
        });
1164
 
1165
 
1166
        #creat modelsim dir
1167
        add_info(\$tview,"creat Modelsim dir in $target_dir\n");
1168
        my $model="$target_dir/Modelsim";
1169
        rmtree("$model");
1170 42 alirezamon
        rmtree("$target_dir/rtl_work");
1171 34 alirezamon
        mkpath("$model/rtl_work",1,01777);
1172
 
1173
        #create modelsim.tcl file
1174
my $tcl="#!/usr/bin/tclsh
1175
 
1176
 
1177
transcript on
1178
if {[file exists rtl_work]} {
1179
        vdel -lib rtl_work -all
1180
}
1181
vlib rtl_work
1182
vmap work rtl_work
1183
";
1184
 
1185
#Get the list of  all verilog files in src_verilog folder
1186
        add_info(\$tview,"Get the list of all verilog files in src_verilog folder\n");
1187
        my @files = File::Find::Rule->file()
1188
                ->name( '*.v','*.V','*.sv' )
1189
                ->in( "$target_dir/src_verilog" );
1190
#make sure source files have key word 'module' 
1191
        my @sources;
1192
        foreach my $p (@files){
1193
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
1194
                if(check_file_has_string($p,'module')){
1195
                        if ($suffix eq ".sv"){$tcl=$tcl."vlog -sv -work work +incdir+$path \{$p\}\n";}
1196
                        else {$tcl=$tcl."vlog -vlog01compat -work work +incdir+$path \{$p\}\n";}
1197
                }
1198
        }
1199
 
1200
$tcl="$tcl
1201
vsim -t 1ps  -L rtl_work -L work -voptargs=\"+acc\"  testbench
1202
 
1203
add wave *
1204
view structure
1205
view signals
1206
run -all
1207
";
1208 38 alirezamon
        add_info(\$tview,"Create run.tcl file\n");
1209 34 alirezamon
        save_file ("$model/run.tcl",$tcl);
1210
        $run -> signal_connect("clicked" => sub{
1211
                set_gui_status($self,'save_project',1);
1212
                $app->do_save();
1213
                my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
1214
                my $cmd="cd $target_dir; $modelsim_bin/vsim -do $model/run.tcl";
1215 42 alirezamon
 
1216 38 alirezamon
                add_info(\$tview,"$cmd\n");
1217 34 alirezamon
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
1218 38 alirezamon
                if(length $stderr>1){
1219
                        add_colored_info(\$tview,"$stderr\n","red");
1220
 
1221 34 alirezamon
                }else {
1222
                        add_info(\$tview,"$stdout\n");
1223
                }
1224
 
1225
        });
1226
 
1227
        #$window->show_all();
1228
}
1229
 
1230
 
1231 38 alirezamon
# source files : $target_dir/src_verilog
1232
# work dir : $target_dir/src_verilog
1233 34 alirezamon
 
1234
sub verilator_compilation {
1235 38 alirezamon
        my ($top_ref,$target_dir,$outtext)=@_;
1236 34 alirezamon
 
1237 38 alirezamon
        my %tops = %{$top_ref};
1238 34 alirezamon
        #creat verilator dir
1239
        add_info(\$outtext,"creat verilator dir in $target_dir\n");
1240
        my $verilator="$target_dir/verilator";
1241
        rmtree("$verilator/rtl_work");
1242
        rmtree("$verilator/processed_rtl");
1243
        mkpath("$verilator/rtl_work/",1,01777);
1244
        mkpath("$verilator/processed_rtl/",1,01777);
1245
 
1246
 
1247
        #copy all verilog files in rtl_work folder
1248
        add_info(\$outtext,"Copy all verilog files in rtl_work folder\n");
1249
        my @files = File::Find::Rule->file()
1250 38 alirezamon
                ->name( '*.v','*.V','*.sv','*.vh')
1251 42 alirezamon
                ->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
1252 34 alirezamon
        foreach my $file (@files) {
1253
                copy($file,"$verilator/rtl_work/");
1254
        }
1255 38 alirezamon
 
1256
        @files = File::Find::Rule->file()
1257
                ->name( '*.sv','*.vh' )
1258 42 alirezamon
            ->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
1259 38 alirezamon
        foreach my $file (@files) {
1260
                copy($file,"$verilator/processed_rtl");
1261
        }
1262
 
1263
 
1264 34 alirezamon
 
1265
        #"split all verilog modules in separate  files"
1266
        add_info(\$outtext,"split all verilog modules in separate files\n");
1267
        my $split = Verilog::EditFiles->new
1268
        (outdir => "$verilator/processed_rtl",
1269
        translate_synthesis => 0,
1270
        celldefine => 0,
1271
        );
1272
        $split->read_and_split(glob("$verilator/rtl_work/*.v"));
1273
        $split->write_files();
1274 38 alirezamon
        $split->read_and_split(glob("$verilator/rtl_work/*.sv"));
1275
        $split->write_files();
1276 34 alirezamon
 
1277 42 alirezamon
 
1278 34 alirezamon
        #run verilator
1279
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e sh -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
1280 38 alirezamon
        foreach my $top (sort keys %tops) {
1281 42 alirezamon
                add_colored_info(\$outtext,"Generate $top Verilator model from $tops{$top} file\n",'green');
1282
                my $cmd= "cd \"$verilator/processed_rtl\" \n  verilator  --cc $tops{$top}  --prefix \"$top\" -O3  -CFLAGS -O3";
1283 38 alirezamon
                add_info(\$outtext,"$cmd\n");
1284
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
1285
                if(length $stderr>1){
1286
                        add_info(\$outtext,"$stderr\n");
1287
                }else {
1288
                        add_info(\$outtext,"$stdout\n");
1289
                }
1290
        }
1291
 
1292 34 alirezamon
 
1293
        #check if verilator model has been generated 
1294 38 alirezamon
        foreach my $top (sort keys %tops) {
1295
                if (-f "$verilator/processed_rtl/obj_dir/$top.cpp"){#succsess
1296
 
1297 42 alirezamon
 
1298 38 alirezamon
                }else {
1299
                        return 0;
1300
                }
1301
        }
1302 42 alirezamon
        #generate makefile
1303
        gen_verilator_makefile($top_ref,"$verilator/processed_rtl/obj_dir/Makefile");
1304 38 alirezamon
        return 1;
1305
}
1306
 
1307
 
1308
sub gen_verilator_makefile{
1309
        my ($top_ref,$target_dir) =@_;
1310
        my %tops = %{$top_ref};
1311
        my $p='';
1312
        my $q='';
1313
        my $h='';
1314
        my $l;
1315 42 alirezamon
        my $lib_num=0;
1316
        my $all_lib="";
1317 38 alirezamon
        foreach my $top (sort keys %tops) {
1318
                $p = "$p ${top}__ALL.a ";
1319 42 alirezamon
                $q = $q."lib$lib_num:\n\t\$(MAKE) -f ${top}.mk\n";
1320 38 alirezamon
                $h = "$h ${top}.h ";
1321
                $l = $top;
1322 42 alirezamon
                $all_lib=$all_lib." lib$lib_num";
1323
                $lib_num++;
1324 38 alirezamon
        }
1325
 
1326
 
1327
        my $make= "
1328
 
1329
default: sim
1330
 
1331
 
1332
 
1333
include $l.mk
1334
 
1335 42 alirezamon
lib: $all_lib
1336
 
1337 38 alirezamon
$q
1338
 
1339
 
1340
#######################################################################
1341
# Compile flags
1342
 
1343
CPPFLAGS += -DVL_DEBUG=1
1344
ifeq (\$(CFG_WITH_CCWARN),yes)  # Local... Else don't burden users
1345
CPPFLAGS += -DVL_THREADED=1
1346
CPPFLAGS += -W -Werror -Wall
1347
endif
1348
 
1349
#######################################################################
1350
# Linking final exe -- presumes have a sim_main.cpp
1351
 
1352
 
1353
sim:    testbench.o \$(VK_GLOBAL_OBJS) $p
1354
        \$(LINK) \$(LDFLAGS) -g \$^ \$(LOADLIBES) \$(LDLIBS) -o testbench \$(LIBS) -Wall -O3 2>&1 | c++filt
1355
 
1356
testbench.o: testbench.cpp $h
1357
 
1358
clean:
1359 42 alirezamon
        rm *.o *.a testbench
1360 38 alirezamon
";
1361
 
1362
 
1363
 
1364
save_file ($target_dir,$make);
1365
 
1366
 
1367
 
1368
 
1369
}
1370
 
1371
 
1372
 
1373
sub verilator_compilation_win {
1374
        my ($self,$name,$top,$target_dir)=@_;
1375
        my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
1376
        my $mtable = def_table(10, 10, FALSE);
1377
        my ($outbox,$outtext)= create_text();
1378
        add_colors_to_textview($outtext);
1379
        my $next=def_image_button('icons/run.png','Next');
1380
        my $back=def_image_button('icons/left.png','Previous');
1381
 
1382
 
1383
        $mtable->attach_defaults ($outbox ,0, 10, 4,9);
1384
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
1385
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
1386
 
1387
 
1388
 
1389
        $back-> signal_connect("clicked" => sub{
1390
 
1391
                $window->destroy;
1392
                select_compiler($self,$name,$top,$target_dir);
1393
 
1394
        });
1395
        $next-> signal_connect("clicked" => sub{
1396
 
1397
                $window->destroy;
1398
                verilator_testbench($self,$name,$top,$target_dir);
1399
 
1400
        });
1401 42 alirezamon
 
1402
        $window->add ($mtable);
1403
        $window->show_all();
1404
 
1405
 
1406
        my $result;
1407
 
1408
        my $n= $self->object_get_attribute('soc_name',undef);
1409
        if(defined $n){ #we are compiling a single tile as SoC
1410
                my %tops;
1411
                $tops{"Vtop"}= "$name.v";
1412
                $result = verilator_compilation (\%tops,$target_dir,$outtext);
1413
                $self->object_add_attribute('verilator','libs',\%tops);
1414
        }
1415
        else { # we are compiling a complete NoC-based mpsoc
1416
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext);
1417
 
1418
 
1419
        }
1420
 
1421
 
1422 38 alirezamon
        #check if verilator model has been generated 
1423
        if ($result){
1424 34 alirezamon
                add_colored_info(\$outtext,"Veriator model has been generated successfully!",'blue');
1425
        }else {
1426
                add_colored_info(\$outtext,"Verilator compilation failed!\n","red");
1427
                $next->destroy();
1428
        }
1429
 
1430
 
1431
 
1432
 
1433 42 alirezamon
 
1434 34 alirezamon
 
1435
 
1436
 
1437
}
1438
 
1439 38 alirezamon
 
1440
 
1441 42 alirezamon
 
1442
 
1443
sub  gen_mpsoc_verilator_model{
1444
        my ($self,$name,$top,$target_dir,$outtext)=@_;
1445
        my $dir = Cwd::getcwd();
1446
        my $project_dir   = abs_path("$dir/..");
1447
        my $src_verilator_dir="$project_dir/src_verilator";
1448
        my $sw_dir      = "$target_dir/sw";
1449
 
1450
 
1451
        #copy src_verilator files
1452
        add_info(\$outtext,"Copy verilator files\n");
1453
        my @files=(
1454
                "$src_verilator_dir/noc_connection.sv",
1455
                "$src_verilator_dir/router_verilator.v"
1456
        );
1457
        if (-d "$target_dir/src_verilator/"==0){
1458
                mkpath("$target_dir/src_verilator/",1,01777);
1459
        }
1460
        copy_file_and_folders (\@files,$project_dir,"$target_dir/src_verilator");
1461
 
1462
        #create each tile top module 
1463
        my $nx= $self->object_get_attribute('noc_param',"NX");
1464
    my $ny= $self->object_get_attribute('noc_param',"NY");
1465
    my $processors_en=0;
1466
    my $mpsoc=$self;
1467
 
1468
    my $lisence= get_license_header("verilator_tiles");
1469
        my $warning=autogen_warning();
1470
    my $verilator=$lisence.$warning;
1471
 
1472
 
1473
    # generate NoC parameter file
1474
        my ($noc_param,$pass_param)=gen_noc_param_v($self);
1475
 
1476
        my $noc_param_v= " \`ifdef     INCLUDE_PARAM \n \n
1477
        $noc_param
1478
        /* verilator lint_off WIDTH */
1479
        localparam  P=(TOPOLOGY==\"RING\" || TOPOLOGY==\"LINE\")? 3 : 5;
1480
        localparam  ROUTE_TYPE = (ROUTE_NAME == \"XY\" || ROUTE_NAME == \"TRANC_XY\" )?    \"DETERMINISTIC\" :
1481
                        (ROUTE_NAME == \"DUATO\" || ROUTE_NAME == \"TRANC_DUATO\" )?   \"FULL_ADAPTIVE\": \"PAR_ADAPTIVE\";
1482
        /* verilator lint_on WIDTH */
1483
        //simulation parameter
1484
 
1485
\n \n \`endif" ;
1486
        save_file("$target_dir/src_verilator/parameter.v",$noc_param_v);
1487
 
1488
 
1489
 
1490
   my %tops = (
1491
        "Vrouter" => "router_verilator.v",
1492
        "Vnoc" => "noc_connection.sv"
1493
    );
1494
 
1495
    for (my $y=0;$y<$ny;$y++){
1496
                for (my $x=0; $x<$nx;$x++){
1497
 
1498
                my $tile_num= $y*$nx+$x;
1499
                #print "$tile_num\n";
1500
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num);
1501
                if(!defined $soc_name){
1502
                        #this tile is not connected to any ip. the noc input ports will be connected to ground
1503
                                my $soc_v="\n\n // Tile:$tile_num (x=$x,y=$y)   is not assigned to any ip\n";
1504
                                $soc_v="$soc_v
1505
 
1506
        assign ni_credit_out[$tile_num]={V{1'b0}};
1507
        assign ni_flit_out[$tile_num]={Fw{1'b0}};
1508
        assign ni_flit_out_wr[$tile_num]=1'b0;
1509
        ";
1510
                next;
1511
 
1512
                }
1513
                my $soc=eval_soc($mpsoc,$soc_name,$outtext);
1514
 
1515
 
1516
                my $top=$mpsoc->mpsoc_get_soc($soc_name);
1517
                my $soc_num= $y*$nx+$x;
1518
 
1519
 
1520
 
1521
 
1522
                #update core id
1523
                $soc->object_add_attribute('global_param','CORE_ID',$tile_num);
1524
                #update NoC param
1525
                #my %nocparam = %{$mpsoc->object_get_attribute('noc_param',undef)};
1526
                my $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
1527
                my @nis=get_NI_instance_list($top);
1528
                $soc->soc_add_instance_param($nis[0] ,$nocparam );
1529
                my $tile=($nx*$y)+ $x;
1530
 
1531
                my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
1532
                my %params;
1533
                if ($setting eq 'Custom'){
1534
                         %params= $top->top_get_custom_soc_param($tile);
1535
                }else{
1536
                         %params=$top->top_get_default_soc_param();
1537
                }
1538
 
1539
 
1540
                my $sw_path     = "$sw_dir/tile$tile_num";
1541
                $verilator = $verilator.soc_generate_verilatore ($soc,$sw_path,"tile_$tile",\%params);
1542
                $tops{"Vtile$tile_num"}= "tile_$tile.v";
1543
 
1544
 
1545
        }}
1546
 
1547
        save_file ("$target_dir/src_verilator/verilator_tiles.v",$verilator);
1548
        my $result = verilator_compilation (\%tops,$target_dir,$outtext);
1549
        $self->object_add_attribute('verilator','libs',\%tops);
1550
        return $result;
1551
 
1552
}
1553
 
1554
 
1555 34 alirezamon
sub gen_verilator_soc_testbench {
1556
        my ($self,$name,$top,$target_dir)=@_;
1557
        my $verilator="$target_dir/verilator";
1558
        my $dir="$verilator/";
1559
        my $soc_top= $self->soc_get_top ();
1560 42 alirezamon
 
1561 34 alirezamon
        my @intfcs=$soc_top->top_get_intfc_list();
1562
        my %PP;
1563
        my $top_port_info="IO type\t  port_size\t  port_name\n";
1564
        foreach my $intfc (@intfcs){
1565
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
1566
                         ( $intfc eq 'plug:reset[0]')? 'reset':
1567
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
1568
                my $key1="${key}1";
1569
                my $key0="${key}0";
1570
 
1571
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
1572
                foreach my $p (@ports){
1573
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
1574
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} top->$p=1;\n" : "top->$p=1;\n";
1575
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} top->$p=0;\n" : "top->$p=0;\n";
1576
                        $top_port_info="$top_port_info $type  $range  top->$p \n";
1577
                }
1578
 
1579
 
1580
        }
1581
        my $main_c=get_license_header("testbench.cpp");
1582
$main_c="$main_c
1583
#include <stdlib.h>
1584
#include <stdio.h>
1585
#include <unistd.h>
1586
#include <string.h>
1587
#include <verilated.h>          // Defines common routines
1588
#include \"Vtop.h\"               // From Verilating \"$name.v\" file
1589
 
1590
Vtop                    *top;
1591
/*
1592
$top_port_info
1593
*/
1594
 
1595
int reset,clk;
1596
unsigned int main_time = 0; // Current simulation time
1597
 
1598
int main(int argc, char** argv) {
1599
        Verilated::commandArgs(argc, argv);   // Remember args
1600
        top     = new Vtop;
1601
 
1602
        /********************
1603
        *       initialize input
1604
        *********************/
1605
 
1606
        $PP{reset1}
1607
        $PP{en1}
1608
        main_time=0;
1609
        printf(\"Start Simulation\\n\");
1610
        while (!Verilated::gotFinish()) {
1611
 
1612
                if (main_time >= 10 ) {
1613
                        $PP{reset0}
1614
                }
1615
 
1616
 
1617
                if ((main_time & 1) == 0) {
1618
                        $PP{clk1}      // Toggle clock
1619
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
1620
 
1621
 
1622
 
1623
                }//if
1624
                else
1625
                {
1626
                        $PP{clk0}
1627
 
1628
 
1629
 
1630
                }//else
1631
 
1632
 
1633
                main_time ++;
1634
                top->eval();
1635
                }
1636
        top->final();
1637
}
1638
 
1639
double sc_time_stamp () {       // Called by \$time in Verilog
1640
        return main_time;
1641
}
1642
";
1643
        save_file("$dir/testbench.cpp",$main_c);
1644
 
1645
 
1646
 
1647
}
1648
 
1649 42 alirezamon
sub eval_soc{
1650
        my ($mpsoc,$soc_name,$outtext)=@_;
1651
        my $path=$mpsoc->object_get_attribute('setting','soc_path');
1652
        $path=~ s/ /\\ /g;
1653
        my $p = "$path/$soc_name.SOC";
1654
        my  $soc = eval { do $p };
1655
        if ($@ || !defined $soc){
1656
                show_info(\$outtext,"**Error reading  $p file: $@\n");
1657
               next;
1658
        }
1659
        return $soc;
1660
}
1661 34 alirezamon
 
1662 42 alirezamon
 
1663
sub gen_verilator_mpsoc_testbench {
1664
        my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
1665
        my $verilator="$target_dir/verilator";
1666
        my $dir="$verilator/";
1667
        #my $soc_top= $self->soc_get_top ();
1668
 
1669
        my $nx= $mpsoc->object_get_attribute('noc_param',"NX");
1670
    my $ny= $mpsoc->object_get_attribute('noc_param',"NY");
1671
 
1672
        my $libh="";
1673
        my $inst= "";
1674
        my $newinst="";
1675
 
1676
        my $tile_x="";
1677
        my $tile_y="";
1678
        my $tile_flit_in="";
1679
        my $tile_flit_in_l="";
1680
        my $tile_credit="";
1681
        my $noc_credit="";
1682
        my $noc_flit_in="";
1683
        my $noc_flit_in_l="";
1684
        my $noc_flit_in_wr="";
1685
        my $noc_flit_in_wr_l="";
1686
        my $tile_flit_in_wr="";
1687
        my $tile_flit_in_wr_l="";
1688
        my $tile_eval="";
1689
        my $tile_final="";
1690
        my $tile_reset="";
1691
        my $tile_clk="";
1692
        my $tile_en="";
1693
        my $top_port_info="IO type\t  port_size\t  port_name\n";
1694
        my $no_connected='';
1695
 
1696
        for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
1697
                my $t= $y*$nx+$x;
1698
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($t);
1699
                if(defined $soc_name) {#we have a conncted tile
1700
 
1701
                        #get ni instance name
1702
                        my $ni_name;
1703
                        my $soc=eval_soc($mpsoc,$soc_name,$tview);
1704
                        my $soc_top=$soc->object_get_attribute('top_ip',undef);
1705
                        my @intfcs=$soc_top->top_get_intfc_list();
1706
                        my @instances=$soc->soc_get_all_instances();
1707
                        foreach my $id (@instances){
1708
                                        my $category = $soc->soc_get_category($id);
1709
                                        if ($category eq 'NoC') {
1710
                                                 $ni_name=  $soc->soc_get_instance_name($id);
1711
                                        }
1712
                        }
1713
 
1714
 
1715
                                $libh=$libh."#include \"Vtile${t}.h\"\n";
1716
                                $inst=$inst."Vtile${t}\t*tile${t};\t  // Instantiation of tile${t}\n";
1717
                                $newinst = $newinst."\ttile${t}\t=\tnew Vtile${t};\n";
1718
                                $tile_flit_in = $tile_flit_in . "\ttile${t}->${ni_name}_flit_in  = noc->ni_flit_out [${t}];\n";
1719
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${t}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${t}][j];\n";
1720
                                $tile_credit= $tile_credit."\ttile${t}->${ni_name}_credit_in= noc->ni_credit_out[${t}];\n";
1721
                                $noc_credit= $noc_credit."\tnoc->ni_credit_in[${t}] = tile${t}->${ni_name}_credit_out;\n";
1722
                                $noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${t}]  = tile${t}->${ni_name}_flit_out;\n";
1723
                                $noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${t}][j]  = tile${t}->${ni_name}_flit_out[j];\n";
1724
                                $noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${t}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${t});\n";
1725
                                $tile_flit_in_wr=$tile_flit_in_wr."\ttile${t}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${t}) & 0x01);\n";
1726
                                $noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${t}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${t});\n";
1727
                                $tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${t}->${ni_name}_flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,${t})>0);\n";
1728
                                $tile_eval=$tile_eval."\ttile${t}->eval();\n";
1729
                                $tile_final=$tile_final."\ttile${t}->final();\n";
1730
 
1731
 
1732
 
1733
 
1734
 
1735
 
1736
                                foreach my $intfc (@intfcs){
1737
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
1738
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
1739
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
1740
                                                         'other';
1741
 
1742
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
1743
                                        foreach my $p (@ports){
1744
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
1745
                                                $tile_reset=$tile_reset."\t\ttile${t}->$p=reset;\n" if $key eq 'reset';
1746
                                                $tile_clk=$tile_clk."\t\ttile${t}->$p=clk;\n" if $key eq 'clk';
1747
                                                $tile_en=$tile_en."\t\ttile${t}->$p=enable;\n" if $key eq 'en'; ;
1748
                                                $top_port_info="$top_port_info $type  $range  tile${t}->$p \n";
1749
                                        }#ports
1750
 
1751
                                }#interface
1752
 
1753
                                $tile_x= $tile_x."\ttile${t}->${ni_name}_current_x=$x;\n";
1754
                                $tile_y= $tile_y."\ttile${t}->${ni_name}_current_y=$y;\n";
1755
                        }else{
1756
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
1757
                                $no_connected=$no_connected."\n // Tile:$t (x=$x,y=$y)   is not assigned to any ip\n";
1758
                                $no_connected=$no_connected."\t\tnoc->ni_credit_in[${t}]=0; \n";
1759
 
1760
                        }
1761
 
1762
 
1763
        }}
1764
        my $main_c=get_license_header("testbench.cpp");
1765
$main_c="$main_c
1766
#include <stdlib.h>
1767
#include <stdio.h>
1768
#include <unistd.h>
1769
#include <string.h>
1770
#include <verilated.h>          // Defines common routines
1771
 
1772
#include \"Vnoc.h\"
1773
#include \"Vrouter.h\"
1774
$libh
1775
 
1776
 
1777
/*
1778
$top_port_info
1779
*/
1780
 
1781
 
1782
#ifndef  NX
1783
        #define  NX     $nx
1784
#endif
1785
 
1786
#ifndef  NY
1787
        #define  NY     $ny
1788
#endif
1789
 
1790
#ifndef  NC
1791
        #define  NC             ($nx*$ny)
1792
#endif
1793
 
1794
 
1795
Vrouter                 *router[NC];                     // Instantiation of router
1796
Vnoc                    *noc;
1797
$inst
1798
 
1799
 
1800
 
1801
int reset,clk,enable;
1802
unsigned int main_time = 0; // Current simulation time
1803
 
1804
void update_all_instances_inputs(void);
1805
 
1806
 
1807
int main(int argc, char** argv) {
1808
        int i,j,x,y;
1809
 
1810
        Verilated::commandArgs(argc, argv);   // Remember args
1811
 
1812
        for(i=0;i<NC;i++)       router[i]       = new Vrouter;             // Create instance
1813
        noc                                                             = new Vnoc;
1814
$newinst
1815
 
1816
        /********************
1817
        *       initialize input
1818
        *********************/
1819
 
1820
 
1821
        reset=1;
1822
        enable=1;
1823
        $no_connected
1824
        for(x=0;x<NX;x++)for(y=0;y<NY;y++){
1825
                                        i=(y*NX)+x;
1826
                                        router[i]->current_x            = x;
1827
                                        router[i]->current_y            = y;
1828
        }
1829
$tile_x
1830
$tile_y
1831
 
1832
        main_time=0;
1833
        printf(\"Start Simulation\\n\");
1834
        while (!Verilated::gotFinish()) {
1835
 
1836
                if (main_time >= 10 ) {
1837
                        reset=0;
1838
                }
1839
 
1840
 
1841
                if ((main_time % 5) == 0) {
1842
                        clk = 1;       // Toggle clock
1843
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
1844
 
1845
                }
1846
                else{
1847
                        clk = 0;       // Toggle clock
1848
                        update_all_instances_inputs();
1849
 
1850
 
1851
 
1852
                }
1853
 
1854
 
1855
                //clk,reset,enable
1856
                noc-> clk = clk;
1857
                noc-> reset = reset;
1858
$tile_reset
1859
$tile_clk
1860
$tile_en
1861
                for(i=0;i<NC;i++){
1862
                        router[i]->reset= reset;
1863
                        router[i]->clk= clk;
1864
                }
1865
 
1866
                //eval instances
1867
                noc->eval();
1868
                for(i=0;i<NC;i++) {
1869
                                router[i]->eval();
1870
                }
1871
$tile_eval
1872
 
1873
 
1874
                main_time++;
1875
 
1876
 
1877
 
1878
        }//while
1879
 
1880
        // Simulation is dne
1881
        for(i=0;i<NC;i++) {
1882
                router[i]->final();
1883
        }
1884
        noc->final();
1885
$tile_final
1886
}
1887
 
1888
double sc_time_stamp () {       // Called by \$time in Verilog
1889
        return main_time;
1890
}
1891
 
1892
 
1893
void update_all_instances_inputs(void){
1894
 
1895
        int x,y,i,j;
1896
        int flit_out_all_size = sizeof(router[0]->flit_out_all)/sizeof(router[0]->flit_out_all[0]);
1897
 
1898
#if (NC<=64)
1899
        noc->ni_flit_in_wr =0;
1900
#else
1901
        for(j=0;j<(sizeof(noc->ni_flit_in_wr)/sizeof(noc->ni_flit_in_wr[0])); j++) noc->ni_flit_in_wr[j]=0;
1902
#endif
1903
        for(x=0;x<NX;x++)for(y=0;y<NY;y++){
1904
                i=(y*NX)+x;
1905
                router[i]->flit_in_we_all = noc->router_flit_out_we_all[i];
1906
                router[i]->credit_in_all = noc->router_credit_out_all[i];
1907
                router[i]->congestion_in_all = noc->router_congestion_out_all[i];
1908
                for(j=0;j<flit_out_all_size;j++) router[i]->flit_in_all[j]      = noc->router_flit_out_all[i][j];
1909
                noc->router_flit_in_we_all[i] = router[i]->flit_out_we_all ;
1910
                noc->router_credit_in_all[i]    =       router[i]->credit_out_all;
1911
                noc->router_congestion_in_all[i]=       router[i]->congestion_out_all;
1912
                for(j=0;j<flit_out_all_size;j++) noc->router_flit_in_all[i][j]  = router[i]->flit_out_all[j] ;
1913
        }       //for
1914
 
1915
 
1916
 
1917
 
1918
#if (Fpay<=32)
1919
        //tile[i]->flit_in  = noc->ni_flit_out [i];
1920
$tile_flit_in
1921
#else
1922
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++){
1923
                //traffic[i]->flit_in[j]  = noc->ni_flit_out [i][j];
1924
$tile_flit_in_l
1925
        }
1926
#endif
1927
 
1928
        //traffic[i]->credit_in= noc->ni_credit_out[i];
1929
$tile_credit
1930
 
1931
        //noc->ni_credit_in[i] = traffic[i]->credit_out;
1932
$noc_credit
1933
 
1934
#if (Fpay<=32)
1935
        //noc->ni_flit_in [i]  = traffic[i]->flit_out;
1936
$noc_flit_in
1937
 
1938
#else
1939
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++){
1940
                 //noc->ni_flit_in [i][j]  = traffic[i]->flit_out[j];
1941
$noc_flit_in_l
1942
        }
1943
#endif
1944
 
1945
 
1946
#if (NC<=64)
1947
                //if(traffic[i]->flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<i);
1948
$noc_flit_in_wr
1949
 
1950
                //traffic[i]->flit_in_wr= ((noc->ni_flit_out_wr >> i) & 0x01);
1951
$tile_flit_in_wr
1952
#else
1953
                //if(traffic[i]->flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,i);
1954
$noc_flit_in_wr_l
1955
 
1956
                //traffic[i]->flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,i)>0);
1957
$tile_flit_in_wr_l
1958
 
1959
#endif
1960
 
1961
 
1962
 
1963
}
1964
";
1965
 
1966
        save_file("$dir/testbench.cpp",$main_c);
1967
 
1968
}
1969
 
1970
 
1971
 
1972
sub soc_get_all_parameters {
1973
        my $soc=shift;
1974
        my @instances=$soc->soc_get_all_instances();
1975
 
1976
        my %all_param;
1977
        foreach my $id (@instances){
1978
 
1979
                my $module      =$soc->soc_get_module($id);
1980
                my $category    =$soc->soc_get_category($id);
1981
                my $inst        = $soc->soc_get_instance_name($id);
1982
                my %params      = $soc->soc_get_module_param($id);
1983
                my $ip = ip->lib_new ();
1984
                my @param_order=$soc->soc_get_instance_param_order($id);
1985
 
1986
                foreach my $p (sort keys %params){
1987
                        my $inst_param= "$inst\_$p";
1988
                        #add instance name to parameter value
1989
                        $params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
1990
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
1991
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
1992
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
1993
                        $vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
1994
                        $all_param{ $inst_param} =      $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
1995
                        print"$all_param{ $inst_param} =        $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
1996
                }
1997
        }
1998
        return %all_param;
1999
}
2000
 
2001
sub soc_get_all_parameters_order {
2002
        my $soc=shift;
2003
        my @instances=$soc->soc_get_all_instances();
2004
        my $ip = ip->lib_new ();
2005
        my @all_order;
2006
        foreach my $id (@instances){
2007
                my $module      =$soc->soc_get_module($id);
2008
                my $category    =$soc->soc_get_category($id);
2009
                my $inst        = $soc->soc_get_instance_name($id);
2010
                my @order       = $soc->soc_get_instance_param_order($id);
2011
 
2012
                foreach my $p ( @order){
2013
                        my $inst_param= "$inst\_$p";
2014
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
2015
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
2016
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
2017
                        $vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
2018
                        push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
2019
                }
2020
        }
2021
        return @all_order;
2022
}
2023
 
2024
 
2025
 
2026 34 alirezamon
sub gen_modelsim_soc_testbench {
2027
        my ($self,$name,$top,$target_dir)=@_;
2028
        my $dir="$target_dir/src_verilog";
2029
        my $soc_top= $self->object_get_attribute('top_ip',undef);
2030
        my @intfcs=$soc_top->top_get_intfc_list();
2031
        my %PP;
2032
        my $top_port_def="// ${name}.v IO definition \n";
2033
        my $pin_assign;
2034
        my $rst_inputs='';
2035
 
2036
 
2037
 
2038 42 alirezamon
 
2039
        #add functions
2040
        my $d = Cwd::getcwd();
2041
        open my $file1, "<", "$d/lib/verilog/functions.v" or die;
2042
        my $functions_all='';
2043
        while (my $f1 = readline ($file1)) {
2044
                 $functions_all="$functions_all $f1 ";
2045
        }
2046
        close($file1);
2047
 
2048
        #get parameters
2049
        my $params_v="";
2050
        my $n= $self->object_get_attribute('soc_name',undef);
2051
 
2052
        if(defined $n){ #we are compiling a single tile as SoC
2053
                my $core_id= $self->object_get_attribute('global_param','CORE_ID');
2054
                my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
2055
 
2056
                        $params_v="\tlocalparam\tCORE_ID=$core_id;
2057
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
2058
                my %params=soc_get_all_parameters($self);
2059
                my @order= soc_get_all_parameters_order($self);
2060
                foreach my $p (@order){
2061
                        add_text_to_string(\$params_v,"\tlocalparam  $p = $params{$p};\n") if(defined $params{$p} );
2062
                }
2063
        }else{ # we are simulating a mpsoc
2064
                $params_v= gen_socs_param($self);
2065
 
2066
 
2067
        }
2068 34 alirezamon
 
2069
        foreach my $intfc (@intfcs){
2070
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
2071
                         ( $intfc eq 'plug:reset[0]')? 'reset':
2072
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
2073
                my $key1="${key}1";
2074
                my $key0="${key}0";
2075
 
2076
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
2077
                my $f=1;
2078
                foreach my $p (@ports){
2079
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
2080
 
2081
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
2082
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
2083
 
2084
 
2085
                        if  (length($range)!=0){
2086 42 alirezamon
#                               #replace parameter with their values            #
2087
#                               my @a= split (/\b/,$range);
2088
#                               print "a=@a\n";
2089
#                               foreach my $l (@a){
2090
#                                       my $value=$params{$l};
2091
#                                       if(defined $value){
2092
#                                               chomp $value;
2093
#                                               ($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l});
2094
#                                               print "($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l}); \n";
2095
#                                       }
2096
#                               }
2097 34 alirezamon
                                $range = "[ $range ]" ;
2098
                        }
2099
 
2100
 
2101
 
2102 42 alirezamon
 
2103
 
2104 34 alirezamon
                        if($type eq 'input'){
2105
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
2106
                        }else{
2107
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
2108
                        }
2109
                        $pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)":  "\t\t.$p($p)";
2110
                        $rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
2111
                }
2112
 
2113
 
2114
        }
2115
 
2116
my $test_v= get_license_header("testbench.v");
2117
 
2118
$test_v ="$test_v
2119
 
2120
`timescale       1ns/1ps
2121
 
2122
module testbench;
2123
 
2124 42 alirezamon
$functions_all
2125
 
2126
$params_v
2127
 
2128 34 alirezamon
$top_port_def
2129
 
2130
 
2131
        $name uut (
2132
$pin_assign
2133
        );
2134
 
2135
//clock defination
2136
initial begin
2137
        forever begin
2138
        #5 $PP{clk0}
2139
        #5 $PP{clk1}
2140
        end
2141
end
2142
 
2143
 
2144
 
2145
initial begin
2146
        // reset $name module at the start up
2147
        $PP{reset1}
2148
        $PP{en1}
2149
        $rst_inputs
2150
        // deasert the reset after 200 ns
2151
        #200
2152
        $PP{reset0}
2153
 
2154
        // write your testbench here
2155
 
2156
 
2157
 
2158
 
2159
end
2160
 
2161
endmodule
2162
";
2163
        save_file("$dir/testbench.v",$test_v);
2164
 
2165
 
2166
 
2167
}
2168
 
2169
sub verilator_testbench{
2170
        my ($self,$name,$top,$target_dir)=@_;
2171
        my $verilator="$target_dir/verilator";
2172
        my $dir="$verilator";
2173 42 alirezamon
 
2174
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
2175
 
2176
        my $n= $self->object_get_attribute('soc_name',undef);
2177
        if(defined $n){ #we are compiling a single tile as SoC
2178
                gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
2179
        }
2180
        else { # we are compiling a complete NoC-based mpsoc
2181
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
2182
 
2183
        }
2184
 
2185 34 alirezamon
        #copy makefile
2186 38 alirezamon
        #copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile"); 
2187 34 alirezamon
 
2188
 
2189 42 alirezamon
 
2190 34 alirezamon
 
2191
 
2192
        my $make = def_image_button('icons/gen.png','Compile');
2193
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
2194
        my $run = def_image_button('icons/run.png','Run');
2195
        my $back=def_image_button('icons/left.png','Previous');
2196
 
2197
        $table->attach ($back,1,2,1,2,'shrink','shrink',0,0);
2198
        $table->attach ($regen,3,4,1,2,'shrink','shrink',0,0);
2199
        $table->attach ($make,7, 8, 1,2,'shrink','shrink',0,0);
2200
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
2201
 
2202
        $back-> signal_connect("clicked" => sub{
2203
 
2204
                $window->destroy;
2205 38 alirezamon
                verilator_compilation_win($self,$name,$top,$target_dir);
2206 34 alirezamon
 
2207
        });
2208
 
2209
        $regen-> signal_connect("clicked" => sub{
2210
                my $dialog = Gtk2::MessageDialog->new (my $window,
2211
                                      'destroy-with-parent',
2212
                                      'question', # message type
2213
                                      'yes-no', # which set of buttons?
2214
                                      "Are you sure you want to regenaret the testbench.cpp file? Note that any changes you have made will be lost");
2215
                my $response = $dialog->run;
2216
                if ($response eq 'yes') {
2217 42 alirezamon
                        my $n= $self->object_get_attribute('soc_name',undef);
2218
                        if(defined $n){ #we are compiling a single tile as SoC
2219
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
2220
                        }
2221
                        else { # we are compiling a complete NoC-based mpsoc
2222
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
2223
 
2224
                        }
2225
 
2226 34 alirezamon
                        $app->load_source("$dir/testbench.cpp");
2227
                }
2228
                $dialog->destroy;
2229
 
2230
        });
2231
 
2232
 
2233
        $make -> signal_connect("clicked" => sub{
2234
                $app->do_save();
2235
                copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
2236 42 alirezamon
 
2237
                my $tops_ref=$self->object_get_attribute('verilator','libs');
2238
                my %tops=%{$tops_ref};
2239
                my $lib_num=0;
2240
 
2241
                foreach my $top (sort keys %tops) {
2242
                                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"lib$lib_num");
2243
                                $lib_num++;
2244
                }
2245
                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"sim");
2246 34 alirezamon
 
2247
        });
2248
 
2249
        $run -> signal_connect("clicked" => sub{
2250
                my $bin="$verilator/processed_rtl/obj_dir/testbench";
2251
                if (-f $bin){
2252
                        my $cmd= "cd \"$verilator/processed_rtl/obj_dir/\" \n xterm -e sh -c $bin";
2253
                        add_info(\$tview,"$cmd\n");
2254
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2255
                        if(length $stderr>1){
2256
                                add_colored_info(\$tview,"$stderr\n",'red');
2257
                        }else {
2258
                                add_info(\$tview,"$stdout\n");
2259
                        }
2260
 
2261
                }else{
2262
                        add_colored_info(\$tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
2263
                }
2264
 
2265
                });
2266
 
2267
 
2268
}
2269
 
2270
 
2271
1;

powered by: WebSVN 2.1.0

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