《CPLD FPGA串行通信》项目报告

合集下载

基于CPLD_FPGA的串行异步通信_UART_接口电路设计

基于CPLD_FPGA的串行异步通信_UART_接口电路设计

第25卷第3期2007年5月西安航空技术高等专科学校学报Journal of Xi ’an Aerotechnical CollegeVol 125No 13May 2007收稿日期:2006212228作者简介:储海燕(1981-),女,陕西省西安市人,毕业于空军工程大学电讯工程学院通信工程专业,现任职于西安航专电气系,助教,主要从事电子及通信专业课程的教学工作。

基于CPLD/FP GA 的串行异步通信(UAR T )接口电路设计储海燕(西安航空技术高等专科学校电气工程系,陕西西安710077)摘 要:UART (即Universal Asynchronous Receiver Transmitter 通用异步收发器)是广泛使用的串行数据传输协议。

UART 允许在串行链路上进行全双工的通信。

通过应用EDA 技术,基于CPLD/FPG A 器件设计与实现UART 的波特率产生器、UART 发送器和接收器及其整合电路,目的是熟练运用VHDL 语言,掌握CPLD 芯片的使用。

关键词:VHDL ;CPLD/FPG A ;UART 接口电路中图分类号:TN702 文献标识码:A 文章编号:100829233(2007)03200252031 引言目前,很多理工高校的EDA 实验室都已建立,这为我们熟悉、使用可编程逻辑器件,学有所用的开发实验室产品提供了便利条件。

本设计就是从这一点出发,利用Altera 公司的可编程逻辑器件EP1K100Q208-3(ACEX 1K 系列),设计简易的串行异步UART 接口电路,这里我们选用VHDL 硬件描述语言编写源程序,通过Altera 公司为其可编程逻辑器件专门开发的仿真软件MAX +Plus Ⅱ编译仿真,然后下载到EP1K100Q208-3芯片上,进行实现,最后做出实物。

2 基于CPLD 的软件设计方案CPLD (Complex Programmable Logic Device )是复杂可编程逻辑器件的缩写。

关于实验报告cpld

关于实验报告cpld

报告要求一.报告用A4纸张打印,报告封面用统一模板(见下页),上交时间为课程结束后的下一周周四上午九点至十一点。

二.字数要求2500--3500字之内,每个同学一份,同组同学可共用成果,其余部分应有区别。

三.实验项目1、实验一组合逻辑设计、实验装置的使用方法2、实验二用VHDL设计十六进制加法计数器3、实验三用VHDL设计6进制、60进制计数器4、实验四报时电路、分频电路、二选一电路5、实验五数字钟综合设计6、实验六 PROTEL99SE原理图、印制电路板图(PCB)设计四.实验报告内容要反映出以上6个实验的内容,重点说明数字钟综合设计,包括实验目的、实验原理、实验步骤、实验电路或者是程序、仿真波形(在能够仿真的情况下)、实验中遇到的问题及解决的方法,实验完成的效果等。

五.总结简单谈一下学习本课程的体会。

1CPLD及电子CAD 实验报告姓名:黄嘉宝学号:2010108122网选班号:1网选序号:13同组同学姓名:郑琦三峡大学电气与新能源学院21、实验一组合逻辑设计、实验装置的使用方法一、实验目的:(1)简单了解38译码器的设计,初步掌握组合逻辑电路的设计方法(2)学会使用MAX2软件二、实验步骤:1、指定项目名称启动max2软件——file——Project name(对话框中输入项目名)2、建立新文件File ——new(选第一个XX.gdf文件)——OK3、设计的输入1)原图的空白处双击鼠标左键2)输入原件名称或鼠标点击选取即可以38译码器的逻辑电路设计为例步骤如下:双击max2启动软件——file——project——输入项目名ymq38_13——file——new——选第一个XX.gfd——OK——保存命名ymq38.gdf——双击鼠标左键依次输入元器件input\output\not\and3\依次命名然后连线得到附录一图——保存——编译确定是否有连线错误(max2+plus——comfile)4、硬件检测功能编程下载,验证电路逻辑功能的硬件检测方法1、指定器件assign/device选ACEX1k和EP1K30TC144—12、编译生效max-plus/compiler3、分配管脚max-plus/floorplan editor4、编译生效max-plus/compiler5、打开装置的电源开关调到模式56、下载max-plus/programmer7、载入下载文件JIAG/Multi-Device JIAG Chain setup8、删除无用文件9、浏览后缀为.sof的文件,点add10、点configure管脚如何分配:在给定的装置结构图里面选取适当的数码管和相应的控制开关,然后在给定的表格中找到对应的管脚,然后分别把管脚导入到相应的位置34附录一五、波形仿真:file-new-waveform editor (波形文件)保存 Node-enter-list-(导入输入、输出)options-gridsize(改尺寸不能低于10nm) simulator(开始仿真) timing anal(定时分析器) 得到如下结果验证38译码器52.VHDL 硬件描述语言在VHDL 程序中,通常包括实体(ENTITY )、结构体(ARCHITECTURE )、配置(CONFIGURATION)、包集合(PACKAGE)、和库(LIBRARY)5部分。

CPLD可编程数字信号发生器通信原理实验正文

CPLD可编程数字信号发生器通信原理实验正文

