FPGA实验二:模可变计数器设计

news2024/9/27 21:28:36

目录

一、实验目的

二、实验要求

三、实验代码

1.实验源码

2.部分代码设计思路分析

四、实验结果及分析

1、引脚锁定

2、仿真波形及分析

3、下载测试结果及分析

五、实验心得

1.解决实验中遇到的困难及解决

2.完成实验后的心得


一、实验目的

(1)掌握组合逻辑电路和时序电路的 FPGA实现方法;

(2)熟悉EDA开发板和开发软件的使用方法;

(3)学习静态数码管的使用和7段数码显示译码器设计;

(4)掌握时钟在时序电路中的作用;

(5)掌握分频电路的实现方法。

二、实验要求

设计BCD计数器,可任选模的大小(最大模值至少3位),实验要求:

(1)计数结果用3位数码管显示,显示BCD码;

(2)给出此项设计的仿真波形;

(3)选择实验电路验证此计数器的功能。

(4)设计模值可变的输入端口,通过输入模值和设置信号改变计数器模值

(5)设置涉及1个开关和一个按键,开关作为使能控制,按键作为异步清0。

(6)带有进位输出,并进位输出用LED灯显示

三、实验代码

1.实验源码

(1)design source文件(限于篇幅,仅展示部分代码,核心代码均标注有)

  1. `timescale 1ns / 1ns
    module final_counter(
        input CLK,          
        input SW1,          
        input KEY1,       
        input [6:0] M_SET,  
        input M_EN,
        output reg [10:0] display_segout,
        output reg LED_OUT          //输出,用于显示进位状态
    );
    
    reg  [6:0] M;       // 计数器模数
    wire [3:0] bw;
    wire [3:0] sw;
    wire [3:0] gw;
    wire [3:0] qw;
    reg [7:0] cnt_count;
    
    //设置模值
    always@(posedge M_EN)
        begin
           M[0]<=M_SET[0];
           M[1]<=M_SET[1];
           M[2]<=M_SET[2];
           M[3]<=M_SET[3];
           M[4]<=M_SET[4];
           M[5]<=M_SET[5];
           M[6]<=M_SET[6];
         end
            
    
    //数码管各位逻辑关系
    assign qw =M/10;
    assign bw =M%10;
    assign sw =cnt_count%100/10;
    assign gw =cnt_count%10;
    
    reg [19:0]count=0; 
    reg [30:0]count2=0; 
    reg [2:0] sel=0; 
    parameter T1MS=50000;
    reg [6:0]t;
    
    //多位数码管显示
    always@(posedge CLK) 
         begin 
            count<=count+1; 
            if(count==T1MS) 
            begin 
                count<=0; 
                sel<=sel+1; 
                if(sel==4) 
                sel<=0; 
             end 
         end
    //板子计数频率
    reg clk1;
    always @(posedge CLK)
     begin 
      if(count2 == 9_999_999) // 9_999_999==100ms
        begin 
            clk1<=1'b1; 
            count2<=0;
        end 
      else
                begin 
                    clk1<=1'b0;
                    count2<=count2+1'b1;
                end
     end
    //板子数码管显示
    always@(posedge CLK) 
     begin 
        case(sel) 
            0:display_segout<={4'b0111,BCD_OUT0};
            1:display_segout<={4'b1011,BCD_OUT1};
            2:display_segout<={4'b1101,BCD_OUT2};
            3:display_segout<={4'b1110,BCD_OUT3};
            default:display_segout<=11'b1111_1111111; 
        endcase 
     end
     //计数器逻辑
    always @(negedge clk1 or posedge KEY1 )
    begin
        if(KEY1 == 1'b1)   // 异步清零
            begin
                cnt_count <= 0;
            end
        else if(t!=M)
            begin
                cnt_count <= 0;
                t=M;
            end
        else if(SW1 == 1'b1)   // 使能控制
            begin
                if(cnt_count<M-1)
                    begin
                        cnt_count<=cnt_count+1;
                        LED_OUT<=1'b0;
                        if(cnt_count == M-2)
                            LED_OUT <=1'b1;
                    end
                else
                    begin 
                        cnt_count<=0;
                        LED_OUT<=1'b0;
                     end
            end
    end
    
    end module

(2)仿真测试文件

  1. `timescale 1ns/1ps
    module sim_CNT();
    reg SW1,KEY1;
    reg [6:0]M_SET;
    reg  M_EN;
    wire [10:0] display_segout;   
    wire LED_OUT;
    
    reg clk1;
    
    initial
        begin
        clk1= 1'b0;
        SW1 = 1'b0;
        M_EN=1'b0;
        #2 KEY1 = 1'b1;
           M_EN<=1'b1;
           M_SET<=7'b000_1010;
           M_EN=1'b0;
        #2 M_EN=1'b0;
        
        #2 KEY1 = 1'b1;    //清零
        #2 KEY1 = 1'b0; SW1 = 1'b1;   //复位,准备开始
           #192 
             M_EN<=1'b1;
             M_SET<=7'b001_1111;
           #2 M_EN=1'b0;
           #20
           #2 KEY1 = 1'b1;    //清零
        #2 KEY1 = 1'b0; SW1 = 1'b1;   //复位,准备开始
        end
    always
        begin
        #5 clk1 = ~clk1;
        end
    final_counter uu1(clk1,SW1,KEY1,M_SET,M_EN,display_segout,LED_OUT);
    
    endmodule   

