URL
https://opencores.org/ocsvn/sv_dir_tb/sv_dir_tb/trunk
Subversion Repositories sv_dir_tb
Compare Revisions
- This comparison shows the changes necessary to convert path
/sv_dir_tb
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/trunk/doc/directedtbusers1.doc
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/doc/directedtbusers1.odt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/tb_gen/tb_gen_cmd
File deleted
/trunk/tb_gen/tb_gen.tcl
1,6 → 1,6
#! /usr/bin/env wish |
##------------------------------------------------------------------------------- |
## Copyright 2018 Ken Campbell |
## Copyright 2019 Ken Campbell |
## |
## Licensed under the Apache License, Version 2.0 (the "License"); |
## you may not use this file except in compliance with the License. |
16,7 → 16,7
##------------------------------------------------------------------------------- |
##-- $Author: $ Ken Campbell |
##-- |
##-- $Date: $ August 2018 |
##-- $Date: $ April 2019 |
##-- |
##-- $Id: $ |
##-- |
33,7 → 33,7
package require Tk |
|
## set the current version info |
set version "Version 1.0" |
set version "Version 1.2" |
## put up a title on the main window boarder |
wm title . "SV TB Gen $version" |
|
78,6 → 78,7
## type spec |
set tsf [frame .tsfr] |
set load_but [button $tsf.bt1 -text "Generate" -command ttb_gen] |
## this button enables quicker development of the parser. If |
set test_but [button $tsf.bt2 -text "Source" -command {source tb_gen_parser.tcl}] |
set comb_vals {"No mod" "Gen mod"} |
set comb_val "No mod" |
90,14 → 91,11
set gen_prog 0.0 |
set p_view [ttk::progressbar $tsf.fb1 -variable gen_prog] |
set statsVar "" |
##set stat_txt [label $tsf.lb1 -textvariable statsVar] |
set stat_txt [label .lb1 -textvariable statsVar] |
|
## about button |
button $tsf.bout1 -text "About" -command show_about |
|
#pack $cpak -side left |
#pack $gbat -side left |
pack $mo_sel -side left |
pack $load_but -side left -padx 20 |
pack $test_but -side left -padx 20 |
119,14 → 117,12
set m_select "" |
set list_win [listbox $wtop.sb -listvariable sel_lst -height 16] |
set list_ent [entry $wtop.lent -textvariable m_select] |
#set view_win [iwidgets::scrolledtext $wbot.rts -borderwidth 2 -wrap none] |
set view_win [text $wmid.rts -borderwidth 2 -wrap none] |
pack $list_win -fill both -expand yes |
pack $list_ent -anchor s -fill x -expand yes |
pack $view_win -fill both -expand yes |
|
## some tags for the view window |
##$view_win tag configure highlite -background #a0b7ce |
## tag for the view window |
$view_win tag configure highlite -background grey80 |
|
########################################################################### |
147,10 → 143,10
## field passed to it |
proc browsed_from_set { src dest } { |
set wdir [$src get] |
puts $wdir |
#puts $wdir |
if {$wdir == ""} { |
set curd [pwd] |
puts $curd |
#puts $curd |
set fn [tk_chooseDirectory -title "Choose a directory" -initialdir $curd] |
} else { |
set fn [tk_chooseDirectory -initialdir $wdir -title "Choose a directory"] |
202,6 → 198,4
|
## enable pop up console for debug |
bind . <F12> {catch {console show}} |
#bind $list_win <<ListboxSelect>> {load_ent_file} |
#bind $list_win <<ListboxSelect>> {set m_select [$list_win curselection]} |
bind $list_win <<ListboxSelect>> {set sel_dx [$list_win curselection]; set m_select [$list_win get $sel_dx]; load_ent_file} |
bind $list_win <<ListboxSelect>> {process_selected} |
/trunk/tb_gen/tb_gen_parser.tcl
14,14 → 14,29
## limitations under the License. |
##------------------------------------------------------------------------------- |
##-- $Author: $ Ken Campbell |
##-- $Date: $ Jan. 2019 |
##-- $Date: $ April 2019 |
##-- $Id: $ |
##-- $Source: $ |
##-- Description : |
##-- This application takes a text file containing the definition of a Verilog |
## module, produces a file set for the SV Directed Test Bench. |
##-- module, produces a file set for the SV Directed Test Bench. |
##-- This file is the parser and generator. |
##-- The parser is a simple one, in that it is not able to provide reliable |
##-- code generation for all possible syntax. It is intended that it will |
##-- generate good code if the module I/O are defined like shown in the examples. |
##-- |
##-- If you intend to generate many TB, and this parser is not quite what you |
##-- need, feel free to modify it for your needs. There are ample comments |
##-- and left over puts statements that should help with any efforts to |
##-- modify the parser. |
##------------------------------------------------------------------------------ |
|
################################################################# |
## parse out the pin definitions from the list of raw pins text from the module. |
## input : list of strings containing pin definitions. |
## output : list of list of pin properties. |
## three lists are output, each designed to provide information for |
## the generation process. |
proc pars_pindef { pins } { |
set pdef {} |
set def_lst {} |
35,12 → 50,10
set is_mult [string first "," $l] |
set is_bv [string first "\[" $l] |
set l [string trim $l "\;"] |
## if is a vector def |
#puts $l |
#handle precompile |
set ispre [string first "`" $l] |
if {$ispre >= 0} { |
#strip `timescale |
if {[string first "timescale" $l] >= 0} { |
continue |
} |
49,15 → 62,21
lappend dut_modport $l |
continue |
} |
## if is a vector def |
#puts "is_bv: $is_bv" |
if {$is_bv > 0} { |
set is_cbv [string first "\]" $l] |
|
set is_cbv [string last "\]" $l] |
set bv_spec [string range $l $is_bv $is_cbv] |
set type [string range $l 0 $is_bv-1] |
set names [string range $l $is_cbv+1 end] |
set snames [split $names ","] |
foreach n $snames { |
##set n [string trim $n "\;"] |
#puts $n |
set sn [string trim $n] |
if {$sn == ""} { |
break |
} |
lappend names_lst [string trim $n] |
if {$type != "inout"} { |
set tmp "logic " |
69,17 → 88,31
set tmp [string trim $type] |
append tmp " [string trim $n]," |
lappend dut_modport $tmp |
#puts "$type $bv_spec [string trim $n]\;" |
} |
} else { |
#puts $l |
set sl [split $l ","] |
set frst [split [lindex $sl 0]] |
set type [string trim [lindex $frst 0]] |
## get the pin type from the def. |
set tmp "" |
foreach pt [lrange $frst 1 end] { |
if {$pt != ""} { |
if {$pt == "var"} { |
set tmp "$pt " |
} else { |
append tmp $pt |
set pin_type $tmp |
break |
} |
} |
} |
#puts $pin_type |
set fname [string trim [lindex $frst end]] |
set sl [lrange $sl 1 end] |
lappend names_lst [string trim $fname] |
if {$type != "inout"} { |
set tmp "logic " |
set tmp "$pin_type " |
} else { |
set tmp "wire " |
} |
93,7 → 126,7
if {$n == ""} { |
continue |
} |
puts $n |
#puts $n |
lappend names_lst [string trim $n] |
if {$type != "inout"} { |
set tmp "logic " |
117,8 → 150,23
} |
## end pars_pindef |
|
##------------------------------------------------------------------------------- |
## pars parameters |
proc pars_params {plst} { |
set rtn {} |
foreach p $plst { |
set sp [split [string trim $p ","] " "] |
set tmp [lindex $sp 1] |
lappend tmp [lindex $sp end] |
lappend rtn $tmp |
} |
return $rtn |
} |
## end pars_params |
##-------------------------------------------------------------------------------- |
## Write header to file passed |
## if you intend to use this tool many times and it matters |
## mod this section to output the header as required. |
proc write_header { handle } { |
global version |
##global scan_date |
151,8 → 199,8
## A directory has been selected now fill the list win with *V files |
proc fill_list {} { |
global ent_dir odir |
global tlist_ent use_list list_win ts_ent statsVar |
global view_win mo_sel sel_lst |
global use_list list_win ts_ent statsVar |
global view_win mo_sel sel_lst list_ent |
|
## get the user selection |
browsed_from_set $ent_dir $ent_dir |
163,20 → 211,26
$odir configure -state readonly |
|
## clear the list window and selection |
#$list_win clear items |
$list_win delete 0 end |
$list_ent delete 0 end |
#$list_win clear selection |
#$view_win clear |
$view_win delet 0.0 end |
## get the working directory |
set dir [$ent_dir get] |
## get the list of VHDL files in working directory |
## get the list of SV & v files in working directory |
set ftype ".*v" |
set file_lst "" |
set file_lst [glob -directory $dir *$ftype] |
set are_files [catch {glob -directory $dir *$ftype} rtn_code] |
if {$are_files == 0} { |
set file_lst [glob -directory $dir *$ftype] |
} else { |
return |
} |
#puts $file_lst |
## for each of the files in the file_lst |
foreach l $file_lst { |
## creat string that is just the file name: no path |
puts "File : $l" |
#puts "File : $l" |
set testt $l |
set nstart [string last "/" $l] |
incr nstart |
184,12 → 238,25
set name_str [string range $l $nstart end] |
set sel_lst [lappend sel_lst $name_str] |
#puts $sel_lst |
## insert item on list |
#$list_win insert items 1 $name_str |
} |
} |
|
###################################################################### |
## click on the listbox process it. |
proc process_selected {} { |
global list_win m_select |
|
set sz [$list_win size] |
#puts $sz |
if {$sz > 0} { |
set sel_dx [$list_win curselection] |
set m_select [$list_win get $sel_dx] |
load_ent_file |
} else { |
} |
} |
|
###################################################################### |
## load the vhdl file that has just been selected from list_win |
proc load_ent_file {} { |
global ent_dir list_win view_win statsVar gen_prog |
196,7 → 263,6
|
set gen_prog 0.0 |
## update selection with selected item |
#set fn [$list_win curselection] |
set sel_dx [$list_win curselection] |
if {$sel_dx == ""} { |
return |
224,7 → 290,7
lappend file_list $rline |
} |
close $ent_file |
## put file in text window and highlite the entity part |
## put file in text window and highlite the module part |
set ent_found 0 |
set in_ent 0 |
set statsVar "" |
231,7 → 297,8
foreach l $file_list { |
if {$in_ent == 0} { |
set ent_def [string first module $l] |
if {$ent_def >= 0} { |
## Make crazy assumption the module def is in the first few chars. |
if {$ent_def >= 0 && $ent_def <= 6} { |
set ent_name [lindex $l 1] |
set statsVar "Module: $ent_name found" |
set ent_found 1 |
239,28 → 306,26
$view_win insert end "$l\n" highlite |
} else { |
$view_win insert end "$l\n" |
} |
} else { |
set ent_def [string first "endmodule" $l] |
if {$ent_def >= 0} { |
set end_name [lindex $l 1] |
set end_found 1 |
set in_ent 0 |
$view_win insert end "$l\n" highlite |
} |
} else { |
set ent_def [string first "endmodule" $l] |
if {$ent_def >= 0} { |
set end_name [lindex $l 1] |
set end_found 1 |
set in_ent 0 |
$view_win insert end "$l\n" highlite |
} else { |
$view_win insert end "$l\n" highlite |
} |
} |
} |
} |
if {$ent_found == 0} { |
set statsVar "No Module found!!" |
} |
##$view_win import $lp |
##$view_win yview moveto 1 |
##puts $lp |
} |
|
######################################################################### |
## The main generator proc |
proc ttb_gen {} { |
global mo_sel template ent_dir list_win odir p_view tdir |
global cpakv gbatv gen_prog comb_val m_select |
270,7 → 335,6
$p_view configure -maximum 7 |
set gen_prog 1.0 |
## recover the selected item |
#set sel_dx [$list_win curselection] |
set ln $m_select |
## Get the working directory |
#puts $ln |
283,7 → 347,7
set infile [open $path_text r] |
set file_list {} |
|
|
set bl_comm 0; ## block comment indication. |
################################################################## |
## Read in the file and strip comments as we do |
while {![eof $infile]} { |
294,14 → 358,29
set rline [string trim $rline] |
## Find comment if there |
set cindex [string first "//" $rline] |
## Block comments. |
set bcomm_s [string first "/*" $rline] |
set bcomm_e [string first "*/" $rline] |
## this will break if block start after some code ... |
if {$bcomm_s >= 0} { |
set bl_comm 1 |
continue |
} |
if {$bcomm_s == 1} { |
if {$bcomm_e >= 0} { |
set bl_comm 0 |
} |
continue |
} |
## if a comment was found at the start of the line |
if {$cindex == 0 || $rline == ""} { |
continue |
## else was not found so put line in list |
## else if comment somewhere in the line |
} elseif {$cindex > 0} { |
# get rid of trailing comments and trim off spaces |
set rline [string trim [string range $rline 0 $cindex-1]] |
lappend file_list $rline |
## else was not found so put line in list |
} else { |
lappend file_list $rline |
} |
308,7 → 387,13
} |
close $infile |
|
$p_view step |
|
#foreach l $file_list { |
# puts $l |
#} |
#return |
|
#$p_view step |
## check for the module def |
set mod_name "" |
foreach l $file_list { |
327,7 → 412,7
return |
## exit |
} |
$p_view step |
#$p_view step |
set mod_list {} |
## check for end module |
foreach l $file_list { |
350,9 → 435,13
foreach l $mod_list { |
set p_found [string first "parameter" $l] |
if {$p_found >= 0} { |
lappend $parameter_list $l |
lappend parameter_list $l |
} |
} |
#foreach pl $parameter_list { |
# puts $pl |
#} |
## inc the progress bar |
set gen_prog 2.0 |
#foreach l $mod_list { |
# puts $l |
361,14 → 450,11
## a few checks have been done, and non-relevant stuff stripped off. |
## now create an arrry of just the pin names and related info |
set port_lst {} |
set import_lst {} |
set lc 0 |
foreach l $mod_list { |
## make lines that are continued, one line. |
set cont [string first "\;" $l] |
#set tick [string first "`" $l] |
#if {$tick >= 0} { |
# continue |
#} |
## look for the port statements |
set inp [string first "input " $l] |
if {$inp >= 0} { |
386,15 → 472,28
if {$tick_dir >= 0} { |
lappend port_lst $l |
} |
#puts $port_lst |
set is_import [string first "import" $l] |
if {$is_import >= 0} { |
lappend import_lst $l |
} |
set end_pins [string first "\)\;" $l] |
set end_len [string length $l] |
if {$end_pins >= 0 && $end_len >= 2} { |
set stl [string trim $l "\)\;"] |
if {$stl != ""} { |
lappend port_lst $l |
} |
break |
} |
} |
|
#foreach p $port_lst { |
# puts $p |
#} |
## Change the port list into a pin info list |
#return |
## Change the port list into a pin info list of lists |
set io_pins [pars_pindef $port_lst] |
|
## get the lists |
set log_lst [lindex $io_pins 0] |
set mod_lst [lindex $io_pins 1] |
set name_lst [lindex $io_pins 2] |
408,7 → 507,16
#foreach r $name_lst { |
# puts $r |
#} |
#return |
########################################## |
## if there are parameters. |
if {[llength $parameter_list] > 0} { |
set param_lst [pars_params $parameter_list] |
} |
|
#foreach l $param_lst { |
# puts $l |
#} |
|
# dbg_msg $split_pin |
## calculate the longest pin name in characters |
423,8 → 531,8
## Make the name length one bigger |
incr name_length |
|
## inc the progress bar |
set gen_prog 3.0 |
#$p_view step |
######################################################################### |
## Generate the tb top. |
set tfn $destin_text |
432,7 → 540,7
set tfh [open $tfn w] |
|
write_header $tfh |
puts $tfh "`include \"../sv/tb_prg.sv\"" |
puts $tfh "`include \"../sv/tb_mod.sv\"" |
puts $tfh "" |
puts $tfh "module tb_top \(\)\;" |
puts $tfh "" |
442,13 → 550,32
puts $tfh " // Handle plus args" |
puts $tfh " initial begin : file_select" |
puts $tfh " if\(\$value\$plusargs\(\"STM_FILE=%s\", tmp_fn\)\) begin" |
puts $tfh " stm_file = tmp_fn\;" |
puts $tfh " STM_FILE = tmp_fn\;" |
puts $tfh " end" |
puts $tfh " end" |
puts $tfh "" |
puts $tfh " dut_if theif\(\)\;" |
puts $tfh "" |
puts $tfh " $mod_name u1 \(" |
## handle parameters. |
if {[llength $param_lst] == 0} { |
puts $tfh " $mod_name u1 \(" |
} else { |
puts $tfh " $mod_name" |
puts $tfh " \#\(" |
set llen [llength $param_lst] |
set idx 1 |
foreach p $param_lst { |
set tmp " .[lindex $p 0]\(" |
if {$idx < $llen} { |
append tmp "[lindex $p 1]\)," |
} else { |
append tmp "[lindex $p 1]\)" |
} |
puts $tfh $tmp |
incr idx |
} |
puts $tfh " \) u1 \(" |
} |
|
set llen [llength $name_lst] |
set idx 1 |
480,8 → 607,8
puts $tfh "endmodule" |
|
close $tfh |
## inc the progress bar |
set gen_prog 4.0 |
#$p_view step |
############################################################################ |
## generate the interface file. |
set ifn $destin_text |
489,8 → 616,31
set ifh [open $ifn w] |
|
write_header $ifh |
puts $ifh "interface dut_if\(\)\;" |
## handle the parameters. |
if {[llength $param_lst] == 0} { |
puts $ifh "interface dut_if\(\)\;" |
} else { |
puts $tfh " $mod_name" |
puts $tfh " \#\(" |
set llen [llength $param_lst] |
set idx 1 |
foreach p $param_lst { |
set tmp " [lindex $p 0] = " |
if {$idx < $llen} { |
append tmp "[lindex $p 1]," |
} else { |
append tmp "[lindex $p 1]" |
} |
puts $tfh $tmp |
incr idx |
} |
puts $tfh " \)\(\)\;" |
} |
puts $ifh "" |
foreach i $import_lst { |
puts $ifh " $i" |
} |
puts $ifh "" |
foreach l $log_lst { |
puts $ifh " $l" |
} |
500,6 → 650,7
set llen [llength $mod_lst] |
set idx 1 |
foreach p $mod_lst { |
## if there is an `ifdef ... |
set tick_dir [string first "`" $l] |
if {$tick_dir >= 0} { |
puts $ifh " $p" |
506,10 → 657,11
incr idx |
continue |
} |
set sp [split $p] |
if {$idx < $llen} { |
puts $ifh " $p" |
puts $ifh " [lindex $sp 0] [lindex $sp end]" |
} else { |
puts $ifh " [string trim $p ","]" |
puts $ifh " [lindex $sp 0] [string trim [lindex $sp end] ","]" |
} |
incr idx |
} |
518,6 → 670,7
puts $ifh " modport tb_conn\(" |
set idx 1 |
foreach p $mod_lst { |
## if there is an `ifdef ... |
set tick_dir [string first "`" $p] |
if {$tick_dir >= 0} { |
puts $ifh " $p" |
535,6 → 688,7
} |
|
set sp [split $p] |
#puts $sp |
if {$idx < $llen} { |
puts $ifh " $type [lindex $sp end]" |
} else { |
546,16 → 700,16
puts $ifh "" |
puts $ifh "endinterface" |
close $ifh |
## inc the progress bar |
set gen_prog 5.0 |
#$p_view step |
########################################################################## |
## generate the tb_prg file from template. |
#set prg_gen [$mo_sel get] |
#puts $comb_val |
if {$comb_val == "No mod"} { |
## indicate done in progress bar. |
set gen_prog 7.0 |
#$p_view step |
#$p_view step |
return |
puts "No tb_mod file was generated." |
return |
} |
set tpl_fh [open $template r] |
set tpl_lst {} |
598,8 → 752,8
# puts $l |
#} |
|
## inc the progress bar |
set gen_prog 6.0 |
#$p_view step |
set idx 0 |
foreach l $tpl_lst { |
set ent_pt [string first ">>drive sigs" $l] |
624,7 → 778,6
#puts [lindex $tpl_lst $idx] |
incr idx |
incr midx |
#$p_view step |
} |
break |
} |
636,6 → 789,5
puts $pfh $l |
} |
set gen_prog 7.0 |
#$p_view step |
close $pfh |
} |
/trunk/tb_gen/tb_mod_template.sv
22,7 → 22,11
module tb_mod (dut_if.tb_conn tif); |
|
import tb_pkg::*; |
|
// some handy defs |
`define PAR1 r.rtn_val.par1 |
`define PAR2 r.rtn_val.par2 |
`define PAR3 r.rtn_val.par3 |
`define PAR4 r.rtn_val.par4 |
// package and container |
cmd_lst cmds; |
tb_trans r; |
68,7 → 72,7
//cmds.define_instruction("VERIFY", 1); |
|
// load the stimulus file |
cmds.load_stm(`STM_FILE); |
cmds.load_stm(tb_top.STM_FILE); |
|
r.cmd = cmds; |
///////////////////////////////////////////////////// |
93,7 → 97,7
/////////////////////////////////////////////////////////////////////////// |
// RESET |
if (cmd_string == "RESET") begin |
@(posedge clock) |
@(posedge clock); |
/////////////////////////////////////////////////////////////////////////// |
// READ |
//end else if (cmd_string == "READ") begin |