第一章

1-1 EDA技术与ASIC设计和FPGA开发有什么关系?   P3~4

答:利用EDA技术进行电子系统设计的最后目标是完成专用集成电路ASIC的设计和实现;FPGA和CPLD是实现这一途径的主流器件。FPGA和CPLD通常也被称为可编程专用IC,或可编程ASIC。FPGA和CPLD的应用是EDA技术有机融合软硬件电子设计技术、SoC(片上系统)和ASIC设计,以及对自动设计与自动实现最典型的诠释。

1-2与软件描述语言相比,VHDL有什么特点?  P6

答:编译器将软件程序翻译成基于某种特定CPU的机器代码,这种代码仅限于这种CPU而不能移植,并且机器代码不代表硬件结构,更不能改变CPU的硬件结构,只能被动地为其特定的硬件电路结构所利用。综合器将VHDL程序转化的目标是底层的电路结构网表文件,这种满足VHDL设计程序功能描述的电路结构,不依赖于任何特定硬件环境;具有相对独立性。综合器在将VHDL(硬件描述语言)表达的电路功能转化成具体的电路结构网表过程中,具有明显的能动性和创造性,它不是机械的一一对应式的“翻译”,而是根据设计库、工艺库以及预先设置的各类约束条件,选择最优的方式完成电路结构的设计。

l-3什么是综合?有哪些类型?综合在电子设计自动化中的地位是什么?  P5

什么是综合? 答:在电子设计领域中综合的概念可以表示为:将用行为和功能层次表达的电子系统转换为低层次的便于具体实现的模块组合装配的过程。

有哪些类型? 答:(1)从自然语言转换到VHDL语言算法表示,即自然语言综合。(2)从算法表示转换到寄存器传输级(RegisterTransport Level,RTL),即从行为域到结构域的综合,即行为综合。(3)从RTL级表示转换到逻辑门(包括触发器)的表示,即逻辑综合。(4)从逻辑门表示转换到版图表示(ASIC设计),或转换到FPGA的配置网表文件,可称为版图综合或结构综合。

综合在电子设计自动化中的地位是什么? 答:是核心地位(见图1-3)。综合器具有更复杂的工作环境,综合器在接受VHDL程序并准备对其综合前,必须获得与最终实现设计电路硬件特征相关的工艺库信息,以及获得优化综合的诸多约束条件信息;根据工艺库和约束条件信息,将VHDL程序转化成电路实现的相关信息。

1-4在EDA技术中,自顶向下的设计方法的重要意义是什么?  P7~10

答:在EDA技术应用中,自顶向下的设计方法,就是在整个设计流程中各设计环节逐步求精的过程。

1-5 IP在EDA技术的应用和发展中的意义是什么?  P11~12

答:IP核具有规范的接口协议,良好的可移植与可测试性,为系统开发提供了可靠的保证。

2  习    题

2-1  OLMC(输出逻辑宏单元)有何功能?说明GAL是怎样实现可编程组合电路与时序电路的。  P34~36

2-2  什么是基于乘积项的可编程逻辑结构?  P33~34,40  什么是基于查找表的可编程逻辑结构?  P40~41

:GAL、CPLD之类都是基于乘积项的可编程结构;即包含有可编程与阵列和固定的或阵列的PAL(可编程阵列逻辑)器件构成

FPGA(现场可编程门阵列)是基于查找表的可编程逻辑结构。

2-3  FPGA系列器件中的LAB有何作用?  P43~45

2-5  解释编程与配置这两个概念。  P58

:编程:基于电可擦除存储单元的EEPROM或Flash技术。CPLD一股使用此技术进行编程。CPLD被编程后改变了电可擦除存储单元中的信息,掉电后可保存。电可擦除编程工艺的优点是编程后信息不会因掉电而丢失,但编程次数有限,编程的速度不快。 配置:基于SRAM查找表的编程单元。编程信息是保存在SRAM中的,SRAM在掉电后编程信息立即丢失,在下次上电后,还需要重新载入编程信息。大部分FPGA采用该种编程工艺。该类器件的编程一般称为配置。对于SRAM型FPGA来说,配置次数无限,且速度快;在加电时可随时更改逻辑;下载信息的保密性也不如电可擦除的编程

2-6  请参阅相关资料,并回答问题:按本章给出的归类方式,将基于乘积项的可编程逻辑结构的PLD器件归类为CPLD;将基于查找表的可编程逻辑结构的PLD器什归类为FPGA,那么,APEX系列属于什么类型PLD器件? MAX II系列又属于什么类型的PLD器件?为什么?  P54~56

第二章

2-1 叙述EDA的FPGA/CPLD设计流程。  P13~16

答:1.设计输入(原理图/HDL文本编辑);2.综合;3.适配;4.时序仿真与功能仿真;5.编程下载;6.硬件测试。

2-2 IP是什么?IP与EDA技术的关系是什么?  P24~26

IP是什么? 答:IP是知识产权核或知识产权模块,用于ASIC或FPGA/CPLD中的预先设计好的电路功能模块。

IP与EDA技术的关系是什么? 答:IP在EDA技术开发中具有十分重要的地位;与EDA技术的关系分有软IP、固IP、硬IP:软IP是用VHDL等硬件描述语言描述的功能块,并不涉及用什么具体电路元件实现这些功能;软IP通常是以硬件描述语言HDL源文件的形式出现。固IP是完成了综合的功能块,具有较大的设计深度,以网表文件的形式提交客户使用。硬IP提供设计的最终阶段产品:掩模。

2-3 叙述ASIC的设计方法。  P18~19

答:ASIC设计方法,按版图结构及制造方法分有半定制(Semi-custom)和全定制(Full-custom)两种实现方法。

全定制方法是一种基于晶体管级的,手工设计版图的制造方法。

半定制法是一种约束性设计方式,约束的目的是简化设计,缩短设计周期,降低设计成本,提高设计正确率。半定制法按逻辑实现的方式不同,可再分为门阵列法、标准单元法和可编程逻辑器件法。

2-4 FPGA/CPLD在ASIC设计中有什么用途?  P16,18

答:FPGA/CPLD在ASIC设计中,属于可编程ASIC的逻辑器件;使设计效率大为提高,上市的时间大为缩短。

2-5 简述在基于FPGA/CPLD的EDA设计流程中所涉及的EDA工具,及其在整个流程中的作用。  P19~23

答:基于FPGA/CPLD的EDA设计流程中所涉及的EDA工具有:设计输入编辑器(作用:接受不同的设计输入表达方式,如原理图输入方式、状态图输入方式、波形输入方式以及HDL的文本输入方式。);HDL综合器(作用:HDL综合器根据工艺库和约束条件信息,将设计输入编辑器提供的信息转化为目标器件硬件结构细节的信息,并在数字电路设计技术、化简优化算法以及计算机软件等复杂结体进行优化处理);仿真器(作用:行为模型的表达、电子系统的建模、逻辑电路的验证及门级系统的测试);适配器(作用:完成目标系统在器件上的布局和布线);下载器(作用:把设计结果信息下载到对应的实际器件,实现硬件设计)。

第三章

3-1 OLMC(输出逻辑宏单元)有何功能?说明GAL是怎样实现可编程组合电路与时序电路的。  P34~36

OLMC有何功能? 答:OLMC单元设有多种组态,可配置成专用组合输出、专用输入、组合输出双向口、寄存器输出、寄存器输出双向口等。

说明GAL是怎样实现可编程组合电路与时序电路的? 答:GAL(通用阵列逻辑器件)是通过对其中的OLMC(输出逻辑宏单元)的编程和三种模式配置(寄存器模式、复合模式、简单模式),实现组合电路与时序电路设计的。

3-2 什么是基于乘积项的可编程逻辑结构?  P33~34,40

答:GAL、CPLD之类都是基于乘积项的可编程结构;即包含有可编程与阵列和固定的或阵列的PAL(可编程阵列逻辑)器件构成。

3-3 什么是基于查找表的可编程逻辑结构?  P40~41

答:FPGA(现场可编程门阵列)是基于查找表的可编程逻辑结构。

3-4 FPGA系列器件中的LAB有何作用?  P43~45