实验一CPLD可编程数字信号发生器实验实验项目名称:CPLD可编程数字信号发生器实验项目性质:验证性所属课程名称:数字通信原理实验计划学时:2一、实验目的1.熟悉各种时钟信号的特点及波形2.熟悉各种数字信号的特点及波形二、实验电路的工作原理1、CPLD可编程模块电路的功能及电路组成图2-1是CPLD可编程模块的电路图。

CPLD可编程模块(芯片位号:U101)用来产生实验系统所需要的各种时钟信号和数字信号。

它由CPLD可编程器件ALTERA公司的EPM7128(或者是Xilinx公司的XC95108)、编程下载接口电路(J101)和一块晶振(OSC1)组成。

晶振用来产生系统内的16.384MHz 主时钟。

本实验要求参加实验者了解这些信号的产生方法、工作原理以及测量方法,才可通过CPLD可编程器件的二次开发生成这些信号,理论联系实践,提高实际操作能力。

2、各种信号的功用及波形CPLD型号为EPM7128由计算机编好程序从J101下载写入芯片,OSC1为晶体,频率为16.384MHz,经8分频得到2.048MHz主时钟,面板测量点与EPM7128各引脚信号对应关系如下:SP101 2048kHz主时钟方波对应U101EPM7128 11脚SP102 1024kHz 方波对应U101EPM7128 10脚SP103 512kHz 方波对应U101EPM7128 9脚SP104 256kHz 方波对应U101EPM7128 8脚SP105 128kHz 方波对应U101EPM7128 6脚SP106 64K 方波对应U101EPM7128 5脚SP107 32K 方波对应U101EPM7128 4脚SP108 16K 方波对应U101EPM7128 81脚SP109 8K 方波对应U101EPM7128 80脚SP110 4K 方波对应U101EPM7128 79脚SP111 2K 方波对应U101EPM7128 77脚SP112 1K 方波对应U101EPM7128 76脚SP113 PN32K 32kHz伪随机码对应U101EPM7128 75脚SP114 PN2K 2kHz伪随机码对应U101EPM7128 74脚SP115 自编自编码波形,波形由对应U101EPM7128 73脚J102开关位置决定SP116 长0长1码码形为1、0连“1”对应U101EPM7128 70脚与1、0连“0”码SP117 X 绝对码输入对应U101EPM7128 69脚SP118 Y 相对码输出对应U101EPM7128 68脚SP119 F80 8kHZ时隙取样脉冲对应U101EPM7128 12脚此外,取样时钟、编码时钟、同步时钟、时序信号还将被接到需要的单元电路中。

CPLD实验报告

CPLD实验报告

实验一 Xilinx软件及状态机设计一实验目的:学习FPGA设计软件, 掌握软件流程, 掌握状态机编程。

二实验内容:设计一个状态机三实验说明:状态机设计是数字电路中使用非常广泛和方便的时序设计工具。

由于硬件是并行的触发, 相对软件是串行执行, 那么让硬件电路按照节拍执行串行操作指令就成为一个问题, 这就是状态机的主要功能。

相应的, 软件指令中的几十条简单顺序执行代码可能需要硬件的几十上百个触发器去实现其功能。

所以, 软件与硬件的设计思路有相当大的区别。

当然, 随着FPGA规模的不断扩大, 这些问题也越来越容易解决了。

我们可以用软件的思路去描述自己的设计, 可能最终实现的电路是几十万门级的器件, 但是你只要花费几美元就能买到。

状态机是数字电路的基础, 因此, VHDL的学习也从这个实验开始。

四实验过程:1.在进行实验之前, 我先自学了VHDL语言。

2.熟悉Xilinx软件环境。

3.通过仿真, 读懂了states这段代码所实现的功能及其出现的问题。

五思考题:1.通过仿真, 这段代码实现相应功能时出了什么问题?请修正代码。

答:这段程序完成的是对红绿灯的控制功能。

通过仿真发现所有的灯都比预期的多亮了2秒, 比如东西方向绿灯亮62秒(应该是60秒), 黄灯是5秒(应该是3秒)。

出现此问题的原因是没有考虑到硬件的延时问题。

所以只要把程序中的59改为57, 39改为37, 3改为1, 再进行仿真, 结果就正确了。

2.状态机输出分成同步输出和异步输出, 状态机异步输出直接用状态机的某个状态进行组合逻辑运算来得到一个输出, 同步输出是在该状态的时钟上跳沿控制输出变化。

请问同步输出和异步输出利弊各在哪里?答: 同步输出的优点是: 时钟脉冲的间距解决了组合逻辑电路中的延时和竞争问题。

只要时钟脉冲的宽度合适, 输出就不会存在竞争与现象。

缺点是: 外部输入信号的变化应满足触发器正常工作所需的建立和保持时间。

因为上述特点使得同步时序输出的工作速度的提高受到限制, 且对时钟脉冲到达个触发器的时间及外部信号的变化有较严格的要求。

可编程逻辑器件、FPGA、CPLD实验报告2

可编程逻辑器件、FPGA、CPLD实验报告2

