Bootstrap

EDA技术及应用实验报告

实验一 组合逻辑3-8译码器设计

一、实验目的

1、通过3-8译码器的设计,让学生掌握组合逻辑电路的设计方法。

2、掌握组合逻辑电路的静态测试方法。

3、初步了解可编程器件设计的全过程。

二、实验内容

1、打开Quartus II软件。

2、选择路径。选择File/New Project Wizard,指定工作目录(默认路径,不要修改),指定工程和顶层设计实体名称;注意:工作目录名不能有中文,实体名称起英文字母组合,不要简单起成123之类,不要以数字开头命名。工程名,实体名,文件名,三个名称保持一致!

3、添加设计文件。将设计文件加入工程中。如果有已经建立好的VHDL或者原理图等文件可以在File name中选择路径然后添加,或者选择Add All添加所有可以添加的设计文件(.VHDL ,.Verilog原理图等)。如果没有直接点击“Next”,等建立好工程后再添加也可。这里暂不添加,点击“Next”。

4、选择FPGA器件。Family选择ACEX1K,Available devices选EP1K30TC144-3;确定无误后再点击“Next”。(可选其它)

5、选择外部综合器、仿真器和时序分析器。Quartus II支持外部工具,可通过选中来指定工具的路径。这里不做选择,默认使用Quartus II自带的工具。

6、结束设置。单击“Next”,弹出“工程设置统计”窗口,上面列出了工程的相关设置情况。最后单击“Finish”,结束工程设置。

7、建立原理图文件。File/ New/Block Diagram/Schematic File。

8、添加文件到工程中。点击“OK”,并选择File/Save,选择和工程相同的文件名!点击“保存”,文件就被添加进工程当中。

9、原理图建立完毕。这时,可以开始在原理图上进行设计了。

提示:用户可以在打开Quartus II后直接建立原理图或者VHDL文件,选择Save As,系统会提示是否要保存为工程文件,选择建立工程文件,也可进入工程文件建立流程。

10、添加器件。按照3-8译码器的电路图添加器件并连线。添加方法:原理图空白处双击鼠标左键进入Symbol界面,在Name中输入器件名称点击OK找到合适位置放置器件。连线时不能出现结点,连线方法:鼠标放到器件上变成十字形后按住鼠标左键拖到需要连接的结点上。修改端口名称:将pin_name全部改为A,B,C和Y0-Y7。

11、预编译。选择Processing/Start/Start Analysis&Synthesis,快捷键:

进行综合。如果有错误,可以双击红色错误行进行错误定位,进行纠错。

12、添加管脚信息。当综合完成后,网表信息才会生成。选择Assignments/Pin Planner,快捷键: 。将引脚列表拉上来。

13、为每个节点分配引脚。双击Location的空白处出现下拉列表选择对应的引脚。

14、全局编译。Processing/Start Compilation,快捷键:

15、从菜单File/New/Other Files中选择创建Vector Waveform File。在新的波形文件中选入需要验证的引脚,通过在左边窗栏里点击鼠标右键,选Insert Node or Bus .. , 在打开的对话框中点击Node Finder,在打开的对话框中点击List, 点击中间第二个快捷键,将所有的信号选到右侧,点击两次OK。此时信号被添加进波形文件左侧。选择所要观察的信号引脚,设置引脚的信号值,单击信号使其变成浅蓝色,选择左侧带时钟的波形按钮: ,给A,B,C添加输入值,修改周期: A周期2.5ns,B周期5ns,C周期10ns。 点击保存Save,注意:一般情况下文件名默认和工程名师一致的,不需要修改,如果重复建立了多个波形图,一定点击file:save as另存为,将波形图名称修改为和工程名称一致,否则无法出现象。Assignments中选择Settings,快捷键: ,列表左侧选中Simulator Settings选择页,设置Function类型仿真,并将新创建的波形文件当作仿真输入,设置完毕之后,点击Processing ->Generate Functional Simulator Netlist, 生产网表文件之后,点击Start Simulator,快捷键: 进行功能仿真,然后验证逻辑功能是否正确。

三、实验过程

在此处填写实验过程并黏贴截图。

四、实验结果与分析

        在本次组合逻辑3-8译码器设计实验中,我深入了解了译码器的基本原理、设计方法和实现步骤。通过亲手搭建电路、编写代码和进行仿真测试,我不仅掌握了理论知识,还获得了宝贵的实践经验。

        通过这次实验,我深刻体会到了理论与实践相结合的重要性。在实验过程中,我不仅学会了如何设计数字电路,还学会了如何运用EDA软件来进行电路仿真和测试。这些技能对于我未来的学习和工作都具有重要的意义。实验中的故障排除和问题解决过程锻炼了我的分析和批判性思维能力。每当遇到错误或不符合预期的结果时,我都需要仔细检查代码,分析可能的原因,并进行相应的调整。这个过程虽然具有挑战性,但它帮助我建立了解决复杂问题的自信。

        此外,我还认识到了团队合作的重要性。在实验过程中,我与同学们进行了深入的交流和讨论,共同解决了许多问题。这种合作不仅提高了我的学习效率,还让我学会了如何与他人进行有效的沟通和协作。

        总的来说,这次组合逻辑3-8译码器设计实验让我受益匪浅。我不仅掌握了数字电路设计的基本技能,还学会了如何运用EDA软件来进行电路仿真和测试。同时,我也深刻体会到了理论与实践相结合的重要性以及团队合作的力量。我相信这些经验和技能将对我未来的学习和工作产生积极的影响。

五、思考题

思考:为什么在功能仿真时输入设置的周期为2倍的关系?

答:1.组合逻辑38译码器在功能仿真时输入设置的周期为2倍的关系,这主要是由于38译码器的输入输出的特性所决定的。

2.在功能仿真时,为了测试38译码器的所有可能的输入组合和对应的输出,通常需要将输入设置为遍历所有可能的组合。

3.由于38译码器有3个输入线,共有8个可能的组合(从000到111),因此设置输入周期为2倍的关系(即每个输入组合持续两个周期)可以确保每个组合都得到充分的测试和验证。