答:FPGA(Cyclone/Cyclone II)系列器件主要由逻辑阵列块LAB、嵌入式存储器块(EAB)、I/O单元、嵌入式硬件乘法器和PLL等模块构成;其中LAB(逻辑阵列块)由一系列相邻的LE(逻辑单元)构成的;FPGA可编程资源主要来自逻辑阵列块LAB。

3-5 与传统的测试技术相比,边界扫描技术有何优点?  P47~50

答:使用BST(边界扫描测试)规范测试,不必使用物理探针,可在器件正常工作时在系统捕获测量的功能数据。克服传统的外探针测试法和“针床”夹具测试法无法对IC内部节点测试的难题。

3-6 解释编程与配置这两个概念。  P58

答:编程:基于电可擦除存储单元的EEPROM或Flash技术。CPLD一股使用此技术进行编程。CPLD被编程后改变了电可擦除存储单元中的信息,掉电后可保存。电可擦除编程工艺的优点是编程后信息不会因掉电而丢失,但编程次数有限,编程的速度不快。

配置:基于SRAM查找表的编程单元。编程信息是保存在SRAM中的,SRAM在掉电后编程信息立即丢失,在下次上电后,还需要重新载入编程信息。大部分FPGA采用该种编程工艺。该类器件的编程一般称为配置。对于SRAM型FPGA来说,配置次数无限,且速度快;在加电时可随时更改逻辑;下载信息的保密性也不如电可擦除的编程。

3-7 请参阅相关资料,并回答问题:按本章给出的归类方式,将基于乘积项的可编程逻辑结构的PLD器件归类为CPLD;将基于查找表的可编程逻辑结构的PLD器什归类为FPGA,那么,APEX系列属于什么类型PLD器件? MAX II系列又属于什么类型的PLD器件?为什么?  P54~56

答:APEX(Advanced Logic Element Matrix)系列属于FPGA类型PLD器件;编程信息存于SRAM中。MAX II系列属于CPLD类型的PLD器件;编程信息存于EEPROM中。

第三章

3-1  画出与以下实体描述对应的原理图符号元件:

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-2  图3-16所示的是4选1多路选择器,试分别用IF_THEN语句和CASE语句的表达方式写出此电路的VHDL程序,选择控制信号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。

图3-16  4选1多路选择器

--解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-3  图3-17所示的是双2选1多路选择器构成的电路MUXK,对于其中MUX21A,当s=’0’和s=’1’时,分别有y<=‘a’和y<=’b’。试在一个结构体中用两个进程来表达此电路,每个进程中用CASE语句描述一个2选1多路选择器MUX21A。

图3-17  含2选1多路选择器的模块

--解:用CASE语句实现图4-18所示的是双2选1多路选择器构成的电路

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY mux31 IS

PORT(a1,a2,a3,s0,s1: IN STD_LOGIC;

outy:OUT STD_LOGIC);

END ENTITY mux31;

ARCHITECTURE  case_mux31  OF mux31  IS

SIGNAL y : STD_LOGIC;

BEGIN

u1:  PROCESS(s0,a1,a2,a3)

BEGIN

CASE s0 IS    --类似于真值表的case语句

WHEN '0'  =>  y  <=  a2;

WHEN '1'  =>  y  <=  a3;

WHEN OTHERS  =>NULL  ;

END CASE;

END PROCESS;

u2:  PROCESS(s1,a1,a2,a3,y)

BEGIN

CASE s1 IS    --类似于真值表的case语句

WHEN '0'  =>  outy  <=  a1;

WHEN '1'  =>  outy  <=  y;

WHEN OTHERS  =>NULL  ;

END CASE;

END PROCESS;

END ARCHITECTURE  case_mux31;

3-4  将例3-20程序的计数器改为十二进制计数器,程序用例3-21的方式表述,并且将复位RST改为同步清零控制,加载信号LOAD改为异步控制方式。讨论例3-20与例3-21的异同点。

--解:十二进制计数器VHDL程序设计。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY CNT12 IS

PORT(CLK,RST,EN,LOAD : IN STD_LOGIC;

DATA   :   IN STD_LOGIC_VECTOR(3 DOWNTO 0); --4位预置数

DOUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--计数值输出

COUT : OUT STD_LOGIC);             --计数进位输出

END CNT12;

ARCHITECTURE behav OF CNT12 IS

SIGNAL  Q : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

REG: PROCESS(CLK,RST,EN,LOAD,Q)

BEGIN

IF LOAD='0' THEN Q<=DATA;            --允许加载

ELSIF CLK'EVENT AND CLK='1' THEN     --检测时钟上升沿

IF RST='0' THEN Q<=(OTHERS =>'0'); --计数器异步复位

ELSE

IF EN='1' THEN                   --检测是否允许计数或加载(同步使能)

IF LOAD='0' THEN Q<=DATA;      --允许加载

ELSE

IF Q<12 THEN Q<=Q+1;          --允许计数,检测是否小于9

ELSE Q<=(OTHERS=>'0');       --大于等于9时,计数值清零

END IF;

END IF;

END IF;

END IF;

END IF;

END PROCESS;

COM: PROCESS(Q)

BEGIN

IF Q=12 THEN COUT<='1'; --计数大于9,输出进位信号

ELSE COUT<='0';

END IF;

DOUT<=Q;       --将计数值向端口输出

END PROCESS;

END behav;

3-5  设计含有异步清零和计数使能的16位二进制加减可控计数器。

--解:用VHDL实现含有异步清零和计数使能的16位二进制加减可控计数器。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY ADD_SUB_16 IS

PORT (CLK,RST,ADD_EN,SUB_EN:  IN STD_LOGIC;

CQ  :  OUT  STD_LOGIC_VECTOR(15  DOWNTO  0)  ;

COUT:  OUT STD_LOGIC);

END ENTITY ADD_SUB_16;

ARCHITECTURE A_S_16 OF ADD_SUB_16 IS

BEGIN

PROCESS(CLK,RST,ADD_EN,SUB_EN)

VARIABLE CQI: STD_LOGIC_VECTOR(15 DOWNTO 0);

BEGIN

IF RST = '1' THEN CQI:=(OTHERS => '0');--计数器异步复位

ELSIF CLK'EVENT AND CLK='1' THEN    --检测时钟上升沿

IF ADD_EN='1'THEN    --检测是否允许计数(同步他能)

IF CQI<16#FFFF# THEN  CQI:=CQI+1;    --允许计数,检测是否小于65535

ELSE CQI:=(OTHERS => '0');    --大于65535,计数值清零

END IF;

IF CQI=16#FFFF# THEN COUT<='1';    --计数大于9,输出进位信号

ELSE COUT <= '0';

END IF;

END IF;

IF SUB_EN='1'THEN    --检测是否允许计数(同步他能)

IF CQI>0 THEN  CQI:=CQI-1;    --允许计数,检测是否小于65535

ELSE CQI:=(OTHERS => '1');    --大于65535,计数值清零

END IF;

IF CQI=0 THEN COUT<='1';    --计数大于9,输出进位信号

ELSE COUT <= '0';

END IF;

END IF;

END IF;

CQ<=CQI;    --将计数值向端口输出

END PROCESS;

END ARCHITECTURE A_S_16;

3-6  图3-18是一个含有上升沿触发的D触发器的时序电路(sxdl),试写出此电路的VHDL设计文件。

图3-18  时序电路

--解:实现图4-19电路的VHDL程序t4_19.vhd

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY t4_19 IS

PORT  (CL,CLK0: IN STD_LOGIC;

OUT1:    OUT STD_LOGIC);

END ENTITY t4_19;

ARCHITECTURE  sxdl  OF t4_19  IS   ----时序电路sxdl

SIGNAL Q : STD_LOGIC;

BEGIN

PROCESS(CLK0)

BEGIN

IF  CLK0'EVENT AND CLK0='1'  THEN    --检测时钟上升沿

Q <= NOT(Q OR CL);

END IF;

END PROCESS;

OUT1 <= NOT Q;

END ARCHITECTURE  sxdl;

3-7  给出1位全减器的VHDL描述;最终实现8位全减器。要求:

1)首先设计1位半减器,然后用例化语句将它们连接起来,图4-20中h_suber是半减器,diff是输出差(diff=x-y),s_out是借位输出(s_out=1,x<y),sub_in是借位输入。