CPLD/FPGA 设计实验报告实验名称: 时序电路设计基础 实验目的: 掌握Quartus II 软件的基本使用方法,完成基本时序电路设计 学生姓名: 学号: 实验内容:实验一 模100计数器一、 创建工程工程名称:count100顶层实体文件名:count100 器件: EP1C3T100C8 二、 创建文件 创建Verilog HDL 文件,实现一个模100的计数器功能电路,要求可以实现清零功能。

module count100(clk,cout,qout,reset);input clk,reset;output reg[6:0] qout;output cout;always@(posedge clk)beginif(reset) qout<=0;else if(qout<99) qout<=qout+1;else qout<=0;end assign cout=(qout==99)?1:0; endmodule装订 线三、编译工程报告中下列数据是多少total logic elements:12 total pins:10四、仿真电路1、创建VWF文件2、设定“End Time”为50us3、在VWF文件中添加Node OR Bus4、编辑波形5、仿真6、画出仿真结果实验二8位加法器一、创建工程工程名称:add8 顶层实体文件名:add8器件: EP1C3T100C8二、创建文件创建Verilog HDL文件,实现一个8位加法器功能电路。

module add4(cout,sum,ina,inb,cin);input cin;input[7:0] ina,inb;output[7:0] sum;output cout;assign {cout,sum}=ina+inb+cin;endmodule三、编译工程报告中下列数据是多少total logic elements:10 total pins:26四、仿真电路1、创建VWF文件2、设定“End Time”为20us3、在VWF文件中添加Node OR Bus4、编辑波形5、仿真6、画出仿真结果。

CPLD及FPGA课程学生实验指导

CPLD及FPGA课程学生实验指导

《CPLD/FPGA应用开发技术》实验指导第一部分实验系统介绍本系统主要由CPLD主芯片(或适配器)和外围的输入输出外设构成,CPLD主芯片的所有用户可用I/O口均没有固定接入,而仅以插孔的形式存在,因此用户在设计时,可根据需要定义管脚。

(一)EPM7128S适配器说明环绕适配器的圆插空是将芯片所有的可用插孔直接引出,插空旁的数字/标号就是芯片上被外连的管脚号(即pin number)。

用户可根据适配划分后的结果,直接用连线将对应管脚号的插孔同所选外设的接口插孔相连。

以下是管脚说明。

(二)时钟源六路单独时钟,按频率范围高低排列为:CLK0>CLK1>CLK2=CLK4>CLK3=CLK5,其中CLK0、CLK1直接对4M晶振进行分频,CLK2、CLK3、CLK4、CLK5经过两级分频,第一级为JPCK跳线排;第二级在相应的同标号的跳线排上。

(三)普通输入输出器件接口主要为开关、LED灯。

1、按键开关:不按为“1”,按下为“0”。

2、拨码开关:拨上为“1”,拨下为“0”。

3、LED灯:输入高电平亮、输入低电平灭。

(四)扫描类接口外设1、8位七段数码管共阴极数码管,字形输入为a、b、c、d、e、f、g、Dp。

对应标准数码管的七个段位和一个小数点,高电平有效。

[SEL2,SEL1,SEL0]译码后确定哪一位数码管被点亮;若同时显示,只需要产生[SEL2,SEL1,SEL0]信号的时钟足够快(>100Hz)。

其操作类似于向8*8bit存储器中写数据。

2、16*16LED点阵(1)[L0~L15]对应点阵的行输入、高电平有效。

(2)[SEL3,SEL2,SEL1,SEL0]译码后为点阵列选通,决定哪一列被点亮。

若同时显示,只要产生循环地址信号的时钟足够快。

其操作类似于向16*16bit存储器中写数据。

(五)EEPROM(2864)D0~D7:EEPROM数据端A0~A12: 地址输入端/WE: 写使能,“0”有效/OE: 读使能,“0”有效/CE: 片选第二部分实验内容实验一组合逻辑电路的设计一、实验目的:1、掌握用VHDL语言和EPLD进行组合逻辑电路的设计方法。

cpld报告

cpld报告

CPLD课程学习报告学生姓名:钟琦同组姓名:王晓娟在没有接触cpld这门课程之前,可以说对Max+plusⅡ这个软件一窍不通,第一节课时,黄老师用投影仪为我们仔细演示了一遍这个软件的操作过程,通过这节课的学习,我了解到Max+plusⅡ编译一个项目前,必须确定一个设计文件作为当前项目。

对于每个新的项目应该建立一个单独的子目录,当指定设计项目名称时,也就同时指定了保存该设计项目的子目录名实验步骤如下:实验步骤1)新建文件后,输入项目文件名(File/Project/Name)(此时save as名称如果是程序则需要用vhd结尾保存文件)2)输入源文件(图形、VHDL、波形输入方式)(Max+plusⅡ/graphic Editor;Max+plusⅡ/Text Editor;Max+plusⅡ/Waveform Editor)3)指定CPLD型号,选择器件(Assign/Device)(应选择EP1K 30TC144-1)4)设置管脚、下载方式和逻辑综合的方式(Assign/Global Project Device Option,Assign/Global Logic Synthesis) 5)保存并检查源文件(File/project/Save & Check)6)指定管脚(Max+plusⅡ/Floorplan Editor)(具体的管脚应该参考CPLD管脚资源表格)7)保存和编译源文件(File/project/Save & Compile)8)生成波形文件(Max+plusⅡ/Waveform Editor)9)仿真(Max+plusⅡ/Simulator)10)下载配置(Max+plusⅡ/Programmer)一分别做10,24,60进制的计数器因为是第一次接触CPLD的编程,所以对它所用的语言不清楚,第一次写10进制计数器程序时基本是照着老师写的程序生搬硬套上去的,后面写24和60进制计数器时才基本弄懂有些程序的意思。

