news 2026/4/16 23:57:25

一、组合逻辑设计实战——从波形图到上板验证的多路选择器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一、组合逻辑设计实战——从波形图到上板验证的多路选择器

1. 从零开始搭建多路选择器工程

第一次接触FPGA开发的朋友可能会觉得无从下手,其实只要按照标准流程一步步来,很快就能上手。我刚开始做数字电路设计时,最头疼的就是工程文件管理混乱,后来养成了规范化的习惯,效率提升了不少。

建议在项目文件夹中创建名为mux2_1的工程目录,里面建立四个子文件夹:

  • doc:存放设计文档、波形图和模块图
  • rtl:存放Verilog源代码
  • sim:存放仿真测试文件
  • prj:存放Quartus工程文件

这个结构看起来简单,但在实际项目中特别实用。比如上周调试一个复杂设计时,就是靠清晰的文件夹结构快速定位到了出问题的仿真文件。记得给每个文件加上日期版本号,比如mux2_1_20240815.v,这样回溯起来特别方便。

2. 可视化设计:模块图与波形图

很多新手会直接跳过去写代码,这其实是个坏习惯。我带的实习生就犯过这个错误,结果调试花了三倍时间。先用Visio画出模块图,能帮我们理清数据流向。

对于2选1多路选择器,模块图很简单:

  • 三个输入端口:in_1、in_2和sel
  • 一个输出端口:out 用矩形框表示模块,箭头标明信号方向即可。

波形图绘制更有讲究,我一般会标注这些关键点:

  1. sel上升沿和下降沿画虚线
  2. in_1和in_2信号随机变化
  3. out信号要严格对应sel状态
  4. 标注关键时间点的信号值

建议用不同颜色区分信号,比如红色画时钟,蓝色画数据。最近用WaveDrom在线工具发现特别方便,可以直接生成SVG波形图。

3. Verilog编码实战技巧

打开rtl文件夹新建mux2_1.v文件,这里分享几个我踩坑后总结的编码规范:

module mux2_1( input wire in_1, // 建议信号名带方向,如i_in1 input wire in_2, input wire sel, // 选择信号建议用sel或cs_n这类通用名 output reg out // 驱动寄存器必须声明为reg ); // 方法1:always组合逻辑 always @(*) begin if(sel == 1'b1) out = in_1; else out = in_2; end // 方法2:三目运算符 // assign out = sel ? in_1 : in_2; endmodule

注意几个易错点:

  1. always块内赋值的输出必须声明为reg
  2. 组合逻辑必须用always @(*)或者assign
  3. 建议所有信号显式声明1位宽,避免隐式推断

最近项目中发现个有趣现象:用三目运算符的综合结果有时比if-else更优,大家可以对比下资源占用。

4. 工程创建与代码检查

在Quartus中新建工程时,有几点特别重要:

  1. 器件型号要准确选择,我常用Cyclone IV EP4CE10
  2. 文件添加要用"Add Existing File",不要直接拖拽
  3. 编译前检查Assignments -> Settings里的配置

常见编译错误处理:

  • 端口不匹配:检查实例化时的信号顺序
  • 语法错误:注意分号和括号配对
  • 警告No clocks:组合逻辑可以忽略

建议开启所有警告信息,我遇到过Warning最终导致功能异常的情况。编译通过后,建议立即做一次RTL Viewer检查,确认综合结果符合预期。

5. 仿真调试全攻略

仿真文件建议放在sim文件夹,这是我的标准模板:

`timescale 1ns/1ns module tb_mux2_1(); reg in_1; reg in_2; reg sel; wire out; // 初始化信号 initial begin in_1 <= 1'b0; in_2 <= 1'b0; sel <= 1'b0; #100 $stop; // 建议加停止条件 end // 随机激励生成 always #10 in_1 <= {$random} % 2; always #15 in_2 <= {$random} % 2; // 不同周期更易观察 always #20 sel <= ~sel; // 定期翻转 // 监控输出 initial begin $timeformat(-9,0,"ns",6); $monitor("@%t: in1=%b in2=%b sel=%b out=%b", $time,in_1,in_2,sel,out); end // 实例化被测模块 mux2_1 uut ( .in_1(in_1), .in_2(in_2), .sel(sel), .out(out) ); endmodule

仿真时重点关注:

  1. sel变化后out是否立即跟随(组合逻辑特性)
  2. 输入变化时输出是否保持稳定
  3. 边界情况如全0/全1输入

ModelSim波形调试技巧:

  • 分组信号:右键->Group->Create Group
  • 设置Radix:二进制/十六进制显示
  • 添加标记:Marker功能定位关键时序

6. 管脚绑定与物理验证

上板前最后一步是管脚分配,新手常犯的错误有:

  1. 忘记约束时钟管脚
  2. 输出管脚驱动能力设置不当
  3. 未分配未用管脚状态

推荐操作流程:

  1. 查看开发板原理图确认管脚号
  2. 在Assignment Editor中分配
  3. 生成管脚报告交叉检查
  4. 全编译后检查Fitter消息

实际调试中发现个实用技巧:先用SignalTap抓取内部信号,确认逻辑正确后再接外部设备。最近用DE10-Nano板测试时,发现LED会有微小延迟,这是正常现象。

7. 进阶优化与问题排查

完成基础功能后,可以尝试这些优化:

  1. 添加参数化设计:
parameter WIDTH = 1; input [WIDTH-1:0] in_1, in_2; output [WIDTH-1:0] out;
  1. 使用时序约束:
create_clock -name clk -period 20 [get_ports sel]
  1. 资源优化策略:
  • 共用选择信号
  • 流水线设计

常见问题排查指南:

  • 输出一直为高阻:检查是否有多驱动
  • 仿真结果与预期不符:确认敏感列表完整
  • 板级测试异常:用示波器检查信号质量

最近帮同事调试时发现个典型案例:组合逻辑毛刺导致后续电路误触发,通过加寄存器采样解决了问题。建议大家养成保存调试记录的习惯,这些经验特别宝贵。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 23:55:14

【Windows】使用启动U盘重装Windows10系统

一、准备 启动盘&#xff0c;详情见&#xff1a;【Windows】制作Windows10系统U盘&#xff0c;启动盘制作步骤要重装系统的电脑。 提示 重装系统前一定要备份自己的数据 二、重装系统 &#xff08;一&#xff09;BIOS设置&#xff08;以惠普战66为例&#xff09; 这一步的…

作者头像 李华
网站建设 2026/4/16 23:51:40

2026年了,谁还在手搓本科毕业论文啊??

作为刚熬完本科毕业季、现在还在研究所搬砖的过来人&#xff0c;我太懂本科写毕业论文的时候那种抓心挠肝的痛苦了。跟着导师做了大半年实验&#xff0c;数据攒了一堆&#xff0c;翻了几十篇中英文文献&#xff0c;要么就是不知道怎么梳理逻辑&#xff0c;要么就是抄了句型被查…

作者头像 李华
网站建设 2026/4/16 23:50:28

终极指南:PZEM-004T v3.0电力监测模块的完整快速开发方案

终极指南&#xff1a;PZEM-004T v3.0电力监测模块的完整快速开发方案 【免费下载链接】PZEM-004T-v30 Arduino library for the Updated PZEM-004T v3.0 Power and Energy meter 项目地址: https://gitcode.com/gh_mirrors/pz/PZEM-004T-v30 PZEM-004T v3.0是一款基于Mo…

作者头像 李华