图3-19  1位全加器

--解(1.1):实现1位半减器h_suber(diff=x-y;s_out=1,x<y)

LIBRARY IEEE;   --半减器描述(1):布尔方程描述方法

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY h_suber IS

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;

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-8  给出一个4选1多路选择器的VHDL描述。选通控制端有四个输入:S0、S1、S2、S3。当且仅当S0=0时:Y=A;S1=0时:Y=B;S2=0时:Y=C;S3=0时:Y=D。

--解:4选1多路选择器VHDL程序设计。

LIBRARY  IEEE;  --图3-20(c)RTL图的VHDL程序顶层设计描述

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY mux41a IS

PORT(    A,B,C,D :  IN STD_LOGIC;

S0,S1,S2,S3 :  IN STD_LOGIC;

Y : OUT STD_LOGIC);

END ENTITY mux41a;

ARCHITECTURE one OF mux41a IS

SIGNAL S0_3 : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

S0_3<=S0&S1&S2&S3;

y<=A  WHEN S0_3="0111" ELSE

B  WHEN S0_3="1011" ELSE

C  WHEN S0_3="1101" ELSE

D  WHEN S0_3="1110" ELSE

'Z';

END ARCHITECTURE one;

3-9  分频方法有多种,最简单的是二分频和偶数分频甚至奇数分频,这用触发器或指定计数模的计数器即可办到。但对于现场实现指定分频比或小数分频率的分频电路的设计就不是很简单了。

试对例3-20的设计稍作修改,将其进位输出COUT与异步加载控制LOAD连在一起,构成一个自动加载型16位二进制数计数器,也即一个16位可控的分频器,给出其VHDL表述,并说明工作原理。设输入频率fi=4MHz,输出频率fo=516.5±1Hz(允许误差±0.1Hz),16位加载数值是多少?

--解:3-9  16位数控分频器(可进行奇偶数分频)

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY DVF16 IS

PORT(CLK  :  IN STD_LOGIC;

D  :  IN STD_LOGIC_VECTOR(15 DOWNTO 0);

FOUT  : OUT STD_LOGIC);

END ENTITY DVF16;

ARCHITECTURE one OF DVF16 IS

SIGNAL FULL : STD_LOGIC;

BEGIN

P_REG: PROCESS(CLK)

VARIABLE CNT8 : STD_LOGIC_VECTOR(15 DOWNTO 0);

BEGIN

IF CLK'EVENT AND CLK = '1' THEN

IF CNT8 = "0000000000000000" THEN

CNT8 := D-1;--当CNT8计数归0时,预置CNT8=D-1;

--计数范围(D=n):n-1~n/2取整(n=10:9\8\7\6\5计数,前后半周期相同)

FULL <= '1';--同时使溢出标志信号FULL输出为高电平

--(n=11:10\9\8\7\6\5计数,前比后半周期多一个时钟)

ELSIF CNT8 = ('0' & D(15 DOWNTO 1)) THEN

CNT8 :=('0' & D(15 DOWNTO 1))-1;--当CNT8=n/2取整时,预置CNT8=D/2取整-1;

--计数范围(D=n):n/2取整~0(n=10:4\3\2\1\0计数)

FULL <= '1'; --同时使溢出标志信号FULL输出为高电平   (n=11:4\3\2\1\0计数)

ELSE CNT8 := CNT8 - 1;  --否则继续作加1计数

FULL <= '0';          --且输出溢出标志信号FULL为低电平

END IF;

END IF;

END PROCESS P_REG ;

P_DIV: PROCESS(FULL)

VARIABLE CNT2 : STD_LOGIC;

BEGIN

IF FULL'EVENT AND FULL = '1' THEN

CNT2 := NOT CNT2;--如果溢出标志信号FULL为高电平,D触发器输出取反

IF CNT2 = '1' THEN  FOUT <= '1';

ELSE FOUT <= '0';

END IF;

END IF;

END PROCESS P_DIV;

END ARCHITECTURE one;

3-10  用VHDL设计一个功能类似74LS160的计数器。

--解:3-10  用VHDL设计一个功能类似74LS160(异步复位和同步使能加载、计数的十进制加法计数器)的计数器。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY CNT10 IS

PORT(CLK,RST,EN,LOAD : IN STD_LOGIC;

DATA : IN  STD_LOGIC_VECTOR(3 DOWNTO 0); --4位预置数

DOUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--计数值输出

COUT : OUT STD_LOGIC);        --计数进位输出

END CNT10;

ARCHITECTURE behav OF CNT10 IS

BEGIN

PROCESS(CLK,RST,EN,LOAD)

VARIABLE Q : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF RST='0' THEN Q:=(OTHERS =>'0');   --计数器异步复位

ELSIF CLK'EVENT AND CLK='1' THEN     --检测时钟上升沿

IF EN='1' THEN                     --检测是否允许计数或加载(同步使能)

IF LOAD='0' THEN Q:=DATA;        --允许加载

ELSE

IF Q<9 THEN Q:=Q+1; --允许计数,检测是否小于9

ELSE Q:=(OTHERS=>'0'); --大于等于9时,计数值清零

END IF;

END IF;

END IF;

END IF;

IF Q=9 THEN COUT<='1'; --计数大于9,输出进位信号

ELSE COUT<='0';

END IF;

DOUT<=Q;              --将计数值向端口输出

END PROCESS;

END behav;

3-11  给出含有异步清零和计数使能的16位二进制加减可控计数器的VHDL描述。

--解:3-11 给出含有异步清零和计数使能的16位二进制加减可控计数器的VHDL描述。

--    用VHDL实现含有异步清零和计数使能的16位二进制加减可控计数器。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY ADD_SUB_LOAD_16 IS

PORT (CLK,RST,ADD_EN,SUB_EN,LOAD :  IN STD_LOGIC;

DATA :  IN STD_LOGIC_VECTOR(15  DOWNTO  0);

CQ : OUT STD_LOGIC_VECTOR(15  DOWNTO  0);

COUT : OUT STD_LOGIC);

END ENTITY ADD_SUB_LOAD_16;

ARCHITECTURE A_S_16 OF ADD_SUB_LOAD_16 IS

BEGIN

PROCESS(CLK,RST,ADD_EN,SUB_EN,LOAD)

VARIABLE CQI: STD_LOGIC_VECTOR(15 DOWNTO 0);

--VARIABLE LS_LOAD : STD_LOGIC;

BEGIN

--LS_LOAD:=LOAD;

IF RST = '1' THEN CQI:=(OTHERS => '0');--计数器异步复位

ELSIF LOAD = '1' THEN CQI:=DATA;    --LS_LOAD:='0';     --计数器异步复位

ELSIF CLK'EVENT AND CLK='1' THEN    --检测时钟上升沿

IF ADD_EN='1'THEN    --检测是否允许计数(同步他能)

IF CQI<16#FFFF# THEN  CQI:=CQI+1;    --允许计数,检测是否小于65535

ELSE CQI:=(OTHERS => '0');    --大于65535,计数值清零

END IF;

IF CQI=16#FFFF# THEN COUT<='1';    --计数大于9,输出进位信号

ELSE COUT <= '0';

END IF;

END IF;

IF SUB_EN='1'THEN    --检测是否允许计数(同步他能)

IF CQI>0 THEN  CQI:=CQI-1;    --允许计数,检测是否小于65535

ELSE CQI:=(OTHERS => '1');    --大于65535,计数值清零

END IF;

IF CQI=0 THEN COUT<='1';    --计数大于9,输出进位信号

ELSE COUT <= '0';

END IF;

END IF;

END IF;

CQ<=CQI;    --将计数值向端口输出

END PROCESS;

END ARCHITECTURE A_S_16;

3-12  分别给出图3-20所示的六个RTL图的VHDL描述,注意其中的D触发器和锁存器的表述。

图3-20  RTL图

图3-20  RTL图(a)

--解:实现图3-20(a)RTL图的VHDL程序t3_12_a.vhd

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY t3_12_a IS

PORT  (CL,CLK0: IN STD_LOGIC;

OUT1:    OUT STD_LOGIC);

END ENTITY t3_12_a;

ARCHITECTURE  sxdl  OF t3_12_a  IS   ----时序电路sxdl

