【问题标题】:finiate state machine have the issue with the logic有限状态机的逻辑有问题
【发布时间】:2021-06-27 14:55:00
【问题描述】:

如何使用 Verilog counter FSM for up-down counter 实现输出为 0,1,2,3,4,5,6,7,6,5,4,4,3,2,1与重复。这四个应该重复两次在这里使用两个状态向上向下它工作正常向上向下。

代码

  module top(
            input clk,rst,
            output logic [2:0] dout
            );
            
        typedef enum {up,down} state_type;
        state_type state = up;
         
        integer count = 0;
         
        always@(posedge clk)
        begin
        if(rst == 1'b1) begin
        //dout <= 0;
        count <= 0;
        end
        else begin
        case(state)
        up:
        begin
        if(count == 7) begin
        count <= count - 1;
        state <= down;
        end
        else begin
        state <= up;
        count <= count - 1;
        end
        end
         
        down: begin
        if(count == 0) begin
        count <= count + 1;
        state <= up;
        end
        else begin
        state <= down;
        count <= count - 1;
        end
        end
         
        default: begin
        state <= up;
        count <= 0;
        end
        endcase
        end
        end
        assign dout = count;
         
        endmodule

【问题讨论】:

  • 显然存在计数器 4 和向下步进的特殊状态。您必须尝试实施它。此外,您在计数器递减时计数存在错误。

标签: verilog counter


【解决方案1】:

从逻辑上讲,你需要告诉你的机器关于 Down 计数 4 的情况,你还需要让它知道你第一次或第二次击中 4 之间的区别。第一次你想停止和第二次要减量。目前你有上下的状态。因此,您可能会考虑使用 up、down 和 downto4。也许你在达到 7 时从 up 切换到 downto4,然后在递减时,以 downto4 的状态命中 4,你保持 4 计数,然后将状态设置为 down。

还有其他一些方法可以考虑这一点。想象一下,如果你拿了一个四位计数器,只查看高 3 位。这 3 位仍然可以保存您正在寻找的 0 到 7 个值。在 UP 和 DOWN 时,如果你从那个计数器中加减 2,你的高三位似乎增加了 1。现在想象一下,如果你处于 1010 的状态。高三位看起来像二进制 5。所以如果你现在减去1 从值中得到 1001。高三位看起来像二进制 4。再减去一位,得到 1000。高三位仍然看起来像 4。从逻辑上讲,你总是在向下减去计数,但您可能会说,如果值为 5 或 4,则只需在下一次计数时减一。您将不得不玩弄逻辑,但我认为您也可以做到这一点。

【讨论】:

    【解决方案2】:

    这个怎么样?

    module oddstep(
        input wire clk,
        input wire rst,
        output reg [2:0] step);
    
        reg dir;
        reg hold;
    
        always @(posedge clk)
          begin
            if (rst)
              begin
                step <= 3'b000;
                hold <= 1'b0;
                dir <= 1'b1;
              end
            else if (dir)
              begin
                step <= (step + 3'b001);
                if (step == 4)
                  begin
                    hold <= 1'b1;
                  end
                else if (step == 6)
                  begin
                    dir <= 1'b0;
                  end
              end
            else if (step != 1)
              begin
                if ((step == 4) & hold)
                  begin
                    hold <= 1'b0;
                  end
                else
                  begin
                    step <= (step - 3'b001);
                  end
              end
          end
    endmodule /* oddstep */
    

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 2011-11-22
      • 1970-01-01
      • 2015-08-30
      • 1970-01-01
      • 2019-03-17
      相关资源
      最近更新 更多