第7章 VHDL设计应用实例 7.1 8位加法器的设计 7.2 分频电路 7.3 数字秒表的设计.

Slides:



Advertisements
Similar presentations
什么是SOPC: SOPC是英文System On a Programmable Chip的缩写,称为片上可编程系统。SOPC将传统的EDA技术、计算机系统、嵌入式系统、数字信号处理等融为一体,综合了各自的优势,且在结构上形成一块芯片。 为什么用SOPC:SOPC是现代电子技术和电子系统设计的发展趋势,建立了电子系统设计的新模式。用户利用SOPC开发平台,自行设计高速、高性能的DSP处理器、特定功能的CPU及其外围接口电路,创建结构最为简洁的电子系统。
Advertisements

和码汉字字形技术 和码汉字字形学习法 和码汉字字形输入法.
做实验过程中发现的问题: 新建时工程文件夹建立了,但所建实体文件并没存放在其中 文件名不能用汉字
陶板屋 組員:陳婷 劉峻愷 趙崇佑 陳鵬如.
《 E D A 技 术》 课 程 教 学 讲授:伍宗富 湖南文理学院电气与信息工程学院 2017年3月19日星期日.
第4章 VHDL设计初步.
認識拿破崙˙波拿巴 關於一位運氣很差的矮子的趣事兩三件 我不是矮子!! 本日主角 重點不是這個吧? 惡搞人員:橘蘋3顆和一隻小精靈.
Combinational Logic 組合邏輯
太陽能發電、風力發電 原理概論及實體應用範例
船舶高级消防 第七章 船舶灭火中的危险与应对措施.
第6章 VHDL设计应用实例 6.1 8位加法器的设计 6.3 序列检测器的设计 6.4 正负脉宽数控调制信号发生器的设计
电工电子实验中心.
EPF10K10TI144-4晶片燒錄.
硬件描述语言VHDL及其应用 哈工大微电子中心 王 进 祥 讲课地点:A213 电话:
第三章 组合逻辑电路 第一节 组合电路的分析和设计 第二节 组合逻辑电路中的竞争与冒险 第三节 超高速集成电路硬件描述语言VHDL
題目:十六對一多工器 姓名:李國豪 學號:B
第1章 FPGA概述 1.1 FPGA的发展历程 1.2 FPGA的基本原理 1.3 FPGA的设计方法 1.4 FPGA的设计流程
VHDL數位電路實習與專題設計 文魁資訊-UE301
VHDL數位電路實習與專題設計 文魁資訊-UE301
8.9二进制振幅键控(ASK) 调制器与解调器设计
Ch01-2 Verilog語法 資料流(DataFlow)設計 行為(Behavior)設計
VHDL 硬體描述語言 數位電路設計實務 第四章 VHDL 的語言結構.
第4章 常用EDA工具软件操作指南 4.1 Lattice ispEXPERT 操作指南
VHDL 硬體描述語言 數位電路設計實務 第六章 函數副程序以及套件程式庫.
EDA原理及应用 何宾
使用VHDL設計—4位元減法器 通訊一甲 B 楊穎穆.
EDA原理及应用 何宾
使用VHDL設計—4位元加法器 通訊一甲 B 楊穎穆.
第九章 数字系统设计 数字系统设计概述 ASM图、MDS图以及 ASM图至MDS图的转换 数字密码引爆器系统设计 数字系统设计实例 小结.
使用VHDL設計—4位元位移器 通訊一甲 B 楊穎穆.
欢迎参加VHDL培训 VHDL培训教程 浙江大学电子信息技术研究所 电子设计自动化(EDA)培训中心
第13章 数字电路基础 13.1 数字电路概述 13.2 数字电路中的数值与码制 13.3 逻辑代数 13.4 逻辑门电路
使用VHDL設計—向上&向下計數器 通訊一甲 B 楊穎穆.
计算机操作系统 第二章 进程管理 高校教师、高级项目经理 任铄 QQ:
使用VHDL設計-XOR_GATE 通訊一甲 B 楊穎穆.
Danny Mok Altera HK FAE AHDL培训教材 Danny Mok Altera HK FAE 2018/12/9 P.1.
第2章 Quartus II设计向导 2.1 频率计的VHDL设计 2.2 使用宏功能块设计频率计 2.3 嵌入式系统块ESB的应用
第14章 其它DSP设计库 14.1 总线控制库 14.2 复数信号库 14.3 Gates库 14.4 状态机函数库
使用VHDL設計--Moore Machine
陳慶瀚 機器智慧與自動化技術(MIAT)實驗室 國立中央大學資工系 2013年5月28日
EDA 技术实用教程 第 5 章 QuartusII 应用向导.
使用VHDL設計-多工器/解多工器 通訊一甲 B 楊穎穆.
第12章 图像边缘检测器的设计与分析 12.1 系统设计要求 12.2 系统设计方案 12.3 主要LPM原理图和VHDL源程序
第四章 PL/SQL控制结构 If-then:如果条件为true,则执行一行或多行代码,如果条件为假,转到end if之后。
第五章 VHDL设计基础 本章重点: 本章难点: VHDL程序结构 VHDL的基本数据类型 VHDL的基本描述语句 基本组合逻辑电路设计
義守大學電機工程學系 陳慶瀚 第3章 VHDL Concurrent語法 義守大學電機工程學系 陳慶瀚
第六章 VHDL设计共享.
第五章 VHDL主要描述语句.
移相正弦信号发生器设计 采用直接数字综合器DDS发生器的设计 原理:图1是此电路模型图
使用VHDL設計—4位元ALU電路 通訊一甲 B 楊穎穆.
第一次上机安排 第六周 第七周 周一晚(提高1、2,通信001~012) 周二上(通信014~085) 周四上(通信086~154)
抢答器 设计一个2人抢答器。要求如下: 设计任务 1.两人抢答,先抢为有效,用发光二极 管显示是否抢到优先答题权。
计算机学院 数字逻辑实验的要求.
使用VHDL設計 七段顯示器 通訊工程系 一年甲班 姓名 : 蘇建宇 學號 : B
數位邏輯設計 VHDL.
使用VHDL設計-XOR_GATE 通訊一甲 B 楊穎穆.
使用VHDL設計-8x1多工器 通訊一甲 B 楊穎穆.
自停式向下計數器 通訊一甲 B 楊穎穆.
使用VHDL設計-8x3編碼電路 通訊一甲 B 楊穎穆.
第11章 直接数字频率合成器的设计与分析 11.1 系统设计要求 11.2 系统设计方案 11.3 主要VHDL源程序
可變式計數器 通訊一甲 B 楊穎穆.
使用VHDL設計-七段顯示 通訊一甲 B 楊穎穆.
陳慶瀚 機器智慧與自動化技術(MIAT)實驗室 國立中央大學資工系 2009年10月22日
FPGA组合逻辑 王安然.
按键处理部分 王安然.
Programmable Logic System Design
陳慶瀚 機器智慧與自動化技術(MIAT)實驗室 國立中央大學資工系 2013年5月28日
使用VHDL設計-七段顯示 通訊一甲 B 楊穎穆.
第七章 基本逻辑电路设计.
Programmable Logic System Design
Presentation transcript:

