当前位置: 首页 > news >正文

基于Logisim与Verilog HDL的运动码表计时电路设计与DE2-70开发板验证

1. 从零开始理解运动码表计时电路

第一次接触数字电路设计时,看到"运动码表计时电路"这个概念可能会觉得有点高大上。其实说白了,这就是一个能记录分钟和秒钟的计时器,跟我们平时用的秒表功能差不多。只不过这次我们要用Logisim画电路图,再用Verilog HDL写代码,最后在DE2-70开发板上跑起来。

这个项目最有趣的地方在于,它完美展示了数字电路设计的完整流程:从逻辑设计到硬件实现。我刚开始做这个项目时,对着真值表画电路图画到怀疑人生,但后来看到数码管上的数字正常跳动时,那种成就感真的无法形容。

计时电路的核心是四个计数器:分的十位(0-5)、分的个位(0-9)、秒的十位(0-5)、秒的个位(0-9)。这就像我们平时看时间的习惯一样,只不过在电路里是用二进制实现的。特别要注意的是进位信号的处理——低位的进位信号就是高位的时钟信号,这个设计思路非常巧妙。

2. Logisim电路设计实战

2.1 BCD码计数器设计

在Logisim里设计BCD码计数器是第一个难点。我建议先搞定0-9的十进制计数器,再改造成0-5的六进制计数器。具体来说,一个完整的BCD码计数器需要两部分:

  1. 状态转换电路:控制0到9的状态切换
  2. 输出函数电路:在状态从9跳回0时产生进位信号

画电路图时有个小技巧:先列出真值表,然后用Logisim的"组合分析"功能自动生成电路。这比手动连线省事多了,特别适合我们这些新手。不过自动生成的电路可能不够优化,后期可以手动调整。

记得我第一次做的时候,忘了处理进位信号,结果计数器到9就卡住了。后来发现是输出函数没设计好,当计数器从9变0时,必须输出一个高电平的进位信号。

2.2 完整计时电路搭建

四个计数器都做好后,就要考虑它们之间的连接了。这里的关键是:

  • 秒的个位(0-9)计数器:时钟直接接外部时钟
  • 秒的十位(0-5)计数器:时钟接秒个位的进位
  • 分的个位(0-9)计数器:时钟接秒十位的进位
  • 分的十位(0-5)计数器:时钟接分个位的进位

在Logisim中测试时,建议先用快速时钟信号(比如1Hz)观察计数过程。我第一次测试时用了太快的时钟,结果数字跳得眼花缭乱,根本看不清是否正确进位。后来改用慢速时钟,配合单步调试,才确认电路工作正常。

3. Verilog HDL实现

3.1 十进制计数器模块

用Verilog写计数器比画电路图简单多了。下面是我调试通过的十进制计数器代码:

module bcd_counter1( input en_10, // 使能信号 input clk_10, // 时钟信号 input res_10, // 复位信号 input zin_10, // 进位输入 output zout_10, // 进位输出 output reg [3:0] qout_10 // 计数输出 ); always@(posedge clk_10) begin if(res_10) qout_10 <= 4'b0; // 复位时清零 else if(en_10) if(qout_10 == 4'h9) qout_10 <= 4'b0; // 到9后归零 else if(zin_10) qout_10 <= qout_10 + 1'b1; // 正常计数 end assign zout_10 = (qout_10 == 4'h9); // 产生进位信号 endmodule

这个模块有几个关键点:

  1. 使用posedge clk_10确保在时钟上升沿触发
  2. 复位信号高电平有效
  3. 只有在使能信号有效且收到进位信号时才计数

3.2 六进制计数器模块

秒的十位需要0-5的六进制计数器,代码与十进制类似,但判断条件不同:

module bcd_counter2( input en_6, input clk_6, input res_6, input zin_6, output zout_6, output reg [3:0] qout_6 ); always@(posedge clk_6) begin if(res_6) qout_6 <= 4'b0; else if(en_6) if(qout_6 == 4'h5) // 注意这里是5不是9 qout_6 <= 4'b0; else if(zin_6) qout_6 <= qout_6 + 1'b1; end assign zout_6 = (qout_6 == 4'h5); // 到5时进位 endmodule

3.3 顶层模块设计

顶层模块负责把四个计数器连接起来:

module jishiqi( input en, input clk, input res, output [15:0] D_count_16 ); wire mone_mten_out; // 秒个位→秒十位 wire mten_fone_out; // 秒十位→分个位 wire fone_ften_out; // 分个位→分十位 bcd_counter1 mone( .en_10(en), .clk_10(clk), .res_10(res), .zin_10(1'b1), // 秒个位始终允许计数 .zout_10(mone_mten_out), .qout_10(D_count_16[3:0]) ); bcd_counter2 mten( .en_6(en), .clk_6(clk), .res_6(res), .zin_6(mone_mten_out), .zout_6(mten_fone_out), .qout_6(D_count_16[7:4]) ); // 其他两个计数器类似... endmodule

4. DE2-70开发板验证

4.1 引脚分配

