所以我正在尝试实现我的第一个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个基于状态和输入。我该如何分配它们?
答案 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输出。它也可以正常工作,但我认为将输出与下一个状态逻辑保持在一起更容易进行代码维护和良好的开发习惯。为一项任务快速修改一些代码是一回事,为产品开发代码可能会在产品的整个生命周期内多次更新,而且可维护性至关重要(另一方面)我必须在工作中学习,因为没有人在大学里教过它。