OpenCores
URL https://opencores.org/ocsvn/sv_dir_tb/sv_dir_tb/trunk

Subversion Repositories sv_dir_tb

[/] [sv_dir_tb/] [trunk/] [tb_gen/] [tb_gen_parser.tcl] - Blame information for rev 5

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

Line No. Rev Author Line
1 5 sckoarn
##-------------------------------------------------------------------------------
2
##                     Copyright 2019 Ken Campbell
3
##
4
##   Licensed under the Apache License, Version 2.0 (the "License");
5
##   you may not use this file except in compliance with the License.
6
##   You may obtain a copy of the License at
7
##
8
##     http://www.apache.org/licenses/LICENSE-2.0
9
##
10
##   Unless required by applicable law or agreed to in writing, software
11
##   distributed under the License is distributed on an "AS IS" BASIS,
12
##   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
##   See the License for the specific language governing permissions and
14
##   limitations under the License.
15
##-------------------------------------------------------------------------------
16
##-- $Author:  $ Ken Campbell
17
##-- $Date:  $ Jan. 2019
18
##-- $Id:  $
19
##-- $Source:  $
20
##-- Description :
21
##--      This application takes a text file containing the definition of a Verilog
22
##           module, produces a file set for the SV Directed Test Bench.
23
##--      This file is the parser and generator.
24
##------------------------------------------------------------------------------
25
proc pars_pindef { pins } {
26
    set pdef  {}
27
    set def_lst  {}
28
    set lc 0
29
 
30
    set logic_lst {}
31
    set dut_modport {}
32
    set names_lst {}
33
 
34
    foreach l $pins {
35
        set is_mult [string first "," $l]
36
        set is_bv   [string first "\[" $l]
37
        set l [string trim $l "\;"]
38
        ##  if is a vector def
39
        #puts $l
40
        #handle precompile
41
        set ispre [string first "`" $l]
42
        if {$ispre >= 0} {
43
            #strip `timescale
44
            if {[string first "timescale" $l] >= 0} {
45
                continue
46
            }
47
            lappend names_lst $l
48
            lappend logic_lst $l
49
            lappend dut_modport $l
50
            continue
51
        }
52
        #puts "is_bv:  $is_bv"
53
        if {$is_bv > 0} {
54
            set is_cbv [string first "\]" $l]
55
            set bv_spec [string range $l $is_bv $is_cbv]
56
            set type [string range $l 0 $is_bv-1]
57
            set names [string range $l $is_cbv+1 end]
58
            set snames [split $names ","]
59
            foreach n $snames {
60
                ##set n [string trim $n "\;"]
61
                lappend names_lst [string trim $n]
62
                if {$type != "inout"} {
63
                    set tmp "logic "
64
                } else {
65
                    set tmp "wire "
66
                }
67
                append tmp $bv_spec " [string trim $n]\;"
68
                lappend logic_lst $tmp
69
                set tmp [string trim $type]
70
                append tmp " [string trim $n],"
71
                lappend dut_modport $tmp
72
                #puts "$type $bv_spec [string trim $n]\;"
73
            }
74
        } else {
75
            set sl [split $l ","]
76
            set frst [split [lindex $sl 0]]
77
            set type [string trim [lindex $frst 0]]
78
            set fname [string trim [lindex $frst end]]
79
            set sl [lrange $sl 1 end]
80
            lappend names_lst [string trim $fname]
81
            if {$type != "inout"} {
82
                set tmp "logic "
83
            } else {
84
                set tmp "wire "
85
            }
86
            #set tmp "logic "
87
            append tmp "$fname\;"
88
            lappend logic_lst $tmp
89
            set tmp $type
90
            append tmp " $fname,"
91
            lappend dut_modport $tmp
92
            foreach n $sl {
93
                if {$n == ""} {
94
                    continue
95
                }
96
                puts $n
97
                lappend names_lst [string trim $n]
98
                if {$type != "inout"} {
99
                    set tmp "logic "
100
                } else {
101
                    set tmp "wire "
102
                }
103
                append tmp "[string trim $n]\;"
104
                lappend logic_lst $tmp
105
                set tmp $type
106
                append tmp " [string trim $n],"
107
                lappend dut_modport $tmp
108
            }
109
        }
110
    }
111
 
112
    lappend def_lst $logic_lst
113
    lappend def_lst $dut_modport
114
    lappend def_lst $names_lst
115
 
116
    return $def_lst
117
}
118
##  end pars_pindef
119
 