2.部分代码设计思路分析

(1)进行分频操作,输出为 clk1,每两次完整的 clk 跳变等价于一次完整的 

clk1 跳变,每次 clk1 上升沿到来时(使能端信号有效且异步清零信号无效时), 

计数器的值加一。

 2计数器进行设计。计数器的跳变以 clk1 时钟信号为准,当使能端有效、 

清零信号无效时,在每次 clk1 上升沿跳变之际,若计数器的值小于设定的模值 

model,那么其值就继续加 1,若计数器的值等于设定的模值,那么计数器的值回到 0 开始重新计数。其中当计数器处于该模值下最大数时,out 信号会在一个 

时钟信号内变为 1,代表本次模值计数即将结束。

四、实验结果及分析

1、引脚锁定

set_property PACKAGE_PIN U16 [get_ports {cnt_count[0]}]

set_property PACKAGE_PIN E19 [get_ports {cnt_count[1]}]

set_property PACKAGE_PIN U19 [get_ports {cnt_count[2]}]

set_property PACKAGE_PIN V19 [get_ports {cnt_count[3]}]

set_property PACKAGE_PIN W18 [get_ports {cnt_count[4]}]

set_property PACKAGE_PIN U15 [get_ports {cnt_count[5]}]

set_property PACKAGE_PIN U14 [get_ports {cnt_count[6]}]

set_property PACKAGE_PIN V14 [get_ports {cnt_count[7]}]

set_property PACKAGE_PIN U7 [get_ports {display_segout[0]}]

set_property PACKAGE_PIN V5 [get_ports {display_segout[1]}]

set_property PACKAGE_PIN U5 [get_ports {display_segout[2]}]

set_property PACKAGE_PIN V8 [get_ports {display_segout[3]}]

set_property PACKAGE_PIN U8 [get_ports {display_segout[4]}]

set_property PACKAGE_PIN W6 [get_ports {display_segout[5]}]

set_property PACKAGE_PIN W7 [get_ports {display_segout[6]}]

set_property PACKAGE_PIN W4 [get_ports {display_segout[7]}]

set_property PACKAGE_PIN V4 [get_ports {display_segout[8]}]

set_property PACKAGE_PIN U4 [get_ports {display_segout[9]}]

set_property PACKAGE_PIN U2 [get_ports {display_segout[10]}]

set_property PACKAGE_PIN V17 [get_ports {M_SET[0]}]

set_property PACKAGE_PIN V16 [get_ports {M_SET[1]}]

set_property PACKAGE_PIN W16 [get_ports {M_SET[2]}]

set_property PACKAGE_PIN W17 [get_ports {M_SET[3]}]

set_property PACKAGE_PIN V15 [get_ports {M_SET[5]}]

