FPGA_状态机_序列检测器

 “硬件设计很讲究并行设计思想,虽然用Verilog描述的电路大都是并行实现的,但是对于实际的工程应用,往往需要让硬件来实现一些具有一定顺序的工作,这就要用到状态机思想。什么是状态机呢?简单的说,就是通过不同的状态迁移来完成一些特定的顺序逻辑。硬件的并行性决定了用Verilog描述的硬件实现(臂如不同的always语句)都是并行执行的,那么如果希望分多个时间完成一个任务,怎么办?也许可以用多个使能信号来衔接多个不同的模块,但是这样做多少显得繁琐。状态机的提出会大大简化这一工作。”                                                                                                                                                                                                                                    —特权同学《深入浅出玩转FPGA》

                                                                                                                                          

1 状态机

状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。有限状态机简写为FSM(Finite State Machine),主要分为2大类:

第一类,若输出只和状态有关而与输入无关,则称为Moore状态机

第二类,输出不仅和状态有关而且和输入有关系,则称为Mealy状态机

 “其实这几种状态机之间,只要做一些改变,便可以从一种形式转变为另一种形式。把状态机精确的分为这类或那类,其实并不重要,重要的是设计者如何把握输出的结构能满足设计的整体目标,包括定时的准确性和灵活性。”

                                                                                                                                                     ——夏宇闻《Verilog数字系统设计》

2 序列检测器

序列检测指的就是将一个指定的序列从数字码流中识别出来。本例中,我们将设计一个“10010”序列的检测器。设X为数字码流输入,Z为检出标记输出,高电平表示“发现指定序列”,低电平表示“没有发现指定序列”。考虑码流为“ 110010010000100101…” 则有下表:

在时钟2-6,码流X中出现指定序列“10010”,对应输出Z在第6个时钟变为高电平――“1”,表示“发现指定序列”。同样地,在时钟13-17码流,X中再次出现指定序列“10010”,Z输出“1”。注意,在时钟5-9还有一次检出,但它是与第一次检出的序列重叠的,即前者的前面两位同时也是后者的最后两位。

2.1 状态分析

根据以上逻辑功能描述,我们可以分析得出状态转换图如下:

其中状态A-E表示5比特序列“10010”按顺序正确地出现在码流中。考虑到序列重叠的可能,转换图中还有状态F、G。另外、电路的初始状态设为IDLE。

3 FPGA程序

module seqdet( x, z, clk, rst);
input x,clk, rst;
output z;
reg [2:0] state;//状态寄存器
wire z;
parameter IDLE= 'd0,  A='d1, B='d2,
                      C='d3, D='d4,
                      E='d5, F='d6,
                      G='d7;
assign z=(state==D && x==0) ? 1 :0;
always @(posedge clk or negedge rst)
if(!rst)
   begin
    state<=IDLE;
    end
else
  casex( state)
    IDLE: if(x==1)
           begin
            state<=A;
           end
    A: if (x==0)
         begin
          state<=B;
         end
    B:  if (x==0)
         begin
          state<=C;
         end
       else
        begin
         state<=F;
        end
    C:  if(x==1)
         begin
          state<=D;
         end
        else
         begin
          state<=G;
         end
    D:  if(x==0)
          begin
           state<=E;
          end
        else
         begin
          state<=A;
         end
    E:  if(x==0)
         begin
          state<=C;
         end
        else
         begin
          state<=A;
         end
    F:  if(x==1)
         begin
          state<=A;
         end
       else
        begin
         state<=B;
        end
   G: if(x==1)
        begin
         state<=F;
        end
   default: state<=IDLE;
 endcase
endmodule

4 验证脚本

`timescale 1ns/1ns
module t;
reg clk, rst;
reg [23:0] data;
wire z,x;
assign x=data[23];
initial
    begin
     clk<=0;
     rst<=1;
     #2 rst<=0;
     #30 rst<=1; //复位信号
     data='b1100_1001_0000_1001_0100; //码流数据
    end
always #10 clk=~clk; //时钟信号
always @ (posedge clk) // 移位输出码流
data={data[22:0],data[23]};
seqdet m ( .x(x), .z(z), .clk(clk), .rst(rst)); //调用序列检测器模块
// Enter fixture code here
endmodule 

5 仿真结果

猜你喜欢

转载自blog.csdn.net/qq_40893012/article/details/106950573