120
##--------------------------------------------------------------------------------
121
##  Write header to file passed
122
proc write_header { handle } {
123
    global version
124
    ##global scan_date
125
    set raw_date [clock scan now]
126
    set scan_date [clock format $raw_date -format "%d %b %Y %T"]
127
 
128
    ## so CVS will not modify selections, they have to be chopped up
129
    set auth "// \$Auth"
130
    append auth "or:  \$"
131
 
132
    puts $handle "///////////////////////////////////////////////////////////////////////////////"
133
    puts $handle "//             Copyright ///////////////////////////////////"
134
    puts $handle "//                        All Rights Reserved"
135
    puts $handle "///////////////////////////////////////////////////////////////////////////////"
136
    puts $handle "$auth"
137
    puts $handle "//"
138
    puts $handle "//"
139
    puts $handle "// Description :"
140
    puts $handle "//          This file was generated by SV TB Gen $version"
141
    puts $handle "//            on $scan_date"
142
    puts $handle "//////////////////////////////////////////////////////////////////////////////"
143
    puts $handle "// This software contains concepts confidential to ////////////////"
144
    puts $handle "// /////////. and is only made available within the terms of a written"
145
    puts $handle "// agreement."
146
    puts $handle "///////////////////////////////////////////////////////////////////////////////"
147
    puts $handle ""
148
  }
149
 
150
#####################################################################
151
##  A directory has been selected now fill the list win with *V files
152
proc fill_list {} {
153
    global ent_dir odir
154
    global tlist_ent use_list list_win ts_ent statsVar
155
    global view_win mo_sel sel_lst
156
 
157
    ## get the user selection
158
    browsed_from_set $ent_dir $ent_dir
159
    ## as a default make output dir = input dir
160
    set tmp_dir [$ent_dir get]
161
    $odir delete 0 end
162
    $odir insert end $tmp_dir
163
    $odir configure -state readonly
164
 
165
    ## clear the list window and selection
166
    #$list_win clear items
167
    #$list_win clear selection
168
    #$view_win clear
169
    ## get the working directory
170
    set dir [$ent_dir get]
171
    ## get the list of VHDL files in working directory
172
    set ftype ".*v"
173
    set file_lst ""
174
    set file_lst [glob -directory $dir *$ftype]
175
    #puts $file_lst
176
    ##  for each of the files in the file_lst
177
    foreach l $file_lst {
178
        ## creat string that is just the file name: no path
179
        puts "File : $l"
180
        set testt $l
181
        set nstart [string last "/" $l]
182
        incr nstart
183
        #puts "Index : $nstart"
184
        set name_str [string range $l $nstart end]
185
        set sel_lst [lappend sel_lst $name_str]
186
        #puts $sel_lst
187
        ## insert item on list
188
        #$list_win insert items 1 $name_str
189
    }
190
}
191
 
192
######################################################################
193
##  load the vhdl file that has just been selected from list_win
194
proc load_ent_file {} {
195
    global ent_dir list_win view_win statsVar gen_prog
196
 
197
    set gen_prog 0.0
198
    ## update selection with selected item
199
    #set fn [$list_win curselection]
200
    set sel_dx [$list_win curselection]
201
    if {$sel_dx == ""} {
202
        return
203
    }
204
    ## recover the selected item
205
    set ln [$list_win get $sel_dx]
206
    ##  Get the working directory
207
    #puts $ln
208
    set lp [$ent_dir get]
209
    ##  append the file name
210
    append lp "/" $ln
211
    ## if the file does not exist  return
212
    set fexist [file exist $lp]
213
    if {$fexist == 0} {
214
        return
215
    }
216
    set ent_file [open $lp r]
217
    ## clear the view_win
218
    $view_win delete 1.0 end
219
    set file_list {}
220
    ## load file to memory
221
    while {![eof $ent_file]} {
222
        ##  Get a line
223
        set rline [gets $ent_file]
224
        lappend file_list $rline
225
    }
226
    close $ent_file
227
    ## put file in text window and highlite the entity part
228
    set ent_found 0
229
    set in_ent 0
230
    set statsVar ""
231
    foreach l $file_list {
232
        if {$in_ent == 0} {
233
            set ent_def [string first module $l]
234
            if {$ent_def >= 0} {
235
                set ent_name [lindex $l 1]
236
                set statsVar "Module:  $ent_name found"
237
                set ent_found 1
238
                set in_ent 1
239
                $view_win insert end "$l\n" highlite
240
            } else {
241
                $view_win insert end "$l\n"
242
        }
243
    } else {
244
        set ent_def [string first "endmodule" $l]
245
        if {$ent_def >= 0} {
246
            set end_name [lindex $l 1]
247
            set end_found 1
248
            set in_ent 0
249
            $view_win insert end "$l\n" highlite
250
        } else {
251
                $view_win insert end "$l\n" highlite
252
        }
253
    }
254
    }
255
    if {$ent_found == 0} {
256
        set statsVar "No Module found!!"
257
    }
258
    ##$view_win import $lp
259
    ##$view_win yview moveto 1
260
    ##puts $lp
261
}
262
 