FPGA与CPLD 总结

FPGA与CPLD 总结

CPLD(complex programable logic device)复杂可编程逻辑器件FPGA(field programable gate array)现场可编程门阵列FPGA和CPLD的逻辑单元本身的结构与SPLD相似,即与阵列和可配置的输出宏单元组成。

FPGA逻辑单元是小单元,每个单元只有1-2个触发器,其输入变量通常只有几个因而采用查找表结构(PROM形式)这样的工艺结构占用的芯片面积小,速度高(通常只有1-2纳秒),每个芯片上能集成的单元数多,但逻辑单元功能弱。

如果想实现一个较复杂的功能,需要几个这样的单元组合才能完成(总延时是各个单元延时和互连延时的和),互连关系复杂。

CPLD中的逻辑单元是单元,通常其变量数约20-28个。

因为变量多,所以只能采用PAL结构。

由于这样的单元功能强大,一般的逻辑在单元内均可实现,因而其互连关系简单,一般通过集总总线既可实现。

电路的延时通常就是单元本身和集总总线的延时(通常在数纳秒至十几纳秒),但是同样集成规模的芯片中的触发器的数量少得多。

从上面分析可知道:小单元的FPGA较适合数据型系统,这种系统所需要的触发器数多,但是逻辑相对简单;大单元的CPLD较适合逻辑型系统,如控制器等,这种系统逻辑复杂,输入变量多,但触发器需求量相对较少。

反熔丝工艺只能一次性编程,EPROM EEPROM 和FLASH工艺可以反复的编程,但是他们一经编程片内逻辑就被固定。

他们都是只读型(ROM)编程,这类编程不仅可靠性较高还可以加密。

XILINX公司的FPGA芯片采用RAM型编程,相同集成规模的芯片中的触发器数目较多,功耗低,但是掉电后信息不能保存,必须与存储器联用。

每次上电时必须先对芯片配置,然后才能使用,这似乎是RAM型PLD的缺点,但是ROM型PLD中的编程信息在使用时是不能变化的,RAM型PLD却可以在工作时更换内容,实现不同的逻辑。

CPLD和FPGA的结构,性能对照:CPLD FPGA PROM集成规模:小(最大数万门)大(最高达百万门)单元粒度:大(PAL结构)小(PROM结构)互连方式:集总总线分段总线长线专用互连编程工艺:EPROM EEPROM FLASH SRAM编程类型:ROM RAM型须与存储器联用信息:固定可实时重构触发器数:少多单元功能:强弱速度:高低222222222222222222222222222222222222延迟:确定,可以预测不能确定不能预测功耗:高低加密性能:可加密不能加密适用场合:逻辑型系统数据型系统LCA(LOGIC CELL ARRAY)逻辑单元阵列CLB(CONFIGURABLE LOGIC BLOCK)可配置逻辑模块IOB(INPUT OUTOUT BLOCK)输入输出块Spartan-xl系列FPGA的主要特性SPARTAN-XL系列的FPGA具有低压,低功耗的特点。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《串行通信接口》项目报告计算机学院一、项目目标综合运用所学基本知识,通过在CPLD/FPGA开发板子完成按键响应、蜂鸣器蜂鸣、数码管显示以及其他项目所要达到的效果,最后在开发板上构建成一个全双工的串行通信接口。

用户利用这个串行通信接口,可以与PC机或其它设备进行串行通信,并可以自主设置串行通信的数据格式和其他属性。

二、项目设备1、硬件:PC机CPLD/FPGA开发板2、软件:WindowsXP/2000系统,Quartus II 7.2 (32-Bit)开发环境,comtools2.0。

三、项目内容1、串行通信接口项目,项目内容包括:(1)主模块设计;(2)显示模块设计;(3)时钟模块设计;(4)控制模块设计;(5)收发模块设计;(6)发送模块设计;(7)发送控制模块设计;(8)发送移位寄存器模块设计;(9)接收模块设计;(10)接收控制模块设计。

2、设计一个基于CPLD/FPGA硬件平台的串口通信接口,项目的主要元素分为:(1) 在实验板上构成一个全双工的串行通信接口,用户利用这个串行接口,可以与PC机或其它设备进行串行通信,并可以设置串行通信的格式;(2) 系统的状态分成工作状态和设置状态:在工作状态下,进行串行通信;在设置状态下,进行通信格式的设置。

(3) 该系统用5个数码管(一个单独的数码管和一个4位数码管)显示串行通信的格式,比如串行通信的波特率是4800,7位数据位,校验方式为偶校验,则数码管显示为“E 48-7”。

(4) 当系统处于工作状态时,如果收到串行数据,则把该数据显示在发光管上,如果接收到的数据有错误(包括奇偶校验错误和帧错误),则让蜂鸣器发出响声。

3、串口通信接口实现的功能:(1) 在工作状态下,若用户按下K1按键,则把拨码开关上的数据发送出去。

