状态机思想编程练习

状态机实现LED流水灯

本次实验,我们将利用状态机的思想来进行Verilog编程实现一个LED流水灯,并通过Modelsim来进行模拟仿真,再到DE2-115开发板上进行验证。 ​ 首先进行主要代码的编写。

复制代码
 module led (
     input        sys_clk,
     input        sys_rst_n,
     output reg [7:0] led
 );
 ​
 // 状态定义(8个状态)
 parameter S0 = 3'd0,
           S1 = 3'd1,
           S2 = 3'd2,
           S3 = 3'd3,
           S4 = 3'd4,
           S5 = 3'd5,
           S6 = 3'd6,
           S7 = 3'd7;
 ​
 parameter MAX_COUNT = 25_000_000; // 0.5秒@50MHz
 ​
 reg [2:0] current_state;    // 当前状态寄存器
 reg [2:0] next_state;       // 下一状态寄存器
 reg [25:0] counter;         // 26位定时计数器
 ​
 // 状态寄存器
 always @(posedge sys_clk or negedge sys_rst_n) begin
     if (!sys_rst_n)
         current_state <= S0;                // 异步复位
     else        
         current_state <= next_state;    // 正常状态转移
 end
 ​
 // 计数器逻辑
 always @(posedge sys_clk or negedge sys_rst_n) begin
     if (!sys_rst_n)
         counter <= 0;       // 复位清零
     else if (current_state != next_state)
         counter <= 0;       // 状态切换时清零
     else
         counter <= counter + 1;
 end
 ​
 // 状态转移逻辑
 always @(*) begin
     case (current_state)
         S0: next_state = (counter == MAX_COUNT-1) ? S1 : S0;
         S1: next_state = (counter == MAX_COUNT-1) ? S2 : S1;
         S2: next_state = (counter == MAX_COUNT-1) ? S3 : S2;
         S3: next_state = (counter == MAX_COUNT-1) ? S4 : S3;
         S4: next_state = (counter == MAX_COUNT-1) ? S5 : S4;
         S5: next_state = (counter == MAX_COUNT-1) ? S6 : S5;
         S6: next_state = (counter == MAX_COUNT-1) ? S7 : S6;
         S7: next_state = (counter == MAX_COUNT-1) ? S0 : S7;
         default: next_state = S0;
     endcase
 end
 ​
 // 输出逻辑(循环右移模式)
 always @(*) begin
     case (current_state)
         S0: led = 8'b00000001;
         S1: led = 8'b00000010;
         S2: led = 8'b00000100;
         S3: led = 8'b00001000;
         S4: led = 8'b00010000;
         S5: led = 8'b00100000;
         S6: led = 8'b01000000;
         S7: led = 8'b10000000;
         default: led = 8'b00000001;
     endcase
 end
 ​
 endmodule

然后为了能在Modelsim中进行模拟仿真,我们还需要编写一个测试模块代码。

