key word :
AND , OR , Ex-OR , NOT , Half-Adder , Full-Adder
下位モジュールとの接続方法(順番・名前) 7セグメントデコーダー
001の方では大まかな構成を書いたので、今回は論理回路の記述を。
・AND
VHDL 記述 | 真理値表 | 記号 | |||||||||||||||
architecture RTL of add is signal a : std_logic; signal b : std_logic; signal c : std_logic_vector (1 downto 0); signal z : std_logic; signal z2 : std_logic; begin z <= a and b; z2 <= a and c(0); end RTL |
|
![]() |
ぱっと見ただけでもverilogより堅そうなイメージ。
・OR
VHDL 記述 | 真理値表 | 記号 | |||||||||||||||
architecture RTL of or is signal a : std_logic; signal b : std_logic; signal z : std_logic; begin z <= a or b; end RTL |
|
![]() |
OR。それ以上でもそれ以下でもない。
・Ex-OR
VHDL 記述 | 真理値表 | 記号 | |||||||||||||||
architecture RTL of xor is signal a : std_logic; signal b : std_logic; signal z : std_logic; begin z <= a xor b; end RTL |
|
![]() |
あんまり使わないから、久しぶりに使うときどっちが1だったか忘れてしまったり。
・Not
VHDL 記述 | 真理値表 | 記号 | ||||||
architecture RTL of not is signal a : std_logic; signal z : std_logic; begin z <= not a; end RTL |
|
![]() |
否定。
とりあえず最低限の記述はこんなもんです。
一応、これは内部の信号を使った場合の記述です。
以降は、外部信号を利用した場合がメインになると思われます。
・半加算器 Half-Adder
VHDL 記述 | 真理値表 | 記号 | ||||||||||||||||||||
entity ten_counter is port ( a : in std_logic; b : in std_logic; z : out std_logic; c : out std_logic ); end ten_counter; architecture RTL of hadd is begin z <= a xor b; c <= a and b; end RTL |
|
![]() |
半加算。
入力した2つの値を加算し、その出力と桁上がり分を出力
真理値表を見ての通り、桁上がり無しの出力zはEx-ORの値。
桁上がりの分はANDの値。
・全加算器 Full-Adder
VHDL 記述 | 内容 | |
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity hadd is port ( a : in std_logic; b : in std_logic; z : out std_logic; c : out std_logic ); end hadd; architecture RTL of hadd is begin z <= a xor b; c <= a and b; end RTL |
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity fadd is port ( a : in std_logic; b : in std_logic; cin : in std_logic; zout : out std_logic; cout : out std_logic ); end fadd; architecture RTL of fadd is component ten_counter port ( a : in std_logic; b : in std_logic; z : out std_logic; c : out std_logic ); end domponent begin hadd1: hadd port map ( a, b, z1, c1 ); hadd2: hadd port map ( a => a, b => cin, z => zout1, c => c2 ); cout <= c1 xor c2; end RTL |
全加算。 半加算器の入力に、桁上がり分を追加 Haを組み合わせて記述。 VHDL記述の上部に記述してあるのhaddがモジュール名で、作った各.vhdファイルの最初に定めたentity名と同じ。 別のファイルで作ってある。 一応、同一のファイル内に記述して後で呼び出してもRTLシミュでは動くが、 ゲートシミュで使うツールでは駄目な場合があるのでモジュール毎に分けるのが吉 下部でのhadd1,hadd2は、インスタンス名で、このモジュール内で使用する際の個別の名前 functionが回路内部に記述するのに対し、外部にある回路といったイメージである。 hadd1では、ポートリスト順による接続をしており、モジュールhaddに記述されている順に値が代入される。 使用する値が少なく、構造も簡単な場合は手間がかからず楽であるが、 信号数が増え、接続が複雑になるとhadd2の様な名前による接続を行ったほうが 見ただけで判るので良い。 他人に判り易く、後から記述を見ても判り易いという事を考えると、後者の方が優れている。 |
真理値表 | 記号 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
![]() |
・下位モジュールとの接続に関して
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity hadd is
port (
a : in std_logic;
b : in std_logic;
z : out std_logic;
c : out std_logic
);
end hadd;
architecture RTL of hadd is
begin
z <= a xor b;
c <= a and b;
end RTL
↑呼び出し対象
・順番による接続
hadd1:
hadd port map
(
a,
b,
z1,
c1
);
名前の通り、呼び出し側モジュールで値が宣言されている順にならって値を代入。
xにはxを yにはyを zにはz1を cにはc1を入れる。
・名前による接続
hadd2:
hadd port map
(
a => a,
b => cin,
z => zout1,
c => c2
);
同じく名前の通り、呼び出し対象のどの部分にどんな値を入れるかを記述。
a =>ってのが、呼び出し対象側のaに相当。
最初はちょっと面倒に感じるかもしれないけれど、視覚的に判り易いのでこちらで慣れるのをお勧めします。
・7セグメントデコーダ
動作 | 真理値表 | 記号 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
a-gの信号がLの時に点灯。 |
|
![]() |
時間の入力信号qに対してそれをデコードし、入力信号に応じたデコード信号a-gを出力する。
真理値表より、 a が点灯する条件としては入力値A-Dが"0001"と"0100"の時であり、これを回路で表すと以下のようになる。
そして、VHDL記述は
a <= ((not A) and (not B) and (not C) and D) or ((not A) and B and (not C) and (not D)); |
![]() |
・・・VHDL記述で書きたいところだけれど、 assign a = (~q[3] & ~q[2] & ~q[1] & q[0]) | (~q[3] & q[2] & ~q[1] & ~q[0]); a <= ((not A) and (not B) and (not C) and D) or ((not A) and B and (not C) and (not D)); 上記のようにverilog記述に比べてかったるいので、verilog記述でお送りします。後は上の例を見て脳内補完で。 assign e = (~A & D) | (~A & ~B & ~C) | (~B & ~C & D); 更に冗長項を利用すると assign e = D | (~B & ~C); となる。 今更カルノー図の説明は要らんよね? |
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity segment is port ( q : in std_logic; seg : out std_logic_vector(6 downto 0); ); end segment; architecture RTL of segment is begin seg(6) <= ((not A) and (not B) and (not C) and D) or ((not A) and B and (not C) and (not D)); 以下略 end RTL |
そんな訳でカルノー図を使い記述を楽にするのだけれど、それでも結構面倒だし、
第一式を見ただけじゃ何をやっているのか分からんです。 一応動きますけど。。 |
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity segment is port ( q : in std_logic; seg : out std_logic_vector(6 downto 0); ); end segment; architecture RTL of segment is begin process (q) begin case q is when "0000" => seg <= "0000001"; when "0001" => seg <= "1001111"; when "0010" => seg <= "0010010"; when "0011" => seg <= "0000110"; when "0100" => seg <= "1001100"; when "0101" => seg <= "0100100"; when "0110" => seg <= "0100000"; when "0111" => seg <= "0001101"; when "1000" => seg <= "0000000"; when "1001" => seg <= "0001100"; when others => seg <= "0110000"; end case; end process; end RTL; |
そこで登場するのが case文 qの値が 4'b000 だった場合 segment = 7'0000001;を行う って感じです。 予期しない値が入力された場合に備えてothersを定めるのはデフォ。 この場合のprocessは、qが変化した際に動作するって意味。 |
◎定数の表現
定数は'1' '1010'のように文字や文字列として扱う。
16進や10進での表記も可能だが、制約が多いので実質的に2進数表記のみ用いる。
◎論理値
1bitの信号が取り扱う値は、論理回路の世界では0or1であるが、
この他にも不定値X、H・インピーダンスZがある。
◎演算子
not、andなどは論理演算子
◎代入記号
信号に対する代入は <= を用いる。ここでの代入は、「同時処理代入文」
記述の順番に行うのではなく、「同時」に代入される。
◎分岐条件
when 〜 elseを用いて2方向分岐を記述できる。when直後の条件式が
真:when直前の式の値
偽:else直後の式の値
◎コメント
--で始まり、行末までがコメント
複数行コメントは無し。
◎文字の大小の区別
予約語も含めて文字の大小の区別は行わない。
◎変数の代入
constantで定められた値には <= で値を代入するのではなく、 := で値を代入する。