微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > “10010”序列检测器的状态是7个还是5个?

“10010”序列检测器的状态是7个还是5个?

时间:10-02 整理:3721RD 点击:

“10010”序列检测器的状态是7个还是5个?
    ——这是夏宇闻《Verilog数字系统设计教程》(第二版)上的一个例题,在书中一共用了7个状态(IDLE,A,B,C,D,E,F,G)。而我自己在设计的时候只用了5个状态(没有原书中的F和G),通过仿真,结果依然正确,我想这本来是一个很简单的设计,书中这样写或许又他的道理,但是自己始终没有看出来,希望大家懂的,给小弟解释一下!这里附上原书中的代码和自己的代码。
--------------原书代码--------------------
module test(clock,reset,signalin,signalout);
    input clock,signalin,reset;
    output signalout;
    reg [2:0] state;
   
    parameter
        idle = 3'd0,
        a = 3'd1,
        b = 3'd2,
        c = 3'd3,
        d = 3'd4,
        e = 3'd5,
        f = 3'd6,
        g = 3'd7;
   
    assign signalout = (state == e && signalin == 0)?1:0;
   
    always@(posedge clock)
        if(!reset)
            begin
                state <= idle;
            end
        else
            begin
                casex(state)
                    idle:
                        begin
                            if(signalin == 1)
                                state <= a;
                            else
                                state <= idle;
                        end
                    a:
                        begin
                            if(signalin == 0)
                                state <= b;
                            else
                                state <= a;
                        end
                    b:
                        begin
                            if(signalin == 0)
                                state <= c;
                            else
                                state <= f;
                        end
                    c:
                        begin
                            if(signalin == 1)
                                state <= d;
                            else
                                state <= g;
                        end
                    d:
                        begin
                            if(signalin == 0)
                                state <= e;
                            else
                                state <= a;
                        end
                    e:
                        begin
                            if(signalin == 0)
                                state <= c;
                            else
                                state <= a;
                        end
                    f:
                        begin
                            if(signalin == 1)
                                state <= a;
                            else
                                state <= b;
                        end
                    g:
                        begin
                            if(signalin == 1)
                                state <= a;
                            else
                                state <= f;
                        end
                    default:
                        state <= idle;
                endcase
            end
endmodule
------------------------自己的代码--------------------------------------------
module seqdet (
    rst_n, clk,
    seq, det
    );
    input     clk, rst_n;
    input     seq;
    output  det;
    reg       det;
    reg [2:0] cstate, nstate;
    parameter IDLE = 3'd0,
                   A_1 = 3'd1,
                   B_10 = 3'd2,
                   C_100 = 3'd3,
                   D_1001 = 3'd4,
                   E_10010 = 3'd5;
    always @ (posedge clk or negedge rst_n)
         if (!rst_n)
             cstate <= IDLE;
         else
             cstate <= nstate;
    always @ (seq or cstate)
         case (cstate)
              IDLE :    if (seq == 1)   nstate <= A_1;
                           else               nstate <= IDLE;
              A_1:      if (seq == 0)   nstate <= B_10;
                           else               nstate <= A_1;
              B_10:     if (seq == 0) nstate <= C_100;
                           else                nstate <= A_1;
              C_100:    if (seq == 1) nstate <= D_1001;
                           else                nstate <= IDLE;
              D_1001:  if (seq == 0) nstate <= E_10010;
                           else                nstate <= A_1;
              E_10010: if (seq == 0) nstate <= C_100;
                           else                nstate <= A_1;
              default:  nstate <= IDLE;
         endcase
    always @ (cstate)
         if (cstate == E_10010)     det <= 1;
         else                                det <= 0;
endmodule
-------------------------------完-----------------------

自己先顶起来,正在好好学习,天天向上!

代码我没仔细看。可能有些状态你没有考虑到,但是你仿真发现不了。就是所谓的健壮性吧,你 可以自己再检查一下

这个我也用过,其实五个状态就可以表示了,个人认为是这样的!两个都对!

小编有没有考虑过,将侧10010010这种情况呢。也就是当将检测完10010之后,产生了一个信号,然后又来了010,不是又是一个10010了吗。我想他是基于这种情况,不会漏检。你可以试一下,你的代码是不是遇到这种情况也能检测出来。

刚才没细看小编的代码,小编是考虑了我上面说的。
但是,现在可以确定的是:两个代码肯定不是一样的。
看看我的仿真吧。













