2017-04-25 3 views
0

Ich habe derzeit das Snake-Spiel in vhdl für Spartan3e implementiert.Vhdl Snake - wie Tail-Implementierung zu automatisieren

Ich habe bereits einen Teil geschrieben, der ein Zellenquadrat auf VGA-Bildschirm zeichnet und es ermöglicht, es um das Quadrat zu verschieben.

Das Problem ist mit Schwanz-Implementierung - soweit ich manuell ein anderes Zellsegment zu meiner Schlange hinzugefügt habe, aber ich möchte es automatisieren (wie in Java einfach die Warteschlange mit den Zellen machen und die Position des nächsten setzen Zelle wie die Zelle zuvor). Ich weiß nicht, wie man eine solch komplexe Funktion in vhdl schreibt.

Hier ist mein Code:

begin 
    process (clk, reset, endOfGame) 
    begin 
     if reset='1' or endOfGame=true then 

     ball_y_reg <= to_unsigned(231,10); 
     ball_x_reg <= to_unsigned(311,10); 
     ball_x_reg_cell<=to_unsigned(231,10); 
     ball_y_reg_cell<=to_unsigned(311,10); 
-- velocity after reset schould be none 
     x_delta_reg <= ("0000000000"); 
     y_delta_reg <= ("0000000000"); 


     elsif (clk'event and clk='1') then 
     ball_x_reg_cell<=ball_x_next_cell; 
     ball_y_reg_cell<=ball_y_next_cell; 
     ball_x_reg <= ball_x_next; 
     ball_y_reg <= ball_y_next; 
     x_delta_reg <= x_delta_next; 
     y_delta_reg <= y_delta_next; 
     end if; 
    end process; 

    pix_x <= unsigned(pixel_x); 
    pix_y <= unsigned(pixel_y); 

    -- refr_tick: 1-clock tick asserted at start of v-sync 
    -- i.e., when the screen is refreshed (60 Hz) 
    refr_tick <= '1' when (pix_y=481) and (pix_x=0) else 
       '0'; 

    ---------------------------------------------- 
    -- pixel within wall 
    wall_on <= 
     '1' when ((WALL_X_LEFTSIDE_L<=pix_x) and (pix_x<=WALL_X_LEFTSIDE_R)) or ((WALL_X_RIGHTSIDE_L<=pix_x) and (pix_x<=WALL_X_RIGHTSIDE_R)) or ((WALL_Y_UPSIDE_U<=pix_y) and (pix_y<=WALL_Y_UPSIDE_D)) or ((WALL_Y_DOWNSIDE_U<=pix_y) and (pix_y<=WALL_Y_DOWNSIDE_D)) else 
     '0'; 
    -- wall rgb output 
    wall_rgb <= "001"; -- blue 



    ---------------------------------------------- 

    -- square ball 

    ball_x_l <= ball_x_reg; 
    ball_y_t <= ball_y_reg; 
    ball_x_r <= ball_x_l + BALL_SIZE - 1; 
    ball_y_b <= ball_y_t + BALL_SIZE - 1; 

    ball_x_l_cell <= ball_x_reg_cell; 
    ball_y_t_cell <= ball_y_reg_cell; 
    ball_x_r_cell <= ball_x_l_cell + BALL_SIZE - 1; 
    ball_y_b_cell <= ball_y_t_cell + BALL_SIZE - 1; 


    --tail 


    -- pixel within squared ball 
    sq_ball_on <= 
     '1' when ((ball_x_l<=pix_x) and (pix_x<=ball_x_r) and 
       (ball_y_t<=pix_y) and (pix_y<=ball_y_b)) 
       or 
       ((ball_x_l_cell<=pix_x) and (pix_x<=ball_x_r_cell) and 
       (ball_y_t_cell<=pix_y) and (pix_y<=ball_y_b_cell)) 
       else 
     '0'; 

    ball_x_next <= ball_x_reg + x_delta_reg 
        when refr_tick='1' else 
        ball_x_reg ; 
    ball_y_next <= ball_y_reg + y_delta_reg 
        when refr_tick='1' else 
        ball_y_reg ; 

    ball_x_next_cell <= ball_x_reg - BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_RIGHT 
        else ball_x_reg + BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_LEFT 
        else ball_x_reg when refr_tick='1' 
        else ball_x_reg_cell; 

    ball_y_next_cell <=  ball_y_reg - BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_UP 
         else ball_y_reg + BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_DOWN 
         else ball_y_reg when refr_tick='1' 
         else ball_y_reg_cell; 

    -- new bar y-position 
    process(ball_y_reg, ball_y_b, ball_y_t, refr_tick, btn, ball_x_reg ,ball_x_r, ball_x_l, x_delta_reg, y_delta_reg) 
    begin 
     x_delta_next <= x_delta_reg; 
     y_delta_next <= y_delta_reg; 


     if refr_tick='1' then 
     if btn(1)='1' and ball_y_b<(MAX_Y-1-BALL_SIZE) then 
      if CURRENT_DIRECTION /= DIR_UP then 

       CURRENT_DIRECTION <= DIR_DOWN; 
       y_delta_next <= BALL_V_P; -- move down 
       x_delta_next <= (others=>'0'); 

      end if; 
     elsif btn(0)='1' and ball_y_t > BALL_SIZE then 
      if CURRENT_DIRECTION /= DIR_DOWN then 

       CURRENT_DIRECTION <= DIR_UP; 
       y_delta_next <= BALL_V_N; -- move up 
       x_delta_next <= (others=>'0'); 

      end if; 
     elsif btn(2)='1' and ball_x_r<(MAX_X-1-BALL_SIZE) then 
      if CURRENT_DIRECTION /= DIR_LEFT then 

       CURRENT_DIRECTION <= DIR_RIGHT; 
       x_delta_next <= BALL_V_P; 
       y_delta_next <= (others=>'0'); 

      end if; 
     elsif btn(3)='1' and ball_x_l > BALL_SIZE then 
      if CURRENT_DIRECTION /= DIR_RIGHT then 

       CURRENT_DIRECTION <= DIR_LEFT; 
       x_delta_next <= BALL_V_N; 
       y_delta_next <= (others=>'0'); 

      end if; 
     end if; 

     if ball_x_l < WALL_X_LEFTSIDE_R or ball_y_t < WALL_Y_UPSIDE_D or ball_y_b > WALL_Y_DOWNSIDE_U or ball_x_r > WALL_X_RIGHTSIDE_L then 
     endOfGame <= true; 
     CURRENT_DIRECTION <= IDLE; 
     else 
     endOfGame <= false; 
     end if; 

     end if; 
    end process; 

"Ball x nächste Zelle" Teile manuell hinzugefügt zweite Zelle.

Ich habe Themen mit ähnlichen Problem gesucht, aber es ist nicht in VHDL abdecken.

Vielen Dank für Ihre Hilfe!

Antwort

2

Das Problem ist nicht VHDL - verlieren Sie nicht in den Sprachunterschieden zwischen VHDL und Java - das sind trivial hier.

Das Problem ist die Synthesefähigkeit - Sie benötigen ein Konzept, das in Hardware dargestellt werden kann.

Sie sagen, Ihre Java-Implementierung verwendet eine Warteschlange - dies basiert auf einer verknüpften Liste mit dynamisch zugewiesenen Knoten (Segmenten) und wird über Zeiger referenziert. Und in der Tat könnten Sie das einfach in VHDL übersetzen, Zugriffsarten verwenden, neue und freigeben und so weiter. Sie müßten die Details selbst implementieren, während es in Java eine praktische Bibliothek, d.h. Klasse, geben könnte. Aber das ist nur ein Detail.

Sie nach unten gehen nicht, dass Straße - Zugriffsarten und vor allem die dynamische Zuordnung nicht synthetisierbaren sind - Sie können nicht normal generieren und freie Stücke von Hardware zu einem laufenden System ...

(Aber Sie könnten tun Wenn Sie eine existierende Snake in einem Simulator parallel zur synthetisierbaren Version laufen lassen möchten, vergleichen Sie ihre Ergebnisse und verifizieren Sie, dass die synthetisierbare Version mit der bereits bewährten Softwareversion übereinstimmt.Wenn Sie eine hochzuverlässige Snake für Militär, Luft- und Raumfahrt oder sicherheitskritische Anforderungen, benötigen Sie diesen Schritt.)

Sie benötigen eine andere Denkweise für Hardware-Design, basierend auf dem Wissen, was physikalisch realisierbar ist und wie Konzepte in diese übersetzen.

Stattdessen müssen Sie überlegen, wie Sie ein Snake-Segment implementieren können, bevor das System gestartet wird, und es nur einschalten, wenn Sie es brauchen. Überlegen Sie dann, wie Sie vor dem Systemstart so viele erstellen können, wie Sie benötigen.

Zum Beispiel muss ein Segment möglicherweise seine Farbe und seine X/Y-Koordinaten kennen und einige andere Sachen, wie, ist es noch sichtbar. Wie kannst du das alles darstellen?

Sie könnten entscheiden, nachdem Sie das Spiel gespielt und 50 Segmente erreicht haben, dass 100 genug ist, um das Spiel zu gewinnen.

Jetzt sind Datensätze und Arrays fester Größe absolut synthetisch.

Das könnte Ihnen helfen ...

+0

Vielen Dank für die schnelle Antwort!Ich bin mir der Einschränkungen in der vhdl-Sprache bewusst, jedoch frage ich nach Implementierungstipps. Ich weiß, dass ich Array von Datensätzen verwenden muss, die aktuelle und nächste Position, Richtung, Sichtbarkeit enthält. Die Frage ist, wie kann ich Array von Datensätzen als gleichzeitige Anweisung durchlaufen, wie ich derzeit mit meiner Zelle (Segment). Ich muss solche Operation wegen der Animation tun, der ich gegenüberstellen muss. –

+0

Das hängt von Ihren Leistungsanforderungen ab. Eine einfache Schleife kann in einem einzigen Taktzyklus über den Array-Bereich iterieren, verhindert jedoch, dass das Array als BlockRam implementiert wird, und generiert möglicherweise RIESIGE Hardware. Sie betrachten wahrscheinlich eine Zustandsmaschine und durchlaufen pro Taktzyklus eine Zelle. Das hängt von Ihren genauen Anforderungen ab. –