2.状态机的一段式(one always)、三段式(three always)的练习

本文详细介绍了如何使用Verilog语言编写一段式和三段式状态机模块,用于处理格雷码输入,包括状态转移逻辑和输出计算。通过实例演示了状态机的结构,并配合真值表和TB测试模块,适合初学者理解状态机设计与实现。
摘要由CSDN通过智能技术生成

练习状态图如图所示

真值表

statay1 y2 y3 (格雷码)00011011
0   000000/0111/1001/1011/1
1001000/0001/0011/0001/0
2011011/0011/0010/1010/1
3010010/1111/1010/1111/1
4111000/0000/0000/1111/1

注:米勒状态机不能用一段式完成

1)一段式verilog代码

//one always
//built module
module one_fsm (clk , ina, reset,out);
  input clk, ina,reset;
  wire [1:0] ina;
  output out;
  reg out;
  reg [2:0] state; nextstate;
  parameter s0 = 3'b000, s1 = 3b'001, s2 = 3b'011, s3 = 3b'010, s4 = 3b'110;
//kaishimiaoshu 
  always @ (posedge clk or reset);
    begin  
        if(reset)
            state <= s0;
        else
            state <= nextstate;
        end
//选择状态、每一状态所包含的信息
        case(state)
            s0:begin
                case(ina)
                    ina = 2b'00:begin
                                nextstate <= s0; out = 0;
                                end
                    ina = 2'b10:begin
                                 nextstate <= s1; out = 1;
                                end
                    ina = 2'b01:begin
                                 nextstate <= s4; out = 1;
                                end
                    ina = 2'b11:begin
                                 nextstate <= s2; out = 1;
                                end
                endcase
            s1:begin
                case(ina)
                    ina[0] = 1:begin
                                nextstate <= s1; out = 0;
                                end
                    ina = 2'b00:begin
                                 nextstate <= s0; out = 0;
                                end
                    ina = 2'b10:begin
                                 nextstate <= s2; out = 0;
                                end
                endcase
            s2:begin
                case(ina)
                    ina[1] = 1:begin
                                nextstate <= s3; out = 1;
                                end
                    ina[1] = 0 :begin
                                 nextstate <= s1; out = 0;
                                end
                endcase
            s3:begin
                case(ina)
                    ina[0] = 0:begin
                                nextstate <= s3; out = 1;
                                end
                    ina[1] = 1:begin
                                 nextstate <= s4; out = 1;
                                end
                endcase
            s4:begin
                case(ina)
                    ina[2] = 0:begin
                                nextstate <= s0; out = 0;
                                end
                    ina = 2'b10:begin
                                 nextstate <= s0; out = 1;
                                end
                    ina = 2'b11:begin
                                 nextstate <= s4; out = 1;
                                end
                endcase
            endcase
    end
endmodule

2.三段式

//三段式always
module three_fsm (clk, reset, ina, out)
    input clk, reset, ina;
    wire[1:0] ina;
    output out;
    reg out;
    reg[2:0] state, nextstate;
//格雷码代表每一个阶段
    paratemer s0 = 3b'000, s1 = 3b'001, s2 = 3b'011, s3 = 3b'010, s4 = 3b'110;
//第一个always,判断选择哪一个state
always @ (posedge clk or posedge reset) //用非阻塞赋值
  begin
    if (reset)
        state <= s0;
    else
        state <= nextstate;
  end
//第二个always,根据输入信号Ina决定下一个state是什么
 always @ (state or ina)
  begin 
    case (state)
        s0:begin
            if (ina == 2'b00)
                nextstate = s0;
            else if (ina == 2b'01)
                nextstate = s4;
            else if (ina == 2b'10)
                nextstate = s1;
            else if (ina == 2b'11)
                nextstate = s2;
          end
        s1:begin
            if(ina == 2b'00)
                nextstate = s0;
            else if (ina == 10)
                nextstate = s2;
            else if (ina[0] == 1)
                nextstate = s1;
            end
        s2:begin
            if (ina[1] == 0)
                nextstate = s1;
            else if (ina[0] == 1)
                nextstate = s3;
            end
        s3:begin
            if (ina[0] == 0)
                nextstate = s3;
            else if (ina == 1)
                nextstate = s4;
            end
        s4:begin
            if(ina[1] == 0 or ina == 2b'10)
                nextstate = s0;
            else if(ina == 11)
                nextstate = s4;
                end
      endcase
    end
//第三个always由ina决定输出结果
  alwas @(posedge clk)
    begin
        case(state)
            s0:begin
                if(ina == 2b'00 )
                    out = 0;
                else if (ina == 2b'10 or ina == 2b'01 or ina == 2b'11)
                    out = 1;
                end
            s1:out = 0;
            s2:begin
                if(ina[1] == 0)
                    out = 0;
                else if (ina[1] == 1)
                    out =1;
                end
            s3:out = 1;
            s4:begin
                if (ina[1] == 0)
                    out = 0;
                else if (ina == 2b'10 or ina ==2b'11)        
                    out =1
                end
            endcase
      end
endmodule

tb

`timescale 1 ns/1 ns

module three_fsm_tb();

reg clk;
reg reset;
reg ina;
wire out;

FSM_SequDetection   U1(
  .clk(clk),
  .reset(reset),
  .ina(ina),
  .out(out)
);

initial 
begin 
  clk = 0;
  reset = 1;
  #15;
  reset = 0;
  ina = 2'b01;#10;
  ina = 2'b11;#10;  
  ina = 2'b10;#10;
  ina = 2'b00;#10;
  ina = 2'b01;#10;  
  ina = 2'b11;#10;
  ina = 2'b10;#10;
  ina = 2'b01;#10;  
  ina = 2'b01;#10;
  ina = 2'b11;#10;
  ina = 2'b00;#10;  
  ina = 2'b01;#10;
   #50;
  $stop;  //停止仿真
end 

always #5 clk = ~clk;

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值