2024年寒假练 - 用STEP-MXO2-LPC实现多功能秒表
该项目使用了webIDE,verilog语言,实现了STEP-MXO2-LPC的设计,它的主要功能为:具有启动、停止、递增、清除功能的秒表。
标签
FPGA
参加活动
时序逻辑
shamisen
更新2024-04-01
重庆理工大学
48

1 项目需求

秒表应从0.0秒计数到9.9秒,然后翻转,计数值每0.1秒精确更新一次。

秒表使用四个按钮输入:开始、停止、增量和清除(重置)。开始输入使秒表开始以10Hz时钟速率递增(即每0.1秒计数一次);停止输入使计数器停止递增,但使数码管显示当前计数器值;每次按下按钮时,增量输入都会导致显示值增加一次,无论按住增量按钮多长时间;复位/清除输入强制计数器值为零。


2 需求分析

2.1 输入输出

输入:四个按钮信号(开始、停止、增量、清除)。

输出:数码管显示当前的计数器值。


2.2 时序要求

计数器值每0.1s更新一次。

使用FPGA内置的时钟资源来驱动计数器。


2.3资源消耗

FPGA的资源占用尽可能的小。


3  实现方式

•将整个功能分为三部分实现:计数器、数码管显示、按键逻辑

•使用三个计数器,第一个用于计数0.1s,第二个第三个分别用于计数小数部分和个位

•将左边的数码管与第三个计数器相连,右边的数码管与第二个计数器相连


4 实现效果

4.1初始状态

4.2按下开始按钮

4.3按下暂停按钮

4.4按下增量按钮

4.5按下复位按钮

5 功能框图

注:每个框图右下角名称为执行该功能的主要文件


6 代码实现

6.1 计数器部分(count.v)

第一个计数器的计数上限是0.1s,当计数器计数到0.1s时,翻转,并传出翻转信号,作为第二个计数器的开始条件使用。计数器模板如下,因为该时钟初始状态为0.0,需要按下开始按钮才进行计数,则可以将第一个计数器的开始条件连接到使能信号en上,当en=1时才能开始计数。第二个和第三个计数器只需要修改其开始条件、翻转条件就能实现小数位和个位的计数。

 //The first counter, with a counting limit of 0.1s
always @(posedge clk or negedge rst)
begin
if(!rst)//Reset after pressing rst
begin
cnt0<=0;
end
else if(add_cnt0)
begin
if(end_cnt0)
cnt0<=0;
else
cnt0<=cnt0+1;
end
end
assign add_cnt0=en;//Condition for incrementing cnt0
assign end_cnt0=add_cnt0&&cnt0==1_200_000-1;//Condition for flipping cnt0

计数器count模块

因为在数码管显示模块中需要使用个位、小数的计数,所以会输出cnt1和cnt2。同时,因为增量按钮按下后使当前个位计数+1,可以在cnt2的开始条件加上add信号,当增量按下时add=1,此时cnt2也可以+1

module count(
input clk,
input rst,
output wire [3:0] cnt1_o,
output wire [3:0] cnt2_o,
input en,
input add
);

6.2 数码管显示部分(seg.v)

当计数器计数到某个数字时,显示相应的数字。

 always @(posedge clk or negedge rst)//Displaying on the digital display
begin
if(!rst)
begin
seg_ment_a<=7'h7e;
end
else if(cnt1==0)
seg_ment_a<=7'h7e;
else if(cnt1==1)
seg_ment_a<=7'h30;
else if(cnt1==2)
seg_ment_a<=7'h6d;
else if(cnt1==3)
seg_ment_a<=7'h79;
else if(cnt1==4)
seg_ment_a<=7'h33;
else if(cnt1==5)
seg_ment_a<=7'h5b;
else if(cnt1==6)
seg_ment_a<=7'h5f;
else if(cnt1==7)
seg_ment_a<=7'h70;
else if(cnt1==8)
seg_ment_a<=7'h7f;
else if(cnt1==9)
seg_ment_a<=7'h7b;
end

数码管显示seg模块

将显示数码管所用到的信号都输出,同时因为en,add信号是从clock模块中产生的,而seg模块中例化了count模块,所以还需要输入en,add信号以使count模块工作

module seg(
clk,
rst,
seg_ment_a,
seg_ment_b,
seg_sel,
seg_dp,
en,
add
);

6.3 按键逻辑部分(clock.v)

key1为开始,key2为暂停,当它们被按下时start值保持不变,start与en连接,则可以操控计数器的开始和暂停,并且只有在rst(复位)按下时才能够停止。

key3为递增,通过检测key3按下之前的状态与按下时的状态进行对比,只有当上升沿来临时,也就是从0变1时递增,同时检测start是否为0(暂停状态),此时给add赋值来控制计数器递增。

always @(posedge clk,negedge key1,negedge rst,negedge key2)//Logic for key1 and key2
begin
if(!rst)
start<=0;
else if(!key1)
start<=1;
else if(!key2)
start<=0;
end

always @(posedge clk) //Logic for key3
begin
if(start==0)
begin
if (key3 == 1'b1 && key_last == 1'b0) //Detect rising edges
add <= 1'b1;
else
add <= 1'b0;
key_last <= key3; //Update the value of Key_last
end
else
add<=1'b0;
end

顶层设计clock模块

1个时钟输入,4个按键输入,4个显示输出

module clock(
clk,
rst,
key1,
key2,
key3,
seg_ment_a,
seg_ment_b,
seg_sel,
seg_dp
);

6.4 管脚分配

7 FPGA资源利用


8 设计过程中所遇到的困难

因为我是第一次接触FPGA,在通过GPT生成代码无法实现功能时,我也不知道如何解决。所以做该项目的大部分时间都是在学习verilog,同时是第一次使用软件,所以大部分便利的功能都不知道如何使用。因为我还没学习到仿真,所以每次调试都是直接综合然后FPGA映射到板子上观察功能。在处理按键逻辑时,大部分时候代码没有报错但是没有实现功能,浪费了很多时间。后来发现能直接生成RTL视图查看按键逻辑是否连上了模块,能排除部分代码逻辑错误,节省了不少时间。


9 未来的建议和规划

该项目已经成功实现了多功能秒表的功能,并达到了预期指标。然而还有部分可以提升和完善的地方:

因为时间原因,设计中并没有设计按键消抖模块来防止误读信号。

未来考虑继续学习FPGA,特别是仿真,如果能够掌握仿真的话能少走大部分不必要的弯路。

附件下载
seg.v
数码管显示模块
count.v
计数器模块
clock.v
顶层设计文件
团队介绍
重庆理工大学-熊秋锦
团队成员
shamisen
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号