263
#########################################################################
264
proc ttb_gen {} {
265
    global mo_sel template ent_dir list_win odir p_view tdir
266
    global cpakv gbatv gen_prog comb_val m_select
267
 
268
    set template [$tdir get]
269
 
270
    $p_view configure -maximum 7
271
    set gen_prog 1.0
272
    ## recover the selected item
273
    #set sel_dx [$list_win curselection]
274
    set ln $m_select
275
    ##  Get the working directory
276
    #puts $ln
277
    set lp [$ent_dir get]
278
    ##  append the file name
279
    append lp "/" $ln
280
 
281
    set path_text $lp
282
    set destin_text [$odir get]
283
    set infile [open $path_text r]
284
    set file_list {}
285
 
286
 
287
##################################################################
288
##  Read in the file and strip comments as we do
289
    while {![eof $infile]} {
290
        ##  Get a line
291
        set rline [gets $infile]
292
        #puts $rline
293
        ## get rid of white space
294
        set rline [string trim $rline]
295
        ##  Find comment if there
296
        set cindex [string first "//" $rline]
297
        ## if a comment was found at the start of the line
298
        if {$cindex == 0 || $rline == ""} {
299
            continue
300
        ## else was not found so put line in list
301
        } elseif {$cindex > 0} {
302
            #  get rid of trailing comments and trim off spaces
303
            set rline [string trim [string range $rline 0 $cindex-1]]
304
            lappend file_list $rline
305
        } else {
306
            lappend file_list $rline
307
        }
308
    }
309
    close $infile
310
 
311
    $p_view step
312
    ## check for the module def
313
    set mod_name ""
314
    foreach l $file_list {
315
        set mod_def [string first module $l]
316
        if {$mod_def >= 0} {
317
            set ml [split $l]
318
            set mod_name [lindex $l 1]
319
            break
320
        }
321
    }
322
 
323
    #puts "Module name is: $mod_name"
324
    ## if no ent  die
325
    if {$mod_def < 0} {
326
        dbg_msg "A module definition was not found in the file provided."
327
        return
328
        ##  exit
329
    }
330
    $p_view step
331
    set mod_list {}
332
    ## check for end module
333
    foreach l $file_list {
334
        lappend mod_list $l
335
        set end_def [string first endmodule $l]
336
        if {$end_def >= 0} {
337
            break
338
        }
339
    }
340
    ## if no end die
341
    if {$end_def < 0} {
342
        dbg_msg "no endmodule statement found for this module"
343
        return
344
        ##  exit
345
    }
346
    ####
347
    ## collect the parameters if there are.
348
    set parameter_list {}
349
    set p_found 0
350
    foreach l $mod_list {
351
        set p_found [string first "parameter" $l]
352
        if {$p_found >= 0} {
353
            lappend $parameter_list $l
354
        }
355
    }
356
    set gen_prog 2.0
357
    #foreach l $mod_list {
358
    #    puts $l
359
    #}
360
    ####################################################################
361
    ##  a few checks have been done, and non-relevant stuff stripped off.
362
    ##  now create an arrry of just the pin names and related info
363
    set port_lst {}
364
    set lc 0
365
    foreach l $mod_list {
366
        ## make lines that are continued, one line.
367
        set cont [string first "\;" $l]
368
        #set tick [string first "`" $l]
369
        #if {$tick >= 0} {
370
        #    continue
371
        #}
372
        ## look for the port statements
373
        set inp [string first "input " $l]
374
        if {$inp >= 0} {
375
            lappend port_lst $l
376
        }
377
        set onp [string first "output " $l]
378
        if {$onp >= 0} {
379
            lappend port_lst $l
380
        }
381
        set ionp [string first "inout " $l]
382
        if {$ionp >= 0} {
383
            lappend port_lst $l
384
        }
385
        set tick_dir [string first "`" $l]
386
        if {$tick_dir >= 0} {
387
            lappend port_lst $l
388
        }
389
        #puts $port_lst
390
    }
391
 
392
    #foreach p $port_lst {
393
    #    puts $p
394
    #}
395
    ##  Change the port list into a pin info list
396
    set io_pins [pars_pindef $port_lst]
397
 
398
    set log_lst [lindex $io_pins 0]
399
    set mod_lst [lindex $io_pins 1]
400
    set name_lst [lindex $io_pins 2]
401
 
402
    #foreach r $log_lst {
403
    #    puts $r
404
    #}
405
    #foreach r $mod_lst {
406
    #    puts $r
407
    #}
408
    #foreach r $name_lst {
409
    #    puts $r
410
    #}
411
 
412
 
413
    # dbg_msg $split_pin
414
    ## calculate the longest pin name in characters
415
    set name_length 0
416
    foreach l $name_lst {
417
        set temp_length [string length $l]
418
        if {$temp_length > $name_length} {
419
            set name_length $temp_length
420
        }
421
    }
422
    #dbg_msg $name_length
423
    ##  Make the name length one bigger
424
    incr name_length
425
 
426
    set gen_prog 3.0
427
#$p_view step
428
#########################################################################
429
## Generate the tb top.
430
    set tfn $destin_text
431
    append tfn "/tb_top.sv"
432
    set tfh [open $tfn w]
433
 
434
    write_header $tfh
435
    puts $tfh "`include \"../sv/tb_prg.sv\""
436
    puts $tfh ""
437
    puts $tfh "module tb_top \(\)\;"
438
    puts $tfh ""
439
    puts $tfh "  string STM_FILE = \"../stm/stimulus_file.stm\"\;"
440
    puts $tfh "  string tmp_fn;"
441
    puts $tfh ""
442
    puts $tfh "  //  Handle plus args"
443
    puts $tfh "  initial begin : file_select"
444
    puts $tfh "    if\(\$value\$plusargs\(\"STM_FILE=%s\", tmp_fn\)\) begin"
445
    puts $tfh "      stm_file = tmp_fn\;"
446
    puts $tfh "    end"
447
    puts $tfh "  end"
448
    puts $tfh ""
449
    puts $tfh "  dut_if theif\(\)\;"
450
    puts $tfh ""
451
    puts $tfh "  $mod_name u1 \("
452
 
453
    set llen [llength $name_lst]
454
    set idx 1
455
    foreach n $name_lst {
456
        set ln $n
457
        set tick_dir [string first "`" $n]
458
        if {$tick_dir >= 0} {
459
            puts $tfh "    $n"
460
            incr idx
461
            continue
462
        }
463
        set len [string length $ln]
464
        while {$len < $name_length} {
465
            append ln " "
466
            set len [string length $ln]
467
        }
468
        if {$idx < $llen} {
469
            puts $tfh "    .$ln \(theif.$n\),"
470
        } else {
471
            puts $tfh "    .$ln \(theif.$n\)"
472
        }
473
        incr idx
474
    }
475
 
476
    puts $tfh "  \)\;"
477
    puts $tfh ""
478
    puts $tfh "  tb_mod prg_inst\(theif\)\;"
479
    puts $tfh ""
480
    puts $tfh "endmodule"
481
 
482
    close $tfh
483
    set gen_prog 4.0
484
    #$p_view step
485
############################################################################
486
##  generate the interface file.
487
    set ifn $destin_text
488
    append ifn "/dut_if.sv"
489
    set ifh [open $ifn w]
490
 
491
    write_header $ifh
492
    puts $ifh "interface dut_if\(\)\;"
493
    puts $ifh ""
494
    foreach l $log_lst {
495
        puts $ifh "  $l"
496
    }
497
 
498
    puts $ifh ""
499
    puts $ifh "  modport dut_conn\("
500
    set llen [llength $mod_lst]
501
    set idx 1
502
    foreach p $mod_lst {
503
        set tick_dir [string first "`" $l]
504
        if {$tick_dir >= 0} {
505
            puts $ifh "    $p"
506
            incr idx
507
            continue
508
        }
509
        if {$idx < $llen} {
510
            puts $ifh "    $p"
511
        } else {
512
            puts $ifh "    [string trim $p ","]"
513
        }
514
        incr idx
515
    }
516
    puts $ifh "  \)\;"
517
    puts $ifh ""
518
    puts $ifh "  modport tb_conn\("
519
    set idx 1
520
    foreach p $mod_lst {
521
        set tick_dir [string first "`" $p]
522
        if {$tick_dir >= 0} {
523
            puts $ifh "    $p"
524
            incr idx
525
            continue
526
        }
527
        set in [string first "input" $p]
528
        set out [string first "output" $p]
529
        if {$in >= 0} {
530
            set type "output  "
531
        } elseif {$out >= 0} {
532
            set type "input   "
533
        } else {
534
            set type "inout   "
535
        }
536
 
537
        set sp [split $p]
538
        if {$idx < $llen} {
539
            puts $ifh "    $type [lindex $sp end]"
540
        } else {
541
            puts $ifh "    $type [string trim [lindex $sp end] ","]"
542
        }
543
        incr idx
544
    }
545
    puts $ifh "  \)\;"
546
    puts $ifh ""
547
    puts $ifh "endinterface"
548
    close $ifh
549
    set gen_prog 5.0
550
    #$p_view step
551
##########################################################################
552
##   generate the tb_prg  file from template.
553
    #set prg_gen [$mo_sel get]
554
    if {$comb_val == "No mod"} {
555
        set gen_prog 7.0
556
        #$p_view step
557
        #$p_view step
558
        return
559
    }
560
    set tpl_fh [open $template r]
561
    set tpl_lst {}
562
    set hfound 0
563
    while {![eof $tpl_fh]} {
564
        set rline [gets $tpl_fh]
565
        if {$hfound == 0} {
566
            set head [string first ">>header" $rline]
567
            if {$head == 0} {
568
                set hfound 1
569
            }
570
        } else {
571
            lappend tpl_lst $rline
572
        }
573
    }
574
 
575
    #foreach l $tpl_lst {
576
    #    puts  $l
577
    #}
578
 
579
    set pfn $destin_text
580
    append pfn "/tb_mod.sv"
581
    set pfh [open $pfn w]
582
 
583
    set idx 0
584
    foreach l $tpl_lst {
585
        set ent_pt [string first ">>insert sigs" $l]
586
        if {$ent_pt == 0} {
587
            set tpl_lst [lreplace $tpl_lst $idx $idx]
588
            foreach l $log_lst {
589
                set tpl_lst [linsert $tpl_lst $idx "  $l"]
590
                incr idx
591
            }
592
            break
593
        }
594
        incr idx
595
    }
596
 
597
    #foreach l $tpl_lst {
598
    #    puts  $l
599
    #}
600
 
601
    set gen_prog 6.0
602
    #$p_view step
603
    set idx 0
604
    foreach l $tpl_lst {
605
        set ent_pt [string first ">>drive sigs" $l]
606
        if {$ent_pt == 0} {
607
            set tpl_lst [lreplace $tpl_lst $idx $idx]
608
            set midx 0
609
            foreach l $name_lst {
610
                set dir [lindex $mod_lst $midx]
611
                #puts $dir
612
                #puts "$idx $l"
613
                set idir [string first "input" $dir]
614
                if {[string first "`" $l] >= 0} {
615
                    set tmp $l
616
                } elseif {$idir >= 0} {
617
                    set tmp "  assign tif."
618
                    append tmp "$l = $l\;"
619
                } else {
620
                    set tmp "  assign $l"
621
                    append tmp " = tif.$l\;"
622
                }
623
                set tpl_lst [linsert $tpl_lst $idx $tmp]
624
                #puts [lindex $tpl_lst $idx]
625
                incr idx
626
                incr midx
627
                #$p_view step
628
            }
629
            break
630
        }
631
        incr idx
632
    }
633
 
634
    write_header $pfh
635
    foreach l $tpl_lst {
636
        puts $pfh $l
637
    }
638
    set gen_prog 7.0
639
    #$p_view step
640
    close $pfh
641
}

powered by: WebSVN 2.1.0

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