在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 66741|回复: 94

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

[复制链接]
发表于 2011-6-1 16:56:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 KevinIC 于 2011-6-1 17:33 编辑

“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
-------------------------------完-----------------------
 楼主| 发表于 2011-6-1 16:58:04 | 显示全部楼层
自己先顶起来,正在好好学习,天天向上!
发表于 2011-6-1 17:51:13 | 显示全部楼层
代码我没仔细看。可能有些状态你没有考虑到,但是你仿真发现不了。就是所谓的健壮性吧,你 可以自己再检查一下
发表于 2011-6-1 21:01:50 | 显示全部楼层
这个我也用过,其实五个状态就可以表示了,个人认为是这样的!两个都对!
发表于 2011-6-2 10:00:07 | 显示全部楼层
楼主有没有考虑过,将侧10010010这种情况呢。也就是当将检测完10010之后,产生了一个信号,然后又来了010,不是又是一个10010了吗。我想他是基于这种情况,不会漏检。你可以试一下,你的代码是不是遇到这种情况也能检测出来。
发表于 2011-6-2 11:11:40 | 显示全部楼层
刚才没细看楼主的代码,楼主是考虑了我上面说的。

但是,现在可以确定的是:两个代码肯定不是一样的。

看看我的仿真吧。
Snap4.png

Snap1.png

Snap2.png

Snap3.png



发现书上的代码,应该输出的,但是只是一个毛刺,也应该是组合逻辑的问题,因为书上的输出有点像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      
   
发表于 2011-6-2 11:14:34 | 显示全部楼层
说明一下,图片中,
最后一个信号,是楼主的输出,
倒数第二个信号是书上例子的输出。
 楼主| 发表于 2011-6-6 21:39:36 | 显示全部楼层
回复 7# dlb05061131


    非常感谢,你的细心和耐心都值得我学习!
发表于 2011-6-8 16:00:23 | 显示全部楼层
只要达到目的,实现方法是多样的
关于毛刺问题,一个是寄存输出,一个是组合输出。寄存输出更佳!
发表于 2011-6-16 00:17:54 | 显示全部楼层


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

...
dlb05061131 发表于 2011-6-2 11:11



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

   
我觉得也没有什么用呀,去掉也可以。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-20 12:22 , Processed in 0.034564 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表