目次

ソフトウエアツール

 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で動かします。  大まかな動作を考えてみます。  スクリプトの内容は、以下です。 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リダイレクトを利用。


目次 inserted by FC2 system