《EDA技术实用教程(第五版)》习题答案(第1-10章)--潘
《EDA技术实用教程(第五版)》习题
1 习题
1-1EDA技术与ASIC设计和FPGA开发有什么关系?FPGA在ASIC设计中有什么用途?P3~4 EDA技术与ASIC设计和FPGA开发有什么关系?答:利用EDA技术进行电子系统设计的最后目标是完成专用集成电路ASIC的设计和实现;FPGA和CPLD是实现这一途径的主流器件。FPGA和CPLD的应用是EDA 技术有机融合软硬件电子设计技术、SoC(片上系统)和ASIC设计,以及对自动设计与自动实现最典型的诠释。
FPGA在ASIC设计中有什么用途?答:FPGA和CPLD通常也被称为可编程专用IC,或可编程ASIC。FPGA实现ASIC设计的现场可编程器件。
1-2 与软件描述语言相比,VHDL有什么特点? P4~6
答:编译器将软件程序翻译成基于某种特定CPU的机器代码,这种代码仅限于这种CPU而不能移植,并且机器代码不代表硬件结构,更不能改变CPU的硬件结构,只能被动地为其特定的硬件电路结构所利用。
综合器将VHDL程序转化的目标是底层的电路结构网表文件,这种满足VHDL设计程序功能描述的电路结构,不依赖于任何特定硬件环境;具有相对独立性。综合器在将VHDL(硬件描述语言)表达的电路功能转化成具体的电路结构网表过程中,具有明显的能动性和创造性,它不是机械的一一对应式的“翻译”,而是根据设计库、工艺库以及预先设置的各类约束条件,选择最优的方式完成电路结构的设计。
l-3什么是综合?有哪些类型?综合在电子设计自动化中的地位是什么?P6
什么是综合? 答:在电子设计领域中综合的概念可以表示为:将用行为和功能层次表达的电子系统转换为低层次的便于具体实现的模块组合装配的过程。
有哪些类型?答:(1)从自然语言转换到VHDL语言算法表示,即自然语言综合。(2)从算法表示转换到寄存器传输级(RegisterTransport Level,RTL),即从行为域到结构域的综合,即行为综合。(3)从RTL级表示转换到逻辑门(包括触发器)的表示,即逻辑综合。(4)从逻辑门表示转换到版图表示(ASIC设计),或转换到FPGA的配置网表文件,可称为版图综合或结构综合。
综合在电子设计自动化中的地位是什么?答:是核心地位(见图1-3)。综合器具有更复杂的工作环境,综合器在接受VHDL程序并准备对其综合前,必须获得与最终实现设计电路硬件特征相关的工艺库信息,以及获得优化综合的诸多约束条件信息;根据工艺库和约束条件信息,将VHDL程序转化成电路实现的相关信息。
1-4 在EDA技术中,自顶向下的设计方法的重要意义是什么? P8~10
答:在EDA技术应用中,自顶向下的设计方法,就是在整个设计流程中各设计环节逐步求精的过程。
1-5 IP在EDA技术的应用和发展中的意义是什么? P23~25
答:IP核具有规范的接口协议,良好的可移植与可测试性,为系统开发提供了可靠的保证。
1-6叙述EDA的FPGA/CPLD设计流程,以及涉及的EDA工具及其在整个流程中的作用。 (P12~14) 答:1.设计输入(原理图/HDL文本编辑)(EDA设计输入器将电路系统以一定的表达方式输入计算机);2.综合(EDA综合器就是将电路的高级语言(如行为描述)转换成低级的,可与FPGA/CPLD的基本结构相映射的网表文件或程序。);3.适配(EDA适配器的功能是将由综合器产生的网表文件配置于指定的目标器件中,使之产生最终的下载文件,如JEDEC、JAM格式的文件。);4.时序仿真(ED A时序仿真器就是接近真实器件运行特性的仿真,仿真文件中已包含了器件硬件特性参数,因而,仿真精度高。)与功能仿真(ED A功能仿真器直接对VHDL、原理图描述或其他描述形式的逻辑功能进行测试模拟,以了解其实现的功能是否满足原设计的要求,仿真过程不涉及任何具体器件的硬件特性。);5.编程下载(EDA编程下载把适配后生成的下载或配置文件,通过编程器或编程电缆向FPGA或CPLD下载,以便进行硬件调试和验证(Hardware Debugging)。);6.硬件测试(最后是将含有载入了设计的FPGA或CPLD的硬件系统进行统一测试,以便最终验证设计项目在目标系统上的实际工作情况,以排除错误,改进设计。其中EDA的嵌入式逻辑分析仪是将含有载入了设计的FPGA的硬件系统进行统一测试,并将测试波形在PC机上显示、观察和分析。)。
2 习题
2-1 OLMC(输出逻辑宏单元)有何功能?说明GAL是怎样实现可编程组合电路与时序电路的。 P34~36 OLMC有何功能? 答:OLMC单元设有多种组态,可配置成专用组合输出、专用输入、组合输出双向口、寄存器输出、寄存器输出双向口等。
说明GAL是怎样实现可编程组合电路与时序电路的? 答:GAL(通用阵列逻辑器件)是通过对其中的OLMC(逻辑宏单元)的编程和三种模式配置(寄存器模式、复合模式、简单模式),实现组合电路与时序电路设计的。
2-2什么是基于乘积项的可编程逻辑结构?P33~34,40什么是基于查找表的可编程逻辑结构?P40~42 什么是基于乘积项的可编程逻辑结构?答:GAL、CPLD之类都是基于乘积项的可编程结构;即包含有可编程与阵列和固定的或阵列的PAL(可编程阵列逻辑)器件构成。
什么是基于查找表的可编程逻辑结构?答:FPGA(现场可编程门阵列)是基于查找表的可编程逻辑结构。
2-3 FPGA系列器件中的LAB有何作用? P42~44
答:FPGA(Cyclone/Cyclone II)系列器件主要由逻辑阵列块LAB、嵌入式存储器块(EAB)、I/O单元、嵌入式硬件乘法器和PLL等模块构成;其中LAB(逻辑阵列块)由一系列相邻的LE(逻辑单元)构成的;FPGA可编程资源主要来自逻辑阵列块LAB。
2-4与传统的测试技术相比,边界扫描技术有何优点? P47~50
答:使用BST(边界扫描测试)规范测试,不必使用物理探针,可在器件正常工作时在系统捕获测量的功能数据。克服传统的外探针测试法和“针床”夹具测试法来无法对IC内部节点无法测试的难题。
2-5 解释编程与配置这两个概念。P51~56
答:编程:基于电可擦除存储单元的EEPROM或Flash技术。CPLD一股使用此技术进行编程。CPLD被编程后改变了电可擦除存储单元中的信息,掉电后可保存。电可擦除编程工艺的优点是编程后信息不会因掉电而丢失,但编程次数有限,编程的速度不快。
配置:基于SRAM查找表的编程单元。编程信息是保存在SRAM中的,SRAM在掉电后编程信息立即丢失,在下次上电后,还需要重新载入编程信息。大部分FPGA采用该种编程工艺。该类器件的编程一般称为配置。对于SRAM型FPGA来说,配置次数无限,且速度快;在加电时可随时更改逻辑;下载信息的保密性也不如电可擦除的编程。
2-6 请参阅相关资料,并回答问题:按本章给出的归类方式,将基于乘积项的可编程逻辑结构的PLD器件归类为CPLD;将基于查找表的可编程逻辑结构的PLD器什归类为FPGA,那么,APEX系列属于什么类型PLD器件? MAX II系列又属于什么类型的PLD器件?为什么? P47~51
答:APEX(Advanced Logic Element Matrix)系列属于FPGA类型PLD器件;编程信息存于SRAM中。MAX II系列属于CPLD类型的PLD器件;编程信息存于EEPROM中。
3 习题
3-1 说明端口模式INOUT和BUFFER有何异同点。P60
INOUT : 具有三态控制的双向传送端口
BUFFER: 具有输出反馈的单向东湖出口。
3-2 画出与以下实体描述对应的原理图符号元件:
ENTITY buf3s IS --实体1:三态缓冲器
PORT(input:IN STD_LOGIC; --输入端
enable:IN STD_LOGIC; --使能端
output:OUT STD_LOGIC); --输出端
END buf3s ;
ENTITY mux21 IS --实体2: 2选1
PORT(in0, in1,sel: IN STD_LOGIC;
output:OUT STD_LOGIC);
3-3 试分别用IF_THEN语句和程序,选择控制信号s1和s0的数据类型为STD_LOGIC_VECTOR;当s1=’0’,s0=’0’;s1=’0’,s0=’1’;s1=’1’,s0=’0’和s1=’1’,s0=’1’时,分别执行y<=a、y<=b、y<=c、y<=d。
--解1:用IF_THEN 语句实现4选1多路选择器 LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; ENTITY mux41 IS
PORT (a,b,c,d: IN STD_LOGIC; s0: IN STD_LOGIC; s1: IN STD_LOGIC; y: OUT STD_LOGIC); END ENTITY mux41;
ARCHITECTURE if_mux41 OF mux41 IS
SIGNAL s0s1 : STD_LOGIC_VECTOR(1 DOWNTO 0);--定义标准逻辑位矢量数据 BEGIN
s0s1<=s1&s0; --s1相并s0,即s1与s0并置操作 PROCESS(s0s1,a,b,c,d) BEGIN
IF s0s1 = "00" THEN y <= a; ELSIF s0s1 = "01" THEN y <= b; ELSIF s0s1 = "10" THEN y <= c; ELSE y <= d; END IF;
END PROCESS;
END ARCHITECTURE if_mux41;
--解2:用CASE 语句实现4选1多路选择器 LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; ENTITY mux41 IS
PORT (a,b,c,d: IN STD_LOGIC; s0: IN STD_LOGIC; s1: IN STD_LOGIC; y: OUT STD_LOGIC); END ENTITY mux41;
ARCHITECTURE case_mux41 OF mux41 IS
SIGNAL s0s1 : STD_LOGIC_VECTOR(1 DOWNTO 0);--定义标准逻辑位矢量数据类型 BEGIN
s0s1<=s1&s0; --s1相并s0,即s1与s0并置操作 PROCESS(s0s1,a,b,c,d) BEGIN
CASE s0s1 IS --类似于真值表的case 语句 WHEN "00" => y <= a; WHEN "01" => y <= b; WHEN "10" => y <= c; WHEN "11" => y <= d; WHEN OTHERS =>NULL ; END CASE; END PROCESS;
END ARCHITECTURE case_mux41;
3-4 给出1位全减器的VHDL 描述;最终实现8位全减器。要求:
1)首先设计1位半减器,然后用例化语句将它们连接起来,图4-20中h_suber 是半减器,diff 是输出差(diff=x-y),s_out 是借位输出(s_out=1,x 图3-18 全减器结构图 --解(1.1):实现1位半减器h_suber(diff=x-y ;s_out=1,x xin yin a b diff_out c PORT( x,y: IN STD_LOGIC; diff,s_out: OUT STD_LOGIC); END ENTITY h_suber; ARCHITECTURE hs1 OF h_suber IS BEGIN Diff <= x XOR (NOT y); s_out <= (NOT x) AND y; END ARCHITECTURE hs1; --解(1.2):采用例化实现图4-20的1位全减器 LIBRARY IEEE; --1位二进制全减器顺层设计描述 USE IEEE.STD_LOGIC_1164.ALL; ENTITY f_suber IS PORT(xin,yin,sub_in: IN STD_LOGIC; sub_out,diff_out: OUT STD_LOGIC); END ENTITY f_suber; ARCHITECTURE fs1 OF f_suber IS COMPONENT h_suber --调用半减器声明语句 PORT(x, y: IN STD_LOGIC; diff,s_out: OUT STD_LOGIC); END COMPONENT; SIGNAL a,b,c: STD_LOGIC; --定义1个信号作为内部的连接线。 BEGIN u1: h_suber PORT MAP(x=>xin,y=>yin, diff=>a, s_out=>b); u2: h_suber PORT MAP(x=>a, y=>sub_in, diff=>diff_out,s_out=>c); sub_out <= c OR b; END ARCHITECTURE fs1; (2)以1位全减器为基本硬件,构成串行借位的8位减法器,要求用例化语句来完成此项设计(减法运算是x-y-sun_in=difft)。 --解(2):采用例化方法,以1 位全减器为基本硬件;实现串行借位的8位减法器(上图所示)。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY suber_8 IS PORT(x0,x1,x2,x3,x4,x5,x6,x7: IN STD_LOGIC; y0,y1,y2,y3,y4,y5,y6,y7,sin: IN STD_LOGIC; diff0,diff1,diff2,diff3: OUT STD_LOGIC; diff4,diff5,diff6,diff7,sout: OUT STD_LOGIC); END ENTITY suber_8; ARCHITECTURE s8 OF suber_8 IS COMPONENT f_suber --调用全减器声明语句 PORT(xin,yin,sub_in: IN STD_LOGIC; diff0 diff1 sout diff7 串行借位的8位减法器 sub_out,diff_out: OUT STD_LOGIC); END COMPONENT; SIGNAL a0,a1,a2,a3,a4,a5,a6: STD_LOGIC; --定义1个信号作为内部的连接线。 BEGIN u0:f_suber PORT MAP(xin=>x0,yin=>y0,diff_out=>diff0,sub_in=>sin,sub_out=>a0); u1:f_suber PORT MAP(xin=>x1,yin=>y1,diff_out=>diff1,sub_in=>a0,sub_out=>a1); u2:f_suber PORT MAP(xin=>x2,yin=>y2,diff_out=>diff2,sub_in=>a1,sub_out=>a2); u3:f_suber PORT MAP(xin=>x3,yin=>y3,diff_out=>diff3,sub_in=>a2,sub_out=>a3); u4:f_suber PORT MAP(xin=>x4,yin=>y4,diff_out=>diff4,sub_in=>a3,sub_out=>a4); u5:f_suber PORT MAP(xin=>x5,yin=>y5,diff_out=>diff5,sub_in=>a4,sub_out=>a5); u6:f_suber PORT MAP(xin=>x6,yin=>y6,diff_out=>diff6,sub_in=>a5,sub_out=>a6); u7:f_suber PORT MAP(xin=>x7,yin=>y7,diff_out=>diff7,sub_in=>a6,sub_out=>sout); END ARCHITECTURE s8; 3-5 用VHDL设计一个3-8译码器,要求分别用(条件)赋值语句、case语句、if else语句或移位操作符来完成。比较这4种方式中,哪一种最节省逻辑资源。 解(1):条件赋值语句 --3-5 3到8译码器设计(条件赋值语句实现) LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; --为使用类型转换函数,打开此程序包。 ENTITY decoder3to8 IS port( DIN: IN STD_LOGIC_VECTOR(2 DOWNTO 0); DOUT: OUT BIT_VECTOR(7 DOWNTO 0)); END decoder3to8; ARCHITECTURE behave OF decoder3to8 IS BEGIN WITH CONV_INTEGER(DIN) SELECT DOUT<="00000001" WHEN 0, "00000010" WHEN 1, "00000100" WHEN 2, "00001000" WHEN 3, "00010000" WHEN 4, "00100000" WHEN 5, "01000000" WHEN 6, "10000000" WHEN 7, UNAFFECTED WHEN OTHERS; END behave; 解(2):case语句 --3-5 3到8译码器设计(case语句实现) LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; --为使用类型转换函数,打开此程序包。 ENTITY decoder3to8 IS port( DIN: IN STD_LOGIC_VECTOR(2 DOWNTO 0); DOUT: OUT BIT_VECTOR(7 DOWNTO 0)); END decoder3to8; ARCHITECTURE behave OF decoder3to8 IS BEGIN PROCESS (DIN) BEGIN CASE CONV_INTEGER(DIN) IS WHEN 0 => DOUT<="00000001"; WHEN 1 => DOUT<="00000010"; WHEN 2 => DOUT<="00000100"; WHEN 3 => DOUT<="00001000"; WHEN 4 => DOUT<="00010000"; WHEN 5 => DOUT<="00100000"; WHEN 6 => DOUT<="01000000"; WHEN 7 => DOUT<="10000000"; WHEN OTHERS => NULL; END CASE; END PROCESS; END behave; 解(3):if_else语句 --3-5 3到8译码器设计(if_else语句实现) LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; --为使用类型转换函数,打开此程序包。 ENTITY decoder3to8 IS port( DIN: IN STD_LOGIC_VECTOR(2 DOWNTO 0); DOUT: OUT BIT_VECTOR(7 DOWNTO 0)); END decoder3to8; ARCHITECTURE behave OF decoder3to8 IS BEGIN PROCESS (DIN) BEGIN IF CONV_INTEGER(DIN)=0 THEN DOUT<="00000001"; ELSIF CONV_INTEGER(DIN)=1 THEN DOUT<="00000010"; ELSIF CONV_INTEGER(DIN)=2 THEN DOUT<="00000100"; ELSIF CONV_INTEGER(DIN)=3 THEN DOUT<="00001000"; ELSIF CONV_INTEGER(DIN)=4 THEN DOUT<="00010000"; ELSIF CONV_INTEGER(DIN)=5 THEN DOUT<="00100000"; ELSIF CONV_INTEGER(DIN)=6 THEN DOUT<="01000000"; ELSIF CONV_INTEGER(DIN)=7 THEN DOUT<="10000000"; END IF; END PROCESS; END behave; 解(4):移位操作符 --3-5 3到8译码器设计(移位操作实现) LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; --为使用类型转换函数,打开此程序包。 ENTITY decoder3to8 IS port( DIN: IN STD_LOGIC_VECTOR(2 DOWNTO 0); DOUT: OUT BIT_VECTOR(7 DOWNTO 0)); END decoder3to8; ARCHITECTURE behave OF decoder3to8 IS BEGIN DOUT<="00000001" SLL CONV_INTEGER(DIN); --被移位部分是常数 END behave; 3-6 设计一个比较电路,当输入的8421BCD码大于5时输出1,否则输出0。 --解:3-6 设计一个比较电路,当输入的8421BCD码大于5时输出1,否则输出0。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY g_5_cmp IS PORT( d_in : IN STD_LOGIC_VECTOR(3 DOWNTO 0); --输入数据 cmp_out : OUT STD_LOGIC); --比较输出(1:输入数据>5) END g_5_cmp; ARCHITECTURE BHV OF g_5_cmp IS BEGIN PROCESS(d_in) BEGIN IF(d_in>"0101") THEN cmp_out<='1'; --输入数据大于5,比较输出1。 else cmp_out<='0'; --输入数据小于等于5,比较输出0。 END IF; END PROCESS; END BHV; 3-7 利用if语句设计一个全加器。 --3-7 利用if语句设计一个全加器 LIBRARY IEEE; --1位二进制全加器顶层设计描述 USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY f_adder IS PORT (ain,bin,cin : IN STD_LOGIC; cout,sum : OUT STD_LOGIC ); END ENTITY f_adder; ARCHITECTURE fd1 OF f_adder IS BEGIN PROCESS (ain,bin,cin) BEGIN IF ain='1' XOR bin='1' XOR cin='1' THEN sum<='1'; ELSE sum<='0'; END IF; IF (ain='1' AND bin='1')OR(ain='1' AND cin='1')OR(bin='1' AND cin='1')OR(ain='1' AND bin='1' AND cin='1') THEN cout<='1'; ELSE cout<='0'; END IF; END PROCESS; END ARCHITECTURE fd1; 3-8 设计一个求补码的程序,输入数据是一个有符号的8位二进制数。 --解:3-8 设计一个求补码的程序,输入数据是一个有符号的8位二进制数。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY org_patch IS PORT( org_data : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--原码输入 patch_data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));--补码输出 END org_patch; ARCHITECTURE BHV OF org_patch IS BEGIN PROCESS(org_data) BEGIN IF(org_data(7)='0') THEN patch_data<=org_data; --org_data>=0,补码=原码。 else patch_data<=org_data(7)&(not org_data(6 DOWNTO 0))+1;--org_data<0,补码=|原码|取反+1。 END IF; END PROCESS; END BHV; 3-9 设计一个格雷码至二进制数的转换器。 --3-9 设计一个格雷码至二进制数的转换器。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; --为使用类型转换函数,打开此程序包。 ENTITY grayTObinary IS port( DIN: IN STD_LOGIC_VECTOR(3 DOWNTO 0); DOUT: OUT BIT_VECTOR(3 DOWNTO 0)); END grayTObinary; ARCHITECTURE behave OF grayTObinary IS BEGIN PROCESS (DIN) BEGIN CASE DIN IS WHEN "0000" => DOUT<="0000"; WHEN "0001" => DOUT<="0001"; WHEN "0011" => DOUT<="0010"; WHEN "0010" => DOUT<="0011"; WHEN "0110" => DOUT<="0100"; WHEN "0111" => DOUT<="0101"; WHEN "0101" => DOUT<="0110"; WHEN "0100" => DOUT<="0111"; WHEN "1100" => DOUT<="1000"; WHEN "1101" => DOUT<="1001"; WHEN "1111" => DOUT<="1010"; WHEN "1110" => DOUT<="1011"; WHEN "1010" => DOUT<="1100"; WHEN "1011" => DOUT<="1101"; WHEN "1001" => DOUT<="1110"; WHEN "1000" => DOUT<="1111"; WHEN OTHERS => NULL; END CASE; END PROCESS; END behave; 3-10 利用if语句设计一个3位二进制数A[2..0]、B[2..0]的比较器电路。对于比较(AB)、(A=B)的结果分别给出输出信号LT=1、GT=1、EQ=1。 --3-10 利用if语句设计一个3位二进制数A[2..0]、B[2..0]的比较器电路。 --对于比较(AB)、(A=B)的结果分别给出输出信号LT=1、GT=1、EQ=1。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY COMP IS PORT( A,B: IN STD_LOGIC_VECTOR(2 DOWNTO 0); --两个3位输入 LT: OUT STD_LOGIC; --小于输出 GT: OUT STD_LOGIC; --大于输出 EQ: OUT STD_LOGIC); --等于输出 END ENTITY COMP; ARCHITECTURE ONE OF COMP IS BEGIN PROCESS(A,B) BEGIN IF (A IF (A>B) THEN GT<='1';ELSE GT<='0';END IF; IF (A=B) THEN EQ<='1';ELSE EQ<='0';END IF; END PROCESS; -- LT <= (A -- GT <= (A>B); --大于 -- EQ <= (A=B); --等于 END ARCHITECTURE ONE; 3-11 利用8个全加器,可以构成一个8位加法器。利用循环语句来实现这项设计。并以此项设计为例,使用GENERIC参数传递的功能,设计一个32位加法器。 --3-11 利用GENERIC参数和循环语句将8个全加器构成成8位加法器 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY ADDER8B IS GENERIC(S: INTEGER:=8); --定义参数S为整数类型,且等于4 PORT(A,B: IN STD_LOGIC_VECTOR(S-1 DOWNTO 0); CIN: IN STD_LOGIC; SUM: OUT STD_LOGIC_VECTOR(S-1 DOWNTO 0); COUT: OUT STD_LOGIC); END ENTITY ADDER8B; ARCHITECTURE ONE OF ADDER8B IS BEGIN PROCESS(A,B,CIN) V ARIABLE S1: STD_LOGIC_VECTOR(S-1 DOWNTO 0); V ARIABLE C1: STD_LOGIC;--_VECTOR(S DOWNTO 0); BEGIN C1:=CIN; --C1(0):=CIN; FOR i IN 1 TO S LOOP IF A(i-1)='1' XOR B(i-1)='1' XOR C1='1' THEN S1(i-1):='1'; ELSE S1(i-1):='0'; END IF; IF (A(i-1)='1' AND B(i-1)='1')OR(A(i-1)='1' AND C1='1')OR(B(i-1)='1' AND C1='1')OR(A(i-1)='1' AND B(i-1)='1' AND C1='1') THEN C1:='1'; ELSE C1:='0'; END IF; END LOOP; SUM<=S1;COUT<=C1; END PROCESS; END ARCHITECTURE ONE; 3-12 设计一个2位BCD码减法器。注意可以利用BCD码加法器来实现。因为减去一个二进制数,等于加上这个数的补码。只是需要注意,作为十进制的BCD码的补码获取方式与普通二进制数稍有不同。我们知道二进制数的补码是这个数的取反加1。假设有一个4位二进制数是0011,其取补实际上是用1111减去0011,再加上l。相类似,以4位二进制表达的BCD码的取补则是用9(1001)减去这个数再加上1。 --3-12 设计2位BCD码减法器(利用减去数等于加上该数补码方法) (a-b=a+[-b]补码) LIBRARY IEEE; --待例化元件 USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_arith.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; ENTITY SUB2BCD IS PORT(a,b: IN STD_LOGIC_VECTOR(7 DOWNTO 0); diff: out STD_LOGIC_VECTOR(7 DOWNTO 0); sout: OUT STD_LOGIC); END SUB2BCD; ARCHITECTURE behave OF SUB2BCD IS BEGIN PROCESS(a,b) V ARIABLE cc: STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN IF a cc:="10011010"-b; IF cc(3 DOWNTO 0) > "1001" THEN cc:=cc+"00000110";END IF; IF cc(7 DOWNTO 4) > "1001" THEN cc:=cc+"01100000";END IF; cc:=a+cc; IF cc(3 DOWNTO 0) > "1001" THEN cc:=cc+"00000110";END IF; IF cc(7 DOWNTO 4) > "1001" THEN cc:=cc+"01100000";END IF; IF a cc:="10011010"-cc; IF cc(3 DOWNTO 0) > "1001" THEN cc:=cc+"00000110";END IF; IF cc(7 DOWNTO 4) > "1001" THEN cc:=cc+"01100000";END IF; END IF; diff<=cc; END PROCESS; END behave; 3-13 设计一个4位乘法器,为此首先设计一个加法器,用例化语句调用这个加法器,用移位相加的方式完成乘法。并以此项设计为基础,使用GENERIC参数传递的功能,设计一个16位乘法器。 --3-13 4位移位相加型乘法器设计(例化调用加法器) LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY MULT4B IS GENERIC( S: INTEGER:=4); --定义参数S为整数类型,且等于4 PORT( R: OUT STD_LOGIC_VECTOR(2*S-1 DOWNTO 0); A,B: IN STD_LOGIC_VECTOR(S-1 DOWNTO 0)); END ENTITY MULT4B; ARCHITECTURE ONE OF MULT4B IS COMPONENT addern IS PORT(a,b: IN STD_LOGIC_VECTOR; result: out STD_LOGIC_VECTOR); END COMPONENT; SIGNAL A0: STD_LOGIC_VECTOR(2*S-1 DOWNTO 0); SIGNAL RR3,RR2,RR1,RR0,ZZ1,ZZ0: STD_LOGIC_VECTOR(2*S-1 DOWNTO 0); BEGIN A0<=CONV_STD_LOGIC_VECTOR(0,S) & A; PROCESS(A,B) BEGIN IF(B(0)='1')THEN RR0<=TO_STDLOGICVECTOR(TO_BITVECTOR(A0) SLL 0);ELSE RR0<=(OTHERS=>'0');END IF; IF(B(1)='1')THEN RR1<=TO_STDLOGICVECTOR(TO_BITVECTOR(A0) SLL 1);ELSE RR1<=(OTHERS=>'0');END IF; IF(B(2)='1')THEN RR2<=TO_STDLOGICVECTOR(TO_BITVECTOR(A0) SLL 2);ELSE RR2<=(OTHERS=>'0');END IF; IF(B(3)='1')THEN RR3<=TO_STDLOGICVECTOR(TO_BITVECTOR(A0) SLL 3);ELSE RR3<=(OTHERS=>'0');END IF; END PROCESS; u0: addern PORT MAP(a=>RR0,b=>RR1,result=>ZZ0); u1: addern PORT MAP(a=>ZZ0,b=>RR2,result=>ZZ1); u2: addern PORT MAP(a=>ZZ1,b=>RR3,result=>R); END ARCHITECTURE ONE; --3-13a 16位乘法器(通过底层3-13_MULTSB和顶层GENERIC参数和传递例化语句实现) LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MULT16B IS PORT(D1,D2: IN STD_LOGIC_VECTOR(15 DOWNTO 0); Q: OUT STD_LOGIC_VECTOR(31 DOWNTO 0)); END; ARCHITECTURE BHV OF MULT16B IS COMPONENT MULTSB --MULTS8模块的调用声明 GENERIC(S: integer); --照抄MULTSB实体中关于参数“端口”定义的语句 PORT(R: OUT std_logic_vector(2*S-1 DOWNTO 0); A,B: IN std_logic_vector(S-1 DOWNTO 0)); END COMPONENT ; BEGIN u1: MULTSB GENERIC MAP(S=>16) PORT MAP(R=>Q,A=>D1,B=>D2); END; 3-14 用循环语句设计一个7人投票表决器。 --解:3-14 用循环语句设计一个7人投票表决器,及一个4位4输出最大数值检测电路。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY vote_7 IS PORT( DIN: IN STD_LOGIC_VECTOR(6 DOWNTO 0);--7位表决输入(1:同意,0:不同意) G_4: OUT STD_LOGIC; --超过半数指示 CNTH: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));--表决结果统计数 END vote_7; ARCHITECTURE BHV OF vote_7 IS BEGIN PROCESS(DIN) V ARIABLE Q: STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN Q:="000"; FOR n IN 0 TO 6 LOOP -- n是LOOP的循环变量 IF(DIN(n)='1') THEN Q:=Q+1; END IF; END LOOP; CNTH<=Q; IF Q>=4 THEN G_4<='1'; ELSE G_4<='0'; END IF; END PROCESS; END BHV; 3-15 设计一个4位4输入最大数值检测电路。