第七章 基本逻辑电路设计
主要内容 组合逻辑电路和时序逻辑的概念; 组合逻辑电路设计实例; 时序逻辑电路设计实例。
基本概念 数字逻辑电路主要分为组合逻辑电路与时序逻辑电路两类 ; 两者都拥有一个或者多个输入信号和输出信号,但是组合逻辑电路的输出只与当前的输入相关,而时序逻辑电路的输出不仅与现在的输入信号相关,而且与过去的输入信号相关; 两种逻辑电路都是数字电路系统的重要基本组成部分,是数字系统电路的基本元素 。
7.1 组合逻辑电路设计 7.7.1、译码器 3-8译码器的核心代码如下: 译码器通常用来产生存储器或者外设的片选信号,也就是说将二进制地址码作为输入,并产生多个选择信号输出 。典型的译码器有3-8译码器和4-16译码器 。 3-8译码器的核心代码如下: ENTITY decoder IS PORT(A,B,C,Enable : IN STD_LOGIC; Y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END decoder; ARCHITECTURE fun OF decoder IS SIGNAL input: STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN input<=C&B&A; PROCESS(input,Enable) IF (Enable='1') THEN --使能输入高电平有效
7.7.1 译码器(续1) 3-8译码器的核心代码: CASE input 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 "111"=>Y<="01111111"; WHEN OTHERS => NULL; END CASE; ELSE y<="11111111"; END IF; END PROCESS; END fun;
7.7.1 译码器(续2) 3-8译码器的时序仿真波形如下:
7.1.2 编码器 编码器的逻辑功能是将输入信号的高、低电平信号编成一个对应的二进制码。 7.1.2 编码器 编码器的逻辑功能是将输入信号的高、低电平信号编成一个对应的二进制码。 在目前经常使用的编码器有普通编码器和优先编码器两种。 在普通编码器中,任何时候只允许一个编码信号出现,否则将出现混乱。 但在优先编码器中,允许同时输入两个以上编码信号。在设计优先编码器电路时,需要先将所有的输入信号按优先顺序排好对,当几个输入信号同时出现时,只对优先权最高的一个信号进行编码。
7.1.2 编码器(续1) 8-3线优先编码器的核心代码如下: ENTITY encoder IS PORT( 7.1.2 编码器(续1) 8-3线优先编码器的核心代码如下: ENTITY encoder IS PORT( I : IN STD_LOGIC_VECTOR(7 DOWNTO 0); Y: OUT STD_LOGIC_VECTOR(2 DOWNTO 0); Enable : IN STD_LOGIC); END encoder; ARCHITECTURE fun OF encoder IS BEGIN PROCESS(I,Enable) IF Enable= '1' THEN IF I(7) = '1' THEN Y <= "111"; ELSIF I(6) = '1' THEN Y <= "110"; ELSIF I(5) = '1' THEN Y <= "101"; ELSIF I(4) = '1' THEN Y <= "100"; ELSIF I(3) = '1' THEN Y <= "011"; ELSIF I(2) = '1' THEN Y <= "010"; ELSIF I(1) = '1' THEN Y <= "001"; ELSIF I(0) = '1' THEN Y <= "000"; ELSE Y<="111"; END IF; END PROCESS; END fun ;
7.1.2 编码器(续2) 8-3线优先编码器时序仿真波形图如下:
7.1.3 数据选择器 在数字信号的传输中,有时候需要从一组数据中选出某一个数据来,这就需要用数 7.1.3 数据选择器 在数字信号的传输中,有时候需要从一组数据中选出某一个数据来,这就需要用数 据选择器。常用的数据选择器有4选1、8选1、16选1等类型。 8选1数据选择器 的核心代码如下: ENTITY mux4_1 IS PORT(A, B,C, D, E, F, G, H: IN STD_LOGIC_VECTOR(3 DOWNTO 0); s: IN STD_LOGIC_VECTOR(2 DOWNTO 0); Y : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END mux8_1; ARCHITECTURE fun OF mux8_1 IS BEGIN Y <= A WHEN s = "000" ELSE B WHEN s = "001" ELSE C WHEN s = "010" ELSE D WHEN s = "011" ELSE E WHEN s = "100" ELSE F WHEN s = "101" ELSE G WHEN s = "110" ELSE H; END fun;
7.1.3 数据选择器(续) 8选1数据选择器的时序仿真波形图如下:
7.1.4 数值比较器 在一些数字系统中,经常需要比较两个数字的大小,为完成这一功能 所设计的各种逻辑电路统称为数值比较器。数值比较器根据比较数据的 位数不同,可以分为一位数值比较器和多位数值比较器。 通用多位数值比较器的核心代码如下 : IF A>B THEN Y1<='1'; ELSE Y1<='0'; END IF; IF A<B THEN Y2<='1'; ELSE Y2<='0'; IF A=B THEN Y3<='1'; ELSE Y3<='0'; END PROCESS; END fun; ENTITY comp IS GENERIC(X : INTEGER :=4); PORT( A, B : IN STD_LOGIC_VECTOR(X-1 DOWNTO 0); Y1,Y2,Y3 : OUT STD_LOGIC ); END comp; ARCHITECTURE fun OF comp IS BEGIN PROCESS(A,B)
7.1.4 数值比较器(续) 4位数值比较器的时序仿真波形图
7.1.5 奇偶校验器 奇偶校验器经常用在数字电路的检测中,用来检测一个二进制数据中的0或1的个数为奇数还是偶数,然后输出检测结果。 8位奇偶校验器的核心代码如下: ENTITY check_N IS PORT( A: IN STD_LOGIC_VECTOR(7 DOWNTO 0); Y: OUT STD_LOGIC ); END check_N; ARCHITECTURE fun OF check_N IS BEGIN PROCESS(A) VARIABLE temp: STD_LOGIC ; BEGIN temp:='1'; FOR n IN 0 TO 7 LOOP temp:=temp xor A(n); END LOOP; Y<=temp; END PROCESS; END fun; 8位奇偶校验器的时序仿真波形图如下:
7.2 时序逻辑电路设计 7.2.1 触发器 触发器是能够存储二值信号的基本单元电路。触发器的种类有很多,根据不同的功能可以分为D触发器、T触发器、JK触发器已经RS触发器等。 JK触发器的核心代码如下 ENTITY jk_trigger IS PORT( J,K,CLK: IN STD_LOGIC; Q: OUT STD_LOGIC ); END jk_trigger; ARCHITECTURE fun OF jk_trigger IS SIGNAL temp:STD_LOGIC ; BEGIN PROCESS(J,K,CLK) IF (CLK'EVENT AND CLK='1') THEN temp<=(J AND NOT(temp)) OR ((NOT K) AND temp); END IF; END PROCESS; Q<=temp; END fun;
7.2.1 触发器(续) 同步JK触发器的时序仿真波形图如下:
7.2.2 寄存器 寄存器用来存储二进制数值,其种类有很多中,常用的锁存器和移位寄存器等。本文中以一个通用寄存器来介绍寄存器的设计,包括清零、所存、左移和右移功能。 通用寄存器的核心代码如下: ENTITY reg IS GENERIC(n : Positive := 8); --寄存器宽度 PORT(CLK, shift_l, shift_r : IN STD_LOGIC; --时钟信号和左移、右移输入数值 mode : IN STD_LOGIC_VECTOR(1 DOWNT 0); --寄存器模式 datain : IN STD_LOGIC_VECTOR ((n-1) DOWNTO 0); --并行输入 dataout : OUT STD_LOGIC_VECTOR ((n-1) DOWNTO 0)); --并行输出 END reg; ARCHITECTURE fun OF reg IS SIGNAL temp_reg : STD_LOGIC_VECTOR ((n-1) DOWNTO 0); --定义临时变量 BEGIN
7.2.2 寄存器(续) 通用寄存器的时序仿真波形图如下: PROCESS BEGIN 7.2.2 寄存器(续) PROCESS BEGIN IF (CLK'EVENT AND CLK='1') THEN CASE mode IS WHEN "00" => int_reg <= (OTHERS => '0'); --寄存器清零 WHEN "01" => int_reg <= datain; --锁存器 WHEN "10" => int_reg <= int_reg((n-2) DOWNTO 0) & shift_l; --左移 WHEN "11" => int_reg <= shift_r & int_reg((n-1) DOWNTO 1); --右移 WHEN OTHERS => NULL; END CASE; END PROCESS; dataout <= int_reg; END fun; 通用寄存器的时序仿真波形图如下:
7.2.3 分频器 分频电路是非常有用的一种电路,在具体的电路设计中可能需要不同的时钟频率,但在实际的电路中往往只有一种单一的外部时钟输入,这是可以采用分频器对时钟脉冲进行分频。 1、二分频电路核心代码如下: ENTITY fenp_2 IS PORT(CLK_IN: IN STD_LOGIC; CLK_OUT: OUT STD_LOGIC); END fenp_2; ARCHITECTURE fun OF fenp_2 IS SIGNAL temp: STD_LOGIC:='0'; BEGIN PROCESS(CLK_IN,temp) IF (CLK_IN'EVENT AND CLK_IN='1') THEN temp<= not temp; END IF; CLK_OUT<= temp; END PROCESS; END fun;
7.2.3 分频器(续1) 2、五分频电路的核心代码如下: ENTITY fenp_5 IS 7.2.3 分频器(续1) 2、五分频电路的核心代码如下: ENTITY fenp_5 IS PORT(CLK_IN : IN STD_LOGIC; CLK_OUT: OUT STD_LOGIC); END fenp_5; ARCHITECTURE fun OF fenp_5 IS SIGNAL temp_A,temp_B: INTEGER RANGE 0 TO 7; BEGIN PROCESS(CLK_IN,temp_A,temp_B) IF (CLK_IN'EVENT AND CLK_IN='1') THEN IF temp_A=4 THEN temp_A<=0; ELSE temp_A <= temp_A+1;--对上升沿计数 END IF;
7.2.3 分频器(续2) 二分频电路的时序仿真波形图如下 五分频电路的时序仿真波形图如下:
7.2.4 计数器 计数器是数字电路中使用的最多的时序电路,它不仅能用于对时钟脉冲的计数,还可以用于分频、定时、产生节拍脉冲和脉冲序列以及进行数字运算等。 BCD码 60进制计数器的核心代码如下: ENTITY counter IS PORT(CLK,Enable,clr: IN STD_LOGIC; --时钟信号、计数使能、清零信号 Cout: OUT STD_LOGIC; --进位信号 q0,q1: BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0)); --计数输出 END counter ;
7.2.4 计数器(续1) BCD码 60进制计数器的核心代码: ARCHITECTURE fun OF COUNTER IS 7.2.4 计数器(续1) BCD码 60进制计数器的核心代码: ARCHITECTURE fun OF COUNTER IS SIGNAL temp: STD_LOGIC; --临时变量,表示个位数p0的进位 BEGIN PROCESS (CLK,Enable,clr,q0) --此进程描述个位计数器 IF clr='1' THEN q0<="0000"; --个位清零 ELSE IF (CLK'EVENT AND CLK='1') THEN --对时钟脉冲进行计数 IF Enable='1' THEN --使能信号搞电平有效 IF q0="1001" THEN q0<="0000"; temp <='1'; --计数到9置0,输出进位 ELSE q0<=q0+1; temp <='0'; END IF; END PROCESS;
7.2.4 计数器(续2) BCD码 60进制计数器的核心代码: 7.2.4 计数器(续2) BCD码 60进制计数器的核心代码: PROCESS (q0,clr,q1, temp) --此进程描述十位计数器 BEGIN IF clr='1' THEN q1<="0000"; --十位清零 ELSE IF (temp 'EVENT AND temp ='1') THEN --对个位的进位temp进行计数 IF enable='1' THEN IF q1="0101" THEN q1<="0000"; ELSE q1<=q1+1; END IF; IF Q0="1001" AND q1="0101" THEN Cout<='1'; --计数到59后,输出进位 ELSE Cout<='0'; END PROCESS; END fun;
7.2.4 计数器(续3) BCD码的60进制计数器时序仿真波形图
本章小结 本章介绍了数字电路中的基本逻辑电路。 基本逻辑电路是所有数字系统的基本部件,是进行数字逻辑设计的基础,它主要分为组合逻辑电路和数字逻辑电路,这两种电路的逻辑功能和描述方法都有显著的区别。 对于这两种电路的一些典型、常用的电路,本章给出了可综合的VHDL源程序与时序仿真结果。