前言:
而今我们对“bcd转换为二进制数计算器”可能比较注意,咱们都想要知道一些“bcd转换为二进制数计算器”的相关资讯。那么小编同时在网络上搜集了一些对于“bcd转换为二进制数计算器””的相关资讯,希望大家能喜欢,你们快快来学习一下吧!写在前面的话
我大学本科学的是测控专业,2012年考取首都师范大学物理系研究生。我从未学习过数字电路设计,对FPGA和Verilog语言没有任何概念,更没有设计数字电路系统的基础和经验,也从未自己动手装配和完成过一台能实际运行的电子系统。但我从小就对电子设计有浓厚的兴趣。为什么小小的计算器按几下就能完成非常复杂的数学计算,一直困惑着我,激起我年轻的好奇心。大学四年里,虽然学习过“数字电路”和“模拟电路”课程,考试成绩也很不错,但对我而言,计算器是如何设计的,仍旧是一头雾水。
听同学们说,如果掌握了FPGA设计,这个谜就能找到答案。我用关键字“FPGA培训”在百度搜索,发现一个公司正在开设FPGA就业培训(100天)班,也知道这个班由北京航空航天大学的夏宇闻教授亲自讲授和管理。于是下定决心抽出3个月时间,认真学习一下FPGA。经过100天的学习和练习,我初步掌握了如何用FPGA芯片设计和搭建复杂数字系统。现在我有充分的信心,只要设计需求明确,我完全有能力独立设计并完成一个较复杂的数字系统,并能可靠地完成预先设定的数据 处理任务。这个阶段的学习给了我很多启发,也增强了我的信心,很想把自己的感受和学习心得编写成小册子与大家分享。我的想法得到夏宇闻教授的支持。于是我把学习期间的心路历程和学到的知识、经验略加整理,以日记的形式写出来,与大家分享,希望能给打算学习Verilog和FPGA设计的初学者一些帮助和启发,起到抛砖引玉的作用。
本书使用的硬件为至芯科技的四代开发板、Altera CycloneⅣ的芯片,软件为QuartusⅡ13.0 sp1。
——作者
1设计需求讲解
今天是我参加FPGA设计培训班的第2周。
上周夏宇闻老师把Verilog语言的基本概念、FPGA工作原理和FPGA开发工具做了全面的介绍。通过几天的听讲和上机练习,我已初步掌握了用ModelSim进行简单模块仿真和综合的步骤和要点,也初步理解了可综合模块和专门用于仿真的测试模块有什么不同,当然我的语法知识还十分贫乏,电路结构的概念也十分模糊。因此心里不免有些担心,我能开始独立设计吗? 怀着忐忑不安的心情,我走进了教室。
今天在课堂上,夏老师要求我们用十天时间完成一个能进行三位数加、减、乘、除四则运算的计算器,最后结果可以显示六位数字。他对设计目标和要求做了明确的说明,并介绍了几个相关的小模块,作为大家开始设计时的参考。他说先把功能做出来,再逐步提高性能,减小电路资源的消耗,让大家边设计边学习。
这些小模块容易理解吗? 怎样才能把这些小模块加以改造,重新组装,最后做成一个能进行三位数的加、减、乘、除四则运算功能基本完善的小计算器? 我心里实在没有把握。
今天上午夏老师的讲课非常重要,我一定要认真听讲,积极思考,多提问题,多上机练习,争取对设计过程和方法有完整彻底的理解。夏老师今天讲课的主要内容包括五个部分:
1)LED数码显示部分;
2)4×4键盘码扫描分析电路;
3)算术逻辑运算单元部分;
4)数制转换部分: BCD码到二进制,二进制到BCD码;
5)运算操作过程的状态机。
他描述了这几个部分之间是如何联系的,讲解了最低设计要求和最高设计要求。他让我们每位同学各显其能,尽量达到最高标准。最后一天每位同学都必须要把自己完成的计算器样机演示给大家看,并允许别人操作,大家民主评比,看哪位同学设计的样机性价比最高。
今天老师在课堂上演示了几个程序段,但并没有详细讲解。详细讲解的只有 LED数码显示部分,要求大家在今天完成的也只有数码显示部分。其余部分将在随后几天详细讲述。
2七段式数码显示原理讲解
下面是我对夏老师LED数码显示讲课要点的总结。
七段式数码管就是使用七段点亮的线段来拼成常见的数字和某些字母,这种显示方式在数字电路中非常容易见到。再加上右下角显示的小数点,实际上一个显示单元包括了8根信号线。根据电路设计的不同,这些信号线可能高电平有效也可能低电平有效。我们通过控制这些线段为0或者1,即高或低电平即可达到显示效果。
单个数码管的结构图如图1-1所示。
图中共有8个显示段(7个数字显示段,1个小数点显示段),每个显示段由一个独立的发光二极管(LED)组成,通过8位数据线(sig[7:0])控制8个LED的亮和灭,由此显示出设计者想要显示的字符和小数点。本实验中采用的是至芯开发板,它采用共阳极数码管,因此若显示某段LED的另外一端为高电平(1),则该段LED熄灭;若为低电平(0),则该段LED点亮。例如,若想要显示数字“1”,则由图中可以看出1是由B和C两发光段组成的,所以只要向显示B、C段的两个LED的另外一端输出0,向显示其余各段的LED的另外一端输出1,即11111001(由高至低),便可显示数字1。由此可知,0~F的显示码依次是:
0 : 8'b11000000; 1 : 8'b11111001;
2 : 8'b10100100; 3 : 8'b10110000;
4 : 8'b10011001; 5 : 8'b10010010;
6 : 8'b10000010; 7 : 8'b11111000;
8 : 8'b10000000; 9 : 8'b10010000;
A : 8'b10001000; B : 8'b10000011;
C : 8'b11000110; D : 8'b10100001;
E : 8'b10000110; F : 8'b10001110;
上述显示码中的8表示8位数, ‘b表示二进制。对于有多个数码管的显示模块,将每一个模块都连接到FPGA的引脚会耗用大量的引脚资源。在实际电路中,每个数码管中的8个LED管的正极被连接在一起,通过一个通/断可控的三极管再连接到电源的阳极,控制该三极管的通/断并配合8位数据线(sig[7:0])的输入,就可依次点亮6个数码管中的某一个。这种方法就是广泛应用于数码显示的扫描点亮的方式。换言之,在点亮某一个数码管期间,在8位数据线(sig[7:0])上输入该管应该显示的电平,即依次点亮6个数码管中的某一个,显示该数码管应该显示的数字。当扫描的频率足够高时,由于数码管的余晖以及人眼的视觉延迟会觉得数码管是全部点亮的。通常建议使用60Hz左右(即每个数码管导通约16ms)的扫描频率即可达到多位数码管同时点亮(只是人眼看上去是同时点亮,如果用照相机拍照即可发现并不是同时点亮)的效果。
由于是用作简易计算器显示,本计算器的功能不涉及浮点数据,因此忽略小数点显示段。本开发板使用的是共阳极数码管,其原理如图1-2所示,位选通过PNP三极管接电源,因此数码管为低电平选通,显示段为低电平点亮。
由原理图可以看出,数码管的输入,也就是FPGA控制数码管的连线有段选SEG-0~SEG-7,位选SEL0~SEL2,共11根线。没有接触过数码管扫描显示的同学注意了,要有段选和位选的概念。“段”是指刚刚所说的A、B、C、D、E、F、G、DP 这8根信号线,通过“段选”来控制数码管显示的是什么字;“位”是指这6个数码管其中的一个,注意这里是“个”而不是“段”,通过“位选”来控制这6个数码管哪一个会亮。也就是说,板子上有6个数码管,每个数码管有8段,段选控制数码管显示的是哪个数字,而位选则控制这个数字会出现在哪个位置,即个位、十位、百位、千位……本来位选也应该是由6根线来控制6个数码管的,但是考虑到这些数码管不会同时点亮,所以采用一个3-8译码器将6根线减少到3根,节约了FPGA的引脚资源。
那么数码管显示模块的输出就确定下来了, 3根选择线(SEL[2:0])和8根字段线 (SEG[7:0])。接下来就可以开始写代码了。首先暂不考虑输入的问题,先让该模块输出一个固定的数字,比如输出8个1,就是让SEG为11111001, SEL的取值从000到101,正好对应上6个数码管,所以让SEL随时钟变化而增加,就会出现6个数码管上都显示1。
3设计工具使用讲解
想要完成设计,计算机上必须安装 Quartus II和 ModelSim两个工具。前者是 FPGA综合分析工具;后者是验证设计的Verilog模块功能是否正确,是否与其他模块能正常交流数据的仿真工具。
1、Quartus Ⅱ 工具的配置
单击计算机桌面上的Quartus Ⅱ图标,启动 Quartus Ⅱ工具,稍等片刻,系统会弹出一个Introduction页面。单击页面下方的next按钮,系统弹出Quartus Ⅱ的主菜单,单击File→New Project Wizard(见图1-3),随即弹出如图1-4所示的对话框。
在开始设计之前, Quartus Ⅱ工具自动弹出要求设计者回答:工程的名称、放置的目录路径、设计的模块名、所用器件型号、所用仿真工具类型、所用语言等重要设置。如图1-4所示的对话框中需要填写工程所在目录、工程名以及模块名。
夏老师在讲解中特别提到:所有的设计文件必须放置在自己觉得取用方便的硬盘目录中,任何设计目录都不能用中文命名。在这里我们把工程定义为计算器,取名calc,填入第2行空格;模块为数码管显示模块,取名为display,填入第3行空格(见图1-4),写好之后单击对话框下面的Next按钮。
弹出的第2个对话框是要添加已经写好的代码文件。因为要从头开始写,所以这一页可以不予处理,直接按Next按钮。
弹出的第3个对话框是设置FPGA器件页。找到与开发板上对应的器件型号EP4CE10F17C8(见图1-5),选好之后单击对话框下面的Next按钮。
随即弹出的第4个对话框(见图1-6)是配置EDA工具的界面。这里只需把对话框中Simulation工具栏的空格设置一下即可.选择Tool Name(工具名称)为 ModelSim-Altera或者ModelSim,选择Format(s)(语言格式)为VerilogHDL,如图配置好后,单击对话框下面的Next按钮。
注意:选择哪种类型的仿真工具与用户所安装的Quartus Ⅱ版本有密切的关系. 该类型的仿真工具和语言必须得到Quartus Ⅱ版本的支持。
随即弹出的第5个对话框是对之前所选的项做一个总结,请用户核对一下信息,看是否跟之前设置的一致,若正确无误,单击下面的Finish按钮即可。
工程创建完毕,选择File→New或者直接单击菜单左上角的新文件按钮,会弹出如图1-7所示菜单,选择Verilog HDL File,然后单击下面的OK按钮即可创建一个新的代码文件。
2、数据管显示模块的可综合代码
至此,编写模块代码的准备工作已完成,可以开始编写代码了。以下是数码管显示模块的可综合代码。
module display0(clk, rst_n , sel, seg); //定义模块名为display0,定义输入输出端口 input clk; //两个输入:一个为时钟clk, input rst_n; //另一个为复位rst_n(信号名后缀_n表示该信号低电平有效) output reg [2:0] sel; //两个输出:一个为位选sel output reg [7:0] seg; //另一个为段选seg reg [15:0] cnt; //而产生慢时钟则需要一个计数器cnt// 故定义一个计数器cnt,位宽大一些没关系,要保证够用 reg clk_slow; //数码管扫描需要一个慢时钟clk_slow, always @ (posedge clk) //这个always块用来产生慢时钟clk_slow begin if(!rst_n) begin seg <= 8'b11111001; //复位时输出数字1所对应的seg cnt <= 0; clk_slow <= 1; //复位时clk_slow静止不动 end else begin cnt <= cnt + 1; //复位结束后cnt开始计数 clk_slow <= cnt[12]; //扫描没有必要非得是60Hz整,大于60Hz即可 end end //这个always块用于扫描数码管,也就是sel循环发生变化周期约16ms, //时钟每一次上升沿sel变化一次,所以在括号里写上时钟上升沿作为触发条件 always @ (posedge clk_slow or negedge rst_n) begin if(!rst_n) begin sel <= 0; //复位时sel静止 end else begin sel <= sel + 1; //复位后sel开始扫描 if(sel >= 5) sel <= 0; //因为只有6个数码管,所以让sel在0-5之间循环 end endendmodule
写完之后将文件命名为display0.v,按ctrl+s键保存。注意,文件名必须与模块名相同,并将该模块设置为顶层模块(在文件名上单击鼠标右键,选择Set as Top-Level Entity,如图1-8所示)。
设置好后,按Ctrl+K键分析综合,让编译器检查代码的语法错误。没有了错误之后,还要为该代码写测试(testbench)代码。
3、显示模块的测试
下面简单介绍一下测试模块文件testbench。当你编写完一个模块的代码并且成功将其综合成电路后,如何知道你编写的代码是否就综合成了你想要的电路了呢? 硬件语言不像C语言那样按顺序执行代码,逐句调试成功即可得到最终结果,而是由编译器分析之后转变成一些由逻辑组成的电路。编译器很聪明,它通过我们写的代码就能得到相应的电路;但是写代码的我却很傻,傻到不能准确地写出我们想要的结果的代码,导致代码编译之后下载到开发板里,什么反应都没有,或者奇怪的错误一大堆。当然,一些简单的代码可以通过一些输出( LED灯、数码管等)观察到逻辑的错误,但是当逻辑比较复杂、时序快、信号量多的时候,这种测试方法显然就不给力了。而通过调用ModelSim进行仿真,可以看出模块中每个信号的变化过程,这样就可以监测这些信号是否正确变化,达到查错的目的。有时候,因为一个信号的错误, 就会导致结果大不一样,所以如果你不喜欢写testbench测试代码,你就有可能离正确只差那么一点点却无法企及。
夏老师在课堂上曾多次提醒我们编写测试代码的重要性,他说磨刀不误砍柴工, 养成良好的测试习惯非常重要。在编程实践中,我深刻体会到夏老师的话千真万确。按照他的建议多写测试代码进行仿真,使我的代码成功率大大提高,减少了盲目修改的时间,大大加快了工作的进度。通过了RTL仿真和布局布线后仿真的代码块,下载到开发板里出错的概率非常小,而没有经过仿真的代码,下载到开发板几乎总是不能运行,即使能运行也会存在各种奇怪的问题。
由于刚才这段代码的输入只有时钟clk和复位信号rst _n,所以只需要定义这两个信号为reg型的变量,作为数码管显示代码的输入。和刚刚的方法一样,新建一个Verilog文件,并写测试代码testbench如下:
`timescale 1ns/1ns //设置延迟时间单位和时间精度,注意这句结束没有分号module display_tb0; //本测试模块没有输入输出端口,所以只需写模块名display_tb0 //声明输入到被测试模块的所需要的激励信号 reg clk; //被测试模块需要的时钟信号 reg rst_n; // 被测试模块需要的复位信号,负电平有效 //定义例化中的连线 wire [2:0] sel; //把选择信号从被测试模块引出,通过波形观察器观察 wire [7:0] seg; //把字段信号从被测试模块引出,通过波形观察器观察 //对被测试模块进行例化 display0 u1(.clk(clk), .rst_n(rst_n), .sel(sel), .seg(seg)); initial begin clk = 1; rst_n = 0; //给变量信号赋初始值,使复位信号有效#101 rst_n = 1; //经过一段时间(101ns)后将复位信号置为无效#10000000 $stop; //经过10ms之后自动停止仿真 end //生成50MHz的时钟(开发板上时钟为50MHz)always #10 clk = ~clk;endmodule
代码写好之后,按Ctrl+S, Ctrl+K组合键,让编译器检查一下有没有语法错误。通过了之后就可以进行simulation的设置了。在 Quartus Ⅱ主菜单顶层工具栏上,单击Assignments→Settings,弹出设置页,左侧选择EDA Tool Settings 里的Simulation选项,右侧选择 Compile test bench并单击Test Benches(见图1-9)。
在弹出的页面中选择new来新建一个测试,前两行就写test bench的模块名display _tb,然后在下面添加文件,找到刚刚写好的testbench和被测试文件,并添加进去,如图1-10所示.看到文件已经添加到下面的空白框里就可以单击OK按钮了。
4、转到ModelSim仿真工具进行测试
在完成以上操作之后,按OK按钮就回到了Settings页面,然后再按OK按钮, 就进入仿真阶段了。在QuartusⅡ主菜单顶层工具栏上找到Tool项,单击Tools→ Run Simulation Tool→RTL Simulation(见图1-11),然后等待ModelSim主菜单出现。
如果运行之后出现如图1-12所示的错误:
则表示Quartus并不知道ModelSim的安装路径在哪儿,需要用户手动设置EDA工具的目录。选择菜单栏上的Tools→Options,打开设置页面,选择EDAToolsOptions,将ModelSim的安装路径填入ModelSim-Altera里,如图1-13所示,单击OK按钮,再次运行仿真即可。
RTL仿真又称行为级仿真、功能仿真或者前仿真,在大部分设计中执行的第一个仿真就是RTL仿真.这个阶段的仿真可以用来检查代码中的语法错误以及代码行为的正确性,其中不包括延时信息。如果没有实例化一些与器件相关的特殊底层元件的话,这个阶段的仿真也可以做到与器件无关。通常可以用前仿真来验证用户写的代码是否正确,是否能实现用户想要的功能。而第二个选项Gate Level Simulation称为门级仿真或者布局布线后时序仿真,在该仿真中加入了器件的延迟信息,更接近于真实使用情况,所以在前仿真通过之后通常需要运行布局布线后仿真,来验证编写的程序在真实情况下是否还能实现时序要求的功能。现在先做前仿真来验证功能。
待ModelSim仿真完成后,波形就出现了。在波形窗口上单击右键或者利用工具栏上的放大镜按钮(见图1-14)可以调整波形显示的范围,这和示波器差不多。
从波形图(见图1-15)上可以看出sel的数值一直在发生变化,而seg的数值 一直不变,对应到开发板上就意味着每个数码管都会显示同一个数字。但由于sel变化得太快(大约2~3ms变一次),人眼无法分辨,就会看到所有数码管同时显示同一个数字。
看样子没什么问题,那么也就是说功能正常,可以准备下载程序到开发板里了。
5、下载程序到开发板进行调试
下载程序到开发板(也简称“下板”)之前要做的准备:
1)分配引脚。单击Quartus Ⅱ主菜单顶层工具栏Assignments→Pin Planner (见图1-16)进入引脚分配界面。
2)按照原理图提供的引脚分配索引进行分配。双击Location下面的空白处, 逐个输入引脚位置,如图1-17所示。
3)编译。按Ctrl+L组合键或者单击工具栏上三角形Start Compilation实现编译功能。
4)仿真。单击选择Tools→Run Simulation Tool→Gate Level Simulation,系统弹出如图1-18所示的仿真窗口。
默认的Timing model是慢模型,也就是由RTL代码生成的电路在最坏条件下的运行模型,该模型能反映器件中出现的最大延迟。如果该模型通过了测试,那么其他模型在一般情况下应该不会有问题,所以通常需要对这个模型进行仿真。单击Run按钮即可运行慢模型的后仿真。如果波形和刚才的一样,并没有出现红色的警告提示,就表示后仿真顺利通过。
5)打开Programmer,在Hardware Setup里选择USB-Blaster(见图1-19),如果没有自动匹配sof文件就选择添加文件Add File,找到刚刚编译生成的sof文件 display.sof。
准备好之后,就可以单击Start按钮了。每次要下载到开发板时单击Start的瞬间心情都很复杂,因为接下来有可能面临着几种情况:第一种是在开发板上看到了希望的结果,给人一种付出后得到回报的喜悦感,觉得人生充满了正能量;第二种……不说了。遇到了除第一种以外的情况,先不要着急,静下心来再检查一遍流程,尤其是分配引脚这个步骤。不要觉得这项工作很简单,是不需要动脑筋的地方,我不会犯错。我遇到很多同学,他们都因为分配引脚出错,出不了结果。如果成功的话,会看到数码管显示6个1。那么接下来就让6个数码管分别显示不同的数字吧,从左到右依次显示123456。这样就得考虑sel和seg之间的配合问题了,也就是说当sel选到了左边第1个数码管的时候,seg输出就要对应数字1所代表的编码; sel选到第2个数码管, seg就输出2对应的编码……以此类推,一直到第6个数码管。所以通过判断sel来输出seg,这里用case语句最合适不过了。把这段case条件语句加入刚刚的代码里,就变成以下代码:
module display1 (clk, rst_n , sel, seg); //为体现模块进行过修改,模块名字不要完全相同,用后缀加以区别//两个输入,一个时钟clk,一个复位rst_n(信号名后缀_n表示该信号低电平有效) input clk; input rst_n;//两个输出,位选sel和段选seg output reg [2:0] sel; output reg [7:0] seg; //数码管扫描需要一个慢时钟 clk_slow,而产生慢时钟则需要一个计数器 cnt reg [16:0] cnt; reg clk_slow;//这个always块用来产生慢时钟clk_slow always @ (posedge clk) begin if(!rst_n) begin cnt <= 0; clk_slow <= 1; //复位时clk_slow静止不动 end else begin cnt <= cnt + 1; //复位结束后cnt开始计数 clk_slow <= cnt[12]; //扫描没有必要非得是60Hz整,大于60Hz即可 end end //这个always块用于扫描数码管,也就是sel循环地变化, //时钟每一次上升沿sel变化一次,所以在括号里写上时钟上升沿作为触发条件 always @ (posedge clk_slow or negedge rst_n) begin if(!rst_n) begin sel <= 0; //复位时sel静止 end else begin sel <= sel + 1; //复位后sel开始扫描 if(sel >= 5) sel <= 0; //因为只有6个数码管,所以让sel在0-5之间循环 end end //下面这段代码是新添加的,由于seg是随着sel变化而跟时钟无关, //所以括号不需要写时钟沿 always @ (*) begin if(!rst_n) seg <= 8'b11111111; //按下复位键时让数码管熄灭,共阳极数码管0亮1灭 else begin case(sel) 0: seg <= 8'b11111001; //右起第1个数码管上显示1 1: seg <= 8'b10100100; //右起第2个数码管上显示1 2: seg <= 8'b10110000; 3: seg <= 8'b10011001; 4: seg <= 8'b10010010; 5: seg <= 8'b10000010; //右起第6个数码管上显示6 default: seg <= 8'b11111111; endcase end endendmodule
把以上修改后的显示模块代码另存为文件display1,文件名必须与模块名相同;经分析综合,将该模块设置为顶层。然后看一下仿真波形,可以继续用刚才的testbench文件,但由于模块的名字进行过修改,所以在实例化时的名字也要对应进行修改,测试文件的代码改后如下:
`timescale 1ns/1ns module display_tb1; //为体现模块进行过修改,名字不要相同 reg clk; reg rst_n; wire [2:0] sel; wire [7:0] seg; //对被测试模块进行例化,此处要修改实例化名为display1 display1 u1(.clk(clk), .rst_n(rst_n), .sel(sel), .seg(seg)); initial begin clk = 1; rst_n = 0; #101 rst_n = 1; #10000000 $stop; endalways #10 clk = ~clk;endmodule
由于测试的模块名进行过修改,同样要另存为同名文件,并且要在testbench设置下,重新添加新的仿真文件,如图1-20所示。
添加好后就有两个仿真文件了,注意选择刚刚添加的仿真文件,否则会运行之前的仿真文件,如图1-21所示。
设置完毕后单击RTL Simulation按钮就可以了。从波形上可以看出sel不同时, seg会对应发生变化;同时可以看一下sel为0,也就是选通最左端数码管的时候, seg是否输出1所对应的码值。波形无误时可以再一次将程序下载到开发板里观察结果。
4今天工作总结
成功在数码管上显示123456之后,今天数码管的调试就可以先告一段落了。今天所学的内容总结如下:
1)理解了LED数码管显示数字和符号的工作原理。
2)学会了利用QuartusⅡ开发工具新建工程,编写可综合模块和测试模块的步骤和方法。
3)掌握了利用QuartusⅡ开发工具将模块代码综合成逻辑网表,定义引脚的步骤和方法。
4)掌握了用布局布线工具生成可下载到开发板的FPGA构造码流的步骤和方法。
5)掌握了用QuartusⅡ开发工具启动ModelSim仿真工具的步骤。
6)掌握了用 ModelSim仿真工具对设计模块进行RTL级别和网表级别仿真的步骤。在学习以上操作的过程中, 我掌握了最基本的设计流程,对Verilog基本语法更加熟悉了。
对QuartusⅡ和ModelSim工具不再感到畏惧和陌生。另外我还知道了每次改进后,都需要重新命名修改过的模块和文件,配套测试模块名和文件名也要做相应的改动,并存入对应的独立目录,用以表示不同的版本。千万不要怕麻烦,省略这一步骤,很容易造成模块配套混乱,浪费大量调试时间。另外,这样编写代码,可以明确地记录设计的进化过程,便于错误的追溯和修改。
明天将开始编写输入模块,也就是机械键盘模块。由于检查键盘输入是否正确的LED显示模块已经写好,这样调试输入模块就会方便许多,因为可以直接观察到输入的结果。
5夏老师评述
在第一天显示模块的设计过程中,赵然同学深入理解了老师讲解的设计原理,对老师在课堂上提醒需要注意的操作细节,严格照办,认真执行,较迅速地完成了课堂设计任务。但他只用Verilog可综合的RTL模块和测试模块对电路模块的功能进行了全面的测试,在验证RTL代码功能基本正确后,就将直接综合产生的布局布线后网表加载到FPGA中进行电路行为的全面测试。这样做,对于FPGA设计当然是可以的。
但是作为老师,我建议初学者最好再做一次布局布线后仿真,在证明布线后电路功能仍旧正确后,再下载到开发板,进行实际电路的测试.这样做,从表面上看,似乎浪费不少时间,但其实因为通过布局布线后仿真,可以发现由于电路延迟引起的冒险竞争,以便迅速诊断出电路不稳定的原因,从而节省大量的查错调试时间,是非常值得的。
为了更好更快地完成布局布线后仿真,我建议把慢时钟的生成编写成一个独立的模块。在后仿真的测试模块中,把输入时钟的基本单位改为毫秒级,先证明电路级别的布线后仿真是完全正确的。再用布线后仿真证明用计数器产生的慢时钟波形也是正确的。然后把这两个模块的实例连接起来,成为一个模块,再综合成一个电路,那么该电路功能出错的概率就会变得非常非常小了。注意这样做的目的,并非针对本设计,而是针对对时钟速度要求较高的一般电路。由于本设计对时钟速度要求极低,只要RTL仿真功能正确,布局布线引起的延迟几乎不可能对电路的功能产生任何破坏,所以不做布局布线后仿真,直接下载到开 发板,也能顺利地通过实际电路的功能测试,这是很自然的现象。
标签: #bcd转换为二进制数计算器 #bcd码计数器verilog #verilog bcd计数器 #fpga数码管小数点