微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 一个序列检测器的问题

一个序列检测器的问题

时间:10-02 整理:3721RD 点击:
大大们下午好,小弟新学VERILOG遇到了一个很头疼的问题,盼你们能帮助一下我。
我写了一个10010序列检测器,每检测有一串10010就输输出一个1。我写出了代码,仿真不对,希望大大们帮我分析一下
代码如下
`timescale 1ns / 1ps
module test8_fsm(x,z,clk,rst,
  state_out  );
  input x,clk,rst;
  output z;
  output [2:0]state_out;
  wire z;
  reg[2:0] state,nextstate;
  parameter idle=3'b000,
     s1=3'b001,
     s10=3'b010,
     s100=3'b011,
     s1001=3'b100,
     s10010=3'b101;
  
  assign state_out=state;
  
  always@(posedge clk)
     if(rst)
     state<=idle;
     else
     state<=nst;
   
   
  always@( posedge clk )
  
        case(state)
   idle: if(x) nextstate=s1;//小弟编了6个装备,空闲0,按10010输入的顺序,S1,S10,S100,S1001,S10010
         else   nextstate=idle;
     
   s1:  if(!x)   nextstate=s10;
         else nextstate=s1;
   s10:                     
        if(!x )  nextstate=s100;
    else nextstate=s1;
   
   s100:if(x) nextstate=s1001;
         else   nextstate=idle;
     
   s1001:if(!x) nextstate=s10010;
                else   nextstate=s1;
      
   s10010:if(x) nextstate=s1;
    else nextstate=s100;
   
   default:nextstate=3'bxxx;
   endcase
   

assign z=(state==s10010)?1:0;
endmodule
仿真激励如下
`timescale 1ns / 1ps
module time_test8;
wire x;
reg clk;
reg rst;
reg [23:0]data;
wire z;
wire [2:0]state_out;

test8_fsm uut (
  .x(x),
  .z(z),
  .clk(clk),
  .rst(rst),
  .state_out(state_out)
);

assign x=data[23];
always #10clk=~clk;
always@(posedge clk)
   data<={data[22:0],data[23]};

  
initial
begin
  
  
  clk = 1;
  rst = 0;
  data=24'b1100_1001_0000_10010_0100_1010;
  #10rst=1;
  #100rst=0;
  

  #1000 rst=1;
  #1000 rst=0;
  #2000 rst=1;
  #1000 rst=0;
  #5000 $stop;
  end
  
endmodule
错误的仿真结果如下··


麻烦看看我写的 问题出在了哪儿··谢谢各位了!

看下状态机方面的资料吧,状态转换和输入的always块改写为组合逻辑电路。

问题不少
nst没有声明过
nextstate=3'bxxx; 改成3'b000;  哪有自己把状态导向不可知的
给nextstate赋值的always 改成组合逻辑 always @*  这个应该是造成你状态机不能正常转移的关键问题

Have  you compiled the code successfully?
it is no neccessary to finish this function by means of fsm,in fact.
you can use a shifter to realize the same function.
If you do finish the funciton in your own way, i suggest that you should learn how to finish function  in  fsm



       你好,谢谢你的耐心和热心!我那个NST就是NEXTSTATE```之前复制时这个没替换到,不好意思!
  主要问题就出在always@()里的触发条件噢,如果改为always@(*)的话 ,假如输入为连续两个低电平,X不跳变,这样状态会不会发生转移·····?
  我后来又改了一下 ,把状态跳转改成阻塞赋值了 ,结果可以出正常结果了,可是结果总是慢两个时钟,大大您看一下,这是为什么呢?
原先是                  always@(posedge clk)
                              if(rst)
                             state<=idle;
                              else
                              state<=nextstate;
改后                always@(posedge clk)
                       if(rst)
                       state=idle;
                         else
                       state=nextstate;  
     这样能出结果了 ,就是慢了两个周期才出!仿真图如下




    恩,目前正在学习。!但有时遇到问题解决不了确实蛮难受的·



    我现在就在学习如何用三段式状态机写法来写代码啊···我用两段式写出来的没问题,但三段式总是有问题,现在就是自己发现不了问题!盯着这段代码看了好久好久,也换东西仿真,但还是····哎,谢谢各位能热情的点开这个求助帖!



    大大!如你所眼我把always@(posedge clk)改成always@(*)后,仿真了一下 ,能行了!
   谢谢你!但是我还想问一下为什么会这样,我每个上升沿采集一下X然后判定一次状态转移感觉上时行的,可实际上为什么行不通呢?
   而且如我楼上那个回复,为什么把非阻塞改为阻塞后 ,也可以?只是慢了两个时钟

慢慢学会debug,,楼上已经说了,可以用移位寄存器和FSM来实现此功能,FSM写法很重要

不知异或后就和检测是不是更方便。



   @*包含的敏感信号不止x,  还有state, 第二个0来的时候state已经转移过,会再次触发always.



     可能是小弟没有表达清楚,是这样的,有一连串的数据到来,只要里面有一次10010的数据 就报一次1。因我也是个初学者,这样用位移寄存器的思路是怎么样的呢~我现在就是先借这个练习一下状态机~



   恩,谢谢大大!我有种豁然开朗的感觉,谢谢你!

只用state,不用nextstate,应该没有问题的。

用你的代码仿真了一下
代码改了一下, 把nextstate去掉了.
在modelsim 10.1a se 下仿真
结果正确

用移位寄存器会比较简单,可以尝试一下。



    恩,我试着用不同的方法写一下!谢谢你



    额,,其实你们说用位移寄存器写,我头脑中都没有思路该如何利用位移寄存器。新手慢慢学的过程中··用移位寄存器的大概思路是咋样的呢?

建议你分清组合逻辑和时序逻辑以及代码和电路的对应关系,如果这些都清楚了的话,modelsim是可以跟踪每一个信号的,什么时候应该输出啥,结果输出啥也就一目了然了


状态转移的时候要看原来的状态state跟输入x,always(*)即always(state or x) state改变或者x改变都能触发,然后产生下一状态

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top