FPGA巩固基础:秒表的设计

设计要求:

6位8段数码管,低三位显示毫秒计数,最高位显示分钟,其余两位显示秒计数。

开始案件与暂停按键,复位按键直接全部归零。

扩展部分:每计满一次,led移位一次。

框图设计:

 

思路讲解:

首先按键信号经过消抖再用,然后把产生的标志信号传给控制模块,由于控制逻辑很简单就把这部分控制逻辑放进“数据产生模块中了”;

然后把数码管与led接口模块interface放进去。

按理来讲,应该重新定义个接口模块再把led与nixie放进去,比较规范。

模块讲解:

值得一提就是数据产生模块与数码管接口模块:

数据产生模块:

 其实输出端口是几个级联得计数器。

代码奉上:

`include "para.v"
module data_gen (input		wire				sys_clk         ,input		wire				sys_rst_n       ,input       wire                start_flag      ,input       wire                stop_flag       ,output      reg     [3:0]       po_data_one     ,output      reg     [3:0]       po_data_two     ,output      reg     [3:0]       po_data_thr     ,output      reg     [3:0]       po_data_fou     ,output      reg     [3:0]       po_data_fiv     ,output      reg     [3:0]       po_data_six     ,output      reg                 minute_flag     
);// localparamlocalparam      IDLE    = 3'b001 ,WORKING = 3'b010 ,STOP    = 3'b100 ;// reg signal reg     [15:0]      cnt_1ms     ;reg     [2:0]       state_c     ;reg     [2:0]       state_n     ;// wire signalwire                add_cnt_1ms     ;wire                end_cnt_1ms     ;wire                IDLEtoWORKING   ;wire                WORKINGtoSTOP   ;wire                STOPtoWORKING   ;   
/******************************************************************************************
********************************************main code**************************************
*******************************************************************************************/// // reg signal // reg     [2:0]       state_c     ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) state_c <= IDLE ;else state_c <= state_n ;end// reg     [2:0]       state_n     ;always @(*) beginif(~sys_rst_n)state_n = IDLE ;else case(state_c)IDLE   :    if(IDLEtoWORKING)state_n = WORKING ;else state_n = IDLE ;WORKING:    if(WORKINGtoSTOP)state_n = STOP ;else state_n = WORKING ;STOP   :    if(STOPtoWORKING)state_n = WORKING ;else state_n = STOP ;default:        state_n = IDLE ;endcaseendassign  IDLEtoWORKING   = (state_c == IDLE      ) && (start_flag) ;assign  WORKINGtoSTOP   = (state_c == WORKING   ) && (stop_flag ) ;assign  STOPtoWORKING   = (state_c == STOP      ) && (start_flag) ;// reg     [15:0]      cnt_1ms     ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) cnt_1ms <= 16'd0 ;else if(add_cnt_1ms) beginif(end_cnt_1ms)cnt_1ms <= 16'd0 ;else cnt_1ms <= cnt_1ms + 1'b1 ;endelse if(state_c == IDLE) cnt_1ms <= 16'd0 ; else cnt_1ms <= cnt_1ms ;// 注意这里,是保持还是归零。end// wire                add_cnt_1ms ;assign  add_cnt_1ms = (state_c == WORKING   ) ;// wire                end_cnt_1ms ;assign  end_cnt_1ms = add_cnt_1ms && (cnt_1ms == `MAX_CNT_1MS - 1) ;// output signal description// output		reg     [3:0]       po_data_one    ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) po_data_one <= 4'd0 ;else if(end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1)po_data_one <= 4'd0 ;else if(end_cnt_1ms)po_data_one <= po_data_one + 1'b1 ;elsepo_data_one <= po_data_one ;end// output      reg     [3:0]       po_data_two     ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) po_data_two <= 4'd0 ;else if((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)po_data_two <= 4'd0 ;else if(end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1)po_data_two <= po_data_two + 1'b1 ;elsepo_data_two <= po_data_two ;end// output      reg     [3:0]       po_data_thr     ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) po_data_thr <= 4'd0 ;else if((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1))po_data_thr <= 4'd0 ;else if(((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1))po_data_thr <= po_data_thr + 1'b1 ;elsepo_data_thr <= po_data_thr ;end// output      reg     [3:0]       po_data_fou     , 显示秒的个位 0 ~ 9always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) po_data_fou <= 4'd0 ;else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1))po_data_fou <= 4'd0 ;else if((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1))po_data_fou <= po_data_fou + 1'b1 ;elsepo_data_fou <= po_data_fou ;end// output      reg     [3:0]       po_data_fiv     , 显示秒的十位 0 ~ 5always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) po_data_fiv <= 4'd0 ;else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5))po_data_fiv <= 4'd0 ;else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1))po_data_fiv <= po_data_fiv + 1'b1 ;elsepo_data_fiv <= po_data_fiv ;end// output      reg     [3:0]       po_data_six     ,always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) po_data_six <= 4'd0 ;else if((((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5)) && (po_data_six == `MAX_CNT_NUM - 1))po_data_six <= 4'd0 ;else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5))po_data_six <= po_data_six + 1'b1 ;elsepo_data_six <= po_data_six ;end// reg minute_flagalways @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) minute_flag <= 1'b0 ;else if((((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5)) && (po_data_six == `MAX_CNT_NUM - 1))minute_flag <= 1'b1 ;else minute_flag <= 1'b0 ;endendmodule

