基础知识~ 状态机的定义及Verilog代码实现

MEALY/MOORE 状态机

定义:

Moore (摩尔)型状态机:输出只由当前状态决定,即次态=f(现状,输入),输出=f(现状);
Mealy (米粒)型状态机:输出不但与当前状态有关,还与当前输入值有关,即次态=f(现状,输入),
输出=f(现状,输入);

二者的不同点:

  1. Moore 型状态机的输出信号是直接由状态寄存器译码得到,而 Mealy 型状态机则是以 现时的输入信号 结合 即将变成次态的现态,编码成输出信号。
  2. Mooer 状态机的输出只与当前的状态有关,也就是当前的状态决定输出,而与此时的输入无关,输入只决定状态机的状态改变,不影响电路最终的输出。(注意:这里所说的输出不是状态机的状态输出,而是当前状态的所代表的含义,比如:检测 110 序列的状态机,当状态机跳转到 STA_GOT110 时,电路会有一个输出信号,假如说是 find,此时 find就会为高电平,其他状态时 find 就会为低电平。find 是我们最后电路的输出,find 的值只与我们的状态机当前所处的状态有关,而与输入无关)。
    Mealy 状态机的输出不仅与当前的状态有关,还与当前的输入有关(同样,不要误认为状态机的输出只能是状态机的状态),即当前的输入和当前的状态共同决定当前的输入。

有限状态机 FSM 设计

描述方式:

状态机描述时关键是要描述清楚几个状态机的要素,即如何进行状态转移,每个状态的输出是什么,状态转移的条件等。具体描述时方法各种各样,最常见的有三种描述方式:
(1)一段式:整个状态机写到一个 always 模块里面,在该模块中既描述状态转移,又描述状态的输入和输出;
(2)二段式:用两个 always 模块来描述状态机,其中一个 always 模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出;
(3)三段式:在两个 always 模块描述方法基础上,使用三个 always 模块,一个 always 模块采用同步时序描述状态转移,一个 always 采用组合逻辑判断状态转移条件,描述状态转移规律,另一个 always 模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。

三段式状态机示例模板:

//第一个进程,同步时序 always 模块,格式化描述次态寄存器迁移到现态寄存器
always @ (posedge clk or negedge rst_n) //异步复位
if(!rst_n)
 current_state <= IDLE;
else
 current_state <= next_state; //注意,使用的是非阻塞赋值
 
//第二个进程,组合逻辑 always 模块,描述状态转移条件判断
always @ (current_state) //电平触发,现存状态为敏感信号
begin
 next_state = x; //要初始化,使得系统复位后能进入正确的状态
case(current_state)
 S1: if(...)
  next_state = S2; //阻塞赋值
 S2: if(...)
 next_state = S3; //阻塞赋值
……
endcase
end

//第三个进程,同步时序 always 模块,格式化描述次态寄存器输出
always @ (posedge clk or negedge rst_n)
begin
...//初始化
case(next_state)
 S1:
 out1 <= 1'b1; //注意是非阻塞逻辑
 S2:
 out2 <= 1'b1;
 default:... //default 的作用是免除综合工具综合出锁存器
endcase
end

现学现卖:

VL21 根据状态转移表实现时序电路

代码如下:

`timescale 1ns/1ns

module seq_circuit(
      input                A   ,
      input                clk ,
      input                rst_n,
 
      output   wire        Y   
);
    
    reg [1:0] cur_state;
    reg [1:0] nex_state;
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)
            cur_state <= 2'b00; //复位
        else
            cur_state <= nex_state; //次态 给 现态
    end
    
    always @ (*) begin
        case (cur_state)
            2'b00 : nex_state = (A == 1'b0) ? 2'b01 : 2'b11;
            2'b01 : nex_state = (A == 1'b0) ? 2'b10 : 2'b00;
            2'b10 : nex_state = (A == 1'b0) ? 2'b11 : 2'b01;
            2'b11 : nex_state = (A == 1'b0) ? 2'b00 : 2'b10;
            default : nex_state = 2'b00;
        endcase
    end

//     reg Y_wire;
//     always @ (posedge clk or negedge rst_n) begin
//         if(!rst_n)
//             Y_wire <= 1'b0;
//         else
//             if(nex_state == 2'b11)
//                 Y_wire <= 1'b1;    
//     end
    assign Y = (cur_state == 2'b11) ? 1'b1 : 1'b0;
    
endmodule

VL22 根据状态转移图实现时序电路

代码如下:

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   
);
    
    reg [1:0] cur_state, nex_state;
    
    parameter state0 = 2'b00;
    parameter state1 = 2'b01;
    parameter state2 = 2'b10;
    parameter state3 = 2'b11;
    
    always @ (posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                cur_state <= state0;
            else
                cur_state <= nex_state;
        end
    
    always @ (*)
        begin
            case(cur_state)
                state0 : nex_state = (C == 1'b0) ? state0 : state1;
                state1 : nex_state = (C == 1'b0) ? state3 : state1;
                state2 : nex_state = (C == 1'b0) ? state0 : state2;
                state3 : nex_state = (C == 1'b0) ? state3 : state2;
                default : nex_state = state0;
            endcase
        end

    assign Y = (cur_state == state3 | (cur_state == state2 & C == 1'b1)) ? 1'b1 : 1'b0;
endmodule
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Verilog是一种硬件描述语言(HDL),用于描述数字系统的行为和结构。它广泛应用于数字电路设计、验证和仿真领域。以下是一些Verilog基础知识: 1. 模块(Module):Verilog代码由一个或多个模块组成,模块是Verilog的基本单元。每个模块都有输入和输出端口,以及内部的逻辑实现。 2. 端口(Port):模块的输入和输出被定义为端口。端口可以是输入(input)、输出(output)或双向(inout)类型。 3. 信号(Signal):信号是在模块内部定义的变量,用于存储和传递数据。信号可以是单比特或多比特的。 4. 运算符(Operator):Verilog支持多种运算符,包括算术运算符、逻辑运算符、位运算符等。 5. 时钟(Clock):在数字电路,时钟被用于同步各个部件的操作。Verilog的时钟通常使用一个时钟信号来表示。 6. 时序建模(Sequential Modeling):Verilog可以用于描述时序逻辑,包括寄存器、时序电路等。通过使用不同的关键字和语法,可以实现状态机、计数器等复杂的时序逻辑。 7. 组合逻辑建模(Combinational Modeling):Verilog也可以用于描述组合逻辑,例如门电路、多路复用器等。组合逻辑没有状态,输出仅依赖于当前输入。 8. 仿真(Simulation):Verilog代码可以通过仿真工具进行功能验证和性能分析。仿真工具可以模拟电路的行为,使设计者能够验证其功能和正确性。 这些是Verilog的一些基础知识,希望对你有所帮助!如果你有更具体的问题,欢迎提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值