首页 > 其他分享 >三种状态机的区别?

三种状态机的区别?

时间:2022-09-01 14:56:40浏览次数:52  
标签:区别 always 状态机 localparam 三种 rst input reg

状态机的写法可以分为以下几种:

一段式:最主要的特征是只有一个always块。在这个always块内既描述状态转移,又含有组合逻辑输入/输出,当前状态用寄存器输出;在这种状态机的写法中,组合逻辑电路和时序逻辑电路都在一起,没有分开;因此这种写法增加了代码的复杂度且不利于代码的维护和修改,同时也不利于后期约束;

两段式:最主要的特征是有两个always块,将组合逻辑和时序逻辑分开。其中一个always块采用同步时序描述状态转移,而另一个always块采用组合逻辑来判断状态转移的条件,描述状态转移规律及输出;在这种写法下,需要定义两个状态,分别是现态和次态,通过现态和次态的转换来实现状态转移;两段式状态机可以清晰完整的显示出状态机的结构,有利于代码的维护和后期修改,同时也降低编写复杂度;

三段式:最主要的特征是有三个always块。区别于两段式状态机的关键在于两段式状态机直接采用组合逻辑输出,而三段式状态机则通过在组合逻辑后再增加一级寄存器实现逻辑输出——即一个always块采用同步时序描述状态转移,一个always块采用组合逻辑判断转移条件、转移状态规律,最后一个always块采用同步时序描述状态的输出;这种三段式状态机的写法代码非常清晰,极大降低了编写维护代码的复杂度,最大程度清晰完整的显示出状态机的结构。同时可以有效地滤除两段式状态机组合逻辑输出可能产生的毛刺信号;另外对于总线形式的输出来说,容易使总线数据对齐,从而减小总线数据间的偏移,减小接收端数据采样出错的频率;但是代码量会长一些哦OvO

下面是以上介绍的三种状态机在下面这种状态转移图下的代码

module simple(
    input clk,
    input rst_n,
    input w,
    output reg[1:0] z
);

localparam A = 2'b00;
localparam B = 2'b01;
localparam C = 2'b10;

reg [1:0] state;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= A;
        z <= 0;
    end
    else
    case (state)
        A:
        begin
            if (w) begin
                state <= B;
                z <= 2'd1;
            end
            else begin
                state <= A;
                z <= 2'd0;
            end
        end 
        B:
        begin
            if (w) begin
                state <= C;
                z <= 2'd2;
            end
            else begin
                state <= A;
                z <= 2'd1;
            end
        end
        C:
        begin
            if (w) begin
                state <= C;
                z <= 2'd2;
            end
            else begin
                state <= A;
                z <= 2'd0;
            end
        end
        default: 
        begin
            state <= A;
            z <= 2'd0;
        end
    endcase
end
endmodule

两段式状态机代码:

module simple(
    input clk,
    input rst_n,
    input w,
    output reg[1:0] z
);

localparam A = 2'b00;
localparam B = 2'b01;
localparam C = 2'b10;

reg [1:0] current_state;
reg [1:0] next_state;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        current_state <= A;
    end
    else 
        current_state <= next_state;
end

always @(*) begin
    case (current_state)
        A:
        begin
            if (w) begin
                next_state = B;
                z = 2'd1;
            end
            else begin
                next_state = A;
                z = 2'd0;
            end
        end 
        B:
        begin
            if (w) begin
                next_state = C;
                z = 2'd2;
            end
            else begin
                next_state <= A;
                z = 2'd1;
            end
        end
        C:
        begin
            if (w) begin
                next_state = C;
                z = 2'd2;
            end
            else begin
                next_state = A;
                z = 2'd0;
            end
        end
        default: 
        begin
            next_state = A;
            z = 2'd0;
        end
    endcase
end
endmodule

三段式状态机代码:

module simple(
    input clk,
    input rst_n,
    input w,
    output reg[1:0] z
);

localparam A = 2'b00;
localparam B = 2'b01;
localparam C = 2'b10;

reg [1:0] current_state;
reg [1:0] next_state;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        current_state <= A;
    end
    else 
        current_state <= next_state;
end

always @(*) begin
    case (current_state)
        A:
        begin
            if (w) begin
                next_state = B;
            end
            else begin
                next_state = A;
            end
        end 
        B:
        begin
            if (w) begin
                next_state = C;
            end
            else begin
                next_state <= A;
            end
        end
        C:
        begin
            if (w) begin
                next_state = C;
            end
            else begin
                next_state = A;
            end
        end
        default: 
        begin
            next_state = A;
        end
    endcase
end
always @(posedge clk or negedge rst_n) begin
    if (rst_n) begin
        z <= 2'd0;
    end
    else begin
        case (next_state)
            A: z <= 2'd0;
            B: z <= 2'd1;
            C: z <= 2'd2;
            default: z <= 2'd0;
        endcase
    end
end

endmodule

转自:https://zhuanlan.zhihu.com/p/431143109

标签:区别,always,状态机,localparam,三种,rst,input,reg
From: https://www.cnblogs.com/amxiang/p/16646484.html

相关文章

  • HTTP HTTPS区别
    一:HTTP与HTTPS有哪些区别?(1)HTTP是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS则解决HTTP不安全的缺陷,在TCP和HTTP网络层之间加入了SSL/TLS安全协......
  • python kafka 生产者发送数据的三种方式
    发送方式同步发送发送数据耗时最长有发送数据的状态,不会丢失数据,数据可靠性高以同步的方式发送消息时,一条一条的发送,对每条消息返回的结果判断,可以明确地知道每......
  • JS缓存三种方法
    1.sessionStorage:临时的会话存储只要当前的会话窗口未关闭,存储的信息就不会丢失,即便刷新了页面,或者在编辑器中更改了代码,存储的会话信息也不会丢失。2.localStor......
  • 【IO复用】epoll和select以及poll的区别
    select原理说在前面,整个select在内核空间中的工作事实上非常有趣,中间还会穿插一些可抢占点,检测当前是否有进程可以调度,增加系统的实时性初始化阶段:FD_set,把要监听的fd都......
  • delete和truncate删除的区别
    delete: (1)一行一行的把数据删除,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。 (2)delete是数据操作语言(DML)命令。 (3)delete命令不会影响表结构tr......
  • spring三种注入方式
    构造器注入@AutowiredpublicAService(BServicebService){this.bService=bService;}set注入(重点)AServiceaService;@Autowiredpu......
  • NMOS与PMOS区别
    在CMOS设计里,PMOS管和NMOS管同等重要,不过因为一般的电路设计书籍都注重NMOS管的讲解,PMOS都是直接类比NMOS,所以让人不太清楚PMOS的工作原理。1.端口不同PMOS和NMOS的源漏......
  • Hive中insert into 和 insert overwrite的区别
    相同点insertinto和insertoverwrite都是往表中插入数据的。 不同点区别1:insertinto:其实是将数据追加到表的末尾,注意可不是覆盖是追加。insertoverwrite......
  • 【C++】引用与指针的区别
    安全性首先引用要比指针要安全,因为引用不能更改绑定,但是指针可以更改指向,此外指针可以有多级,但是引用一般只有一级。在使用指针的时候,我们往往需要使用断言,判断指针是不是......
  • verilog 中的三段式状态机
    抄的:https://zhuanlan.zhihu.com/p/431143109一段式状态机特点:最主要的特征是只有一个always块。在这个always块内既描述状态转移,又含有组合逻辑输入/输出,当前状态用......