忍者ブログ

[PR]

2025年04月26日
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

subprogram宣言を使ってみた

2008年11月30日
同じ文を何度も書くと、関数にしたくなります。
そこでsubprogram宣言に挑戦してみました。これを使うと、
-----------------------------------------------------
ARCHITECTURE behavior OF hoge IS 

 function func_hoge(以下略...)
 end func_hoge;
 
 signal A,B,x,y : std_logic;

begin

 A := func_hoge(x);
 B:= func_hoge(y);

end hoge;
-------------------------------------------------------
みたいな感じで書けます。
コンポーネントとどこが違うんだ?と思いますよね。
ファンクション文は出力が一個だけで、それこそC言語の関数みたいですが、
プローシージャ文は入出力を任意に設定でき、それこそコンポーネントと大差無い様に見えます。

サブプログラムとコンポーネントの違いは、コンポーネントが下位層にある全く別の回路(別ファイル)を繋げて階層化するのに対して、サブプログラムの場合、機能自体を信号やコンポーネントのI/Oを定義するアーキテクチャ宣言部に書いてしまうので、一つ回路内で完結しているということです。
よって、C言語と違って関数を別ファイルにすることが出来ません。
従って、一つのソース内で何度も使用するが階層化するほどでもない、
小さい処理を関数にしたいときにサブプログラムを使うと良さそうです。


--追記、サブプログラム宣言の入出力は、信号か変数しかとらないそうです。
fprintfみたいな関数を作ろうとしていたが残念。
ファイル入出力用の便利なパッケージを作りたいです。
てかサブプログラムに出力がある必然性を感じられない。void型みたいなのがあればいいのに、
ファイル入出力ぐらいしか需要がなさそうだが。

----まとめ----
ファンクション 戻り値一個の組み合わせ回路
プロシージャー 戻り値複数の組み合わせ回路
コンポーネント 順序回路
綺麗にまとまった!
PR

ファイルへの入出力

2008年11月25日

テストベンチの際に、ファイルへ任意の値を入出力するやり方

1.まず、use ieee.std_logic_textio.all; と、use std.textio.all; を宣言。

2.ファイル型を定義
  file read_file text open read_mode is "input.txt"; --入力ファイル
  file write_file text open write_mode is "output.txt" --出力ファイル

3.入力ファイルから値の読み出し(値は2進数)
  variable read_line : line;   --変数のライン型を定義
  variable read_value : std_logic_vector();

  readline(read_file,read_line); --ファイルの一行を読み出し
  read(read_line,read_value); --行中の値を読み出し(信号ではなく変数)
  hoge <= read_value; --信号に代入して、後は煮るなり焼くなり

4.出力ファイルへの書き出し
  variable write_line : line;
  variable write_value : std_logic_vector(); --signalでもok!

  write(write_line,write_value,right,10); --10の文字幅で値を行に右詰め格納(値は信号可)
  writeline(write_file,write_line); --行をファイルに書き出し

5.バリエーション
  oread(); owrite(); --read,writeの8進数ver. bit数は3の倍数
  hread(); hwrite(); --read,writeの16進数ver. bit数は4の倍数
  条件に満たない場合は適当に&で連結して任意の倍数bit長にしましょう。

--追記
16進数をファイルからreadする場合は
型の大きさより小さい数は、空白を0で埋めなきゃ駄目ですね。
Excelでもそうですしファイル読み取り全般に言えることらしいです。

FIFOもどきを作る

2008年11月21日
他のモジュールとの信号のタイミングを合わせるバッファとして、FIFOを作りました。
そこでFIFOのソースを探してみたら、何やらFullFlagやらEmptyFlagやら難しい機能がやたら目に付きました。単に信号を遅延させるだけでいいのに・・・。

1.シフトレジスタで代用
 
 IPでもいいのですがgeneric文で汎用性の高い部品を作りたかったので、自分でソースを書くことにしました。とりあえず、ROMやRAMのソースをベースにして作るということでarray文にも挑戦してみたのですが、なかなか上手くいかず・・・

結局2次元配列なんてかっこいいことは出来ずに、複数ビット分だけシフトするシフトレジスタでFIFOの機能を実現することにしました。要はデータ×レイテンシの幅のシフトレジスタを作るわけです。

記述がかなりシンプルで済みました。動作速度800MHz
ん?何か間違っているんじゃないか??


それに、実用的な機能を再現するだけでも恐ろしい幅になってしまいます。
32bit×50レイテンシ=1600bit
怖い怖い。

2.BRAMを使用
 
 メモリにスライスを割り当てると案の定回路がものすごく大きくなってしまったので、FPGAに搭載されているBRAMを使用することにしました。既存のRAM回路からアドレス関係のI/Oを取り除き、内部にアドレス指定のカウンタを取り付けることでそれっぽく動作させました。メモリ関係のソースはこちらのページが参考になります。
http://www.nahitech.com/nahitafu/fpgavhdl/bram/bram.html

VHDLの定数に関して

2008年11月20日
数字定数
固定された整数を表現。#で囲み、基数を指定することも可能(2,8,16のみ)
46   -- 10進定数
2#101001#  -- 2進定数
16#AC#  -- 16進定数

文字定数
' '(クオート)で囲まれた1bitのバイナリを表現、Std_Logicで良く使う。

ストリング定数
" "(ダブルクオート)で囲まれた複数bitのバイナリを表現、Std_Logic_Vectorで良く使う。

VHDLの型に関して

2008年11月20日
VHDLは型については非常に厳格な言語です。C言語等と違って、異なる型同士で、演算、代入をする場合にはキャストをしないと必ずエラーが返ってきます。まぁそこが良い所でもあるのですが!
そこで型に関して簡単に紹介するので参考にして下さい。それぞれの型がどのライブラリで定義されているかまで説明すれば、長くなるんで割愛します。
  • Std_Logic
    • 1bitデータを扱う。
  • Std_Logic_Vector(基本はこれ)
    • 複数ビットデータを扱う 
  • Signed(Std_Logic_Vectorのサブタイプ。符号アリ)
  • Unsigned(Std_Logic_Vectorのサブタイプ。符号ナシ)
  • Integer(整数。constantで定数を宣言するときに使ったりします。)
  • Real(実数。これは使わないなー)
Std_Logic_Vectorの型だけでは算術演算は出来ません。例えば負の数は2の補数で表現されますが、Std_Logic_Vectorだとそれを正の数として計算するので、実際の値と異なってしまいます。正負が入り混じった演算をしたい場合は、signed、unsignedで一時的にキャストしましょう。

Xが符号ナシ、Yが符号アリの場合このようにキャストすると正しい値が出てきます。

Z<=unsigned(X)*signed(Y)
« 前のページ | HOME |