数字电路与逻辑设计
实验报告
专业:通信工程 班级:2013211123 姓名: 学号: 班内序号: 指导老师:
实验一:QuartusⅡ原理图输入法设计与实现
实验目的:
(1)熟悉用QuartusⅡ原理图输入法进行电路设计和仿真; (2)掌握QuartusⅡ图形模块单元的生成与调用; (3)熟悉实验板的使用。
实验内容:
(1)用逻辑门设计实现一个半加器,仿真验证其功能,并生成新的半加器图形模块单元; (2)用实验内容1中生成的半加器模块和逻辑门设计实现一个全加器,仿真验证其功能,并下载到实验板测试,要求用拨码开关设定输入信号,发光二极管显示输出信号;
(3)用3线-8线译码器(74LS138)和逻辑门设计实现函数F=CBA+CBA+CBA+CBA,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,发光二极管显示输出信号。
原理图及仿真波形图:
(1)半加器 原理图:
仿真波形图:
分析:S=a⊕b;C=ab
其中a,b为输入端,C为进位端,S为本位和,当ab=‘00’‘01’‘10’时不用进位,故C=‘0’,当ab=‘11’时需要进位使得C=‘1’,S=‘0’。 (2)全加器 原理图:
仿真波形图:
分析:Si=Ai⊕Bi⊕Ci-1;Ci=AiBi+Ci-1(Ai⊕Bi)
全加器与半加器的不同在于,全加器需要考虑低位的进位,而半加器不需要。因而对于全加器,Ai、Bi为加数和被加数,Ci-1为低位的进位,Ci为进位,Si为本位和,实质上相当于Ai+Bi+Ci-1,满2进1,Ci为进位,Si为本位和。 (3)译码器 原理图:
仿真波形图:
分析:又有要实现的功能为F=CBA+CBA+CBA+CBA,又根据74LS138的使用原理可得图示的连接方法。
实验二:用VHDL设计与实现组合逻辑电路
实验目的:
(1)熟悉用VHDL语言设计组合逻辑电路的方法; (2)熟悉用QuartusⅡ文本输入法进行电路设计; (3)熟悉不同的编码及其之间的转换。
实验内容:
(1)用VHDL语言设计实现一个共阴极7段数码管译码器,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,7段数码管显示输出信号; (2)用VHDL语言设计实现一个8421码转换为余3码的代码转换器,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,发光二极管显示输出信号;
(3)用VHDL语言设计实现一个4位二进制奇校验器,输入奇数个‘1’时,输出为‘1’,否则输出为‘0’,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,发光二极管显示输出信号。
VHDL代码及仿真波形图:
(1)数码管译码器 VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY seg7_1 IS PORT(
a:IN STD_LOGIC_VECTOR(3 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
end seg7_1;
ARCHITECTURE seg7_1_arch OF seg7_1 IS BEGIN
PROCESS(a) BEGIN CASE a IS
WHEN"0000" => b b b b b b b b b b b
END PROCESS;
END;
仿真波形图:
分析:数码管译码器主要运用case语句,将每一种情况罗列出来,而仿真波形图既是每一
种情况的一种直观体现
(2)8421码转换为余3码的代码转换器 VHDL代码: library ieee;
use ieee.std_logic_1164.all;
entity TWO is port(
a:in std_logic_vector(3 downto 0); b:out std_logic_vector(3 downto 0) );
end TWO;
architecture TWO_arch of TWO is begin process(a) begin case a is
when "0000" =>b b b b b b b b b b b
end process; end;
仿真波形图:
分析:余三码实际为8421码加上3的结果,可以用case列举的方式,也可以用加号,但需要加上相应的库
(3)奇校验器 VHDL代码: library ieee;
use ieee.std_logic_1164.all;
entity THREE is port(
a:in std_logic_vector(3 downto 0); b:out std_logic_vector(0 downto 0) );
end THREE;
architecture THREE_arch of THREE is begin process(a) begin case a is
when "0000" =>b b b b b b b b b b b b b b b b b
仿真波形图:
实验三:用VHDL设计与实现时序逻辑电路
实验目的:
(1)熟悉用VHDL语言设计时序逻辑电路的方法; (2)熟悉用QuartusⅡ文本输入法进行电路设计; (3)熟悉计数器和分频器的设计与应用。
实验内容:
(1)用VHDL语言设计实现一个带异步复位的8421码十进制计数器,仿真验证其功能,并下载到实验板测试。要求用按键设定输入信号,发光二极管显示输出信号;
(2)用VHDL语言设计实现一个分频系数为12,分频输出信号占空比为50%的分频器,要求在QuartusⅡ平台上设计程序并仿真验证设计;
(3)将(1)(2)和数码管译码器三个电路进行连接,并下载到实验板显示计数结果。
VHDL代码、仿真波形图、模块端口说明:
(1)计数器 VHDL代码: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_arith.all;
entity count_10 is port(
clk,clear:IN STD_LOGIC;
q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END count_10;
architecture a of count_10 is signal cn:integer range 0 to 10;
begin
process(clk) begin
IF (clear='0'OR cn=10) THEN cn
ELSIF(clk'event AND clk='1')THEN
cn
END PROCESS;
q
仿真波形图:
分析:输入为时钟信号和复位信号。由于是异步复位,所以复位信号的优先级最高。当复位信号为0时,输出变为0000;当复位信号为1时,每当遇到时钟上升沿,输出状态加1,实现加计数,计数循环为0000→···1010,其中1010与0000占用同一个周期的clk,因此输出波形会出现“芒刺”。 (2)分频器 VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY div_12 IS PORT(
clk :IN STD_LOGIC; clear :IN STD_LOGIC;
clk_out:OUT STD_LOGIC); END div_12;
ARCHITECTURE a OF div_12 IS
SIGNAL tmp:INTEGER RANGE 0 TO 5; SIGNAL clktmp:STD_LOGIC;
BEGIN
PROCESS(clear,clk) BEGIN
IF clear ='0' THEN tmp
ELSIF clk'event AND clk='1' THEN
IF tmp = 5 THEN
tmp
tmp
END IF;
END PROCESS; clk_out
仿真波形图:
分析:
在本段设计中,clear=0不再是简单的清零操作,而是重新计算clk数目的操作,当出现clear=0时,将会重新计算6个时钟周期,再进行输出状态的翻转。 (3)计时器与分频器的连接 VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY the IS PORT(
clear1 :IN STD_LOGIC; clear2 :IN STD_LOGIC; clk1:IN STD_LOGIC;
b1:OUT STD_LOGIC_VECTOR(6 downto 0); CAT:OUT STD_LOGIC_VECTOR(5 downto 0) );
end the;
ARCHITECTURE a OF the IS
COMPONENT div_12 --分频器 PORT(
clk :IN STD_LOGIC; clear :IN STD_LOGIC; clk_out:OUT STD_LOGIC );
END COMPONENT;
COMPONENT count_10 --计数器 PORT(
clk,clear:IN STD_LOGIC;
q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0) );
END COMPONENT;
COMPONENT seg7_1 --数码管译码器 PORT(
a:IN STD_LOGIC_VECTOR(3 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
END COMPONENT;
SIGNAL na:STD_LOGIC;
SIGNAL nb:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
u1:div_12 PORT MAP(clk_out=>na,clk=>clk1,clear=>clear1); u2:count_10 PORT MAP(clear=>clear2,clk=>na,q=>nb); u3:seg7_1 PORT MAP(a=>nb,b=>b1); CAT
模块端口说明:
仿真波形图:
分析:
以clk1作为外部时钟使得分频器产生12分频的信号,分频器的输出作为计数器的时钟信号,使得计数器实现加计数的功能,译码管用于直观地显示计数器的输出。
实验四:数码管动态扫描控制器
实验目的:
(1)掌握VHDL语言的语法规范,掌握时序电路描述方法; (2)掌握多个数码管动态扫描显示的原理及设计方法。
实验内容:
(1)用VHDL语言设计并实现六个数码管串行扫描电路,要求同时显示0、1、2、3、4、5这6个不同的数字图形到6个数码管上,仿真验证其功能,并下载到实验板测试; (2)用VHDL语言设计并实现六个数码管滚动显示电路
①循环向左滚动,始终点亮6个数码管,左进右出。状态为:012345→123450→234501→345012→450123→501234→012345 ②向左滚动,用全灭的数码管填充右边,直至全部变灭,然后又依次从右边一个一个地点亮。状态为:012345→12345X→2345XX→345XXX→45XXXX→5XXXXX→XXXXXX→XXXXX0→XXXX01→XXX012→XX0123→X01234→012345,其中‘X’表示数码管不显示
VHDL代码、仿真波形图、模块端口说明:
(1)数码管串行扫描电路 VHDL语言: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY TaLL IS PORT (
clk,rs:IN STD_LOGIC;
b:OUT STD_LOGIC_VECTOR(6 downto 0); cat:OUT STD_LOGIC_VECTOR(5 downto 0) );
END TaLL;
ARCHITECTURE a OF TaLL IS
COMPONENT gray --技术状态不连续的异步计数器 PORT(
clk,rs:IN STD_LOGIC;
countout:OUT STD_LOGIC_VECTOR(5 downto 0) );
END COMPONENT;
COMPONENT shuma --数码管
cat:IN STD_LOGIC_VECTOR(5 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
END COMPONENT;
SIGNAL na:STD_LOGIC_VECTOR(5 downto 0); BEGIN
u1:gray PORT MAP(clk=>clk,rs=>rs,countout=>na); u2:shuma PORT MAP(cat=>na,b=>b); cat
模块端口说明:
仿真波形图:
分析:技术状态不连续的异步计数器作为脉冲分配器产生相应的cat信号控制6个数码管的亮与灭,而每一个数码管显示同样的数字,故而每个cat对应的输出b是固定的。当时钟频率较高时,人眼无法辨别几个数码管输出的先后,看上去就可以认为几个数码管同时输出012345
技术状态不连续的异步计数器: VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY gray IS
clk,rs:IN STD_LOGIC;
countout:OUT STD_LOGIC_VECTOR(5 downto 0) );
END gray;
ARCHITECTURE behav OF gray IS
SIGNAL nextcount:STD_LOGIC_VECTOR(5 downto 0);
BEGIN
PROCESS(clk,rs)
BEGIN
IF rs='0' THEN
nextcount
ELSIF (clk'event AND clk='1')THEN
CASE nextcount IS
WHEN"111110"=>nextcountnextcountnextcountnextcountnextcountnextcountnextcount
END IF;
END PROCESS; countout
仿真波形图:
数码管:
VHDL代码:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY shuma IS PORT(
cat:IN STD_LOGIC_VECTOR(5 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
END shuma;
ARCHITECTURE seg_arch OF shuma IS BEGIN
PROCESS (cat) BEGIN
CASE cat IS
WHEN"111110"=>bbbbbbb
(2)循环向左滚动 VHDL代码: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity diaseg2 is
port(clear,clk: in std_logic;
q: out std_logic_vector(6 downto 0);
countout: out std_logic_vector(5 downto 0) ); end diaseg2;
architecture diaseg2_arc of diaseg2 is
signal q_temp:std_logic_vector(6 downto 0); signal count:std_logic_vector(5 downto 0);
signal cnt,cnt1:integer range 0 to 5; signal tmp: integer range 0 to 15999; signal clk1: std_logic; begin
process(clk) begin
if(clk'event and clk='1') then if(cnt=5) then cnt
end process;
process(clk,clear) begin
if(clear='1') then tmp
elsif (clk'event and clk='1') then if(tmp=15999) then tmp
end process;
process(tmp) begin
if(clk'event and clk='1') then if(tmp
end process;
process(clk1) begin
if(clk1'event and clk1='1') then if(cnt1=5) then cnt1
end process;
process(cnt,cnt1) begin
if(clear='1') then q_temp
case cnt+cnt1 is
when 0=>q_tempq_tempq_tempq_tempq_tempq_tempq_tempq_tempq_temp
when 9=>q_tempq_tempq_tempq_temp
end process; q
process(cnt) begin
if(clear='1') then count
case cnt is
when 0=>countcountcountcountcountcount
when others =>count
end process;
countout
仿真波形图:
开始的波形图如下:
第一次左移的波形图如下:
之后的波形图类似
分析:
本实验较为复杂,需要两个时钟信号,一个用于控制数码管的显示,一个用于控制循环向左移动。可以由clk直接提供,另一个时钟信号要对clk进行分频之后提供。所以仿真波形END TIME的选取要适当,本次实验为10ms,便于观察波形的变化。 (3)向左滚动 VHDL代码: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity diaseg3 is
port(clear,clk: in std_logic;
q: out std_logic_vector(6 downto 0);
countout: out std_logic_vector(5 downto 0) ); end diaseg3;
architecture diaseg3_arc of diaseg3 is
signal q_temp:std_logic_vector(6 downto 0); signal count:std_logic_vector(5 downto 0); signal cnt,cnt1:integer range 0 to 11; signal tmp: integer range 0 to 1999; signal clk1: std_logic; begin
process(clk) begin
if(clk'event and clk='1') then if(cnt=11) then cnt
end process;
process(clk,clear) begin
if(clear='1') then tmp
elsif (clk'event and clk='1') then if(tmp=1999) then tmp
end process;
process(tmp) begin
if(clk'event and clk='1') then if(tmp
end process;
process(clk1) begin
if(clk1'event and clk1='1') then if(cnt1=11) then cnt1
end process;
process(cnt,cnt1) begin
if(clear='1') then q_temp
case cnt+cnt1 is
when 6=>q_tempq_tempq_temp
when 9=>q_tempq_tempq_tempq_temp
end process; q
process(cnt) begin
if(clear='1') then count
case cnt is
when 0=>countcountcountcountcountcount
when others =>count
end process;
countout
仿真波形图: 显示6个数字:
显示5个数字:
显示4个数字:
显示3个数字:
显示2个数字:
显示1个数字:
之后依次循环。
分析:
本个实验和2类似,只是将每次循环左移后,尾部的数码管熄灭。
故障及问题分析:
(1)实验一:下载之后,发光二极管一直闪。原因:拨码开关有问题,重新锁定其他引脚,得以解决;
(2)实验三:复位信号不是异步的,需要等到有效时钟信号到来之后才能清零。原因:代码逻辑错误,将清零条件放在最外层的IF语句中,再调整其他地方,得以解决; 数码管不能自动变化。原因:时钟信号引脚连接错误,应该接18引脚 (3)实验四:循环向左移位的输出波形混乱。原因:分频器参数设置不当
(4)刚开始出现过的问题,比如编译出错,因为文件夹出现了中文名,还有可能是实体名与保存的VHDL文件名不一致。为了安全起见,凡是数电实验的文件夹一律改为英文命名,而且同一个实验尽量用同样的文件名
总结和结论:
(1)实物电路的连接,要注意连线,尤其在移动器件位置之后可能使某些连线断开;
(2)VHDL语言的逻辑语法类似于C语言,也和SQL语言有某些类似之处,学习的时候要触类旁通,有编程的基础,学起VHDL来更为得心应手;
(3)数字电路与上学期的模拟电路相比,没有了自己搭电路的烦恼,做起来也顺利了许多。提前编好代码,做好了充足的准备,才能在课堂上顺利地完成实验
(4)现在的单元实验是下个学期综合实验的基础。翻看了一下下个学期的实验题目,觉得好有趣,也很期待
数字电路与逻辑设计
实验报告
专业:通信工程 班级:2013211123 姓名: 学号: 班内序号: 指导老师:
实验一:QuartusⅡ原理图输入法设计与实现
实验目的:
(1)熟悉用QuartusⅡ原理图输入法进行电路设计和仿真; (2)掌握QuartusⅡ图形模块单元的生成与调用; (3)熟悉实验板的使用。
实验内容:
(1)用逻辑门设计实现一个半加器,仿真验证其功能,并生成新的半加器图形模块单元; (2)用实验内容1中生成的半加器模块和逻辑门设计实现一个全加器,仿真验证其功能,并下载到实验板测试,要求用拨码开关设定输入信号,发光二极管显示输出信号;
(3)用3线-8线译码器(74LS138)和逻辑门设计实现函数F=CBA+CBA+CBA+CBA,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,发光二极管显示输出信号。
原理图及仿真波形图:
(1)半加器 原理图:
仿真波形图:
分析:S=a⊕b;C=ab
其中a,b为输入端,C为进位端,S为本位和,当ab=‘00’‘01’‘10’时不用进位,故C=‘0’,当ab=‘11’时需要进位使得C=‘1’,S=‘0’。 (2)全加器 原理图:
仿真波形图:
分析:Si=Ai⊕Bi⊕Ci-1;Ci=AiBi+Ci-1(Ai⊕Bi)
全加器与半加器的不同在于,全加器需要考虑低位的进位,而半加器不需要。因而对于全加器,Ai、Bi为加数和被加数,Ci-1为低位的进位,Ci为进位,Si为本位和,实质上相当于Ai+Bi+Ci-1,满2进1,Ci为进位,Si为本位和。 (3)译码器 原理图:
仿真波形图:
分析:又有要实现的功能为F=CBA+CBA+CBA+CBA,又根据74LS138的使用原理可得图示的连接方法。
实验二:用VHDL设计与实现组合逻辑电路
实验目的:
(1)熟悉用VHDL语言设计组合逻辑电路的方法; (2)熟悉用QuartusⅡ文本输入法进行电路设计; (3)熟悉不同的编码及其之间的转换。
实验内容:
(1)用VHDL语言设计实现一个共阴极7段数码管译码器,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,7段数码管显示输出信号; (2)用VHDL语言设计实现一个8421码转换为余3码的代码转换器,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,发光二极管显示输出信号;
(3)用VHDL语言设计实现一个4位二进制奇校验器,输入奇数个‘1’时,输出为‘1’,否则输出为‘0’,仿真验证其功能,并下载到实验板测试。要求用拨码开关设定输入信号,发光二极管显示输出信号。
VHDL代码及仿真波形图:
(1)数码管译码器 VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY seg7_1 IS PORT(
a:IN STD_LOGIC_VECTOR(3 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
end seg7_1;
ARCHITECTURE seg7_1_arch OF seg7_1 IS BEGIN
PROCESS(a) BEGIN CASE a IS
WHEN"0000" => b b b b b b b b b b b
END PROCESS;
END;
仿真波形图:
分析:数码管译码器主要运用case语句,将每一种情况罗列出来,而仿真波形图既是每一
种情况的一种直观体现
(2)8421码转换为余3码的代码转换器 VHDL代码: library ieee;
use ieee.std_logic_1164.all;
entity TWO is port(
a:in std_logic_vector(3 downto 0); b:out std_logic_vector(3 downto 0) );
end TWO;
architecture TWO_arch of TWO is begin process(a) begin case a is
when "0000" =>b b b b b b b b b b b
end process; end;
仿真波形图:
分析:余三码实际为8421码加上3的结果,可以用case列举的方式,也可以用加号,但需要加上相应的库
(3)奇校验器 VHDL代码: library ieee;
use ieee.std_logic_1164.all;
entity THREE is port(
a:in std_logic_vector(3 downto 0); b:out std_logic_vector(0 downto 0) );
end THREE;
architecture THREE_arch of THREE is begin process(a) begin case a is
when "0000" =>b b b b b b b b b b b b b b b b b
仿真波形图:
实验三:用VHDL设计与实现时序逻辑电路
实验目的:
(1)熟悉用VHDL语言设计时序逻辑电路的方法; (2)熟悉用QuartusⅡ文本输入法进行电路设计; (3)熟悉计数器和分频器的设计与应用。
实验内容:
(1)用VHDL语言设计实现一个带异步复位的8421码十进制计数器,仿真验证其功能,并下载到实验板测试。要求用按键设定输入信号,发光二极管显示输出信号;
(2)用VHDL语言设计实现一个分频系数为12,分频输出信号占空比为50%的分频器,要求在QuartusⅡ平台上设计程序并仿真验证设计;
(3)将(1)(2)和数码管译码器三个电路进行连接,并下载到实验板显示计数结果。
VHDL代码、仿真波形图、模块端口说明:
(1)计数器 VHDL代码: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_arith.all;
entity count_10 is port(
clk,clear:IN STD_LOGIC;
q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END count_10;
architecture a of count_10 is signal cn:integer range 0 to 10;
begin
process(clk) begin
IF (clear='0'OR cn=10) THEN cn
ELSIF(clk'event AND clk='1')THEN
cn
END PROCESS;
q
仿真波形图:
分析:输入为时钟信号和复位信号。由于是异步复位,所以复位信号的优先级最高。当复位信号为0时,输出变为0000;当复位信号为1时,每当遇到时钟上升沿,输出状态加1,实现加计数,计数循环为0000→···1010,其中1010与0000占用同一个周期的clk,因此输出波形会出现“芒刺”。 (2)分频器 VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY div_12 IS PORT(
clk :IN STD_LOGIC; clear :IN STD_LOGIC;
clk_out:OUT STD_LOGIC); END div_12;
ARCHITECTURE a OF div_12 IS
SIGNAL tmp:INTEGER RANGE 0 TO 5; SIGNAL clktmp:STD_LOGIC;
BEGIN
PROCESS(clear,clk) BEGIN
IF clear ='0' THEN tmp
ELSIF clk'event AND clk='1' THEN
IF tmp = 5 THEN
tmp
tmp
END IF;
END PROCESS; clk_out
仿真波形图:
分析:
在本段设计中,clear=0不再是简单的清零操作,而是重新计算clk数目的操作,当出现clear=0时,将会重新计算6个时钟周期,再进行输出状态的翻转。 (3)计时器与分频器的连接 VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY the IS PORT(
clear1 :IN STD_LOGIC; clear2 :IN STD_LOGIC; clk1:IN STD_LOGIC;
b1:OUT STD_LOGIC_VECTOR(6 downto 0); CAT:OUT STD_LOGIC_VECTOR(5 downto 0) );
end the;
ARCHITECTURE a OF the IS
COMPONENT div_12 --分频器 PORT(
clk :IN STD_LOGIC; clear :IN STD_LOGIC; clk_out:OUT STD_LOGIC );
END COMPONENT;
COMPONENT count_10 --计数器 PORT(
clk,clear:IN STD_LOGIC;
q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0) );
END COMPONENT;
COMPONENT seg7_1 --数码管译码器 PORT(
a:IN STD_LOGIC_VECTOR(3 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
END COMPONENT;
SIGNAL na:STD_LOGIC;
SIGNAL nb:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
u1:div_12 PORT MAP(clk_out=>na,clk=>clk1,clear=>clear1); u2:count_10 PORT MAP(clear=>clear2,clk=>na,q=>nb); u3:seg7_1 PORT MAP(a=>nb,b=>b1); CAT
模块端口说明:
仿真波形图:
分析:
以clk1作为外部时钟使得分频器产生12分频的信号,分频器的输出作为计数器的时钟信号,使得计数器实现加计数的功能,译码管用于直观地显示计数器的输出。
实验四:数码管动态扫描控制器
实验目的:
(1)掌握VHDL语言的语法规范,掌握时序电路描述方法; (2)掌握多个数码管动态扫描显示的原理及设计方法。
实验内容:
(1)用VHDL语言设计并实现六个数码管串行扫描电路,要求同时显示0、1、2、3、4、5这6个不同的数字图形到6个数码管上,仿真验证其功能,并下载到实验板测试; (2)用VHDL语言设计并实现六个数码管滚动显示电路
①循环向左滚动,始终点亮6个数码管,左进右出。状态为:012345→123450→234501→345012→450123→501234→012345 ②向左滚动,用全灭的数码管填充右边,直至全部变灭,然后又依次从右边一个一个地点亮。状态为:012345→12345X→2345XX→345XXX→45XXXX→5XXXXX→XXXXXX→XXXXX0→XXXX01→XXX012→XX0123→X01234→012345,其中‘X’表示数码管不显示
VHDL代码、仿真波形图、模块端口说明:
(1)数码管串行扫描电路 VHDL语言: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY TaLL IS PORT (
clk,rs:IN STD_LOGIC;
b:OUT STD_LOGIC_VECTOR(6 downto 0); cat:OUT STD_LOGIC_VECTOR(5 downto 0) );
END TaLL;
ARCHITECTURE a OF TaLL IS
COMPONENT gray --技术状态不连续的异步计数器 PORT(
clk,rs:IN STD_LOGIC;
countout:OUT STD_LOGIC_VECTOR(5 downto 0) );
END COMPONENT;
COMPONENT shuma --数码管
cat:IN STD_LOGIC_VECTOR(5 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
END COMPONENT;
SIGNAL na:STD_LOGIC_VECTOR(5 downto 0); BEGIN
u1:gray PORT MAP(clk=>clk,rs=>rs,countout=>na); u2:shuma PORT MAP(cat=>na,b=>b); cat
模块端口说明:
仿真波形图:
分析:技术状态不连续的异步计数器作为脉冲分配器产生相应的cat信号控制6个数码管的亮与灭,而每一个数码管显示同样的数字,故而每个cat对应的输出b是固定的。当时钟频率较高时,人眼无法辨别几个数码管输出的先后,看上去就可以认为几个数码管同时输出012345
技术状态不连续的异步计数器: VHDL代码: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY gray IS
clk,rs:IN STD_LOGIC;
countout:OUT STD_LOGIC_VECTOR(5 downto 0) );
END gray;
ARCHITECTURE behav OF gray IS
SIGNAL nextcount:STD_LOGIC_VECTOR(5 downto 0);
BEGIN
PROCESS(clk,rs)
BEGIN
IF rs='0' THEN
nextcount
ELSIF (clk'event AND clk='1')THEN
CASE nextcount IS
WHEN"111110"=>nextcountnextcountnextcountnextcountnextcountnextcountnextcount
END IF;
END PROCESS; countout
仿真波形图:
数码管:
VHDL代码:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY shuma IS PORT(
cat:IN STD_LOGIC_VECTOR(5 downto 0); b:OUT STD_LOGIC_VECTOR(6 downto 0) );
END shuma;
ARCHITECTURE seg_arch OF shuma IS BEGIN
PROCESS (cat) BEGIN
CASE cat IS
WHEN"111110"=>bbbbbbb
(2)循环向左滚动 VHDL代码: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity diaseg2 is
port(clear,clk: in std_logic;
q: out std_logic_vector(6 downto 0);
countout: out std_logic_vector(5 downto 0) ); end diaseg2;
architecture diaseg2_arc of diaseg2 is
signal q_temp:std_logic_vector(6 downto 0); signal count:std_logic_vector(5 downto 0);
signal cnt,cnt1:integer range 0 to 5; signal tmp: integer range 0 to 15999; signal clk1: std_logic; begin
process(clk) begin
if(clk'event and clk='1') then if(cnt=5) then cnt
end process;
process(clk,clear) begin
if(clear='1') then tmp
elsif (clk'event and clk='1') then if(tmp=15999) then tmp
end process;
process(tmp) begin
if(clk'event and clk='1') then if(tmp
end process;
process(clk1) begin
if(clk1'event and clk1='1') then if(cnt1=5) then cnt1
end process;
process(cnt,cnt1) begin
if(clear='1') then q_temp
case cnt+cnt1 is
when 0=>q_tempq_tempq_tempq_tempq_tempq_tempq_tempq_tempq_temp
when 9=>q_tempq_tempq_tempq_temp
end process; q
process(cnt) begin
if(clear='1') then count
case cnt is
when 0=>countcountcountcountcountcount
when others =>count
end process;
countout
仿真波形图:
开始的波形图如下:
第一次左移的波形图如下:
之后的波形图类似
分析:
本实验较为复杂,需要两个时钟信号,一个用于控制数码管的显示,一个用于控制循环向左移动。可以由clk直接提供,另一个时钟信号要对clk进行分频之后提供。所以仿真波形END TIME的选取要适当,本次实验为10ms,便于观察波形的变化。 (3)向左滚动 VHDL代码: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity diaseg3 is
port(clear,clk: in std_logic;
q: out std_logic_vector(6 downto 0);
countout: out std_logic_vector(5 downto 0) ); end diaseg3;
architecture diaseg3_arc of diaseg3 is
signal q_temp:std_logic_vector(6 downto 0); signal count:std_logic_vector(5 downto 0); signal cnt,cnt1:integer range 0 to 11; signal tmp: integer range 0 to 1999; signal clk1: std_logic; begin
process(clk) begin
if(clk'event and clk='1') then if(cnt=11) then cnt
end process;
process(clk,clear) begin
if(clear='1') then tmp
elsif (clk'event and clk='1') then if(tmp=1999) then tmp
end process;
process(tmp) begin
if(clk'event and clk='1') then if(tmp
end process;
process(clk1) begin
if(clk1'event and clk1='1') then if(cnt1=11) then cnt1
end process;
process(cnt,cnt1) begin
if(clear='1') then q_temp
case cnt+cnt1 is
when 6=>q_tempq_tempq_temp
when 9=>q_tempq_tempq_tempq_temp
end process; q
process(cnt) begin
if(clear='1') then count
case cnt is
when 0=>countcountcountcountcountcount
when others =>count
end process;
countout
仿真波形图: 显示6个数字:
显示5个数字:
显示4个数字:
显示3个数字:
显示2个数字:
显示1个数字:
之后依次循环。
分析:
本个实验和2类似,只是将每次循环左移后,尾部的数码管熄灭。
故障及问题分析:
(1)实验一:下载之后,发光二极管一直闪。原因:拨码开关有问题,重新锁定其他引脚,得以解决;
(2)实验三:复位信号不是异步的,需要等到有效时钟信号到来之后才能清零。原因:代码逻辑错误,将清零条件放在最外层的IF语句中,再调整其他地方,得以解决; 数码管不能自动变化。原因:时钟信号引脚连接错误,应该接18引脚 (3)实验四:循环向左移位的输出波形混乱。原因:分频器参数设置不当
(4)刚开始出现过的问题,比如编译出错,因为文件夹出现了中文名,还有可能是实体名与保存的VHDL文件名不一致。为了安全起见,凡是数电实验的文件夹一律改为英文命名,而且同一个实验尽量用同样的文件名
总结和结论:
(1)实物电路的连接,要注意连线,尤其在移动器件位置之后可能使某些连线断开;
(2)VHDL语言的逻辑语法类似于C语言,也和SQL语言有某些类似之处,学习的时候要触类旁通,有编程的基础,学起VHDL来更为得心应手;
(3)数字电路与上学期的模拟电路相比,没有了自己搭电路的烦恼,做起来也顺利了许多。提前编好代码,做好了充足的准备,才能在课堂上顺利地完成实验
(4)现在的单元实验是下个学期综合实验的基础。翻看了一下下个学期的实验题目,觉得好有趣,也很期待