• hdlbits之Exams/ece241 2013 q4的FSM问题


    工作和学习中的事情太多,想干的事情更多,所以总感觉时间不够用。再加上自己比较懒,好久没有兴致闲下来写东西了。

    之前做过hdlbits的一些题目,挺简单。但是今天被这道题给坑惨了,花费了几个小时才做出来。不是说这道题有多难,一是自己犯了一个脑袋驴踢的及其低级错误,二是题目也有出的不清楚的地方。原题目如下

    自己犯下的极其低级和愚蠢的错误为在S0,S1,S2,S3四个状态,判断输入s的值是忘了加数据类型和位宽。这个愚蠢而又低级的错误导致无法进入正确的状态。

    1             S0 : begin
    2                 case(s)
    3                     000 : next_state = S0;
    4                     001 : next_state = S1;
    5                     011 : next_state = S2;
    6                     111 : next_state = S3;
    7                     default: next_state = S0;
    8                 endcase                
    9             end

    正确的应该如下所示:

    1             S0 : begin
    2                 case(s)
    3                     3'b000 : next_state = S0;
    4                     3'b001 : next_state = S1;
    5                     3'b011 : next_state = S2;
    6                     3'b111 : next_state = S3;
    7                     default: next_state = S0;
    8                 endcase                
    9             end

    第二个原题目中没有交代清楚的问题:题目中之说了如果之前水位低于当前水位,为正常水流(即dfr不用打开),如果之前水位大于当前水位,则需要打开dfr。没有说当之前水位与当前水位相同时怎么处理dfr。导致自己这个地方一直出错,最后观察作者的测试波形,才发现作者的愿意是这种情况dfr保持之前的值。这个地方挺坑爹的。

    最后代码如下:

     1 module top_module (
     2     input clk,
     3     input reset,
     4     input [3:1] s,
     5     output fr3,
     6     output fr2,
     7     output fr1,
     8     output dfr
     9 ); 
    10 
    11     parameter [1:0] S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
    12     reg       [1:0] current_state, next_state, last_state;
    13 
    14     always @(posedge clk) begin
    15         if(reset) begin
    16             current_state <= S0;
    17             last_state    <= S0;
    18         end
    19         else begin
    20             current_state <= next_state;
    21             last_state    <= current_state;
    22         end
    23     end
    24     
    25     always @(*) begin
    26         case(current_state)
    27             S0 : begin
    28                 case(s)
    29                     3'b000 : next_state = S0;
    30                     3'b001 : next_state = S1;
    31                     3'b011 : next_state = S2;
    32                     3'b111 : next_state = S3;
    33                     default: next_state = S0;
    34                 endcase                
    35             end
    36             S1 : begin
    37                 case(s)
    38                     3'b000 : next_state = S0;
    39                     3'b001 : next_state = S1;
    40                     3'b011 : next_state = S2;
    41                     3'b111 : next_state = S3;
    42                     default: next_state = S0;
    43                 endcase                
    44             end
    45             S2 : begin
    46                 case(s)
    47                     3'b000 : next_state = S0;
    48                     3'b001 : next_state = S1;
    49                     3'b011 : next_state = S2;
    50                     3'b111 : next_state = S3;
    51                     default: next_state = S0;
    52                 endcase                
    53             end
    54             S3 : begin
    55                 case(s)
    56                     3'b000 : next_state = S0;
    57                     3'b001 : next_state = S1;
    58                     3'b011 : next_state = S2;
    59                     3'b111 : next_state = S3;
    60                     default: next_state = S0;
    61                 endcase                
    62             end
    63             default: next_state = S0;
    64         endcase       
    65     end
    66     
    67     always @(*) begin
    68         case(current_state)
    69             S0 : {fr3,fr2,fr1} = 3'b111;
    70             S1 : {fr3,fr2,fr1} = 3'b011;
    71             S2 : {fr3,fr2,fr1} = 3'b001;
    72             S3 : {fr3,fr2,fr1} = 3'b000;
    73             default: {fr3,fr2,fr1} = 3'b111;
    74         endcase
    75     end
    76     //assign fr3 = (current_state == S0);
    77     //assign fr2 = (current_state == S0) || (current_state == S1);
    78     //assign fr1 = (current_state == S0) || (current_state == S1) || (current_state == S2);
    79     
    80     always @(*) begin
    81         if(current_state == S0)
    82             dfr = 1'b1;
    83         else if(last_state > current_state)
    84             dfr = 1'b1;
    85         else if(last_state < current_state)
    86             dfr = 1'b0;
    87         else
    88             dfr = dfr;   //will generate latch        
    89     end
    90     
    91 endmodule

     原作者的非常简洁。主要区别在于自己的写法是以水位的状态为状态机的各种状态。这个状态机相对简单,但是dfr的情况无法在状态机中体现(即没有考虑水位从高到底的情况下dfr的值)。原作者通过细分状态的方式,简化了dfr的verilog代码逻辑。非常漂亮。原作者代码如下:

     1 module top_module (
     2     input clk,
     3     input reset,
     4     input [3:1] s,
     5     output reg fr3,
     6     output reg fr2,
     7     output reg fr1,
     8     output reg dfr
     9 );
    10 
    11 
    12     // Give state names and assignments. I'm lazy, so I like to use decimal numbers.
    13     // It doesn't really matter what assignment is used, as long as they're unique.
    14     // We have 6 states here.
    15     parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
    16     reg [2:0] state, next;        // Make sure these are big enough to hold the state encodings.
    17     
    18 
    19 
    20     // Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.    
    21     always @(posedge clk) begin
    22         if (reset) state <= A2;
    23         else state <= next;
    24     end
    25 
    26 
    27 
    28     // Combinational always block for state transition logic. Given the current state and inputs,
    29     // what should be next state be?
    30     // Combinational always block: Use blocking assignments.    
    31     always@(*) begin
    32         case (state)
    33             A2: next = s[1] ? B1 : A2;
    34             B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
    35             B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
    36             C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
    37             C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
    38             D1: next = s[3] ? D1 : C2;
    39             default: next = 'x;
    40         endcase
    41     end
    42     
    43     
    44     
    45     // Combinational output logic. In this problem, a procedural block (combinational always block) 
    46     // is more convenient. Be careful not to create a latch.
    47     always@(*) begin
    48         case (state)
    49             A2: {fr3, fr2, fr1, dfr} = 4'b1111;
    50             B1: {fr3, fr2, fr1, dfr} = 4'b0110;
    51             B2: {fr3, fr2, fr1, dfr} = 4'b0111;
    52             C1: {fr3, fr2, fr1, dfr} = 4'b0010;
    53             C2: {fr3, fr2, fr1, dfr} = 4'b0011;
    54             D1: {fr3, fr2, fr1, dfr} = 4'b0000;
    55             default: {fr3, fr2, fr1, dfr} = 'x;
    56         endcase
    57     end
    58     
    59 endmodule

     状态图的s1s2s3排列方式不好,如果改为S3S2S1会更符合习惯。

  • 相关阅读:
    小波变化与小波降噪
    非正态分布数据转换成正态分布
    使用pyinstaller将pyqt5打包成exe格式
    使用PyQt5嵌入matplotlib,实现根据界面输入数值更换显示的matplotlib图形
    python异常机制、多进程与PyQt5中的QTimer、多线程
    PyQt5中使用QTimer定时刷新:当要执行可能会超过设定时间的代码
    解决pyinstaller打包sklearn等库出现的问题: 提示failed to execute script xxx
    数据分析实例-MovieLens 1M 数据集
    机器学习各类算法的优缺点
    pandas时间序列
  • 原文地址:https://www.cnblogs.com/guojingdeyuan/p/14669916.html
Copyright © 2020-2023  润新知