汽车转向灯控制 FPGA 设计 Verilog Quartus
名称汽车转向灯控制 FPGA 设计 Verilog Quartus软件Quartus语言Verilog功能介绍本设计实现一个汽车转向灯控制逻辑核心功能包括正常状态、左转向灯闪烁、右转向灯闪烁以及紧急双闪。输入端包含时钟 cp、左转按键 z、右转按键 y 和紧急按键 j输出端为左转向灯 LD 与右转向灯 RD适合用于 FPGA 数字逻辑、有限状态机和交通/车辆控制类课程设计。 系统在正常状态下左右灯均熄灭按下左转按键后左灯按照节拍闪烁松开后返回正常状态按下右转按键后右灯按照节拍闪烁松开后返回正常状态按下紧急按键后左右灯同步闪烁松开后退出紧急模式。状态切换逻辑中设置了按键优先级紧急信号优先于左转信号左转信号优先于右转信号。 工程采用 Verilog 编写顶层模块为 controlwd并配套 tb_controlwd 测试文件。设计中包含 1 秒节拍分频、状态寄存、下一状态组合逻辑、闪烁相位控制和输出控制等部分逻辑结构清晰便于学习 FPGA 状态机设计方法也便于根据实际硬件时钟频率调整闪烁节拍。运行环境开发软件Quartus。 仿真环境Modelsim、Quartus VWF 仿真。 设计语言Verilog。 顶层模块controlwd。 主要工程文件包括 controlwd.qpf、controlwd.qsf、controlwd.v 和 tb_controlwd.v。设计思路整体设计采用有限状态机实现汽车转向灯的工作模式管理。状态编码使用独热编码方式定义正常状态 S_QA、左转状态 S_QB、右转状态 S_QC 和紧急状态 S_QD。独热编码使状态判断条件直观适合教学和调试场景也便于从 RTL 图和状态图中观察控制流程。 输入按键首先进入下一状态组合逻辑进行判断。在正常状态下控制逻辑按照 j z y 的优先级选择进入紧急双闪、左转闪烁或右转闪烁状态在左转、右转、紧急状态下对应按键释放后返回正常状态。这样的设计能够明确区分保持状态和退出状态避免输出在按键持续期间频繁切换模式。 闪烁功能由分频计数器和 phase 相位寄存器共同完成。参数 INPUT_FREQ_HZ 用于设置输入时钟频率SEC_DIV 用于产生 1 秒节拍当状态进入左转、右转或紧急模式时phase 先置为亮随后每过 1 秒翻转一次从而形成灯光闪烁效果。返回正常状态时 phase 清零使左右灯保持熄灭。 输出部分根据当前状态生成 left_en 和 right_en 使能信号。左转状态仅 LD 跟随 phase右转状态仅 RD 跟随 phase紧急状态下 LD 与 RD 同步跟随 phase。该结构把状态判断、节拍控制和输出映射分开处理便于后续扩展更多灯光模式或修改闪烁频率。模块结构工程主要由 controlwd 顶层控制模块和 tb_controlwd 测试模块组成。 controlwd汽车转向灯核心控制模块包含时钟分频、状态机、闪烁相位控制和左右灯输出逻辑。输入信号为 cp、z、y、j输出信号为 LD、RD。 tb_controlwd测试激励模块用于对左转、右转、紧急双闪等典型输入场景进行仿真验证。 状态划分S_QA 表示正常熄灭状态S_QB 表示左转闪烁状态S_QC 表示右转闪烁状态S_QD 表示紧急双闪状态。演示视频演示视频用于查看汽车转向灯控制效果可配合工程仿真结果理解左转、右转和紧急双闪三类工作状态的输出变化。演示视频请关注公众号后获取对应资料查看。仿真图/仿真说明/设计文档图片设计文档内容覆盖工程文件、程序文件、程序编译、RTL 图、状态图、仿真图、Modelsim 仿真图、Testbench 以及 VWF 仿真图。仿真部分可用于观察按键输入变化时 LD、RD 两路输出的响应过程适合对照状态机逻辑检查左转、右转和紧急双闪模式是否符合设计要求。部分代码以下展示顶层模块controlwd的部分代码完整代码可关注下方公众号卡片获取。module controlwd ( input wire cp, // 时钟输入 input wire z, // 左转按键 input wire y, // 右转按键 input wire j, // 紧急按键 output reg LD, // 左转向灯输出 output reg RD // 右转向灯输出 ); // // 参数与状态编码采用独热编码 // // 将输入时钟频率设置为100Hz每秒100个周期可按实际硬件修改 parameter integer INPUT_FREQ_HZ 100; localparam integer SEC_DIV INPUT_FREQ_HZ; // 每数到100产生1秒脉冲 // 一热状态仅有一个比特为1表示当前状态 localparam [3:0] S_QA 4b0001; // 正常左右灯灭 localparam [3:0] S_QB 4b0010; // 左转左灯闪 localparam [3:0] S_QC 4b0100; // 右转右灯闪 localparam [3:0] S_QD 4b1000; // 紧急左右双闪 // 当前状态与下一状态寄存器 reg [3:0] st_cur S_QA; // 初始为QA reg [3:0] st_nxt; // // 1秒节拍分频器 // // 每当sec_cnt计到SEC_DIV-1产生sec_pulse1秒一次 reg [31:0] sec_cnt 32d0; wire sec_pulse (sec_cnt (SEC_DIV - 1)); always (posedge cp) begin // 计满产生1秒脉冲然后清零重新计数 sec_cnt sec_pulse ? 32d0 : (sec_cnt 1); end // // 闪烁相位控制phase1亮phase0灭 // // 进入QB/QC/QD时先置为亮随后每过1秒翻转 reg phase 1b0; // // 下一状态组合逻辑含优先级j z y // always (*) begin st_nxt st_cur; // 默认不变 if (st_cur S_QA) begin // QA下按优先级进入闪烁状态 if (j) st_nxt S_QD; else if (z) st_nxt S_QB; else if (y) st_nxt S_QC; end else if (st_cur S_QB) begin // 左转松开z返回QA if (!z) st_nxt S_QA; end else if (st_cur S_QC) begin // 右转松开y返回QA if (!y) st_nxt S_QA; end else if (st_cur S_QD) begin // 紧急松开j返回QA if (!j) st_nxt S_QA; end else begin // 异常保护 st_nxt S_QA; end end // // 状态寄存与闪烁相位更新保证进入时先亮 // always (posedge cp) begin // 状态更新 st_cur st_nxt; // 进入闪烁状态先亮返回QA则灭 if (st_cur ! st_nxt) begin phase (st_nxt S_QA) ? 1b0 : 1b1; end else begin // 状态未变时每秒按需翻转 if (sec_pulse) begin phase (st_cur S_QA) ? 1b0 : ~phase; end end end // // 输出控制 // // 左、右输出根据当前状态选择是否跟随phase wire left_en (st_cur S_QB) || (st_cur S_QD); wire right_en (st_cur S_QC) || (st_cur S_QD); always (*) begin LD left_en ? phase : 1b0; RD right_en ? phase : 1b0; end endmodule点击下方公众号卡片关注获取代码