HDLbits答案更新系列11(3.2 Sequential Logic 3.2.5 Finite State Machines 3.2.5.1 Simple FSM 1等)

目录

前言

3.2.5 Finite State Machines

3.2.5.1 Simple FSM 1(asynchronous reset)

3.2.5.2 Simple FSM 1(synchronous reset)

3.2.5.3 Simple FSM 2(asynchronous reset)

3.2.5.4 Simple FSM 2(synchronous reset)

结语

HDLbits网站链接


前言

今天终于来到了数字IC设计的另一个重要部分:状态机。对于这部分内容,我可能不会一次更新一个小节,一是因为代码量,二是因为状态机这个小节内容太多了,博主在完成这部分内容时也不是每道题目都很容易就解决了,有几道题目需要深入讲解,所以更新会慢一些,还请大家见谅。当然如果大家有不同的解法,欢迎大家留言~

3.2.5 Finite State Machines

3.2.5.1 Simple FSM 1(asynchronous reset)

module top_module(
    input clk,
    input areset,    // Asynchronous reset to state B
    input in,
    output reg out);//  

    parameter A=1'b0, B=1'b1; 
    reg current_state, next_state;
    
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            current_state <= B;
        end
        else begin
            current_state <= next_state;
        end
    end

    always@(*)begin
        case(current_state)
            B:begin
                if(in == 1'b1)begin
                    next_state = B;
                end
                else begin
                    next_state = A;
                end
            end
            A:begin
                if(in == 1'b1)begin
                    next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
        endcase
    end
    
    //combinational logic way
    always@(*)begin 
        if(current_state == B)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end
    
    /*
    //second way
    //assign out = (current_state == B);
    */
    
    /*
    //third way
    always@(*)begin
        case(current_state)
            B:begin
                out = 1'b1;
            end
            A:begin
                out = 1'b0;
            end
        endcase
    end
    */    
    
    /*
    //forth way
    //sequential logic way
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            out <= 1'b1;
        end
        else if(next_state == B)begin
            out <= 1'b1;
        end
        else begin
            out <= 1'b0;
        end
    end
    */
    
endmodule

第一题根据状态转移图写代码,这道题目博主给出了四种输出写法,前三种是用组合逻辑输出,最后一种是用时序逻辑输出。注意这道题目时序逻辑复位时的out是状态B。

这里大家一定要明白,虽然从代码结构上来说,这四种方式都可以算作三段式状态机,但是从电路设计的角度来说,只有第四种算是三段式状态机。

两段式状态机的第一个进程是格式化描述次态到现态的转移(即current_state <= next_state),第二个进程是纯组合逻辑描述状态转移条件(即case(current_state)),最后使用组合逻辑对current_state进行判断得到输出结果。

三段式状态机的第一个进程是格式化描述次态到现态的转移(即current_state <= next_state),第二个进程是纯组合逻辑描述状态转移条件(即case(current_state)),第三个进程是使用时序逻辑得到输出结果,注意这里判断的是next_state。

两段式状态机代码简单直观,但是组合逻辑易产生毛刺等不稳定因素,如果电路能够允许一个多余的时序节拍,那么两段式状态机采用寄存器输出是很好的。三段式状态机采用寄存器输出,可以避免毛刺,改善时序条件,但是三段式状态机分割了两部分组合逻辑(状态转移条件组合逻辑和输出组合逻辑),因此这条路径的时序相对紧张。博主个人还是建议大家使用三段式状态机。由于两段式状态机更为简洁,博主为了快速完成题目,后面的题目也使用了较多的两段式状态机,实际应用中还是用三段式多一些。

总之,这两种写法都是博主建议的写法。

3.2.5.2 Simple FSM 1(synchronous reset)

// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
    input clk;
    input reset;    // Synchronous reset to state B
    input in;
    output out;//  
    reg out;

    parameter A = 1'b0;
    parameter B = 1'b1;

    reg current_state, next_state;
    
    always@(posedge clk)begin
        if(reset)begin
            current_state <= B;
        end
        else begin
            current_state <= next_state;
        end
    end
    
    always@(*)begin
        case(current_state)
            B:begin
                if(in == 1'b1)begin
                    next_state = B;
                end
                else begin
                    next_state = A;
                end
            end
            A:begin
                if(in == 1'b1)begin
                    next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
        endcase
    end
    
    always@(*)begin
        if(current_state == B)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end


endmodule

这道题目和第一道题目差不多,只是复位换成了同步复位。

3.2.5.3 Simple FSM 2(asynchronous reset)

module top_module(
    input clk,
    input areset,    // Asynchronous reset to OFF
    input j,
    input k,
    output out); //  

    parameter OFF = 1'b0, ON = 1'b1; 
    reg current_state, next_state;

    always@(posedge clk or posedge areset)begin
        if(areset)begin
            current_state <= OFF;
        end
        else begin
            current_state <= next_state;
        end
    end
    
    always@(*)begin
        case(current_state)
            OFF:begin
                if(j == 1'b1)begin
                    next_state = ON;
                end
                else begin
                    next_state = OFF;
                end
            end
            ON:begin
                if(k == 1'b1)begin
                    next_state = OFF;
                end
                else begin
                    next_state = ON;
                end
            end
        endcase
    end
    
    always@(*)begin
        if(current_state == ON)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end            

endmodule

这道题目有相比前两道题目多了一个输入,其他没有太多差别。

3.2.5.4 Simple FSM 2(synchronous reset)

module top_module(
    input clk,
    input reset,    // Synchronous reset to OFF
    input j,
    input k,
    output out); //  

    parameter OFF = 1'b0, ON = 1'b1; 
    reg current_state, next_state;

    always@(posedge clk)begin
        if(reset)begin
            current_state <= OFF;
        end
        else begin
            current_state <= next_state;
        end
    end
    
    always@(*)begin
        case(current_state)
            OFF:begin
                if(j == 1'b1)begin
                    next_state = ON;
                end
                else begin
                    next_state = OFF;
                end
            end
            ON:begin
                if(k == 1'b1)begin
                    next_state = OFF;
                end
                else begin
                    next_state = ON;
                end
            end
        endcase
    end
    
    always@(*)begin
        if(current_state == ON)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end

endmodule

这道题目相比上一道题目,异步复位变成了同步复位,别的没什么区别。

结语

今天先更新这四道题目,这四道题目是最基础的状态机题目,没有什么特别大的难度,重点是清楚两段式状态机和三段式状态机的异同点,仅从结构考虑(广义上),博主在题目3.2.5.1中的四种写法都属于三段式状态机,但是从电路设计的角度来说,只有第四种写法属于三段式状态机,希望大家能够弄清楚这一点。

如果代码有错误的地方希望大家可以提醒我,我一定尽快改正。

HDLbits网站链接

https://hdlbits.01xz.net/wiki/Main_Page

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值