野火征途Pro开发板FPGA数字时钟(秒表)设计学习心得(1)
hc595_ctl
shizhong
第一次写csdn,自学FPGA有一段时间了,七月中旬买的开发板,到现在一个多月终于稍微学懂点FPGA了。
这个分享的是野火FPGA开发指南数码管动态显示拓展训练的试题。
一开始一头雾水,野火教程只讲到动态扫描,自己在网上找秒表的教程,很少,并且野火的板子是使用74hc595驱动数码管,这点跟其他平台的板子不太一样。参考了明德扬一个教程里面的设计方法。
实验目标是生成一个时分秒时钟,设计思路是分别对时分秒的个位,十位进行设计,正好对应6段数码管。计时设计完成之后,直接用顶层模块调用shizhong模块和74hc595驱动模块,74hc595驱动原理野火有详细教程,话不多说直接上代码。
时钟设计
module shizhong
(
input sys_clk,//50MHz
input sys_rst_n,//复位信号
output wire[7:0] seg,//数码管段选信号,
output wire[5:0] sel//位选信号
);
parameter CNT_MAX = 50_000;//动态扫描计时最大值
parameter CNT_MAX_1S = 50_000_000;//1s计数器计时最大值
reg[15:0] cnt_1ms;//动态扫描
reg[2:0] cnt_6;//对动态扫描计时6次,方便位选
reg[5:0] sel_reg;//位选信号中间变量
reg[25:0] cnt_1s;//1s计数器
reg[3:0] m_g;//秒个位
reg[2:0] m_s;
reg[3:0] f_g;
reg[3:0] f_s;
reg[3:0] s_g;
reg[3:0] s_s;
reg[7:0] seg_reg;//段选信号中间变量
reg[3:0] x;//对时个位变量法计数最大值,因为时个位的跳转可能为9(9,19),也可能为3(23)
reg[3:0] data;//很重要,将时分秒各数据赋值到数码管的中间变量//设置动态扫描时间为1ms的计时器cnt_1ms
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)cnt_1ms <= 0;else if(cnt_1ms==CNT_MAX-1)cnt_1ms <= 0;else cnt_1ms <= cnt_1ms + 1;always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)cnt_6 <= 0;else if((cnt_1ms==CNT_MAX-1)&&(cnt_6 > 3'd4)) cnt_6 <= 0;else if(cnt_1ms==CNT_MAX-1)cnt_6 <= cnt_6 + 1; elsecnt_6 <= cnt_6;
//位选信号sel_reg 赋值
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)sel_reg <= 6'b000_001;/* else if(cnt_6==0) sel_reg <= 6'b000_001;else if(cnt_6==1) sel_reg <= 6'b000_010;else if(cnt_6==2) sel_reg <= 6'b000_100;else if(cnt_6==3) sel_reg <= 6'b001_000;else if(cnt_6==4) sel_reg <= 6'b010_000;else sel_reg <= 6'b100_000; */else case(cnt_6) 3'd0:sel_reg <= 6'b000_001;3'd1:sel_reg <= 6'b000_010;3'd2:sel_reg <= 6'b000_100;3'd3:sel_reg <= 6'b001_000;3'd4:sel_reg <= 6'b010_000;3'd5:sel_reg <= 6'b100_000;default:sel_reg <= 6'b000_001;endcase
//秒设计
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)cnt_1s <= 0;else if(cnt_1s==CNT_MAX_1S-1)cnt_1s <= 0;elsecnt_1s <= cnt_1s + 1;
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)m_g <= 0;else if((cnt_1s==CNT_MAX_1S-1)&&(m_g==4'd9))m_g <= 0;else if(cnt_1s==CNT_MAX_1S-1) m_g <= m_g +1;else m_g <= m_g;
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)m_s <= 0;else if((cnt_1s==CNT_MAX_1S-1)&&(m_s==4'd5)&&(m_g==4'd9))m_s <= 0; else if((cnt_1s==CNT_MAX_1S-1)&&(m_g==4'd9)) m_s <= m_s +1;else m_s <= m_s;
//分设计
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)f_g <= 0;else if((cnt_1s==CNT_MAX_1S-1)&&(f_g==4'd9)&&(m_s==4'd5)&&(m_g==4'd9))f_g <= 0; else if((cnt_1s==CNT_MAX_1S-1)&&(m_s==4'd5)&&(m_g==4'd9)) f_g <= f_g +1;else f_g <= f_g;
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)f_s <= 0;else if((cnt_1s==CNT_MAX_1S-1)&&(f_s==4'd5)&&(f_g==4'd9)&&(m_s==4'd5)&&(m_g==4'd9))f_s <= 0; else if((cnt_1s==CNT_MAX_1S-1)&&(f_g==4'd9)&&(m_s==4'd5)&&(m_g==4'd9)) f_s <= f_s +1;else f_s <= f_s;
//时设计
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)s_g <= 0;else if((cnt_1s==CNT_MAX_1S-1)&&(s_g==x-1)&&(f_s==4'd9)&&(f_g==4'd9)&&(m_s==4'd5)&&(m_g==4'd9))s_g <= 0; else if((cnt_1s==CNT_MAX_1S-1)&&(f_s==4'd9)&&(f_g==4'd9)&&(m_s==4'd5)&&(m_g==4'd9)) s_g <= s_g +1;else s_g <= s_g;
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)s_s <= 0;else if((cnt_1s==CNT_MAX_1S-1)&&(s_s==4'd2)&&(s_g==x-1)&&(f_g==4'd9)&&(m_s==4'd5)&&(m_g==4'd9))s_s <= 0; else if((cnt_1s==CNT_MAX_1S-1)&&(s_g==x-1)&&(f_g==4'd9)&&(m_s==4'd5)&&(m_g==4'd9))s_s <= s_s +1;else s_s <= s_s;
always@(*) beginif(s_s==4'd2)x = 4'd4;else x = 4'd10;end //段选seg_reg
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==0)seg_reg <= 8'hc0;else case(data)4'd0:seg_reg <= 8'hc0;4'd1:seg_reg <= 8'hf9;4'd2:seg_reg <= 8'ha4;4'd3:seg_reg <= 8'hb0;4'd4:seg_reg <= 8'h99;4'd5:seg_reg <= 8'h92;4'd6:seg_reg <= 8'h82;4'd7:seg_reg <= 8'hf8;4'd8:seg_reg <= 8'h80;4'd9:seg_reg <= 8'h90;default:seg_reg <= 8'hc0;endcase
always@(*) begincase(cnt_6)0:data = m_g;1:data = m_s;2:data = f_g;3:data = f_s;4:data = s_g;5:data = s_s;default:data = m_g;endcase
endassign sel = sel_reg;assign seg = seg_reg;endmodule
74HC595模块
module hc595_ctl
(input wire clk , //系统时钟,频率50MHzinput wire rst_n , //复位信号,低有效input wire [5:0] smg_sel , //数码管位选信号input wire [7:0] smg_dig , //数码管段选信号output reg stcp , //数据存储器时钟output reg shcp , //移位寄存器时钟output reg ds , //串行数据输入output wire oe //使能信号,低有效
);reg [1:0] cnt_4 ; //分频计数器
reg [3:0] cnt_bit ; //传输位数计数器//wire define
wire [13:0] data ; //数码管信号寄存//将数码管信号寄存
assign data = {smg_dig[0],smg_dig[1],smg_dig[2],smg_dig[3],smg_dig[4],smg_dig[5],smg_dig[6],smg_dig[7],smg_sel};//将复位取反后赋值给其即可
assign oe = ~rst_n;//分频计数器:0~3循环计数
always@(posedge clk or negedge rst_n)if(rst_n == 1'b0)cnt_4 <= 2'd0;else if(cnt_4 == 2'd3)cnt_4 <= 2'd0;elsecnt_4 <= cnt_4 + 1'b1;//cnt_bit:每输入一位数据加一
always@(posedge clk or negedge rst_n)if(rst_n == 1'b0)cnt_bit <= 4'd0;else if(cnt_4 == 2'd3 && cnt_bit == 4'd13)cnt_bit <= 4'd0;else if(cnt_4 == 2'd3)cnt_bit <= cnt_bit + 1'b1;elsecnt_bit <= cnt_bit;//stcp:14个信号传输完成之后产生一个上升沿
always@(posedge clk or negedge rst_n)if(rst_n == 1'b0)stcp <= 1'b0;else if(cnt_bit == 4'd13 && cnt_4 == 2'd3)stcp <= 1'b1;elsestcp <= 1'b0;//shcp:产生四分频移位时钟
always@(posedge clk or negedge rst_n)if(rst_n == 1'b0)shcp <= 1'b0;else if(cnt_4 >= 4'd2)shcp <= 1'b1;elseshcp <= 1'b0;//ds:将寄存器里存储的数码管信号输入即
always@(posedge clk or negedge rst_n)if(rst_n == 1'b0)ds <= 1'b0;else if(cnt_4 == 2'd0)ds <= data[cnt_bit];elseds <= ds;endmodule
总结:从三月份开始学数电,四五月份开始断断续续学Verilog,现在自己能上手操作一些东西了,对于我这个零基础转行的人来说有莫大的欣慰。时钟设计对我来说真的是不小的挑战,通过这一周的找资料设计,对调用模块,写仿真代码,跑波形,管教绑定学习有非常大的帮助。总之FPGA的学习是一个操作性很强的过程,在不断的试错找bug,调试,再试错的过程中学习是最快的。多上手,遇到问题就解决,相信一定能入行。
野火征途Pro开发板FPGA数字时钟(秒表)设计学习心得(1)相关推荐
- 基于FPGA数字时钟的设计(附源码)
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注"FPGA技术江湖"微信公众号,在"闯荡江湖"."行侠仗义"栏里获取其 ...
- 基于DE1 SOC FPGA开发板的数字时钟的制作
数字电子钟的原理石英晶体振荡器和分频器组成标准秒发生电路.石英晶体振荡器的振荡频率为50MHz,经分频后,输出脉冲的频率为1Hz,即周期为1s,即标准秒脉冲.得到新的脉冲周期为1s,再将新的脉冲作为时 ...
- 野火iMX6ULL Pro开发板移植SDL2
承诺的Linux三部曲移植还没写完,差个根文件系统没有写呢,但实在压抑不住内心的亢奋情绪,先把SDL2移植奉献给大家吧.关于SDL的移植,已经进行一个月了,之前把SDL移植成功后打算写Python的模 ...
- FPGA数字时钟系统-设计教程
博主福利:100G+电子设计学习资源包! http://mp.weixin.qq.com/mp/homepage?__biz=MzU3OTczMzk5Mg==&hid=7&sn=ad5 ...
- PC仿真的emwin移植到STM32F103RCT6详尽步骤(正点原子库,正点原子mini开发板,亲测可用,学习心得,大佬勿喷)
所需要的硬件设备:正点原子mini开发板 (STM32F103RCT6,需要正点自带的240*320TFTLCD屏) 所需要的软件: 1.MDK5 2.Code::Blocks(PC上的IDE) 3. ...
- 野火i.MX6ULL Pro开发板构建根文件系统
眼瞅着2020年马上就要到头了,承诺给大家的Linux移植三部曲还差最后一篇,这个拖延癌晚期恐怕今年是治不好了,不到最后的DL绝不妥协-- (这句话是年前写的,写了个开头就疫情了,封城,电脑丢在了公司 ...
- 基于野火F407骄阳开发板的苹果采摘机器人机械臂的采摘轨迹与夹持器的采摘动作的设计(1)
基于野火F407骄阳开发板的苹果采摘机器人机械臂的采摘轨迹与夹持器的采摘动作的设计(1) 苹果采摘机器人 1.采摘流程与硬件设计 2.机械臂驱动以及采摘轨迹设计 2.1.台达A2电机驱动实现 2.2. ...
- 使用轮询方式进行ADC转换(野火STM32 MINI开发板)
实验器材:野火STM32 MINI开发板 任务目标:利用ADC采集电位器的电压,并通过串口调试助手输出变化的电压值 任务内容:调整开发板上的滑动变阻器,将电压值通过开发板到PC进行显示 开发板原理图: ...
- 【D1 Dock Pro开发板】Lichee D1 Dock 开发板用户指南
作者:深圳矽速科技有限公司 1. 概述 D1 Dock Pro 开发板是由深圳矽速科技有限公司研发,搭载了全志D1多媒体处理器,基于阿里平头哥RISC-V 64位C906核心,支持RVV,1GHz主频 ...
- 在Rockchip RK3399 Pro开发板上跑通第一个Qt程序
在Rockchip RK3399 Pro开发板上跑通第一个Qt程序 准备工作:将Qt从Windows移植到Linux 一.交叉编译器的准备 下载交叉编译工具 安装交叉编译工具 二.交叉编译Qt库 三. ...
最新文章
- Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo
- 别说,Cerebro还真好用!老板再也不用担心ES集群了
- mysql batch insert 遇到错误跳过_mysql 主从复制错误如何跳过
- Hash查找的基本原理及实现
- 一个mybatis处理batch的插件,类似于pageHelper插件
- 《最强蜗牛》运营分析:这个奇葩放置游戏的乐趣在哪里?
- java 0x3f_Java源码位操作技巧欣赏
- 计算机二级考试需要怎么备考,计算机二级ms office应该怎么备考 考试内容是什么...
- 华为交换机s2700怎么重置_华为交换机忘记console的密码,怎么恢复出厂设置
- python3.4安装vc_Python3.4 用 pip 安装lxml时出现 “Unable to find vcvarsall.bat ”?
- ubuntu16.04下安装windows软件,以及卸载.
- 一本关于网上支付解决方案的迷你百科全书
- 监狱智能化管理系统综合安防解决方案
- 《神奇的数学》读后感_奇妙的数学王国读后感10篇完美版
- Codeforces - Array Queries
- 测判三极管的口诀 (挑战者)
- 编译Android环境的libjpeg-turbo
- x86架构鼻祖-i8086
- 小猫踢足球-第14届蓝桥杯STEMA测评Scratch真题精选
- river歌曲表达的意思_英文歌曲_river是什么意思_沪江英语
热门文章
- rstudio导入txt文件_R语言 | 读写txt、csv、excel文件
- 《实变函数简明教程》,P63,可测集上的连续函数一定可测
- git deamon 一个简单的git服务器
- win10 python安装以及编辑器pycharm安装
- ad 原理图放置差分对_Altium Designer差分对设置方法
- 制作一个简单的大数据看板(FineReport-帆软)
- 数字孪生|数字孪生装备-概念与内涵
- matlab求解全微分函数,Matlab求解一元函数,再求全微分的错误,表达式复杂不会........
- 修复Windows 7升级Windows 10后Japanese输入法无法使用的Bug
- 光谱分析中的变量选择