在Quartus II中,需要为输入输出信号分配实际引脚。根据DE2-70开发板的硬件布局,我使用了以下配置:

  • SW0:使能信号(en)
  • SW1:复位信号(res)
  • KEY0:手动时钟(clk)
  • HEX0-HEX3:分别显示秒个位、秒十位、分个位、分十位

引脚分配完成后,记得生成编程文件(.sof)。我第一次下载时忘了分配引脚,结果开发板上的数码管完全没反应,排查了好久才发现问题。

4.2 实际测试技巧

在开发板上测试时,建议:

  1. 先用慢速手动时钟(KEY0)测试进位关系
  2. 确认基本功能正常后,再改用50MHz系统时钟分频得到1Hz时钟
  3. 观察从59秒到1分钟的跳变是否正确
  4. 测试复位功能是否正常工作

我在测试时发现秒十位偶尔会显示6,检查后发现是六进制计数器的判断条件写成了"=="而不是">=",导致在快速时钟下可能错过复位时机。这个小bug让我深刻理解了异步电路设计的注意事项。

5. 常见问题与调试技巧

做这个项目时,我踩过不少坑,这里分享几个常见问题:

  1. 计数器不工作:检查时钟极性是否正确,复位信号是否有效
  2. 进位不正常:确认低位计数器的进位输出确实连接到了高位计数器的时钟输入
  3. 显示乱码:检查数码管译码电路是否正确,特别是BCD码到七段码的转换
  4. 计时不准:如果是用高频时钟分频,检查分频计数器是否足够大

调试时建议分模块验证:先单独测试每个计数器,再测试进位关系,最后整合整个系统。用SignalTap II逻辑分析仪可以很方便地观察内部信号变化。

6. 项目扩展思路

基础功能实现后,可以尝试以下扩展:

  1. 添加暂停/继续功能
  2. 实现多组计时记忆
  3. 增加报警功能(如计时到设定时间时触发)
  4. 改用更精确的时钟源(如开发板上的50MHz晶振分频)

我在完成基础功能后,增加了通过VGA显示大号数字的功能。虽然花了不少时间调试,但看到计时器在大屏幕上显示时,感觉特别有成就感。这些扩展不仅能提升项目复杂度,也能让你更深入地理解FPGA开发。

http://www.cnnetsun.cn/news/1710721.html

相关文章:

  • 别再用手机思维做TV App了!Android TV开发必知的模拟器操作与UI焦点设计实战
  • 别只盯着stkInit!用这个STK MATLAB互联测试脚本,一键验证你的环境是否真的配好了
  • 魔兽争霸3 Windows 11兼容性终极解决方案:让你的经典游戏重获新生
  • 终极Limbus Company自动化助手:5大功能彻底解放你的双手
  • 终极指南:如何快速上手ALOHA开源双臂机器人系统,开启你的机器人开发之旅
  • 基于元模型优化的虚拟电厂主从博弈动态定价与能量管理双层调度策略
  • ai辅助开发新体验:让快马ai帮你打造智能win10安装准备助手
  • AI辅助开发性能代码:让快马平台AI成为你的高性能并发任务调度顾问
  • Windows 批量文件夹图标设置工具(支持.ico.exe 图标提取与替换)自动扫描每个文件夹中的ICO和EXE图标文件
  • 智能自动化任务管理器是专业 Windows 自动化工具,零代码可视化配置,支持全类型任务与多模式执行,内置键鼠编辑器
  • 全面掌握HSTracker:从炉石传说套牌追踪到高级数据分析的实战指南
  • 深入剖析Golang HTTP/2客户端连接池与多路复用机制
  • TCP Keep-Alive、HTTP Keep-Alive、应用层心跳,傻傻分不清?一张图讲透网络‘保活’全家桶
  • U盘启动盘制作全攻略:从Rufus到Ventoy的深度对比
  • 3步精通UndertaleModTool:解锁GameMaker游戏修改全流程
  • 抖音批量下载全攻略:一键保存无水印视频,轻松管理海量内容
  • 高光谱成像的噪声估计
  • 2025届毕业生推荐的五大AI辅助论文平台推荐榜单
  • 虚拟机中的AI实验室:VMware安装Ubuntu并部署Phi-4-mini-reasoning
  • IC面试官最爱问的Verilog分频题:手把手教你写出50%占空比的奇偶分频代码
  • 保姆级教程:用YOLOv8/v7/v5训练自己的停车位检测模型(附完整数据集和代码)
  • UG/NX工程师必备:STEP文件导出常见问题排查指南(含环境变量设置技巧)
  • 双天线北斗接收机在机器人导航中的实战配置——以NC502-D为例
  • 避免PCB设计翻车!Allegro铜皮编辑中的5个常见错误及解决方法
  • 别再死记硬背了!一张图帮你理清InfiniBand那些让人头疼的术语(HCA/QP/LID/GID)
  • WAN2.2文生视频+SDXL_Prompt风格中文提示词库:100+行业高频模板免费分享
  • EF Core 慢查询排查实战:TagWith、OpenTelemetry、执行计划,30 分钟定位性能瓶颈
  • 2025届毕业生推荐的十大AI写作助手实际效果
  • 告别评价烦恼:京东自动评价工具的技术实现与高效应用指南
  • Python可执行文件逆向解析工具:从二进制到源代码的完整方案