简介:本资源是面向高校EDA实验与FPGA课程设计的完整实践项目,聚焦基于Quartus平台的智能电梯控制器开发,适用于电子类、自动化及计算机相关专业本科生开展数字系统设计实训。资源包含Verilog源码、Quartus工程文件、课设文档报告及仿真调试材料,覆盖从状态机建模(上升/下降/停留三态编码)、按键控制逻辑、数码管与LED状态显示到电梯锁定功能的全流程实现。压缩包共168个文件,以.v(Verilog源码)、.qpf/.qsf(Quartus工程配置)、.rpt/.summary(综合与布局布线报告)、.txt(说明与注释)及.doc(课设报告)为主,总大小3.77MB,结构规范,便于工程复现与代码研读。已有380人学习下载,提供可直接上板验证的完整工程、状态机图解、关键模块注释及符合现实约束的调度优化思路,助力读者深入理解时序电路设计、状态迁移控制与FPGA软硬件协同调试。
1. 这不是“电梯仿真动画”,而是一套可烧录、可调试、能响应真实按键与楼层请求的 FPGA 实时控制系统
很多同学拿到“智能电梯控制器”课设题目,第一反应是用 Verilog 写个带状态机的流程图动画——但真正合格的 EDA 实验课设,必须跑在真实 FPGA 开发板上:按下开发板上的 KEY0~KEY3 按键(对应 1~4 层楼呼叫),LED 灯实时显示当前轿厢位置,七段数码管滚动显示目标楼层,电机方向信号(UP/DOWN)和开门信号(OPEN)通过 GPIO 引脚输出,且所有时序满足 FPGA 器件的建立/保持时间约束。本工程基于 Quartus Prime 18.0 + Cyclone IV EP4CE6F17C8(常见于 DE1-SoC、CoreEP4CE6 等教学板),Verilog 代码全部采用同步复位、无锁存器、无隐式 latch 的可综合风格,课设文档包含完整的顶层模块接口定义、状态转移图(含 7 个有效状态)、时钟域划分说明(主时钟 50MHz → 分频后 1kHz 控制节拍)、以及关键路径时序报告截图(setup slack ≥ 2.1ns)。它面向的是需要提交可运行工程、通过板级联调验收、并准备数字电路与 EDA 课程答辩的本科生——不是写完波形就交差的仿真练习。
2. 从顶层模块到状态机:Verilog 实现如何兼顾可读性与 FPGA 综合约束
2.1 顶层模块elevator_top的接口设计与引脚绑定逻辑
该工程采用清晰的分层结构:elevator_top.v为唯一顶层,不包含任何行为描述,仅完成端口声明、子模块例化与物理引脚映射。其输入包括 50MHz 系统时钟clk_50m、全局异步复位rst_n(低电平有效)、4 路楼层呼叫按键call_btn[3:0](独立消抖后)、轿厢内 4 路选层按键floor_btn[3:0];输出包括轿厢当前位置cur_floor[1:0](驱动 2 位 LED)、目标楼层target_floor[1:0](驱动七段译码器)、运行方向dir(UP=1/DOWN=0)、开门信号open_door(高电平有效),以及 4 路楼层到达指示灯arrive_led[3:0]。
注意:所有按键均经过
key_debounce模块进行 20ms 同步消抖(非简单延时),使用两级寄存器采样+计数器确认,避免亚稳态传播。该模块输出已同步至clk_50m域,直接接入状态机使能条件。
// elevator_top.v 关键片段(Quartus 18.0 可综合) module elevator_top ( input clk_50m, input rst_n, input [3:0] call_btn, input [3:0] floor_btn, output [1:0] cur_floor, output [1:0] target_floor, output dir, output open_door, output [3:0] arrive_led ); wire [1:0] cur_state; wire [1:0] next_target; wire [1:0] next_floor; wire move_en; // 消抖模块例化(每个按键独立实例) key_debounce uut_key0 (.clk(clk_50m), .rst_n(rst_n), .key_in(call_btn[0]), .key_out(call_deb[0])); key_debounce uut_key1 (.clk(clk_50m), .rst_n(rst_n), .key_in(call_btn[1]), .key_out(call_deb[1])); // ... 其他按键同理 // 核心控制模块 elevator_ctrl uut_ctrl ( .clk(clk_50m), .rst_n(rst_n), .call_req(call_deb), .floor_req(floor_deb), .cur_floor(cur_floor), .target_floor(target_floor), .dir(dir), .open_door(open_door), .arrive_led(arrive_led) ); endmodule2.1.1 引脚分配必须匹配开发板硬件资源
在 Quartus 中执行 Pin Planner 时,必须严格对照开发板原理图:例如 DE1-SoC 的 KEY0 对应 PIN_W15(FPGA BANK 8A),LEDG0 对应 PIN_AE14(BANK 8B),HEX0[6:0] 数码管段选线需绑定至 PIN_AF24~PIN_AD23(BANK 8B)。若错误绑定至未连接的 BANK 或电压不匹配(如 3.3V BANK 接 1.2V I/O),编译会通过但板级无响应。本工程.qsf文件已预置完整约束,关键行如下:
set_location_assignment PIN_W15 -to call_btn[0] set_location_assignment PIN_V16 -to call_btn[1] set_location_assignment PIN_U15 -to call_btn[2] set_location_assignment PIN_T15 -to call_btn[3] set_location_assignment PIN_AE14 -to cur_floor[0] # LEDG0 set_location_assignment PIN_AF14 -to cur_floor[1] # LEDG1 set_location_assignment PIN_AF24 -to hex_seg[0] # HEX0_a # ... 后续段码与位选线按实际原理图补全2.2 电梯状态机:7 状态循环与优先级调度策略
elevator_ctrl模块实现核心调度逻辑,采用三段式 FSM(状态寄存器+次态逻辑+输出逻辑),状态编码为独热码(state_t = 3'b001, 3'b010, ..., 3'b100),降低组合逻辑复杂度。7 个状态分别为:IDLE(空闲等待请求)、MOVE_UP(向上运行中)、MOVE_DOWN(向下运行中)、STOP_AT_FLOOR(到达目标层停靠)、OPEN_DOOR(开门保持 2s)、CLOSE_DOOR(关门延时 1.5s)、CHECK_NEXT(检查新请求并跳转)。
关键设计点在于请求合并与方向优先:当轿厢在 2 楼向上运行时,若 3 楼有呼叫且 4 楼有内选,则MOVE_UP状态持续,依次响应;若此时 1 楼呼叫,则暂存至pending_req[3:0]寄存器,待到达顶层后转入MOVE_DOWN。状态跳转条件全部基于同步时钟边沿采样,无毛刺风险:
// elevator_ctrl.v 状态转移片段(简化) always @(posedge clk or negedge rst_n) begin if (!rst_n) state <= IDLE; else state <= next_state; end always @(*) begin case (state) IDLE: if (|call_req | |floor_req) next_state = MOVE_UP; // 初始默认向上 MOVE_UP: begin if (cur_floor == 2'd3 && !move_up_blocked) next_state = STOP_AT_FLOOR; else if (cur_floor == 2'd0) next_state = MOVE_DOWN; // 到底自动转向 else next_state = MOVE_UP; end // ... 其他状态分支 endcase end2.2.1 时序节拍生成:1kHz 主控时钟与状态驻留时间
为避免状态机在单一时钟周期内完成多个动作(如开门→关门→启动),引入tick_1k信号作为状态驻留基准。该信号由 50MHz 时钟分频得到:
reg [15:0] cnt_1k; always @(posedge clk_50m or negedge rst_n) begin if (!rst_n) cnt_1k <= 0; else if (cnt_1k == 16'd49999) cnt_1k <= 0; else cnt_1k <= cnt_1k + 1; end assign tick_1k = (cnt_1k == 16'd49999); // 50MHz / 50000 = 1kHz所有状态驻留时间均以tick_1k为单位:OPEN_DOOR持续 2000 个tick_1k(即 2s),CLOSE_DOOR持续 1500 个tick_1k(1.5s)。此设计确保时间精度与 FPGA 时钟稳定性强相关,无需外部定时芯片。
3. Quartus 工程配置与 ModelsSim 联合仿真验证流程
3.1 Quartus Prime 18.0 工程创建与综合设置
新建工程时,Family 必须选择Cyclone IV E,Device 选择EP4CE6F17C8(对应 CoreEP4CE6 或 DE1-SoC 的 FPGA 型号)。在 Settings → Compiler → General 中勾选Enable incremental compilation(加速后续修改编译),并在Analysis & Synthesis页将 Optimization Technique 设为Balanced(平衡面积与时序),而非 Aggressive(易导致布线拥塞)。
提示:若使用 Quartus II 13.0/15.0,需手动添加
cycloneiv库路径;Quartus Prime 18.0 默认支持,但需确认安装时勾选了Cyclone IV device support。
3.1.1 关键编译参数表:确保时序收敛
| 参数项 | 推荐值 | 作用说明 |
|---|---|---|
| Fitter Effort | Standard Fit | 避免过度优化导致布线失败 |
| Timing Analysis | Enabled | 必开,否则无法查看 setup/hold slack |
| EDA Netlist Writer | Disabled | 课设无需导出网表供其他工具使用 |
| Logic Options → Auto Shift Register Recognition | Off | 防止误将移位寄存器综合为 RAM 块 |
| Physical Synthesis | Off | 教学工程无需物理综合 |
编译完成后,在TimeQuest Timing Analyzer中查看Report Timing,重点关注Setup Slack:本工程关键路径(如状态机跳转+加法器)slack ≥ 2.1ns,满足 50MHz 主频要求(周期 20ns)。
3.2 ModelsSim 联合仿真:验证状态机行为与按键响应
Quartus 自带的 Simulation 工具功能有限,推荐使用 ModelsSim-Altera Starter Edition(随 Quartus 安装)。在 Quartus 中执行Tools → Run Simulation Tool → RTL Simulation,自动生成 testbench 框架。需手动补充以下内容:
- 初始化
rst_n为 0,持续 3 个clk_50m周期后拉高; - 模拟真实按键时序:
call_btn[1]在t=100us时置 1,保持 20ms 后归 0; - 监控
cur_floor、target_floor、dir信号变化,比对状态机波形与设计文档中的状态转移图。
// testbench 关键激励(ModelsSim 可运行) initial begin rst_n = 0; call_btn = 4'b0000; floor_btn = 4'b0000; #100 rst_n = 1; // 释放复位 #100 call_btn[1] = 1; // 模拟 2 楼呼叫 #20000 call_btn[1] = 0; // 按键释放 #500000 $stop; // 运行 50ms 后停止 end3.2.1 常见报错定位:Quartus II cannot launch ModelSim
该错误本质是 Quartus 未正确识别 ModelsSim 安装路径。解决步骤:
- 打开 Quartus → Tools → Options → EDA Tool Options;
- 在ModelSim-Altera栏填写完整路径:
C:\modeltech64_10.5\win64\vsim.exe(根据实际安装目录调整); - 勾选Use custom path for ModelSim-Altera;
- 重启 Quartus。
若仍失败,检查环境变量PATH是否包含C:\modeltech64_10.5\win64,并确认 ModelsSim 版本与 Quartus 兼容(10.5c 适配 Quartus Prime 18.0)。
4. 板级调试技巧:从 LED 异常闪烁到数码管乱码的逐层排查法
4.1 硬件层:确认开发板供电与下载链路
首先排除物理层问题:DE1-SoC 板需同时接通 USB Blaster(JTAG 下载)与 12V 电源适配器(FPGA 核心供电),仅 USB 供电会导致 BANK 电压不足,LED 显示微弱或数码管段码缺失。使用万用表测量 PIN_AE14(LEDG0)对地电压,正常应为 3.3V;若为 0V,检查SWITCHES[0]是否拨至 ON(部分板卡需手动使能 LED 电源)。
4.2 逻辑层:利用 SignalTap II 实时抓取内部信号
Quartus 内置 SignalTap II 逻辑分析仪是调试关键。添加采样信号时,必须选择已布线完成的寄存器输出(如cur_floor_reg、state_reg),而非组合逻辑中间变量(如next_state),否则可能因布线延迟导致采样失真。采样深度设为 1024,触发条件设为state_reg == STOP_AT_FLOOR,观察cur_floor_reg是否稳定在目标值、open_door是否在 2s 内拉高。
注意:SignalTap 占用约 200 个 LE,需在编译前预留资源。若编译报错 “Exceeded device resource”,临时移除 SignalTap 配置,先验证基础功能。
4.2.1 七段数码管显示异常的三大原因与修复
| 现象 | 可能原因 | 验证与修复方法 |
|---|---|---|
| 数码管全灭 | 位选信号未驱动 | 用万用表测 HEX0_DIG[3:0] 引脚,确认有 3.3V 电平跳变;检查hex_decoder模块是否例化正确 |
| 显示数字错位(如 1 显示为 7) | 段码顺序接反 | 对照原理图确认HEX0_a~HEX0_g与 PCB 上 a~g 引脚物理连接;修改hex_decoder中seg[6:0]赋值顺序 |
| 数字闪烁不定 | 时钟分频不稳定 | 抓取tick_1k信号,确认周期严格为 1ms;若抖动,检查分频计数器是否溢出(cnt_1k == 49999判断是否准确) |
4.3 系统层:验证多请求并发下的调度正确性
真实测试场景:同时按下 KEY1(2 楼外呼)、KEY2(3 楼外呼)、SW0(轿厢内选 4 楼)。预期行为:轿厢从 1 楼启动→停 2 楼→停 3 楼→停 4 楼→开门→关门→返回 1 楼待命。若出现跳层(如 1→3→4,漏掉 2),说明pending_req寄存器未在CHECK_NEXT状态中正确更新;若停靠后不关门,检查CLOSE_DOOR状态的计时器是否被意外复位(常见于rst_n信号受干扰)。
最终验证标准:在连续 10 次不同请求组合下,LED 显示楼层序列、数码管目标值、dir信号极性三者完全一致,且开门/关门动作时长误差 < ±50ms。
本文还有配套的精品资源,点击获取