状态机设计:

当复位按键按下,现态与次态都需要回到IDLE状态。
在代码层面,给state_n设置一个复位情况。

数码管模块: 

创新点,与以往不同的代码设计,这次用了“函数”,function。

代码奉上:

`include "para.v"
module nixie (input		wire				sys_clk         ,input		wire				sys_rst_n       ,input       wire     [3:0]      pi_data_one     ,input       wire     [3:0]      pi_data_two     ,input       wire     [3:0]      pi_data_thr     ,input       wire     [3:0]      pi_data_fou     ,input       wire     [3:0]      pi_data_fiv     ,input       wire     [3:0]      pi_data_six     ,output		reg     [5:0]       sel             , output		reg     [7:0]       dig              
);// reg reg                     dot             ; // 数码管上的小数点。reg     [31:0]          cnt_time        ; // 移位寄存器的移位时间,计数器。// wirewire                    add_cnt_time    ;      wire                    end_cnt_time    ;      
/******************************************************************************************
********************************************main code**************************************
*******************************************************************************************/   // reg signal description // reg     [31:0]          cnt_time    ; // 移位寄存器的移位时间。always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) cnt_time <= 32'd0 ;else if(add_cnt_time) beginif(end_cnt_time)cnt_time <= 32'd0 ;else cnt_time <= cnt_time + 1'b1 ;endelse cnt_time <= 32'd0 ; // 注意这里,是保持还是归零。end// reg         dot ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) dot <= 1'b1 ;else dot <= 1'b1 ;end// wire signal description assign  add_cnt_time = 1'b1 ;assign  end_cnt_time = add_cnt_time && (cnt_time == `MAX_CNT_TIES - 1) ;// task// task       nixie_dig ;//     input   [3:0]   data_num    ;//     output  [7:0]   po_dig      ;//     case (data_num)//     0      :    po_dig  = {dot, `ZERO  } ;//     1      :    po_dig  = {dot, `ONE   } ;//     2      :    po_dig  = {dot, `TWO   } ;//     3      :    po_dig  = {dot, `THREE } ;//     4      :    po_dig  = {dot, `FOUR  } ;//     5      :    po_dig  = {dot, `FIVE  } ;//     6      :    po_dig  = {dot, `SIX   } ;//     7      :    po_dig  = {dot, `SEVEN } ;//     8      :    po_dig  = {dot, `EIGHT } ;//     9      :    po_dig  = {dot, `NINE  } ;//     default:    po_dig  = 8'd0   ;//     endcase// endtask// function
function [6:0]  dig_num;input   [3:0]   data_in ;case (data_in)0      :    dig_num  = `ZERO  ;1      :    dig_num  = `ONE   ;2      :    dig_num  = `TWO   ;3      :    dig_num  = `THREE ;4      :    dig_num  = `FOUR  ;5      :    dig_num  = `FIVE  ;6      :    dig_num  = `SIX   ;7      :    dig_num  = `SEVEN ;8      :    dig_num  = `EIGHT ;9      :    dig_num  = `NINE  ;default:    dig_num  = 7'd0   ;endcase
endfunction// Output signal description// output		reg     [5:0]       sel             , always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) sel <= 6'b111_110 ;else if(end_cnt_time)sel <= {sel[4:0],sel[5]} ;else sel <= sel ;end// output		reg     [7:0]       dig  always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) dig <= 8'd0 ;else case (sel)6'b111_110: dig <= {dot, dig_num(pi_data_one)} ;6'b111_101: dig <= {dot, dig_num(pi_data_two)} ;6'b111_011: dig <= {dot, dig_num(pi_data_thr)} ;6'b110_111: dig <= {1'b0, dig_num(pi_data_fou)} ;6'b101_111: dig <= {dot, dig_num(pi_data_fiv)} ;6'b011_111: dig <= {1'b0, dig_num(pi_data_six)} ;default   : dig <= {dot, `SIX  }        ;endcaseendendmodule

