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.hqwc.cn/news/277503.html

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

相关文章

vue3+echarts 立体柱状效果

vue3echarts 立体柱状效果 废话不多说&#xff0c;直接上代码 就两步&#xff0c;直接复制粘贴一手 <div id"main" class"chart" ref"chartDom"></div>import * as echarts from echarts; type EChartsOption echarts.EChartsOpti…

Vue 组件传参 emit

emit 属性&#xff1a;用于创建自定义事件&#xff0c;接收子组件传递过来的数据。 注意&#xff1a;如果自定义事件的名称&#xff0c;和原生事件的名称一样&#xff0c;那么只会触发自定义事件。 setup 语法糖写法请见&#xff1a;《Vue3 子传父 组件传参 defineEmits》 语…

若依框架springboot——修改前端图片上传样式

简述 使用过若依框架的&#xff0c;一定知道若依前端框架上传图片的样式&#xff0c;是一个正方形加号图片&#xff0c;但是如果你要使用自定义样式呢。 比如将下面这个图进行修改呢 修改后的样式 你可以直接找到element-ui 修改上传图片的组件&#xff0c;也可以加入新的组…

【Go】vs code安装 install/update tools 遇到zip: not a valid zip file

在 vs code 安装 go 工具包 gopls 或 impl时遇到报错 Installing golang.org/x/tools/goplslatest FAILED {"code": 1,"killed": false,"signal": null,"cmd": "C:\\Program Files (x86)\\Go\\bin\\go.exe install -v golang.or…

C语言的system函数简介

函数原型 包含在头文件 “stdlib.h” 中 int system(const char * command) 函数功能 执行 dos(windows系统) 或 shell(Linux/Unix系统) 命令&#xff0c;参数字符串command为命令名。另&#xff0c;在windows系统下参数字符串不区分大小写。 说明&#xff1a;在windows系统中&…

Python求小于m的最大10个素数

为了找到小于m的最大10个素数&#xff0c;我们首先需要确定m的值。然后&#xff0c;我们可以使用一个简单的算法来检查每一个小于m的数字是否是素数。 下面是一个Python代码示例&#xff0c;可以找到小于m的最大10个素数&#xff1a; def is_prime(n): if n < 1: …

高德地图+Vue中使用出现的问题

最近在做高德地图的逆向地理编码API出现了问题 按着官方的方式写代码运行时出现了问题&#xff0c;随后问了技术人员。 添加之后成功运行

卫星影像5天一更新的地图网站

如果全球影像每5天一更新&#xff0c;并集多种地图数据源于一体的PB级海量地图数据该怎样去管理呢&#xff1f; 这是当我了解到SOAR网站之后&#xff0c;思考过的一个问题。 全球最大的在线地图网站 在SOAR的官方网站&#xff0c;据称它是世界上最大的在线地图网站。 它是集…

SpringBoot之JSON参数,路径参数的详细解析

1.6 JSON参数 在学习前端技术时&#xff0c;我们有讲到过JSON&#xff0c;而在前后端进行交互时&#xff0c;如果是比较复杂的参数&#xff0c;前后端通过会使用JSON格式的数据进行传输。 &#xff08;JSON是开发中最常用的前后端数据交互方式&#xff09; 我们学习JSON格式参…

12.15_黑马数据结构与算法笔记Java

目录 144 avl树 balance 145 avl树 put 146 avl树 remove 147 红黑树 概述 148 红黑树 put case1-3 149 红黑树 put case4 150 红黑树 remove case0-1 151 红黑树 remove case2 152 红黑树 remove case3 153 红黑树 remove case4 154 红黑树 remove case5 155 红黑树…

技术分享 | app测试中常用的Android模拟器

Emulator Emualor 是 Android Studio 自带的模拟器&#xff0c;是官方提供的工具&#xff0c;Android 开发最常使用的就是这一款。 它功能非常齐全&#xff0c;电话本、通话等功能都可正常使用。用户可以使用键盘输入&#xff0c;鼠标点击模拟器按键输入&#xff0c;甚至还可以…

SuperMap iClient3D for Cesium 实现鼠标移动选中模型并显示模型对应字段

SuperMap iClient3D for cesium 实现鼠标移动选中模型并显示模型对应字段 一、实现思路二、数据制作1. 计算出模型中心点并保存到属性表中2. 计算出模型顶部高程3. 模型数据切缓存4. 发布三维服务. 三、代码编写 作者&#xff1a;xkf 一、实现思路 将模型属性数据存储到前端&a…