set_property PACKAGE_PIN W14 [get_ports {M_SET[6]}]

set_property PACKAGE_PIN W15 [get_ports {M_SET[4]}]

set_property PACKAGE_PIN W5 [get_ports CLK]

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets M_EN_IBUF] 

set_property PACKAGE_PIN L1 [get_ports LED_OUT]

set_property PACKAGE_PIN R2 [get_ports SW1]

set_property PACKAGE_PIN T1 [get_ports M_EN]

set_property PACKAGE_PIN U18 [get_ports KEY1]

set_property PACKAGE_PIN T1 [get_ports M_EN]

set_property PACKAGE_PIN U18 [get_ports KEY1]

2、仿真波形及分析

SW1为使能端,M_SET为设置的模值,R_SET为清零信号,LED_OUT为计数器输出,cnt_count为计数序列,clk1为时钟信号,SET为模值变化的开关

以上述波形为例进行分析

(1)对使能端的验证:

前10ns,使能端为低电平,无效,计数器不进行计数。使能端为高电平后:当模值为2时,每隔两个时钟信号LED_OUT产生输出信号。

(2)对复位功能的验证

实验要求R_SET作异步清零,如图中蓝线时刻所示,当R_SET信号为 0 时,计数器 

的值立刻清零。

(3)对模值变换的验证

观察可知此处实现了模值的变换,在SET键有效后,计数器也以新的模值进行了重新计数。

在异步清零后,模值变为9,当第九个时钟信号到达后,LED_OUT产生输出信号,后面计数器模值继续变化,LED_OUT对应产生输出信号。

波形仿真可观察到复位、使能、模值进位输出和设置模值的功能,故实现了任意模值计数器的功能。

3、下载测试结果及分析

数码管前两位表示模值,后两位表示计数

模值可设置为1~15,由右下角的四个按钮开关设置,L1所指的led灯代表输出信号,每结束一次计数,就会亮一次。

下面是模值为12 和15时开发板的运行照片

(1)模值为12、计数为11时的临界情况      (2)模值为15时 

 

分析:

当模值为12,计数值为11时,led灯亮,表示模值为 12的一次计数结束

当模值为15,计数值为14时,led灯亮,表模值为15的一次计数结束。

综上可知下载测试现象与仿真相吻合。

五、实验心得

1.解决实验中遇到的困难及解决

(1)代表计数到模值最大时刻的输出信号 out 跳变不是在数值最大的时候,而是在计数器数值回到 0 的时候才变为 1,即跳变时刻比计数器晚一个时钟信号。 

解决方法:在代码文件的计数器模块程序中更改一个判断条件。原程序的编写是只要计数器的数值等于模值,out 就输出 1,但这个判断条件的结果似乎只会在下一个时钟信号才显示。于是将该部分程序改为,当计数器数值等于模值时,判断一个成立的结果,即刻 out 输出为 1。发现将代码更改后out 能够成功在数值最大处跳变

(2)为何要进行分频?

这个要求是在我刚看到实验要求提出的,当时也是满心疑惑,为什么要进行分频,分频有什么好处?查阅资料后得知,分频就是将原有频率除以分频值得到当前频率,简单的来说就是以整数倍降低频率。分频之后可以使输入的速度降低,否则振荡频率太高,信号持续的周期过短,设备无法正常响应。而且有些外设的设备频率要求不同,如果没有分频电路也就控制不了。进行一定的分频还可以缩短仿真时间,提高实验效率。

2.完成实验后的心得

在完成这个实验的过程中,我遇到了一些问题和挑战,但通过不断的尝试和调试,最终成功地完成了整个实验。

我认为充分理解计数器工作原理对于完成此次实验是十分重要的一件事在进行计数器实验时,需要充分理解计数器的工作原理,以便可以根据需要进行合适的参数设置和设计。最初的时候没有搞懂老师的要求后面才知道要在数码管上实现左边两位表示模值右边两位表示计数过程但经过多次代码的调试后还有完成了实验的验收

