VHDL语言与数字系统设计西电.docx
《VHDL语言与数字系统设计西电.docx》由会员分享,可在线阅读,更多相关《VHDL语言与数字系统设计西电.docx(33页珍藏版)》请在冰点文库上搜索。
VHDL语言与数字系统设计西电
(此文档为word格式,下载后您可任意编辑修改!
)
科目:
VHDL语言与数字系统EDA设计
专业:
微电子与固体电子学
学生姓名:
陈庆宇
提交日期:
2011年5月26号
实验一······································1
实验二······································5
实验三······································9
实验四······································11
实验五······································17
作业········································27
Ø实验一
1.实验内容
1.用IF语句设计一个四-十六译码器;
2.用CASE语句设计一个四-十六译码器;
3.用GENERATE语句构造一个串行的十六进制计数器。
2.实验目的
会用VHDL语言实现一些简单的组合逻辑和时序逻辑,学会使用相关EDA软件进行VHDL代码的输入、仿真。
3.实验方案
本实验有三个小实验组成,先分别将方案分别列出:
a:
用IF语句设计一个四-十六译码器
接口信号的定义如图--1:
g1,g2a,g2b为片选信号,sel为输入
编码,y为译码输出
图-1
b:
用CASE语句设计一个四-十六译码器
接口定义同样的如图-1:
g1,g2a,g2b为片选信号,sel为输入编码,y为译码输出
c:
用GENERATE语句构造一个串行的十六进制计数器
先用行为描述设计一个D触发器,然后用结构描述的方法将四个D触发器用特定的接法连接起来。
其中clk、clr为时钟和清零输入,q为计数输出。
图-2即综合器生成的RTL框图。
图-2十六进制计数器的RTL框图
4.仿真结果(仿真软件:
QuartusII7.2)
a:
用IF语句实现的四-十六译码器的仿真结果
上图为:
片选信号无效的时候的仿真波形,输出为高电平。
上图为:
片选信号有效的时候的仿真波形。
b:
用CASE语句实现的一个四-十六译码器的仿真结果(直接让片选有效)
c:
用GENERATE语句构造的串行的十六进制计数器的仿真波形
注:
当clr为0时对计数结果清零,时钟上升沿计数器加1.
5.关键部分代码
a:
用IF语句设计一个四-十六译码器
PROCESS(G1,g2a,g2b,sel)
begin
if(g1='1'andg2a='0'andg2b='0')then
elsey<="XXXXXXXXXXXXXXXX";
endif;
endif;
endprocess;
b:
用CASE语句设计一个四-十六译码器
caseselis
whenothers=>y<="XXXXXXXXXXXXXXXX";
endcase;
c:
用GENERATE语句构造一个串行的十六进制计数器
architecturecount16erofcount16is
componentdfipis
port(
d:
instd_logic;
clr:
instd_logic;
ck:
instd_logic;
q:
outstd_logic;
qb:
outstd_logic
);
endcomponent;
signalclk_in:
std_logic_vector(4downto0);
begin
clk_in(0)<=clk;
G1:
foriin0to3generate
U0:
dfipportmap(d=>clk_in(i+1),ck=>clk_in(i),clr=>clr,q=>q(i),qb=>clk_in(i+1));
endgenerate;
endcount16er;
Ø
实验二
6.实验内容
1.设计一个两位二进制的加法器
2.设计一个两位的BCD计数器
7.实验目的
会用VHDL语言的多种描述方式实现典型的组合逻辑和时序逻辑,学会使用相关EDA软件进行VHDL代码的输入、仿真。
明确典型的组合逻辑和时序逻辑的基本构成。
练习层次化设计。
8.实验方案
本实验有两个小实验组成,先分别将方案分别列出:
a:
设计一个二位二进制加法器
接口信号的定义如右图:
a、b为两位的二进制输入,ci为进入输入,
s为全家和,co为进入输出。
设计方案:
先用行为描述设计一位全加器,然后再把一位全加器用结构描述的方法,通过引用已设计好的元件组成。
其RTL框图如下:
其中full_add为一位全加器。
b:
用设计一个两位的BCD计数器
接口信号的定义如右图:
g1为使能信号,当其有效时才可以计数;
clk为时钟输入,clr为清零,异步清零。
cout为进位输出。
设计方案
先设计一位BCD计数器,采用两个BCD计数器串联的方式完成最终设计,为了严格同步,使用前一个计数器的进位输出做为后一个的使能信号。
其RTL框图如下:
9.仿真结果(仿真软件:
QuartusII7.2)
a:
二位二进制加法器的仿真结果
b:
两位的BCD计数器的仿真结果
上图中,cout为进位输出,当计数到99时产生进位。
q0为个位BCD计数,q1为十位BCD计数。
下图即计数到99时cout产生进位的情况,仿真完全正确。
10.关键部分代码
a:
设计一个二位二进制加法器的核心代码
一位全加器部分
architecturedata_flowoffull_addis
signals:
std_logic;
begin
s<=xxory;
sum<=sxorcin;
cout<=(xandy)or(sandcin);
enddata_flow;
二位二进制加法器
U0:
full_addportmap(a(0),b(0),ci,s(0),m);
U1:
full_addportmap(a
(1),b
(1),m,s
(1),co);
b:
设计一个两位的BCD计数器的核心代码
一位BCD计数器
architecturertlofBCD_counteris
signalin_q0:
integer:
=0;
begin
process(clk,clr,g1)
begin
if(g1='1')then
if(clr='0')then
in_q0<=0;
elsif(clk'eventandclk='1')then
if(in_q0=9)then
in_q0<=0;
co<='1';
else
in_q0<=in_q0+1;
co<='0';
endif;
endif;
endif;
endprocess;
q0<=conv_std_logic_vector(in_q0,4);
endrtl;
两位BCD计数器
UO:
BCD_counterportmap(clk,clr,g1,m,q0);
U1:
BCD_counterportmap(clk,clr,m,cout,q1);
Ø
实验三
11.实验内容
利用数组形式描述256x8bits的RAM,并利用测试床完成对其读写操作。
12.实验目的
明确RAM的工作原理及过程,学会简单随机存储器的读写操作,并利用测试台对其进行测试。
13.实验方案
接口信号的定义如右图:
对于256x8bits的RAM,它有八条地址
线adr(0)~adr(7),八条数据输入线din(0)~din(7)、八
条数据输出线dout(0)~dout(7),wr为写控制线,rd
为读控制线。
当片选信号cs=1,wr信号上升沿时,
din上的数据写入由adr所指定的单元;当cs=1、
rd=0时,由adr所指定的单元的内容将从dout上
输出。
设计方案
分别由相应的进程控制RAM的读写过程,并且对建立及保持时间进行检测,让不符合要求时输出waring。
14.仿真结果(仿真软件:
QuartusII7.2)
如上图:
初始化RAM所有单元为0。
当片选信号无效时,输出高祖。
当当片选信号cs=1,wr信号上升沿时,din上的数据写入由adr所指定的单元;当cs=1、rd=0时,由adr所指定的单元的内容将从dout上输出。
仿真结果符合预期。
15.关键部分代码
adr_in<=conv_integer(adr);
process(wr)
begin
if(wr'eventandwr='1')then
wr_rise<=now;
if(cs='1')then
sram(adr_in)<=dinafter2ns;
endif;
endif;
assert(wr_rise-din_change>=800ps)report"writesramsetuptimeviolation"severityWARNING;
endprocess;
process(rd,cs,adr_in,wr)
begin
if(rd='0'andcs='1')then
dout<=sram(adr_in)after3ns;
else
dout<=(others=>'Z')after4ns;
endif;
endprocess;
process(din)
begin
din_change<=now;
assert(din_change-wr_rise>300ps)report"readsramholdtimeviolation"severityWARNING;
endprocess;
Ø
实验四
16.实验内容
采用VHDL语言设计实现UART串行通信的发送、接收模块。
17.实验目的
了解UART的基本原理,掌握串行异步通信实现同步的方法。
同时,学会用VHDL语言设计复杂电路的技巧及对复杂电路的仿真分析。
同时培养相关方面的能力。
18.实验方案
通用异步收发器UART是最常见的一种串行接口电路,广泛应用于微机与外设的通信。
其主要由发送器、接收器、波特率发生器、同步先进先出缓存、Modem控制模块、接口模块等组成。
本设计主要设计UART中最重要的发送部分和接收部分,其他部分设计不在赘述。
收发双方实现同步的方法是在字符格式中设置起始位和停止位。
其数据帧的各位为下图:
其中奇偶效验位可有可无。
在本次设计中,没有使用效验。
波特率因子为16.
下面就发送部分和接收部分的设计做一个叙述:
发送模块:
发送模块的主要功能是从CPU接收要发送的并行数据,将之转换成串行数据,按照约定的数据格式和波特率,在发送时钟clk16x的作用下,从端口tx端输出。
由此可以得出发送模块的主要功能为发送缓冲器(thr)、发送移位寄存器(tsr)、帧产生、并转串。
其工作过程为微处理器给出wr信号,发送器根据此信号将并行数据data[7..0]锁存进发送缓冲器thr[7..0],并通过发送移位寄存器tsr[7..0]发送串行数据至串行数据输出端tx。
在数据发送过程中用输出信号txdy作为标志信号,当数据由发送移位寄存器tsr[7..0]串行发送完毕时,txdy信号为1,通知CPU在下个时钟装入新数据。
发送器端口信号如下图所示:
如上图:
rst为复位信号,clk16x为基准时钟,wr为写控制信号,date为并行数据输入信号,tx为串行数据输出信号,txdy为输出完成信号。
串行数据帧和接收时钟是异步的,发送来的数据由逻辑1变为逻辑0可以视为一个数据帧的开始。
接收器先要捕捉起始位,确定rxd输入由1到0,逻辑0要8个CLK16时钟周期,才是正常的起始位,然后在每隔16个CLK16时钟周期采样接收数据,移位输入接收移位寄存器rsr,最后并行输出数据dout。
还要输出一个数据接收标志信号data_ready标志数据接收完。
接受模块端口信号如下图:
如上图:
rst为复位信号,clk16x为基准时钟,rdn为读控制信号,rxd为串行写信号,dout为并行输出信号,data_ready为接收完标志信号。
19.各模块及整体仿真结果(仿真软件:
QuartusII7.2)
发送模块的仿真波形
如上图所示,为了容易观察,引入波特率的波形,如bits所示,基准时钟为波待cpu下一个数据的输入。
接受模块的仿真波形
如上图:
经过10个波特率,就可以并行输出一个8位的二进制数。
data_ready之所以瞬间变高,因为rxd一直出现下降边,因此,只要在data_ready变为高电平后且rxd出现下降边,那么将开始新的采集。
若data_ready变为高电平后的rxd不出现低电平,那么data_ready会维持,下面的仿真图可以证明上述观点。
总模块的RTL框图如下:
20.关键部分代码
发送模块
process(rst,clk16x)--对clk1x_enable进行控制
begin
ifrst='1'then
clk1x_enable<='0';
txdy<='1';
elsifclk16x'eventandclk16x='1'then--true
ifwrn1='0'andwrn2='1'then
txdy<='0';
clk1x_enable<='1';
elsifstd_logic_vector(no_bits_sent)="1100"then
clk1x_enable<='0';
txdy<='1';
endif;
endif;
endprocess;
process(rst,wr)--接收数据至tbr
begin
ifrst='1'then
thr<=(others=>'0');
elsifwr'eventandwr='0'then
thr<=date;
endif;
endprocess;
process(rst,clk16x,clk1x_enable)--true
begin
ifrst='1'then
clkdiv<="0000";
elsifclk16x'eventandclk16x='1'then
ifclk1x_enable='1'then
clkdiv<=clkdiv+"0001";
endif;
endif;
endprocess;
clk1x<=clkdiv(3);--产生clk1x时钟true
process(rst,clk1x,no_bits_sent,thr)
begin
ifrst='1'then
tx<='1';
elsifclk1x'eventandclk1x='1'then
ifstd_logic_vector(no_bits_sent)="0001"then
tsr<=thr;--发送缓冲器tbr数据进入发送移位寄存器tsr
elsifstd_logic_vector(no_bits_sent)="0010"then
tx<='0';--发送起始位信号“0”
elsifstd_logic_vector(no_bits_sent)>="0011"andstd_logic_vector(no_bits_sent)<="1010"then
tsr<='0'&tsr(7downto1);--从低位到高位进行移位输出至串行输出端sdo
tx<=tsr(0);
elsifstd_logic_vector(no_bits_sent)="1011"then
tx<='1';
endif;
endif;
endprocess;
process(rst,clk1x,clk1x_enable)--产生发送字符长度和发送次序计数器
begin
ifrst='1'orclk1x_enable='0'then
no_bits_sent<="0000";
elsifclk1x'eventandclk1x='1'then
ifclk1x_enable='1'then
no_bits_sent<=no_bits_sent+"0001";
endif;
endif;
endprocess;
end;
接收模块代码
process(rst,clk16x,rxd1,rxd2,no_bits_rcvd)
begin
ifrst='1'orstd_logic_vector(no_bits_rcvd)="1011"then
data_ready<='1';
clk1x_enable<='0';
elsifclk16x'eventandclk16x='1'then
ifrxd1='0'andrxd2='1'then
data_ready<='0';
clk1x_enable<='1';
endif;
endif;
endprocess;
process(rst,clk16x,clk1x_enable)
begin
ifrst='1'then
clkdiv<="0000";
elsifclk16x'eventandclk16x='1'then
ifclk1x_enable='1'then
clkdiv<=clkdiv+"0001";
endif;
endif;
endprocess;
clk1x<=clkdiv(3);
process(clk1x,rst)
begin
ifrst='1'then
elsifclk1x'eventandclk1x='1'then
ifstd_logic_vector(no_bits_rcvd)>="0001"andstd_logic_vector(no_bits_rcvd)<"1001"then---数据帧数据由接收串行数据端移位入接收移位寄存器
rsr(0)<=rxd2;
rsr(7downto1)<=rsr(6downto0);
elsifstd_logic_vector(no_bits_rcvd)="1010"then
rbr<=rsr;--接收移位寄存器数据进入接收缓冲器
endif;
endif;
endprocess;
process(rst,clk1x,clk1x_enable,no_bits_rcvd)
begin
ifrst='1'or(std_logic_vector(no_bits_rcvd)="1011"andclk1x_enable='0')then
no_bits_rcvd<="0000";
elsifclk1x'eventandclk1x='1'then
ifclk1x_enable='1'then
no_bits_rcvd<=no_bits_rcvd+"0001";
endif;
endif;
endprocess;
dout<=std_logic_vector(rbr)whenrdn='0'else"ZZZZZZZZ";
end;
整体代码
begin
u1:
transferPORTMAP(rst,clk16x,wr,din,txdy,tx);
u2:
rcvrPORTMAP(rst,clk16x,rxd,rdn,dout,data_ready);
endv1;
Ø
实验五
21.实验内容
完成第九章计时电路设计,要求设计一块ASIC芯片,使其具有1/100s计时器所有的控制功能和定时结构。
且有如下功能要求:
精度应大于1/100s
计时器的最长计时时间为1h
设置复位和启/停开关
22.实验目的
学会利用层次化和模块化的方法设计稍微复杂一点的电路,掌握这种自顶向下的设计方法。
23.实验方案
接口信号的定义如右图:
⏹输入信号
◆复位输入reset_sw
◆启/停输入start_stop_sw
◆系统复位输入sysres
◆时钟输入clk
⏹输出信号
✓LED7段输出segment(6downto0),共7条输出线
✓LED公共端输出commom(5downto0),共6条输出线
设计方案
为了便于描述,结合top_down设计方法,应用模块化设计,将整个芯片分为5个子模块,即键输入子模块(keyin),时钟产生子模块(clkgen),控制子模块(ctrl),定时计数子模块(cntblk),显示子模块(disp)。
对其中的各个子模块用层次化设计,通过结构化描述通过调用元件组成。
其中整体方案的RTL框图如附页所示。
24.各子模块的功能、设计及仿真结果(仿真软件:
QuartusII)
4.1时钟产生子模块(clkgen)
该模块的输入为1khz的时钟信号,输出为25hz的keyclk(用于keyin模块的时钟信号)和用于定时计数的100hz计时脉冲cntclk。
为了严格同步,该模块采用同步计数电路,其RTL框图如下:
时钟产生子模块的仿真结果如下:
如上图:
产生了周期为10ms的cntclk,周期为40ms的keyclk。
符合预期。
4.2定时计数子模块(cntblk)
该模块的功能是实现计时计数,它由四个十进制计数器和两个六制计数器串接而成。
该模块将输出1/100s,1/10s,秒各位,秒十位,分个位,分十位的计数器值。
其中十进制计数器和六制计数器以元件形式被本模块使用。
前一个计数器的进位输出作为后一个元件的使能信号。
该模块的RTL框图如下:
该模块的仿真结果如下图:
(注:
为了更容易观察仿真结果,假设使能信号一直有效,且为发生复位)。
在上面的组图中,我们可以看到,secl2为1/100s,secl1为1/10s,各级计数均可在正确的时刻跳变,当计时到59分59秒99时,从零重新开始计数。
4.3ctrl子模块
该模块的功能是产生计时计数模块的计数允许信号cnten,模块中采用一个enb1兵乓开关,