SIGNAL Q : STD_LOGIC;

BEGIN

PROCESS(CLK0)

BEGIN

IF  CLK0'EVENT AND CLK0='1'  THEN    --检测时钟上升沿

Q <= NOT(Q OR CL);

END IF;

END PROCESS;

OUT1 <= NOT Q;

END ARCHITECTURE  sxdl;

图3-20  RTL图(b)

--解:实现图3-20(b)RTL图的VHDL程序t3_12_b.vhd

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY t3_12_b IS

PORT  (A,B,C,D: IN STD_LOGIC;

Y: OUT STD_LOGIC);

END ENTITY t3_12_b;

ARCHITECTURE  sxdl  OF t3_12_b  IS   ----时序电路sxdl

SIGNAL AB,CD,ABCD : STD_LOGIC;

BEGIN

PROCESS(A,B,C,D,AB,CD,ABCD)

BEGIN

AB<=A AND B;

CD<=C OR D;

ABCD<=AB XOR CD;

CASE AB IS    --类似于真值表的case语句

WHEN '0'  =>  Y  <=  A;

WHEN '1'  =>  Y  <=  ABCD;

WHEN OTHERS  =>NULL  ;

END CASE;

END PROCESS;

END ARCHITECTURE  sxdl;

图3-20  RTL图(c)

--解1:实现图3-20(c) RTL图的VHDL程序mux21a.vhd底层设计描述。

--   用(WHEN_ELSE)实现2选1多路选择器程序(mux21a.vhd)。

LIBRARY  IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY mux21a IS

PORT(a,b :  IN STD_LOGIC;

s :  IN STD_LOGIC;

y : OUT STD_LOGIC);

END ENTITY mux21a;

ARCHITECTURE one OF mux21a IS

BEGIN

y<=a  WHEN s='0' ELSE b;

END ARCHITECTURE one;

--解2:实现图3-20(c)RTL图的VHDL程序DFF6.vhd底层设计描述。

--   电平触发D型触发器程序(DFF6.vhd)

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY DFF6 IS

PORT(CLK: IN STD_LOGIC;

D: IN STD_LOGIC;

Q:OUT STD_LOGIC);

END;

ARCHITECTURE bhv OF DFF6 IS

BEGIN

PROCESS(CLK,D)

BEGIN

IF CLK='1'

THEN Q<=D;

END IF;

END PROCESS;

END bhv;

--解3:实现图3-20(c)RTL图的VHDL程序t3_12_c.vhd顶层设计描述。

LIBRARY  IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY t3_12_c IS

PORT(D1,D2,CLK :  IN STD_LOGIC;

Q : OUT STD_LOGIC);

END ENTITY  t3_12_c;

ARCHITECTURE one OF t3_12_c IS

COMPONENT mux21a    --调用2选1多路选择器声明语句

PORT(a,b :  IN STD_LOGIC;

s :  IN STD_LOGIC;

y : OUT STD_LOGIC);

END COMPONENT;

COMPONENT DFF6      --调用电平型D触发器声明语句

PORT(CLK: IN STD_LOGIC;

D: IN STD_LOGIC;

Q:OUT STD_LOGIC);

END COMPONENT;

SIGNAL DD: STD_LOGIC;  --定义1个信号作为内部的连接线。

BEGIN

u1:  mux21a PORT MAP(CLK,D2,D1,DD);

u2:  DFF6   PORT MAP(CLK,DD,Q);

END ARCHITECTURE one;

图3-20  RTL图(d)

--解1:实现图3-20(d)RTL图的VHDL程序DFF_PRE.vhd底层设计描述

--   带预置、清零和输出使能的D触发器程序(DFF_PRE.vhd)。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY DFF_PRE_CLR_ENA IS

PORT(CLK : IN STD_LOGIC;

D : IN STD_LOGIC;

Q :OUT STD_LOGIC;

ENA : IN STD_LOGIC;

PRE : IN STD_LOGIC;

CLR : IN STD_LOGIC);

END;

ARCHITECTURE bhv OF DFF_PRE_CLR_ENA IS

SIGNAL Q1:STD_LOGIC;  --类似于在芯片内部定义一个数据的暂存节点

BEGIN

PROCESS(CLK,D,Q1,ENA,PRE,CLR)

BEGIN

IF CLR='1' THEN Q1<='0';

ELSIF PRE='1' THEN Q1<='1';

ELSIF CLK'EVENT AND CLK='1' AND ENA='1' THEN Q1<=D;

END IF;

--IF EN='1' THEN Q<=Q1;    --将内部的暂存数据向端口输出

--END IF;

Q<=Q1;    --将内部的暂存数据向端口输出

END PROCESS;

END bhv;

--解2:实现图3-20(d)RTL图的VHDL程序t3_12_d.vhd顶层设计描述

LIBRARY  IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY t3_12_d IS

PORT(SET,D,CLK,EN,RESET :  IN STD_LOGIC;

Q : OUT STD_LOGIC);

END ENTITY  t3_12_d;

ARCHITECTURE one OF t3_12_d IS

COMPONENT DFF_PRE_CLR_ENA      --调用D触发器声明语句

PORT(CLK : IN STD_LOGIC;

D : IN STD_LOGIC;

Q :OUT STD_LOGIC;

ENA : IN STD_LOGIC;

PRE : IN STD_LOGIC;

CLR : IN STD_LOGIC);

END COMPONENT;

SIGNAL SS: STD_LOGIC;  --定义1个信号作为内部的连接线。

BEGIN

SS<=SET AND (NOT RESET);

u1: DFF_PRE_CLR_ENA PORT MAP(CLK,D,Q,EN,SS,RESET);

END ARCHITECTURE one;

图3-20  RTL图(e)

--解1:实现图3-20(e)RTL图的VHDL程序DFF_PRE_CLR.vhd底层设计描述

--  带预置、清零和输出使能的D触发器程序(DFF_PRE_CLR.vhd)

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY DFF_PRE_CLR_ENA IS

PORT(CLK : IN STD_LOGIC;

D : IN STD_LOGIC;

Q :OUT STD_LOGIC;

ENA : IN STD_LOGIC;

PRE : IN STD_LOGIC;

CLR : IN STD_LOGIC);

END;

ARCHITECTURE bhv OF DFF_PRE_CLR_ENA IS

SIGNAL Q1:STD_LOGIC;  --类似于在芯片内部定义一个数据的暂存节点

BEGIN

PROCESS(CLK,D,Q1,ENA,PRE,CLR)

BEGIN

IF CLR='1' THEN Q1<='0';

ELSIF PRE='1' THEN Q1<='1';

ELSIF CLK'EVENT AND CLK='1' AND ENA='1' THEN Q1<=D;

END IF;

--IF EN='1' THEN Q<=Q1;    --将内部的暂存数据向端口输出

--END IF;

Q<=Q1;    --将内部的暂存数据向端口输出

END PROCESS;

END bhv;

--解2:实现图3-20(e)RTL图的VHDL程序t3_12_d.vhd顶层设计描述

LIBRARY  IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY t3_12_e IS

PORT(D,EN,CLK,RST :  IN STD_LOGIC;

Q1,Q : OUT STD_LOGIC);

END ENTITY  t3_12_e;

ARCHITECTURE one OF t3_12_e IS

COMPONENT DFF_PRE_CLR_ENA      --调用D触发器声明语句

PORT(CLK : IN STD_LOGIC;

D : IN STD_LOGIC;

Q :OUT STD_LOGIC;

ENA : IN STD_LOGIC;

PRE : IN STD_LOGIC;

CLR : IN STD_LOGIC);

END COMPONENT;

SIGNAL D_EN: STD_LOGIC;  --定义1个信号作为内部的连接线。

BEGIN

D_EN<=D AND EN;

u1:  DFF_PRE_CLR_ENA PORT MAP(CLK=>CLK,D=>D,Q=>Q,ENA=>EN,PRE=>'0',CLR=>RST);

Q1<=(NOT D_EN) OR RST;

END ARCHITECTURE one;

图3-20  RTL图(f)

--解1:实现图3-20(f)RTL图的VHDL程序mux21a.vhd底层设计描述

--   用WHEN_ELSE实现2选1多路选择器程序(mux21a.vhd)

LIBRARY  IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY mux21a IS

