牛客刷题<22>根据状态转移图实现时序电路

题目:根据状态转移图实现时序电路_牛客题霸_牛客网

解法一:

本题提供的是状态转换图,可采用状态机实现,也可采用列激励方程、输出方程,进而用D触发器和组合逻辑电路实现。本题解采用第二种方案实现。

由状态转换图可得出,电路共4个状态,所以使用2个寄存器来实现状态的寄存。两个寄存器的输出为Q1和Q0,两个寄存器的输入为D1和D0。

 

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   
);
    reg q1;
    reg q0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            q1 <= 1'b0;
        else
            q1 <= (q1 & (q0 | C)) | (~q1 & q0 & ~C);
    end
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            q0 <= 1'b0;
        else
            q0 <= (~q1 & (q0 | C)) | (q1 & q0 & ~C);
    end
    assign Y = (C & q1) | (q1 & q0);
endmodule

解法二:三段式状态机

第一段,时序逻辑实现状态转移

第二段,组合逻辑实现状态跳转

第三段,组合逻辑实现状态内的赋值

第一个always时序初态和次态,第二个always组合逻辑描述状态转移,第三个always组合逻辑描述输出。输出可以不合并,编译器会帮你优化的。

注意:第二段我刚开始使用的时序逻辑输出,部分代码如下:

always@(posedge clk or negedge rst_n)begin  //括号里改为*就好了
        if(!rst_n)
            curr_state <= 2'b00;

发现答案不通过,波形如下:

 明显看出,我的Y比参考答案延后了一个时钟周期,因为时序逻辑会延后一个时钟周期,根据波形逆推,所以采用了组合逻辑,代码如下:

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   
);
    reg Y1;
    reg [1:0] curr_state;
    reg [1:0] next_state;
    // 当前状态切换,时序逻辑
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            curr_state <= 2'b00;
        else
            curr_state <= next_state;
    end
    // 下个状态更新,组合逻辑
    always@(*)
            case(curr_state)
                2'b00: begin
                if(C==1)
                    next_state <= 2'b01;
                else
                    next_state <= 2'b00;
                
                end
                2'b01: begin
                if(C==1)
                    next_state <= 2'b01;
                else
                    next_state <= 2'b11;
                
                end
                2'b10: begin
                if(C==1)
                    next_state <= 2'b10;
                else
                    next_state <= 2'b00;
                
                end
                2'b11: begin
                if(C==1)
                    next_state <= 2'b10;
                else
                    next_state <= 2'b11;
                
                end
                default: next_state <= 2'b00;
            endcase
    // 输出,组合逻辑
    always@(*)begin
        case(curr_state)
            2'b11: Y1 = 1;
            2'b10: Y1 = C ? 1 : 0;
            2'b00: Y1 = 0;
            2'b01: Y1 = 0;
        endcase
    end
    assign Y = Y1;
endmodule

解法三:

这里有别于日常所见的FSM,根据状态转移图,输出Y的表达式受当前状态以及同一时刻次态的状态影响

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   
);
    reg [1:0] curr_state;
    reg [1:0] next_state;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            curr_state <= 2'b00;
        else
            curr_state <= next_state;
    end
    always@(*)begin
            case(curr_state)
                2'b00: begin
                if(C==1)
                    next_state <= 2'b01;
                else if(C==0)
                    next_state <= 2'b00;
                else
                    next_state <= next_state;
                end
                2'b01: begin
                if(C==1)
                    next_state <= 2'b01;
                else if(C==0)
                    next_state <= 2'b11;
                else
                    next_state <= next_state;
                end
                2'b10: begin
                if(C==1)
                    next_state <= 2'b10;
                else if(C==0)
                    next_state <= 2'b00;
                else
                    next_state <= next_state;
                end
                2'b11: begin
                if(C==1)
                    next_state <= 2'b10;
                else if(C==0)
                    next_state <= 2'b11;
                else
                    next_state <= next_state;    
                end
                default: next_state <= 2'b00;
            endcase
    end
    assign Y = (curr_state == 2'b10 && C==1) | (curr_state == 2'b11);
    //这里有别于日常所见的FSM,根据状态转移图,输出Y的表达式受当前状态以及同一时刻次态的状态影响
endmodule

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值