琉球大学情報工学科 和田 知久
library IEEE;
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD;
entity MUX4_1 is
port (Sel : in unsigned (1 downt 0);
A, B, C, D : in std_logic;
Y : out std_logic);
end entity MUX4_1;
architecture COND_DATA_FLOW of MUX4_1 is
begin
ここに内容を記述する。
end architecture COND_DATA_FLOW;
process (Sel, A, B, C, D)
begin
if (Sel = "00") then
Y <= A;
elsif (Sel = "01" then
Y <= B;
elsif (Sel = "10") then
Y <= C;
else
Y <= D;
end if;
end process;
Y <= A when Sel = "00" else
B when Sel = "01" else
C when Sel = "10" else
D ; -- when Sel="11"
process (Sel, A, B, C, D)
begin
if (Sel(1) = '0' ) then
if (Sel(0) = '1') then
Y <= A;
else
Y <= B;
end if;
else
if (Sel(0) = '0') then
Y <= C;
else
Y <= D;
end if;
end if;
end process;
内容4:case文
process (Sel, A, B, C, D)
begin
case Sel is
when "00" => Y <= A;
when "01" => Y <= B;
when "10" => Y <= C;
when others => Y <= D;
end case;
end process;
内容5:選択代入文
with Sel select
Y <= A when "00",
B when "01",
C when "10",
D when others;
INPUTS | OUTPUTS | ||||||||||
A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 | Y2 | Y1 | Y0 | Valid |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | X | X | X | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | X | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 | 0 | 1 | X | X | 0 | 1 | 0 | 1 |
0 | 0 | 0 | 0 | 1 | X | X | X | 0 | 1 | 1 | 1 |
0 | 0 | 0 | 1 | X | X | X | X | 1 | 0 | 0 | 1 |
0 | 0 | 1 | X | X | X | X | X | 1 | 0 | 1 | 1 |
0 | 1 | X | X | X | X | X | X | 1 | 1 | 0 | 1 |
1 | X | X | X | X | X | X | X | 1 | 1 | 1 | 1 |
以下に3種類のVHDLの記述方法を説明する。
library IEEE;
use IEEE.STD_LOGIC_1164.all; IEEE.NUMERIC_STD.all;
entity PRI_EN8_3 is
port (A : in unsigned (7 downto 0);
Valid : out std_logic;
Y : out unsigned (2 downto 0));
end entity PRI_EN8_3;
architecture COND_DATA_FLOW of PRI_EN8_3 is
begin
ここに内容を記述する。
end architecture COND_DATA_FLOW of PRI_EN8_3;
内容1:if文
process (A)
begin
Valid <='1';
if (A(7) = '1') then Y <= "111";
elsif (A(6) = '1') then Y <= "110"
elsif (A(5) = '1') then Y <= "101"
elsif (A(4) = '1') then Y <= "100"
elsif (A(3) = '1') then Y <= "011"
elsif (A(2) = '1') then Y <= "010"
elsif (A(1) = '1') then Y <= "001"
elsif (A(0) = '1') then Y <= "000"
else
Valid <='0';
Y <= "XXXX";
end if;
end process;
内容2:case文
process (A)
Variable A_int : integer range 0 to 255;
begin
A_int := to_integer (A);
Valid <='1';
case (A) is
when 128 to 255 => Y <= "111";
when 64 to 128 => Y <= "110";
when 32 to 63 => Y <= "101";
when 16 to 31 => Y <= "100";
when 8 to 15 => Y <= "011";
when 4 to 7 => Y <= "010";
when 2 to 3 => Y <= "001";
when 1 => Y <= "000";
when others => Valid <= '0' ; Y <=
"XXX";
end case;
end process;
内容3:for-loop文
process (A)
begin
Valid <='0';
Y <= "XXX";
for N in 0 to 7 loop
if (A(N) = '1') then
Y <= To_Unsigned (N, 3);
Valid <= '1' ;
end if;
end loop;
end process;
あるarithmetic logic unit (ALU)の設計
S4 | S3 | S2 | S1 | S0 | Cin | 動作 | 説明 | 実行ブロック |
0 | 0 | 0 | 0 | 0 | 0 | Y <= A | Aを転送 | Arithmetic Unit |
0 | 0 | 0 | 0 | 0 | 1 | Y <= A+1 | Aをインクリメント | Arithmetic Unit |
0 | 0 | 0 | 0 | 1 | 0 | Y <= A + B | 加算 | Arithmetic Unit |
0 | 0 | 0 | 0 | 1 | 1 | Y <= A + B + 1 | キャリー付加算 | Arithmetic Unit |
0 | 0 | 0 | 1 | 0 | 0 | Y <= A + Bbar | AとBの1の補数をたす | Arithmetic Unit |
0 | 0 | 0 | 1 | 0 | 1 | Y <= A + Bbar + 1 | 減算 | Arithmetic Unit |
0 | 0 | 0 | 1 | 1 | 0 | Y <= A - 1 | デクリメント | Arithmetic Unit |
0 | 0 | 0 | 1 | 1 | 1 | Y <= A | Aを転送 | Arithmetic Unit |
0 | 0 | 1 | 0 | 0 | 0 | Y <= A and B | 論理積 | Logic Unit |
0 | 0 | 1 | 0 | 1 | 0 | Y <= A or B | 論理和 | Logic Unit |
0 | 0 | 1 | 1 | 0 | 0 | Y <= A xor B | 排他的論理和 | Logic Unit |
0 | 0 | 1 | 1 | 1 | 0 | Y <= Abar | 1の補数 | Logic Unit |
0 | 0 | 0 | 0 | 0 | 0 | Y <= A | Aを転送 | Shifter Unit |
0 | 1 | 0 | 0 | 0 | 0 | Y <= shl A | Aを左シフト | Shifter Unit |
1 | 0 | 0 | 0 | 0 | 0 | Y <= shr A | Aを右シフト | Shifter Unit |
1 | 1 | 0 | 0 | 0 | 0 | Y <= 0 | 0を転送 | Shifter Unit |
library IEEE;
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all;
entity ALU is
port ( Sel : in unsigned(4 downto 0);
CarryIn: in std_logic;
A, B : in unsigned(7 downto 0);
Y : out unsigned(7 downto 0));
end entity ALU;
architecture COND_DATA_FLOW of ALU is
begin
ALU_AND_SHIFT:
process (Sel, A, B, CarryIn)
variable Sel0_1_CarryIn : unsigned(2 downto 0);
variable LogicUnit, ArithUnit, ALU_NoShift : unsigned(7
downto 0);
begin
---------------
-- Logic Unit
---------------
LOGIC_UNIT: case Sel(1 downto 0) is
when "00" => LogicUnit := A
and B;
when "01" => LogicUnit := A
or B;
when "10" => LogicUnit := A
xor B;
when "11" => LogicUnit := not
A;
when others => LogicUnit := (others =>
'X');
end case LOGIC_UNIT;
---------------
-- Arithmetic Unit
---------------
Sel0_1_CarryIn := Sel(1 downto 0) & CarryIn; -- VHDLではcaseに連接を使えない
ARITH_UNIT: case Sel0_1_CarryIn is
when "000" => ArithUnit := A;
when "001" => ArithUnit := A
+ 1;
when "010" => ArithUnit := A
+ B;
when "011" => ArithUnit := A
+ B + 1;
when "100" => ArithUnit := A
+ not B;
when "101" => ArithUnit := A
- B;
when "110" => ArithUnit := A
- 1;
when "111" => ArithUnit := A;
when others => ArithUnit := (others =>
'X'); -- "XXXXXXXX"の意味
end case ARITH_UNIT;
---------------
-- Multiplex
---------------
LA_MUX: if (Sel(2) = '1' ) then
ALU_NoShift := LogicUnit;
else
ALU_NoShift := ArithUnit;
end if LA_MUX;
---------------
-- Shift operation
---------------
SHIFT: case Sel(4 downto 3 ) is
when "00" => Y <=
ALU_NoShift;
when "01" => Y <=
Shift_left(ALU_NoShift, 1); -- NUMERIC_STD関数
when "01" => Y <=
Shift_right(ALU_NoShift, 1); -- NUMERIC_STD関数
when "10" => Y <= (others
=> '0');
when others => Y <= (others => 'X');
end case SHIFT;
end process ALU_AND_SHIFT;
end architecture COND_DATA_FLOW;
Variable と Signal (代入が時間的に異なり、トラブリやすい)
architecture RTL of REI is signal X, Y, Z, C : unsigned (3 downto 0); signal A, B : unsigned(3 downto 0); begin process (X, Y, Z, C) begin C <= Z; end process; A <= X + Y B <= X + Y |
architecture RTL of REI is signal X, Y, Z : unsigned (3 downto 0); signal A, B : unsigned(3 downto 0); begin process (X, Y, Z) C := Z; end process; A <= X + Z B <= X + Y |