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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: KevinIC

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

[复制链接]
发表于 2015-9-5 21:51:01 | 显示全部楼层
你的分明是错的,都回不去的,仔细看看把
发表于 2015-9-8 00:19:56 | 显示全部楼层
这个我也用过
发表于 2015-9-8 00:56:54 | 显示全部楼层
只要达到目的
发表于 2016-6-29 23:29:53 | 显示全部楼层
修改了下楼主的部分代码,两种情况下仿真结果一致。因此个人认为,两种情况是一致的,书中的F和A,G和adle是等价状态。因此7状态会产生冗余逻辑。如果有兴趣的,下次发一下DC综合的面积报告,一定是会有区别的。----------------------------------------------------------------------------------------------------
5状态
----------------------------------------------------------------------------------------------------
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)    //修改:always用于组合逻辑,内部赋值用阻塞赋值
         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 @ (nstate)   //修改:楼主是现态,采用次态,可以在最后一个0一出现就输出det=1,用现态,得多等一个周期
         if (nstate == E_10010)     det = 1;
         else                       det = 0;
endmodule
-------------------------------------------------------------------------------------------------------------------------------------


7状态
--------------------------------------------------------------------------------------------------------------------------------------
module seqdetor(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 == d && signalin == 0)?1:0;//改为D状态

    always@(posedge clock)
        if(!reset)
            begin
                state <= idle;
            end
        else
            begin
                casex(state)
                    idle:
                        begin
                            if(signalin == 1) //1st 1 comes
                                state <= a;
                            else
                                state <= idle;
                        end
                    a:
                        begin
                            if(signalin == 0) //1st 0 comes
                                state <= b;
                            else
                                state <= a;
                        end
                    b:
                        begin
                            if(signalin == 0)//2sec 0 comes
                                state <= c;
                            else
                                state <= f;
                        end
                    c:
                        begin
                            if(signalin == 1) //2sec 1 comes
                                state <= d;
                            else
                                state <= g;
                        end
                    d:
                        begin
                            if(signalin == 0)//last 0 comes
                                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 <= g;  //修改,楼主是F,应该转为g或者IDLE,两者等价
                        end
                    default:
                        state <= idle;
                endcase
            end
endmodule

-------------------------------------------------------------------------------------------

仿真图

仿真图


---------------
`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      


--------------------------------------------------------------------------------------------
状态机建议两段式和三段式,清晰易修改。若想要快速反馈输出,第三个always用电平敏感做做组合逻辑用,若考虑剔除毛刺;三段式的第三个always用做时序逻辑,用寄存器打一拍。
发表于 2016-7-4 17:06:05 | 显示全部楼层
用状态机实现序列检测器,只具备研究学习状态机的意义。
实际电路设计,如果你使用状态机来实现那要被辞退的。
直接使用5个移位寄存器即可,当移位寄存器等于“10010”输出状态指示信号,over。
发表于 2016-7-18 08:16:53 | 显示全部楼层



应该是这样:sft_reg[4:0] <= {sft_reg[3:0] : din}


否则这位大哥的代码,就是输入永远都在sft_reg[0]这一位,没有移动。。
发表于 2016-10-23 15:05:04 | 显示全部楼层
正好也在看夏宇文老师的书,正好也看到这里,正好我自己的想法也是五个状态,好巧。然后看了书上的代码反而不明告白了。其实我还是觉得五个状态的比较好理解。
发表于 2016-10-23 16:43:44 | 显示全部楼层
回复 89# 王光敏


   六个更好,便于理解!
发表于 2016-12-30 23:35:04 | 显示全部楼层
如果你要检测的位宽不大,速度不快。。。何必用FSM呢,用sfr型的电路就搞定了。。。
发表于 2017-3-17 09:21:02 | 显示全部楼层
感觉大家说的都蛮有道理的!学习了!我也是看到这段代码,感觉有点问题过来的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-3-29 01:53 , Processed in 0.028284 second(s), 6 queries , Gzip On, Redis On.

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