4.这种设置方式有助于确保在仿真过程中,每个输入组合都能被完整地处理并产生相应的输出,从而验证38译码器的功能和性能。综上所述,组合逻辑38译码器在功能仿真时输入设置的周期为2倍的关系,是为了确保每个输入组合都能得到充分的测试和验证,从而全面评估38译码器的功能和性能。

实验二 多路数据选择器

一、实验目的

设计并实现一个16选1多路数据选择器。

二、实验原理

在VHDL语言中描述一个2选1的多路数据选择器的方法有多种,例如:在一个进程中使用if-when-else语句:在一个进程中case语句:使用with select 构造或使用结构VHDL。推荐的使用方法是使用when else构造,这样在VHDL代码中只用1行就可以描述2选1多路选择器。例如:

Library ieee;

Use ieee.std_logic_1164.all;

Entity mux2 is

      Port(a,b,sel:  in  std_logic;

          q:      out  std_logic);

end;

architecture a of mux2 is

begin

q<=a when sel=’0’ else b;

end;

但我们在描述一个16选1的多路数据选择器时,若采用同样的方法,则就需要许多行VHDL代码,此时我们可以在进程中使用case语句会很清晰,但无论使用哪一种描述方法,综合得到的结果是相同的。16选1多路选择器结构图2-1所示。

图2-1 16选1多路选择器

三、实验步骤

1、参考实验一的实验步骤1-6建立工程,注意:建立的工程名称,下一步建立的VHDL文件名称,VHDL中设计的多路选择器的实体名称保持一致

2、建立VHDL文件。File/ New/VHDL File。在VHDL文件中使用VHDL语言设计多路选择器。保存。注意:上一步建立的工程名称,此时保存的VHDL文件名称,VHDL中设计的多路选择器的实体名称保持一致。

3、预编译。选择Processing/Start/Start Analysis&Synthesis,快捷键:,进行综合。如果有错误,双击错误定位到错误附近,改错,再综合,直到没有错误为止。

4、添加管脚信息。当综合完成后,网表信息才会生成。选择Assignments/Pin Planner。快捷键: ,将引脚列表拉上来。注意引脚的分配自行分配可使用的引脚,并记录引脚分配情况。后续连线时使用。

5、为每个节点分配引脚。双击Location的空白处出现下拉列表选择对应的引脚。

6、全局编译。Processing/Start Compilation,快捷键:

7、运用RTL图观察器观察综合完的RTL级电路图,根据RTL级图,可以看出VHDL程序综合成的电路模块,电路结构是否有错误,并观察生成的电路是否为组合电路或时序电路。方法:选择Tools/Netlist Viewer,在出现的下拉菜单中选择RTL Viewer。如果想查看图形中有关模块的电路结构,可以双击有关模块,逐层了解各层次的电路结构。

8、参考实验一的实验步骤15-16进行硬件仿真。

四、实验过程

五、实验结果与分析

实验三 全加器

一、实验目的

设计并实现一个一位全加器。

二、实验原理

计算机中的加法器一般就是全加器,它实现多位带进位加法。下面以一位全加器介绍。

一位全加器有三个输入、两个输出,见图3-1。

图3-1  一位全加器示意图

图中的“进位入”Ci-1指的是低位的进位输出,“进位出”Ci即是本位的进位输出。一位全加器的真值表见表3-1。

表3-1:

输入

输出

Ci-1

Bi

Ai

Si

Ci

0

0

0

0

0

0

0

1

1

0

0

1

0

1

0

0

1

1

0

1

1

0

0

1

0

1

0

1

0

1

1

1

0

0

1

1

1

1

1

1

根据表3-1可写出逻辑函数表达式:

全加功能的硬件实现方法有多种,例如:可以把全加和看作是Ai与Bi的半加和Hi与进位输入Ci-1的半加和来实现。多位全加器就是在一位的原理上扩展而成的。集成电路全加器有7480、7481、7483等。

三、实验步骤

参考实验二建立工程,建立VHDL文件设计一位全加器,全加器的三个输入所对应的管脚同三位拨码开关相连,三个输入端子是a、b、cin,分别代表 Ai、Bi、Ci-1;;两个输出所对应的管脚同两位发光二极管相连,两个输出端子是co、sum,分别代表Ci 、Si。

接线:将CPU的17脚接D1,18脚接D2,19脚接D3,20脚接L1,21脚接L2。
引脚分配如下:(可以不按照此图进行分配)

四、实验过程

1. 在全英文路径下先创建两个文件夹,一个为半加器h_adder,另一个为全加器f_adder。

先在半加器文件夹路径下创建半加器工程文件

半加器程序如下所示。

2. 编译通过后调出hadder.vhd文件界面,对该文件创建symbol。如下图所示。

编译通过如图

  1. 然后把 和其symbol文件 拷贝到f_adder文件夹中。

在全加器文件夹路径下创建全加器工程文件f_adder。创建全加器时把半加器文件添加到全加器工程里面。然后新建图表文件,调用h_adder和or2a创建下列电路图。

保存.bdf文件,若创建工程时没有把半加器文件加入全加器工程,可通过下图操作加入。

  1. 运行原理图

  1. 创建仿真波形界面

五、实验结果与分析:

1. 实验结果

2. 真值表

输入

输出

实验结果

Ci-1

Bi

Ai

Si

Ci

Si

Ci

0

0

0

0

0

0

0

0

0

1

1

0

1

0

0

1

0

1

0

1

0

0

1

1

0

1

0

1

1

0

0

1

0

1

0

1

0

1

0

1

0

1

1

1

0

0

1

0

1

1

1

1

1

1

1

1

3.分析

本次全加器实验,在老师和我们自己通过正确的查询相关资料后,成功地设计并实现了全加器电路。实验结果表明,本实验设计的全加器电路在各种输入情况下都能正确输出相应的和与进位,证明了电路的正确性和实用性。同时,本次实验也加深了我们对EDA工具和数字电路设计原理的理解和应用能力。

实验四 带进位的通用加法器  

一、实验目的

设计并实现一个通用全加器,其位数可根据需要任意设定。

二、实验原理

本实验所设计的加法器作为一个元件被例化时,由其位数根据父程序给定其位宽,所以在设计时,可将其两个输入向量的长度定义为一个类属参数(即一个变量)N,该N的值在例化时确定。其基本原理与实验三的加法器类似,原理框图如图4-1所示。

