刚接触FPGA那会儿总觉得交通灯项目太“教科书“,真自己动手才发现时序控制藏着不少坑。这次咱们用Verilog搞个带特殊左转信号的交通灯系统,直接上干货

📅 发布时间:2026/7/5 6:06:24 👁️ 浏览次数:
刚接触FPGA那会儿总觉得交通灯项目太“教科书“,真自己动手才发现时序控制藏着不少坑。这次咱们用Verilog搞个带特殊左转信号的交通灯系统,直接上干货
基于fpga的交通灯设计要求A通道绿灯亮30S黄灯亮5S左拐灯亮15S黄灯亮5S这个过程中B通道一直亮红灯之后A通道亮红灯B通道绿灯亮40S之后黄灯亮5S之后左拐灯亮15S之后黄灯亮5S之后A通道转为绿灯B通道转为红灯。 提供quartus以及modelsim工程以及仿真结果文档可以上板先看核心状态机设计拿always块搭了个交通指挥官reg [3:0] state; parameter A_GREEN 4b0001, A_YELLOW 4b0010, A_LEFT 4b0100, A_Y2 4b1000, B_GREEN 4b0001, B_YELLOW 4b0010, B_LEFT 4b0100, B_Y2 4b1000; // 状态持续时间设定 reg [5:0] counter; parameter A_G_TIME 30, A_Y_TIME 5, A_L_TIME 15, B_G_TIME 40, B_Y_TIME 5, B_L_TIME 15;这里用独热码编码状态每个通道独立的状态参数看起来有点重复但实测比合并编码更易维护。注意counter用6位足够存最大40秒的计数值。计时控制是重点看这段always块always (posedge clk_1hz) begin case(state) A_GREEN: begin if(counter A_G_TIME-1) begin state A_YELLOW; counter 0; end else begin counter counter 1; end } // 其他状态类似... default: state A_GREEN; endcase end这里有个细节counter判断用AGTIME-1而不是AGTIME因为从0开始计数。用1Hz时钟源是关键在顶层模块做了分频// 50MHz转1Hz reg [25:0] div_cnt; always (posedge clk_50m) begin if(div_cnt 50_000_000-1) begin clk_1hz ~clk_1hz; div_cnt 0; end else begin div_cnt div_cnt 1; end end分频计数器位宽算清楚26位足够存5千万次计数。注意这里用取反生成时钟实际项目建议用使能信号更稳定。输出控制部分最考验位运算assign A_light (state A_GREEN) ? 3b100 : (state A_YELLOW) ? 3b010 : (state A_LEFT) ? 3b001 : 3b010; assign B_red (state inside {A_GREEN, A_YELLOW, A_LEFT, A_Y2}) ? 1b1 : 0;这里用三元运算符实现状态到灯光的映射。注意B通道红灯在A通道所有状态期间保持亮起用inside操作符简化判断。Modelsim仿真抓个波形图基于fpga的交通灯设计要求A通道绿灯亮30S黄灯亮5S左拐灯亮15S黄灯亮5S这个过程中B通道一直亮红灯之后A通道亮红灯B通道绿灯亮40S之后黄灯亮5S之后左拐灯亮15S之后黄灯亮5S之后A通道转为绿灯B通道转为红灯。 提供quartus以及modelsim工程以及仿真结果文档可以上板!仿真波形显示状态切换时间准确A通道绿灯持续30个时钟周期后跳转黄灯从波形可见A通道绿灯计数到290开始后切黄灯完全符合设计。B通道在A活动期间保持红灯切换后立即变绿。上板时要注意引脚分配建议这样配置set_location_assignment PIN_B14 -to clk_50m set_location_assignment PIN_A13 -to A_light[0] # 左转灯 set_location_assignment PIN_B13 -to A_light[1] # 黄灯 set_location_assignment PIN_A14 -to A_light[2] # 绿灯 # B通道类似...实测时发现个有趣现象机械继电器控制的信号灯在切换时会有轻微延迟加入10ms的消抖逻辑后问题解决。这也提醒我们真实硬件和仿真环境确实存在差异。完整工程已经打包包含Quartus项目文件、仿真脚本和约束文件。直接烧录到Cyclone IV开发板就能看到红绿灯按设计节奏跳动。下次试试加入紧急车辆感应功能用红外传感器触发优先通行应该挺有意思。