第7章 VHDL设计应用实例 7.1 8位加法器的设计 7.2 分频电路 7.3 数字秒表的设计

7.1 8位加法器的设计 1.设计思路 加法器是数字系统中的基本逻辑器件,减法器和硬件乘法器都可由加法器来构成。多位加法器的构成有两种方式:并行进位和串行进位。并行进位加法器设有进位产生逻辑,运算速度较快;串行进位方式是将全加器级联构成多位加法器。

并行进位加法器通常比串行级联加法器占用更多的资源。随着位数的增加,相同位数的并行加法器与串行加法器的资源占用差距也越来越大。因此,在工程中使用加法器时,要在速度和容量之间寻找平衡点。 实践证明,4位二进制并行加法器和串行级联加法器占用几乎相同的资源。这样,多位加法器由4位二进制并行加法器级联构成是较好的折中选择。本设计中的8位二进制并行加法器即是由两个4位二进制并行加法器级联而成的,其电路原理图如图7.2所示。

图7.2 8位加法器电路原理图

2.VHDL源程序 1) 4位二进制并行加法器的源程序ADDER4B.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY ADDER4B IS --4位二进制并行加法器 PORT(C4: IN STD_LOGIC; --低位来的进位

A4: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --4位加数 B4: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --4位被加数 S4: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--4位和 CO4: OUT STD_LOGIC); --进位输出 END ENTITY ADDER4B; ARCHITECTURE ART OF ADDER4B IS SIGNAL S5:STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL A5,B5: STD_LOGIC_VECTOR(4 DOWNTO 0);

BEGIN A5<='0'& A4; --将4位加数矢量扩为5位,为进位提供空间 B5<='0'& B4; --将4位被加数矢量扩为5位,为进位提供空间 S5<=A5+B5+C4 ; S4<=S5(3 DOWNTO 0); CO4<=S5(4); END ARCHITECTURE ART;

2) 8位二进制加法器的源程序ADDER8B.VHD LIBRARY IEEE; USE IEEE.STE_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL: ENTITY ADDER8B IS --由4位二进制并行加法器级联而成的8位二进制加法器 PORT(C8:IN STD_LOGIC; A8:IN STD_LOGIC_VECTOR(7 DOWNTO 0); B8:IN STD_LOGIC_VECTOR(7 DOWNTO 0);

S8:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); CO8:OUT STD_LOGIC); END ENTITY ADDER8B; ARCHITECTURE ART OF ADDER8B IS COMPONENT ADDER4B IS --对要调用的元件ADDER4B的界面端口进行定义 PORT(C4:IN STD_LOGIC; A4:IN STD_LOGIC_VECTOR(3 DOWNTO 0);

B4:IN STD_LOGIC_VECTOR(3 DOWNTO 0); S4:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CO4:OUT STD_LOGIC); END COMPONENT ADDER4B; SIGNAL SC:STD_LOGIC; --4位加法器的进位标志 BEGIN U1:ADDER4B --例化(安装)一个4位二进制加法器U1 PORT MAP(C4=>C8,A4=>A8(3 DOWNTO 0),B4=>B8(3 DOWNTO0),

S4=>S8(3 DOWNTO 0),CO4=>SC); U2:ADDER4B --例化(安装)一个4位二进制加法器U2 PORT MAP(C4=>SC,A4=>A8(7 DOWNTO 4),B4=>B8(7 DOWNTO 4), S4=>S8 (7 DOWNTO 4),CO4=>CO8); END ARCHITECTURE ART;

7.2 分频电路 例1:2分频、4分频、8分频、16分频

例1:2分频、4分频、8分频、16分频 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY clk_div IS PORT(clk :IN STD_LOGIC; clk_div2 :OUT STD_LOGIC; clk_div4 :OUT STD_LOGIC; clk_div8 :OUT STD_LOGIC; clk_div16 :OUT STD_LOGIC); END clk_div;

