職業訓練29日目 PLD基本設計 テキスト入力(VHDLによる設計)
VHDLの文法
ライブラリ宣言
使用するライブラリを記述。
他の言語で言う、import文、include文か。
library ライブラリ名;
use ライブラリ名.パッケージ名.アイテム;
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all;
エンティティ宣言
後に出てくるアーキテクチャ宣言を含めて考えると、
クラスみたいなものの方が近いかも。
でも、引数も取れるからクラスと関数宣言を合わせたような感じ?
クラスっていう表現もあまり適当ではないかも。
単に、回路の名前と入力・出力を定義しただけ、
って考えた方がすんなりいくかも。
entity エンティティ名 is
port(信号名, ... : 入出力タイプ 信号タイプ;
信号名, ... : 入出力タイプ 信号タイプ);
end エンティティ名;
entity ENTITY_NAME is port(A, B : in std_logic; C, D : out std_logic); end ENTITY_NAME;
内部信号宣言
エンティティ内部で使われる信号の宣言。
「変数」ってことで良い?
signal 信号名 : 信号タイプ;
signal A, B : bit; signal C : std_logic; signal D : std_logic_vector(7 downto 0); signal E : std_logic_vector(0 to 7);
アーキテクチャ宣言
回路の機能の記述を行うための宣言。
「関数」や「メソッド」のような感じ?
(再利用っていう面も考えるとcomponentっていうのもあるみたいですが、まだ未利用なのでいまいち分かってません)
architecture アーキテクチャ名 of エンティティ名 is
-- 回路機能の記述
end アーキテクチャ名;
architecture ARCHITECTURE_NAME of ENTITY_NAME -- 回路機能の記述 end ARCHITECTURE_NAME;
シーケンシャルステートメント
回路の機能を記述
process文に含まれる代入文を指す。
「イベントリスナ」に近い感じがする。
特に、センシティビティ・リストに書いてある信号に変化があったときに、
process文の中の処理が実行される、っていうあたりが。
気をつけるべきは、process文内の処理は、
順次処理じゃなく、同時処理ってことですね。
(といっても、そこがいまいち理解できてないポイントだったりしますが…orz)
process(入力信号--センシティビティ・リスト)
begin
-- プロセス文内の機能記述
end process;
process(A, B) begin C <= A or B; D <= A nand B; end process;
このprocess文の理解が今一歩な感じがするので、リンクも貼っておこっと。
http://laputa.cs.shinshu-u.ac.jp/~yizawa/VHDL/process.htm
if文
if 条件式 then
-- ステートメント
elsif 条件式 then
-- ステートメント
else
-- ステートメント
end if;
if (RESET = '1') then COUNT <= "0000"; elsif (CLK'event and CLK = '1') then COUNT <= COUNT + '1'; end if;
条件式の括弧は付けなくても大丈夫だったはず。
それでも、多少まどろっこしい間は否めないけど…。
case文
case 信号 is
when 値 => 代入;
when 値 => 代入;
when 値 => 代入;
when others => 代入;
and case;
case SEL is when "001" => SOUT <= A; when "010" => SOUT <= B; when "100" => SOUT <= C; when others => SOUT <= "UU"; and case
代入式
<=
with SEL select SOUT <= A when "001", B when "010", C when "010", "UU" when others;
上記で所々使ってきたのでいまさらではありますが…。
テキストの例文を丸写ししちゃいましたが、
when句の使い方がいまいち分からない。
練習問題の回答例も書き方がちょっと違うし。
論理演算子
- and
- or
- nand
- nor
- xor
- not
A <= B and C; D <= not (B or C);
そのまま書けばOKのようです。
優先順位は「notが高い」ってCPLDのテキストに書いてありました。
クォーテーション
- 1bit→シングルクォーテーション ex) '0', '1'
- 2bit以上→ダブルクォーテーション ex) "00", "001", "0010"
その他注意事項
- 大文字と小文字を区別しない
- 使用可能な文字は、英字、数字、_(アンダースコア)
- 最初の文字は英字
- "--"から行末までがコメント
- outで宣言された信号を参照できない
D型フリップフロップ
-- クロック信号の変化を捉える process(CLK) begin -- 立ち上がりエッジの処理 if (CLK'event and CLK = '1') then Q <= D; end if; end process;
「CLK'event」のシングルクォートが何とも気持ち悪いのは自分だけでしょうか?