(2) 在工作状态下,如果用户按下K2按键,进入设置状态,首先设置进行校验方式的设置:这时单独的数码管闪烁显示,若用户按下K3按键可以改变校验方式(共有O、E、n三个取值)。

(3) 在此过程中,如果用户再次按下K2按键,可以进行波特率的设置:这时4位数码管的高两位闪烁,若用户按下K3按键可以改变波特率(共有96、48、24、12四个取值)。

(4) 在此过程中,如果用户再次按下K2按键,可以改变数据位位数:这时4位数码管的(5) 最低位闪烁,用户按下K3按键可以改变数据位的位数(共有8、7、6、5四个取值)。

(6) 在此过程中,如果用户再次按下K2按键,则系统又回到工作状态。

四、项目设计根据设计要求,应把系统分成4个模块来完成,这四个模块分别是:时钟模块(向系统各部分提供各种频率的时钟信号)收发模块(进行串行通信的发送和接收)显示模块(显示通信的数据格式)控制模块(控制系统的工作)1.程序各模块的逻辑框图项目主模块的逻辑框图如下:2、各个模块逻辑框架图如下:①时钟模块②控制模块③显示模块④发送模块⑤发送移位寄存器模块⑥发送控制模块⑦接收模块⑧接收控制模块三、程序代码module mainmodule(k1,k2,k3,Hz24,sw,L4BitSel,L1Seg,L4Seg,Txd,Rxd,shineled,beep);input k1,k2,k3,Hz24,Rxd;input[7:0]sw;output[7:0]L1Seg,L4Seg,shineled;output[3:0]L4BitSel;output Txd,beep;wire enable;wire[15:0] bcd;wire[4:0] shine;wire Hz1,Hz50,Hz400,Hz1000,send,recv;wire[1:0]baud,chk,bits;Clk Clk(Hz24,baud,Hz1,Hz50,Hz400,Hz1000,recv,send); //时钟模块Ctrl Ctrl(k2,k3,Hz50,chk,baud,bits,bcd,shine,enable); //控制模块Show Show(bcd,Hz400,chk,shine,Hz1,L1Seg,L4Seg,L4BitSel);//显示模块Send Send(sw,k1,Hz50,enable,send,bits,chk,Txd); //发送模块Rev Rev(recv,Hz1000,enable,bits,chk,Rxd,beep,shineled); //接收模块Endmodulemodule Clk(Hz24M,baud,Hz1,Hz50,Hz400,Hz1000,recv,send); //时钟模块input Hz24M;input [1:0] baud;output Hz1,Hz50,Hz400,Hz1000,send,recv;wire Hz28800,Hz14400,Hz7200,Hz3600,Hz9600,Hz4800,Hz2400,Hz1200;fenpin2 tfenpin1(Hz24M,Hz28800);fenpin3 tfenpin2(Hz24M,Hz400);fenpin1 tfenpin3(Hz24M,Hz1000);onehalffenpin afenpin1(Hz28800,Hz14400);onehalffenpin afenpin2(Hz14400,Hz7200);onehalffenpin afenpin3(Hz7200,Hz3600);threefenpin threefenpin0(Hz28800,Hz9600);onehalffenpin afenpin4(Hz9600,Hz4800);onehalffenpin afenpin5(Hz4800,Hz2400);onehalffenpin afenpin6(Hz2400,Hz1200);Datasel Datasel({Hz28800,Hz9600},{Hz14400,Hz4800},{Hz7200,Hz2400}, {Hz3600,Hz1200},baud,{recv,send});eightfenpin ffenpin0(Hz400,Hz50);fiftyfenpin gfenpin0(Hz50,Hz1);endmodulemodule Datasel(d1,d2,d3,d4,addr,out); //数据选择器模块input[1:0] d1,d2,d3,d4;input[1:0] addr;output[1:0] out;reg[1:0] out;always@(d1 or d2 or d3 or d4 or addr)case(addr)2'b00:out=d1;2'b01:out=d2;2'b10:out=d3;2'b11:out=d4;endcaseendmodulemodule threefenpin(clkin,clkout);//三分频input clkin;output clkout;reg[1:0] Q; //寄存器always @(negedge clkin)if(Q==2'b10)Q=2'b0;elseQ =Q+1'b1;assign clkout=Q[1];endmodulemodule fenpin1(clkin,clkout);// 24MHz TO 1000Hz input clkin;output clkout;reg[13:0] Q;reg clkout;always @(negedge clkin)if(Q==14'd12000-1)beginQ=14'h0000;clkout=~clkout;endelseQ=Q+1'b1;endmodulemodule fenpin2(clkin,clkout);// 24MHz TO 28800Hz input clkin;output clkout;reg[8:0] Q;reg clkout;always @(negedge clkin)if(Q==9'd416)beginQ=9'h0000;clkout=~clkout;endelseQ=Q+1'b1;endmodulemodule fenpin3(clkin,clkout);// 24MHz TO 400Hz input clkin;output clkout;reg[14:0] Q; //计数器reg clkout;always @(negedge clkin)if(Q==15'd30000-1)beginQ=15'h0000;clkout=~clkout;endelseQ=Q+1'b1;endmodulemodule eightfenpin(clkin,clkout);//八分频input clkin;output clkout;reg[1:0] Q; //计数器reg clkout;always @(negedge clkin)if(Q==2'd3)beginQ=2'h0;clkout=~clkout;endelseQ=Q+1'b1;endmodulemodule onehalffenpin(clkin,clkout);//2分频input clkin;output clkout;reg clkout;always @(negedge clkin)clkout=~clkout;endmodulemodule fiftyfenpin(clkin,clkout);//50分频input clkin;output clkout;reg[4:0] Q; //计数器reg clkout;always@(negedge clkin)if(Q==5'd24)beginQ=5'h0;clkout=~clkout;endelseQ=Q+1'b1;endmodulemodule Ctrl(k2,k3,Hz50,chk,baud,bits,bcd,shine,enable); //控制模块input k2,k3,Hz50;output enable;output[1:0] chk,baud,bits;output[15:0] bcd;output[4:0] shine;wire k2out,k3out;wire[1:0] sysmode;wire[2:0] outk3;Filter filter1({k2,k3},Hz50,{k2out,k3out});//去抖动Cntfour cntfour1(k2out,sysmode); //4计数器K3mux k3m(k3out,sysmode,outk3); //数据分配器Cntfour cntfour2(outk3[0],bits); //4计数器Cntfour cntfour3(outk3[1],baud); //4计数器Cntthree cntthree0(outk3[2],chk); //3计数器Shine shine0(sysmode,shine); //闪烁Bauddecoder bauddecoder0(baud,bcd[15:8]); //译码器—波特率Bitsdecoder bitsdecoder0(bits,bcd[3:0]); //译码器-位assign bcd[7:4]=4'b1111;assign enable=~|sysmode;endmodulemodule Filter(D,clk,Q); //去抖input[1:0] D;input clk;output[1:0] Q;reg[1:0] Q;always @(negedge clk)Q=D;endmodulemodule Cntfour(clk,Q); //四进制计数input clk;output[1:0] Q;reg[1:0] Q;always@(negedge clk)Q=Q+1'b1;endmodulemodule Cntthree(clk,Q); // 三进制计数input clk;output[1:0] Q;reg[1:0] tmp;always@(negedge clk)if(tmp==2'b10)tmp=2'b0;elsetmp=tmp+1'b1;//tmp can be 00,01,10,assign Q=tmp+1'b1;//Q can be 01,10,11endmodulemodule K3mux(in,addr,out); //数据分配器input in;input[1:0] addr;output[2:0] out;reg[2:0] out;always@(in or addr)case(addr)2'b00: out=3'b111;//zai gong zui2'b01: out={in,2'b11};2'b10: out={1'b1,in,1'b1};//set baud2'b11: out={2'b11,in};//set bits endcaseendmodulemodule Shine(codein,codeout);//闪烁input[1:0] codein;output[4:0] codeout;reg[4:0] codeout;always@(codein)case(codein)2'b00: codeout=5'b00000;2'b01: codeout=5'b10000;2'b10: codeout=5'b01100;2'b11: codeout=5'b00001;endcaseendmodulemodule Bauddecoder(codein,codeout);// 波特率译码器input[1:0] codein;output[7:0] codeout;reg[7:0] codeout;always@(codein)case(codein)2'b00: codeout=8'h96;2'b01: codeout=8'h48;2'b10: codeout=8'h24;2'b11: codeout=8'h12;endcaseendmodulemodule Bitsdecoder(codein,codeout);//数据位译码器input[1:0] codein;output[3:0] codeout;reg[3:0] codeout;always@(codein)case(codein)2'b00: codeout=4'h8;2'b01: codeout=4'h7;2'b10: codeout=4'h6;2'b11: codeout=4'h5;endcaseendmodulemodule Show(L4bcd,Hz400,chk,shine,Hz1,L1Seg,L4Seg,L4BitSel); //显示模块input[15:0]L4bcd;input[4:0]shine;input[1:0]chk;input Hz1,Hz400;output[7:0]L1Seg,L4Seg;output[3:0]L4BitSel;wire[7:0]L1SegTmp;wire shine1;wire[3:0] L4Shine,BitSelTmp,L4BCDTmp;wire[1:0] CntOut;L1Decoder L1Decoder1(chk,L1SegTmp); //共阴1个数码管L1tux L1tux1(L1SegTmp,8'h00,shine1,L1Seg); //L1 数据选择器assign shine1=Hz1 & shine[4];L4Shinetux L4Shinetux1(shine[3:0],4'h0,Hz1,L4Shine); //闪烁数据选择器CountFour Countfour1(Hz400,CntOut); //4 计数VariDecoder Varidecoder1(CntOut,BitSelTmp); //变量译码器assign L4BitSel=L4Shine|BitSelTmp;tux tux1(L4bcd[15:12],L4bcd[11:8],L4bcd[7:4],L4bcd[3:0],CntOut, L4BCDTmp); //L4数据选择L4Decoder L4Decoder1(L4BCDTmp,L4Seg);//共阳4个数码管endmodulemodule VariDecoder(in,out); //变量译码器input[1:0]in;output[3:0]out;reg[3:0] out;always@(in)case(in)2'b00:out=4'b0111;2'b01:out=4'b1011;2'b10:out=4'b1101;2'b11:out=4'b1110;endcaseendmodulemodule L4Shinetux(d1,d2,addr,out);//闪烁数据选择器input[3:0] d1;input[3:0] d2;output[3:0] out;input addr;reg[3:0] out;always@(d1 or d2 or addr)case(addr)1'b0:out=d1;1'b1:out=d2;endcaseendmodulemodule L1Decoder(codein,segout);//共阴1个数码管input[1:0] codein;output[7:0] segout;reg[7:0]segout;always@(codein)case(codein)2'b01: segout=8'h37;//8'b11101101;//"n"2'b10: segout=8'h79;//8'b01111001;//"E"2'b11: segout=8'h3f;//8'b00111111;//"O"default:segout=8'b00000000;//bu xian shi endcaseendmodulemodule L4Decoder(codein,segout);//共阳4个数码管input[3:0] codein;output[7:0] segout;reg[7:0]segout;always@(codein)case(codein)4'h0: segout=8'hc0;//8'b11000000;4'h1: segout=8'hf9;//8'b11111001;4'h2: segout=8'ha4;//8'b10101100;4'h3: segout=8'hb0;//8'b10110000;4'h4: segout=8'h99;//8'b10011001;4'h5: segout=8'h92;4'h6: segout=8'h82;4'h7: segout=8'hd8;4'h8: segout=8'h80;4'h9: segout=8'h90;4'hf: segout=8'hbf;default:segout=8'b11111111;endcaseendmodulemodule CountFour(clk,Q);//4计数input clk;output[1:0] Q;reg[1:0] Q;always@(negedge clk)Q=Q+1'b1;endmodulemodule tux(data0,data1,data2,data3,addr,out);//L4数据选择input[3:0] data0,data1,data2,data3;input[1:0]addr;output[3:0]out;reg[3:0]out;always@(data0 or data1 or data2 or data3 or addr)case(addr)2'b00:out=data0;2'b01:out=data1;2'b10:out=data2;2'b11:out=data3;endcaseendmodulemodule L1tux(d1,d2,addr,out);//L1 数据选择器input[7:0] d1;input[7:0] d2;output[7:0] out;input addr;reg[7:0] out;always@(d1 or d2 or addr)case(addr)1'b0:out=d1;1'b1:out=d2;endcaseendmodule//发送模块module Send(sw,k1,hz50,enable,sendclk,datebits,check,Txd);//发送模块input k1,hz50,enable;input[7:0] sw;input sendclk;input[1:0] datebits,check;output Txd;wire[8:0] dataout;wire k1out;SendCtrl SendCtrl_1(sw,datebits,check,enable,sendclk,dataout, sendclkout);ClearupShake2 ClearupShake_2(hz50,k1,k1out);send_move send_move_1(k1out,hz50,sendclkout,dataout,Txd); endmodule//发送控制模块module SendCtrl(sw,datebits,check,enable,sendclk,dataout,sendclkout);input sendclk,enable;input[1:0] datebits,check;input[7:0] sw;output[8:0] dataout;output sendclkout;wire[2:0] swout1,encoderout,middate1;wire swout2,swout3,jy_bits;encoder_one encoder_one_1(datebits,encoderout);assign swout1 = sw[7:5] & encoderout;assign swout2 = ^{swout1,sw[4:0]};assign swout3 = ~swout2;//三选一数据选择器dataselone dataselone_1(1'b1,swout2,swout3,check,jy_bits);encoder_two encoder_two_1(datebits,jy_bits,middate1,dataout[8]);assign dataout[7:5] = swout1 | middate1;assign sendclkout = ~(enable & sendclk);assign dataout[4:0]=sw[4:0];endmodulemodule encoder_one(in,out);input[1:0] in;output[2:0] out;reg[2:0] out;always@(in)case(in)2'b00: out = 3'b111;2'b01: out = 3'b011;2'b10: out = 3'b001;2'b11: out = 3'b000;endcaseendmodulemodule encoder_two(in,date,out,high);input[1:0] in;input date;output[2:0] out;output high;reg[2:0] out;reg high;always@(in or date)case(in)2'b00:beginhigh = date;out[2] = 1'b0;out[1] = 1'b0;out[0] = 1'b0;end2'b01:beginhigh = 1'b1;out[2] = date;out[1] = 1'b0;out[0] = 1'b0;end2'b10:beginhigh = 1'b1;out[2] = 1'b1;out[1] = date;out[0] = 1'b0;end2'b11:beginhigh = 1'b1;out[2] = 1'b1;out[1] = 1'b1;out[0] = date;endendcaseendmodulemodule dataselone(data0,data1,data2,addr,out);//三选一数据选择器input data0,data1,data2;input[1:0] addr;output out;reg out;always@(data0 or data1 or data2 or addr)case(addr)2'b01: out = data0;2'b10: out = data1;2'b11: out = data2;default: out = data0;endcaseendmodulemodule send_move(k1,hz50,senclkout2,date,Txd);//发送移位模块input k1,hz50,senclkout2;input[8:0] date;output Txd;mov_reg11 mov_reg11_1(date,k1,Txd,senclkout2);endmodulemodule mov_reg11(date,keyin,out,clkcp); //11位移位寄存器input keyin,clkcp;input[8:0] date;output out;reg[10:0] Q;assign out = Q[0];always@(negedge clkcp)if(keyin == 1'b1)Q = {date,2'b01};elseQ = {1'b1,Q[10:1]};endmodulemodule ClearupShake2(clk,D,Q); //去抖动模块input clk;input D;output Q;reg Q;always@(negedge clk)Q = D;endmodulemodule Rev(revclk,hz1000,enable,databits,check,Rxd,beep,shineled); //接收模块input revclk,hz1000,enable;input[1:0] databits,check;input Rxd;output beep;output[7:0] shineled;wire[2:0] regout;wire startbits,judgeout,outrevclk,movenews;wire[9:0] revdata;RevCtrl RevCtrl_1(enable,databits,revclk,startbits,revdata,check, hz1000,outrevclk,movenews,beep,shineled);mov_reg3 mov_reg3_1(Rxd,outrevclk,regout,startbits);judgement judgement_1(regout,judgeout);mov_reg10 mov_reg10_1(judgeout,movenews,revdata);endmodulemodule mov_reg3(Rxd,clk,out,start);//3位移位寄存器input Rxd,clk;output start;output[2:0] out;reg[2:0] out;assign start = out[0] | out[1];always@(negedge clk)out = {Rxd,out[2:1]};endmodulemodule judgement(in,out);input[2:0] in;output out;reg out;always@(in)case(in)3'b000: out = 1'b0;3'b001: out = 1'b0;3'b010: out = 1'b0;3'b011: out = 1'b1;3'b100: out = 1'b0;3'b101: out = 1'b1;3'b110: out = 1'b1;3'b111: out = 1'b1;endcaseendmodulemodule mov_reg10(in,clk,out);input in,clk;output[9:0] out;reg[9:0] out;always@(negedge clk)out = {in,out[9:1]};endmodule//接收控制模块Module RevCtrl(enable,databits,revclk,startbits,revdata,check,hz1000, outrevclk,movenews,beep,shineled);input enable,revclk,startbits,hz1000;input[1:0] databits,check;input[9:0] revdata;output outrevclk,movenews,beep;output[7:0] shineled;wire[3:0] countout0,data0,data1,dataout;wire countout1,countout2,dataout2,dataout3,seldataout,seldataout2, Gstart;wire[8:0] newdata;wire[7:0] shineled0;assign Gstart = startbits | countout1;//或门assign outrevclk = ~(enable & revclk);assign countout1 = | countout0;//或门assign countout2 = outrevclk & countout1;threefenpin Onethird_2(countout2,movenews);//三分频Gary Gary_1(movenews,Gstart,data0,countout0);//格雷码计数器模块encoder encoder_1(databits,check[1],data0,data1);//译码器模块assign dataout = revdata[3:0] & data1;//assign newdata = {revdata[8:4] , dataout};//assign dataout2 = ^newdata;//异或门assign dataout3 = ~dataout2;//非门dataselone dataselone_2(1'b1,dataout3,dataout2,check,seldataout);//三选一数据选择器assign seldataout2 = &{revdata[9],seldataout};//assign beep = hz1000 | countout1 | seldataout2;//或门assign shineled = ~shineled0;//非门datasel2 datasel2_1(newdata,check[1],shineled0);//一选一数据选择器endmodulemodule Gary(clk,set,data,out);//格雷码计数器模块input clk,set;input[3:0] data;output[3:0] out;reg[3:0] out;initial out = 4'b0000;always@(negedge clk or negedge set)if(set == 1'b0)out = 4'b0001;elsebeginif(out == data)out = 4'b0000;elsecase(out)4'b0001: out = 4'b0011;//24'b0011: out = 4'b0010;//34'b0010: out = 4'b0110;//44'b0110: out = 4'b0111;//54'b0111: out = 4'b0101;//64'b0101: out = 4'b0100;//74'b0100: out = 4'b1100;//84'b1100: out = 4'b1101;//94'b1101: out = 4'b1111;//10default: out = 4'b0000;endcaseendendmodulemodule encoder(databits,judgenews,data0,data1);//译码器模块input judgenews;input[1:0] databits;output[3:0] data0,data1;reg[3:0] data0,data1;always@(judgenews or databits)if(judgenews == 1'b0)case(databits)2'b00: begindata0 = 4'b1101;//9data1 = 4'b1110;end2'b01: begindata0 = 4'b1100;//8data1 = 4'b1100;end2'b10: begindata0 = 4'b0100;//7data1 = 4'b1000;end2'b11: begindata0 = 4'b0101;//6data1 = 4'b0000;endelsecase(databits)2'b00: begindata0 = 4'b1111;//10data1 = 4'b1111;end2'b01: begindata0 = 4'b1101;//9data1 = 4'b1110;end2'b10: begindata0 = 4'b1100;//8data1 = 4'b1100;end2'b11: begindata0 = 4'b0100;//7data1 = 4'b1000;endendcaseendmodulemodule datasel2(in,clk,out);input[8:0] in;input clk;output[7:0] out;reg[7:0] out;always@(clk or in)case(clk)1'b0: out = in[8:1];1'b1: out = in[7:0];endcaseendmodule五、运行结果(主要步骤的截图)1、时钟模块2、控制模块3、显示模块4、发送模块5、接收模块30 6、整体模块五、项目总结1、遇到的问题:虽然项目的整体框架已经明确,但在具体的实际编写中仍会遇到各种各样的问题。

相关文档
最新文档