目次
前
次
ソフトウエアツール
ISEWebPackで、entityの中に信号名を入力する
時間を短縮するため、AWK、Tcl/Tkのスクリプト
を作成し使っています。
信号名、入出力方向、ビット数を1行に記述した
テキストファイルを渡すと、entity記述を生成
する単純なツールです。
信号名は、そのまま文字列としますが、入出力
の方向指定は、次のように数値を割当てます。
ビット数は、そのまま数字で指定します。
ファイルから、3つのパラメータを入力し
2、3の数値を利用して、entity記述の
文字列を生成します。
ファイルの内容は、次のように指定します。
nRESET 0 1
CLOCK 0 1
ENABLE 0 1
SEL 0 3
DOUT 1 1
上のファイル内容から、以下のentity記述を生成します。
entity ??? is
port(
nRESET : in std_logic;
CLOCK : in std_logic;
ENABLE : in std_logic;
SEL : in std_logic_vector(2 downto 0);
DOUT : out std_logic;
);
end ??? ;
entity名は、???として、テキストエディタを
利用して、好みの文字列に変換します。
portの右括弧の前のセミコロンを、コメントで
抑止します。
entity tst1 is
port(
nRESET : in std_logic;
CLOCK : in std_logic;
ENABLE : in std_logic;
SEL : in std_logic_vector(2 downto 0);
DOUT : out std_logic--;
);
end tst1 ;
AWKスクリプト
AWKスクリプトのスクリプト名を、econ.awkとしておきます。
使い方は、次のようにCUIで動かします。
大まかな動作を考えてみます。
- 信号名は、そのまま文字列で出力
- 第2パラメータを利用し、in、out、inoutを指定
- 入出力は、std_logicで表現
- 第3パラメータを利用し、vectorにするか判定
- entity、port等は固定文字列を出力
スクリプトの内容は、以下です。
BEGIN {
printf("entity ??? is \n port(\n");
}
{
# signal name
printf(" %s : ",$1);
# judge direction
if ( $2 == "0" ) {
printf("in std_logic");
}
if ( $2 == "1" ) {
printf("out std_logic");
}
if ( $2 == "2" ) {
printf("inout std_logic");
}
# judge bus size
if ( $3 > 1 ) {
printf("_vector(%d downto 0)",$3-1);
}
printf(";\n");
}
END {
printf(" );\nend ??? ;\n");
}
使う場合は、I/Oリダイレクトを使います。
jgawkは、マルチプラットホーム対応なので
UNIX、Windowsを問わずに使えます。
entityを入力したファイルができたなら
copy、catを利用し、ライブラリ、パッケージ
architecture等の固定内容を、付加した
スケルトンファイルを作成します。
バッチファイルは、次のように記述します。
copy head.vhd+%1.vhd+behavior.vhd %2.vhd
バッチファイル内で指定されている2つの
ファイル内容は、以下とします。
head.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
behavior.vhd
architecture Behavioral of ??? is
begin
end Behavioral;
次のように操作します。
内容を確認すると、VHDLのファイルが
出来上がっていることがわかります。
ファイルができれば、テキストエディタを
使い、編集します。
Tcl/Tkスクリプト
AWKスクリプトは、CUIで操作しますがGUIでも
似た操作が欲しくなり、Tcl/Tkスクリプトで
GUIアプリケーションを作成しました。
最初に操作画面を考えます。
操作画面にあるオブジェクトを考えます。
メニューバー
「File」をクリックし、「Quit」を表示します。
「Quit」をクリックして、このアプリを終了します。
ラベル
信号名、入出力、ビット数を記述したテキスト
ファイルを入力とし、VHDLファイルを出力します。
テキスト、VHDLファイルのためのラベルを使います。
エントリ
2つのファイル名を表示します。
ボタン
テキストファイル名指定に「Open」ボタンを使います。
VHDLファイルを生成するため「Save」ボタンを使います。
AWKスクリプトと同様に、tst1.txtを利用しVHDLファイル
を作成してみます。
WindowsのExplorerを使い、mkvhd.tclをクリックします。
GUI画面を表示します。
テキストファイル指定に、「Open」ボタンをクリックします。
ファイルの選択になります。
例として、tst1.txtを指定します。
ファイル指定後、2つのエントリボックスに
内容が表示されます。
VHDLファイル名を変更します。
「Save」ボタンをクリックします。
ファイル名の拡張子に、VHDを付加します。
メニューバーにある「Quit」ボタンをクリックして
終了します。
作成されたVHDLファイルの内容を確認します。
AWKスクリプトよりも、多少盛り込む内容を
増やしてあります。
スクリプトの内容は、以下です。
#!/bin/sh
wm title . "Make vhdl code file"
###############
# substrate
###############
set ftext ""
set ftexts ""
set fvhdl ""
###############
# define label
###############
label .lblText -font {{MS ゴシック} 14 bold} -text "Text : "
label .lblVhdl -font {{MS ゴシック} 14 bold} -text "VHDL : "
###############
# define entry
###############
entry .edtText -font {{MS ゴシック} 14 bold} -textvariable ftext
entry .edtVhdl -font {{MS ゴシック} 14 bold} -textvariable fvhdl
##################
# define button
##################
button .btnOpen -font {{MS ゴシック} 14 bold} -text "Open" -command {OpenText}
button .btnSave -font {{MS ゴシック} 14 bold} -text "Save" -command {SaveVHDL}
#######################
# add menu on TopLevel
#######################
. configure -menu .mnuTop
menu .mnuTop
# add sub form
.mnuTop add cascade -label File -underline 0 -menu .mnuTop.file
menu .mnuTop.file -tearoff no
# add sub menu "Quit"
.mnuTop.file add command -label "Quit" -command {exit}
###########################
# Open text file procedure
###########################
proc OpenText {} {
global ftext
global ftexts
global fvhdl
# set file types
set ftype {{ "text Files" .txt} { "All Files" * }}
# get file name from built-in tool
set fname [tk_getOpenFile -filetypes $ftype -parent . ]
# store text file name
set ftext $fname
set ftexts [file tail $ftext]
set ftexts [lindex [split $ftexts "."] 0]
set fvhdl $ftexts
#tk_messageBox -type ok -message $ftexts
}
############################
# Save VHDL code procedure
############################
proc SaveVHDL {} {
global ftext
global ftexts
global fvhdl
# set file types
# append file extention
set fname "$fvhdl.vhd"
set fvhdl $fname
# open
set fd_out [open $fname "w"]
# store head
puts $fd_out "library IEEE;"
puts $fd_out "use IEEE.STD_LOGIC_1164.ALL;"
puts $fd_out "use IEEE.STD_LOGIC_ARITH.ALL;"
puts $fd_out "use IEEE.STD_LOGIC_UNSIGNED.ALL;"
puts $fd_out ""
puts $fd_out "entity $ftexts is"
puts $fd_out " port ("
# store Entity
set fd_in [open $ftext "r"]
set result ""
while { [gets $fd_in sbuf] >= 0 } {
# splite 1 line
set result $sbuf
set signame [lindex $result 0]
set inout [lindex $result 1]
set bcnt [lindex $result end]
# judge (direction)
if { $inout == "2" } {
set result " $signame : inout std_logic" ;
} else {
if { $inout == "1" } {
set result " $signame : out std_logic" ;
} else {
set result " $signame : in std_logic" ;
}
}
# judge (bit size)
if { $bcnt > 1 } {
set result [format "%s_vector(%d downto 0)" $result [expr $bcnt - 1]]
}
# store
puts $fd_out "$result ;"
}
close $fd_in
#
puts $fd_out " );"
puts $fd_out "end $ftexts ;"
# store Behavioral
puts $fd_out ""
puts $fd_out "architecture Behavioral of $ftexts is"
puts $fd_out " -- signal ??? : std_logic ;"
puts $fd_out "begin"
puts $fd_out " -- process (nRESET,CLOCK)"
puts $fd_out " -- begin"
puts $fd_out " -- if ( nRESET = '0' ) then"
puts $fd_out " -- "
puts $fd_out " -- elsif rising_edge( CLOCK ) then"
puts $fd_out " -- "
puts $fd_out " -- endif ;"
puts $fd_out " -- end process ;"
puts $fd_out ""
puts $fd_out "end Behavioral;"
# close
close $fd_out
}
##################
# displacement
##################
grid .lblText -column 0 -row 0
grid .edtText -column 1 -row 0
grid .lblVhdl -column 0 -row 1
grid .edtVhdl -column 1 -row 1
grid .btnOpen -column 0 -row 3
grid .btnSave -column 2 -row 3
TestBench雛型生成スクリプト
VHDLコードをテストするTcl/Tkスクリプトも作成しました。
使い方は、mkvhd.tclと殆ど同じです。
#!/bin/sh
wm title . "Make vhdl code test bench"
###############
# substrate
###############
set ftext ""
set ftexts ""
set fBench ""
###############
# define label
###############
label .lblText -font {{MS ゴシック} 14 bold} -text "Text : "
label .lblBench -font {{MS ゴシック} 14 bold} -text "Bench: "
###############
# define entry
###############
entry .edtText -font {{MS ゴシック} 14 bold} -textvariable ftext
entry .edtBench -font {{MS ゴシック} 14 bold} -textvariable fBench
##################
# define button
##################
button .btnOpen -font {{MS ゴシック} 14 bold} -text "Open" -command {OpenText}
button .btnSave -font {{MS ゴシック} 14 bold} -text "Save" -command {SaveBench}
#######################
# add menu on TopLevel
#######################
. configure -menu .mnuTop
menu .mnuTop
# add sub form
.mnuTop add cascade -label File -underline 0 -menu .mnuTop.file
menu .mnuTop.file -tearoff no
# add sub menu "Quit"
.mnuTop.file add command -label "Quit" -command {exit}
###########################
# Open text file procedure
###########################
proc OpenText {} {
global ftext
global ftexts
global fBench
# set file types
set ftype {{ "text Files" .txt} { "All Files" * }}
# get file name from built-in tool
set fname [tk_getOpenFile -filetypes $ftype -parent . ]
# store text file name
set ftext $fname
set ftexts [file tail $ftext]
set ftexts [lindex [split $ftexts "."] 0]
set fBench $ftexts
#tk_messageBox -type ok -message $ftexts
}
#################################
# Save Test Bench code procedure
#################################
proc SaveBench {} {
global ftext
global ftexts
global fBench
# set file types
# append file extention
set fname "Test_$fBench.vhd"
set fBench $fname
# open
set fd_out [open $fname "w"]
# store head
puts $fd_out "library IEEE;"
puts $fd_out "use IEEE.STD_LOGIC_1164.ALL;"
puts $fd_out "use IEEE.STD_LOGIC_ARITH.ALL;"
puts $fd_out "use IEEE.STD_LOGIC_UNSIGNED.ALL;"
puts $fd_out ""
puts $fd_out "use std.textio.all;"
puts $fd_out "use work.$ftexts;"
puts $fd_out ""
puts $fd_out "entity TESTBNCH is"
puts $fd_out "end TESTBNCH;"
puts $fd_out ""
puts $fd_out "architecture stimulus of TESTBNCH is"
puts $fd_out " component $ftexts is"
puts $fd_out " port ("
# store Component
set fd_in [open $ftext "r"]
set result ""
while { [gets $fd_in sbuf] >= 0 } {
# splite 1 line
set result $sbuf
set signame [lindex $result 0]
set inout [lindex $result 1]
set bcnt [lindex $result end]
# judge (direction)
if { $inout == "2" } {
set result " $signame : inout std_logic" ;
} else {
if { $inout == "1" } {
set result " $signame : out std_logic" ;
} else {
set result " $signame : in std_logic" ;
}
}
# judge (bit size)
if { $bcnt > 1 } {
set result [format "%s_vector(%d downto 0)" $result [expr $bcnt - 1]]
}
# store
puts $fd_out "$result ;"
}
close $fd_in
#
puts $fd_out " );"
puts $fd_out " end component;"
puts $fd_out ""
puts $fd_out " constant PERIOD : time := 50 ns;"
puts $fd_out " constant PER0 : time := 125 ns;"
puts $fd_out " constant PER1 : time := 875 ns;"
puts $fd_out ""
puts $fd_out " -- Top level signals go here..."
# store signal
set fd_in [open $ftext "r"]
set result ""
while { [gets $fd_in sbuf] >= 0 } {
# splite 1 line
set result $sbuf
set signame [lindex $result 0]
set inout [lindex $result 1]
set bcnt [lindex $result end]
# judge (direction)
if { $inout == "2" } {
set result " signal $signame : std_logic" ;
} else {
if { $inout == "1" } {
set result " signal $signame : std_logic" ;
} else {
set result " signal $signame : std_logic" ;
}
}
# judge (bit size)
if { $bcnt > 1 } {
set result [format "%s_vector(%d downto 0)" $result [expr $bcnt - 1]]
}
# store
puts $fd_out "$result ;"
}
close $fd_in
#
puts $fd_out " signal done: boolean := false;"
puts $fd_out ""
puts $fd_out "begin"
# get signal name
set fd_in [open $ftext "r"]
set result ""
while { [gets $fd_in sbuf] >= 0 } {
# splite 1 line
set signame [lindex $sbuf 0]
# concatenate
set result "$result,$signame"
}
close $fd_in
#
puts $fd_out " DUT: $ftexts port map ($result);"
puts $fd_out ""
puts $fd_out " -- CLOCK1"
puts $fd_out " process"
puts $fd_out " variable clktmp: std_ulogic := '0';"
puts $fd_out " begin"
puts $fd_out " wait for PERIOD/2;"
puts $fd_out " clktmp := not clktmp;"
puts $fd_out " -- CLOCK <= clktmp; -- Attach your clock here"
puts $fd_out " end process ;"
puts $fd_out ""
puts $fd_out " -- STIMULUS1"
puts $fd_out " process"
puts $fd_out " begin"
puts $fd_out " -- Sequential stimulus goes here..."
puts $fd_out " --"
puts $fd_out " -- Sample stimulus..."
puts $fd_out " -- nRESET <= '0' ; -- Reset the system"
puts $fd_out " wait for RPERIOD; -- Wait"
puts $fd_out " -- nRESET <= '1' ; -- de-assert reset"
puts $fd_out " wait for PER0; -- Wait"
puts $fd_out " -- ENABLE <= '1' ;"
puts $fd_out " wait for PER1; -- Wait"
puts $fd_out " -- ENABLE <= '0' ;"
puts $fd_out " -- "
puts $fd_out " -- Enter more stimulus here..."
puts $fd_out " --"
puts $fd_out " done <= true; -- Turn off the clock"
puts $fd_out " wait; -- Suspend simulation"
puts $fd_out " end process ;"
puts $fd_out ""
puts $fd_out "end stimulus;"
# close
close $fd_out
}
##################
# displacement
##################
grid .lblText -column 0 -row 0
grid .edtText -column 1 -row 0
grid .lblBench -column 0 -row 1
grid .edtBench -column 1 -row 1
grid .btnOpen -column 0 -row 3
grid .btnSave -column 2 -row 3
真理値表記述生成スクリプト(AWK)
VHDLで真理値表を表現する記述は、以下。
LED <=
"11111110" when ( GCBA = "100000" ) else
"11111101" when ( GCBA = "100001" ) else
"11111011" when ( GCBA = "100010" ) else
"11110111" when ( GCBA = "100011" ) else
"11101111" when ( GCBA = "100100" ) else
"11011111" when ( GCBA = "100101" ) else
"10111111" when ( GCBA = "100110" ) else
"01111111" when ( GCBA = "100111" ) else
"11111111" ;
似かよった文字列を入力すると、タイプミスを
しやすいので、テキストファイルに必要充分な
情報を格納して、スクリプトでVHDL記述に変換
する方が確実と考えました。
テキストファイルの内容は、以下。
LED
"11111110" GCBA "100000"
"11111101" GCBA "100001"
"11111011" GCBA "100010"
"11110111" GCBA "100011"
"11101111" GCBA "100100"
"11011111" GCBA "100101"
"10111111" GCBA "100110"
"01111111" GCBA "100111"
"11111111" ;
1行目に、代入する信号名を入れて
2行目以降には、出力、判定で使う信号名
条件値を格納。
最終行は、デフォルトの条件値を置きます。
この書式で、VHDL記述生成スクリプトは
次のように定義。
{
# variable signal name
if ( NF == 1 ) {
printf("%s <= \n",$1)
}
# last value
if ( NF == 2 && $2 == ";" ) {
printf("\t%s ;\n",$1)
}
# table
if ( NF == 3 ) {
printf("\t%s when ( %s = %s ) else \n",$1,$2,$3)
}
}
使うときは、コマンドラインにタイプするだけになります。
ファイルに保存したければ、I/Oリダイレクトを利用。
目次
前
次