職業訓練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;
信号タイプ

いわゆる「型」ですよね?
vectorが付くと配列っぽい感じ。

  • bit, bit_vector:'1'または'0'
  • std_logic, std_logic_vector:'0', '1', 'U', 'Z'などの値
  • integer:32ビットの整数値

std_logicの取りうる値については、調べたらすぐ出てきた!
std_logic

内部信号宣言

エンティティ内部で使われる信号の宣言。
「変数」ってことで良い?

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」のシングルクォートが何とも気持ち悪いのは自分だけでしょうか?