状态机思想编程

文章目录


一、状态机思想重新写一个 LED流水灯的FPGA代码

1.状态机的概念

状态机的基本要素有 3 个,其实我们在第一节的举例中都有涉及,只是没有点明,它们是:状态、输出和输入。

1、状态:也叫状态变量。在逻辑设计中,使用状态划分逻辑顺序和时序规律。比如:设计伪随机码发生器时,可以用移位寄存器序列作为状态;在设计电机控制电路时,可以以电机的不同转速作为状态;在设计通信系统时,可以用信令的状态作为状态变量等。

2、输出:输出指在某一个状态时特定发生的事件。如设计电机控制电路中,如果电机转速过高,则输出为转速过高报警,也可以伴随减速指令或降温措施等。

3、输入:指状态机中进入每个状态的条件,有的状态机没有输入条件,其中的状态转移较为简单,有的状态机有输入条件,当某个输入条件存在时才能转移到相应的状态。

根据状态机的输出是否与输入条件相关,可将状态机分为两大类:摩尔(Moore)型状态机和米勒(Mealy)型状态机。

2.代码设计

bash 复制代码
// 流水灯模块代码:led_fsm.v
module led_fsm(
    input        clk,     // 时钟信号 (50MHz)
    input        rst_n,   // 复位信号 (低有效)
    output reg [3:0] led  // LED输出,低电平点亮
);

// 定义状态编码
parameter S0 = 2'b00;    // LED0亮
parameter S1 = 2'b01;    // LED1亮
parameter S2 = 2'b10;    // LED2亮
parameter S3 = 2'b11;    // LED3亮

reg [1:0] state;         // 当前状态
reg [1:0] next_state;    // 下一状态
reg [24:0] counter;      // 计时器(0.5秒@50MHz)

// 状态寄存器
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        state <= S0;
    else
        state <= next_state;
end