PORT(a,b :  IN STD_LOGIC;

s :  IN STD_LOGIC;

y : OUT STD_LOGIC);

END ENTITY mux21a;

ARCHITECTURE one OF mux21a IS

BEGIN

y<=a  WHEN s='0' ELSE b;

END ARCHITECTURE one;

--解2:实现图3-20(f)RTL图的VHDL程序DFF_PRE_CLR.vhd底层设计描述

--   带预置、清零和输出使能的上升沿D触发器程序(DFF_PRE_CLR.vhd)

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY DFF_PRE_CLR_ENA IS

PORT(CLK : IN STD_LOGIC;

D : IN STD_LOGIC;

Q :OUT STD_LOGIC;

ENA : IN STD_LOGIC;

PRE : IN STD_LOGIC;

CLR : IN STD_LOGIC);

END;

ARCHITECTURE bhv OF DFF_PRE_CLR_ENA IS

SIGNAL Q1:STD_LOGIC;  --类似于在芯片内部定义一个数据的暂存节点

BEGIN

PROCESS(CLK,D,Q1,ENA,PRE,CLR)

BEGIN

IF CLR='1' THEN Q1<='0';

ELSIF PRE='1' THEN Q1<='1';

ELSIF CLK'EVENT AND CLK='1' AND ENA='1' THEN Q1<=D;

END IF;

--IF EN='1' THEN Q<=Q1;    --将内部的暂存数据向端口输出

--END IF;

Q<=Q1;    --将内部的暂存数据向端口输出

END PROCESS;

END bhv;

--解3:实现图3-20(f)RTL图的VHDL程序t3_12_d.vhd顶层设计描述

LIBRARY  IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY t3_12_f IS

PORT(RST,D,CLK :  IN STD_LOGIC;

Q,DOUT : OUT STD_LOGIC);

END ENTITY  t3_12_f;

ARCHITECTURE one OF t3_12_f IS

COMPONENT DFF_PRE_CLR_ENA      --调用D触发器声明语句

PORT(CLK : IN STD_LOGIC;

D : IN STD_LOGIC;

Q :OUT STD_LOGIC;

ENA : IN STD_LOGIC;

PRE : IN STD_LOGIC;

CLR : IN STD_LOGIC);

END COMPONENT;

COMPONENT mux21a      --调用D触发器声明语句

PORT(a,b :  IN STD_LOGIC;

s :  IN STD_LOGIC;

y : OUT STD_LOGIC);

END COMPONENT;

SIGNAL DD,DDD: STD_LOGIC;  --定义1个信号作为内部的连接线。

BEGIN

u1:  mux21a PORT MAP(D,'0',RST,DD);

DDD<=D XOR DD;

u2:  DFF_PRE_CLR_ENA PORT MAP(CLK,DDD,DOUT,'1','0','0');

u3:  DFF_PRE_CLR_ENA PORT MAP(CLK,DD,Q,'1','0','0');

END ARCHITECTURE one;

第四章

5-1 归纳利用Quartus II进行VHDL文本输入设计的流程:从文件输入一直到SignalTap II测试。P95~P115

答:1  建立工作库文件夹和编辑设计文件;2  创建工程;3  编译前设置;4  全程编译;5  时序仿真;6  引脚锁定;7  配置文件下载;8  打开SignalTap II编辑窗口;9  调入SignalTap II的待测信号;10  SignalTap II参数设置;11  SignalTap II参数设置文件存盘;12  带有SignalTap II测试信息的编译下载;13  启动SignalTap II进行采样与分析;14  SignalTap II的其他设置和控制方法。

5.6

5.7

5.8

5.9

5.10

5.12

5.13

5.14

第五章

6-1 什么是固有延时?什么是惯性延时?P150~151

答:固有延时(Inertial Delay)也称为惯性延时,固有延时的主要物理机制是分布电容效应。

6-2 δ是什么?在VHDL中,δ有什么用处?P152

δ是什么? 答:在VHDL仿真和综合器中,默认的固有延时量(它在数学上是一个无穷小量),被称为δ延时。

在VHDL中,δ有什么用处?答:在VHDL信号赋值中未给出固有延时情况下,VHDL仿真器和综合器将自动为系统中的信号赋值配置一足够小而又能满足逻辑排序的延时量δ;使并行语句和顺序语句中的并列赋值逻辑得以正确执行。

6-4 说明信号和变量的功能特点,以及应用上的异同点。P128~P129

答:变量:变量是一个局部量,只能在进程和子程序中使用。变量不能将信息带出对它做出定义的当前结构。变量的赋值是一种理想化的数据传输,是立即发生的,不存在任何延时行为。变量的主要作用是在进程中作为临时的数据存储单元。

信号:信号是描述硬件系统的基本数据对象,其性质类似于连接线;可作为设计实体中并行语句模块间的信息交流通道。信号不但可以容纳当前值,也可以保持历史值;与触发器的记忆功能有很好的对应关系。

6-5 在VHDL设计中,给时序电路清零(复位)有两种力方法,它们是什么?

解:设Q定义成信号,一种方法:Q<=“000…000”; 其中“000…000”反映出信号Q的位宽度。第二种方法:Q<=(OTHERS=>‘0’);其中OTHERS=>‘0’不需要给出信号Q的位宽度,即可对Q清零。

6-6 哪一种复位方法必须将复位信号放在敏感信号表中?给出这两种电路的VHDL描述。

解:边沿触发复位信号要将复位信号放在进程的敏感信号表中。

(1)边沿触发复位信号

…………………….

ARCHITECTURE bhv 0F DFF3 IS

SIGNAL QQ:STD_LOGIC;

BEGIN

PROCESS(RST)

BEGIN

IF  RST’EVENT AND RST=‘1'  THEN

QQ<=(Others=>‘0’);

END IF;

END PROCESS;

Q1<=QQ;

END;

………………………

(2)电平触发复位信号

…………………….

ARCHITECTURE bhv 0F DFF3 IS

SIGNAL QQ:STD_LOGIC;

BEGIN

PROCESS(CLK)

BEGIN

IF RST=‘1' THEN

QQ<=(Others=>‘0’);

END IF;

END PROCESS;

Q1<=QQ;

END;

………………………

6-7 什么是重载函数?重载算符有何用处?如何调用重载算符函数?

答:(1)什么是重载函数? 根据操作对象变换处理功能。

(2)重载算符有何用处? 用于两个不同类型的操作数据自动转换成同种数据类型,并进行运算处理。

(3)如何调用重载算符函数?采用隐式方式调用,无需事先声明。

6-8 判断下面三个程序中是否有错误,若有则指出错误所在,并给出完整程序。

程序1:

Signal A,EN : std_logic;

…………………

Process(A, EN)

Variable B: std_log ic;

Begin

if EN=l then  B<=A;  end if;   --将“B<=A”改成“B:=A”

end process;

程序2:

Architecture one of sample is

variable a,b,c:integer;

begin

c<=a+b;   --将“c<=a+b”改成“c:=a+b”

end;

程序3:

library ieee;

use ieee.std_logic_1164.all;

entity mux21 is

PORT(a,b:in std_logic; sel:in std_loglc;c:out std_logle;);    --将“;)”改成“)”

end sam2;      --将“sam2”改成“entity mux21”

architecture one of mux2l is

begin

--增加“process(a,b,sel) begin”

if sel= '0' then c:=a; else c:=b; end if;  --应改成“if sel= '0' then c<=a; else c<=b; end if;”

--增加“end process;”

end two;      --将“two”改成“architecture one”

7-2 LPM_ROM、LPM_RAM、LPM_FIFO等模块与FPGA中嵌入的EAB、ESB、M4K有怎样的联系?

答:ACEXlK系列为EAB;APEX20K系列为ESB;Cyclone系列为M4K

7  习    题

7-1  根据图7-30(a)所示的状态图,分别按照图7-30(b)和图7-30(c)写出对应结构的VHDL状态机。并根据表7-2,分别用三种不同编码方式实现二状态机,并讨论它们的容错措施。

图7-30 习题7-1状态图

--    解:根据图7-30(a)所示的状态图,按照图7-30(b)单进程状态机端口形式,编写的VHDL程序代码如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY state_8_16_a_b IS