发现书上的代码,应该输出的,但是只是一个毛刺,也应该是组合逻辑的问题,因为书上的输出有点像mealy状态机那样子。

小编的就没有问题。

下面是我的测试代码:

`timescale 1ns/1ns
module seqdet_tb;
    reg     clk    ;
    reg     rst_n;
    reg     seq;
    wire    det;
wire [23: 0]  dat = 20'b1111_0101_1010_0110_0100_1111 ;    ///////用这样的仿真测试没有问题,initial begin
   clk   = 1'b0 ;
   rst_n = 1'b0 ;
   seq   = 1'b0 ;
   #200 rst_n = 1'b1 ;
end
always #25 clk = ~clk ;
integer i ;
initial i = 0 ;
always@( posedge clk )
begin
    seq <= $random ;//dat;
      
    if( i == 23 )
      i = 0 ;
    else
     i = i + 1 ;   
end
seqdet dut(          //小编的代码
    .rst_n(rst_n ),
    .clk( clk ),
    .seq( seq ),
    .det( det )    //det  是小编的输出。
    );
   
wire det2 ;
seqdetor  dut2(      //书上的例子
.clock( clk ),
.reset( rst_n ),
.signalin( seq ),
.signalout( det2 ));   //det2  是书上例子的输出

   
initial begin
   $fsdbDumpfile("wave.fsdb");
   $fsdbDumpvars( 0 , seqdet_tb );
end
endmodule      
   

说明一下,图片中,
最后一个信号,是小编的输出,
倒数第二个信号是书上例子的输出。



    非常感谢,你的细心和耐心都值得我学习!

只要达到目的,实现方法是多样的
关于毛刺问题,一个是寄存输出,一个是组合输出。寄存输出更佳!

请问下,你是不是让seq读取data采用的这句:wire [23: 0]  dat = 20'b1111_0101_1010_0110_0100_1111    可你后来没用呀。
还有这段:
if( i == 23 )
      i = 0 ;
    else
     i = i + 1 ;   

   
我觉得也没有什么用呀,去掉也可以。



    细看一下代码就知道了。
   seq是随机数。
  那个i是用来跟前边的data配合的。

我仔细看了一下,我认为,书上的代码有问题!其实我感觉这本书很垃圾。

我仔细看了一下,我认为,书上的代码有问题!其实我感觉这本书很垃圾。

书中写的很罗嗦, 小编的方面没有问题,放心好了。

xuexizhi ....................

对与仿真应该没有什么问题,我觉得小编还是应该设置G状态,因为一般状态机不会把IDLE放入循环。因为第一次IDLE状态是未知状态。而你
C_100:    if (seq == 1) nstate <= D_1001;
                           else                nstate <= IDLE;
这个语句里的IDLE不是未知状态。至于他的F状态为什么有具体不知道。我想估计也是和IDLE状态有关吧。另外书上判断输出时
assign signalout = (state == e && signalin == 0)?1:0;
加了个输入信号为零  是不是有些多此一举 不太了解

其实我也认为5个状态就足够了,

我感觉序列检测最重要的就是观察这一序列是否会重叠,
比如在这里序列是10010
但是如果输入进来的是100“10”010,就会形成两个10010序列,打引号的为两序列复用
所以需要多考虑010这三个状态
LZ的程序并没有错误,只是没有考虑周全而已

觉得小编想的简单了。

5个状态也行。


小编,想问问你的毛刺是怎么显示出来的啊?为什么我用verdi看不到毛刺的



    可以吧,我是用debussy5.4的。


那问下您是用哪个仿真工具的?VCS?NC?



    modelsim 6.5e
    不过,我认为不关仿真工具的事。

不错啊,这种氛围才是做技术应该有的,来这里几天就喜欢上了,以后天天泡,泡到成为牛人为止。

不错啊,这种氛围才是做技术应该有的,来这里几天就喜欢上了,以后天天泡,泡到成为牛人为止。
顶回复的兄弟门,我当时也遇到这种情况,没仔细想

I discovered this question before.
5 states is OK.
The book is not perfect.



   好好学习!

    糊涂了。seq是随机数没错,可是你的data和i也确实没有用到吧?
我想多半是你一开始seq = dat 吧。后面改用随机数了。

另外那个data是24bit,写成20'hxxxx_xxxx_xxxx....会丢掉4bit

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

网站地图

Top