public override void MouseUpCreateNew(object sender, MouseEventArgs e) { cretion_flag = false; mouse_down = MouseDown; mouse_move = MouseMove; mouse_up = MouseUp; Creation_Point.X = e.X; Creation_Point.Y = e.Y; //ищем ближайшее состояние int?min_distance = null; foreach (My_State s in core.Graph.States) { int distance = (e.X - s.CenterPoint.X) * (e.X - s.CenterPoint.X) + (e.Y - s.CenterPoint.Y) * (e.Y - s.CenterPoint.Y); if ((min_distance == null) || (distance < min_distance)) { min_distance = distance; state = s; } } center_point.X -= state.CenterPoint.X; center_point.Y -= state.CenterPoint.Y; core.Bitmap.UpdateBitmap(); core.form.Invalidate(); }
private void CreateLine(Schematix.FSM.My_State st1, Schematix.FSM.My_State st2) { this.state_begin = st1; this.state_end = st2; if ((st1.CenterPoint.X == st2.CenterPoint.X) && (st1.CenterPoint.Y == st2.CenterPoint.Y)) { Angle1 = new Point((st1.CenterPoint.X - 2 * st1.rect.Width), (st1.CenterPoint.Y - 2 * st1.rect.Height)); Angle2 = new Point((st1.CenterPoint.X - 2 * st1.rect.Width), (st1.CenterPoint.Y + 2 * st1.rect.Height)); } else { int deltax = (state_end.CenterPoint.X - state_begin.CenterPoint.X) / 3; int deltay = (state_end.CenterPoint.Y - state_begin.CenterPoint.Y) / 3; Angle1 = new Point((state_begin.CenterPoint.X + deltax), (state_begin.CenterPoint.Y + deltay)); Angle2 = new Point((state_end.CenterPoint.X - deltax), (state_end.CenterPoint.Y - deltay)); } mouse_move = MouseMove; mouse_down = MouseDown; mouse_up = MouseUp; draw = Draw; core.Graph.UpdateLinesAggle(st1, st2); //core.AddToHistory("Line " + name + " created"); }
/// <summary> /// Обновление углов под которыми выходят линии из состояний s1 и s2 /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> public void UpdateLinesAggle(My_State s1, My_State s2) { List <My_Line> lines = GetLinesByStates(s1, s2); if ((lines.Count == 0) || (lines.Count == 1)) { return; } double sweep_angle = (Math.PI / 4.0) / ((double)lines.Count - 1); double cur_angle = -(Math.PI / 4.0) / 2.0; for (int i = 0; i < lines.Count; i++, cur_angle += sweep_angle) { if (lines[i].state_begin == s1) { lines[i].RotateStartPoint(cur_angle); lines[i].RotateEndPoint(-cur_angle); } else { lines[i].RotateStartPoint(-cur_angle); lines[i].RotateEndPoint(cur_angle); } } }
/// <summary> /// возвращает список линий, которые соединяют состояния s1 и s2 /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> /// <returns></returns> private List <My_Line> GetLinesByStates(My_State s1, My_State s2) { List <My_Line> res = new List <My_Line>(); foreach (My_Line line in Lines) { if ( ((line.state_begin == s1) && (line.state_end == s2)) || ((line.state_begin == s2) && (line.state_end == s1)) ) { res.Add(line); } } return(res); }
public My_Line(My_State s1, My_State s2, string name, string condition, Schematix.FSM.Constructor_Core core) { this.core = core; this.state_begin = s1; this.state_end = s2; this.name = name; this.condition = condition; this.color = Color.Black; this.priority = 0; selected = false; selected_mark = 0; creation_pt1 = new Point(); creation_pt2 = new Point(); this.label_condition = new My_Label(condition, color, core, this); this.label_condition.Owner = this; color_mark = new Color[2]; UpdateBitmapColors(); /* * if ((s1.CenterPoint.X == s2.CenterPoint.X) && (s1.CenterPoint.Y == s2.CenterPoint.Y)) * { * angle1 = s1.rect.Location; * angle2 = new Point(s1.rect.Location.X, s1.rect.Location.Y + s1.rect.Height); * } * else * { * int deltax = (state_end.CenterPoint.X - state_begin.CenterPoint.X) / 2; * int deltay = (state_end.CenterPoint.Y - state_begin.CenterPoint.Y) / 2; * * angle1 = new Point((state_begin.CenterPoint.X + deltax), (state_begin.CenterPoint.Y + deltay)); * angle2 = new Point((state_end.CenterPoint.X - deltax), (state_end.CenterPoint.Y - deltay)); * } */ CreateLine(s1, s2); mouse_move = MouseMove; mouse_down = MouseDown; mouse_up = MouseUp; draw = Draw; }
public My_State(My_State item) { this.color = item.color; this.color_name = item.color_name; this.condition = item.condition; this.ActivityInput = item.ActivityInput; this.ActivityExit = item.ActivityExit; this.color_state = item.color_state; this.core = item.core; this.name = item.name; this.rect = item.rect; this.label_name = new My_Label(item.label_name); this.label_name.Owner = this; mouse_move = MouseMove; mouse_up = MouseUp; mouse_down = MouseDown; draw = Draw; color_marks = new Color[8]; UpdateBitmapColors(); }
private void CreateLine() { Schematix.FSM.My_State st1 = new My_State(core); Schematix.FSM.My_State st2 = new My_State(core); float?L = null; foreach (Schematix.FSM.My_State st in core.Graph.States) { float S = (creation_pt1.X - st.CenterPoint.X) * (creation_pt1.X - st.CenterPoint.X) + (creation_pt1.Y - st.CenterPoint.Y) * (creation_pt1.Y - st.CenterPoint.Y); if ((L == null) || (L > S)) { L = S; st1 = st; } } if (L > 10000) { core.Graph.RemoveFigure(this); } L = null; foreach (Schematix.FSM.My_State st in core.Graph.States) { float S = (creation_pt2.X - st.CenterPoint.X) * (creation_pt2.X - st.CenterPoint.X) + (creation_pt2.Y - st.CenterPoint.Y) * (creation_pt2.Y - st.CenterPoint.Y); if ((L == null) || (L > S)) { L = S; st2 = st; } } if (L > 10000) { core.Graph.RemoveFigure(this); } CreateLine(st1, st2); }
public My_Line(My_State s1, My_State s2, Schematix.FSM.Constructor_Core core) : this(s1, s2, ("L" + core.Graph.Lines.Count.ToString()), " ", core) { }
public My_Line(My_State s1, My_State s2, string name, Schematix.FSM.Constructor_Core core) : this(s1, s2, name, " ", core) { }
public string GenerateCode() { StringBuilder res = new StringBuilder(); //выписываем имя модуля res.AppendFormat("`timescale {0}\n", graph.VerilogModule.Timescale); res.AppendFormat("module {0} (", graph.VerilogModule.ModuleName); //имя модуля //выписываем перечень портов for (int i = 0; i < graph.Ports.Count; i++) { My_Port p = graph.Ports[i]; if (i < (graph.Ports.Count - 1)) { res.AppendFormat("{0}, ", p.name); } else { res.AppendFormat("{0}", p.name); } } res.Append("); \n"); //выписываем перечень входных и выходных сигналов foreach (My_Port p in graph.Ports) { string direction = string.Empty; switch (p.Direction) { case My_Port.PortDirection.In: direction = "input"; break; case My_Port.PortDirection.Out: direction = "output"; break; case My_Port.PortDirection.InOut: direction = "inout"; break; default: break; } if (p.Type_inf.avaliable == false) { res.AppendFormat("\t{0} {1} {2};\n", direction, p.Type, p.name); } else { res.AppendFormat("\t{0} {1} [{2} : {3}] {4};\n", direction, p.Type, p.Type_inf.range1, p.Type_inf.range2, p.name); } } int bus_width = 0; if (graph.Signals.Count != 0) { //Обьявление переменных (Variables) res.Append("\t//Variables Declaration\n"); foreach (My_Signal s in graph.Signals) { res.AppendFormat("\t{0} {1};\n", s.Type, s.name); } } if (graph.Constants.Count != 0) { //Обьявление констант res.Append("\t//Constant Declaration\n"); foreach (My_Constant c in graph.Constants) { if (c.Gen_Type == My_Constant.GenerationType.Generic) { res.AppendFormat("\t`define {0} {1}\n", c.name, c.Default_Value); } if (c.Gen_Type == My_Constant.GenerationType.Constant) { res.AppendFormat("\tparameter {0} = {1};\n", c.name, c.Default_Value); } } } //Обьявление состояний автомата for (int i = 0; i < graph.States.Count; i++) { My_State s = graph.States[i]; string bin_value = System.Convert.ToString(i, 2); string value = string.Format("{0}'b{1}", bin_value.Length, bin_value); if (bus_width < bin_value.Length) { bus_width = bin_value.Length; } res.AppendFormat("`define {0} {1}\n", s.name, value); } //обьявление текущего и следующего состояния res.AppendFormat("reg [{0} : 0] Current_State;\n", bus_width - 1); res.AppendFormat("reg [{0} : 0] Next_State;\n", bus_width - 1); //Здесь происходит инициалзация автомата res.Append("initial\n"); res.Append("\tbegin\n"); res.Append("\t\tCurrent_State <= `S0;"); res.Append("\tend\n"); //процесс, отвечающий за действия в текущем состоянии и переход в следующее состояние res.Append("\t always @ (Current_State)\n"); res.Append("\t\t begin\n"); res.Append("\t\t\t Next_State = Current_State; \n"); res.Append("\t\t\t case (Current_State)\n"); foreach (My_State s in graph.States) { //выписываем имя состояния res.AppendFormat("\t\t\t\t `{0}:\n", s.name); res.Append("\t\t\t\tbegin\n"); //выписываем действия при входе (ЕСЛИ ТАКОВЫ ИМЕЮТСЯ) if (string.IsNullOrEmpty(s.ActivityInput) == false) { res.Append("\t\t\t\t\t////////////////////////////////\n"); res.AppendFormat("\t\t\t\t\t{0}\n", s.ActivityInput); res.Append("\t\t\t\t\t////////////////////////////////\n"); } //выписываем действия внутри (ЕСЛИ ТАКОВЫ ИМЕЮТСЯ) if (string.IsNullOrEmpty(s.condition) == false) { res.Append("\t\t\t\t\t////////////////////////////////\n"); res.AppendFormat("\t\t\t\t\t{0}\n", s.condition); res.Append("\t\t\t\t\t////////////////////////////////\n"); } //выписываем действия на выходе (ЕСЛИ ТАКОВЫ ИМЕЮТСЯ) if (string.IsNullOrEmpty(s.ActivityExit) == false) { res.Append("\t\t\t\t\t////////////////////////////////\n"); res.AppendFormat("\t\t\t\t\t{0}\n", s.ActivityExit); res.Append("\t\t\t\t\t////////////////////////////////\n"); } //перебираем все выходящие дуги... List <Schematix.FSM.My_Line> out_lines = new List <My_Line>(); //это список линий, которые выходят из данного состояния //первым делом нужно построить данный список out_lines = graph.Lines.ToList().FindAll(r => r.state_begin == s); //теперь нам нужно отсортировать список по приоритетам out_lines.Sort((r1, r2) => r1.priority.CompareTo(r2.priority)); if (out_lines.Count != 0) { bool start = false; foreach (Schematix.FSM.My_Line line in out_lines) { if (string.IsNullOrEmpty(line.condition) == false) { //пишем условие перехода if (start == false) { start = true; res.AppendFormat("\t\t\t if ( {0} )\n", line.condition); res.Append("\t\t\t\t begin\n"); } else { res.AppendFormat("\t\t\t else if ({0})\n", line.condition); res.Append("\t\t\t\t begin\n"); } //действия внутри перехода if (string.IsNullOrEmpty(line.Action) == false) { res.AppendFormat("\t\t\t\t {0} \n ", line.Action); } //переход к следующему состоянию res.AppendFormat("\t\t\t\t Next_State <= `{0}; \n", line.state_end.name); //конец res.AppendFormat("\t\t\t\t end \n\n "); } else { if (start == false) { res.Append("\t\t\t\t begin\n"); if (string.IsNullOrEmpty(line.Action) == false) { res.AppendFormat("\t\t\t\t {0} \n ", line.Action); } res.AppendFormat("\t\t\t\t Next_State <= `{0}; \n", line.state_end.name); res.AppendFormat("\t\t\t\t end \n\n "); } else { res.Append("\t\t\t else \n"); res.Append("\t\t\t\t begin\n"); if (string.IsNullOrEmpty(line.Action) == false) { res.AppendFormat("\t\t\t\t {0} \n ", line.Action); } res.AppendFormat("\t\t\t\t then Next_State <= `{0}; \n", line.state_end.name); res.AppendFormat("\t\t\t\t end \n\n "); } } } } res.Append("\t\t\t\tend\n"); } res.Append("\t\t endcase \n"); res.Append("\t end \n"); //процесс, реагирующий на таймер //и выполняющий переход в следующее состояние //Также в этом процессе выполняется сброс My_Port ClockedPort = graph.ClockPort; string argument = ""; if (ClockedPort != null) { argument = ClockedPort.name; } if (graph.Reset == null) { res.AppendFormat("\t always @(posedge {0}) \n", argument); res.Append("\t\tbegin\n"); res.Append("\t\t\tCurrent_State = Next_State;\n"); res.Append("\t\tend\n"); } else { if (graph.Reset.res_type == My_Reset.Reset_Type.Asynchonous) { argument += ", " + graph.Reset.signal; } res.AppendFormat("\t always @(posedge {0}) \n", argument); res.Append("\t\tbegin\n"); //выписываем условие перехода res.AppendFormat("\t\tif({0})\n", graph.Reset.condition); res.AppendFormat("\t\t\tCurrent_State = `{0};\n", graph.Reset.state.name); res.Append("\t\telse\n"); res.Append("\t\t\tCurrent_State = Next_State;\n"); res.Append("\t\tend\n"); } res.Append("endmodule"); return(res.ToString()); }