ARCHITECTURE rtl OF clk_div6 IS SIGNAL count :STD­_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(clk) IF (clk’EVENT AND clk =’1’) THEN IF (count = “1111”) THEN Count <= (OTHERS=>’0’); ELSE Count := count+1 ; END IF; END PROCESS; Clk_div2 <= count(0); Clk_div4 <= count(1); Clk_div8 <= count(2); Clk_div16 <= count(3); END rtl;

例2:6分频的分频电路 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY clk_div6 IS PORT(clk :IN STD_LOGIC; clk_out :OUT STD_LOGIC); END clk_div6; ARCHITECTURE rtl OF clk_div6 IS SIGNAL clk_temp :STD­_LOGIC; BEGIN

PROCESS(clk) VARIABLE counter: INTEGER RANGER 0 TO 15; CONSTANT md: INTEGER :=3; BEGIN IF (clk’EVENT AND clk =’1’) THEN IF (counter = md) THEN Counter := 0; Clk_temp <= NOT clk_temp; ELSE Counter := counter +1 ; END IF; END PROCESS; Clk_out <= clk_temp; END rtl;

例2实现了一个6分频的分频电路,并且输出信号的占空比为1:1。 若需要得到的占空比不是1:1的分频电路,应如何设计分频电路? 方法是: 首先描述一个计数器电路,然后根据计数电路的并行输出信号来决定输出时钟信号的高低电平,即可完成这种分频电路的VHDL语言描述。 例3所示是一个16分频电路,并且分频后时钟信号的占空比为1:15,描述该分频电路功能的VHDL语言程序如下:

例3: 16分频电路,分频后时钟信号的占空比为1:15 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY clk_div16 IS PORT(clk :IN STD_LOGIC; clk_out :OUT STD_LOGIC); END clk_div16; ARCHITECTURE rtl OF clk_div16 IS SIGNAL counter :STD­_LOGIC; BEGIN

P1: PROCESS(clk) BEGIN IF (clk’EVENT AND clk =’1’) THEN IF (counter =”1111”) THEN Counter <= (OTHERS=>’0’); ELSE Counter := counter +1 ; END IF; END PROCESS;

P2: PROCESS(clk) BEGIN IF (clk’EVENT AND clk =’1’) THEN IF (counter =”1111”) THEN Clk_out < = ‘1’; ELSE Clk_out <= ‘0’ ; END IF; END PROCESS; END rtl; 思考:用此程序实现占空比为1:1的分频电路,在哪进行修改?

Clk clk_out 10分频电路 U0 20分频电路 U1 200分频电路

首先实现10分频电路和20分频电路的VHDL语言描述。

7.3 1秒计时电路的设计 外部输入的频率为1KHz,要求产生一个1S的时钟信号 1Kz ( 1/1000 秒) 10分频 (1/100秒) 10分频 (1/10秒) 10分频 1秒 clk001 10 分 频 10 分 频 clk01 10 分 频 CLK(1KHz) clk1s

(1)10分频的VHDL语言描述 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY clk_div10 IS PORT(clk :IN STD_LOGIC; clk_out :OUT STD_LOGIC); END clk_div10;

ARCHITECTURE rtl OF clk_div10 IS SIGNAL clk_temp :STD­_LOGIC; BEGIN PROCESS(clk) VARIABLE counter: INTEGER RANGER 0 TO 15; IF (clk’EVENT AND clk =’1’) THEN IF (counter = 9) THEN Counter := 0; Clk_out <= ‘1’; ELSE Counter :=counter +1 ; Clk_out <= ‘0’; END IF; END PROCESS; END rtl;

(2)1s计时电路的VHDL语言描述 Library ieee; Use ieee.std_logic_1164.all; Entity t1sec is port(clk1khz:in std_logic; clk1s:out std_logic); End t1sec; Architecture rtl of t1sec is signal clk001,clk01:std_logic; begin u0:clk_div10 port map(clk1khz,clk001); u1:clk_div10 port map(clk001,clk01); u2:clk_div10 port map(clk01,clk1s); End rtl;

交通十字路口的红绿信号灯按如下规律控制: 南北方向通行绿灯亮30秒后,禁止通行红灯亮30秒。 例: 交通十字路口的红绿信号灯按如下规律控制: 南北方向通行绿灯亮30秒后,禁止通行红灯亮30秒。 东西方向通行绿灯亮30秒后,禁止通行红灯亮30秒。如此循环交替通行。红绿灯用红绿色发光二极管模拟,如图所示: 红 绿 南北向 东西向 控 制 逻 辑 绿 1KHz时钟

已知时钟输入Clk频率为1KHz,试画出控制逻辑框图,并采用VHDL语言描述该控制逻辑。(10分频器和3分频器已生成,可直接使用)。 Component cnt10 Port(reset,clk:in std_logic; Carry:out std_logic); End component Component cnt3 Port(reset,clk:in std_logic; Carry:out std_logic); End component

7.3 数字秒表的设计 1.设计要求(秒表的功能描述) 7.3 数字秒表的设计 1.设计要求(秒表的功能描述) (1)要求设置复位开关。当按下复位开关时,秒表清零并做好计时准备。在任何情况下只要按下复位开关,秒表都要无条件地进行复位操作,即使是在计时过程中也要无条件地进行清零操作。 (2)要求设置启/停开关。当按下启/停开关后,将启动秒表并开始计时,当再按一下启/停开关时,将终止秒表的计时操作。 (3)要求计时精确度大于0.01秒。要求设计的计时器能够显示分(2位)、秒(2位)、0.1秒(1位)的时间。 (4)要求秒表的最长计时时间为1小时。