复制代码
 `timescale 1ns/1ps
 ​
 module tb_led();
 ​
 reg sys_clk;
 reg sys_rst_n;
 wire [7:0] led;
 ​
 // 实例化被测试模块(缩小计数器值便于仿真)
 led_fsm_8bit #(.MAX_COUNT(3)) uut (
     .sys_clk(sys_clk),
     .sys_rst_n(sys_rst_n),
     .led(led)
 );
 ​
 // 生成50MHz时钟
 initial begin
     sys_clk = 0;
     forever #10 sys_clk = ~sys_clk;  // 20ns周期=50MHz
 end
 ​
 // 测试流程控制
 initial begin
     // 初始化
     sys_rst_n = 0;
     #20;                    // 等待一个时钟上升沿
     sys_rst_n = 1;
     
     // 运行2000ns(观察完整状态周期)
     #2000;
     $finish;
 end
 ​
 // 监控输出
 initial begin
     $monitor("Time = %tns | State = %d | LED = %08b",
              $time, uut.current_state, led);
 end
 ​
 endmodule

编写完测试代码并成功编译后,就可以准备进行模拟仿真了,首先对仿真文件进行绑定,选择Setting-->EDA Tool Settings-->Simulation。

然后就可以进行模拟仿真了。

仿真完成后,进行DE2-115开发板的实物验证。首先对管脚进行配置。

把程序烧录到开发板,就可以看到效果。

CPLD和FPGA

对比维度 CPLD FPGA
核心架构 基于乘积项(Product-Term)和宏单元(Macrocell),结构简单,逻辑资源有限 基于查找表(LUT)和寄存器,逻辑单元(LE)灵活组合,资源丰富
存储技术 采用EEPROM或Flash工艺,非易失性,无需外部配置芯片 基于SRAM工艺,掉电丢失配置数据,需外部存储器
资源规模 逻辑单元较少(几十至几百宏单元),适合小规模逻辑设计 逻辑单元可达数百万级,支持大规模复杂设计
时序特性 连续式布线,延迟均匀且可预测 分段式布线,延迟不可预测
功耗 静态功耗较高,适合低复杂度场景 动态功耗优化更好,适合高性能计算
编程灵活性 编程次数有限(约1万次),逻辑固化后不可重构 支持无限次动态重构,灵活适配不同算法
启动时间 上电即用,无需配置时间 需从外部加载配置数据,存在启动延迟

CPLD的典型应用场景:简单逻辑控制比如状态机、地址译码、总线控制等组合逻辑密集型任务;某些接口的转换,比如电平转换(TTL与LVDS)、I/O扩展、协议适配(SPI转UART);胶合逻辑,这在复杂系统中作为"粘合剂",可以连接不同功能模块(DSP与存储器间的控制逻辑);低功耗需求场景比如工业控制、仪器仪表中的简单逻辑处理。 ​

FPGA的典型应用场景:复杂时序逻辑比如如高速数据处理(通信协议处理、雷达信号处理)、实时控制(自动驾驶传感器融合);并行计算加速:数字信号处理(DSP)、AI推理、图像处理(ISP算法加速);动态重构系统,常用于需要硬件功能随需求变化的场景(软件定义无线电);高性能计算如数据中心加速、加密解密、科学仿真等对算力要求高的领域。 ​

从设计复杂度上看,CPLD适用于门数小于1万的设计,FPGA更适合大规模设计(>10万门)。从时序要求上看,CPLD延迟可预测,适合实时性强的控制逻辑;FPGA虽延迟不可预测,但通过时序约束优化可实现高频运行(如500MHz以上)。从功耗与成本上看,CPLD成本低但功耗较高,FPGA能效比更优但需要额外配置芯片。从技术融合趋势上看,现代CPLD(如Altera MAX系列)逐渐采用FPGA的LUT架构,界限模糊,但核心差异仍存在。

hdlbitsFPGA组合逻辑练习

D触发器

D锁存器

Two gates

计数器1-12

简单电路A

总结

本次实验通过状态机设计方法,成功实现了LED流水灯的Verilog编程,并在Modelsim中进行了仿真验证,最终在DE2-115开发板上进行了实物验证。此外,通过对CPLD和FPGA的对比分析,进一步加深了对这两种器件的理解,为今后的设计提供了参考。

相关推荐
shock - shock8 小时前
基于高云fpga实现的fir串行滤波器
fpga开发
落笔太慌张~11 小时前
【FPGA基础学习】状态机思想实现流水灯
学习·fpga开发
一瓶勇闯天涯的雪花11 小时前
FPGA入门学习Day0——状态机相关内容解析HDLbits练习
fpga开发
2202_7544215411 小时前
设计一个UART接口的AXI_LITE_MASTER之一 总体介绍
fpga开发
Abcdsa12 小时前
labview RT FPGA学习心得
fpga开发·labview
肯德基疯狂星期四-V我501 天前
【FPGA】状态机思想实现LED流水灯&HDLbits组合逻辑题训练
fpga开发·verilog·de2-115
乌恩大侠1 天前
【调研】YOLO算法在FPGA/ZYNQ上的部署与加速
yolo·fpga开发
Abcdsa1 天前
labview RT FPGA使用技巧 基础知识
fpga开发·labview
暴富奥利奥2 天前
FPGA学习(四)——状态机重写LED流水灯并仿真
学习·fpga开发