PORT(  ina: IN STD_LOGIC_VECTOR(2 DOWNTO 0);

CLK,RESET: IN STD_LOGIC;

outa:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));

END ENTITY state_8_16_a_b;

ARCHITECTURE behav OF state_8_16_a_b IS

TYPE ST_TYPE IS(S0,S1,S2,S3);

SIGNAL C_ST: ST_TYPE;

BEGIN

FSM: PROCESS(CLK,RESET)

BEGIN

IF RESET='1' THEN C_ST<=S0;

ELSIF CLK'EVENT AND CLK='1' THEN

CASE C_ST IS

WHEN S0=> C_ST<=S1;

IF    ina="101" THEN outa<="0010";

ELSIF ina="111" THEN outa<="1100";

END IF;

WHEN S1=> IF ina="110" THEN C_ST<=S2;

ELSE              C_ST<=S1;

END IF;

outa<="1001";

WHEN S2=> IF    ina="011" THEN C_ST<=S1;

ELSIF ina="100" THEN C_ST<=S3;

ELSE C_ST<=S2;

END IF;

outa<="1111";

WHEN S3=> C_ST<=S0;

IF    ina="101" THEN outa<="1101";

ELSIF ina="011" THEN outa<="1110";

ELSE                 outa<="1111";

END IF;

WHEN OTHERS=>C_ST<=S0;

END CASE;

END IF;

END PROCESS FSM;

END ARCHITECTURE behav;

--    解:根据图7-30(a)所示的状态图,按照图7-30(c)双进程状态机端口形式,编写的VHDL程序代码如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY state_8_16_a_c IS

PORT(  ina: IN STD_LOGIC_VECTOR(2 DOWNTO 0);

CLK,RESET: IN STD_LOGIC;

outa:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));

END state_8_16_a_c;

ARCHITECTURE behav OF state_8_16_a_c IS

TYPE ST_TYPE IS (S0,S1,S2,S3);

SIGNAL C_ST,N_ST: ST_TYPE;

BEGIN

REG: PROCESS(CLK,RESET)         --主控时序进程

BEGIN

IF RESET='1' THEN C_ST<=S0;    --检测异步复位信号

ELSIF CLK='1' AND CLK'EVENT THEN

C_ST<=N_ST;

END IF;

END PROCESS REG;

COM: PROCESS(C_ST,ina)         --主控组合进程

BEGIN

CASE C_ST IS

WHEN S0=> N_ST<=S1;

IF    ina="101" THEN outa<="0010";

ELSIF ina="111" THEN outa<="1100";

--ELSE  outa<="1111";--不加此句,产生所存不安全

END IF;

WHEN S1=> IF ina="110" THEN N_ST<=S2;

ELSE              N_ST<=S1;

END IF;

outa<="1001";

WHEN S2=> IF    ina="011" THEN N_ST<=S1;

ELSIF ina="100" THEN N_ST<=S3;

ELSE                 N_ST<=S2;

END IF;

outa<="1111";

WHEN S3=> N_ST<=S0;

IF    ina="101" THEN outa<="1101";

ELSIF ina="011" THEN outa<="1110";

ELSE                 outa<="1111";

END IF;

WHEN OTHERS=>N_ST<=S0;

END CASE;

END PROCESS COM;

END ARCHITECTURE behav;

7-2  举二例说明,有哪些常用时序电路是状态机比较典型的特殊形式,并说明它们属于什么类型的状态机(编码类型、时序类型和结构类型)。

解:1)计数器、循环移位寄存器。

2)计数器:Moore型状态机;顺序编码;状态编码直接输出。

3)循环移位寄存器:Moore型状态机;一位热码;状态编码直接输出。

7-3  用Mealy机类型,写出控制ADC0809采样的状态机。

--  解:7-3 根据图7-5状态图,采用Mealy型状态机,设计ADC0809采样控制器。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY ADC0809 IS

PORT(D: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --来自0809转换好的8位数据

CLK: IN STD_LOGIC;    --状态机工作时钟

RST: IN STD_LOGIC;    --系统复位控制

EOC: IN STD_LOGIC;    --转换状态指示,低电平表示正在转换

ALE:OUT STD_LOGIC;    --8个模拟信号通道地址锁存信号

START:OUT STD_LOGIC;    --转换开始信号

OE:OUT STD_LOGIC;    --数据输出三态控制信号

ADDA:OUT STD_LOGIC;    --信号通道最低位控制信号

LOCK_T:OUT STD_LOGIC;    --观察数据锁存时钟

Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));  --8位数据输出

END ADC0809;

ARCHITECTURE behav OF ADC0809 IS

TYPE states IS(s0,s1,S2,s3,s4); --定义各状态子类型

SIGNAL cs,next_state: states:=s0;

SIGNAL REGL: STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL LOCK: STD_LOGIC;--转换后数据输出锁存时钟信号

BEGIN

ADDA<='1';--当ADDA<='0',选择模拟信号通道IN0;当ADDA<='1',则选择通道IN1

LOCK_T<=LOCK;

COM: PROCESS(cs,EOC) BEGIN   --规定各状态转换方式

CASE cs IS

WHEN s0=> ALE<='0';START<='0';LOCK<='0';OE<='0';

next_state<=s1;  --0809初始化

WHEN s1=> ALE<='1';START<='1';LOCK<='0';OE<='0';

next_state<=s2 ;--启动采样

WHEN s2=> ALE<='0';START<='0';LOCK<='0';

IF(EOC='1') THEN next_state<=s3;OE<='1';--EOC=1转换结束,OE=1(Mealy型)

ELSE next_state<=s2;OE<='0'; END IF;    --未结束等待,OE=0(Mealy型)

WHEN s3=> ALE<='0';START<='0';LOCK<='0';OE<='1';

next_state<=s4;--开启OE,输出转换好的数据

WHEN s4=> ALE<='0';START<='0';LOCK<='1';OE<='1';next_state<=s0;

WHEN OTHERS=>next_state<=s0;

END CASE;

END PROCESS COM;

REG:PROCESS(CLK,RST)

BEGIN

IF(RST='1') THEN cs<=next_state;

ELSIF(CLK'EVENT AND CLK='1') THEN cs<=next_state;

END IF;

END PROCESS REG;    --由信号cs将当前状态值带出此进程:REG

LATCH1: PROCESS(LOCK) --此进程中,在LOCK的上升沿,将转换好的数据锁入

BEGIN

IF LOCK='1' AND LOCK'EVENT THEN REGL<=D; END IF;

END PROCESS LATCH1;

Q<=REGL;

END behav;

7-4  请设计一种信号去抖动的电路模型,仿真后,讨论其优缺点点和使用范围。

解:R-S触发器去抖动电路,优点:电路简单,适用于宽延时范围抖动;缺点:对输入按键采用单刀双掷开关。

7-5  根据7.5节,用表格法和绘图法设计状态机,实现例7-2的功能,用时序仿真波形图验证之。最后将其转变成VHDL程序,将此程序与例7-2相比,讨沦它们的表述风格。

解:

第八章

8-1仿照例8-1,将例8-4单进程用两个进程,即一个时序进程,一个组合进程表达出来。

--解:【例8-4】的改写如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY MOORE1 IS

PORT(DATAIN: IN STD_LOGIC_VECTOR(1 DOWNTO 0);

CLK,RST: IN STD_LOGIC;

Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));

END MOORE1;

ARCHITECTURE behav OF MOORE1 IS

TYPE ST_TYPE IS (ST0,ST1,ST2,ST3,ST4);

SIGNAL C_ST,N_ST: ST_TYPE;

BEGIN

REG: PROCESS(CLK,RST)

BEGIN

IF RST='1' THEN C_ST<=ST0;    -- Q<="0000";

ELSIF CLK'EVENT AND CLK='1' THEN

C_ST<=N_ST;

END IF;

END PROCESS REG;

COM: PROCESS(C_ST,DATAIN)

BEGIN

CASE C_ST IS

WHEN ST0=> IF DATAIN="10" THEN N_ST<=ST1;

ELSE N_ST<=ST0; END IF;

Q<="1001";

WHEN ST1=> IF DATAIN="11" THEN N_ST<=ST2;

ELSE N_ST<=ST1 ;END IF;

Q<="0101";

