• 领导讲话
  • 自我介绍
  • 党会党课
  • 文秘知识
  • 转正申请
  • 问题清单
  • 动员大会
  • 年终总结
  • 工作总结
  • 思想汇报
  • 实践报告
  • 工作汇报
  • 心得体会
  • 研讨交流
  • 述职报告
  • 工作方案
  • 政府报告
  • 调研报告
  • 自查报告
  • 实验报告
  • 计划规划
  • 申报材料
  • 当前位置: 勤学考试网 > 公文文档 > 实验报告 > 正文

    数电自主设计实验报告——Verilog秒表

    时间:2020-11-02 12:42:49 来源:勤学考试网 本文已影响 勤学考试网手机站

    姓名 班级 学号

    实验日期 节次 教师签字 成绩

    基于BASYS2开发板的

    记忆秒表设计

    实验目的

    熟悉基于Verilog HDL语言输入方式的数字电路的设计方法。

    掌握基于FPGA的设计流程。

    熟悉BASYS2开发板的使用方法。

    熟悉Xilinx ISE软件的使用方法。

    培养自己独立自主设计并完成实验的能力。

    总体设计方案或技术路线

    本实验利用BASYS2开发板的已有资源来进行设计实验,并用Xilinx ISE软件来编写和综合Verilog代码。总体设计方案是设计一个带有记忆功能的秒表。具体而言,该秒表通过BASYS2开发板的50M的时钟进行分频计时,最大计时时间为99.99s,用4位数码管动态显示计时时间,除了有基本的运行、暂停及复位清空功能,还有存储当前时间和查看存储时间的功能。

    实验电路图

    BASYS2开发板原理图--数码管

    板上数码管为4位共阳极数码管,每段为低电平点亮,位选接了三极管增大驱动电流,同时为非逻辑,所以位选信号为低电平有效。

    BASYS2开发板原理图--按键

    本实验用到了两个按键BTN0和BTN1,BTN0为复位按键,对应程序的clear信号,BTN1为存储按键,对应程序的btn[1]信号,按一次该按键数据存储一次,下一次按下时这一次存的数据将被替换掉。

    BASYS2开发板原理图--开关

    本实验用到了两个开关SW7和SW1,SW7为运行、暂停开关,对应程序的sw[0]信号,开关打到上方为运行,下方为暂停,SW1为显示切换开关,对应程序的sw[1]信号,在计时暂停的前提下,将开关打到上方显示出存储的时间数据。

    仪器设备名称、型号和技术指标

    硬件:BASYS2开发板

    软件:Xilinx ISE(编程)、Digilent Adept(下载)

    程序流程图

    程序源代码

    /////////////////////////////////////////////////////////程序文件

    `timescale 1ns / 1ps

    //////////////////////////////////////////////////////////////////////////////////

    // Company:

    // Engineer:

    //

    // Create Date: 15:45:01 11/26/2014

    // Design Name:

    // Module Name: miaobiao

    // Project Name:

    // Target Devices:

    // Tool versions:

    // Description:

    //

    // Dependencies:

    //

    // Revision:

    // Revision 0.01 - File Created

    // Additional Comments:

    //

    ///////////////////////////////////////////////////////////秒表的顶层模块

    module miaobiao(

    input wire clk,///////////////////////////////开发板系统时钟50MHz

    input wire[1:0] btn,////////////////////////两个按键:[0]复位和[1]存时间

    input wire[1:0] sw,/////////////////////////两个开关:[0]运行/暂停和[1]显示存储时间

    output wire[7:0] smg,/////////////////////数码管的8个段选信号

    output wire[3:0] smg_an/////////////////数码管的4个位选信号

    );

    wire clear;

    assign clear=btn[0];////////////////////////////////////将复位按键信号传给clear变量

    wire clk_1k;

    clkdiv #(50000) m0(clk,clear,clk_1k);//将50MHz进行5万分频输出1kHz时钟信号

    wire[15:0]number;

    timer m1(sw[0]&clk_1k,clear,number);///////////计时器模块,输出当前时间数据

    wire[15:0]num_save;

    save m2(clk,clear,btn[1],number,num_save);//////按键按下存储当前时间

    wire[15:0]num_display;

    /////////////////////////////////////////////////////////////////////////////根据开关状态选择显示内容

    choose_4num m3(sw,number,num_save,num_display);

    display m4(clk_1k,clear,num_display,smg,smg_an);///////将数字送给数码管显示

    endmodule

    ///////////////////////////////////////////////////////////////////////////////4选1数据选择器模块

    module choose_4num(

    input wire[1:0]sw,

    input wire[15:0]number,

    input wire[15:0]num_save,

    output reg[15:0]num_display

    );

    always@(*)

    case(sw)

    0:num_display<=number;/////////////显示内容为当前时间

    1:num_display<=number;/////////////。。。。。。。。。当前时间

    2:num_display<=num_save;/////////显示内容为存储时间

    3:num_display<=number;/////////////。。。。。。。。。当前时间

    default:num_display<=number;

    endcase

    endmodule

    //////////////////////////////////////////////////////////////////////////////////存储时间模块

    module save(

    input wire clk_save,

    input wire clear,

    input wire button,

    input wire[15:0]number,

    output reg[15:0]num_save

    );

    always@(posedge clk_save)

    begin

    if(1==clear)

    num_save<=0;

    else if(1==button)

    num_save<=number;

    else

    num_save<=num_save;

    end

    endmodule

    //////////////////////////////////////////////////////////////////////////////////////计时器模块

    module timer(

    input wire clk_timer,

    input wire clear,

    output reg[15:0] number

    );

    reg[3:0] reg_1ms;

    always@(posedge clk_timer,posedge clear)

    begin

    if(1==clear)

    begin

    number<=0;

    reg_1ms<=0;

    end

    else

    begin

    reg_1ms<=reg_1ms+1;

    if(reg_1ms>=9)///////////////1ms的计数变量到10清零,同时10ms变量加一

    begin

    reg_1ms<=0;

    number[3:0]<=number[3:0]+1;

    if(number[3:0]>=9)////10ms变量到10清零,100ms加一

    begin

    number[3:0]<=0;

    number[7:4]<=number[7:4]+1;

    if(number[7:4]>=9)////100ms变量到10清零,1s加一

    begin

    number[7:4]<=0;

    number[11:8]<=number[11:8]+1;

    if(number[11:8]>=9)/////1s到10清零,10s加一

    begin

    number[11:8]<=0;

    number[15:12]<=number[15:12]+1;

    if(number[15:12]>=9)////10s变量到10清零

    number[15:12]<=0;///综上,计时到99.99s后清零

    end

    end

    end

    end

    end

    end

    endmodule

    /////////////////////////////////////////////////////////////////////////////////////动态扫描显示数字模块

    module display(

    input wire clk_dis,

    input wire clear,

    input wire[15:0] number,

    output wire[7:0] smg,

    output wire[3:0] smg_an

    );

    reg[1:0] counter;

    reg[3:0] reg_num;

    wire dp;

    always@(posedge clk_dis,posedge clear)

    begin

    if(1==clear)

    begin

    counter<=0;

    end

    else

    counter<=counter+1;

    end

    always@(*)

    begin

    case(counter)

    0:reg_num<=number[3:0];////////将10ms 变量送到数码管第0位显示

    1:reg_num<=number[7:4];////////将100ms 变量送到数码管第1位显示

    2:reg_num<=number[11:8];//////将1s 变量送到数码管第2位显示

    3:reg_num<=number[15:12];////将10s 变量送到数码管第3位显示

    default:reg_num<=0;

    endcase

    end

    assign dp=(2==counter);//////////////////第2位数码管的小数点点亮,其余小数点熄灭

    num2smg m0(counter,reg_num,dp,smg_an,smg);

    endmodule

    //////////////////////////////////////////////////////////////////////////////////////时钟分频模块

    module clkdiv

    #(parameter div=50000)///////默认5万分频

    (input wire clk,

    input wire clear,

    output reg new_clk

    );

    reg[31:0] counter;

    always@(posedge clk,posedge clear)

    begin

    if(1==clear)

    begin

    counter<=0;

    new_clk<=0;

    end

    else if(counter>=div/2-1)

    begin

    counter<=0;

    new_clk<=~new_clk;//二分频

    end

    else

    counter<=counter+1;

    end

    endmodule

    ///////////////////////////////////////////////////////////////////////////数字转换成数码管段、位码模块

    module num2smg(

    // input wire clk_smg,

    input wire[1:0] which,

    input wire[3:0] num,

    input wire dp,//dp=1时,点亮小数点

    output reg[3:0] smg_an,

    output wire[7:0] smg

    );

    always@(*)

    case(which)/////////////////////////////////////////数码管位选子模块

    3:smg_an<=4'b0111;

    2:smg_an<=4'b1011;

    1:smg_an<=4'b1101;

    0:smg_an<=4'b1110;

    default:smg_an<=4'b1111;

    endcase

    reg[7:0] r_smg;

    always@(*)//////////////////////////////////////////////数码管段选子模块

    begin

    case(num)

    0:r_smg<=8'hc0;

    1:r_smg<=8'hf9;

    2:r_smg<=8'ha4;

    3:r_smg<=8'hb0;

    4:r_smg<=8'h99;

    5:r_smg<=8'h92;

    6:r_smg<=8'h82;

    7:r_smg<=8'hf8;

    8:r_smg<=8'h80;

    9:r_smg<=8'h90;

    10:r_smg<=8'h88;

    11:r_smg<=8'h83;

    12:r_smg<=8'hc6;

    13:r_smg<=8'ha1;

    14:r_smg<=8'h86;

    15:r_smg<=8'h8e;

    default:r_smg<=8'hff;

    endcase

    end

    assign smg=r_smg-128*dp;////////////////////////////////////判断是否显示小数点

    endmodule

    ////////////////////////////////////////////////////////////////////////////程序结束END

    //////////////////////////////////引脚约束文件

    ////////////////////////////////////////////////////时钟约束

    NET"clk"TNM_NET=clk;

    TIMESPEC TS_CLK=PERIOD"clk"20ns high 50%;

    NET"clk"LOC="B8";

    //////////////////////////////////////////////////////////数码管

    NET"smg<7>"LOC="N13";

    NET"smg<6>"LOC="M12";

    NET"smg<5>"LOC="L13";

    NET"smg<4>"LOC="P12";

    NET"smg<3>"LOC="N11";

    NET"smg<2>"LOC="N14";

    NET"smg<1>"LOC="H12";

    NET"smg<0>"LOC="L14";

    NET"smg_an<3>"LOC="K14";

    NET"smg_an<2>"LOC="M13";

    NET"smg_an<1>"LOC="J12";

    NET"smg_an<0>"LOC="F12";

    //////////////////////////////////////////////////////按键

    //NET"btn<3>"LOC="A7";

    //NET"btn<2>"LOC="M4";

    NET"btn<1>"LOC="C11";

    NET"btn<0>"LOC="G12";

    ////////////////////////////////////////////////////开关

    NET"sw<1>"LOC="L3";

    NET"sw<0>"LOC="N3";

    实验结果

    最后,成功地编写出程序,调试通过,完成所有功能,整个设计达到预期目标:最大计时时间为99.99s,用4位数码管动态显示计时时间,除了有基本的运行、暂停及复位清空功能,还有存储当前时间和查看存储时间的功能。

    实验中出现的问题及解决对策

    问题一:数码管按照板子上给的位选引脚编号进行引脚约束后,发现4个数码管显示的内容恰好反过来。

    解决对策:用万用表检查电路后,再通过每一位数码管单独静态显示的测试后,证明确实是板子上给的引脚编号有误,在引脚约束文件中对4位数码管的引脚约束进行了修改之后,最后成功地改变了显示顺序,达到了预期的效果。

    问题二:每次综合的时候都出现了很多很多的错误和警告。

    解决对策:首先,通过软件给出的提示进行修改,解决了一部分错误和警告;然后,将错误和警告代码复制粘贴到网上进行搜索,寻找解决方案,又解决了一部分错误和警告;最后,给老师和学长发邮件请教,或者当面请教寻求帮助,解决了所有错误和又一部分警告,剩下几个警告直接无视,下载到开发板后证明对秒表的功能没有任何影响,说明这些警告可以忽视。

    本次实验的收获和体会、对电路实验室的意见或建议

    收获和体会:

    本次实验,我从一开始的完全不懂FPGA到最后学会FPGA并且成功完成整个实验内容,我最大的收获就是一种自信和成就感,这增加了我在以后的学习生活中面对困难时的勇气和决心。在老师教授FPGA之前,我自己尝试去提前自学FPGA,边看文档边学习,通过对例程的编写和思考完成了基础知识的构建,然后自己编程锻炼和提高编程水平。在FPGA的编程控制过程中,我建立了模块化编程的思想,明白了FPGA触发式的运行方式,初步学会了FPGA编程,并且对FPGA产生了浓厚的兴趣。

    但是,从另一方面我也明白了自己掌握的知识只是冰山一角,要想能力更强,还需要付出更多努力。

    意见和建议:

    希望实验室可以根据课程进度安排实验内容。

    希望实验室能举办更多的FPGA的培训。

    希望仿真实验室能在所有电脑上都安装Xilinx ISE软件。

    希望实验室能定期检查领取了BASYS2开发板的同学的学习进度,或者安排定期必须完成的小任务,督促大家认真学习BASYS2开发板。

    参考文献

    [1] 廉玉欣. 电子技术基础实验教程. 北京:机械工业出版社,2013.2.

    [2] 孟涛. 电工电子EDA实践教程. 北京:机械工业出版社,2010.2.

    [3] 王伟. Verilog HDL程序设计与应用. 北京:人民邮电出版社,2005.3.

    [4] 云创工作室. Verilog HDL程序设计与实践. 北京:人民邮电出版社,2009.2.

    • 考试时间
    • 范文大全
    • 作文大全
    • 课程
    • 试题
    • 招聘
    • 文档大全

    推荐访问