URL
https://opencores.org/ocsvn/vhld_tb/vhld_tb/trunk
Subversion Repositories vhld_tb
Compare Revisions
- This comparison shows the changes necessary to convert path
/vhld_tb/tags/rel_001/ttb_gen
- from Rev 3 to Rev 14
- ↔ Reverse comparison
Rev 3 → Rev 14
/ttb_gen_gui.tcl
0,0 → 1,754
##------------------------------------------------------------------------------- |
##-- Copyright 2007 Ken Campbell |
##-- All Rights Reserved |
## |
## This program is free software; you can redistribute it and/or modify |
## it under the terms of the GNU General Public License as published by |
## the Free Software Foundation; either version 2 of the License, or |
## (at your option) any later version. |
## |
## This program is distributed in the hope that it will be useful, |
## but WITHOUT ANY WARRANTY; without even the implied warranty of |
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
## GNU General Public License for more details. |
## |
## You should have received a copy of the GNU General Public License |
## along with this program; if not, write to the Free Software |
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
##------------------------------------------------------------------------------- |
##-- $Author: sckoarn $ |
##-- |
##-- $Date: 2007-04-06 04:06:49 $ |
##-- |
##-- $Name: not supported by cvs2svn $ |
##-- |
##-- $Id: ttb_gen_gui.tcl,v 1.1.1.1 2007-04-06 04:06:49 sckoarn Exp $ |
##-- |
##-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/ttb_gen/ttb_gen_gui.tcl,v $ |
##-- |
##-- Description : |
##-- This application takes a text file containing the definition of a VHDL |
## entity, parses that entity and generates the VHDL Test Bench starting |
## file set. ( This was the first application written by the author |
## in the tcl\tk language, forgive the style.) |
##-- |
##------------------------------------------------------------------------------ |
## set the current version info |
set ttbgen_version "v1.0" |
## get the time and date from the system |
set raw_date [clock scan now] |
set scan_date [clock format $raw_date -format "%d %b %Y %T"] |
## title and version info for window |
set msg_txt [label .l1 -text "Test Bench Generation Tool $ttbgen_version"]; |
pack $msg_txt |
|
## destination spec frame |
set g [frame .dest] |
label $g.lab -text "Destination Directory: " -anchor e |
entry $g.ent -width 20 |
pack $g.lab -side left |
pack $g.ent -side left -expand yes -fill x |
|
## source spec frame with browser |
set f [frame .sour] |
label $f.lab -text "Select Generation Source: " -anchor e |
entry $f.ent -width 20 |
button $f.but -text "Browse ..." -command "fileDialog $f $f.ent $g.ent" |
pack $f.lab -side left |
pack $f.ent -side left -expand yes -fill x |
pack $f.but -side left |
pack $f -fill x -padx 1c -pady 3 |
## pack destination frame |
pack $g -fill x -padx 1c -pady 3 |
## check button for optional bhv generation |
checkbutton .b1 -text "Generate the bhv file?" -variable bhv |
pack .b1 |
## create and place the buttons frame |
frame .buttons |
pack .buttons -side bottom -fill x -pady 2m |
button .buttons.exit -text "Exit" -command exit |
button .buttons.help -text "Help" -command "show_help $msg_txt" |
button .buttons.gene -text "Generate" -command "ttb_gen $f.ent $g.ent" |
pack .buttons.gene -side left -expand 1 |
pack .buttons.help -side left -expand 1 |
pack .buttons.exit -side left -expand 1 |
|
|
########################################################################### |
## some debug and help procs |
## Message Error, terminate |
proc msg_error { msg } { |
tk_messageBox -message $msg -type ok |
exit |
} |
########################################################################### |
## Message, continue |
proc dbg_msg { msg } { |
tk_messageBox -message $msg -type ok |
} |
##----------------------------------------------------------------------- |
## Help display proc. It changes the Lable at the top of the window to |
## have the following text |
proc show_help { h } { |
$h configure -justify left -text "Test Bench Generation Help \n \n \ |
1) Use Browse to select a source entity VHDL file \n \ |
2) Provide the path to the destination directory \n \ |
3) Check Generate bhv, if behave file should be generated \n \ |
4) Hit the Generate button" |
} |
|
##--------------------------------------------------------------- |
## File dialog handler |
proc fileDialog {f ent des} { |
# Type names Extension |
# |
#--------------------------------------------------------- |
set types { |
{"VHDL Code" {.vhd .vhdl} } |
{"Text files" {.txt} } |
{"Tcl Scripts" {.tcl} TEXT} |
{"All files" *} |
} |
|
set file [tk_getOpenFile -filetypes $types -parent $f] |
|
if {[string compare $file ""]} { |
$ent delete 0 end |
$ent insert 0 $file |
$ent xview end |
|
set des_directory [string last / $file] |
$des delete 0 end |
$des insert 0 [string range $file 0 $des_directory] |
$des xview end |
} |
} |
|
##----------------------------------------------------------------------- |
## proc pars_pindef |
proc pars_pindef { pin } { |
set pdirection "" |
# dbg_msg $pin |
set spin [split $pin ":"] |
set pname_str [lindex $spin 0] |
set pname [lindex $pname_str 0] |
# dbg_msg "Pin name is $pname" |
set pdirection_str [lindex $spin 1] |
# dbg_msg $pdirection_str |
## parce out the direction, supporting only 3 |
set direction [string first "in " $pdirection_str] |
if {$direction >= 0} { |
set pdirection "in" |
} |
set direction [string first "out " $pdirection_str] |
if {$direction >= 0} { |
set pdirection "out" |
} |
set direction [string first "inout " $pdirection_str] |
if {$direction >= 0} { |
set pdirection "inout" |
} |
if {$pdirection == ""} { |
msg_error "Unsuported Pin direction found. \n Suported are IN OUT and INOUT." |
} |
# dbg_msg "Pin direction is $pdirection" |
## now parce out the type |
## to overcome the std_logic_vector( # to #); vs (# to #); syntax |
## check and see if there is a vector spec in this pin with space after |
## the first bracket |
set vect [string first "( " $pdirection_str] |
if {$vect < 0} { |
set ptype1 [lindex $pdirection_str 1] |
set ptype2 [lindex $pdirection_str 2] |
set ptype3 [lindex $pdirection_str 3] |
set ptype "$ptype1 $ptype2 $ptype3" |
} else { |
set ptype1 [lindex $pdirection_str 1] |
set ptype2 [lindex $pdirection_str 2] |
set ptype3 [lindex $pdirection_str 3] |
set ptype4 [lindex $pdirection_str 4] |
set ptype "$ptype1 $ptype2 $ptype3 $ptype4" |
} |
##puts $ptype |
|
set last_pin [string first \; $ptype] |
if {$last_pin >= 0} { |
set is_vector [string first ( $ptype] |
## if there is a vector def |
if {$is_vector >= 0} { |
set temp_v [string first )) $ptype] |
|
if {$temp_v >= 0} { |
set s_e [expr $last_pin - 2] |
set ptype [string range $ptype 0 $s_e] |
} else { |
set s_e [expr $last_pin - 1] |
set ptype [string range $ptype 0 $s_e] |
} |
} else { |
set temp_v [string first ) $ptype] |
## found a ); in the last pin def |
if {$temp_v >= 0} { |
set s_e [expr $last_pin - 2] |
set ptype [string range $ptype 0 $s_e] |
} else { |
set s_e [expr $last_pin - 1] |
set ptype [string range $ptype 0 $s_e] |
} |
} |
} |
set ptype [string trim $ptype] |
# dbg_msg "The type is $ptype" |
lappend pdef $pname $pdirection $ptype |
return $pdef |
} |
|
##-------------------------------------------------------------------------------- |
## Write header to file passed |
proc write_header { handle } { |
global ttbgen_version |
global scan_date |
|
## so CVS will not modify selections, they have to be chopped up |
set auth "-- \$Auth" |
append auth "or: \$" |
set cvs_date "-- \$dat" |
append cvs_date "e: \$" |
set cvs_name "-- \$Nam" |
append cvs_name "e: \$" |
set cvs_id "-- \$I" |
append cvs_id "d: \$" |
set cvs_source "-- \$Sour" |
append cvs_source "ce: \$" |
set cvs_log "-- \$Lo" |
append cvs_log "g: \$" |
|
puts $handle "-------------------------------------------------------------------------------" |
puts $handle "-- Copyright 2007 xxxx" |
puts $handle "-- All Rights Reserved" |
puts $handle "-------------------------------------------------------------------------------" |
puts $handle "$auth" |
puts $handle "--" |
puts $handle "$cvs_date" |
puts $handle "--" |
puts $handle "$cvs_name" |
puts $handle "--" |
puts $handle "$cvs_id" |
puts $handle "--" |
puts $handle "$cvs_source" |
puts $handle "--" |
puts $handle "-- Description :" |
puts $handle "-- This file was generated by ttb_gen2_gui $ttbgen_version" |
puts $handle "-- on $scan_date" |
puts $handle "------------------------------------------------------------------------------" |
# puts $handle "-- This software contains concepts confidential to ------------------" |
# puts $handle "-- -----------. and is only made available within the terms of a written" |
# puts $handle "-- agreement." |
# puts $handle "-------------------------------------------------------------------------------" |
puts $handle "-- Revision History:" |
puts $handle "$cvs_log" |
puts $handle "--" |
puts $handle "-------------------------------------------------------------------------------" |
puts $handle "" |
} |
|
##------------------------------------------------------------------------- |
## write Library and use statements |
proc write_lib_statements { handle } { |
puts $handle "library IEEE;" |
puts $handle "library ieee_proposed;" |
puts $handle "--library modelsim_lib;" |
puts $handle "use IEEE.STD_LOGIC_1164.all;" |
puts $handle "use IEEE.STD_LOGIC_ARITH.all;" |
puts $handle "use ieee_proposed.STD_LOGIC_1164_additions.all;" |
puts $handle "use std.textio.all;" |
puts $handle "--use modelsim_lib.util.all;" |
puts $handle "" |
} |
|
|
######################################################################### |
## |
## START of main program |
## |
######################################################################### |
proc ttb_gen { source destin } { |
|
global bhv |
|
set path_text [$source get] |
set destin_text [$destin get] |
|
set infile [open "$path_text" r] |
set file_list list |
|
########################################## |
## Path needs to be set up for the some usage cases |
## set the path to the template behave file |
set template "template_tb_bhv.vhd" |
#set template "\\\\Gs1\\public\\fpga_projects\\verification_docs\\html\\vhdltb\\template2_tb_bhv.vhd" |
|
set tmpcnt 0 |
|
## ------------------------------------------------------------- |
## Read in the file and strip comments as we do |
while {![eof $infile]} { |
## Get a line |
set rline [gets $infile] |
## get rid of white space |
set rline [string trim $rline] |
## Find comment if there |
set cindex [string first -- $rline] |
## if a comment was found at the start of the line |
if {$cindex == 0 || $rline == ""} { |
set rline [string range $rline 0 [expr $cindex - 1]] |
##dbg_msg $rline |
if {[llength $rline] > 0} { |
lappend file_list [string tolower $rline] |
} |
## else was not found so put line in list |
} else { |
lappend file_list [string tolower $rline] |
# if {$tmpcnt > 490} { |
# dbg_msg "$rline $tmpcnt" |
# } |
} |
incr tmpcnt |
} |
|
## collect the library statements |
foreach l $file_list { |
set libpos [string first library $l] |
if {$libpos >= 0} { |
lappend libs_list $l |
} |
} |
|
## collect the use statements |
foreach l $file_list { |
set usepos [string first use $l] |
if {$usepos >= 0} { |
lappend use_list $l |
} |
} |
## check for the entity def |
set ent_found 0 |
foreach l $file_list { |
set ent_def [string first entity $l] |
if {$ent_def >= 0} { |
## set ent_found 1 |
set ent_name [lindex $l 1] |
break |
} |
} |
## if no ent die |
if {$ent_def < 0} { |
msg_error "An entity definition was not found in the file provided." |
## exit |
} |
|
## check for end entity |
foreach l $file_list { |
lappend ent_list $l |
set end_def [string first end $l] |
if {$end_def >= 0} { |
set end_ent [string first "end $ent_name" $l] |
if {$end_ent >= 0} { |
break |
} |
set end_ent [string first "end entity $ent_name" $l] |
if {$end_ent >= 0} { |
break |
} |
} |
} |
## if no end die |
if {$end_def < 0} { |
msg_error "no end statement found for this entity" |
## exit |
} |
|
set port_found 0 |
#######---------------------------------------------------------------- |
## a few checks have been done, and non-relevant stuff stripped off. |
## now create an arrry of just the pin names and related info |
foreach l $ent_list { |
## look for the port statement |
if {$port_found == 0} { |
set pfound [string first port $l] |
## found one now check if there is a pin def in the same line |
if {$pfound >= 0} { |
set port_found 1 |
set efound [string first : $l] |
if {$efound >= 0} { |
set line_test [split $l "("] |
if {[llength $line_test] > 1} { |
lappend port_list [lindex $line_test 1] |
} |
} |
} |
} else { |
set efound [string first : $l] |
if {$efound >= 0} { |
lappend port_list $l |
} |
} |
} |
#dbg_msg $port_list |
## Change the port list into a pin info list |
foreach l $port_list { |
lappend split_pin [pars_pindef $l] |
} |
# dbg_msg $split_pin |
|
## calculate the longest pin name in characters |
set name_length 0 |
foreach l $split_pin { |
set temp_length [string length [lindex $l 0]] |
if {$temp_length > $name_length} { |
set name_length $temp_length |
} |
} |
#dbg_msg $name_length |
## Make the name length one bigger |
incr name_length |
|
######################################################################### |
## Generate the test bench entity. |
|
## Create the file name |
set file_type "_tb_ent.vhd" |
set ent_file_name $destin_text |
append ent_file_name "/" $ent_name $file_type |
# dbg_msg $ent_file_name |
## Create the tb entity name |
set tb_ent_name $ent_name |
set tb_sufix "_tb" |
append tb_ent_name $tb_sufix |
|
## open and write the header |
set ent_file [open $ent_file_name w+] |
write_header $ent_file |
|
## write out Library and use statements |
write_lib_statements $ent_file |
|
puts $ent_file "entity $tb_ent_name is" |
puts $ent_file " generic (" |
puts $ent_file " stimulus_file: in string" |
puts $ent_file " )\;" |
puts $ent_file " port (" |
|
##----------------------------------------- |
# for each pin in the list output the TB ent pin |
set plist_size [llength $split_pin] |
#dbg_msg $plist_size |
set i 1 |
foreach l $split_pin { |
set pdirection [lindex $l 1] |
# puts $pdirection |
## switch on the source pin direction |
switch -exact $pdirection { |
"in" {set tb_ptype "buffer"} |
"out" {set tb_ptype "in"} |
"inout" {set tb_ptype "inout"} |
default { |
msg_error "Should have not got here .. pin direction in entity creation!!" |
} |
} |
## creat some formats for appending |
set new_pname [format " %-${name_length}s" [lindex $l 0]] |
set new_ptype [format ": %-8s" $tb_ptype] |
if {$i != $plist_size} { |
append new_pname $new_ptype [lindex $l 2] ";" |
} else { |
append new_pname $new_ptype [lindex $l 2] |
} |
puts $ent_file $new_pname |
incr i |
} |
|
puts $ent_file " )\;" |
puts $ent_file "end $tb_ent_name;" |
|
close $ent_file |
|
################################################################## |
## Generate the top level test bench entity |
## Create the file name |
set file_type "_ttb_ent.vhd" |
set ent_file_name $destin_text |
append ent_file_name "/" $ent_name $file_type |
# dbg_msg $ent_file_name |
## Create the tb entity name |
set ttb_ent_name $ent_name |
set ttb_sufix "_ttb" |
append ttb_ent_name $ttb_sufix |
|
## open and write the header |
set ttb_ent_file [open $ent_file_name w+] |
write_header $ttb_ent_file |
|
puts $ttb_ent_file "library IEEE;" |
puts $ttb_ent_file "library dut_lib;" |
puts $ttb_ent_file "use IEEE.STD_LOGIC_1164.all;" |
puts $ttb_ent_file "use dut_lib.all;" |
puts $ttb_ent_file "" |
puts $ttb_ent_file "entity $ttb_ent_name is" |
puts $ttb_ent_file " generic (" |
puts $ttb_ent_file " stimulus_file: string := \"stm/stimulus_file.stm\"" |
puts $ttb_ent_file " )\;" |
puts $ttb_ent_file "end $ttb_ent_name\;" |
|
close $ttb_ent_file |
|
################################################################# |
## Generate the top level structure |
## Create the file name |
set file_type "_ttb_str.vhd" |
set str_file_name $destin_text |
append str_file_name "/" $ent_name $file_type |
# dbg_msg $ent_file_name |
## Create the tb entity name |
set ttb_ent_name $ent_name |
set ttb_sufix "_ttb" |
append ttb_ent_name $ttb_sufix |
|
## open and write the header |
set ttb_str_file [open $str_file_name w+] |
write_header $ttb_str_file |
|
puts $ttb_str_file "" |
puts $ttb_str_file "architecture struct of $ttb_ent_name is" |
puts $ttb_str_file "" |
puts $ttb_str_file "component $ent_name" |
puts $ttb_str_file " port (" |
## put out the dut component def |
##----------------------------------------- |
# for each pin in the list output the TB ent pin |
set i 1 |
foreach l $split_pin { |
## creat some formats for appending |
set new_pname [format " %-${name_length}s" [lindex $l 0]] |
set new_ptype [format ": %-8s" [lindex $l 1]] |
if {$i != $plist_size} { |
append new_pname $new_ptype [lindex $l 2] ";" |
} else { |
append new_pname $new_ptype [lindex $l 2] |
} |
puts $ttb_str_file $new_pname |
incr i |
} |
puts $ttb_str_file " )\;" |
puts $ttb_str_file "end component\;" |
|
puts $ttb_str_file "" |
puts $ttb_str_file "component $tb_ent_name" |
puts $ttb_str_file " generic (" |
puts $ttb_str_file " stimulus_file: in string" |
puts $ttb_str_file " )\;" |
puts $ttb_str_file " port (" |
## put out the tb component def |
##----------------------------------------- |
# for each pin in the list output the TB ent pin |
set i 1 |
foreach l $split_pin { |
set pdirection [lindex $l 1] |
# dbg_msg $pdirection |
## switch on the source pin direction |
switch -exact $pdirection { |
"in" {set tb_ptype "buffer"} |
"out" {set tb_ptype "in"} |
"inout" {set tb_ptype "inout"} |
default { |
msg_error "Should have not got here .. pin direction in entity creation!!" |
} |
} |
## creat some formats for appending |
set new_pname [format " %-${name_length}s" [lindex $l 0]] |
set new_ptype [format ": %-8s" $tb_ptype] |
if {$i != $plist_size} { |
append new_pname $new_ptype [lindex $l 2] ";" |
} else { |
append new_pname $new_ptype [lindex $l 2] |
} |
puts $ttb_str_file $new_pname |
incr i |
} |
puts $ttb_str_file " )\;" |
puts $ttb_str_file "end component\;" |
puts $ttb_str_file "" |
|
puts $ttb_str_file "for all: $ent_name use entity dut_lib.$ent_name\(str)\;" |
puts $ttb_str_file "for all: $tb_ent_name use entity work.$tb_ent_name\(bhv)\;" |
|
puts $ttb_str_file "" |
##----------------------------------------- |
# for each pin in the list output the TB ent pin |
# generate a signal name |
foreach l $split_pin { |
## creat some formats for appending |
set new_pname [format " signal temp_%-${name_length}s" [lindex $l 0]] |
append new_pname ": " [lindex $l 2] ";" |
puts $ttb_str_file $new_pname |
} |
|
puts $ttb_str_file "" |
puts $ttb_str_file "begin" |
puts $ttb_str_file "" |
puts $ttb_str_file "dut: $ent_name" |
puts $ttb_str_file " port map(" |
##----------------------------------------- |
# for each pin in the list output the TB ent pin |
# Generate port map for DUT |
set i 1 |
foreach l $split_pin { |
## creat some formats for appending |
set new_pname [format " %-${name_length}s" [lindex $l 0]] |
if {$i != $plist_size} { |
append new_pname "=> temp_" [lindex $l 0] "," |
} else { |
append new_pname "=> temp_" [lindex $l 0] |
} |
puts $ttb_str_file $new_pname |
incr i |
} |
|
puts $ttb_str_file " )\;" |
puts $ttb_str_file "" |
puts $ttb_str_file "tb: $tb_ent_name" |
puts $ttb_str_file " generic map(" |
puts $ttb_str_file " stimulus_file => stimulus_file" |
puts $ttb_str_file " )" |
puts $ttb_str_file " port map(" |
##----------------------------------------- |
# for each pin in the list output the TB ent pin |
# Generate port map for DUT |
set i 1 |
foreach l $split_pin { |
## creat some formats for appending |
set new_pname [format " %-${name_length}s" [lindex $l 0]] |
if {$i != $plist_size} { |
append new_pname "=> temp_" [lindex $l 0] "," |
} else { |
append new_pname "=> temp_" [lindex $l 0] |
} |
puts $ttb_str_file $new_pname |
incr i |
} |
|
puts $ttb_str_file " )\;" |
puts $ttb_str_file "" |
puts $ttb_str_file "end struct\;" |
|
close $ttb_str_file |
|
###################################################################### |
## Now generate the bhv file from template |
|
if {$bhv == 1} { |
|
set infile [open "$template" r] |
|
while {![eof $infile]} { |
## Get a line |
set rline [gets $infile] |
lappend temp_file_list $rline |
} |
|
close $infile |
|
## strip off the header |
set end_header 0 |
foreach l $temp_file_list { |
set comment [string first -- $l] |
if {$comment < 0} { |
set end_header 1 |
} |
## if we found the end of the header |
if {$end_header == 1} { |
lappend template_list $l |
} |
} |
|
## split the file into two peices, to the point of input initialization |
set i 1 |
foreach l $template_list { |
## check for parsing point |
set mid_point [string first parse_tb1 $l] |
if {$mid_point >= 0} { |
break |
} |
|
if {$i > 2} { |
lappend top_half $l |
} |
incr i |
} |
|
set found 0 |
foreach l $template_list { |
if {$found == 1} { |
lappend bottom_half $l |
} |
## check for parsing point |
set mid_point [string first parse_tb1 $l] |
if {$mid_point >= 0} { |
set found 1 |
} |
} |
|
## Create the file name |
set file_type "_tb_bhv.vhd" |
set bhv_file_name $destin_text |
append bhv_file_name "/" $ent_name $file_type |
# dbg_msg $ent_file_name |
|
## open and write the header |
set bhv_file [open $bhv_file_name w+] |
write_header $bhv_file |
|
puts $bhv_file "" |
puts $bhv_file "architecture bhv of $tb_ent_name is" |
puts $bhv_file "" |
foreach l $top_half { |
puts $bhv_file $l |
} |
|
puts $bhv_file "" |
## now generate and write out input initialization |
foreach l $split_pin { |
set temp_def [lindex $l 1] |
set input_def [string first in $temp_def] |
if {$input_def >= 0} { |
set vector [string first vector $l] |
set init_def [format " %-${name_length}s" [lindex $l 0]] |
if {$vector >= 0} { |
append init_def "<= (others => '0')\;" |
} else { |
append init_def "<= '0'\;" |
} |
puts $bhv_file $init_def |
} |
} |
puts $bhv_file "" |
## now write out the bottem half and termination |
foreach l $bottom_half { |
puts $bhv_file $l |
} |
|
close $bhv_file |
} |
## put out a terminating message for the user |
dbg_msg "Test bench files were generated in directory:\n $destin_text" |
|
} |
|
bind . <F12> {catch {console show}} |
|
##------------------------------------------------------------------------------- |
##-- Revision History: |
##-- $Log: not supported by cvs2svn $ |
##-- |
##---------------------------------------------------------------------------- |
|