// 状态转移逻辑
always @(*) begin
    case(state)
        S0: next_state = (counter == 25'd24_999_999) ? S1 : S0;
        S1: next_state = (counter == 25'd24_999_999) ? S2 : S1;
        S2: next_state = (counter == 25'd24_999_999) ? S3 : S2;
        S3: next_state = (counter == 25'd24_999_999) ? S0 : S3;
        default: next_state = S0;
    endcase
end

// 计数器逻辑
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        counter <= 25'd0;
    else if(next_state != state)
        counter <= 25'd0;
    else
        counter <= counter + 25'd1;
end

// 输出逻辑
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        led <= 4'b1110;  // 初始状态LED0亮
    else begin
        case(state)
            S0: led <= 4'b1110;
            S1: led <= 4'b1101;
            S2: led <= 4'b1011;
            S3: led <= 4'b0111;
            default: led <= 4'b1111;
        endcase
    end
end

endmodule

代码解释:

使用 二进制编码(2位可表示4个状态)。每个状态对应一个LED点亮(S0→LED0,S1→LED1,依此类推)。

state 和 next_state 用于实现状态寄存器和组合逻辑的分离。

计数器阈值:24_999_999 对应 0.5 秒计时(50MHz时钟下,周期20ns,总时间=25,000,000×20ns=500ms)。

状态转移条件:当计数器达到阈值时切换到下一状态,否则保持当前状态。

复位清零:复位或状态即将切换时计数器清零。连续计数:在状态保持期间,每个时钟周期加1。低电平有效:0 表示点亮LED(例如 4'b1110 表示LED0亮)。同步输出:在时钟上升沿更新输出,避免毛刺。

二、CPLD和FPGA芯片的主要技术区别与适用场合

二、适用场合

CPLD 的典型应用

1.控制密集型任务

状态机、总线接口控制(如PCI、I2C)、逻辑粘合(Glue Logic)。简单数据处理(编码转换、电平转换)。

2.实时性与可靠性要求高的场景

工业控制、电源管理、电机驱动。需要快速上电启动(毫秒级配置加载)。

3.低功耗与成本敏感设计

便携设备、加密芯片控制、简单协议转换。

FPGA 的典型应用

1.数据密集型任务

高速信号处理(图像处理、通信基带)、数字滤波器、FFT。并行计算(AI加速、区块链哈希运算)。

2.复杂系统原型与动态重构

ASIC/SoC原型验证、软件定义无线电(SDR)。支持部分动态重配置(如Xilinx的部分型号)。

3.高吞吐量接口

高速串行通信(PCIe、10G以太网)、视频编解码(H.265/AV1)。数据中心加速(SmartNIC、存储控制器)。

三、hdlbitsFPGA教程网站上进行学习

1.创建一个具有两个 2 位输入A1:0和B1:0的电路,并产生一个输出z。如果A = B ,则z的值应为 1 ,否则z应为 0。

bash 复制代码
module top_module ( input [1:0] A, input [1:0] B, output z ); 
    assign z = (A ==B) ? 1'B1 : 1'B0;
endmodule

2.创建一个半加法器。半加器将两位相加(没有进位)得到加和和进位。

bash 复制代码
module top_module( 
    input a, b,
    output cout, sum );
	assign sum = a^b;
    assign cout = a&b;
endmodule

3.创建一个全加器。全加器将三位相加(包括进位)并产生和和进位。

bash 复制代码
module top_module( 
    input a, b, cin,
    output cout, sum );
    assign sum = a^b^cin;
    assign cout = a&b | a&cin | b&cin;
endmodule

4.创建 3 个实例来创建一个 3 位二进制波纹进位加法器。加法器将两个 3 位数字和一个进位相加产生一个 3 位加和和进位。为了鼓励实例化全加器,还要输出纹波进位加法器中每个全加器的进位。cout2 是最后一个全加器的最终进位,也是您通常看到的进位。

bash 复制代码
//第一种方法
module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
    add1 u1 (.a(a[0]),.b(b[0]),.cin(cin),.sum(sum[0]),.cout(cout[0]));
    add1 u2 (.a(a[1]),.b(b[1]),.cin(cout[0]),.sum(sum[1]),.cout(cout[1]));
    add1 u3 (.a(a[2]),.b(b[2]),.cin(cout[1]),.sum(sum[2]),.cout(cout[2]));
endmodule
 
module add1 ( input a, input b, input cin,   output sum, output cout );
	assign sum = a^b^cin;
    assign cout = a&b|a&cin|b&cin;
endmodule

5.假设您有两个 8 位 的补码,a7:0 和 b7:0。这些数字相加产生 s7:0。还要计算是否发生了(有符号的)溢出。

bash 复制代码
module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); 
    assign s = a+b;
    assign overflow = (a[7]&b[7]&~s[7])|(~a[7]&~b[7]&s[7]);
endmodule
相关推荐
坏孩子的诺亚方舟3 天前
FPGA系统架构设计实践15_高云Arora V系列时钟体系
fpga开发·系统架构
FPGA小徐4 天前
入门 CNN 结构全解析|从流程图理论到 FPGA Verilog 硬件实现(含习题带讲解)
fpga开发
FPGA小徐4 天前
FPGA 数字信号处理:并行 FIR 与串行滤波器设计原理、对比与完整 Verilog 实现
fpga开发
Saniffer_SH5 天前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
zlinear数据采集卡5 天前
双核架构深度解析:ARM+FPGA如何让数据采集卡实现500Ksps高性能?
arm开发·fpga开发·架构
9527华安5 天前
FPGA实现GTH Transceivers Wizard传输2路视频,基于aurora 8b10b编解码架构,提供4套工程源码和技术支持
fpga开发·gth·aurora 8b10b·transceivers
FPGA小徐6 天前
FPGA 数字信号处理(二):并行 FIR 滤波器的 Verilog 全流程设计与实现
fpga开发
国科安芯6 天前
基于AS32S601ZIT2型抗辐照MCU的商业航天卫星姿态确定与控制系统研究
单片机·嵌入式硬件·安全·fpga开发·架构·risc-v
ALINX技术博客6 天前
【黑金云课堂】FPGA技术教程FPGA基础:I2C 总线通信技术
fpga开发·i2c
Hello-FPGA6 天前
Xilinx KU040 FPGA Camera Link 图像采集
c++·fpga开发