总的来说,模可变计数器设计实验是一项非常有意义和有用的设计实践项目,在这个实验中我们可以学习到许多数字电路设计的基础知识,同时也可以提高我们的问题解决和思维能力。同时,也需要我们具备耐心和毅力,通过不断的调试和优化,最终完成一个稳定可靠的计数器设计

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/731039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux系统编程】Linux 软件包管理器——yum

文章目录 1. 什么是yum2. yum的使用2.1 注意事项2.2 查看软件包2.3 如何安装软件2.4 如何卸载软件2.5 yum源 这篇文章我们要学习的是—— Linux 软件包管理器 yum。 1. 什么是yum 首先来问大家一个问题&#xff1a; 我们平时使用的手机上&#xff0c;都会有一个应用叫做“应…

【全栈开发指南】OAuth2授权获取token调试接口的方式

在我们实际应用接口的调用调试过程中&#xff0c;需要用到token或者刷新token&#xff0c;GitEgg支持OAuth2.0协议进行认证授权&#xff0c;这里介绍说明如何通过Postman获取token和refresh_token并进行接口调试。 1、使用密码模式获取token 根据spring-security-oauth2的实现…

创建虚拟机安装windowserver2016服务器(NETBASE第二课)

2 操作流程 文件-新建虚拟机-自定义&#xff08;高级&#xff09;-下一步-稍后安装操作系统-下一步-客户机操作系统-选择Windows 10 X64-下一步-虚拟机名输入win10-1-位置选择&#xff08;E:\虚拟机\Win10-1&#xff09;-下一步-固件类型选择UEFI-下一步-下一步-输入内存2048M-…

2023年Arm最新处理器架构分析——X4、A720和A520

1、引言 上一篇文章我们介绍了Arm的Cortex-X1至Cortex-X3系列处理器&#xff0c;2023年的5月底&#xff0c;Arm如期发布了新一年的处理器架构&#xff0c;分别为超级大核心Cortex-X4&#xff0c;大核心A720和小核心A520。在智能手机行业&#xff0c;Arm始终保持每年一迭代的处…

ModaHub魔搭社区:ChatGLM-RLHF:无需微调 教程

目录 使用方法 效果展示 对ChatGLM直接使用RLHF进行调整参数&#xff0c;无需传统的finetune|Modify ChatGLM params with only RLHF。 大部分的RLHF代码都是在分布式框架&#xff0c;不适合学习和使用&#xff0c;本代码的RLHF代码不需要Megatron或者deepspeed框架&#xff…

Maven高级(三)--聚合

1.解决的问题&#xff1a; 此时tlias-web-management模块的父工程是tlias-parent,该模块又依赖了tlias-pojo,tlias-utils模块。那么此时&#xff0c;我们要将tlias-web-management模块打包&#xff0c;是比较繁琐的。因为进行项目打包&#xff0c;maven会从本地仓库来查找tlias…

Jupyter notebook 安装代码提示和补全

打开Anaconda Prompt 终端 依次输入 pip install jupyter_contrib_nbextensions jupyter contrib nbextension install --user pip install jupyter_nbextensions_configurator jupyter nbextensions_configurator enable --user 打开Jupyter notebook

Linux的用户管理精简全总结

&#xff08;该图由AI绘制 关注我 学习AI画图&#xff09; 目录 Linux操作系统用户和组的概念 1、为什么需要了解用户和组 2、用户和组的关系 3、用户组操作 ☆☆☆☆☆☆☆☆☆☆☆ /etc/group文件解析 ☆ 用户组的修改 ☆ 用户组的删除 4、用户操作 ☆ 用户信息查…

VSCode 提示 1.16.15 版本的Go,不支持 gopls v.0.13.0

Go1.16.15无法使用 goplsv.0.13.0 问题详情解决办法 问题详情 Gopls was built with Go version 1.16, which will be unsupported by gopls v0.13.0. Please upgrade to Go 1.18 or later and reinstall gopls. If you cant upgrade and want this message to go away, pleas…

FPGA实现二进制转BCD码

1、简介 bcd码&#xff1a;以4bit二进制码表示一个十进制码 例如&#xff0c;432&#xff08;d&#xff09; 0100-0011-0010&#xff08;bcd&#xff09; 这里具体的判断方法为&#xff1a;&#xff08;满5&#xff09;加3法 二进制位宽为W&#xff0c;则BCD位宽只需要&…

