在有限状态机verilog中处理大量输出

时间:2016-05-03 01:29:19

标签: verilog fsm

所以我正在尝试实现我的第一个FSM,而且我很困惑。

代码有点长,所以让我总结一下: 我首先声明输入和输出 然后声明(我有五个加三个占位符) 然后是当前状态分配,这是顺序

always @(posedge clk)
begin
    if (rst == 1'b1)
        Current_State <= MainGreen;
    else
        Current_State <= Next_state;
end

然后......我迷路了。我最初只有一个大的ol'顺序电路,分配next_state和输出,但这很乱/可能有很多错误。

我现在拥有的只是next_state逻辑,但与输出无关:

always @*
begin
    Next_state = Current_State;
    case (Current_State)

        MainGreen:
        begin
            if (count && expired)
            begin
                Next_state = MainYel;
            end
        end

        MainYel:
        begin
            if (WR && expired)
                Next_state = AllRed;
            else if (expired)
                Next_state = SideGreen;
        end

        AllRed:
        begin
            if (expired)
                Next_state = SideGreen;
        end

        SideGreen:
        begin
            if(sensor && expired)
                Next_state = SideYel;
        end

        SideYel:
        begin
            if(expired)
                Next_state = MainGreen;
        end
    endcase
    end

我只有8个基于状态的输出,4个基于状态和输入。我该如何分配它们?

1 个答案:

答案 0 :(得分:0)

你90%的方式都在那里。有两种方法可以继续(可能更多的方式,但我会给你我认为最好的两种选择):

首先,您是否有很多输出只能为少数几个州声明?如果是这样,我建议在你的组合中总是阻止这样的事情:

always @*
begin
  // default output values
  output1 = 1'b0;
  output2 = 1'b0;
  output3 = 1'b0;
  ....
  case (Current_State)
    STATE1: 
    begin
      output2 = 1'b1;
      // calculate next state
      ...
    end

    STATE2: 
    begin
      output4 = 1'b1;
      // calculate next state
      ...
    end
    ...
  endcase
end 

这可能是对状态机进行编码的最有效方法,因为您不需要在每个状态中定义每个输出。现在,如果每个输出都在很多不同的状态中处于活动状态,则可能更容易在case语句中的每个状态中定义这些输出。

我不建议的最后一种方法是在单独的assign语句中导出sm输出。它也可以正常工作,但我认为将输出与下一个状态逻辑保持在一起更容易进行代码维护和良好的开发习惯。为一项任务快速修改一些代码是一回事,为产品开发代码可能会在产品的整个生命周期内多次更新,而且可维护性至关重要(另一方面)我必须在工作中学习,因为没有人在大学里教过它。