VHDL程序设计教程
习题参考解答
第1章思考题解答`
``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
1. 什么是VHDL?简述VHDL的发展史。
答: VHDL是美国国防部为电子项目设计承包商提供的,签定合同使用的,电子系统硬件描述语言。1983年成立VHDL语言开发组,1987年推广实施,1993年扩充改版。VHDL是IEEE标准语言,广泛用于数字集成电路逻辑设计。
2. 简述VHDL设计实体的结构。
答:实体由实体名、类型表、端口表、实体说明部分和实体语句部分组成。根据IEEE标准,实体组织的一般格式为:
ENTITY 实体名 IS
[GENERIC(类型表);] --可选项
[PORT(端口表);] --必需项
1
实体说明部分; --可选项
[BEGIN
实体语句部分;]
END [ENTITY] [实体名];
3. 分别用结构体的3种描述法设计一个4位计数器。
答: 用行为描述方法设计一个4位计数器如下,其它描述方法,读者可自行设计。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
ENTITY countA IS
PORT (clk,clr,en:IN STD_LOGIC;
Qa,qb,qc,qd:OUT STD_LOGIC);
END countA;
2
ARCHITECTURE example OF countA IS
SIGNAL count_4:STD_LOGIC_vector (3 DOWNTO 0);
BEGIN
Qa <= count_4(0);
Qb <= count_4(1);
Qc <= count_4(2);
Qd <= count_4(3);
PROCESS (clk,clr)
BEGIN
IF (clr = '1' ) THEN
Count_4 <= \"0000\";
ELSIF (clk'EVENT AND clk = '1' ) THEN
IF (en = '1' ) THEN
3
IF (count_4 = \"1111\") THEN
count_4 <= \"0000\";
ELSE
count_4 <= count_4+ '1';
END IF;
END IF;
END IF;
END PROCESS;
END example;
第2章 思考题解答
1. 什么叫对象?对象有哪几个类型?
答:在VHDL语言中,凡是可以赋于一个值的客体叫对象(object)。VHDL对象包含有专门数据类型,主要有4个基本类型:常量(CONSTANT)、信号(SIGNAL)、变量(VARIABLE)和文件(FILES)。
4
2. VHDL语言定义的标准类型有哪些?
答 VHDL语言标准所定义的标准数据类型
(1) 整数类型(INTEGER TYPE)
(2) 实数类型或浮点类型(REAL TYPE & FLOATING TYPE)
(3) 位类型(BIT TYPE)
(4) 位矢量类型(BIT_VECTOR TYPE)
(5) 布尔类型(BOOLEAN TYPE)
(6) 字符类型(CHARACTER TYPE)
(7) 时间类型或物理类型(TIME TYPE & PHYSICAL TYPE)
(8) 错误类型(NOTE,WARNIING,ERROR,FAILURE TYPE)
(9) 自然数、整数类型(NATURAL TYPE)
(10) 字符串类型(TRING TYPE)
3. 简述VHDL语言操作符的优先级。
5
答: 在表2.1中,取反和取绝对值优先级较高,与、或逻辑运算的优先级低于算术运算的优先级。
4. 哪3种方法可用来进行类型转换?
答:进行不同类型的数据变换,有3种方法:类型标记法、函数转换法和常数转换法。
第3章思考题解答
1. 什么叫进程?简述进程的工作方式。
答:进程(process)是由外部信号触发执行的一段程序。进程语句是并行处理语句,即各个进程是同时处理的,在结构体中多个Process语句是同时并发运行的。在进程内部是顺序执行的。Process语句在VHDL程序中,是描述硬件并行工作行为的最常用、最基本的语句。
进程Process语句中一般带有几个信号量例表,称为该进程的敏感量表。这些信号无论哪一个发生变化都将启动Process进程。一旦启动,进程Process中的程序将从上到下顺序执行一遍,由新变化的量引导进程产生变化结果输出。当进程的最后一个语句执行完成后,就返回到进程开始处,等待敏感量的新变化,引发进程的再一次执行。周而复始,循环往复,以至无穷。这就是进程的执行过程。
2. 什么叫模块?区分模块与进程。
答:模块(Block)语句是结构体中积木化设计语言,适用于复杂项目设计。
6
Block块是一个独立的子结构,可以包含PORT语句、GENERIC语句,允许设计者通过这两个语句将Block块内的信号变化传递给Block块的外部信号。同样,也可以将Block块的外部信号变化传递给Block块的内部信号。
对VHDL语言中的Block模块进行仿真时,Block模块中所描述的各个语句是可以并发执行的,和模块中的语句书写顺序无关。进程语句是一段程序,这段程序是顺序执行的。
3. 用结构描述法和GENERATE语句设计一个8位移位寄存器。
答:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY shift_register IS
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END ENTITY shift_regester;
ARCHITECTURE eight_BIT_shift_register OF shift_register IS
COMPONENT dff
-- dff元件调用
7
PORT(a,Clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT;
SIGNAL X: STD_LOGIC_VECTOR(0 TO 4);
BEGIN
X(0) <= a;
dff1:dff PORT MAP (X(0),clk,Z(1));
dff2:dff PORT MAP (X(1),clk,Z(2));
dff3:dff PORT MAP (X(2),clk,Z(3));
dff4:dff PORT MAP (X(3),CLK,Z(4));
dff5:dff PORT MAP (X(4),CLK,Z(5));
dff6:dff PORT MAP (X(5),CLK,Z(6));
dff7:dff PORT MAP (X(6),CLK,Z(7));
8
dff4:dff PORT MAP (X(7),CLK,Z(8));
B<=X(8);
END ARCHITECTURE eight_bit_shift_register;
4. 设计一个3-8优先级编码器。
答:参考书中第5章编码器设计。
5. 设计一个4-16译码器。
答:参考书中第5章译码器设计。
第4章思考题解答
1. 配置语句的书写格式是怎样的?
答:配置语句的书写形式为:
CONFIGURAT10N 配置名 OF 实体名 IS
FOR 选配构造体名
END FOR;
9
END 配置名;
2. 配置说明中的映射有哪两种方法?
答:位置关联法和名称关联法。
3. 在配置语句中用GENERIC 指定参数,设计一个译码器。
答:LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY decode IS
PORT(a,b,en : IN std_logic;
Q0,q1,q2,q3: OUT std_logic);
END decode;
ARCHITECTURE structural OF decode IS
COMPONENT inv
PORT(a : IN std_logic;
10
b : OUT std_logic);
END COMPONENT;
COMPONENT and3
PORT(a1,a2,a3 : IN std_logic;
O1: OUT std_logic);
END COMPONENT;
SIGNAL nota,notb : std_logic;
BEGIN
I1 : inv
PORT MAP(a,nota);
I2 : inv
PORT MAP(b,notb);
AN1 : and3
11
PORT MAP(nota,en,notb,q0);
AN2 : and3
PORT MAP(a,en,notb,q1);
AN3 : and3
PORT MAP(nota,en,b,q2);
AN4 : and3
PORT MAP(a,en,b,q3);
END structural;
-------------------------------------------
CONFIGURATION decode_gen1_con OF decode IS
FOR structural
FOR I1 : inv USE ENTITY WORK.inv(inv_gen1)
GENERIC MAP(int_rise => 1.2 ns,
12
Int_fall => 1.7 ns,
Ext_rise => 2.6 ns,
Ext_fall => 2.5 ns);
END FOR;
FOR I2 : inv USE ENTITY WORK.inv(inv_gen1)
GENERIC MAP(int_rise => 1.3 ns,
Int_fall => 1.4 ns,
Ext_rise => 2.8 ns,
Ext_fall => 2.9 ns);
END FOR;
FOR AN1 : and3 USE ENTITY WORK.and3(and3_gen1)
GENERIC MAP(int_rise => 2.2 ns,
Int_fall => 2.7 ns,
13
Ext_rise => 3.6 ns,
Ext_fall => 3.5 ns);
END FOR;
FOR AN2 : and3 USE ENTITY WORK.and3(and3_gen1)
GENERIC MAP(int_rise => 2.2 ns,
Int_fall => 2.7 ns,
Ext_rise => 3.1 ns,
Ext_fall => 3.2 ns);
END FOR;
FOR AN3 : and3 USE ENTITY WORK.and3(and3_gen1)
GENERIC MAP(int_rise => 2.2 ns,
Int_fall => 2.7 ns,
Ext_rise => 3.3 ns,
14
Ext_fall => 3.4 ns);
END FOR;
FOR AN4 : and3 USE ENTITY WORK.and3(and3_gen1)
GENERIC MAP(int_rise => 2.2 ns,
Int_fall => 2.7 ns,
Ext_rise => 3.0 ns,
Ext_fall => 3.1 ns);
END FOR;
END FOR;
END decode_gen1_con;
4. 计一个加法器,元件例化后放入库中备用。
答:半加器及全加器VHDL程序设计(1)。
LIBRARY IEEE;
15
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY full_adder IS
PORT (a,b,cin:IN STD_LOGIC;
Sum,co:OUT STD_LOGIC);
END full_adder;
ARCHITECTURE full1 OF full_adder IS
COMPONENT half_adder
PORT (a,b:IN STD_LOGIC;
S,co:OUT STD_LOGIC);
END COMPONENT;
SIGNAL u0_co,u0_s,u1_co:STD_LOGIC;
BEGIN
U0:half_adder PORT MAP (a,b,u0_s,u0_co);
16
U1:half_adder PORT MAP (u0_s,cin,sum,u1_co);
Co <= u0_co OR u1_co;
END full1;
半加器及全加器VHDL程序设计(2)。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY half_adder IS
PORT (a,b:IN STD_LOGIC;
S,co:OUT STD_LOGIC);
END half_adder;
ARCHITECTURE half1 OF half_adder IS
SIGNAL c,d:STD_LOGIC;
BEGIN
17
C <= a OR b;
D <= a NAND b;
Co <= NOT d;
S <= c AND d;
END half1;
5. 简述层次化设计的过程。
答:层次化设计是指对于一个大型设计任务,将目标层层分解,在各个层次上分别设计的方法。有些设计,在一些模块的基础上,通过搭建积木的方法进行设计。有人称,在整个设计任务上进行行为描述的设计方法,称为高层次设计,而从事某一模块、某一元件行为设计称为底层设计方法。
6. 什么是库,程序包,子程序,过程调用,函数调用?
答:库(libraries)和程序包(package)用来描述和保存元件、类型说明、函数、模块等,以便在其他设计中可随时引用它们。
库(libraries)是用来存储和放置可编译的设计单元的地方,通过其目录可查询、调用。设计库中的设计单元(实体说明、结构体、配置说明、程序包说明和程序包体)可以用作其他VHDL描述的资源。
18
函数和过程统称为子程序。
子程序由过程和函数组成。在子程序调用过程中,过程能返回多个变量,函数能返回一个变量。若子程序调用是一个过程,就称为过程调用;若子程序调用是一个函数,则称为函数调用。过程调用和函数调用都是子程序调用。
函数的参数都是输入参数。
过程的参数有输入、输出和双向参数。
函数有顺序函数、并行函数。
过程有顺序过程、并行过程。
7. 编写一个OR函数,重载它,对不同的数据类型进行OR运算。
答: 参考例4-24 读者自行编写。
第5章思考题解答
1. CLK信号怎样用VHDL语言描述?
答:时钟信号的上升沿的描述:
if clk‘event and clk = ‘1’ then …;
19
时钟信号的下降沿的描述:
if clk ‘event and clk = ‘1’ then …;
2. 异步复位怎样用VHDL语言描述?
答:当复位信号低电平有效时,VHDL的描述为:
if reset = ‘0’ then …;
当复位信号高电平有效时, VHDL的描述为:
if reset =‘1’ then …;
3. 设计一个8位循环移位寄存器。
答: 8位循环计寄存器的VHDL参考程序设计如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY circleshift8 IS
PORT (seldata:in std_logic_vector(2 downto 0);
20
clr,clk: IN STD_LOGIC;
sel: OUT STD_LOGIC_vector(7 downto 0));
END circleshift8;
ARCHITECTURE sample OF circleshift8 IS
begin
process(clk,clr)
Begin
if (clr='1')then sel<=\"00000000\";
elsif clk'event and clk='1' then
case seldata is
when \"001\"=> sel<=\"00000001\";
when \"010\"=> sel<=\"00000010\";
when \"011\"=> sel<=\"00000100\";
21
when \"100\"=> sel<=\"00001000\";
when \"101\"=> sel<=\"00010000\";
when \"110\"=> sel<=\"00100000\";
when \"111\"=> sel<=\"01000000\";
when others => sel<=\"00000000\";
end case;
end if;
end process;
end sample;
4. 设计一个六十进制计数器。
答: 60进制计数器的VHDL参考程序设计如下:
Library ieee;
use ieee.std_logic_1164.all;
22
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--*******************************************************
Entity counter60 is
port(
cp:in std_logic;
bin:out std_logic_vector(6 downto 0);
s:in std_logic;
clr:in std_logic;
ec:in std_logic;
cy60:out std_logic
);
End counter60;
23
--*******************************************************
Architecture b of counter60 is
signal q:std_logic_vector(6 downto 0);
signal rst,dly:std_logic;
begin
process(rst,cp)
begin
if rst='1' then q<=\"0000000\"; -- cy(60)<='0';
elsif cp'event and cp='1' then dly<=q(5);
if ec='1'then
if q=59 then q<=\"0000000\";
else
q<=q+1;
24
end if;
else
q<=q;
end if;
end if;
end process;
cy60<= not q(5) and dly;
rst<= clr;
bin<=q when s='1' else
\"1111111\";
End b;
5. 设计一个八位编码器。
答: 八位编码器的VHDL参考程序设计如下:
25
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY priotyencoder IS
PORT (d : IN Std_Logic_Vector (7 Downto 0);
E1: IN Std_Logic;
GS,E0: OUT BIT STD_LOGIC;
Q : OUT Std_Logic_Vector(2 Downto 0);
END priotyencoder;
ARCHITECTURE encoder OF prioty encoder IS
BEGIN
P1: PROCESS ( d )
BEGIN
IF ( d(0) = 0 AND E1 = 0 ) THEN
26
Y <= 111;
GS <= 0 ;
E0 <= 1 ;
ELSIF (d(1) = 0 AND E1 = 0 ) THEN
Q <= 110;
GS <= 0 ;
E0 <= 1 ;
ELSIF (d(2) = 0 AND E1 = 0 ) THEN
Q <= 101 ;
GS <= 0 ;
E0 <= 1 ;
ELSIF (d(3) = 0 AND E1= 0 ) THEN
Q <= 100 ;
27
GS <= 0 ;
E0 <= 1 ;
ELSIF (d(4) = 0 AND E1= 0 ) THEN
Q <= 011 ;
GS <= 0 ;
E0 <= 1 ;
ELSIF (d(5) = 0 AND E1= 0 ) THEN
Q <= 010 ;
GS <= 0 ;
E0 <= 1 ;
ELSIF (d(6) = 0 AND E1 = 0 ) THEN
Q <= 001 ;
GS<= 0 ;
28
E0<= 1 ;
ELSIF (d(7) = 0 AND E1 = 0 ) THEN
Q <= 000 ;
GS <= 0 ;
E0 <= 1 ;
ELSIF (E1 = 1 ) THEN
Q <= 111 ;
GS <= 1 ;
E0 <= 1 ;
ELSIF (d = 1111 1111 AND E1 = 0 ) THEN
Q <= 111 ;
GS <= 1 ;
E0 <= 0 ;
29
END IF;
END PROCESS P1;
END encoder;
6. 设计一个三八译码器。
答: 三八译码器的VHDL参考程序设计如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY decoder3_8 IS
PORT (a,b,c,g1,g2a,g2b:IN STD_LOGIC;
Y:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END decoder3_8;
ARCHITECTURE rtl OF decoder3_8 IS
SIGNAL indata:STD_LOGIC_VECTOR (2 DOWNTO 0);
30
BEGIN
Indata <= c & b & a;
PROCESS (indata,g1,g2a,g2b)
BEGIN
IF (g1 = 1 AND g2a = 0 AND g2b = 0 ) THEN
CASE indata 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 31
;;;;;;;
WHEN 111 => y <= 01111111 ;
WHEN OTHERS=> y <= XXXXXXXX ;
END CASE;
ELSE
Y <= 11111111 ;
END IF;
END PROCESS;
END rtl;
7. 设计一个N位通用加法器。
答: 设N=8位时,通用加法器的VHDL参考程序设计如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY B8_adder IS
32
PORT (a,b,cin:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Sum,co:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END B8_adder;
ARCHITECTURE STRUCTURE OF B8_adder IS
COMPONENT full_adder
PORT (a,b,cin:IN STD_LOGIC;
Sum,co:OUT STD_LOGIC);
END COMPONENT;
BEGIN
ga: for i in 0 to 7 generate
adder: full_adder PORT MAP (a(i),b(i),cin(i),Sum(i),co(i));
end generate;
END STRUCTURE;
33
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY full_adder IS
PORT (a,b,cin:IN STD_LOGIC;
Sum,co:OUT STD_LOGIC);
END full_adder;
ARCHITECTURE full1 OF full_adder IS
COMPONENT half_adder
PORT (a,b:IN STD_LOGIC;
S,co:OUT STD_LOGIC);
END COMPONENT;
SIGNAL u0_co,u0_s,u1_co:STD_LOGIC;
BEGIN
34
U0:half_adder PORT MAP (a,b,u0_s,u0_co);
U1:half_adder PORT MAP (u0_s,cin,sum,u1_co);
Co <= u0_co OR u1_co;
END full1;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY half_adder IS
PORT (a,b:IN STD_LOGIC;
S,co:OUT STD_LOGIC);
END half_adder;
ARCHITECTURE half1 OF half_adder IS
SIGNAL c,d:STD_LOGIC;
BEGIN
35
C <= a OR b;
D <= a NAND b;
Co <= NOT d;
S <= c AND d;
END half1;
8.为什么要层次化设计?
答: 原因有二。第一,对于一个大型设计项目,层次分解后,由不同设计人员分别进行设计,可以大大提高设计效率。第二 层次分解后,各个层次由不同的设计模块构成,可以分别测试,验证。大大降低了项目的风险和难度。
9.Moore型状态机和Mealy型状态机有什么相同和不同?
答: Moore型状态机的输出信号仅与现态相关,Moore 型状态机输出是现态的函数,Mealy型状态机输出是现态和输入的函数。
10.一位有效状态机有什么优点?
答:一位有效编码,比顺序编码方式占用资源多,在目标器件具有较多寄存器资源,并且寄存器之间组合逻辑较少时,一位有效编码是一个比较合适的方法。
36
11.设计一个3位8状态机。
答:
library ieee;
use ieee.std_logic_1164.all;
entity memory_controller is
port ( reset, read_write, ready, burst, clk : in std_logic;
bus_id : in std_logic_vector(7 downto 0);
oe,we : out std_logic;
addr : out std_logic_vector(1 downto 0));
end memory_controller;
architecture state_machine of memory_controller is
type StateType is (idle, decision, read1, read2, read3, read4,signal present_state,next_state : StateType;
37
write);
begin
state_comb:process(reset, bus_id, present_state, burst, read_write, ready)
begin
if (reset = '1') then --复位处理
oe <='-'; addr <='—';
next_state <=idle; --信号代入
else
case present_state is
when idle => oe <='0'; we <='0'; addr <=\"00\";
if (bus_id) = \"11110011\") then
next_state <= decision;
else
next_state <= idle;
38
end if;
when decision=> oe <='0'; we <='0'; addr <=\"00\";
if (read_write) = '0') then
next_state <= read1;
else — read_write='0'
next_state <= write;
end if;
when read1 => oe <='1'; we <='0'; if (ready = '0') then
next_state <= read1;
elsif (burst ='0') then
next_state <= idle;
else
39
addr <=\"00\";
next_state <= read2;
end if;
when read2 => oe <='1'; we <='0'; addr <=\"01\";
if (ready = '1') then
next_state <= read3;
else
next_state <= read2;
end if;
when read3 => oe <='1'; if (ready = '1') then
next_state <= read4;
else
next_state <= read3;
we <='0';40
addr <=\"10\";
end if;
when read4 => oe <='1'; we <='0'; addr <=\"11\";
if (ready = '1') then
next_state <= idle;
else
next_state <= read4;
end if;
when write => oe <='0'; if (ready = '1') then
next_state <= idle;
else
next_state <= write;
end if;
we <='1';41
addr <=\"00\";
end case;
end if;
end process state_comb;
state_clocked:process(clk)
begin
if rising_edge(clk'EVENT AND clk='1') then
present_state <= next_state;
end if;
end process state_clocked;
end state_machine;
12.设计一个PCI BUS VGA图像接口芯片,画出层次分解图,由几个人分别编程,再组合通调,写出一个团体协作的案例,总结成功失败的经验。
答: 1. 首先熟悉PCI总线规范。
2.其次熟悉VGA图象处理器件工作原理。
42
3.分解设计任务。
4.分别由不同的设计小组编写VHDL程序
5.分别编译、调试,仿真、验证通过。
6.项目合成,整体通调,仿真验证。
7.设计实验原理电路,设计实验电路板。
8.编程、配置FPGA器件,进行性能测试。
9.进行ASIC版图设计,进行MPW流片。
10.编写产品使用手册,提供用户详尽技术参数。
第7章思考题解答
1. VHDL程序到集成电路版图需要那些过程?
答:需要逻辑综合,功能仿真,形式验证或FPGA功能验证,时序仿真,到版图设计。
2. 怎样在实验室实现集成电路设计?
答:用VHDL语言进行行为设计,用EDA工具作为设计环境,用FPGA器件作为设计实现载体,就可以在实验室进行集成电路的设计和实现。
43
3. 什么是MPW多项目晶圆服务?
答:多项目晶圆(Multi-Profect Wafer,简称MPW)就是将多种具有相同工艺的集成电路设计项目放在同一圆片上流片,流片后,每个设计项目可以得到数十片芯片样品,这一数量对于设计开发阶段的实验、测试已经足够。而实验费用就由所有参加MPW的项目按照芯片面积分摊,极大地降低了实验成本,降低了中小集成电路设计企业在起步时的门槛。
4. 设计一个8位CPU版图,参加MPW流片,并测试设计结果。
答:参考实验讲义,研究实验8的内容并付诸实践。
44
因篇幅问题不能全部显示,请点此查看更多更全内容