一、项目需求
通过小脚丫FPGA核心板上的2个数码管和轻触按键制作一个秒表,通过按键来控制秒表的功能,并在数码管上显示数值。使用七段显示器作为输出设备,在小脚丫FPGA核心板上创建一个2位数秒表。 秒表应从 0.0 秒计数到 9.9秒,然后翻转,计数值每0.1秒精确更新一次。秒表使用四个按钮输入:开始、停止、增量和清除(重置)。开始输入使秒表开始以10Hz时钟速率递增(即每0.1秒计数一次); 停止输入使计数器停止递增,但使数码管显示当前计数器值; 每次按下按钮时,增量输入都会导致显示值增加一次,无论按住增量按钮多长时间; 复位/清除输入强制计数器值为零。
二、需求分析
1.该秒表需要能从0.0s计数到9.9s,然后归零。计数单位长度为0.1s,目前的时钟频率为12MHz,需要对时钟进行分频。
2.该秒表的显示方式数码管显示,需要设计一个模块来对数码管的亮灭进行管理。
3.该秒表有四个按键控制,分别控制四个功能,应当分别设计功能模块。
三、实现方式(使用chatGPT进行简单设计)
时钟分频:
通过 divide 模块生成慢时钟 (clk_sw),用以便慢速驱动秒表实现秒级计时。
控制逻辑:
当 start_btn 被按下时,秒表进入运行状态 (running 设置为 1)。
当 stop_btn 被按下时,秒表停止运行 (running 设置为 0)。
当 rst_btn 被按下时,秒表的计数器被重置为 0,同时停止运行。
当秒表停止运行且 incr_btn 被按下时,秒表的个位数 (ones) 递增,并且通过 flag 保证只在按钮首次按下时递增一次。
当 incr_btn 被释放时,flag 被设置为 1 以允许下一次按钮按下时的递增。
计数递增:
若秒表处于运行状态,个位数(ones)每次时钟上升沿递增,当递增至 9 后再次递增则归零,并使得十位数(tens)递增。
当 tens 和 ones 均递增至 9 后,下一个时钟上升沿将使它们归零,重新开始计数。
7段显示:
display 模块接收十位(tens)和个位(ones)的数值,并将其转换为 7 段显示编码,使得数值能够在外部的 7 段LED上显示
四、功能框图
五、部分代码及说明
module stopwatch(
input clk,
input start_btn,
input stop_btn,
input incr_btn,
input rst_btn,
output [8:0] digit_0,
output [8:0] digit_1
);
说明:这是对四个按钮以及七段数码管的定义
display display(
.seg_data_0(tens),
.seg_data_1(ones),
.seg_led_0(digit_0),
.seg_led_1(digit_1)
);
说明:这是对显示模块的调用
module display(seg_data_0,seg_data_1,seg_led_0,seg_led_1);
input [3:0] seg_data_0;
input [3:0] seg_data_1;
output [8:0] seg_led_0;
output [8:0] seg_led_1;
reg [8:0] seg0 [9:0];
reg [8:0] seg1 [9:0];
initial begin
seg0[0] = 9'hBF;
seg0[1] = 9'h86;
seg0[2] = 9'hDB;
seg0[3] = 9'hCF;
seg0[4] = 9'hE6;
seg0[5] = 9'hED;
seg0[6] = 9'hFD;
seg0[7] = 9'h87;
seg0[8] = 9'hFF;
seg0[9] = 9'hEF;
seg1[0] = 9'h3F;
seg1[1] = 9'h06;
seg1[2] = 9'h5B;
seg1[3] = 9'h4F;
seg1[4] = 9'h66;
seg1[5] = 9'h6D;
seg1[6] = 9'h7D;
seg1[7] = 9'h07;
seg1[8] = 9'h7F;
seg1[9] = 9'h6F;
end
assign seg_led_0 = seg0[seg_data_0];
assign seg_led_1 = seg1[seg_data_1];
endmodule
说明:这是显示模块的定义。
ps:分频模块部分代码和项目实例中的分频模块相同。
wire clk_sw;
divide #(.WIDTH(32), .N(1200000)) devide (
.clk(clk),
.rst_n(rst_btn),
.clkout(clk_sw)
);
说明:这是分频模块的调用。
六、FPGA资源利用说明
Design Summary:
Number of registers: 45 out of 4635 (1%)
PFU registers: 45 out of 4320 (1%)
PIO registers: 0 out of 315 (0%)
Number of SLICEs: 58 out of 2160 (3%)
SLICEs as Logic/ROM: 58 out of 2160 (3%)
SLICEs as RAM: 0 out of 1620 (0%)
SLICEs as Carry: 30 out of 2160 (1%)
Number of LUT4s: 114 out of 4320 (3%)
Number used as logic LUTs: 54
Number used as distributed RAM: 0
Number used as ripple logic: 60
Number used as shift registers: 0
Number of PIO sites used: 23 + 4(JTAG) out of 105 (26%)
Number of block RAMs: 0 out of 10 (0%)
Number of GSRs: 1 out of 1 (100%)
EFB used : No
JTAG used : No
Readback used : No
Oscillator used : No
Startup used : No
POR : On
Bandgap : On
Number of Power Controller: 0 out of 1 (0%)
Number of Dynamic Bank Controller (BCINRD): 0 out of 6 (0%)
Number of Dynamic Bank Controller (BCLVDSO): 0 out of 1 (0%)
Number of DCCA: 0 out of 8 (0%)
Number of DCMA: 0 out of 2 (0%)
Number of PLLs: 0 out of 2 (0%)
Number of DQSDLLs: 0 out of 2 (0%)
Number of CLKDIVC: 0 out of 4 (0%)
Number of ECLKSYNCA: 0 out of 4 (0%)
Number of ECLKBRIDGECS: 0 out of 2 (0%)
上面的设计摘要提供了FPGA资源利用情况的一个快照。设计摘要包括了特定类型资源的使用情况和总资源量的百分比。这样的信息能够帮助设计工程师了解其设计在FPGA内的资源占用情况,从而对设计做出调整以适应资源限制或者性能要求。
以下是上述设计摘要的分析:
- Number of registers: 在4635个可用的寄存器中,只有45个寄存器被使用,占据1%的资源。
- Number of SLICEs: SLICE是FPGA中的一个逻辑单元,总共2160个单元中有58个在用,占据了3%。
- Number of LUT4s: LUT(查找表)是FPGA中实现逻辑功能的基本单元,用于数据映射。4320个LUT4中有114个在用,占据了3%。
- Number used as logic LUTs: 54个LUT用于逻辑操作。
- Number used as ripple logic: 60个LUT用作级联逻辑。
- Number of PIO sites used: 105个可用的PIO(并行输入/输出)站点中有23个以及附加的4个JTAG接口被使用,总共占据了26%。
- Number of GSRs: GSR(全局设置/复位)使用了1个,共1个,占100%,这是正常的,每个设计都需要一个全局的复位或配置信号。
- Number of block RAMs: 没有使用块RAM,意味着设计中没有使用到内部的大容量存储。
- Number of PLLs: 没有使用PLL(相位锁定环),PLLs通常用于时钟生成或时钟频率调整。
摘要中还列出了其他资源如ECLKSYNCA(时钟同步块)、ECLKBRIDGECS(时钟桥接)、DCCA和DCMA(专用携带链和专用携带多路复用器)等的使用情况,但在当前设计中这些资源都没有被使用。
资源利用率较低通常意味着FPGA在当前设计中还有大量未利用的空间,可以用于更复杂的逻辑或者未来的设计扩展。同时,低资源使用也可能意味着较低的功耗和较快的设计编译时间。
七、chatgpt对该设计实现方案的建议
实际硬件电路在检测按钮按下时通常需要去抖动逻辑以减少误触发。在这段代码中,按键去抖动并未被实现,这可能在物理硬件上导致问题。
八、总结
基于FPGA的秒表设计与实现总结
一、设计目标
本项目设计了一款基于FPGA的简单秒表,要求如下:
1. 使用FPGA板卡上的4个按钮作为输入控制,两个七段数码管作为计数显示输出。
2. 秒表计数范围为0.0~9.9秒,计数周期为0.1秒。
3. 按钮功能包括:开始、停止、增量和清零。
二、设计实现
1. 硬件平台
选用Lattice MachXO2 FPGA开发板,主频12MHz。
2. 设计语言
使用Verilog HDL作为设计语言,通过模块化编程实现各功能模块。
3. 关键模块
- 计数器与控制逻辑模块
- 七段数码管译码显示模块
4. 设计流程
- Verilog代码编写
- 功能仿真验证
- 逻辑综合、布局布线等物理实现步骤
- timing分析,确保时序满足要求
- 生成可编程文件并下载到FPGA
三、实现结果
1. 功能验证
按钮输入可正确控制秒表的开始、停止、增量和清零操作,两个数码管显示计数值。
2. 资源利用
- 寄存器: 45个(1%)
- LUT: 1124个逻辑LUT (3%)
- 未使用任何块RAM和DSP资源
3. 时序报告
设计能在12MHz时钟频率下正常工作,满足10Hz计数更新率。
四、总结与改进
1. 总结
通过模块化设计,成功在FPGA上实现了预期的秒表功能,满足了设计要求。
2. 潜在改进
- 优化时钟约束,提高可工作的最高频率
- 增加测试案例,验证异常情况如按钮同时按下等
- 完善按钮处理逻辑,提高鲁棒性
- 优化代码,降低资源占用
该项目涵盖了FPGA设计的主要流程,对于培养数字电路设计和开发能力具有一定的促进作用。通过持续改进,该秒表设计可以进一步优化和完善。
九、功能图片
十、代码附件
见附件部分,包括完整的工程文件,以及代码的TXT文件。