(被加数)Bi(N-1..0)

全加器

(被加数)Ai(N-1..0)

(进位入)Ci-1

(全加和)Si(N-1..0)

(进位出)Ci

实验源程序文件名是add_n..vhd。

三、实验步骤

程序运行无误后,点击Tools,Netlist Viewers,选择RTL Viewer,观察设计综合出的RTL级电路图。

全加器的输入所对应的管脚同拨码开关相连,9个输入管脚是a0~a3、b0~b3、cin, a0~a3、b0~b3代表两路被加数Ai0~Ai3和Bi0~Bi3,cin代表进位位Ci-1;5个输出所对应的管脚同发光二极管相连,5个输出管脚是sum0~sum3和cout, sum0~sum3代表相加结果Si0~Si3,cout代表进位出Ci。

接线:将CPU的17脚接D1,18脚接D2,19脚接D3,20脚接D4,21脚接D5,22脚接D6,23脚接D7,26脚接D8,27脚接D9,30脚接L9,31脚接L1,32脚接L2,33脚接L3,36脚接L4。

引脚分配如下:

从菜单File/New/Other Files中选择创建Vector Waveform File。

在新的波形文件中选入需要验证的引脚,通过在左边窗栏理点击鼠标右键,选Insert Node or Bus .. , 在打开的对话框中点击Node Finder,在打开的对话框中找到Filter,下拉选择Pins:all,然后点击List, 点击中间第二个快捷键,将所有的信号选到右侧,点击两次OK。此时信号被填进波形文件左侧。注意:不使用实验箱时必须选择Pins:all,否则无法将波填进来。

Assignments中选择Settings,快捷键: 。选中Simulator Settings选择页,设置Function类型仿真,并将新创建的波形文件当作仿真输入。

对两个加数A,B,输出的和S进行数据格式选择。我们仿真时统一将加法器定为4位宽度。所以两个加数和输出的和都是4位宽度。将鼠标放到一个加数A上单击右键,选择最后一项Properties,把Radix下拉菜单选择为Hexadecimal,即16进制表示方式。同理将加数B,和S设置为16进制表示方式。在加数A的前10ns区域里用鼠标拖蓝此区域,单击左侧工具栏中带?的蓝色快捷键,弹出输入值的窗口,输入数据。同理对加数B进行数据值输入。选中进位输入C,单击左侧工具栏中有数字“1”的蓝色快捷键,将进位输入设置为高电平。点击保存Save。

     Assignments中选择Settings,快捷键: 。左侧选中Simulator Settings选择页,设置Function类型仿真,并将新创建的波形文件当作仿真输入。

设置完毕之后,点击Processing ->Generate Functional Simulator NetList, 生产网表文件之后,点击Start Simulator,快捷键: 进行功能仿真,然后验证逻辑功能是否正确。

四、实验过程

一、 4位加法器。

1. 建立工程文件,程序输入,编译。

编译通过

2. 根据实验步骤创建波形文件并设置输入值。

二、  扩展内容:把n=8,计算8位加法器。

1. 更改代码并运行。

2. 根据实验步骤创建波形文件并设置输入值。

三、 把输入输出都设置为无符号的16进制数。

五、实验结果与分析

一、4位的乘法器

1. 实验结果:

 2.真值表:

A

B

R

0

0

0

1

15

15

2

14

24

3

13

39

4

12

48

5

11

55

6

10

60

7

9

63

8

8

64

9

7

63

10

6

60

11

5

55

12

4

48

13

3

39

14

2

28

15

1

15

二、8位的乘法器

1. 实验结果:

2.真值表:

A

B

R

0

59

0

32

102

3264

64

145

9280

96

188

18048

128

231

29568

160

18

2880

192

61

11712

224

104

23296

三、实验结果分析

正确性验证:通过对比实验数据与预期结果,我们发现乘法器能够准确地计算出两个二进制数的乘积。无论是小数值还是大数值乘法,乘法器都表现出良好的正确性和稳定性。

运算速度:乘法器的运算速度符合预期要求。在多个输入周期后,乘法器能够快速地输出正确的乘积结果。然而,当处理大数值乘法时,由于资源限制和运算速度的约束,性能可能会有所下降。

资源消耗:乘法器的资源消耗也在可接受的范围内。虽然使用了一些额外的逻辑门和存储器等资源,但整体资源利用率较高,且未出现明显的资源浪费现象。

通过本次EDA乘法器实验,我们验证了乘法器在二进制乘法运算中的正确性和性能。实验结果表明,乘法器能够准确地计算出两个二进制数的乘积,并且具有较好的运算速度和资源消耗表现。然而,在处理大数值乘法时,乘法器的性能可能会受到一定的限制。

实验六 7段数码管控制接口实验

一、实验目的

  1. 设计共阴数码管动态显示,要求位选动态扫描,段选显示,具体要求有且只有第一位数码管显示“0”,保持1秒;有且只有第二位显示“1”,保持一秒;依次显示,直到有且仅有第八位显示“7”,保持1秒,然后又从第一位显示“8”直到“F”显示完,一直周期性循环。
  2. 要求程序段选数据用ROM实现,将编码值保存在ROM中。

二、实验原理

1. 硬件原理图

位选扫描为SEL[2,0]。7位段选数据DSP[7,0]。


2. 程序模块

AND1代码:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity AND1 is port

   (HZSEL,CR:  in std_logic;

    AD6,AD5,AD4:  out std_logic);

end;

architecture ARC_AND1 of AND1 is

   signal  dou:  std_logic_vector(2 downto 0);

   begin

      AD6<=dou(2);

      AD5<=dou(1);

      AD4<=dou(0);