输入信号 复位开关信号reset_sw 启/停开关信号start_on_off 系统电源复位信号sysreset 外部时钟信号clk 输出信号 分十位LED七段显示数码管输出信号min10seg(6 downto 0) 分个位LED七段显示数码管输出信号minseg(6 downto 0) 秒十位LED七段显示数码管输出信号sec10seg(6 downto 0) 秒个位LED七段显示数码管输出信号secseg(6 downto 0) 0.1秒位LED七段显示数码管输出信号sec01seg(6 downto 0)

STOPWATCH 7 Reset_sw Start_on_off sysreset clk Min10seg[6..0] sec10seg[6..0] sysreset secseg[6..0] clk sec01seg[6..0]

秒表系统共分成5个模块: 键输入模块、 时钟分频模块、 控制模块、 秒表计时模块 显示模块。

键输入模块 输入信号: 复位开关信号reset_sw; 启/停开关信号start_on_off; 外部时钟信号clk; 输出信号; 去除抖动后的复位信号reset; 去除抖动后的启/停信号on_off;

时钟分频模块 输入信号: 外部时钟信号clk; 输出信号: 用来消除抖动的时钟信号clk1; 秒表的内部计时时钟信号clk0;

控制模块 输入信号: 去除抖动后的复位信号reset; 去除抖动后的启/停信号on_off; 秒表的内部计时时钟信号clk0 输出信号: 秒表定时计数的使能信号enable;

秒表计时模块 输入信号: 去除抖动后的复位信号reset0; 秒表的内部计时时钟信号clk0; 秒表定时计数的使能信号enable; 输出信号: 分十位信号min10; 分个位信号min; 秒十位信号sec10; 秒个位信号sec; 0.1秒位信号sec01;

秒表显示模块 输入信号: 外部时钟信号clk; 分十位信号min10; 分个位信号min; 秒十位信号sec10; 秒个位信号sec; 输出信号: 分十位信号七段显示数码管的输出信号min10seg; 分个位信号七段显示数码管的输出信号minseg; 秒十位信号七段显示数码管的输出信号sec10seg; 秒个位信号七段显示数码管的输出信号secseg; 0.1秒位信号七段显示数码管的输出信号sec01seg;

7.4 闹钟系统的设计 7.4.1 闹钟系统的设计要求及设计思路 要求设计一个带闹钟功能的24小时计时器,计时器的外观如图6.14所示。

图6.14 计时器外观

该计时器设计要求完成如下功能: (1) 计时功能:这是本计时器设计的基本功能,每隔一分钟计时一次,并在显示屏上显示当前时间。 (2) 闹钟功能:如果当前时间与设置的闹钟时间相同,则扬声器发出蜂鸣声。 (3) 设置新的计时器时间:用户用数字键‘0’~‘9’输入新的时间,然后按 "TIME"键确认。

(4) 设置新的闹钟时间:用户用数字键“0”~“9”输入新的时间,然后按“ALARM”键确认。过程与(3)类似。

6.12.2 闹钟系统的控制器的设计 1.设计思路 控制器命名为ALARM_CONTROLLER,其外部端口如图6.15所示。各端口的作用如下:

图6.15 控制器的外部端口

(1) CLK为外部时钟信号,RESET为复位信号。 (2) 当KEY为高电平(KEY= '1')时,表示用户按下数字键(“0”~“9”)。 (3) 当ALARM_BUTTON为高电平时,表示用户按下“ALARM”键。 (4) 当TIME_BUTTON为高电平时,表示用户按下“TIME”键。 (5) 当LOAD_NEW_A为高电平时,控制(闹钟时间寄存器)加载新的闹钟时间值。

(6) 当LOAD_NEW_C为高电平时,控制(时钟计数器)设置新的时间值。 (7) 当SHOW_NEW_TIME为高电平时,控制(七段数码显示电路)显示新的时间值,即用户通过数字键输入的时间;否则,当SHOW_NEW_TIME为低电平时,根据SHOW_A信号的值控制显示当前时间或闹钟时间。

根据设计要求及端口设置,需要五个状态来实现: S0:表示电路初态即正常时钟计数状态,完成前面设计功能 (1) 的工作。 S1:接收键盘输入状态。在状态S0时用户按下数字键后进入此状态。在此状态下,显示屏上显示的是用户键入的数字。

S2:设置新的闹钟时间。在状态S1时用户按下ALARM键后进入此状态。 S3:设置新的计时器时间。在状态S1时用户按下TIME键后进入此状态。 S4:显示闹钟时间。在状态S0时用户直接按下ALARM键后进入此状态。

在此状态下,显示屏上显示的是所设置的闹钟时间。注意:在此状态下,用户按下ALARM键后,显示屏上保持显示闹钟时间,经过一段时间以后,再返回状态S0显示计时器时间。相应的状态转换及控制如表6.1所示。

表6.1 控制器状态转换及控制输出表

表6.1中没有显式说明的控制信号赋值,表示信号的值为 零。例如在状态S0,当信号KEY =‘1’时,SHOW_NEW_TIME信号的赋值为‘1’,而其他信号LOAD_NEW_A、LOAD_NEW_C和SHOW_A的值此时都赋为‘0’。另外,表中关于“超时”判断处理的处理细节见VHDL源程序中的有关部分。

