590 likes | 811 Views
第九章 数字系统设计与实现. 9.1 时钟电路的设计与实现 9.2 UART 数据接收发送电路设计与实现 9.3 人机接口电路的设计与实现 9.4 8255 并行接口电路的设计与实现. 9.1 时钟电路的设计与实现 9.1.1 模 24 计数器的 VHDL 设计 9.1.2 模 60 计数器的原理图设计 9.1.3 顶层文件设计.
E N D
第九章 数字系统设计与实现 9.1 时钟电路的设计与实现 9.2 UART数据接收发送电路设计与实现 9.3 人机接口电路的设计与实现 9.4 8255并行接口电路的设计与实现
9.1 时钟电路的设计与实现 • 9.1.1 模24计数器的VHDL设计 • 9.1.2 模60计数器的原理图设计 • 9.1.3 顶层文件设计
9.1 时钟电路的设计与实现数字系统设计一般采用自顶向下的层次化设计方法,在MAX+plusⅡ环境下可利用层次化设计方法实现自顶向下的设计。电路设计时,分析设计要求,划分模块,进行低层设计,然后进行顶层设计的连接。下面以图形和文本混合输入为例,设计一个时钟电路,时钟电路由模60计数器构成秒、分电路,模24计数器构成小时电路,生产各模块的符号文件,最后用时、分、秒模块构成顶层时钟电路。
9.1.1 模24计数器的VHDL设计 1. 实体端口定义 模24的计数器的实体端口定义如下: ENTITY cntm24v IS PORT(en: IN std_logic; clr:in std_logic; clk:in std_logic; cont:out std_logic; qh:buffer std_logic_vector(3 downto 0); ql: buffer std_logic_vector(3 downto 0)); END ; 输入端口为计数使能en、清零clear和时钟clk,其数据类型为 std_logic标准逻辑类型;输出端口cont的数据类型为std_logic标准逻辑类型;小时信号qh、ql的数据类型为std_logic_vector(3 downto 0) 向量标准逻辑类型。
2. 模24计数器VHDL设计 LIBRARY ieee; --调用程序包 USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.ALL; -------------------- ENTITY cntm24v IS --定义实体端口 PORT(en: IN std_logic; clr:in std_logic; clk:in std_logic; cont:out std_logic; qh:buffer std_logic_vector(3 downto 0); ql: buffer std_logic_vector(3 downto 0)); END ; ----------------------------- ARCHITECTURE beh OF cntm24v IS --结构体设计 BEGIN cont<='1'when (qh="0010"and ql="0011"and en='1')else '0'; PROCESS(CLK,clr) BEGIN
IF(clr='0')THEN • qh<="0000"; • ql<="0000"; • elsif (clk'event and clk='1')then • IF(en='1')THEN • if(ql=3)then • ql<="0000"; • if(qh=2)then • qh<="0000"; • else • qh<=qh+1; • end if; • else • ql<=ql+1; • end if; • end if; • end if; • end process; • end beh;
完成模24计数器的设计,且仿真通过之后,执行菜单File下的Create Default Symbol命令,生成符号cntm24v,该符号将成为当前项目库中的一个元件。 9.1.2 模60计数器的原理图设计 这里采用原理图输入方式设计模60计数器,输入信号有计数使能en、清零clear、时钟clk;输出信号有ql0、ql1、ql2、ql3、qh0、qh1、qh2以及进位输出。调用库中已有的元件符号74161、三输入与非门nand3、非门not等,构成符合要求的计数器,图9.1是模60计数器的原理图。
9.1.3 顶层文件设计 • 执行菜单File下的建立新文件,文件名为clock.gdf。在clock.gdf空白处双击鼠标左键,打开Enter symbol对话框选择调用的元件,在元件列表区可看到已经生成的两个元件cntm24和cntm60,调用cntm24和cntm60,连接构成时钟电路的顶层设计文件,clock.gdf文件如图9.2所示。 图9.2 顶层clock.gdf文件
对顶层设计文件clock.gdf进行编译和仿真,调整仿真时间和栅格尺寸,观察仿真波形。在Option菜单下选择Grid Size调整显示栅格的大小。在File菜单下选择End Time设置仿真时间。利用左侧工具栏上的波形绘制图标,可以方便地对波形文件进行编辑,如输入时钟信号clk,en和clr设置为高电平等。波形文件保存为clock .scf,接下来对该文件进行仿真。 • 打开仿真器窗口,单击Start按钮,开始仿真,得到如图9.3所示的仿真波形,观察时、分、秒之间的进位关系。选择芯片,分配引脚,再次进行编译,正确后将设计配置到芯片。
完成全部设计后,在菜单MAX+plusⅡ下选择Hierarchy Display命令,显示clock文件层次结构如图9.4所示。 图9.4 clock.gdf的层次结构 由图9.4可见,顶层clock.gdf调用cntm24v符号和cuntm60符号,cntm24v符号是文本编辑生成的符号文件;cuntm60符号是图形编辑生成的符号文件。 符号cntm24v和cuntm60又各自调用了LPM库中的宏单元LMP-ADD-SUB:120和74160符号。
9.2 UART数据接收发送电路设计与实现 • 9.2.1 UART程序设计 • 9.2.2 UART程序仿真
通用异步数据接收发送方式UART(Universal Asynchronous Receiver Transmitter)不仅能实现接收发送方相互之间通讯,同时还能满足PC机、微处理器等设备之间的数据通信。 串行外设都会用到RS232串行接口,传统上采用专用的集成电路即UART专用芯片实现,如TI、EXAR、EPIC的550、452等系列芯片。有时,人们不需要使用完整的UART的功能,而对于多串口的设备或需要加密通讯的场合使用UART也不是最佳选择。如果采用FPGA/CPLD器件,那么就可以将所需要的UART功能集成到FPGA内部,使用VHDL集成UADT的核心功能,从而使整个设计更加紧凑,更小巧、稳定、可靠。 • 9.2 UART数据接收发送电路设计与实现
分析UART结构,可以看出UART主要由数据总线接 口和控制逻辑、波特率发生器、发送和接受等部分组 成,各部分间关系如图9.5所示。 图9.5 UART结构框图
了解UART的基本组成结构后,需要对各部分的功能进行详细的分析。假定所要设计的UART功能为:数据位7位、8位可选,波特率可选,校验方式有奇、偶、无等多种方式。了解UART的基本组成结构后,需要对各部分的功能进行详细的分析。假定所要设计的UART功能为:数据位7位、8位可选,波特率可选,校验方式有奇、偶、无等多种方式。 • 1. 波特率的设定 • UART的接收和发送可以采用相同的波特率进行,当然也可以实现不同波特率的收发,这里采用相同波特率的收发,波特率可以通过CPU的总线接口进行设置。假设UART收发的每一个数据宽度都是波特率发生器输出时钟周期的16倍,假定按照9600bps的波特率进行收发,那么波特率发生器输出的时钟频率应为9600×16Hz。 • 假定系统提供的时钟为1.8432MHz,那么可以用CPU写入不同的数值到波特率保持寄存器,然后用计数器方式生成所需要的各种波特率,该数值计算原则是1843200/(16×所期望的波特率)。如果希望获得9600Hz的波特率,计算数值为1843200/(16×9600)=12(0CH)。
2. 数据发送 • 数据发送过程中,需要解决几个关键问题: • CPU要判断何时可以向发送保持寄存器(THR)写入数据?也就是说CPU要写入数据到THR之前必须判断当前是否可写?很明显如果不判断,发送的数据会出错,除非CPU写入THR的频率低于当前数据传输的波特率,这种情况是极少出现的。 • CPU写入数据到THR后,何时THR的数据传送到发送移位寄存器(TSR)进行移位?即处理THR和TSR的关系。 • 数据位有7、8位两种,校验位有三种,因此发送的数据可能有9、10、11位三种长度,所以需要按照所设置的传输情况分别进行处理。可以通过CPU写一个端口数据设置数据位、校验方式,发送和接受根据该数据设置进行处理。
根据以上分析,UART的数据发送定义如下信号:根据以上分析,UART的数据发送定义如下信号: • txhold:数据发送保持信号,标准逻辑向量型: • std_logic_vector(0 TO 7); • txreg :数据发送存储器,标准逻辑向量型: • std_logic_vector(0 TO 7); • txtag2:查找数据标志位,标准逻辑型: std_logic; • txtag1:清空寄存器,标准逻辑型: std_ logic; • txparity:存储器产生奇偶校验,标准逻辑型: • std_ logic; • txclk:数据发送时钟信号,标准逻辑型: std_ logic; • txdone:数据发送结束,标准逻辑型: std_ logic; • paritycycle:数据发送位校验,标准逻辑型: • std_ logic; • txdatardy:数据发送读操作,标准逻辑型: • std_ logic;
图9.6给出了一个奇校验8bit数据的发送时序图。图9.6给出了一个奇校验8bit数据的发送时序图。 图9.6 UART数据发送时序图 3. 数据接收 数据接收同样存在9、10、11位三种串行数据长度的问题,必须根据设置的不同情况将数据完整地取下来。接收数据时还有一个特殊情况,移位时钟不是始终存在,移位时钟在接受到起始位的中间开始产生,到停止位的中间时结束。接受到停止位后,给出中断信号,并提供相应的校验出错、帧出错以及溢出等。
数据接收时,需引入hunt和idle两个信号,hunt为高电平时表示捕捉到起始位,idle为高电平时表示不在移位状态,利用这两个信号就可以产生接收所需要的移位时钟。数据接收时,需引入hunt和idle两个信号,hunt为高电平时表示捕捉到起始位,idle为高电平时表示不在移位状态,利用这两个信号就可以产生接收所需要的移位时钟。 • 根据上述分析,UART的数据接收过程定义如下信号: • rxhold:数据接收保持信号,标准逻辑向量型: • std_ logic_vector (0 TO 7); • rxreg :数据接收存储器,标准逻辑向量型: • std_logic_vector (0 TO 7); • rxparity:数据接收校验位,标准逻辑型:std_logic; • paritygen:产生数据接收校验位,标准逻辑型: • std_logic; • rxstop:数据接收停止位,标准逻辑型:std_logic; • rxclk:数据接收时钟,标准逻辑型:std_logic; • rxidle:数据接收空操作,标准逻辑型:std_logic; • rxdatardy:数据接收准备读操作,标准逻辑型: • std_logic;
图9.7是一个8bit奇校验的接收数据时序图,假定接收正确,因此没有给出校验、溢出、帧出错等信号。 图9.7 UART数据接收时序图 9.2.1 UART程序设计 1. 库与实体端口的定义 UART的设计中,调用的库文件有IEEE库,打开的程序包有:std_logic_1164、 std_logic_arith、 std_logic_unsigned。
实体端口的定义如下: • PORT (clkx16 : IN std_logic; -- 时钟 • read : IN std_logic; -- 接收数据读操作 • write : IN std_logic; -- 发送数据写操作 • rx : IN std_logic; -- 接收数据 • reset : IN std_logic; -- 复位清零 • tx : OUT std_logic; -- 发送数据 • rxrdy : OUT std_logic; --准备接收数据 • txrdy : OUT std_logic; --准备发送数据 • parityerr : OUT std_logic; --接收数据校验错误 • framingerr : OUT std_logic; --接收帧数据错误 • overrun : OUT std_logic; --接收溢出错误 • data : INOUT std_logic_vector(0 TO 7)); --双向数据总线 • 2. UART程序设计 • UART的程序设计分为5部分。第一部分是CLOCK时钟设计,第二部分是发送数据设计,第三部分是接收数据设计,第四部分是异步控制设计,第五部分是发送与接收异步控制设计。
结构体采用“IF…THEN…ELSE(ELSIF)”顺序语句设计,结构体命名为exemplar,项目名为UART。下面提供的是UART的VHDL设计参考程序,图9.8是UART的参考程序生成的UART符号文件。结构体采用“IF…THEN…ELSE(ELSIF)”顺序语句设计,结构体命名为exemplar,项目名为UART。下面提供的是UART的VHDL设计参考程序,图9.8是UART的参考程序生成的UART符号文件。 图9.8 UART符号文件
9.2.2 UART程序仿真 • 编译UART程序,正确后开始进行仿真。仿真前信号的设置如下:rx端口设置为时钟周期信号,周期为20 us、clkx16端口设置为时钟周期信号,周期为40us、reset端口设置为逻辑1、read端口设置为逻辑0、data端口设置数据为01、02、03、04、05、06…。仿真通过后可以看到对应输出端口data数据发生的变化,UART的仿真波形如图9.9所示。 • 作者使用Altera公司的MAX7000SEPM7128SLC84-6完成项目设计,打开UART.RPT报告文件,可以了解详细的集成电路资源利用与分配情况。
9.3 人机接口电路的设计与实现 • 9.3.1 接口电路的分析 9.3.2 接口电路的设计
9.3 人机接口电路的设计与实现 • 人机接口电路在微机系统中应用非常广泛,主要接口有数码管显示、键盘和VGA显示器等。在CPLD系统设计中人机接口电路的设计与开发也是一个重要的环节,例如,数码管的静态和动态扫描显示;矩阵方式的键盘扫描、按键去抖动、键码识别等。这里主要讨论矩阵方式的键盘接口电路的设计与实现。 • 9.3.1 接口电路的分析 • 矩阵方式的键盘接口电路的设计主要包含的矩阵扫描、去抖动、键码识别及显示功能的设计,下面以4×4键盘接口电路的设计为例。 • 接口电路的系统时钟inclk频率为22MHz,接口电路的主要功能是分频和扫描。利用系统时钟22MHz 的inclk分频产生5ms的键查询时钟keyclkout,keyclkout十分频后产生50ms的触发时钟chuclkout。在触发时钟chuclkout的
高电平期间送出列扫描数据,将得到的行数据送去抖动电路,去抖动后读入,根据行、列数据之间的关系确定其键值。高电平期间送出列扫描数据,将得到的行数据送去抖动电路,去抖动后读入,根据行、列数据之间的关系确定其键值。 • 键盘布局如图9.10所示,图9.11是设计电路KEY2编译通过后生产的符号文件。 图9.10 KBC键盘电路示意图
图9.11 KEY2的符号文件 9.3.2 接口电路的设计 1. 去抖动电路设计 去抖动电路的基本设计原理:电路采用5ms的时钟接收输入数据A,如果连续三次数据为零,可以确认数据是稳定的,且可以接收。如图9.12所示是去抖动电路的设计,采用图形设计输入。
图9.12 键盘去抖动电路 以上是通用的抖动消除电路设计,由D触发器构成。信号稳定时间由D触发器的个数决定。该单元电路命名为tinglmove,该电路作为元件将在下面的VHDL程序中调用。
2. 键盘扫描显示电路的设计 • 下面是键盘串行扫描显示电路实体的VHDL描述,具体程序中采用元件例化语句调用键盘去抖动电路tinglmove。 • LIBRARY ieee; • USE ieee.std_logic_1164.all; • USE ieee.std_logic_arith.all; • USE ieee.std_logic_unsigned.all; • ----------------------------------------- • ENTITY key2 IS • PORT (inclk :IN std_logic; --时钟信号 • inkey : IN std_logic_vector(0 to 3);--按键信号 • outkey : OUT std_logic_vector( 0 to 3); • --键盘扫描输出信号 • outled : OUT std_logic_vector(7 downto 0) • --LED显示输出信号 • ); • END key2; • ---------------------------------------------
图9.13是key2.vhd文件的层次结构。 图9.13 key2.vhd文件的层次结构 图9.14是key2的仿真波形,可以看到输入clk端口的设置,inkey端口设置逻辑信号,仿真通过后可以看出对应输出口outkey数据发生的变化。
9.4 8255并行接口电路的设计与实现 • 9.4.1 8255接口电路的分析 • 9.4.2 8255接口电路的设计
9.4 8255并行接口电路的设计与实现 • 8255是典型的可编程并行接口芯片,广泛用于各种外设接口电路中。用可编程逻辑器件,如FLEX和MAX系列设计可以实现8255的设计,设计具有24个可编程I/O接口、静态读/写模式、同步处理设计模式等功能的并行接口电路。 • 9.4.1 8255接口电路的分析 • 可编程并行接口芯片8255从结构上看主要有四部分组成:控制寄存器和逻辑分配单元;数据输出多路选通单元;AB端口输入输出单元以及C端口输入输出控制选择单元。图9.15是8255的结构框图。表9.2是8255的接口引脚功能类型及其说明。
8255三种工作方式的时序波形不同,图9.16给出工作方式0的时序波形。读者如果需要了解方式1和2的时序波形可以查阅相关资料。 (a) 方式0输入时序波形 (b) 方式0输出时序波形 图9.16 工作方式0的时序波形
9.4.2 8255接口电路的设计 • 8255的VHDL程序中的前几条语句说明调用的IEEE库及其相关的程序包;接着是8255的端口描述,其中输入输出端口的定义与A8255定义相同;其他语句是8255的功能描述。 • 这里采用元件例化的设计方法,主程序包含相对独立的7个例化的子程序,这些子程序分别是dout_mux、cntl_log、partaout、partain、partbin、partbout和partcout。图9.17给出主程序与子程序之间的层次关系。
图9.17 主程序与子程序的层次关系 图9.18是CNTL-LOG.SCF文件仿真波形。由图可以看出,输入RESET端口设置逻辑0、PCIN端口设置逻辑0、nRD端口设置逻辑0、CLK端口设置时钟40ns、nWR端口设置写信号,可以看到输出端口PortAoouLd数据发生的变化。
图9.19是cntl_log生成的符号文件。 图9.19 cntl_log的符号文件
图9.20是dout_mux的仿真波形。输入UTSelect端口设置逻辑0、ontrlReg端口设置逻辑00、rtAinReg端口设置逻辑00、PAIN端口设置逻辑01、02、03、04、05、06…,仿真后,可以看出输出端口DOUT数据发生的变化。图9.20是dout_mux的仿真波形。输入UTSelect端口设置逻辑0、ontrlReg端口设置逻辑00、rtAinReg端口设置逻辑00、PAIN端口设置逻辑01、02、03、04、05、06…,仿真后,可以看出输出端口DOUT数据发生的变化。 图9.20 dout_mux的仿真波形
图9.21是dout_mux.vhd文件编译后生成的符号文件。图9.21是dout_mux.vhd文件编译后生成的符号文件。 图9.21 dout_mux的符号文件
图9.22是portain的仿真波形。输入RESET端口设置逻辑0,复位时RESET设置为逻辑1;PortALnLd端口设置逻辑0、PAIN端口设置为00、01、02、03、04、05、06…、CLK端口设置逻辑时钟40ns,仿真通过后可以看出对应输出口PortAInReg数据变化,同时可以观测到输入RESET端口设置逻辑1时间段内的复位功能。图9.22是portain的仿真波形。输入RESET端口设置逻辑0,复位时RESET设置为逻辑1;PortALnLd端口设置逻辑0、PAIN端口设置为00、01、02、03、04、05、06…、CLK端口设置逻辑时钟40ns,仿真通过后可以看出对应输出口PortAInReg数据变化,同时可以观测到输入RESET端口设置逻辑1时间段内的复位功能。 图9.22 portain的仿真波形
图9.23是portain.vhd文件编译后产生的符号文件。 图9.23 portain的符号文件
图9.24是portaout的仿真波形。输入RESET端口设置为逻辑0,复位有效时设置RESET为逻辑1;PortAOutLd端口设置逻辑0、DIN端口设置数据00、01、02、03、04、05、06…;CLK端口设置时钟周期40ns。仿真通过后,可以看到输出端口PAOUT数据发生的变化,同时可以观测到输入RESET端口设置逻辑1时间段内,信号被复位。图9.24是portaout的仿真波形。输入RESET端口设置为逻辑0,复位有效时设置RESET为逻辑1;PortAOutLd端口设置逻辑0、DIN端口设置数据00、01、02、03、04、05、06…;CLK端口设置时钟周期40ns。仿真通过后,可以看到输出端口PAOUT数据发生的变化,同时可以观测到输入RESET端口设置逻辑1时间段内,信号被复位。 图9.24 portaout的仿真波形
图9.25是portout.vhd文件编译生成的符号文件。 图9.25 portout符号文件
图9.26是portbin的仿真波形。输入RESET端口设置逻辑0,复位有效时RESET为逻辑1;PortBLnLd端口设置逻辑0、PBIN端口输入00、01、02、03、04、05、06…;CLK端口设置时钟周期40ns。仿真通过后,可以看到输出端口PortBInReg数据的变化,同时可以看到输入RESET端口为逻辑1时,信号复位功能。图9.26是portbin的仿真波形。输入RESET端口设置逻辑0,复位有效时RESET为逻辑1;PortBLnLd端口设置逻辑0、PBIN端口输入00、01、02、03、04、05、06…;CLK端口设置时钟周期40ns。仿真通过后,可以看到输出端口PortBInReg数据的变化,同时可以看到输入RESET端口为逻辑1时,信号复位功能。 图9.26 portbin仿真波形
图9.27是portbin.vhd文件编译后生成的符号文件。 图9.27 portbin符号文件