/// <summary> /// Renders all the statements in a state machine method as VHDL /// </summary> /// <returns>The statements in the method.</returns> /// <param name="method">The method to render.</param> public IEnumerable <string> RenderStateMachine(AST.Method method, RenderStateProcess rsp) { var proc = method.GetNearestParent <SME.AST.Process>(); var statesignal = proc.InternalDataElements[proc.InternalDataElements.Length - 2]; var runvariable = method.Variables.Last(); yield return($"{method.Name}: process (RST, FSM_Trigger)"); foreach (var n in method.Variables.Union(proc.SharedVariables).Where(x => x != runvariable)) { yield return($" variable {n.Name}: {Parent.VHDLWrappedTypeName(n)} := reset_{n.Name};"); } yield return($" variable {runvariable.Name}: {Parent.VHDLWrappedTypeName(runvariable)} := {RenderExpression(new PrimitiveExpression("State0", runvariable.CecilType))};"); yield return("begin"); // The first statement is the state reset call foreach (var s in method.Statements.Take(1).SelectMany(x => RenderStatement(method, x, 4))) { yield return(s); } yield return(" if RST = '1' then"); foreach (var bus in Process.OutputBusses.Concat(Process.InternalBusses).Distinct()) { foreach (var signal in rsp.WrittenSignals(bus)) { foreach (var s in RenderStatement(null, Parent.GetResetStatement(signal), 8)) { yield return(s); } } } foreach (var variable in method.AllVariables.Union(proc.SharedVariables).Where(x => x != statesignal)) { yield return($" {variable.Name} := {Naming.ToValidName("reset_" + variable.Name)};"); } yield return(" FIN <= '0';"); yield return(" else"); foreach (var s in method.Statements.Skip(1).SelectMany(x => RenderStatement(method, x, 8))) { yield return(s); } yield return(" FIN <= RDY;"); yield return(" end if;"); yield return("end process;"); }