1.24k likes | 1.43k Views
数字逻辑单元设计. 何宾 2011.09. 数字逻辑单元设计 - 本章概要. 在复杂数字系统中,其结构总可以用若干基本逻辑单元 的组合进行描述。 基本逻辑单元一般分为组合逻辑电路和时序电路两大类。 在此基础上,可以更进一步进行组合 . 本章所介绍的存储器、运算单元和有限自动状态机就是 由基本逻辑单元组合而成的。 本章首先介绍基本的组合逻辑电路和时序电路设计, 然后介绍在数字系统设计中普遍使用的存储器电路、运算 单元和有限自动状态机。. 数字逻辑单元设计 - 基本逻辑门电路设计. 对基本逻辑门的操作主要有:与、与非、或、或非、
E N D
数字逻辑单元设计 • 何宾 • 2011.09
数字逻辑单元设计-本章概要 • 在复杂数字系统中,其结构总可以用若干基本逻辑单元 • 的组合进行描述。 • 基本逻辑单元一般分为组合逻辑电路和时序电路两大类。 • 在此基础上,可以更进一步进行组合. • 本章所介绍的存储器、运算单元和有限自动状态机就是 • 由基本逻辑单元组合而成的。 • 本章首先介绍基本的组合逻辑电路和时序电路设计, • 然后介绍在数字系统设计中普遍使用的存储器电路、运算 • 单元和有限自动状态机。
数字逻辑单元设计-基本逻辑门电路设计 • 对基本逻辑门的操作主要有:与、与非、或、或非、 • 异或、异或非和非操作。通过使用VHDL语言中描述基本 • 逻辑门电路操作的关键字:and(与),nand(与非), • or(或),nor(或非),xor(异或),xnor(异或 • 非),not(非)来实现对基本逻辑门的操作。一堆复杂 • 的逻辑门操作总可以化简为集中基本逻辑门操作的组合。
数字逻辑单元设计-基本逻辑门电路设计 • 基本门电路的设计 • Library ieee; • Use ieee.std_logic_1164.all; • Entity gate is • Port(a, b,c : in std_logic; • d : out std_logic); • end gate; • architecture rtl of gate is • begin • d<=((not a) and b) or c; • end rtl;
数字逻辑单元设计-编码器和译码器设计 • 在数字系统中,常常会将某一信息用特定的代码进行 • 描述,这称为编码过程。编码过程可以通过编码器电路实 • 现。 • 同时,将某一特定的代码翻译成原始的信息,这称为 • 译码过程。译码过程可以通过译码器电路实现。
数字逻辑单元设计-编码器设计 • 将某一信息用一组按一定规律排列的二进制代码描 • 述称为编码。典型的有8421码、BCD码等。在使用 • VHDL语言设计编码器时,通过使用CASE和IF语句实现 • 对编码器的描述。
数字逻辑单元设计-编码器设计 • 8/3线编码器的VHDL描述 • library ieee; • use ieee.std_logic_1164.all; • entity priority_encoder_1 is • port ( sel : in std_logic_vector (7 downto 0); • code :out std_logic_vector (2 downto 0)); • end priority_encoder_1; • architecture archi of priority_encoder_1 is • begin • code <= "000" when sel(0) = '1' else • "001" when sel(1) = '1' else • "010" when sel(2) = '1' else • "011" when sel(3) = '1' else • "100" when sel(4) = '1' else • "101" when sel(5) = '1' else • "110" when sel(6) = '1' else • "111" when sel(7) = '1' else • "ZZZ"; • end archi;
数字逻辑单元设计-译码器设计 • 译码的过程实际上就是编码过程的逆过程,即将一 • 组按一定规律排列的二进制数还原为原始的信息。 • 下面以最常用的3:8译码器为例,给出其VHDL语 • 言描述。
数字逻辑单元设计-译码器设计 • 十六进制数的共阳极7段数码显示VHDL描述 • library ieee; • use ieee.std_logic_1164.all; • use ieee.std_logic_unsigned.all; • entity decoder is • port(hex: in std_logic_vector(3 downto 0); • led : out std_logic_vector(6downto 0)); • end decoder; • architecture rtl of decoder is • begin • with hex select • LED<= "1111001" when "0001", --1 • "0100100" when "0010", --2 • "0110000" when "0011", --3 • "0011001" when "0100", --4 • "0010010" when "0101", --5 • "0000010" when "0110", --6 • "1111000" when "0111", --7 • "0000000" when "1000", --8 • "0010000" when "1001", --9 • "0001000" when "1010", --A • "0000011" when "1011", --b • "1000110" when "1100", --C • "0100001" when "1101", --d • "0000110" when "1110", --E • "0001110" when "1111", --F • "1000000" when others; --0 • end rtl;
数字逻辑单元设计-数据选择器设计设计 • 在数字系统设计中,常使用CASE和IF语句描述数 • 据选择器。下面给出这两种描述方法。
数字逻辑单元设计-数据选择器设计设计 • 4选1多路选择器的IF语句描述 • library ieee; • use ieee.std_logic_1164.all; • entity multiplexers_1 is • port (a, b, c, d : in std_logic; • s : in std_logic_vector (1 downto 0); • o : out std_logic); • end multiplexers_1; • architecture archi of multiplexers_1 is • begin • process (a, b, c, d, s) • begin • if (s = "00") then o <= a; • elsif (s = "01") then o <= b; • elsif (s = "10") then o <= c; • else o <= d; • end if; • end process; • end archi;
数字逻辑单元设计-数据选择器设计设计 • 4选1多路选择器的CASE语句描述 • library ieee; • use ieee.std_logic_1164.all; • entity multiplexers_2 is • port (a, b, c, d : in std_logic; s : in std_logic_vector (1 downto 0); • o : out std_logic); • end multiplexers_2; • architecture archi of multiplexers_2 is • begin • process (a, b, c, d, s) • begin • case s is • when "00" => o <= a; • when "01" => o <= b; • when "10" => o <= c; • when others => o <= d; • end case; • end process; • end archi;
数字逻辑单元设计-数字比较器 • 比较器就是对输入数据进行比较,并判断其大小的逻 • 辑电路。在数字系统中,比较器是基本的组合逻辑单元之 • 一,比较器主要是使用关系运算符实现的。
数字逻辑单元设计-数字比较器 • 8位数据比较器的VHDL描述 • library ieee; • use ieee.std_logic_1164.all; • use ieee.std_logic_unsigned.all; • entity comparator_1 is • port(A,B : in std_logic_vector(7 downto 0); • CMP : out std_logic); • end comparator_1; • architecture archi of comparator_1 is • begin • CMP <= '1' when A >= B else '0'; • end archi; • 从上面的例子可以看出,使用VHDL中的>、>=、<、<=、=、 • /=,这几种关系运算符及其它们的组合,可以设计出具有复杂比 • 较功能的比较器。
数字逻辑单元设计-总线缓冲器 • 总线是一组相关信号的集合。在计算机系统常用的 • 总线有数据总线、地址总线和控制总线。由于总线上 • 经常需要连接很多的设备,因此必须正确的控制总线 • 的输入和输出,这样才不会产生总线访问的冲突,下 • 面将介绍总线三态控制和双向控制的VHDL描述方法。
数字逻辑单元设计-总线缓冲器 • 三态门的进程描述 • Library ieee; • Use ieee.std_logic_1164.all; • Entity tri_gate is • Port (en : in std_logic; • din : in std_logic_vector(7 downto 0); • dout : out std_logic_vector(7 downto 0)); • end tri_gate; • Architecture rtl of tri_gate is • begin • process(din,en) • begin • if(en=’1’) then • dout<=din; • else • dout<=’ZZZZZZZZ’; • end if; • end process; • end rtl;
数字逻辑单元设计-总线缓冲器 • 三态门的WHEN-ELSE进程描述 • Library ieee; • Use ieee.std_logic_1164.all; • Entity tri_gate is • Port (en : in std_logic; • din : in std_logic_vector(7 downto 0); • dout : out std_logic_vector(7 downto 0)); • end tri_gate; • Architecture rtl of tri_gate is • begin • dout<= din when en ='1' else 'ZZZZZZZZ'; • end rtl; • 从上面的两个例子中可以看出,使用条件并行语句描述三态 • 门比使用进程要简单的多。
数字逻辑单元设计-总线缓冲器 • 双向总线缓冲器的描述 • Library ieee; • Use ieee.std_logic_1164.all; • Entity bidir is • Port(a : inout std_logic_vector(15 downto 0)); • End bidir; • Architecture rtl of bidir is • signal a_in : std_logic_vector(15 downto 0); • signal a_out : std_logic_vector(15 downto 0); • signal T : std_logic; • Begin • a<= a_out when T = '0' else "ZZZZZZZZZZZZZZZZ"; • a_in<=a; • end rtl;
数字逻辑单元设计-运算单元 • 数据运算单元主要包含加法器、减法器、乘法器和除 • 法器,由这四种运算单元和逻辑运算单元一起,可以完成 • 复杂数学运算。在VHDL语言中,支持的几种运算有:加 • (+)、减(-)、乘(*)、除(/)、取余(MOD)、幂 • 乘(**)。
数字逻辑单元设计-加法器设计 • 在VHDL描述加法器时,使用’+’运算符比门级描 • 述更简单。下面给出带进位输入和输出的无符号的8 • 比特加法器的VHDL描述。
数字逻辑单元设计-加法器设计 • 带进位输入和输出的无符号的8比特加法器的VHDL描述 • library ieee; • use ieee.std_logic_1164.all; • use ieee.std_logic_arith.all; • use ieee.std_logic_unsigned.all; • entity adders_4 is • port(A,B,CI : in std_logic_vector(7 downto 0); • SUM : out std_logic_vector(7 downto 0); • CO : out std_logic); • end adders_4; • architecture archi of adders_4 is • signal tmp: std_logic_vector(8 downto 0); • begin • SUM <= tmp(7 downto 0); • CO <= tmp(8); • tmp <= conv_std_logic_vector((conv_integer(A) + conv_integer(B) • +conv_integer(CI)),9); • end archi;
数字逻辑单元设计-减法器设计 • 减法是加法的反运算,采用VHDL语言的‘-’符号描述 • 减法器,比用门级描述更简单。下面给出一个无符号8位 • 带借位的减法器的VHDL描述。
数字逻辑单元设计-减法器设计 • 【例4-10】无符号8位带借位的减法器的VHDL描述 • library IEEE; • use IEEE.STD_LOGIC_1164.ALL; • use IEEE.STD_LOGIC_UNSIGNED.ALL; • entity adders_8 is • port(A,B : in std_logic_vector(7 downto 0); • BI : in std_logic; • RES : out std_logic_vector(7 downto 0)); • end adders_8; • architecture archi of adders_8 is • begin • RES <= A - B - BI; • end archi;
数字逻辑单元设计-ALU设计 • 前面几节介绍了加法器和减法器电路的设计。通过增加一些逻辑操作,设计一个叫做算术/逻辑单元ALU的模块。 • 由于ALU包含了所希望实现的功能集的电路,因此很容易替换/扩展来包含不同的操作。 • 下面将给出ALU的原理符号。
数字逻辑单元设计-ALU设计 • 类似于前面的复用开关有选择线一样,ALU也有选择线来控制所要使用的操作。
数字逻辑单元设计-ALU设计 • 设计原理: • 1)由于ALU完成8种功能,所以选择线为3位; • 2)此外,ALU也提供4位的y输出和四个标志 • 位。 • cf为进位标志; • ovf为溢出标志; • zf为0标志(当输出为0时,该标志有效), • nf为负标志(当输出的第4位为1时,该标志有 效)。
数字逻辑单元设计-ALU设计 • 为了讨论进位标志和溢出标志的不同,考虑一个8位 • 的加法(最高位为符号位)。 • 1)当无符号的数的和超过255时,进位标志被设置。 • 2)当有符号数的和超过了-128-+127的范围时,溢出 • 标志被设置。
数字逻辑单元设计-ALU设计 • 考虑下面的几个例子(最高位为符号位): • 1)5310+2510=3516+1916=7810=4E16, cf=0, ovf=0 • 2)5310+9110=3516+5B16=14410=9016, cf=0, ovf=1 • 3)5310-4510=3516+D316=810=10816, cf=1, ovf=0 • 4)-9810-4510=9E16+D316=-14310=17116, cf=1,ovf=1 • 当满足条件:(第六位向第七位进位) xor • (第七位向cf进位)时,ovf=1
数字逻辑单元设计-ALU设计 • library IEEE; ---库声明及调用 • use IEEE.STD_LOGIC_1164.ALL; • use IEEE.STD_LOGIC_ARITH.ALL; • use IEEE.STD_LOGIC_UNSIGNED.ALL; • entity alu4 is • port( • a : in std_logic_vector(3 downto 0); • b : in std_logic_vector(3 downto 0); • alusel : in std_logic_vector(2 downto 0); • y : out std_logic_vector(3 downto 0); • nf : out std_logic; • zf : out std_logic; • cf : out std_logic; • ovf : out std_logic • ); • end alu4;
数字逻辑单元设计-ALU设计 • architecture Behavioral of alu4 is --功能描述 • begin • process(a,b,alusel) • variable temp : std_logic_vector(4 downto 0):="00000"; • variable y_temp : std_logic_vector(3 downto 0):="0000"; • begin • cf<='0'; • ovf<='0'; • case alusel is • when "000"=> • y_temp:=a; • when "001"=> • temp:=('0'&a)+('0'&b); • y_temp:=temp(3 downto 0); • cf<=temp(4); • ovf<=temp(3) xor a(3) xor b(3) xor temp(4);
数字逻辑单元设计-ALU设计 • when "010"=> • temp:=('0'&a)-('0'&b); • y_temp:=temp(3 downto 0); • cf<=temp(4); • ovf<=temp(3) xor a(3) xor b(3) xor temp(4); • when "011"=> • temp:=('0'&b)-('0'&a); • y_temp:=temp(3 downto 0); • cf<=temp(4); • ovf<=temp(3) xor a(3) xor b(3) xor temp(4);
数字逻辑单元设计-ALU设计 • when "100"=> • y_temp:=not a; • when "101"=> • y_temp:=a and b; • when "110"=> • y_temp:=a or b; • when "111"=> • y_temp:=a xor b; • when others=> • y_temp:=a; • end case;
数字逻辑单元设计-ALU设计 • nf<=y_temp(3); • y<=y_temp; • if(temp="0000") then • zf<='1'; • else • zf<='0'; • end if; • end process; • end Behavioral;
数字逻辑单元设计-乘法器设计 • 用VHDL语言实现乘法器时,乘积和符号应该 • 为2的幂次方。PLD的优点就是在内部集成了乘法器 • 的硬核,具体在IP核的设计中详细讨论。
数字逻辑单元设计-乘法器设计 • 下面给出一个8位和4位无符号的乘法器的VHDL描述 • library ieee; • use ieee.std_logic_1164.all; • use ieee.std_logic_unsigned.all; • entity multipliers_1 is • port(A : in std_logic_vector(7 downto 0); • B : in std_logic_vector(3 downto 0); • RES : out std_logic_vector(11 downto 0)); • end multipliers_1; • architecture beh of multipliers_1 is • begin • RES <= A * B; • end beh;
数字逻辑单元设计-除法器设计 • 除法器可以用VHDL语言的‘/’符号实现,需要注意的是 • 在使用‘/’符号进行除法运算时,除数必须是常数,而且是 • 2的整数幂。因为除法器的运行有这样的限制,实际上除 • 法也可以用移位运算实现。下面给出一个除法器的VHDL • 描述。
数字逻辑单元设计-除法器设计 • 除法器的VHDL描述。 • library ieee; • use ieee.std_logic_1164.all; • use entity divider_1 is • port(DI : in unsigned(7 downto 0); • DO : out unsigned(7 downto 0)); • end divider_1; • architecture archi of divider_1 is • begin • DO <= DI / 2; • end archi;
数字逻辑单元设计-除法器设计(任意除数) • 通过A中的数字向左移位,一次一位地进入移位寄 • 存器。对于一个A为2n宽度,B为n宽度的除法运算,Q • 为2n位。其运算步骤为: • 1)每次移位操作; • 2)比较R和B。如果,则在商的某一位适当位置上 • 放上一个1,然后从R中减去B;否则在商的某一适当 • 位置放上一个0; • 3)重复上述步骤,直到移位操作结束;
数字逻辑单元设计-除法器设计(任意除数) • 除数不为2的整数幂的除法器VHDL描述 • library IEEE; • use IEEE.STD_LOGIC_1164.ALL; • use IEEE.STD_LOGIC_ARITH.ALL; • use IEEE.STD_LOGIC_UNSIGNED.ALL; • entity div8 is • port( • numerator : in std_logic_vector(7 downto 0); • denominator : in std_logic_vector(3 downto 0); • quotient : out std_logic_vector(7 downto 0); • remainder : out std_logic_vector(3 downto 0) • ); • end div8;
数字逻辑单元设计-除法器设计(任意除数) • architecture Behavioral of div8 is • begin • process(numerator,denominator) • variable n1 : std_logic_vector(4 downto 0); • variable n2 : std_logic_vector(7 downto 0); • variable numer : std_logic_vector(7 downto 0); • variable d : std_logic_vector(4 downto 0); • Begin • n1:="00000"; • n2:="00000000"; • numer:=numerator; • d:='0' & denominator; • quotient<=n2(7 downto 0); • remainder<=n1(3 downto 0);
数字逻辑单元设计-除法器设计(任意除数) • for i in 0 to 7 loop • for j in 4 downto 1 loop • n1(j):=n1(j-1); • end loop; • n1(0):=numer(7); • for k in 7 downto 1 loop • numer(k):=numer(k-1); • end loop; • numer(0):='0'; • for l in 7 downto 1 loop • n2(l):=n2(l-1); • end loop; • if(n1(4 downto 0)>=d) then • n1:=n1-d; • n2(0):='1'; • else • n1:=n1; • n2(0):='0'; • end if; • end loop; • end process; • end Behavioral;
数字逻辑单元设计-时序逻辑电路设计 • 时序逻辑电路的输出状态不仅与输入变量的状态有关, • 而且还与系统原先的状态有关。时序电路最重要的特点是 • 存在着记忆单元部分,时序电路主要包括: • 1) 基本触发器 • 2) 计数器 • 3) 移位寄存器 • 4) 脉冲宽度调制等。
数字逻辑单元设计-触发器设计 • 触发器是时序逻辑电路的最基本单元,触发器具有“记 • 忆”能力。 • 根据沿触发、复位和置位方式的不同触发器可以有多种 • 实现方式。在PLD中经常使用的触发器有D触发器、JK触 • 发器和T触发器等。
数字逻辑单元设计-D触发器设计 • 【例4-20】带时钟使能和异 • 步复位/置位的D触发器的 • VHDL描述 • D触发器是数字电路中应 • 用最多的一种时序电路。表 • 4.1给出了带时钟使能和异 • 步复位/置位的D触发器的真 • 值表。
数字逻辑单元设计-D触发器设计 process(clk,clr,pre,c) begin if(clr=’1’) then q_tmp<=’0’; elsif(pre=’1’) then q_tmp<=’1’; elsif rising_edge(clk) then if(ce=’1’) then q_tmp<=d; else q_tmp<=q_tmp; end if; end if; end process; end rtl; • Library ieee; • Useieee.std_logic_1164.all; • Entity fdd is • Port(clk,d,clr,pre,ce : in std_logic; • q : out std_logic); • end fdd; • architecture rtl of dff is • signal q_tmp : std_logic; • begin • q<=q_tmp;
数字逻辑单元设计-JK触发器设计 • JK触发器要比D触发器复杂一些。
数字逻辑单元设计-JK触发器设计 if(r=’1’) then q_tmp<=’0’; elsif(s=’1’) then q_tmp<=’1’; elsif rising_edge(clk) then if(ce=’0’) then q_tmp<=q_tmp; else if(j=’0’ and k=’1’) then q_tmp<=’0’; elsif(j=’1’ and k=’0’) then q_tmp<=’1’; elsif(j=’1’ and k=’1’) then q_tmp<=not q_tmp; end if; end if; end process; end rtl; • 带时钟使能和异步复位/置位的JK • 触发器的VHDL描述 • Library ieee; • Use ieee.std_logic_1164.all; • Entity fdd is • Port(s,r,j,k,ce,c: in std_logic; • q : out std_logic); • end fdd; • architecture rtl of dff is • signal q_tmp : std_logic; • begin • q<=q_tmp; • process(s,r,c) • begin