第五章 组合逻辑电路设计
5.1 门电路
5.2 编码器
5.3 优先编码器
5.4 译码器
5.5 多路选择器
5.6 数值比较器
5.7 加法器
在前面的各章里,分别介绍了VHDL语言的语句、语法以及利用VHDL语言设计硬件电路的基本方法,本章重点介绍利用VHDL语言设计基本组合逻辑模块的方法。
5.1 门电路
二输入异或门
二输入异或门的逻辑表达式如下所示:
二输入异或门的逻辑符号如图所示,真值表如下表所示:
a b y
0 0 0
0 1 1
1 0 1
1 1 0
例:采用行为描述方式设计的异或门
(依据逻辑表达式)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY xor2_v1 IS
PORT(a,b: IN STD_LOGIC;
y: OUT STD_LOGIC);
END xor2_v1;
ARCHITECTURE behave OF xor2_v1 IS
BEGIN
y <= a XOR b; --并行语句
END behave;
例:采用数据流描述方式设计的异或门
(依据真值表)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY xor2_v2 IS
PORT(a,b: IN STD_LOGIC;
y: OUT STD_LOGIC);
END xor2_v2;
ARCHITECTURE dataflow OF xor2_v2 IS
BEGIN
PROCESS (a,b)
VARIABLE comb : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
comb := a & b;
CASE comb IS
WHEN "00"=> y <='0';
WHEN "01"=> y <='1';
WHEN "10"=> y <='1';
WHEN "11"=> y <='0';
WHEN OTHERS => y <='X';
END CASE;
END PROCESS;
END dataflow;
5.2 编码器
用一组二进制代码按一定规则表示给定字母、数字、符号等信息的方法称为编码,能够实现这种编码功能的逻辑电路称为编码器。
输入 输出
I0 I1 I2 I3 I4 I5 I6 I7 A2 A1 A0
1 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 1 1
0 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 1 0 0 1 0 1
0 0 0 0 0 0 1 0 1 1 0
0 0 0 0 0 0 0 1 1 1 1
8线—3线编码器真值表
8线—3线编码器逻辑表达式:
A2=I4+I5+I6+I7
A1=I2+I3+I6+I7
A0=I1+I3+I5+I7
例:采用行为描述方式的8线—3线编码器VHDL源代码 (依据逻辑表达式)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY coder83_v1 IS
PORT(I0,I1,I2,I3,I4,I5,I6,I7: IN STD_LOGIC;
A0,A1,A2: OUT STD_LOGIC);
END coder83_v1;
ARCHITECTURE behave OF coder83_v1 IS
BEGIN
A2 <= I4 OR I5 OR I6 OR I7;
A1 <= I2 OR I3 OR I6 OR I7;
A0 <= I1 OR I3 OR I5 OR I7;
END behave;
例:采用数据流描述方式的8线—3线编码器VHDL源代码(依据真值表)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY coder83_v2 IS
PORT( I: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END coder83_v2;
ARCHITECTURE dataflow OF coder83_v2 IS
BEGIN
PROCESS (I)
BEGIN
CASE I IS
WHEN "10000000"=> A <="111";
WHEN "01000000"=> A <="110";
WHEN "00100000"=> A <="101";
WHEN "00010000"=> A <="100";
WHEN "00001000"=> A <="011";
WHEN "00000100"=> A <="010";
WHEN "00000010"=> A <="001";
WHEN OTHERS => A <="000";
END CASE;
END PROCESS;
END dataflow;
5.3 优先编码器
输 入 输出
EI I0 I1 I2 I3 I4 I5 I6 I7 A2 A1 A0 GS EO
1 × × × × × × × × 1 1 1 1 1
0 1 1 1 1 1 1 1 1 1 1 1 1 0
0 × × × × × × × 0 0 0 0 0 1
0 × × × × × × 0 1 0 0 1 0 1
0 × × × × × 0 1 1 0 1 0 0 1
0 × × × × 0 1 1 1 0 1 1 0 1
0 × × × 0 1 1 1 1 1 0 0 0 1
0 × × 0 1 1 1 1 1 1 0 1 0 1
0 × 0 1 1 1 1 1 1 1 1 0 0 1
0 0 1 1 1 1 1 1 1 1 1 1 0 1
74148优先编码器真值表 (反码编码方案)
各输出端的逻辑方程
以74148逻辑表达式为依据,按行为描述方式编写的VHDL源代码如 下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY prioritycoder83_v1 IS
PORT(I7,I6,I5,I4,I3,I2,I1,I0 : IN STD_LOGIC;
EI:IN STD_LOGIC;
A2,A1,A0: OUT STD_LOGIC;
GS,EO:OUT STD_LOGIC);
END prioritycoder83_v1;
ARCHITECTURE behave OF prioritycoder83_v1 IS
BEGIN
A2 <= EI OR (I7 AND I6 AND I5 AND I4);
A1 <= EI OR (I7 AND I6 AND I3 AND I2)
OR (I7 AND I6 AND NOT I5)
OR (I7 AND I6 AND NOT I4) ;
A0 <= EI OR (I7 AND NOT I6)
OR (I7 AND I5 AND NOT I4)
OR (I7 AND I5 AND I3 AND I1)
OR (I7 AND I5 AND I3 AND NOT I2);
GS <= EI OR (I7 AND I6 AND I5 AND I4 AND I3
AND I2 AND I1 AND I0);
EO <= EI OR NOT(I7 AND I6 AND I5
AND I4 AND I3 AND I2 AND I1 AND I0);
END behave;
注意:采用数据流编写优先编码器时,因为VHDL语言目前还不能描述任意项,即下面的语句形式是非法的:WHEN “0XXXXXXX”=>A<=“000”;
因此不能用CASE语句来描述74148 。采用IF语句对74148进行了逻辑描述 如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY prioritycoder83_v2 IS
PORT ( I: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
EI:IN STD_LOGIC;
A: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
GS,EO:OUT STD_LOGIC);
END prioritycoder83_v2;
ARCHITECTURE dataflow OF prioritycoder83_v2 IS
BEGIN
PROCESS(EI,I)
BEGIN
IF(EI='1')THEN
A <= "111";
GS <= '1';
EO <= '1';
ELSIF (I="11111111" AND EI='0')THEN
A <= "111";
GS <= '1';
EO <= '0';
ELSIF (I(7)='0' AND EI='0')THEN
A <= "000";
GS <= '0';
EO <= '1';
ELSIF (I(6)='0' AND EI='0')THEN
A <= "001";
GS <= '0';
EO <= '1';
ELSIF (I(5)='0' AND EI='0')THEN
A <= "010";
GS <= '0';
EO <= '1';
ELSIF (I(4)='0' AND EI='0')THEN
A <= "011";
GS <= '0';
EO <= '1';
ELSIF (I(3)='0' AND EI='0')THEN
A <= "100";
GS <= '0';
EO <= '1';
ELSIF (I(2)='0' AND EI='0')THEN
A <= "101";
GS <= '0';
EO <= '1';
ELSIF (I(1)='0' AND EI='0')THEN
A <= "110";
GS <= '0';
EO <= '1';
ELSE (I(0)='0' AND EI='0')THEN
A <= "111";
GS <= '0';
EO <= '1';
END IF;
END PROCESS;
END dataflow;
5.4 译码器
输 入 输 出
G1 G2A G2B A2 A1 A0 Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
× 1 × × × × 1 1 1 1 1 1 1 1
× × 1 × × × 1 1 1 1 1 1 1 1
0 × × × × × 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1
1 0 0 0 0 1 1 0 1 1 1 1 1 1
1 0 0 0 1 0 1 1 0 1 1 1 1 1
1 0 0 0 1 1 1 1 1 0 1 1 1 1
1 0 0 1 0 0 1 1 1 1 0 1 1 1
1 0 0 1 0 1 1 1 1 1 1 0 1 1
1 0 0 1 1 0 1 1 1 1 1 1 0 1
1 0 0 1 1 1 1 1 1 1 1 1 1 0
3线—8线译码器74138真值表
按数据流描述方式编写的3线—8线译码器74138VHDL源代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY decoder138_v2 IS
PORT(G1,G2A,G2B: IN STD_LOGIC;
A: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
Y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END decoder138_v2;
ARCHITECTURE dataflow OF decoder138_v2 IS
BEGIN
PROCESS (G1,G2A,G2B,A)
BEGIN
IF(G1='1' AND G2A='0' AND G2B='0')THEN
CASE A IS
WHEN "000" => Y <="11111110";
WHEN "001" => Y <="11111101";
WHEN "010" => Y <="11111011";
WHEN "011" => Y <="11110111";
WHEN "100" => Y <="11101111";
WHEN "101" => Y <="11011111";
WHEN "110" => Y <="10111111";
WHEN OTHERS => Y <="01111111";
END CASE;
ELSE Y <="11111111";
END IF;
END PROCESS;
ENDdataflow;
5.5 多路选择器
输入 输出
使能 地 址 选 择 Y Y b
G A2 A1 A0
1 × × × 0 1
0 0 0 0 D0 D0
0 0 0 1 D1 D1
0 0 1 0 D2 D2
0 0 1 1 D3 D3
0 1 0 0 D4 D4
0 1 0 1 D5 D5
0 1 1 0 D6 D6
0 1 1 1 D7 D7
74151 8选1数据选择器真值表
参考74151的真值表,采用IF语句结构编写的VHDL源代码如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux8_v2 IS
PORT(A: IN STD_LOGIC_VECTOR (2 DOWNTO 0);
D0,D1,D2,D3,D4,D5,D6,D7:IN STD_LOGIC;
G:IN STD_LOGIC;
Y: OUT STD_LOGIC;
YB:OUT STD_LOGIC);
END mux8_v2;
ARCHITECTURE dataflow OF mux8_v2 IS
BEGIN
PROCESS (A,D0,D1,D2,D3,D4,D5,D6,D7,G)
BEGIN
IF (G ='1') THEN
Y <='0';
YB <='1';
ELSIF(G='0'AND A="000")THEN
Y <= D0;
YB <= NOT D0;
ELSIF(G='0'AND A="001")THEN
Y <= D1;
YB <= NOT D1;
ELSIF(G='0'AND A="010")THEN
Y <= D2;
YB <= NOT D2;
ELSIF(G='0'AND A="011")THEN
Y <= D3;
YB <= NOT D3;
ELSIF(G='0'AND A="100")THEN
Y <= D4;
YB <= NOT D4;
ELSIF(G='0'AND A="101")THEN
Y <= D5;
YB <= NOT D5;
ELSIF(G='0'AND A="110")THEN
Y <= D6;
YB <= NOT D6;
ELSE
Y <= D7;
YB <= NOT D7;
END IF;
END PROCESS;
END dataflow;
参考74151的真值表,采用CASE语句结构编写的VHDL源代码如下
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux8_v3 IS
PORT(A2,A1,A0: IN STD_LOGIC;
D0,D1,D2,D3,D4,D5,D6,D7:IN STD_LOGIC;
G:IN STD_LOGIC;
Y: OUT STD_LOGIC;
YB:OUT STD_LOGIC);
END mux8_v3;
ARCHITECTURE dataflow OF mux8_v3 IS
SIGNAL comb: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
comb <= G & A2 & A1 & A0;
PROCESS (comb,D0,D1,D2,D3,D4,D5,D6,D7,G)
BEGIN
CASE comb IS
WHEN "0000" =>
Y <= D0;
YB <= NOT D0;
WHEN "0001" =>
Y <= D1;
YB <= NOT D1;
WHEN "0010" =>
Y <= D2;
YB <= NOT D2;
WHEN "0011" =>
Y <= D3;
YB <= NOT D3;
WHEN "0100" =>
Y <= D4;
YB <= NOT D4;
WHEN "0101" =>
Y <= D5;
YB <= NOT D5;
WHEN "0110" =>
Y <= D6;
YB <= NOT D6;
WHEN "0111" =>
Y <= D7;
YB <= NOT D7;
WHEN OTHERS =>
Y <='0';
YB <='1';
END CASE;
END PROCESS;
END dataflow;
5.6 数值比较器
数值比较器是对两个位数相同的二进制数进行比较并判定其大小关系的算术运算电路。
下例是一个采用IF语句编制的对两个4位二进制数进行比较例子,其中A和B分别是参与比较的两个4位二进制数,YA、YB和YC是用来分别表示A>B、A<B和A=B的3个输出端。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY comp4_v1 IS
PORT(A:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
YA,YB,YC: OUT STD_LOGIC);
END comp4_v1;
ARCHITECTURE behave OF comp4_v1 IS
BEGIN
PROCESS (A,B)
BEGIN
IF (A > B) THEN
YA <='1';
YB <='0';
YC <='0';
ELSIF(A < B) THEN
YA <='0';
YB <='1';
YC <='0';
ELSE
YA <='0';
YB <='0';
YC <='1';
END IF;
END PROCESS;
END behave;
5.7 加法器
加法器是数字电路中的基本运算单元,下例是直接利用VHDL运算符“+”实现加法运算的8位加法器源代码。其中A和B是两个相加的8位二进制数,Cin是低位进位位,S是A、B相加之和,Co是A、B相加之后的进位位。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY adder8_v IS
PORT(A :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
B :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Cin:IN STD_LOGIC;
Co : OUT STD_LOGIC;
S :OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END adder8_v;
ARCHITECTURE behave OF adder8_v IS
SIGNAL Sint : STD_LOGIC_VECTOR(8 DOWNTO 0);--9位,包括进位
SIGNAL AA,BB: STD_LOGIC_VECTOR(8 DOWNTO 0);
BEGIN为进位提供空间
AA <='0'& A(7 DOWNTO 0); --将8位加数矢量扩展为9位,
BB <='0'& B(7 DOWNTO 0); --将8位被加数矢量扩展为9位,为进位提供空间
Sint <= AA + BB + Cin;
S(7 DOWNTO 0) <= Sint(7 DOWNTO 0);
Co <= Sint(8);
END behave;