我想对状态机进行VHDL编程。在这种状态机中,一个状态本身就是另一个状态机。我怎么能从主状态机调用这个状态机? 我实际想做的事情的例子如下:
主状态机(sm_main.vhd): -
clk_process : process (clk, reset)
begin
if(reset = '1') then
state_reg <= start;
elsif (clk'event and clk =' 1' ) then
state_reg <= state_next;
end if;
end process;
state_process : process (state_reg,input,enable)
begin
case state_reg is
when start =>
if (input =1) then
state_next <= wait;
else
state_next <= start;
end if;
when wait =>
if (enable =1) then
output <= '1';
state_next <= execute;
else
output <='0';
state_next <= wait;
end if ;
when execute =>
if (enable =1) then
state_next <= done;
else
state_next <= start;
end if;
when done =>
if(result = 1) then
state_next <= execute;
else
state_next <= start;
end if;
end case;
end process;
子状态机(sm_execute.vhd): -
上述状态机的执行状态本身就是另一个状态机程序。
state_process : process (state_reg,a,b)
begin
case state_reg is
when start =>
if (a=1) then
state_next <= s1;
else
state_next <= s2;
end if;
when s1 =>
if (b =1) then
state_next <= s3;
else
state_next <= s3;
end if ;
when s3=>
if(c=1) then
result <= '1';
state_next <= s3
else
result <='0';
state_next <= start
end case;
end process;
我想要的是在sm_main.vhd的执行状态下调用此sm_execute.vhd。作为结果的sm_execute的输出将用作输入,以确定在sm_main.vhd中执行后的下一个状态。这意味着我想调用子状态机程序,并在子状态机程序完成执行后将值返回到主状态机程序。
提前谢谢 Sruthi Rajan答案 0 :(得分:1)
握手。第一台机器发出第二台机器的信号,等待它确认。然后它缩回启动信号并等待第二个完成。
这不是唯一的方法,但是你可以将第二个状态机分成它自己的进程,它可能是最简单的。
首先是SM(主人):
SM_1 : process(clock,reset)
begin
if reset = '1' then
State_1 <= Idle;
elsif rising_edge(clock) then
-- default actions
Start <= '0';
-- state machine proper
case State_1 is
...
when Need_Result =>
Start <= '1';
-- wait here until slave SM starts processing
if Done = '0' then
State_1 <= Wait_Result;
end if;
when Wait_Result =>
if Done = '1' then
State_1 <= Have_Result;
end if;
...
when others => State_1 <= Idle;
end case;
end if;
end process;
第二个SM(奴隶):
SM_2 : process(clock,reset)
begin
if reset = '1' then
State_2 <= Idle;
elsif rising_edge(clock) then
case State_2 is
when Idle =>
Done <= '1';
if Start = '1' then
Done <= '0';
State_2 <= Start_Process;
end if;
when Start_Process =>
State_2 <= Process_Done;
when Process_Done =>
Done <= '1';
if Start = '0' then
State_2 <= Idle;
end if;
when others => State_2 <= Idle;
end case;
end if;
end process;
请注意,在此实现中,主服务器等待从服务器开始处理(done = '0';
)。这包括奴隶可能无法立即响应的情况。它不包括已经Done='0'
的情况,因为从服务器正在为另一个主服务器处理数据。
奴隶还等待主人撤回开始,然后返回空闲状态。通常Start已经是'0'但如果不是,你可能不希望奴隶立即重新触发。
如果你能保证这些情况都不会发生,你可以稍微简化一下握手,但设计对信号时序的变化会更敏感。
另请注意,由于默认分配,Start
默认为'0'
,但Done
没有默认分配,因此在处理期间保留其状态。除非您在Done设置为指示处理已停止时返回空闲状态(可能通过错误路径)。
如果对处理是否完成存在不确定性,您可能希望主机超时,而不是死锁等待不会发生的事情。我这样做是通过添加一个延迟计时器,可以由不同的状态用于不同的目的:在这里它检测一个冻结的从属,让我们处理错误。
首先是SM(主人):
SM_1 : process(clock,reset)
variable Delay : natural range 0 to 100;
constant Timeout : natural := 50;
begin
if reset = '1' then
State_1 <= Idle;
Delay := 0;
elsif rising_edge(clock) then
-- default actions
Start <= '0';
if Delay > 0 then
Delay := Delay - 1;
end if;
-- state machine proper
case State_1 is
...
when Need_Result =>
Start <= '1';
-- wait here until slave SM starts processing
if Done = '0' then
Delay := Timeout;
State_1 <= Wait_Result;
end if;
when Wait_Result =>
if Done = '1' then
State_1 <= Have_Result;
elsif Delay = 0 then
State_1 <= Timed_Out; -- do error processing
end if;
...
when others => State_1 <= Idle;
end case;
end if;
end process;