首页 > 其他分享 >verilog 中的三段式状态机

verilog 中的三段式状态机

时间:2022-08-31 15:34:53浏览次数:65  
标签:三段式 always state 状态机 localparam verilog rst input

抄的: https://zhuanlan.zhihu.com/p/431143109

一段式状态机

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

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

二段式状态机

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

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

三段式状态机

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

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

标签:三段式,always,state,状态机,localparam,verilog,rst,input
From: https://www.cnblogs.com/han-guang-xue/p/16643280.html

相关文章

  • 计算机体系结构--指令Cache设计verilog实现
    前段时间一直在做MIPSCPU的设计,并且同步学习了一些计算机体系结构的相关知识,五级流水线单周期CPU设计已经完善了,本文主要记录一下指令Cache的设计及实现。一、Cache设计......
  • 实现串口通信数据帧打包与解析,串口通信可靠传输,屡试不爽的数据封包与状态机数据解析程
    前言串口通信是一种异步通信方式,收发双方约定好通信速率,通过两根数据线即可简单的时序全双工数据收发。最常用的串口通信协议由1位起始位8位数据位1位停止位组成,总共10位......
  • verilog中的task用法
    任务就是一段封装在“task-endtask”之间的程序。任务是通过调用来执行的,而且只有在调用时才执行,如果定义了任务,但是在整个过程中都没有调用它,那么这个任务是不会执行的。......
  • Verilog中函数function写法使用方法
    function写法function的标准写法如下:  函数的语法为:.定义函数时至少要有一个输入参量;可以按照ANSI和module形式直接定义输入端口。例如:function[63:0]alu(input[......
  • *Codeforces Round #363 (Div. 1) A. Vacations(状态机)
    https://codeforces.com/contest/698/problem/AVasya有n天假期!Vasya知道关于这n天中每一天的以下信息:那家健身房是否开门,以及那天是否在互联网中进行了比赛。第i天有四个......
  • SystemVerilog 随机化约束速查手册
    SystemVerilog随机化约束速查手册dist关键字权重分布使用dist关键字来实现权重分布:=表示范围内每个权重是相同的:/表示权重要均分到范围的每个值randintsrc;......
  • Verilog中信号定义位宽的一些问题
    总是被Verilog中信号定义位宽的问题所困扰:wire[7:0]data1和wire[0:7]data1有什么不一样wire[7:0]data2[3:0]、wire[7:0]data2[0:3]、wire[0:7]data2[3:0]、wire[0......
  • HDLBits答案——Verilog Language
    VerilogLanguage1Basics1.1Wiremoduletop_module(inputin,outputout);assignout=in;endmodule1.2Wire4moduletop_module(inputa,b,......
  • verilog随机序列发生器及很久不写verilog回忆起来的一些tips
    今天写了一个随机序列发生器,实际上是伪随机数,使用了LFSR(linefeedbackshiftregister)LFSR将移位寄存器中的值取出,做适当的运算,再返回到序列中作为新的输入,就可以构......
  • Verilog编译指令
    编译指令编译指令(Compilerdirective)能够让仿真器和综合工具执行一些特殊的操作。特点:以`(重音符号)为前缀从处理位置一直保持有效,除非被其他指令覆盖或者取消`rese......