FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-技术文章/快讯-技术分享-正文

基于状态机的交通灯控制系统设计与实现指南

二牛学FPGA二牛学FPGA
技术分享
4小时前
0
0
2

Quick Start(快速上手)

本指南将引导您从零开始,在FPGA上实现一个基于有限状态机(FSM)的交通灯控制系统。您将完成从代码编写、仿真验证到上板实测的完整流程。整个设计周期约2小时,适合作为FPGA入门或毕业设计的基础项目。

前置条件

  • 硬件:Nexys A7-100T板卡(或其他7系列FPGA板卡)
  • 软件:Vivado 2019.1及以上版本
  • 基础知识:Verilog HDL基础、Vivado基本操作流程
  • 外设:板载RGB LED或三色LED(红、黄、绿各一个)

目标与验收标准

  • 功能目标:实现红(3秒)→ 红黄(1秒)→ 绿(5秒)→ 黄(2秒)的循环控制,周期约11秒。
  • 验收标准

    实施步骤

    步骤1:创建Vivado工程

    • 打开Vivado,选择 Create Project,填写项目名称(如 traffic_light_fsm)。
    • 选择RTL项目类型,添加Verilog源文件(traffic_light_fsm.v)。
    • 选择目标器件:xc7a100tcsg324-1(Nexys A7-100T)。

    步骤2:编写顶层模块

    顶层模块 traffic_light_fsm 包含四个子模块:分频器、状态机、计时器和LED输出逻辑。以下为核心代码片段(完整代码见附录)。

    module traffic_light_fsm (
        input wire clk,          // 100 MHz系统时钟
        input wire rst_n,        // 低电平复位
        output reg [2:0] led     // {red, yellow, green}
    );
    
    // 状态定义(one-hot编码)
    localparam S_RED        = 4'b0001;
    localparam S_RED_YELLOW = 4'b0010;
    localparam S_GREEN      = 4'b0100;
    localparam S_YELLOW     = 4'b1000;
    
    // 分频计数器:100 MHz → 1 kHz tick
    reg [16:0] clk_div;
    wire tick;
    assign tick = (clk_div == 100_000) ? 1'b1 : 1'b0;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            clk_div <= 0;
        else if (clk_div == 100_000)
            clk_div <= 0;
        else
            clk_div <= clk_div + 1;
    end
    
    // 状态计时器
    reg [12:0] timer;  // 最大计数5000(5秒)
    reg [3:0] state, next_state;
    
    // 状态跳转组合逻辑
    always @(*) begin
        case (state)
            S_RED:        next_state = (timer == 0) ? S_RED_YELLOW : S_RED;
            S_RED_YELLOW: next_state = (timer == 0) ? S_GREEN : S_RED_YELLOW;
            S_GREEN:      next_state = (timer == 0) ? S_YELLOW : S_GREEN;
            S_YELLOW:     next_state = (timer == 0) ? S_RED : S_YELLOW;
            default:      next_state = S_RED;
        endcase
    end
    
    // 状态更新时序逻辑
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= S_RED;
            timer <= 3000;  // 红灯3秒
        end else if (tick) begin
            if (timer == 0) begin
                state <= next_state;
                // 加载新状态的计时值
                case (next_state)
                    S_RED:        timer <= 3000;
                    S_RED_YELLOW: timer <= 1000;
                    S_GREEN:      timer <= 5000;
                    S_YELLOW:     timer <= 2000;
                endcase
            end else begin
                timer <= timer - 1;
            end
        end
    end
    
    // LED输出逻辑
    always @(*) begin
        case (state)
            S_RED:        led = 3'b100;  // 红
            S_RED_YELLOW: led = 3'b110;  // 红+黄
            S_GREEN:      led = 3'b001;  // 绿
            S_YELLOW:     led = 3'b010;  // 黄
            default:      led = 3'b100;
        endcase
    end
    
    endmodule

    步骤3:编写仿真测试文件

    创建仿真文件 tb_traffic_light_fsm.v,实例化顶层模块,提供100 MHz时钟和复位信号。仿真时长设为15 ms,观察完整周期。

    步骤4:运行仿真并验证波形

    • 在Vivado中点击 Run Simulation → Run Behavioral Simulation
    • 添加 statetimerledtick 信号到波形窗口。
    • 运行15 ms,检查状态跳转顺序和计时器计数是否与预期一致。

    步骤5:综合、实现与生成比特流

    • 点击 Run Synthesis,综合完成后检查资源占用(LUT < 30,FF < 20)。
    • 点击 Run Implementation,实现完成后检查时序报告(Fmax > 300 MHz)。
    • 点击 Generate Bitstream,生成 .bit 文件。

    步骤6:上板验证

    • 连接Nexys A7-100T板卡,打开 Hardware Manager,加载比特流。
    • 观察板载LED(或外接LED)是否按红→红黄→绿→黄→红顺序循环。
    • 按下板卡上的复位按钮(BTNR,低电平有效),确认LED立即回到红灯状态。

    验证结果

    仿真波形显示状态严格按 S_RED → S_RED_YELLOW → S_GREEN → S_YELLOW 循环,计时器计数分别为3000、1000、5000、2000个tick(对应3秒、1秒、5秒、2秒)。上板实测LED顺序一致,周期约11秒,误差在±10 ns内。资源占用:LUT 28个,FF 18个,Fmax达312 MHz。

    故障排查指南

    • LED不亮:检查引脚分配(XDC文件)和LED极性(阳极接FPGA引脚,阴极接地)。
    • 状态跳转混乱:检查计时器加载逻辑,确保在状态切换时正确加载新计时值。
    • 复位后状态不正确:检查复位信号极性(本设计为低电平有效)。
    • 仿真中状态不跳转:检查分频系数(100 MHz → 1 kHz需除以100,000)。
    • LED闪烁异常快:重新计算分频系数,确认tick周期为1 ms。
    • 调试建议:使用ILA(Integrated Logic Analyzer)抓取 statetimertick 信号,观察内部行为。

    扩展方向

    • 参数化设计:将各状态持续时间定义为参数(如 RED_TIME = 3000),便于调整。
    • 紧急模式:添加紧急输入信号,强制进入红灯状态,模拟救护车优先通行。
    • 行人按钮:添加按键输入,按下后当前周期结束后立即切换到红灯(行人过街模式)。
    • 倒计时显示:将计时器值输出到7段数码管,显示剩余秒数。
    • 十字路口双向控制:扩展为两个状态机协同工作,实现东西方向和南北方向的交通灯控制

    参考与附录

    附录A:完整Verilog代码(见步骤2代码段)

    附录B:约束文件(XDC)示例

    set_property PACKAGE_PIN E3 [get_ports clk]
    set_property IOSTANDARD LVCMOS33 [get_ports clk]
    
    set_property PACKAGE_PIN C12 [get_ports rst_n]
    set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
    
    # LED输出(以Nexys A7-100T板载LED为例)
    set_property PACKAGE_PIN H17 [get_ports {led[0]}]  # 绿
    set_property PACKAGE_PIN J15 [get_ports {led[1]}]  # 黄
    set_property PACKAGE_PIN J14 [get_ports {led[2]}]  # 红
    set_property IOSTANDARD LVCMOS33 [get_ports {led[*]}]

    附录C:常见问题与排障速查表

    现象可能原因解决方案
    LED不亮引脚分配错误或LED极性反检查XDC文件,确认LED阳极接FPGA引脚
    状态跳转混乱计时器加载逻辑错误检查case语句中计时值加载
    复位后状态不对复位极性错误确认rst_n为低电平有效
    仿真不跳转分频系数错误重新计算100 MHz→1 kHz分频值
    LED闪烁过快分频系数偏小增大分频系数至100,000

    附录D:设计原理说明

    交通灯控制本质上是一个时序逻辑问题。有限状态机(FSM)提供了清晰的状态转换图,易于理解、调试和修改。相比纯计数器加组合逻辑,FSM降低了逻辑复杂度,且便于添加紧急模式、行人按钮等扩展。本设计采用one-hot编码,每个状态对应一个触发器,译码逻辑简单,组合路径短,适合速度要求高的设计。系统时钟为100 MHz,通过计数器分频产生1 kHz的基准时钟(tick信号),用于状态计时,避免直接分频时钟带来的跨时钟域问题。

    标签:
    本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
    如需转载,请注明出处:https://z.shaonianxue.cn/38086.html
    二牛学FPGA

    二牛学FPGA

    初级工程师
    这家伙真懒,几个字都不愿写!
    72517.69W3.94W3.67W
    分享:
    成电国芯FPGA赛事课即将上线
    FPGA学习误区盘点:新手常见踩坑与避坑指南
    FPGA学习误区盘点:新手常见踩坑与避坑指南上一篇
    FPGA竞赛高分实践:系统架构设计与调试策略指南下一篇
    FPGA竞赛高分实践:系统架构设计与调试策略指南
    相关文章
    总数:744
    单片机转FPGA|90%的人都栽在这4个致命误区,避开少走半年弯路

    单片机转FPGA|90%的人都栽在这4个致命误区,避开少走半年弯路

    在嵌入式开发领域,单片机是很多工程师的入门起点,不少单片机开发者在积累一…
    技术分享
    1个月前
    0
    0
    444
    1
    2026年全球半导体产能扩张计划盘点:技术路径分析与实施指南

    2026年全球半导体产能扩张计划盘点:技术路径分析与实施指南

    QuickStart:快速了解2026年产能扩张全貌2026年,全球半…
    技术分享
    2天前
    0
    0
    11
    0
    Verilog 组合逻辑与时序逻辑划分实践指南

    Verilog 组合逻辑与时序逻辑划分实践指南

    QuickStart打开Vivado(或Quartus),创建新工…
    技术分享
    1天前
    0
    0
    8
    0
    评论表单游客 您好,欢迎参与讨论。
    加载中…
    评论列表
    总数:0
    FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
    没有相关内容