函数或者任务的使用,是使得代码写起来更方便,设计起来更节省时间。

减少重复劳动。

要灵活使用。多观察,多分析,多获取信息。找到相关性,相似性。

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

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

相关文章

linux 应用开发笔记---【信号:基础】

1.基本概念 信号是发生事件时对进程的通知机制&#xff0c;也可以称为软件中断 信号的目的是用来通信的 1.硬件发生异常&#xff0c;将错误信息通知给内核&#xff0c;然后内核将相关的信号给相关的进程 2.在终端输入特殊字符产生特殊信号 3.进程调用kill()将任意信号发送…

解决nuxt3环境中css样式失效的问题

现象: 底部播放器进度条拖动按钮没有了&#xff01; 然后通过chrome开发工具检查html元素的结构&#xff1a; 发现progressbar这个元素是存在的&#xff0c;但是为什么没有显示呢&#xff0c;然后回到代码中&#xff1a; 发现原来是组件的名字写错了&#xff0c;多写了一个字母…

Leetcode 47 全排列 II

题意理解&#xff1a; 首先理解全排列是什么&#xff1f;全排列&#xff1a;使用集合中所有元素按照不同元素进行排列&#xff0c;将所有的排列结果的集合称为全排列。 这里的全排列难度升级了&#xff0c;问题在于集合中的元素是可以重复的。 问题&#xff1a;相同的元素会导致…

vivado约束方法5

打开向导时可用的报告功能 当定时约束向导打开时&#xff0c;它会阻止Vivado IDE中的大多数操作包括使用Tcl控制台或运行时序分析&#xff0c;以避免数据库差异。向导窗口始终位于其他Vivado IDE窗口的前面。如果你需要访问Vivado IDE菜单或窗口&#xff0c;必须将向导窗口移动…

推荐一个界面设计软件aardio,配合python三分钟制作一个小软件。【批量doc文件转docx文件】

文章目录 前言一、aardio软件代码二、python代码总结 前言 aardio这个软件不多说&#xff0c;好用方便。 一、aardio软件代码 import win.ui; /*DSG{{*/ mainForm win.form(text"批量doc文件转docx文件";right623;bottom171) mainForm.add( button{cls"butto…

DataFunSummit:2023年数据科学在线峰会-核心PPT资料下载

一、峰会简介 数据会说谎&#xff1f;如何正确的挖掘并使用数据&#xff1f;前沿的科学实验如何做&#xff1f;实验又是如何欺骗你的&#xff1f;数据中台如何发挥功效&#xff1f;用户增长有捷径吗&#xff1f;数据科学的最佳实践有哪些&#xff1f; 本次峰会共包含了&#…

人工智能与数据分析:新时代的趋势和机会

目录 写在开头1. 融合AI和数据分析的趋势1.1 趋势变化1.2 数据驱动目标转换 2 对数据分析行业的影响2.1 技能需求2.2 工作流程和角色的变化2.3 创新和业务驱动的数据分析 3.场景变化3.1 场景1&#xff1a;智能决策支持系统3.1.1 智能决策支持系统的架构设计3.1.2 Python代码演示…

RocketMQ —消费重试

消费者出现异常&#xff0c;消费某条消息失败时&#xff0c; Apache RocketMQ 会根据消费重试策略重新投递该消息进行故障恢复。本文介绍消费重试机制的原理、版本兼容性和使用建议。 一、应用场景​ Apache RocketMQ 的消费重试主要解决的是业务处理逻辑失败导致的消费完整性…

DICOM 文件中,VR,VL,SQ,图像二进制的几个注意点

DICOM 文件的结构&#xff0c;在网上有很多的学习资料&#xff0c;这里只介绍些容易混淆的概念&#xff0c;作为回看笔记。 1. 传输语法 每个传输语法&#xff0c;起都是表达的三个概念&#xff1a;大小端、显隐式、压缩算法 DICOM Implicit VR Little Endian: 1.2.840.1000…

