-- -- Controller -- use work.smaxpck.ALL; entity CONTROLLER is generic (STW: positive); port (inknopf : in bit_vector (1 to STW); outknopf : in bit_vector (1 to STW); at : in bit_vector (1 to STW); door_open: in bit; moving : in bit; go_up : out bit; go_down : out bit; open_door: out bit); end CONTROLLER; architecture CONTROLLER of CONTROLLER is signal idle : bit := '0'; signal movereq : bit := '0'; signal oldreq : bit_vector (1 to STW) := smax_fae('0',STW); begin process (inknopf, outknopf, at, door_open, moving, idle, movereq) variable requests : bit_vector (1 to STW) := smax_fae('0',STW); variable doorstat : bit_vector (0 to 1) := "00"; variable going_up : bit := '0'; begin -- -- Verarbeite neue requests. Ignoriere requests in das Stockwerk, in dem -- wir gerade sind (das beruehmte Kaugummi auf dem Knopf). Aber falls wir -- eh' nichts zu tun haben ... Mit Kaugummi machen wir die Tuer dauernd -- auf und zu. Na und? -- moving wird abgefragt, weil wir uns ja nur dann in 'at' befinden, wenn -- wir uns nicht bewegen. -- requests := requests or ((inknopf or outknopf) and (smax_fae (movereq or moving or idle, STW) or not(at) or not(oldreq))); oldreq <= inknopf or outknopf; if door_open='0' then doorstat(0) := '0'; else doorstat(1) := '0'; end if; -- -- Falls wir uns bewegen und das naechste Stockwerk angefahren werden soll, -- dann gebe dem Aufzug den Befehl zum anhalten. Falls wir nicht in diesem -- Stock halten sollen, dann gebe keine Befehle und lasse Aufzug einfach -- weiterfahren. -- if moving='1' then movereq <= '0'; if (at and requests) /= smax_fae ('0', STW) then go_up <= '0'; go_down <= '0'; end if; -- -- wir halten. Falls wir hier halten sollen, mache die Tuer auf. Falls die -- Tuer auf ist, so mache sie wieder zu, und loesche request. Die Abfrage -- auf die offene Tuer verhindert, dass wir in den letzten elsif-Zweig fallen -- und den Lift bei offener oder noch nicht korrekt geschlossener Tuer in -- Bewegung setzen. -- elsif (((at and requests) /= smax_fae ('0', STW)) and movereq='0') or (door_open='1' or doorstat(1)='1') then if door_open='0' and doorstat(1)='0' then open_door <= '1'; doorstat(1) := '1'; elsif door_open='1' and doorstat(0)='0' then idle <= '0'; open_door <= '0'; doorstat(0) := '1'; requests := requests and not(at); end if; -- -- wir halten, und wir haben in diesem Stockwerk nichts mehr zu suchen. Falls -- aber nix los ist, dann bleibe einfach hier. Versuche zuerst in die durch -- going_up vorgegebene Richtung zu fahren. Falls wir aber dort gar nicht hin- -- wollen, dann wechsle die Fahrtrichtung. -- elsif requests /= smax_fae('0', STW) then -- die Arbeit ruft idle <= '0'; movereq <= '1'; -- wir fahren los if going_up='1' then -- wir wollen hoch if (not(smax_dcr(at))and requests)/=smax_fae('0',STW) then -- ist oben was los? go_up <= '1'; -- ab nach oben else -- oben ist aber nix go_down <= '1'; -- dann eben runter going_up := '0'; -- Richtungswechsel end if; else -- wir wollen runter if (smax_dcr(at) and requests)/=smax_fae('0',STW) then -- ist unten was los? go_down <= '1'; -- ab nach unten else -- unten ist aber nix go_up <= '1'; -- na dann eben hoch going_up := '1'; -- Richtungswechsel end if; end if; else -- es gibt einfach keine neue Anfrage mehr idle <= '1'; -- dann wirds uns halt langweilig. end if; end process; end CONTROLLER;