2.VHDL源程序 --整个设计中将要用到的程序包定义程序P_ALARM.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; PACKAGE P_ALARM IS SUBTYPE T_DIGITAL IS INTEGER RANGE 0 TO 9; SUBTYPE T_SHORT IS INTEGER RANGE 0 TO 65535; TYPE T_CLOCK_TIME IS ARRAY (3 DOWNTO 0) OF T_DIGITAL; TYPE T_DISPLAY IS ARRAY (3 DOWNTO 0) OF

STD_LOGIC_VECTOR(6 DOWNTO 0); TYPE SEG7 IS ARRAY (0 TO 9) OF STD_LOGIC_VECTOR(6 DOWNTO 0); CONSTANT SEVEN_SEG: SEG7 := (

“0111111”, “0000110”, “1011011”, "1001111", "1100110", "1101101", "1111101", "0000111", "1111111', "1110011" );

TYPE KEYPAD9 IS ARRAY (0 TO 9) OF STD_LOGIC_VECTOR(9 DOWNTO 0); CONSTANT KEYNUMBER: KEYPAD9 := (

"0000000001", -- 0 "0000000010", -- 1 "0000000100", -- 2 "0000001000", -- 3 "0000010000", -- 4 "0000100000", -- 5 "0001000000", -- 6 "0010000000", -- 7 "0100000000", -- 8 "1000000000" -- 9 ); END PACKAGE P_ALARM;  

-- 控制器源程序ALARM_CONTROLLER.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE WORK.P_ALARM.ALL; ENTITY ALARM_CONTROLLER IS PORT( KEY :IN STD_LOGIC; ALARM_BUTTON :IN STD_LOGIC; TIME_BUTTON :IN STD_LOGIC; CLK :IN STD_LOGIC;

RESET :IN STD_LOGIC; LOAD_NEW_A :OUT STD_LOGIC; LOAD_NEW_C :OUT STD_LOGIC; SHOW_NEW_TIME :OUT STD_LOGIC; SHOW_A :OUT STD_LOGIC); END ENTITY ALARM_CONTROLLER; ARCHITECTURE ART OF ALARM_CONTROLLER IS TYPE T_STATE IS (S0, S1, S2, S3,S4); CONSTANT KEY_TIMEOUT :T_SHORT := 500;

CONSTANT SHOW_ALARM_TIMEOUT : T_SHORT := 500; SIGNAL CURR_STATE : T_STATE; SIGNAL NEXT_STATE : T_STATE; SIGNAL COUNTER_K : T_SHORT; SIGNAL ENABLE_COUNT_K : STD_LOGIC; SIGNAL COUNT_K_END : STD_LOGIC; SIGNAL COUNTER_A : T_SHORT; SIGNAL ENABLE_COUNT_A : STD_LOGIC; SIGNAL COUNT_A_END : STD_LOGIC; BEGIN

PROCESS(CLK,RESET) IS BEGIN IF RESET ='1' THEN CURR_STATE <= S0; ELSIF RISING_EDGE(CLK) THEN CURR_STATE <= NEXT_STATE; END IF; END PROCESS;

PROCESS(KEY, ALARM_BUTTON, TIME_BUTTON, CURR_STATE, COUNT_A_END,COUNT_K_END) IS BEGIN NEXT_STATE <= CURR_STATE; LOAD_NEW_A <= '0'; LOAD_NEW_C <= '0'; SHOW_A <= '0'; SHOW_NEW_TIME <= '0'; ENABLE_COUNT_K <= '0'; ENABLE_COUNT_A <= '0';

CASE CURR_STATE IS WHEN S0 => IF (KEY = '1') THEN NEXT_STATE <= S1; SHOW_NEW_TIME <= '1'; ELSIF (ALARM_BUTTON = '1') THEN NEXT_STATE <= S4; SHOW_A <= '1'; ELSE NEXT_STATE <= S0; END IF;

WHEN S1 => IF (KEY = '1') THEN NEXT_STATE <= S1; ELSIF (ALARM_BUTTON = '1') THEN NEXT_STATE <= S2; LOAD_NEW_A <= '1'; ELSIF (TIME_BUTTON = '1') THEN NEXT_STATE <= S3; LOAD_NEW_C <= '1'; ELSE IF (COUNT_K_END = '1') THEN NEXT_STATE <= S0;

ELSE NEXT_STATE <= S1; END IF; ENABLE_COUNT_K <= '1'; SHOW_NEW_TIME <= '1'; WHEN S2 => IF (ALARM_BUTTON = '1') THEN NEXT_STATE <= S2; LOAD_NEW_A <= '1'; NEXT_STATE <= S0;

WHEN S3 => IF (TIME_BUTTON = '1') THEN NEXT_STATE <= S3; LOAD_NEW_C <= '1'; ELSE NEXT_STATE <= S0; END IF; WHEN S4 => IF (KEY = '1') THEN NEXT_STATE <= S1;

ELSE NEXT_STATE <= S4; IF (COUNT_A_END = '1') THEN NEXT_STATE <= S0; SHOW_A <= '1';

END IF; ENABLE_COUNT_A <= '1'; WHEN OTHERS => NULL; END CASE; END PROCESS;

COUNT_KEY : PROCESS(ENABLE_COUNT_K, CLK) IS BEGIN IF (ENABLE_COUNT_K = '0') THEN COUNTER_K <= 0; COUNT_K_END <= '0'; ELSIF (RISING_EDGE(CLK)) THEN IF (COUNTER_K >= KEY_TIMEOUT) THEN COUNT_K_END <= '1'; ELSE

COUNTER_K <= COUNTER_K + 1; END IF; END PROCESS COUNT_KEY;   COUNT_ALARM : PROCESS(ENABLE_COUNT_A, CLK) IS BEGIN IF (ENABLE_COUNT_A = '0') THEN COUNTER_A <= 0;

COUNT_A_END <= '0'; ELSIF RISING_EDGE(CLK) THEN IF (COUNTER_A >= SHOW_ALARM_TIMEOUT) THEN COUNT_A_END <= '1'; ELSE COUNTER_A <= COUNTER_A + 1; END IF; END PROCESS COUNT_ALARM; END ARCHITECTURE ART;

6.12.3 闹钟系统的译码器的设计 1.设计思路 本模块的功能是将每次按下闹钟系统的数字键盘后产生的一个数字所对应的10位二进制数据信号转换为1位十进制整数信号,以作为小时、分钟计数的四个数字之一,如图6.16所示。其中,KEYPAD为输入端口,接收10位二进制数据信号;VALUE为输出端口,输出相应的1位十进制整数信号。输入数据与输出数据的译码关系见表6.2。

图6.16 电路系统示意图

表6.2 输入、输出数据的译码关系

2.VHDL源程序 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE WORK.P_ALARM.ALL; ENTITY DECODER IS PORT(KEYPAD :IN STD_LOGIC_VECTOR(9 DOWNTO 0); VALUE :OUT T_DIGITAL); END ENTITY DECODER; ARCHITECTURE ART OF DECODER IS

BEGIN WITH KEYPAD SELECT VALUE <= 0 WHEN “0000000001”, 1 WHEN “0000000010”, 2 WHEN “0000000100”, 3 WHEN “0000001000”, 4 WHEN “0000010000”, 5 WHEN “0000100000”, 6 WHEN “0001000000”, 7 WHEN “0010000000”,

8 WHEN “0100000000”, 9 WHEN “1000000000”, 0 WHEN OTHERS; END ARCHITECTURE ART;

6.12.4 闹钟系统的移位寄存器的设计 1.设计思路 本模块的功能是在CLK端口输入信号的上升沿同步下,将KEY端口的输入信号移入NEW_TIME 端口的输出信号最低位,原有信息依次向左移,最高位信息丢失;RESET端口的输入信号对NEW_TIME端口输出信号进行异步清零复位。电路系统示意图如图6.17所示。

图6.17 移位寄存器电路示意图

2.VHDL源程序 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE WORK.P_ALARM.ALL; ENTITY KEY_BUFFER IS PORT(KEY :IN T_DIGITAL; CLK :IN STD_LOGIC; RESET :IN STD_LOGIC; NEW_TIME:OUT T_CLOCK_TIME); END ENTITY KEY_BUFFER;

ARCHITECTURE ART OF KEY_BUFFER IS SIGNAL N_T:T_CLOCK_TIME; BEGIN SHIFT:PROCESS(RESET,CLK) IS IF (RESET = '1') THEN N_T <= (0,0,0,0); ELSIF (CLK'EVENT AND CLK = '1' )THEN FOR I IN 3 DOWNTO 1 LOOP N_T(I) <= N_T(I-1);

END LOOP; N_T(0) <= KEY; END IF; END PROCESS SHIFT; NEW_TIME <= N_T; END ARCHITECTURE ART;

6.12.5 闹钟系统的闹钟寄存器和时间计数器的设计 1.电路系统工作原理 闹钟寄存器模块的功能是在时钟上升沿同步下,根据LOAD_NEW_A端口的输入信号控制ALARM_TIME端口的输出;当控制信号有效(高电平)时,把NEW_ALARM_TIME端口的输入信号值输出;RESET端口输入信号对ALARM_TIME端口的输出进行异步的清零复位。图6.18是闹钟寄存器模块的示意图。

图6.18 闹钟寄存器示意图

闹钟系统的闹钟时间由闹钟寄存器保存和传递,而当前时间由时间计数器保存、传递并按分钟累加推进。这两个组件的功能和设计描述比较相似,它们之间的区别主要在于自动累加功能的有无和控制信号的优先作用次序。

图6.19 时间计数器示意图

时间计数器模块的功能是当RESET端口输入信号为高电平时,对CURRENT_TIME端口输出信号清零复位;当LOAD_NEW_C端口输入信号为高电平时,将NEW_CURRENT_TIME端口的输入信号输出给CURRENT_TIME端口。RESET端口的控制优先于LOAD_NEW_C端口。当这两个控制信号都无效时,在时钟上升沿同步下,对CURRENT_TIME端口输出信号累加1,并根据小时、分钟的规律处理进位。图6.19是时间计数器模块的示意图。

2.VHDL源程序 --时间计数器的源程序ALARM_COUNTER.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE WORK.P_ALARM.ALL; ENTITY ALARM_COUNTER IS PORT(NEW_CURRENT_TIME:IN T_CLOCK_TIME; LOAD_NEW_C:IN STD_LOGIC; CLK:IN STD_LOGIC;

RESET:IN STD_LOGIC; CURRENT_TIME:OUT T_CLOCK_TIME); END ENTITY ALARM_COUNTER; ARCHITECTURE ART OF ALARM_COUNTER IS SIGNAL I_CURRENT_TIME : T_CLOCK_TIME; BEGIN PROCESS(CLK,RESET,LOAD_NEW_C) IS VARIABLE C_T:T_CLOCK_TIME; IF RESET = '1' THEN

I_CURRENT_TIME <= (0,0,0,0); ELSIF LOAD_NEW_C ='1' THEN I_CURRENT_TIME <= NEW_CURRENT_TIME; ELSIF RISING_EDGE(CLK) THEN C_T := I_CURRENT_TIME; IF C_T(0) < 9 THEN C_T(0) := C_T(0) + 1;

ELSE C_T(0) := 0; IF C_T(1) < 5 THEN C_T(1) := C_T(1) + 1; C_T(1) := 0; IF C_T(3) < 2 THEN IF C_T(2) < 9 THEN C_T(2) := C_T(2) + 1; C_T(2) := 0; C_T(3) := C_T(3) + 1; END IF;

ELSE IF C_T(2) < 3 THEN C_T(2) := C_T(2) + 1; C_T(2) := 0; C_T(3) := 0; END IF; I_CURRENT_TIME <= C_T;

END PROCESS; CURRENT_TIME <= I_CURRENT_TIME; END ARCHITECTURE ART;   --闹钟寄存器的源程序ALARM_REG.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE WORK.P_ALARM.ALL; ENTITY ALARM_REG IS

PORT(NEW_ALARM_TIME:IN T_CLOCK_TIME; LOAD_NEW_A :IN STD_LOGIC; CLK :IN STD_LOGIC; RESET :IN STD_LOGIC; ALARM_TIME:OUT T_CLOCK_TIME); END ENTITY ALARM_REG; ARCHITECTURE ART OF ALARM_REG IS BEGIN PROCESS(CLK,RESET) IS

IF RESET = '1' THEN ALARM_TIME <= (0,0,0,0); ELSE IF RISING_EDGE(CLK) THEN IF LOAD_NEW_A = '1' THEN ALARM_TIME <= NEW_ALARM_TIME; ELSIF LOAD_NEW_A /= '0' THEN ASSERT FALSE REPORT“UNCERTAIN LOAD_NEW_ALARM CONTROL!” SEVERITY WARNING;

END IF; END PROCESS; END ARCHITECTURE ART;

6.12.6 闹钟系统的显示驱动器的设计 1.设计思路 本模块的功能是:当SHOW_NEW_TIME端口输入信号有效(高电平)时,根据NEW_TIME端口输入信号(时间数据),产生相应的四个七段数码显示器的驱动数据,并在DISPLAY端口输出该信号。

当SHOW_NEW_TIME端口输入信号无效(低电平)时,判断SHOW_A端口的输入信号,为高电平时,根据ALARM_TIME端口的输入信号(时间数据)产生相应的四个七段数码显示器的驱动数据,并在DISPLAY端口输出该信号;为低电平时,根据CURRENT_TIME端口的输入信号,对DISPLAY端口进行驱动。当ALARM_TIME 端口的输入信号值与CURRENT_TIME端口的输入信号值相同时,SOUND_ALARM端口的输出信号有效(高电平),反之无效。图6.20为显示驱动器示意图。

图6.20 显示驱动器示意图

2.VHDL源程序 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE WORK.P_ALARM.ALL; ENTITY DISPLAY_DRIVER IS PORT(ALARM_TIME :IN T_CLOCK_TIME; CURRENT_TIME :IN T_CLOCK_TIME; NEW_TIME :IN T_CLOCK_TIME; SHOW_NEW_TIME:IN STD_LOGIC; SHOW_A :IN STD_LOGIC; SOUND_ALARM :OUT STD_LOGIC; DISPLAY:OUT T_DISPLAY);

END ENTITY DISPLAY_DRIVER; ARCHITECTURE ART OF DISPLAY_DRIVER IS SIGNAL DISPLAY_TIME:T_CLOCK_TIME; BEGIN CTRL:PROCESS(ALARM_TIME,CURRENT_TIME,NEW_TIME,SHOW_A,SHOW_NEW_TIME) IS

SOUND_LP: FOR I IN ALARM_TIME'RANGE LOOP IF NOT(ALARM_TIME(I) = CURRENT_TIME(I)) THEN SOUND_ALARM <= '0'; EXIT SOUND_LP; ELSE SOUND_ALARM <= '1'; END IF;

END LOOP SOUND_LP; IF SHOW_NEW_TIME = '1' THEN DISPLAY_TIME <= NEW_TIME; ELSIF SHOW_A = '1' THEN DISPLAY_TIME <= ALARM_TIME; ELSIF SHOW_A = '0' THEN DISPLAY_TIME <= CURRENT_TIME; ELSE

ASSERT FALSE REPORT “UNCERTAIN DISPLAY_DRIVER CONTROL!” SEVERITY WARNING; END IF; END PROCESS CTRL; DISP:PROCESS(DISPLAY_TIME) IS BEGIN

FOR I IN DISPLAY_TIME'RANGE LOOP DISPLAY(I) <= SEVEN_SEG(DISPLAY_TIME(I)); END LOOP; END PROCESS DISP; END ARCHITECTURE ART;

6.12.7 闹钟系统的分频器的设计 1.设计思路  本模块的功能是将CLK_IN端口输入的时钟信号分频后送给CLK_OUT端口;当RESET端口输入信号有效(高电平)时,CLK_OUT端口输出信号清零。图6.21为分频器示意图。

图6.21 分频器示意图

2.VHDL源程序 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE WORK.P_ALARM.ALL; ENTITY FQ_DIVIDER IS PORT( CLK_IN:IN STD_LOGIC; RESET:IN STD_LOGIC; CLK_OUT:OUT STD_LOGIC );

END ENTITY FQ_DIVIDER; ARCHITECTURE ART OF FQ_DIVIDER IS CONSTANT DIVIDE_PERIOD : T_SHORT := 6000; BEGIN DIVIDE_CLK: PROCESS(CLK_IN,RESET) IS VARIABLE CNT : T_SHORT; IF (RESET = '1') THEN CNT := 0; CLK_OUT <= '0';

ELSIF RISING_EDGE(CLK_IN) THEN IF (CNT < (DIVIDE_PERIOD/2)) THEN CLK_OUT <= '1'; CNT := CNT + 1; ELSIF (CNT < (DIVIDE_PERIOD-1)) THEN CLK_OUT <= '0';

ELSE CNT := 0; END IF; END PROCESS DIVIDE_CLK; END ARCHITECTURE ART;

6.12.8 闹钟系统的整体组装 1.整体组装说明 前边已经完成了计时器各个组成部分的设计,下面把这些组成部分组装起来,形成完整的总体设计。该计时器命名为ALARM_CLOCK,其外部端口如图6.22所示。

图6.22 计时器的外部端口

各个输入/输出端口的作用如下: (1) CLK为外部时钟信号,RESET为复位信号。 (2) KEYPAD是一个10位信号,若其中某一位为高电平,则表示用户按下了相应下标的数字键。 (3) 当KEYDOWN为高电平时(KEYDOWN= '1'),表示用户按下某一数字键。 (4) 当ALARM_BUTTON为高电平时,表示用户按下ALARM键。 (5) 当TIME_BUTTON为高电平时,表示用户按下TIME键。

(6) DISPLAY实际上表示了四个七段数码显示管,用于显示时间,如12∶20。 (7) SOUND_ALARM用于控制扬声器发声,当SOUND_ALARM = '1'时,扬声器发出蜂鸣,表示到了设定的闹钟时间。 设计的总体结构图如图6.23所示。

图6.23 总体结构

下面再简要说明各组成部分的功能: (1) 译码器(DECODER) 可将KEYPAD信号转换为0~9的整型数,以直观地表示和处理用户输入的数字。 (2) 键盘缓冲器(KEY_BUFFER)是一个移位寄存器,暂存用户键入的数字,并且实现用户键入数字在显示器上从右到左的依次显示。这里需要注意的是,由图6.23可以看出,KEY_BUFFER的时钟端连接的是外部KEY_DOWN 信号。这表示用户每输入一个数字,KEY_BUFFER移位一次。

(3) 分频器(FQ_DIVIDER)将较高速的外部时钟频率分频成每分钟一次的时钟频率,以便进行时钟计数。 (4) 计数器(ALARM_COUNTER)实际上是一个异步复位、异步置数的累加器,通常情况下进行时钟累加计数,必要时可置入新的时钟值,然后从该值开始新的计数。 (5) 寄存器(ALARM_REG)用于保存用户设置的闹钟时间,是一个异步复位寄存器。

(6) 显示器(DISPLAY_DRIVER)根据需要显示当前时间、用户设置的闹钟时间或用户通过键盘输入的新的时间,同时判断当前时间是否已到了闹钟时间,实际上是一个多路选择器加比较器。 (7) 控制器(ALARM_CONTROLLER)是设计的核心部分,按设计要求产生相应的控制逻辑,以控制其他各部分的工作。

2.VHDL源程序 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE WORK.P_ALARM.ALL; ENTITY ALARM_CLOCK IS PORT(KEYPAD : IN STD_LOGIC_VECTOR(9 DOWNTO 0); KEY_DOWN : IN STD_LOGIC; ALARM_BUTTON: IN STD_LOGIC; TIME_BUTTON : IN STD_LOGIC;

CLK : IN STD_LOGIC; RESET : IN STD_LOGIC; DISPLAY : OUT T_DISPLAY; SOUND_ALARM : OUT STD_LOGIC); END ENTITY ALARM_CLOCK; ARCHITECTURE ART OF ALARM_CLOCK IS COMPONENT DECODER IS PORT( KEYPAD :IN STD_LOGIC_VECTOR(9 DOWNTO 0); VALUE :OUT T_DIGITAL); END COMPONENT DECODER;

... SIGNAL S0 : T_DIGITAL; SIGNAL S1,S2,S3,S4,S5 : STD_LOGIC; SIGNAL S6,S7,S8 : T_CLOCK_TIME; BEGIN U1: DECODER PORT MAP(KEYPAD, S0); U2: KEY_BUFFER PORT MAP(S0, KEY_DOWN,RESET, S6); U3: ALARM_CONTROLLER PORT MAP(KEY_DOWN,ALARM_BUTTON,TIME_BUTTON,

CLK,RESET,S1,S2,S3,S4); U4: ALARM_COUNTER PORT MAP(S6,S2,S5,RESET,S8); U5: ALARM_REG PORT MAP(S6,S1,CLK,RESET,S7); U6: DISPLAY_DRIVER PORT MAP(S7,S6,S8,S3,S4,SOUND_ALARM,DISPLAY); U7: FQ_DIVIDER PORT MAP(CLK,RESET,S5); END ARCHIITECTURE ART;

6.12.9 闹钟系统的硬件验证 若用GW48型EDA实验开发系统进行硬件验证,考虑到实验开发系统提供的输入信号按键的有限,可将输入数字按键0~9改为一个按键,该按键的信号作为一个8421码信号发生器的输入,由8421码信号发生器输出数字0~9。同时,每输入完一个数字后应增加一个输入确认键。具体验证方案由读者自行完成。