process(HZSEL,CR)

   begin

   if(CR='0')then

      dou<="000";

   elsif(HZSEL'event and HZSEL='1')then

           if(dou="111")then

               dou<="000";

           else

               dou<=dou+1;

           end if;

        end if;

   end process;

end ARC_AND1;

AND1作用累加产生SEL[2,0]位选信号,同时产生ROM地址A4、A5、A6信号,时钟ck0用高频1M信号驱动。

AND2代码:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity AND_2 is port

   (CKDSP,CR:  in std_logic;

    AD3,AD2,AD1,AD0:  out std_logic);

end;

architecture ARC_AND2 of AND_2 is

   signal  dou:  std_logic_vector(3 downto 0);

   begin

      AD3<=dou(3);

      AD2<=dou(2);

      AD1<=dou(1);

      AD0<=dou(0);

process(CKDSP,CR)

   begin

   if(CR='0')then

      dou<="0000";

   elsif(CKDSP'event and CKDSP='1')then

           if(dou="1111")then

               dou<="0000";

           else

               dou<=dou+1;

           end if;

        end if;

   end process;

end ARC_AND2;

AND2作用产生ROM地址A0、A1、A2、A3信号。ck时钟选1Hz。

ROM代码

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity ROM is port  

(CR,A6,A5,A4,A3,A2,A1,A0:  in std_logic;  

 L6,L5,L4,L3,L2,L1,L0: out std_logic);

end;

architecture arc_ROM of ROM is

signal din:  std_logic_vector(6 downto 0);

signal dout:  std_logic_vector(6 downto 0);

begin

   din<=A6&A5&A4&A3&A2&A1&A0;

process(din)    

begin         

if(CR='1')then

case din is

 when"0000000"=>dout<="1111110"; --0   

 when"0010001"=>dout<="0110000"; --1   

 when"0100010"=>dout<="1101101"; --2   

 when"0110011"=>dout<="1111001"; --3   

 when"1000100"=>dout<="0110011"; --4   

 when"1010101"=>dout<="1011011"; --5   

 when"1100110"=>dout<="1011111"; --6   

 when"1110111"=>dout<="1110000"; --7 

 when"0001000"=>dout<="1111111"; --8   

 when"0011001"=>dout<="1111011"; --9   

 when"0101010"=>dout<="1110111"; --A   

 when"0111011"=>dout<="0011111"; --b   

 when"1001100"=>dout<="1001110"; --C   

 when"1011101"=>dout<="0111101"; --d   

 when"1101110"=>dout<="1001111"; --E   

 when"1111111"=>dout<="1000111"; --F

 when others=>dout<="0000000";

             end case;         

        end if;

end process;

L6<=dout(6);

L5<=dout(5);

L4<=dout(4);

L3<=dout(3);

L2<=dout(2);

L1<=dout(1);

L0<=dout(0);

end arc_ROM;

ROM代码作用根据地址信息选择输出,ROM的地址高3位以1M变化,低4位以1Hz变化,执行“when"0000000"=>dout<="1111110"; --0”,低4位保持“0000”,高3位变化了106次,高3位出现“000”次数为106/8,出现“0000000”次数为106/8。由于低4位“0000”保持1s,所以第一位显示0保持1s。依次类推。

三、实验步骤

1. 引脚分配

2. ck接1Hz,ck0接1M,cr接D1,sel0,sel1,sel2分别接点阵左边的sel0,sel1,sel2,“A、B、C、D、E、F、G”接数码管显示模块的“a、b、c、d、e、f、g”,可参考本程序引脚分配接线,也可重新分配。

仿真步骤同实验4。

四、实验过程

一、 新建文件夹,新建工程,新建VHDL输入文件

1. AND1文件

  1. AND_2文件

  1. ROM文件

  • 编译通过后调出AND1.vhd,AND_2.vhd,ROM.vhd文件界面,对该文件创建symbol。如下图所示。

  • 保存.bdf文件,把AND1,AND_2,ROM文件加入工程,可通过下图操作加入。

  • 创建原理图

  • 运行原理图

  • 创建仿真文件

五、实验结果与分析

1. 寄存器级电路图:

2. 仿真结果波形图

3. 实验结果分析

    功能验证:通过实验,我们验证了AND累加器和7段数码显示译码电路的功能,确保它们能够正确地完成计数和译码显示的任务。时序分析:在仿真测试中,我们观察了7段数码显示译码电路的时序波形图,确保它们的工作时序是正确的,并且能够满足设计要求。

实验七 计数器

一、实验目的

  1. 设计一个带同步使能输入及同步清0的增1计数器,仿真波形图见图20-1;
  2. 设计一个带同步使能输入及同步清0的增1/减1的8位计数器,仿真波形图见图20-2A和20-2B,根据后面的实验程序up-down.vhd进行修改得到本题要求。

二、实验原理

图20-1  计数器2波形图

图20-2A  加减控制计数器波形图

在用VHDL语言描述一个计数器时,如果使用了程序包ieee.std_logic_unsigned,则在描述计数器时就可以使用其中的函数“+”(递增计数)和“-”(递减计数)。假定设计对象是增1计数器并且计数器被说明为向量,则当所有位均为‘1’时,计数器的下一状态将自动变成‘0’。举例来说,假定计数器的值到达“111”是将停止,则在增1之前必须测试计数器的值。

图20-2B  加减控制计数器波形图

如果计数器被说明为整数类型,则必须有上限值测试。否则,在计数顺值等于7,并且要执行增1操作时,模拟器将指出此时有错误发生。

下面的例子是一个3位增1/减1计数器:当输入信号UP等于1 时计数器增1;当输入信号UP等于0时计数器减1。

Library ieee;

Use ieee.std_logic_1164.all;

Use ieee.std_logic_unsigned.all;

Entity up_down is

       Port(clk,rst,en,up:  in    std_logic;

              Sum:      out  std_logic_vector(2 downto 0);

              Cout:      out  std_logic);

End;

Architecture a of up_down is

Signal count:  std_logic_vector(2 downto 0);

Begin

       Process(clk,rst)

       Begin

              If rst=’0’ then

                     Count<=(others=>’0’);

              Elsif rising_edge(clk) then

                     If en=’1’ then

                            Case up is

                                   When ‘1’ => count<=count+1;

                                   When others =>count<=count-1;

                            End case;

                     End if;

              End if;

       End process;

       Sum<=count;

       Cout <=’1’ when en=’1’ and ((up=’1’ and count=7) or (up=’0’ and count=0)) else ‘0’;

End;

参考以上实例完成实验目的中所要求的3个计数器的设计。

三、实验步骤

实验1输入信号有clk(时钟信号)、clr(复位信号)、en(使能控制输入信号),clk用CPLD/FPGA适配器板子上的时钟信号,接数字信号源的CLK5,频率调节到200KHz左右,clr、en接拨码开关,工作时clr为低电平,en为高电平;输出信号有Q0~Q3,接LED灯。

连线:CPU的100脚接CLK(200KHZ),101脚接D1,109脚接D2,110脚接L1,111脚接L2,112脚接L3,113脚接L4。

引脚分配如下:

实验2输入信号有clk(时钟信号)、rst(复位信号)、en(使能控制输入信号)、up(加减控制输入信号),clk用CPLD/FPGA适配器板子上的时钟信号,接数字信号源的CLK5,频率调节到1Hz左右,rst、en、up接拨码开关,工作时rst和en为高电平,up为高电平时增计数,为低电平时减计数;输出信号有SUM0~SUM2(代表输出数据)和COUT(代表进位或借位),都接LED灯。

接线:CPU的13脚接CLK(1HZ),14脚接L1,15脚接D1,16脚接D2,17脚接L2,18脚接L3,19脚接L4,24脚接D3。

引脚分配如下:

在做实验时,请注意仿真波形图中各个输入信号的有效电平。

四、实验过程

1. 新建文件夹,新建工程,新建VHDL输入文件

2. 编译运行文件

  1. 从菜单File/New/Other Files中选择创建University Program VWF, 如下图所示。在新的波形文件中选入需要验证的引脚,通过在左边窗栏里点击鼠标右键,选Insert Node or Bus .. , 在打开的对话框中点击Node Finder,在打开的对话框中点击List, 点击中间第二个快捷键,将所有的信号选到右侧,点击两次OK。此时信号被添加进波形文件左侧。选择所要观察的信号引脚,设置引脚的信号值。

五、实验结果与分析

一、实验结果

1.增/减计数器

       2.真值表

Up

Sum

0

0

1

1

1

2

1

3

1

4

1

5

1

6

1

7

0

6

0

5

0

4

0

3

0

2

0

1

0

0

二、实验结果分析

增功能:当增减控制信号为高电平时,计数器在时钟信号的上升沿进行递增计数。通过波形仿真,可以观察到计数器的输出从000递增到111,符合设计要求。递减功能:当增减控制信号为低电平时,计数器在时钟信号的上升沿进行递减计数。通过波形仿真,可以观察到计数器的输出从111递减到000(或保持在下溢前的值),符合设计要求。复位功能:当复位信号为低电平时,计数器被清零,输出为000。通过波形仿真,可以观察到在复位信号有效时,计数器的输出立即变为000,符合设计要求。

实验八 矩阵键盘控制接口

一、实验目的

设计并实现一个4×8键盘接口控制器,含有时序产生电路、键盘扫描电路、弹跳消除电路、键盘译码电路、按键码存储电路、显示电路。要求:当按下某一键时,在数码管上显示该键对应的键值。

二、实验原理

实验仪器中4×8矩阵键盘的电路原理图如图50-1所示。

图50-1  4×8矩阵键盘电路原理图

扫描信号为BCOM[8..1],在BCOM[8..1]前已接有一个3-8译码器,3-8译码器的输入为SEL0~SEL3。当3-8译码器的输入为“000”时,即BCOM1为‘0’,其他位为‘1’,我们按下第一排第一键,此时KIN0输出‘0’,KIN1~KIN3输出全为‘1’,按下第二排第二键时,KIN1输出‘0’,其他输出‘1’;当3-8译码器输入为001时,即BCOM2为‘0’,我们按下第一排第二键,此时KIN0输出‘0’,KIN1~KIN3输出全为‘1’,同理其他键依此类推。

键盘上的每个按键就是一个开关,当某键被按下时,该按键的接点会呈现‘0’状态,反之为‘1’。扫描信号为SEL[2..0]进入3-8译码器,再从译码器输出到键盘,所以第一次只能扫描一排,依此周而复始。按键位置与数码的关系如表50-1所示。

若从KIN[3..0]输出的皆为‘1’时,表示没有按键按下,代表该列没有按键被按下,则不进行按键编码的操作,反之,如果有被按下时,则应将KIN[3..0]读出的值送到译码电路进行编码。

表50-1  按键位置与数码关系

SEL2~SEL0

KIN3~KIN0

对应的按键

000

1110

0

1101

6

1011

LAST

0111

CTRL

001

1110

1

1101

7

1011

STEP

0111

EMPTY1

010

1110

2

1101

REG

1011

C

0111

EMPTY2

011

1110

3

1101

EXEC

1011

D

0111

EMPTY3

100

1110

MEM

1101

8

1011

E

0111

EMPTY4

101

1110

ESC

1101

9

1011

F

0111

SHIFT

110

1110

4

1101

A

1011

NEXT

0111

NONE

111

1110

5

1101

B

1011

ENTER

0111

NONE

光靠矩阵键盘是无法正确地完成输入工作的,另外还需搭配以下几个电路模块:

时钟产生电路:

当一个系统中使用不同操作频率的脉冲波形时,最方便的方法就是利用一个自由计数器来产生各种频率。本电路中就使用三种不同频率的工作脉冲波形。它们分别是:系统时钟(它是系统内部所有时钟的提供者,频率最高)、弹跳消除取样信号、键盘扫描信号和七段显示器扫描信号。在很多的电路设计中,键盘扫描信号和七段显示器扫描信号可以使用相同的时钟信号,本设计也采用此方法。

具体做法:

  • 先建立一个N位的计数器,N的大小由电路的需求所定。N的值越大,分频的次数就越多,但所占用的空间也越大。
  • 若要得到一个脉冲波形信号,可以只取计数器中一个值,如使用CLK<=Q(4)语句,其值变化为0-1-0-1-1……。
  • 若要得到脉冲波形序列,可以取计数器中的几个值,如使用CLK<=Q(4 DOWNTO 3)语句,其值变化为00-01-10-11-00-01……。
  1. 键盘扫描电路

扫描电路的作用是用来提供键盘扫描信号(表50-1中的SEL2~SEL0)的电路,扫描信号的变化的顺序依次为000-001-010-011-100-101-110-111……依次的周而复始。扫描时依序分别扫描八列按键,当扫描信号为000时,扫描0这一列按键……每扫描一列按键,就检查一次是否有按键按下,如果这排有按键按下,就马上停止扫描,立即进行按键编码动作,存储键码,如果没有按键按下,则继续扫描下一列。

  1. 弹跳消除电路

因为按键大多是机械式开关结构,在开关切换的瞬间会在接触点出现来回弹跳的现象,对于激活关闭一般电器并不会有何影响,但对于灵敏度较高的电路,却有可能产生误动作而出错。

弹跳现象产生的原因可从图50-2说明。虽然只是按下按键一次然后放掉,然而实际产生的按键信号却不只跳动一次,经过取样的检查后将会造成误判,以为按键两次。

按键信号

抽样信号

抽样结果

图50-2  弹跳现象产生错误的抽样结果

如果调整抽样频率(如图50-3),可以发现弹跳现象获得了改善。

按键信号

抽样信号

抽样结果

图50-3  调整抽样频率后得到的抽样结果

因此必须加上弹跳消除电路,避免误操作信号的发生。注意,弹跳消除电路所使用脉冲信号的频率必须比其它电路使用的脉冲信号的频率更高;通常将扫描电路或LED显示电路的工作频率定在24HZ左右,两者的工作频率是通常的4倍或更高。

键盘译码电路

上述键盘中的按键可分为数字键和功能键。

数字键主要用来输入数字,但从表50-2中发现,键盘所产生的输出KIN3~KIN0无法拿来直接使用;另外不同的数字按键也担负不同的功能,因此必须由键盘译码电路来规划第个按键的输出形式,以便执行相应的动作。

有了表50-2,要写出键盘译码电路的VHDL程序就非常容易了,尤其针对有表可以对照的电路设计,只要使用CASE-WHEN或WHNE-ELSE语句,便可轻松完成设计。

表50-2  键盘参数表

SEL2~SEL0

KIN3~KIN0

对应的按键

键盘译码输出

按键功能

000

1110

0

00000

数字0

1101

6

00100

数字6

1011

LAST

10100

功能键

0111

CTRL

11000

功能键

001

1110

1

00001

数字1

1101

7

00111

数字7

1011

STEP

10101

功能键

0111

EMPTY1

11010

扩展1

010

1110

2

00010

数字2

1101

REG

10010

功能键

1011

C

01100

字母C

0111

EMPTY2

11011

扩展2

011

1110

3

00011

数字3

1101

EXEC

10011

功能键

1011

D

01101

字母D

0111

EMPTY3

11100

扩展3

100

1110

MEM

10000

功能键

1101

8

01000

数字8

1011

E

01110

字母E

0111

EMPTY4

11101

扩展4

101

1110

ESC

10001

功能键

1101

9

01001

数字9

1011

F

01111

字母F

0111

SHIFT

11001

功能键

110

1110

4

00100

数字4

1101

A

01010

字母A

1011

NEXT

10110

功能键

0111

NONE

11110

无定义

111

1110

5

00101

数字5

1101

B

01011

字母B

1011

ENTER

10111

功能键

0111

NONE

11110

无定义

译码电路负责的工作有:

          1. 判别是否有键按下。
          2. 若被按下的是数字键或字母键,则编码成相对应的16进制编码
          3. 若被按下的是数字键,除进行16进制编码外,同时还编码成BCD码。
          4. 若按下是的功能键或其他按键,则编码成16进制编码。
  1. 按键码存储电路

因为每次扫描会产生新的按键数据,可能会覆盖前面的数据,所以需要一个按键存储电路,将整个键盘扫描完毕后记录下来。按键存储电路可以用移位寄存器构成,在这里对移位寄存器就不再介绍,请参阅前面相关实验。

键盘接口电路的引脚如图50-4所示。

图50-4  矩阵键盘接口模块引脚图

三、实验步骤

将clk时钟接5KHZ时钟输入, clr接拨码开关D1,key[3..0]分别接实验仪器的键盘输出KIN[3..0],SELOUT[2..0]分别接实验仪器的扫描输入selout[2..0],segout[6..0]分别接7段LED输入G~A。

引脚分配参考下表:

四、实验过程

1. 新建文件夹,新建工程,新建VHDL输入文件

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY sy8 IS

PORT(CLK,RST,EN:  IN STD_LOGIC;

KC:IN STD_LOGIC_VECTOR(3 DOWNTO 0);--列

KR:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--行

LEDG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--数码管段码

SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));--数码管位选

END;

ARCHITECTURE BHV OF sy8 IS

BEGIN

PROCESS(CLK,RST,EN)

VARIABLE RC:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE K:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE ROW:STD_LOGIC_VECTOR(3 DOWNTO 0);

VARIABLE Q:STD_LOGIC_VECTOR(1 DOWNTO 0);

--定义八个变量用于存储对应数码管的值;

VARIABLE Q1:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  Q2:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  Q3:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  Q4:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  Q5:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  Q6:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  Q7:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  Q8:STD_LOGIC_VECTOR(7 DOWNTO 0);

VARIABLE  COUNT:STD_LOGIC_VECTOR(2 DOWNTO 0);

VARIABLE  SELG:STD_LOGIC_VECTOR(2  DOWNTO 0);

VARIABLE  T:STD_LOGIC_VECTOR(9 DOWNTO 0);

VARIABLE  FLAG:STD_LOGIC;

BEGIN

IF RST='0' THEN--当复位信号为低电平时,复位

Q8:="00000000";

Q7:="00000000";

Q6:="00000000";

Q5:="00000000";

Q4:="00000000";

Q3:="00000000";

Q2:="00000000";

Q1:="00000000";

COUNT:="000";

SELG:="000";

ELSIF CLK'EVENT AND CLK='1' THEN--获取时钟上升沿信号

Q:=Q+1;

CASE Q IS

WHEN "00"=>ROW:="1110";KR<=ROW; --扫描第一列

WHEN "01"=>ROW:="1101";KR<=ROW; --扫描第二列

WHEN "10"=>ROW:="1011";KR<=ROW; --扫描第三列

WHEN "11"=>ROW:="0111";KR<=ROW; --扫描第四列

WHEN OTHERS=>NULL;

END CASE;

IF EN='1' THEN

    CASE ROW IS

        WHEN "1110"=>

CASE KC IS

WHEN "0111"=>RC:="11101110";--扫描第一行,按键按下则为1

 WHEN "1011"=>RC:="11101101"; --扫描第二行,按键按下则为4

WHEN "1101"=>RC:="11101011"; --扫描第三行,按键按下则为7

WHEN "1110"=>RC:="11100111"; --扫描第四行,按键按下则为E

WHEN OTHERS=>NULL;

END  CASE;

WHEN "1101"=>

CASE KC IS

WHEN "0111"=>RC:="01111110";--扫描第一行,按键按下则为A

 WHEN "1011"=>RC:="01111101"; --扫描第二行,按键按下则为B

WHEN "1101"=>RC:="01111011"; --扫描第三行,按键按下则为C

WHEN "1110"=>RC:="01110111"; --扫描第四行,按键按下则为D

WHEN OTHERS=>NULL;

END  CASE;

WHEN "1011"=>

CASE KC IS

WHEN "0111"=>RC:="10111110";--扫描第一行,按键按下则为3

WHEN "1011"=>RC:="10111101"; --扫描第二行,按键按下则为6

WHEN "1101"=>RC:="10111011"; --扫描第三行,按键按下则为9

WHEN "1110"=>RC:="10110111"; --扫描第四行,按键按下则为C

WHEN OTHERS=>NULL;

END  CASE;

WHEN "0111"=>

CASE KC IS

WHEN "0111"=>RC:="11011110";--扫描第一行,按键按下则为2

WHEN "1011"=>RC:="11011101"; --扫描第二行,按键按下则为5

WHEN "1110"=>RC:="11010111"; --扫描第四行,按键按下则为0

WHEN OTHERS=>NULL;

END  CASE;

WHEN OTHERS =>NULL;

END CASE;

END IF;

T:=T+1;--每次时钟上升沿T自增1

IF T="0011101101"  THEN--当T满足“0011101101”时

    FLAG:='1';--标志为FLAG为1,即允许按键输入

T:=T-T;--可以适当修改T的值,使得按键灵敏度达到最佳

END IF;

SELG:=SELG-1;--数码管位选自减1

IF(RC/="11111111")AND (FLAG='1') THEN--按键输入一个值时将数码管对应值向左移

Q8:=Q7;

Q7:=Q6;

Q6:=Q5;

Q5:=Q4;

Q4:=Q3;

Q3:=Q2;

Q2:=Q1;

Q1:= RC;

FLAG:='0';-- 标志位返0,目的是避免按键按下一次输入多个值

T:=T-T;--计数器T清0

IF Q8="00000000" THEN--每有一个按键值输入时

    COUNT :=COUNT-1;--COUNT自减1,目得是存储位选值循环的条件

ELSE--当Q8 的值不为0时,说明有8个数输入了,位选信号可以从111自减到000

    COUNT:="000";

END IF;

END IF;

IF FLAG='0' THEN--在标志位为0时

RC:="11111111";--RC始终为“11111111”,避免一次输入多个值

END IF;

IF (SELG<COUNT)OR (Q1="00000000" )  THEN

    SELG:="111";--每当数码管 位选达到最后一位要显示 的位置时,位选重新回归111

END IF;

SEL<=SELG;--把位选信号传递给位选因脚 

--数码管与对应存储数据之间的关系

CASE SELG IS

    WHEN "000"=>K:=Q8;

WHEN "001"=>K:=Q7;

WHEN "010"=>K:=Q6;

WHEN "011"=>K:=Q5;

WHEN "100"=>K:=Q4;

WHEN "101"=>K:=Q3;

WHEN "110"=>K:=Q2;

WHEN "111"=>K:=Q1;

WHEN OTHERS =>NULL;

END CASE;

--数码管显示译码部分

CASE K IS

WHEN "11010111" =>LEDG<="00111111";--0

WHEN "11101110" =>LEDG<="00000110";--1

WHEN "11011110" =>LEDG<="01011011";--2

WHEN "10111110" =>LEDG<="01001111";--3

WHEN "11101101" =>LEDG<="01100110";--4

WHEN "11011101" =>LEDG<="01101101";--5

WHEN "10111101" =>LEDG<="01111101";--6

WHEN "11101011" =>LEDG<="00000111";--7

WHEN "11011011" =>LEDG<="01111111";--8

WHEN "10111011" =>LEDG<="01101111";--9

WHEN "01111110" =>LEDG<="01110111";--A

WHEN "01111101" =>LEDG<="01111100";--B

WHEN "01111011" =>LEDG<="00111001";--C

WHEN "01110111" =>LEDG<="01011110";--D

WHEN "11100111" =>LEDG<="01111001";--E

WHEN "10110111" =>LEDG<="01110001";--F

WHEN  OTHERS =>LEDG<="00000000";

END CASE;

END IF;

END PROCESS;

END BHV;

编译运行文件

创建仿真波形图

五、实验结果与分析

1.寄存器级电路图

3.实验结果分析

矩阵键盘控制接口的设计主要基于行列扫描的原理。在一个典型的4x4矩阵键盘中,共有16个按键,但仅通过8个I/O端口即可实现控制。其中,4个端口用于控制行(作为输出),另外4个端口用于检测列(作为输入)。当某一按键被按下时,对应的行和列将形成闭合回路,从而被微处理器检测并识别。

实验九 任意波形发生器电路

一、实验目的

设计任意波形发神器,将波形数据烧写到外部的ROM 2864中。

二、实验原理

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity generator is

port (CLKIN,RESET: in std_logic;

      KK : in std_logic_vector(3 downto 0);

      DIN: in std_logic_vector(7 downto 0);

      DOUT: out std_logic_vector(7 downto 0);

      ADDR: out std_logic_vector(12 downto 0)

      );

end generator;

architecture doit of generator is

signal counter,decount : std_logic_vector(7 downto 0);

signal sd0,sd1,sd2,sd3,sd4 : std_logic_vector(7 downto 0);

signal clk1,clk :std_logic;

begin

P1: process(CLKIN)

 begin

   if(CLKIN'event and CLKIN='1') then

     clk1<=not(clk1);

   end if;

end process P1;

clk<=CLKIN when KK="0010" or KK="0100" or KK="1001" else

     clk1;

  

P2: process(RESET,clk)

 begin

   if (RESET='0') then

      counter<="00000000";

   elsif(clk'event and clk='1') then

      counter<=counter+1;

   end if;

end process P2;

ADDR<="0010000000000"+("0000" & counter);

decount<=not(counter)+1;

sd0<=counter;

sd1<="00000000" when counter<="10000000" else

     "11111111";

sd2<="00000000" when counter<="01010101" else

     "11111111";

sd3<="00000000" when counter<="10101010" else

     "11111111";

sd4<=counter+counter when counter<"10000000" else

     "11111111" when counter="10000000" else

     decount+decount;

DOUT<=DIN when KK="0001" or KK="0010" else

      sd0 when KK="0011" or KK="0100" else

      sd1 when KK="0101" else

      sd2 when KK="0110" else

      sd3 when KK="0111" else

      sd4 when KK="1000" or KK="1001" else

      "00000000";

end doit;

三、实验步骤

--时钟CLKIN(96脚)接10MHz,

--RESET(137脚)接K1,

--KK[0-3](132,133,135,136脚)分别接D1-D4。

--DOUT[0-7](114,116,117,118,119,120,121,122脚)分别接D/A的D0-D7, D/A的CE、CS接GND。(DA跳线帽短接左侧)

--DIN[0-7](100,101,102,109,110,111,112,113)接2864的D0-D7。

--ADDR[0-12](17,18,19,20,21,22,23,26,27,28,29,30,95)接2864的A0-A12,

--2864的/WE,/OE接GND,/CE接VCC。

--需先用烧录器将正弦波数据写入2864的0400H-04FFH.

--实验结果:D4-D0为选择开关,用示波器测D/A输出,结果见指导书。

引脚分配如下:

仿真步骤同实验4。

四、实验过程

1、新建文件夹D:/GDRSIN_GNT;后续工程的所有文件都放在该文件夹中。打开Quartus软件新建工程GDRSIN_GNT;

2、建立正弦波形数据文件gdrdata7X8.mif。

录入教材163页图6-11的正弦波数据,保存文件名为gdrdata7X8.mif,如下图所示。

3、新建LPM组件正弦波数据存储ROM文件GDRROM78。

给ROM文件选择其内部数据为数据文件gdrdata7X8.mif

  1. 新建LPM组件地址发生器7位计数器GDRCNT7B。

从A rithmetic选项中找计数器

5、把GDRROM78和GDRCNT7B添加如工程。

打开GDRROM78.vhd文件,创建为symbol文件。

打开GDRCNT7B.vhd文件,创建为symbol文件。

6、新建原理图顶层文件GDRSIN-GNT文件。

调用GDRCNT7B和GDRROM78组件,按下图(教材174页图6-26)画图连线,保存文件名为GDRSIN_GNT.bdf。编译。

修改引脚名称,并把原理图保存为GDRSIN_GNT.bdf

编译成功。

7、设置仿真参数。

五、实验结果与分析

  1. 寄存器级电路图

  1. 仿真结果波形图

  1. 实验结果分析

输出波形:实验成功输出了正弦波波形。 输出波形频率:通过调整地址发生器的参数,实验成功实现了不同频率的波形输出,验证了波形发生器电路的频率可调性。输出波形精度:实验结果表明,输出波形的精度较高,与理论值相符,验证了波形发生器电路的准确性。本次实验,我们成功掌握了EDA技术在波形发生器设计中的应用,了解了波形发生器的基本原理和设计方法。实验结果表明,我们设计的波形发生器电路能够输出多种波形、具有频率可调性等特点,且电路稳定性良好。

EDA实验考试

EDA实验考试

班级:

成绩:

学号:

姓名:

实验题目:采用QuartusII软件的原理图设计形式,调用74LS138完成组合逻辑38译码器的设计,基于真值表开展功能仿真。

关键实验步骤:

1、打开QuartusII软件

2、选择路径

3、选择FPGA器件

4、结束设置

5、建立原理图文件

6、原理图设计

7、预编译

8、进行仿真,从菜单File/New/Other Files中选择创建University Program VWF, 如下图所示

9、在新的波形文件中选入需要验证的引脚,通过在左边窗栏里点击鼠标右键,选Insert Node or Bus .. , 在打开的对话框中点击Node Finder,在打开的对话框中点击List, 点击中间第二个快捷键,将所有的信号选到右侧,点击两次OK。

10、选择所要观察的信号引脚,设置引脚的信号值,单击信号使其变成浅蓝色,选择左侧带时钟的波形按钮:

,给A添加输入值,并修改周期:下图表示A被设置为二进制数,初始值为000,增量为1,周期为40ns。

11、设置完毕之后,点击快捷键:

进行功能仿真

实验仿真结果及说明:

仿真结果如下:

通过3-8译码器的设计,让我掌握组合逻辑电路的设计方法。同时也掌握了组合逻辑电路的静态测试方法和了解到了可编程器件设计的全过程。1.软件熟悉:在进行仿真实验之前,首先要熟悉所选用工具的基本操作和功能。这包括如何添加元件、连接线路、设置输入输出以及进行仿真测试等。

2.电路设计:根据38译码器的逻辑功能,设计出对应的电路图。38译码器通常由3个输入和8个输出组成,每个输出对应一个特定的输入组合。设计时需要使用到与门(AND gate)、非门(NOT gate)等基本逻辑门。

3.电路搭建:根据设计好的电路图,使用软件提供的逻辑门元件进行电路搭建。注意连接的正确性,避免出现错误的连接。

4.仿真测试:搭建完成后,进行电路的仿真测试。可以通过软件提供的测试工具,如逻辑分析仪或者示波器,来观察输入输出之间的关系,验证电路的功能是否符合预期。

5.调试与优化:如果在仿真过程中发现问题,需要根据问题现象进行分析,找出可能的错误,并进行调试。这可能包括检查电路连接、修改逻辑门配置或者调整输入输出设置等。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;