WHEN ST2=> IF DATAIN="01" THEN N_ST<=ST3;

ELSE N_ST<=ST0 ;END IF;

Q<="1100";

WHEN ST3=> IF DATAIN="00" THEN N_ST<=ST4;

ELSE N_ST<=ST2; END IF;

Q<="0010";

WHEN ST4=>IF DATAIN="11" THEN N_ST<=ST0;

ELSE N_ST<=ST3 ;END IF;

Q<="1001"  ;

WHEN OTHERS=> N_ST<=ST0;

END CASE;

END PROCESS COM;

END behav;

8-2为确保例8-5(2进程Mealy型状态机)的状态机输出信号没有毛刺,试用例8-4的方式构成一个单进程状态,使输出信号得到可靠锁存,在相同输入信号条件下,给出两程序的仿真波形。

--解:【例8-5】改写如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY MEALY1  IS

PORT(CLK,DATAIN,RESET: IN STD_LOGIC;

Q:OUT STD_LOGIC_VECTOR(4 DOWNTO 0));

END MEALY1;

ARCHITECTURE behav OF MEALY1 IS

TYPE states IS (st0,st1,st2,st3,st4);

SIGNAL  STX: states;

BEGIN

PROCESS(CLK,RESET)        --单一进程

BEGIN

IF RESET='1' THEN STX<=ST0;

ELSIF CLK'EVENT AND CLK='1' THEN

CASE STX IS

WHEN st0=> IF DATAIN='1' THEN STX<=st1; END IF;

IF DATAIN='1' THEN Q<="10000";

ELSE               Q<="01010" ; END IF;

WHEN st1=> IF DATAIN='0' THEN STX<=st2; END IF;

IF DATAIN='0' THEN Q<="10111";

ELSE               Q<="10100" ; END IF;

WHEN st2=> IF DATAIN='1' THEN STX<=st3; END IF;

IF DATAIN='1' THEN Q<="10101";

ELSE               Q<="10011" ; END IF;

WHEN st3=> IF DATAIN='0' THEN STX<=st4; END IF;

IF DATAIN='0' THEN Q<="11011";

ELSE               Q<="01001"; END IF ;

WHEN st4=> IF DATAIN='1' THEN STX<=st0; END IF;

IF DATAIN='1' THEN Q<="11101";

ELSE               Q<="01101"; END IF;

WHEN OTHERS=> STX<=st0; Q<="00000";

END CASE;

END IF;

END PROCESS;

END behav;

图8-6控制ADC0809采样状态图

--  【例8-2】根据图8-6状态图,采用Moore型状态机,设计ADC0809采样控制器。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY ADCINT IS

PORT(D: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --来自0809转换好的8位数据

CLK: IN STD_LOGIC;    --状态机工作时钟

EOC: IN STD_LOGIC;    --转换状态指示,低电平表示正在转换

ALE:OUT STD_LOGIC;    --8个模拟信号通道地址锁存信号

START:OUT STD_LOGIC;    --转换开始信号

OE:OUT STD_LOGIC;    --数据输出三态控制信号

ADDA:OUT STD_LOGIC;    --信号通道最低位控制信号

LOCK0:OUT STD_LOGIC;    --观察数据锁存时钟

Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));  --8位数据输出

END ADCINT;

ARCHITECTURE behav OF ADCINT IS

TYPE states IS(st0,st1,St2,st3,st4); --定义各状态子类型

SIGNAL current_state,next_state: states:=st0;

SIGNAL REGL: STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL LOCK: STD_LOGIC;--转换后数据输出锁存时钟信号

BEGIN

ADDA<='1';--当ADDA<='0',模拟信号进入通道IN0;当ADDA<='1',则进入通道INI

Q<=REGL;LOCK0<=LOCK;

COM: PROCESS(current_state,EOC) BEGIN   --规定各状态转换方式

CASE current_state IS

WHEN st0=> ALE<='0';START<='0';LOCK<='0';OE<='0';

next_state<=st1;  --0809初始化

WHEN st1=> ALE<='1';START<='1';LOCK<='0';OE<='0';

next_state<=st2 ;--启动采样

WHEN st2=> ALE<='0';START<='0';LOCK<='0'; OE<='0';

IF(EOC='1') THEN next_state<=st3;--EOC=1表明转换结束

ELSE next_state<=st2; END IF;    --转换未结束,继续等待

WHEN st3=> ALE<='0';START<='0';LOCK<='0';OE<='1';

next_state<=st4;--开启OE,输出转换好的数据

WHEN st4=> ALE<='0';START<='0';LOCK<='1';OE<='1';next_state<=st0;

WHEN OTHERS=>next_state<=st0;

END CASE;

END PROCESS COM;

REG:PROCESS(CLK)

BEGIN

IF(CLK'EVENT AND CLK='1') THEN current_state<=next_state; END IF;

END PROCESS REG;    --由信号current_state将当前状态值带出此进程:REG

LATCH1: PROCESS(LOCK) --此进程中,在LOCK的上升沿,将转换好的数据锁入

BEGIN

IF LOCK='1' AND LOCK'EVENT THEN REGL<=D; END IF;

END PROCESS LATCH1;

END behav;

8-5在不改变原代码功能的条件下用两种方法改写例8-2,使其输出的控制信号(ALE、START、OE、LOCK)没有毛刺。方法1:将输出信号锁存后输出;方法2:使用状态码直接输出型状态机,并比较这三种状态机的特点。

--    解:"【例8-2】根据图8-6状态图,采用Moore型状态机,设计ADC0809采样控制器" 方法1(将输出控制信号锁存后输出)的VHDL程序代码如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY ADCINT IS

PORT(D:  IN STD_LOGIC_VECTOR(7 DOWNTO 0); --来自0809转换好的8位数据

CLK:  IN STD_LOGIC;    --状态机工作时钟

EOC:  IN STD_LOGIC;    --转换状态指示,低电平表示正在转换

ALE: OUT STD_LOGIC;    --8个模拟信号通道地址锁存信号

START: OUT STD_LOGIC;    --转换开始信号

OE: OUT STD_LOGIC;    --数据输出三态控制信号

ADDA: OUT STD_LOGIC;    --信号通道最低位控制信号

LOCK0: OUT STD_LOGIC;    --观察数据锁存时钟

Q: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));  --8位数据输出

END ADCINT;

ARCHITECTURE behav OF ADCINT IS

TYPE states IS(st0,st1,St2,st3,st4);  --定义各状态子类型

SIGNAL current_state,next_state: states:=st0;

SIGNAL REGL: STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL LOCK: STD_LOGIC;--转换后数据输出锁存时钟信号

SIGNAL   ALE0: STD_LOGIC;    --8个模拟信号通道地址锁存信号

SIGNAL START0: STD_LOGIC;    --转换开始信号

SIGNAL    OE0: STD_LOGIC;    --数据输出三态控制信号

BEGIN

ADDA<='1';--当ADDA<='0',模拟信号进入通道IN0;当ADDA<='1',则进入通道INI

Q<=REGL;              --LOCK0<=LOCK;

COM: PROCESS(current_state,EOC,CLK) BEGIN   --规定各状态转换方式

CASE current_state IS

WHEN st0=> ALE0<='0';START0<='0';LOCK<='0';OE0<='0';

next_state<=st1;  --0809初始化

WHEN st1=> ALE0<='1';START0<='1';LOCK<='0';OE0<='0';

next_state<=st2 ;--启动采样

WHEN st2=> ALE0<='0';START0<='0';LOCK<='0'; OE0<='0';

IF(EOC='1') THEN next_state<=st3;--EOC=1表明转换结束

ELSE next_state<=st2; END IF;    --转换未结束,继续等待

WHEN st3=> ALE0<='0';START0<='0';LOCK<='0';OE0<='1';

next_state<=st4;--开启OE,输出转换好的数据

WHEN st4=> ALE0<='0';START0<='0';LOCK<='1';OE0<='1';next_state<=st0;

WHEN OTHERS=>next_state<=st0;

END CASE;

IF CLK'EVENT AND CLK= '1' THEN

ALE<=ALE0;START<=START0;LOCK0<=LOCK;OE<=OE0;--方法1:信号锁存后输出

END IF;

END PROCESS COM;

REG:PROCESS(CLK)