JS 实现CSV文件转换SQL文件小工具

一. 需求 最近在项目中遇到一个问题&#xff0c;客户提供的数据是CSV格式的&#xff0c; 需要将CSV文件中的数据转换为SQL语句文件。 &#x1f605;由于本人不会Excel的vba编程&#xff0c;因此决定使用JS来实现。 二. 实现思路 提供一个文件上传框&#xff0c;支持多文件上…

微信小程序全局配置详解

通过全局配置实现的效果 开发者 微信公众平台 登录网址 https://mp.weixin.qq.com/ 注册网址 https://mp.weixin.qq.com/cgi-bin/wx?token&langzh_CN 微信小程序开发者工具 下载地址 https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 小…

WPF grid控件定义行和列

在此已经学习了wpf Grid控件&#xff0c; WPF布局控件Grid的基本使用 - 使用kaxaml_bcbobo21cn的博客-CSDN博客 下面继续学习&#xff1b; 定义3行3列的基本代码如下&#xff1b;为了看清效果&#xff0c;设置 ShowGridLines"True"&#xff1b; <Grid ShowGrid…

Tkinter_鼠标选中样式

前言 使用tkinter库创建窗口应用程序示例&#xff0c;包含不同鼠标样式标签。 一、方法 import tkinter as tkclass Mouse_Style:def __init__(self):self.root tk.Tk()self.root.title(样式)self.root.geometry("200x5201100150")self.interface()def interface(…

【G431】多路ADC+DMA采集

文章目录 前言1.CubeMx的配置步骤3.测试代码4.演示效果 总结 前言 之前蓝桥杯程序中使用的是查询方式的ADC&#xff0c;缺点是当采集通道多的时候会导致CPU速率变低从而导致查询ADC代码之后的程序会被阻塞。而DMA就不会&#xff0c;DMA会绕开CPU直接传输。 1.CubeMx的配置步骤…

GDB 查看、修改变量

1、info args : 查看函数的入参内容 2、set print null-stop :遇到无效的字符就不显示出来了 3、set print pretty :让结构体以定义的形式展示出来&#xff0c;一个字段一行 4、 set print arry on :让数组中的元素每个占一行显示 5、 p sizeof(xxx) : 查看xxx的大小&#xff…

STM32 DSP库CUBEMX配置+FFT频率计算

文章目录 前言一、DSP库添加1.1 加一个define1.2 添加文件路径1.3 主函数 二、FFT运算求频率2.1 初始版本版本2 总结 前言 使用DSP中的函数加快计算。 本文首先讲述如何通过添加dsp库。 再讲述使用DSP库进行实数FFT运算。&#xff08;FFT运算用到了前面讲述的STM32CubeMX-ADC …

mysql 安装

常用存储引擎功能对比&#xff1a; mysql 安装流程&#xff1a; 如果直接本地安装&#xff0c;就只需要安装好然后配置环境变量就行了&#xff0c;my.ini文件会自动帮你写好&#xff0c;如果是zip压缩包安装就需要自己写my.ini文件&#xff0c;下面详细介绍zip压缩包安装 下载…

提示工程的前世今生

原文链接&#xff1a;芝士AI吃鱼 通过提示进行情境学习 在生物学中&#xff0c;涌现是一种令人难以置信的特性&#xff0c;由于相互作用的结果&#xff0c;各个部分聚集在一起&#xff0c;表现出新的行为&#xff08;称为涌现&#xff09;&#xff0c;这是你在较小的尺度上看不…

分别基于红黑树、timefd、多级时间轮实现定时器

文章目录 一、定时器的应用二、定时器的触发方式2.1 网络事件和定时事件在一个线程中处理2.2 二、定时器的设计2.1 接口设计2.2 数据结构设计2.2.1 红黑树2.2.3 最小堆2.2.4 时间轮 三、利用红黑树实现定时器3.1 数据结构3.2 接口实现3.2.1 初始化定时器3.2.2 添加定时器3.2.3 …