解决VSCode打开终端Terminal闪退的问题

一、背景 在新电脑上使用了VSCode&#xff0c;但是一打开Terminal&#xff0c;Terminal马上就消失了&#xff0c;在网上找了很久&#xff0c;都没有找到对应的分析 二、解决思路 首先&#xff0c;是从这个文档中找到了灵感&#xff0c;这个文档里面汇集了大部分的问题&#…

孩子都能学会的FPGA:第三十二课——用FPGA实现一个通用的SPI主机发送模块

&#xff08;原创声明&#xff1a;该文是作者的原创&#xff0c;面向对象是FPGA入门者&#xff0c;后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门&#xff0c;作者不光让大家知其然&#xff0c;还要让大家知其所以然&#xff01;每个工程作者都搭建了全自动化的仿…

二百一十五、Flume——Flume拓扑结构之复制和多路复用的开发案例(亲测,附截图)

一、目的 对于Flume的复制和多路复用拓扑结构&#xff0c;进行一个小的开发测试 二、复制和多路复用拓扑结构 &#xff08;一&#xff09;结构含义 Flume 支持将事件流向一个或者多个目的地。 &#xff08;二&#xff09;结构特征 这种模式可以将相同数据复制到多个channe…

微信生态下的私域流量载体有哪些?

私域流量的本质就是&#xff1a;降低我的获客成本&#xff0c;提高我产品服务的复购率&#xff0c;增加我和用户之间的粘性&#xff0c;挖掘用户的终身价值。 私域流量一般我们特指微信体系的个人号、公众号、社群和小程序&#xff0c;现在朋友圈和视频号也成为了打造微信私域…

HubSpot和AI的完美结合:解锁业务增长密码

随着数字化时代的发展&#xff0c;智能营销已经成为企业走向成功的关键之一。在这个领域的领先者之一&#xff0c;HubSpot积极整合人工智能&#xff08;AI&#xff09;技术&#xff0c;为数字营销、销售和服务带来了新的可能性。今天运营坛将带领大家深入探讨HubSpot和人工智能…

活动预告 | 微盟技术沙龙 - Elasticsearch 在微盟的实践 12/21/2023

微盟技术沙龙 「微盟技术沙龙」是由微盟研发中心发起并联合各方小伙伴为开发者举办的系列技术沙龙&#xff0c;从用户&#xff0c;产品&#xff0c;技术等方面与开发者进行交流。 微盟技术沙龙关注开发者在实际应用中遇到的问题。提供最真实的干货&#xff0c;以技术会友&…

GPU 性能测试软件:GPU-Z,2023 年 9 月 12 日更新

GPU-Z是一款用于Windows操作系统的免费工具&#xff0c;它用于查看和监控计算机的图形处理单元&#xff08;GPU&#xff09;信息。这个工具是专为计算机硬件爱好者、游戏玩家、系统管理员和技术支持人员设计的 GPU-Z 的特点 GPU信息&#xff1a;GPU-Z能够显示关于您计算机中G…

命令执行 [BUUCTF 2018]Online Tool1

打开题目 我们代码审计一下 if (isset($_SERVER[HTTP_X_FORWARDED_FOR])) { $_SERVER[REMOTE_ADDR] $_SERVER[HTTP_X_FORWARDED_FOR]; } 如果存在xxf头且不为空&#xff0c;则将xxf头内容&#xff08;真实的客户端ip&#xff09;赋给ROMOTE_ADDR&#xff08;代理服务器传过…

如何使用蜘蛛池蚂蚁SEO

​蜘蛛池是一种利用搜索引擎爬虫进行推广营销的方式。它的核心是建立一个能够吸引搜索引擎爬虫的网站群&#xff0c;这些网站能够产生大量的优质内容&#xff0c;并形成一个巨大的网站群&#xff0c;从而吸引更多的搜索引擎爬虫。 如何联系蚂蚁seo&#xff1f; baidu搜索&…

【C语言(十二)】

数据在内存中的存储 一、整数在内存中的存储 整数的2进制表示方法有三种&#xff0c;即 原码、反码和补码 有符号的整数&#xff0c;三种表示方法均有符号位和数值位两部分&#xff0c;符号位都是用0表示“正”&#xff0c;用1表示“负”&#xff0c;最高位的⼀位是被当做符号…