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 45

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

powered by: WebSVN 2.1.0

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