BEGIN

IF(CLK'EVENT AND CLK='1') THEN current_state<=next_state; END IF;

END PROCESS REG;    --由信号current_state将当前状态值带出此进程:REG

LATCH1: PROCESS(LOCK) --此进程中,在LOCK的上升沿,将转换好的数据锁入

BEGIN

IF LOCK='1' AND LOCK'EVENT THEN REGL<=D; END IF;

END PROCESS LATCH1;

END behav;

--    解:"【例8-2】根据图8-6状态图,采用Moore型状态机,设计ADC0809采样控制器" 方法2(使用状态码直接输出型状态机)的VHDL程序代码(【例8-7】的根据状态编码表8-1给出ADC0809数据采样的状态机)如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY AD0809 IS

PORT(            D: IN STD_LOGIC_VECTOR(7 DOWNTO 0);

CLK,EOC: IN STD_LOGIC;

ALE,START,OE,ADDA:OUT STD_LOGIC;

c_state:OUT STD_LOGIC_VECTOR(4 DOWNTO 0);

Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END AD0809;

ARCHITECTURE behav OF AD0809 IS

SIGNAL  current_state,next_state: STD_LOGIC_VECTOR(4 DOWNTO 0);

CONSTANT st0: STD_LOGIC_VECTOR(4 DOWNTO 0):="00000";

CONSTANT st1: STD_LOGIC_VECTOR(4 DOWNTO 0):="11000";

CONSTANT st2: STD_LOGIC_VECTOR(4 DOWNTO 0):="00001";

CONSTANT st3: STD_LOGIC_VECTOR(4 DOWNTO 0):="00100";

CONSTANT st4: STD_LOGIC_VECTOR(4 DOWNTO 0):="00110";

SIGNAL  REGL: STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL  LOCK: STD_LOGIC;

BEGIN

ADDA<='1';Q<=REGL;START<=current_state(4);ALE<=current_state(3);

OE<=current_state(2);LOCK<=current_state(1);c_state<=current_state;

COM: PROCESS(current_state,EOC) BEGIN  --规定各状态转换方式

CASE current_state IS

WHEN st0=> next_state<=st1;  --0809初始化

WHEN st1=> next_state<=st2;  --启动采样

WHEN st2=> IF(EOC='1') THEN next_state<=st3;  --EOC=1表明转换结束

ELSE next_state<=st2;    --转换未结束,继续等待

END IF;

WHEN st3=> next_state<=st4;    --开启OE,输出转换好的数据

WHEN st4=> next_state<=st0;

WHEN OTHERS=> next_state<=st0;

END CASE;

END PROCESS COM;

REG: PROCESS(CLK)

BEGIN

IF (CLK'EVENT AND CLK='1') THEN current_state<=next_state;

END IF;

END PROCESS REG;    --由信号current_state将当前状态值带出此进程:REG

LATCH1: PROCESS(LOCK)--此进程中,在LOCK的上升沿,将转换好的数据锁入

BEGIN

IF LOCK='1' AND LOCK'EVENT THEN REGL<=D;

END IF;

END PROCESS LATCH1;

END behav;

EDA技术课后题答案相关推荐

  1. 未来教育计算机三级课后题答案,全国计算机三级网络技术课后题答案(2016.3 未来教育).docx...

    三级网络技术课后总复习参考答案 第1章 一.选择题 1-5 :CDBBB 6-10:BDABB 第2章 一.选择题 1-5:DCACD 6-10:ADCBB 第3章 一.选择题 1-5:CBCAC 6 ...

  2. 单边指数信号的特点_测试技术课后题答案1信号描述

    双边指数函数的傅里叶变换 , 双边指数函数的波形如图所示 , 其数学表达式为 0 t 题图 1-2 双边指数函数 解: x t ( ) 是一个非周期信号,它的傅里叶变换即为其频谱密度函数,按定义式求解 ...

  3. 电大计算机dm编写程序,电大数控编程技术课后习题答案.doc

    文档介绍: 电大数控编程技术课后****题答案 第一章数控加工的编程基础课后****题答案 一.填空题 1.为了准确地判断数控机床的运动方向,特规定永远假设***相对于(静止的工件)坐标而运动. 2. ...

  4. 西安电子科技大学计算机网络技术,计算机网络技术与应用课后题答案(西安电子科技大学).doc...

    计算机网络技术与应用课后题答案(西安电子科技大学) <计算机网络应用基础>试题(1) 题目 项目 第一大题 第二大题 第三大题 第四大题 总 分 得 分 评卷人 一.填空题(每空1分,共2 ...

  5. 大数据技术原理与应用—课后题答案(第一章)

    大数据技术原理与应用_林子雨版_课后题答案(第一章) 1.试述信息技术发展史上的3次信息化浪潮及具体内容. 信息化浪潮 发生时间 标志  解决问题                           ...

  6. 大学计算机西安电子科技大学答案,计算机网络技术与应用课后题答案(西安电子科技大学)...

    计算机网络技术与应用课后题答案(西安电子科技大学) <计算机网络应用基础>试题(1) 一.填空题(每空1分,共24分,答案写在横线上) 1.按逻辑组成划分,计算机网络是由和两部分组成的. ...

  7. 汇编语言与接口技术(第4版)清华大学出版社 第2章 80*86微处理器 课后题答案

    汇编语言与接口技术(第4版)清华大学出版社 第2章 80*86微处理器 课后题答案 1. 8086/8088 CPU的地址总线有多少位?其寻址范围是多少? 20位,最大可寻址1MB空间 2. 8086 ...

  8. 清华计算机接口原理,微机原理与接口技术课后习题答案清华大学

    微机原理与接口技术课后习题答案清华大学 微机原理与接口技术课后部分习题参考答案 第一章 2. 第 3项任务,根据状态标志位的状态决定转移方向. 3. 程序存储是将要执行的程序的全部指令存储到存储器中, ...

  9. 微型计算机周明德课后答案,微机原理(周明德)课后题答案..doc

    微机原理(周明德)课后题答案. 第1章 作 业 答 案 1.1 微处理器.微型计算机和微型计算机系统三者之间有什么不同? 解: 把CPU(运算器和控制器)用大规模集成电路技术做在一个芯片上,即为微 处 ...

最新文章

  1. 淘宝装修:第一日 —— 图片轮播
  2. 【Joomla】TinyMCE - Add custom styles
  3. java如何构造ajax回调参数,jQuery实现ajax回调函数带入参数的方法示例
  4. 一个不错的CSS DIV布局,DIV高度自适应
  5. 成功解决xgboost\core.py, ValueError: feature_names may not contain [, ] or
  6. boost::core::typeinfo的用法实例
  7. jakob slam_Jakob Nielsen针对用户界面设计的第二种可用性启发法
  8. LeetCode算法入门- Longest Substring Without Repeating Characters-day4
  9. Incorrect string value: '/xE7/xA8/x8B/xE5/xBA/x8F...' for column 'course' at row 1
  10. 前端开发课件 202002
  11. Unity3D之Json序列化
  12. Linux-nmap命令使用
  13. 安装opencv_contrib-3.4.9, fatal error: opencv2/xfeatures2d.hpp: 没有那个文件或目录. 解决方法
  14. js实现代码高亮显示
  15. 开通支付宝小程序收款功能
  16. 学霸是怎样炼成的(大一上篇)
  17. 2010年Ei收录的中国期刊
  18. GMap.NET入门详细教程【2】-------- 初始化并加载一张地图
  19. IDEA添加快捷注释功能
  20. RuntimeError: Attempting to deserialize object on a CUDA device but torch.cuda.is_available() is

热门文章

  1. 客家刘开七、刘广传刘氏七律族诗赏析V2.0
  2. MTKl 屏的时钟频率计算
  3. 移动应用性能测试工具—PerfDog
  4. c语言作业i love gplt,集思广益 | 寒假天梯赛准备第一阶段总结
  5. 办公软件有哪些,新装电脑常用的办公软件
  6. Study Flex《强引用与弱引用》
  7. unity 3D炫酷开场动画
  8. 对话搜狗陈伟,揭秘搜狗AI合成主播背后的前沿技术
  9. 高仿APP——元贝驾考(三)ListView多ItemView
  10. android App内监听截图加二维码